Files
geant4/examples/advanced/STCyclotron/src/STCyclotronRun.cc
T
2021-12-10 16:15:15 +00:00

584 lines
21 KiB
C++

//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// Author: F. Poignant, floriane.poignant@gmail.com
//
// file STCyclotronRun.cc
#include "STCyclotronRun.hh"
#include "G4RunManager.hh"
#include "G4Event.hh"
#include "G4SDManager.hh"
#include "G4HCofThisEvent.hh"
#include "G4THitsMap.hh"
#include "G4SystemOfUnits.hh"
STCyclotronRun::STCyclotronRun()
: G4Run(),fTotalEnergyDepositTarget(0.),fTotalEnergyDepositFoil(0.),fParticleTarget(0),fTargetThickness(0.),fTargetDiameter(0.),fFoilThickness(0.),fTargetVolume(0.),fFoilVolume(0.),fPrimariesPerEvent(0),fTimePerEvent(0),fBeamName(""),fBeamCurrent(0.),fBeamEnergy(0.)
{ }
STCyclotronRun::~STCyclotronRun()
{ }
void STCyclotronRun::Merge(const G4Run* aRun)
{
const STCyclotronRun* localRun = static_cast<const STCyclotronRun*>(aRun);
//Merging cumulable variables
fTotalEnergyDepositTarget += localRun->fTotalEnergyDepositTarget;
fTotalEnergyDepositFoil += localRun->fTotalEnergyDepositFoil;
fParticleTarget += localRun->fParticleTarget;
//Constant over the different runs
if(localRun->fTargetVolume!=0)fTargetVolume = localRun->fTargetVolume;
if(localRun->fFoilVolume!=0)fFoilVolume = localRun->fFoilVolume;
if(localRun->fPrimariesPerEvent!=0)fPrimariesPerEvent = localRun->fPrimariesPerEvent;
if(localRun->fTimePerEvent!=0)fTimePerEvent = localRun->fTimePerEvent;
if(localRun->fTargetThickness!=0)fTargetThickness = localRun->fTargetThickness;
if(localRun->fTargetDiameter!=0)fTargetDiameter = localRun->fTargetDiameter;
if(localRun->fFoilThickness!=0)fFoilThickness = localRun->fFoilThickness;
fBeamName = localRun->fBeamName;
if(localRun->fBeamCurrent!=0.)fBeamCurrent = localRun->fBeamCurrent;
if(localRun->fBeamEnergy!=0.)fBeamEnergy = localRun->fBeamEnergy;
//<<<----toMerge
std::map<G4String,G4int>::iterator itSI;
std::map<G4String,G4double>::iterator itSD;
std::map<G4String,G4String>::iterator itSS;
std::map<G4int,G4String>::iterator itIS;
//----Merging results for primary isotopes
std::map<G4String,G4int> locPrimaryIsotopeCountTarget = localRun->fPrimaryIsotopeCountTarget;
for (itSI = locPrimaryIsotopeCountTarget.begin(); itSI != locPrimaryIsotopeCountTarget.end(); itSI++)
{
G4String name = itSI->first;
G4int count = itSI->second;
fPrimaryIsotopeCountTarget[name] += count;
}
std::map<G4String,G4double> locPrimaryIsotopeTimeTarget = localRun->fPrimaryIsotopeTimeTarget;
for (itSD = locPrimaryIsotopeTimeTarget.begin(); itSD != locPrimaryIsotopeTimeTarget.end(); itSD++)
{
G4String name = itSD->first;
G4double time = itSD->second;
fPrimaryIsotopeTimeTarget[name] = time;
}
//----Merging results for decay isotopes
// std::map<G4int,G4String> fIsotopeIDTarget;
std::map<G4String,G4String> locDecayIsotopeCountTarget = localRun->fDecayIsotopeCountTarget;
for (itSS = locDecayIsotopeCountTarget.begin(); itSS != locDecayIsotopeCountTarget.end(); itSS++)
{
G4String nameDaughter = itSS->first;
G4String mum = itSS->second;
fDecayIsotopeCountTarget[nameDaughter] = mum;
}
std::map<G4String,G4double> locDecayIsotopeTimeTarget = localRun->fDecayIsotopeTimeTarget;
for (itSD = locDecayIsotopeTimeTarget.begin(); itSD != locDecayIsotopeTimeTarget.end(); itSD++)
{
G4String nameDaughter = itSD->first;
G4double time = itSD->second;
fDecayIsotopeTimeTarget[nameDaughter] = time;
}
std::map<G4String,G4String> locParticleParent = localRun->fParticleParent;
for (itSS = locParticleParent.begin(); itSS != locParticleParent.end(); itSS++)
{
G4String nameDaughter = itSS->first;
G4String parent = itSS->second;
fParticleParent[nameDaughter] = parent;
}
std::map<G4int,G4String> locIsotopeIDTarget = localRun->fIsotopeIDTarget;
for (itIS = locIsotopeIDTarget.begin(); itIS != locIsotopeIDTarget.end(); itIS++)
{
G4int ID = itIS->first;
G4String name = itIS->second;
fIsotopeIDTarget[ID] = name;
}
//----Merging results for stable isotopes
std::map<G4String,G4int> locStableIsotopeCountTarget = localRun->fStableIsotopeCountTarget;
for (itSI = locStableIsotopeCountTarget.begin(); itSI != locStableIsotopeCountTarget.end(); itSI++)
{
G4String name = itSI->first;
G4int count = itSI->second;
fStableIsotopeCountTarget[name] += count;
}
//----Merging results for particles
std::map<G4String,G4int> locParticleCountTarget = localRun->fParticleCountTarget;
for (itSI = locParticleCountTarget.begin(); itSI != locParticleCountTarget.end(); itSI++)
{
G4String name = itSI->first;
G4int count = itSI->second;
fParticleCountTarget[name] += count;
}
G4Run::Merge(aRun);
}
void STCyclotronRun::EndOfRun(G4double irradiationTime)
{
G4int nbEvents = GetNumberOfEvent();
if (nbEvents == 0) return;
//------------------------------------------------------
// Opening the ASCII file
//------------------------------------------------------
fOutPut.open("Output_General.txt",std::ofstream::out);
fOutPut1.open("Output_ParentIsotopes.txt",std::ofstream::out);
fOutPut2.open("Output_DaughterIsotopes.txt",std::ofstream::out);
fOutPut3.open("Output_OtherParticles.txt",std::ofstream::out);
fOutPut4.open("Output_StableIsotopes.txt",std::ofstream::out);
//------------------------------------------------------
// Calculates the equivalent time for a given run
//------------------------------------------------------
G4double timePerEvent = fTimePerEvent; //in seconds
G4double timeForARun = nbEvents*timePerEvent; //in seconds
G4double minDecay = 0.0001; //in seconds
G4double maxDecay = 1000000.; //in seconds
//------------------------------------------------------
// Rescale the value of the beam current to account for
// the loss of primary particles due to the foil.
//------------------------------------------------------
G4int totalPrimaries = fPrimariesPerEvent*nbEvents;
G4double currentFactor;
if(fParticleTarget>0.) currentFactor =(fParticleTarget*1.)/(totalPrimaries*1.);
else currentFactor = 0.;
fOutPut << "//-----------------------------------//" << G4endl;
fOutPut << "// Parameters of the simulation: //" << G4endl;
fOutPut << "//-----------------------------------//" << G4endl;
fOutPut << "Beam parameters: " << G4endl;
fOutPut << fBeamName << " - Name of beam primary particles." << G4endl;
fOutPut << fBeamEnergy << " - Energy of beam primary particles (MeV)." << G4endl;
fOutPut << fBeamCurrent << " - Beam current (Ampere)." << G4endl;
fOutPut << irradiationTime << " - Irradiation time in hour(s)." << G4endl;
fOutPut << currentFactor << " - Current factor." << G4endl;
fOutPut << "//-----------------------------------//" << G4endl;
fOutPut << "Simulation parameters: " << G4endl;
fOutPut << timePerEvent << " - Equivalent time per event (s)." << G4endl;
fOutPut << nbEvents << " - Number of events" << G4endl;
fOutPut << fPrimariesPerEvent << " - Primaries per event" << G4endl;
fOutPut << fPrimariesPerEvent*nbEvents << " - Total number of particles sent." << G4endl;
fOutPut << "//-----------------------------------//" << G4endl;
fOutPut << "Geometry parameters: " << G4endl;
fOutPut << fTargetThickness << " - target thickness (mm)." << G4endl;
fOutPut << fTargetDiameter << " - target diameter (mm)." << G4endl;
fOutPut << fFoilThickness << " - foil thickness (mm)." << G4endl;
//Add particle type, particle energy, beam diameter, beam current
//target material???
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////Calculation of the number of isotopes at the end of the irradiation and the activity generated/////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Maps to fill
std::map<G4String,G4double> fPrimaryIsotopeEOBTarget;
std::map<G4String,G4double> fPrimaryActivityTarget;
std::map<G4String,G4double> fDecayIsotopeEOBTarget;
std::map<G4String,G4double> fDecayActivityTarget;
//----------------------------------------------
// CASE 1 : Parent isotopes
//----------------------------------------------
std::map<G4String,G4int>::iterator it;
G4double primaryActivityTotal = 0.;
G4double decayActivityTotal=0.;
fOutPut1 << "//-----------------------------------//\n"
<< "// Data for parent isotopes //\n"
<< "//-----------------------------------//\n" << G4endl;
for (it = fPrimaryIsotopeCountTarget.begin(); it != fPrimaryIsotopeCountTarget.end(); it++)
{
G4String name = it->first;
G4double count = (it->second)*currentFactor;
G4double halfLifeTime = fPrimaryIsotopeTimeTarget[name]*10E-10/3600.*std::log(2.);
G4String process = fParticleParent[name];
//Only store isotopes with a life time between minDecay and maxDecay.
G4bool store;
if(halfLifeTime > minDecay && halfLifeTime < maxDecay) store = true;
else store = false;
//Calculation of the yield (s-1)
G4double decayConstant = 1/(fPrimaryIsotopeTimeTarget[name]*10E-10);
//----------------------------------------------
// Number of particles per second
//----------------------------------------------
G4double particlesPerSecond = fPrimaryIsotopeCountTarget[name]*currentFactor/timeForARun;
//----------------------------------------------
// Calculation yield EOB
//----------------------------------------------
fPrimaryIsotopeEOBTarget[name] = particlesPerSecond/decayConstant * (1. - std::exp(-irradiationTime*3600*decayConstant));
//----------------------------------------------
// Calculation of the activity
// conversion factor Bq to mCi
//----------------------------------------------
G4double conv = 2.7E-8;
fPrimaryActivityTarget[name]= fPrimaryIsotopeEOBTarget[name]*decayConstant*conv;
if(store)
{
//----------------------------------------------
// Incrementation for total primary activity
//----------------------------------------------
primaryActivityTotal = primaryActivityTotal + fPrimaryActivityTarget[name];
}
//---------------------------//
// Printing out results //
//---------------------------//
if(store)
{
fOutPut1 << name << " - name of parent isotope." << G4endl;
fOutPut1 << count/currentFactor << " - number of isotopes created during the simulation." << G4endl;
fOutPut1 << decayConstant << " - decay constant in s-1." << G4endl;
fOutPut1 << halfLifeTime << " - half life time in hour(s)." << G4endl;
fOutPut1 << process << " - creation process." << G4endl;
fOutPut1 << particlesPerSecond << " - isotope per sec." << G4endl;
fOutPut1 << fPrimaryIsotopeEOBTarget[name] << " - yield EOB." << G4endl;
fOutPut1 << fPrimaryActivityTarget[name] << " - activity (mCi) at the EOB." << G4endl;
fOutPut1 << "------------------------" << G4endl;
}
}
//----------------------------------------------
// CASE 2 : isotopes from primary isotopes decay
//----------------------------------------------
fOutPut2 << "//-----------------------------------//\n"
<< "// Data for daughter isotopes //\n"
<< "//-----------------------------------//\n" << G4endl;
std::map<G4String,G4String>::iterator it1;
for (it1 = fDecayIsotopeCountTarget.begin(); it1 != fDecayIsotopeCountTarget.end(); it1++)
{
G4String nameDaughter = it1->first;
G4String nameMum = it1->second;
G4double halfLifeTimeMum = fDecayIsotopeTimeTarget[nameDaughter]*10E10/3600;
G4double halfLifeTimeDaughter = fPrimaryIsotopeTimeTarget[nameMum]*10E10/3600;
G4bool store;
if(halfLifeTimeMum > minDecay && halfLifeTimeMum < maxDecay &&
halfLifeTimeDaughter > minDecay && halfLifeTimeDaughter < maxDecay){store=true;}
else{store=false;}
//----------------------------------------------
// Calculation of the yield
// fParticleTime[name] is the time
// life of the particle, divided by ln(2), in nS
//----------------------------------------------
G4double decayConstantMum = fPrimaryIsotopeTimeTarget[nameMum]
? 1/(fPrimaryIsotopeTimeTarget[nameMum]*10.E-10) : 0.;
G4double decayConstantDaughter = fDecayIsotopeTimeTarget[nameDaughter]
? 1/(fDecayIsotopeTimeTarget[nameDaughter]*10.E-10) : 0.;
//----------------------------------------------
// Number of particles per second
//----------------------------------------------
G4double particlesPerSecond = fPrimaryIsotopeCountTarget[nameMum]*currentFactor/timeForARun;
//----------------------------------------------
// Number of particles at the EOB
//----------------------------------------------
fDecayIsotopeEOBTarget[nameDaughter] = particlesPerSecond*((1 - std::exp(-irradiationTime*3600*decayConstantDaughter))/decayConstantDaughter + (std::exp(-irradiationTime*3600*decayConstantDaughter) - std::exp(-irradiationTime*3600*decayConstantMum))/(decayConstantDaughter-decayConstantMum));
//----------------------------------------------
// Calculation of activity
// conversion factor Bq to mCu
//----------------------------------------------
G4double conv = 2.7E-8;
fDecayActivityTarget[nameDaughter]= fDecayIsotopeEOBTarget[nameDaughter]*decayConstantDaughter*conv;
if(store)
{
decayActivityTotal = decayActivityTotal + fDecayActivityTarget[nameDaughter];
}
if(store)
{
fOutPut2 << nameDaughter << " - name of daughter isotope." << G4endl;
fOutPut2 << nameMum << " - name of parent isotope." << G4endl;
fOutPut2 << decayConstantDaughter << " - decay constant of daughter in s-1." << G4endl;
fOutPut2 << decayConstantMum << " - decay constant of mum in s-1." << G4endl;
fOutPut2 << halfLifeTimeDaughter << " - half life time of daughter in hour(s)." << G4endl;
fOutPut2 << halfLifeTimeMum << " - half life time of mum in hour(s)." << G4endl;
fOutPut2 << particlesPerSecond << " - isotope per sec." << G4endl;
fOutPut2 << fDecayIsotopeEOBTarget[nameDaughter] << " - yield at the EOB." << G4endl;
fOutPut2 << fDecayActivityTarget[nameDaughter] << " - activity (mCi) at the EOB." << G4endl;
fOutPut2 << "------------------------" << G4endl;
}
}
//----------------------------------------------
// Particles created, other than nuclei
//----------------------------------------------
fOutPut3 << "//-----------------------------------//\n"
<< "// Data for other particles //\n"
<< "//-----------------------------------//" << G4endl;
std::map<G4String, G4int>::iterator it3;
for(it3=fParticleCountTarget.begin(); it3!= fParticleCountTarget.end(); it3++)
{
G4String name = it3->first;
G4double number = it3->second;
fOutPut3 << name << " - name of the particle" << G4endl;
fOutPut3 << number << " - number of particles" << G4endl;
fOutPut3 << "------------------------" << G4endl;
}
fOutPut4 << "//-----------------------------------//\n"
<< "// Data for stable isotopes //\n"
<< "//-----------------------------------//\n" << G4endl;
std::map<G4String, G4int>::iterator it6;
for(it6=fStableIsotopeCountTarget.begin();it6!=fStableIsotopeCountTarget.end();it6++)
{
G4String isotope = it6 ->first;
G4int number = it6 -> second;
fOutPut4 << isotope << " - name of the isotope" << G4endl;
fOutPut4 << number << " - number of isotopes" << G4endl;
fOutPut4 << "------------------------" << G4endl;
}
//Clear the maps
fPrimaryIsotopeEOBTarget.clear();
fPrimaryActivityTarget.clear();
fDecayIsotopeEOBTarget.clear();
fDecayActivityTarget.clear();
//Clear the maps
fPrimaryIsotopeCountTarget.clear();
fPrimaryIsotopeTimeTarget.clear();
fDecayIsotopeCountTarget.clear();
fDecayIsotopeTimeTarget.clear();
fParticleParent.clear();
fParticleCountTarget.clear();
fStableIsotopeCountTarget.clear();
fIsotopeIDTarget.clear();
//-----------------------------
// Calculation of heat
//-----------------------------
G4double totalEnergyDepositTargetEOB = fTotalEnergyDepositTarget/timeForARun * irradiationTime * 3600.;
G4double totalEnergyDepositTargetPerSecond = fTotalEnergyDepositTarget/timeForARun;
//Heat calculation in W/mm3
G4double heatTarget = totalEnergyDepositTargetPerSecond/fTargetVolume * 1.60E-13;
G4double heatFoil = fTotalEnergyDepositFoil / fFoilVolume * 1.60E-13;
//Output data in a .txt file
fOutPut << "//-------------------------------------------------//\n"
<< "// Heating, total activity and process data //\n"
<< "//-------------------------------------------------//" << G4endl;
fOutPut << "Total heating in the target : "
<< heatTarget << " W/mm3" << G4endl;
fOutPut << "The total heating during the irradiation is " << totalEnergyDepositTargetEOB << "J/mm3" << G4endl;
fOutPut << "Total heating in the foil : " << heatFoil << " W/mm3" << G4endl;
fOutPut.close();
fOutPut1.close();
fOutPut2.close();
fOutPut3.close();
fOutPut4.close();
}
// Accumulation functions for maps used at the end of run action
void STCyclotronRun::PrimaryIsotopeCountTarget(G4String name,G4double time)
{
fPrimaryIsotopeCountTarget[name]++;
fPrimaryIsotopeTimeTarget[name]=time;
}
//------------------------------------
void STCyclotronRun::CountStableIsotopes(G4String name)
{
fStableIsotopeCountTarget[name]++;
}
//------------------------------------
void STCyclotronRun::DecayIsotopeCountTarget(G4String nameDaughter,G4String mum, G4double time)
{
fDecayIsotopeCountTarget[nameDaughter]=mum;
fDecayIsotopeTimeTarget[nameDaughter]=time;
}
//------------------------------------
void STCyclotronRun::ParticleParent(G4String isotope, G4String parent)
{
fParticleParent[isotope]=parent;
}
//
//-----> Count other particles
//------------------------------------
void STCyclotronRun::ParticleCountTarget(G4String name)
{
fParticleCountTarget[name]++;
}
//-------------------------------------------------------------------------------------------------------------
// Accumulation functions for maps used only during the run
//
//-----> Isotope ID to obtain the "mother isotope" in SensitiveTarget()
//------------------------------------
void STCyclotronRun::StoreIsotopeID(G4int ID, G4String name)
{
fIsotopeIDTarget[ID]=name;
}
//
std::map<G4int,G4String> STCyclotronRun::GetIsotopeID()
{
return fIsotopeIDTarget;
}
void STCyclotronRun::EnergyDepositionTarget(G4double edep)
{
fTotalEnergyDepositTarget += edep;
}
void STCyclotronRun::EnergyDepositionFoil(G4double edep)
{
fTotalEnergyDepositFoil += edep;
}
void STCyclotronRun::CountParticlesTarget()
{
fParticleTarget++;
}
void STCyclotronRun::SetFoilVolume(G4double foilVolume)
{
fFoilVolume = foilVolume;
}
void STCyclotronRun::SetFoilThickness(G4double foilThickness)
{
fFoilThickness = foilThickness;
}
void STCyclotronRun::SetTargetVolume(G4double targetVolume)
{
fTargetVolume = targetVolume;
}
void STCyclotronRun::SetTargetThickness(G4double targetThickness)
{
fTargetThickness = targetThickness;
}
void STCyclotronRun::SetTargetDiameter(G4double targetDiameter)
{
fTargetDiameter = targetDiameter;
}
void STCyclotronRun::SetPrimariesPerEvent(G4int primaries)
{
fPrimariesPerEvent = primaries;
}
void STCyclotronRun::SetTimePerEvent(G4double timePerEvent)
{
fTimePerEvent = timePerEvent;
}
void STCyclotronRun::SetBeamName(G4String beamName)
{
fBeamName = beamName;
}
void STCyclotronRun::SetBeamCurrent(G4double beamCurrent)
{
fBeamCurrent = beamCurrent;
}
void STCyclotronRun::SetBeamEnergy(G4double beamEnergy)
{
fBeamEnergy = beamEnergy;
}