143 using namespace CLHEP;
147 #ifdef G4MULTITHREADED
153 forceDecayDirection(0.,0.,0.), forceDecayHalfAngle(0.*
deg), verboseLevel(0)
157 G4cout <<
"G4RadioactiveDecay constructor: processName = " << processName
182 #ifdef G4MULTITHREADED
219 for (DecayTableMap::iterator i =
dkmap->begin(); i !=
dkmap->end(); i++) {
230 if (((
const G4Ions*)(&aParticle))->GetExcitationEnergy() > 0.) {
return true;}
239 G4int A = ((
const G4Ions*) (&aParticle))->GetAtomicMass();
240 G4int Z = ((
const G4Ions*) (&aParticle))->GetAtomicNumber();
251 DecayTableMap::iterator table_ptr =
dkmap->find(key);
254 if (table_ptr ==
dkmap->end() ) {
256 (*dkmap)[key] = theDecayTable;
258 theDecayTable = table_ptr->second;
261 return theDecayTable;
270 for (
size_t i = 0; i < theLogicalVolumes->size(); i++) {
271 volume=(*theLogicalVolumes)[i];
272 if (volume->
GetName() == aVolume) {
280 }
else if(i == theLogicalVolumes->size()) {
281 G4cerr <<
"SelectAVolume: "<< aVolume
282 <<
" is not a valid logical volume name" <<
G4endl;
293 for (
size_t i = 0; i < theLogicalVolumes->size(); i++){
294 volume=(*theLogicalVolumes)[i];
295 if (volume->
GetName() == aVolume) {
296 std::vector<G4String>::iterator location;
303 G4cerr <<
" DeselectVolume:" << aVolume <<
" is not in the list "
308 G4cout <<
" DeselectVolume: " << aVolume <<
" is removed from list "
311 }
else if (i == theLogicalVolumes->size()) {
312 G4cerr <<
" DeselectVolume:" << aVolume
313 <<
"is not a valid logical volume name" <<
G4endl;
329 for (
size_t i = 0; i < theLogicalVolumes->size(); i++){
330 volume = (*theLogicalVolumes)[i];
380 G4cout <<
"The DecayRate Table for " << aParticleName <<
" is selected."
390 long double taotime = 0.L;
396 while (t >
SBin[nbin]) nbin++;
399 long double ltao = tao;
402 for (
G4int i = 0; i < nbin; i++) {
403 taotime += (
long double)
SProfile[i] *
404 (std::exp(-(lt-(
long double)
SBin[i+1])/ltao)-std::exp(-(lt-(
long double)
SBin[i])/ltao));
407 taotime += (
long double)
SProfile[nbin] * (1.
L-std::exp(-(lt-(
long double)
SBin[nbin])/ltao));
409 G4cout <<
" Tao time =: " <<taotime <<
" reset to zero!"<<
G4endl;
558 while ( aDecayTime >
DBin[i] ) i++;
583 G4cout <<
"G4RadioactiveDecay::GetMeanLifeTime() " <<
G4endl;
585 <<
" GeV, Mass: " << theParticle->
GetMass()/
GeV
586 <<
" GeV, Life time: " << theLife/
ns <<
" ns " <<
G4endl;
590 else if (theLife < 0.0) {meanlife =
DBL_MAX;}
591 else {meanlife = theLife;}
594 if (((
const G4Ions*)(theParticleDef))->GetExcitationEnergy() > 0. &&
595 meanlife ==
DBL_MAX) {meanlife = 0.;}
599 G4cout <<
" mean life time: " << meanlife/
s <<
" s " <<
G4endl;
621 G4cout <<
"G4RadioactiveDecay::GetMeanFreePath() " <<
G4endl;
623 <<
" GeV, Mass: " << aMass/
GeV <<
" GeV, tau: " << tau <<
" ns "
634 }
else if (tau < 0.0) {
637 ed <<
"Ion has negative lifetime " << tau
638 <<
" but is not stable. Setting mean free path to DBL_MAX" <<
G4endl;
639 G4Exception(
"G4RadioactiveDecay::GetMeanFreePath()",
"HAD_RDM_011",
646 pathlength = c_light*tau*betaGamma;
652 G4cout <<
"G4Decay::GetMeanFreePath: "
654 <<
" stops, kinetic energy = "
664 G4cout <<
"mean free path: "<< pathlength/
m <<
" m" <<
G4endl;
693 #ifdef G4MULTITHREADED
703 G4int A = ((
const G4Ions*)(&theParentNucleus))->GetAtomicMass();
704 G4int Z = ((
const G4Ions*)(&theParentNucleus))->GetAtomicNumber();
705 G4int lvl = ((
const G4Ions*)(&theParentNucleus))->GetIsomerLevel();
708 #ifdef G4MULTITHREADED
709 G4AutoLock lk(&G4RadioactiveDecay::radioactiveDecayMutex);
712 DecayTableMap::iterator master_table_ptr = master_dkmap->find(key);
714 if (master_table_ptr != master_dkmap->end() ) {
715 return master_table_ptr->second;
726 if (!getenv(
"G4RADIOACTIVEDATA") ) {
727 G4cout <<
"Please setenv G4RADIOACTIVEDATA to point to the radioactive decay data files."
729 throw G4HadronicException(__FILE__, __LINE__,
" Please setenv G4RADIOACTIVEDATA to point to the radioactive decay data files.");
731 G4String dirName = getenv(
"G4RADIOACTIVEDATA");
733 std::ostringstream os;
734 os <<dirName <<
"/z" <<Z <<
".a" <<A <<
'\0';
738 std::ifstream DecaySchemeFile(file);
741 if (DecaySchemeFile) {
744 G4bool modeFirstRecord[8];
747 for (
G4int i = 0; i < nMode; i++) {
748 modeFirstRecord[i] =
true;
753 char inputChars[100]={
' '};
760 G4int levelCounter = 0;
767 while (!complete && !DecaySchemeFile.getline(inputChars, 100).eof()) {
768 inputLine = inputChars;
769 inputLine = inputLine.
strip(1);
770 if (inputChars[0] !=
'#' && inputLine.length() != 0) {
771 std::istringstream tmpStream(inputLine);
773 if (inputChars[0] ==
'P') {
776 tmpStream >> recordType >> a >> b;
781 found = (levelCounter == lvl);
788 if (inputChars[0] ==
'W') {
792 G4cout <<
" Warning in G4RadioactiveDecay::LoadDecayTable " <<
G4endl;
798 tmpStream >> theDecayMode >> a >> b >> c >> betaType;
802 if (inputLine.length() < 80) betaType =
allowed;
806 switch (theDecayMode) {
812 (
const G4Ions*)& theParentNucleus, b);
816 theDecayTable->
Insert(anITChannel);
822 if (modeFirstRecord[1]) {
823 modeFirstRecord[1] =
false;
837 for (
G4int ptn = 0; ptn < npti; ptn++) {
839 e = 1. + e0*(ptn+0.5)/100.;
840 p = std::sqrt(e*e - 1.);
841 f = p*e*(e0-e+1)*(e0-e+1);
847 f *= corrections.
ShapeFactor(betaType, p, e0-e+1.);
854 b, c*
MeV, a*MeV, 0,
FBeta, aRandomEnergy);
858 theDecayTable->
Insert(aBetaMinusChannel);
868 if (modeFirstRecord[2]) {
869 modeFirstRecord[2] =
false;
872 e0 = c*
MeV/0.510999 - 2.;
885 for (
G4int ptn = 0; ptn < npti; ptn++) {
887 e = 1. + e0*(ptn+0.5)/100.;
888 p = std::sqrt(e*e - 1.);
889 f = p*e*(e0-e+1)*(e0-e+1);
895 f *= corrections.
ShapeFactor(betaType, p, e0-e+1.);
901 &theParentNucleus, b,
902 (c-1.021998)*
MeV, a*
MeV, 0,
903 FBeta, aRandomEnergy);
907 theDecayTable->
Insert(aBetaPlusChannel);
917 if (modeFirstRecord[3]) {
918 modeFirstRecord[3] =
false;
928 theDecayTable->
Insert(aKECChannel);
935 if (modeFirstRecord[4]) {
936 modeFirstRecord[4] =
false;
945 theDecayTable->
Insert(aLECChannel);
952 if (modeFirstRecord[5]) {
953 modeFirstRecord[5] =
false;
963 theDecayTable->
Insert(aMECChannel);
969 if (modeFirstRecord[6]) {
970 modeFirstRecord[6] =
false;
985 theDecayTable->
Insert(anAlphaChannel);
991 if (modeFirstRecord[7]) {
992 modeFirstRecord[7] =
false;
1002 theDecayTable->
Insert(aProtonChannel);
1029 G4Exception(
"G4RadioactiveDecay::LoadDecayTable()",
"HAD_RDM_000",
1048 theDecayMode =
Alpha;
1053 if (theDecayMode !=
IT) {
1054 theBR = theChannel->
GetBR();
1055 theChannel->
SetBR(theBR*modeTotalBR[theDecayMode]/modeSumBR[theDecayMode]);
1059 DecaySchemeFile.close();
1061 if (!found && lvl > 0) {
1069 theDecayTable->
Insert(anITChannel);
1071 if (!theDecayTable) {
1075 G4cerr <<
"G4RadoactiveDecay::LoadDecayTable() : cannot find ion radioactive decay file "
1078 return theDecayTable;
1085 #ifdef G4MULTITHREADED
1086 (*master_dkmap)[key] = theDecayTable;
1088 return theDecayTable;
1094 if (Z < 1 || A < 2)
G4cout <<
"Z and A not valid!" <<
G4endl;
1096 std::ifstream DecaySchemeFile(filename);
1097 if (DecaySchemeFile) {
1098 G4int ID_ion = A*1000 + Z;
1102 G4cout <<
"The file " << filename <<
" does not exist!" <<
G4endl;
1109 G4int theG, std::vector<G4double> theRates,
1110 std::vector<G4double> theTaos)
1136 G4int nGeneration = 0;
1137 std::vector<G4double> rates;
1138 std::vector<G4double> taos;
1142 rates.push_back(-1.);
1145 G4int A = ((
const G4Ions*)(&theParentNucleus))->GetAtomicMass();
1146 G4int Z = ((
const G4Ions*)(&theParentNucleus))->GetAtomicNumber();
1147 G4double E = ((
const G4Ions*)(&theParentNucleus))->GetExcitationEnergy();
1149 if (tao < 0.) tao = 1e-100;
1150 taos.push_back(tao);
1180 std::vector<G4double> TP;
1181 std::vector<G4double> RP;
1198 for (j = nS; j < nT; j++) {
1205 G4cout <<
"G4RadioactiveDecay::AddDecayRateTable : daughters of ("
1206 << ZP <<
", " << AP <<
", " << EP
1207 <<
") are being calculated, generation = " << nGeneration
1211 aParentNucleus = theIonTable->
GetIon(ZP,AP,EP);
1215 for (
G4int k = 0; k < 8; k++) brs[k] = 0.0;
1218 for (i = 0; i < aTempDecayTable->
entries(); i++) {
1224 AD = ((
const G4Ions*)(theDaughterNucleus))->GetAtomicMass();
1225 ZD = ((
const G4Ions*)(theDaughterNucleus))->GetAtomicNumber();
1237 theDecayTable->
Insert(theChannel);
1239 brs[theDecayMode] += theChannel->
GetBR();
1242 brs[theDecayMode] += theChannel->
GetBR();
1245 brs[theDecayMode] += theChannel->
GetBR();
1248 brs[2] = brs[2]+brs[3]+brs[4]+brs[5];
1249 brs[3] = brs[4] =brs[5] = 0.0;
1250 for (i= 0; i<8; i++){
1256 (
const G4Ions*) aParentNucleus, brs[0]);
1257 theDecayTable->
Insert(theITChannel);
1263 brs[1], 0.*
MeV, 0.*
MeV, 1,
false, 0);
1264 theDecayTable->
Insert(theBetaMinusChannel);
1270 aParentNucleus, brs[2], 0.*
MeV, 0.*
MeV, 1,
false, 0);
1271 theDecayTable->
Insert(theBetaPlusChannel);
1284 theDecayTable->
Insert(theAlphaChannel);
1292 theDecayTable->
Insert(theProtonChannel);
1303 for (i = 0; i < theDecayTable->
entries(); i++){
1306 theBR = theChannel->
GetBR();
1310 if (theNuclearDecayChannel->
GetDecayMode() ==
IT && nGeneration == 1) {
1311 A = ((
const G4Ions*)(theDaughterNucleus))->GetAtomicMass();
1312 Z = ((
const G4Ions*)(theDaughterNucleus))->GetAtomicNumber();
1313 theDaughterNucleus=theIonTable->
GetIon(Z,A,0.);
1316 aParentNucleus != theDaughterNucleus) {
1320 if (aTempDecayTable->
entries() ) {
1321 A = ((
const G4Ions*)(theDaughterNucleus))->GetAtomicMass();
1322 Z = ((
const G4Ions*)(theDaughterNucleus))->GetAtomicNumber();
1323 E = ((
const G4Ions*)(theDaughterNucleus))->GetExcitationEnergy();
1326 if (TaoPlus <= 0.) TaoPlus = 1e-100;
1336 taos.push_back(TaoPlus);
1342 long double ta1,ta2;
1343 ta2 = (
long double)TaoPlus;
1344 for (k = 0; k < RP.size(); k++){
1345 ta1 = (
long double)TP[k];
1349 theRate = ta1/(ta1-ta2);
1351 theRate = theRate * theBR * RP[k];
1352 rates.push_back(theRate);
1359 long double aRate, aRate1;
1361 for (k = 0; k < RP.size(); k++){
1362 ta1 = (
long double)TP[k];
1366 aRate = ta2/(ta1-ta2);
1368 aRate = aRate * (
long double)(theBR * RP[k]);
1372 rates.push_back(theRate);
1384 if (nS == nT) stable =
true;
1411 std::ifstream infile ( filename, std::ios::in );
1414 ed <<
" Could not open file " << filename <<
G4endl;
1415 G4Exception(
"G4RadioactiveDecay::SetSourceTimeProfile()",
"HAD_RDM_001",
1421 while (infile >> bin >> flux ) {
1424 G4Exception(
"G4RadioactiveDecay::SetSourceTimeProfile()",
"HAD_RDM_002",
1451 std::ifstream infile(filename, std::ios::in);
1452 if (!infile)
G4Exception(
"G4RadioactiveDecay::SetDecayBias()",
"HAD_RDM_003",
1462 while (infile >> bin >> flux ) {
1465 G4Exception(
"G4RadioactiveDecay::SetDecayBias()",
"HAD_RDM_004",
1512 G4cout <<
"G4RadioactiveDecay::DecayIt : "
1514 <<
" is not selected for the RDM"<<
G4endl;
1537 G4cerr <<
"G4RadioactiveDecay::DecayIt : "
1539 <<
" is not a valid nucleus for the RDM"<<
G4endl;
1553 if (theDecayTable == 0 || theDecayTable->
entries() == 0) {
1558 G4cerr <<
"G4RadioactiveDecay::DecayIt : decay table not defined for ";
1590 if ( products->
entries() == 1) {
1619 if (temptime < 0.) temptime = 0.;
1620 finalGlobalTime += temptime;
1621 finalLocalTime += temptime;
1624 products->
Boost(ParentEnergy, ParentDirection);
1631 G4cout <<
"G4RadioactiveDecay::DecayIt : Decay vertex :";
1632 G4cout <<
" Time: " <<finalGlobalTime/
ns <<
"[ns]";
1637 G4cout <<
"G4Decay::DecayIt : decay products in Lab. Frame" <<
G4endl;
1642 for (index=0; index < numberOfSecondaries; index++) {
1644 finalGlobalTime, currentPosition);
1656 G4cout <<
"DecayIt: Variance Reduction version " <<
G4endl;
1673 std::vector<G4double> PT;
1674 std::vector<G4double> PR;
1676 long double decayRate;
1680 G4int numberOfSecondaries;
1681 G4int totalNumberOfSecondaries = 0;
1685 std::vector<G4DynamicParticle*> secondaryparticles;
1686 std::vector<G4double> pw;
1687 std::vector<G4double> ptime;
1703 }
else if (nbin > 1) {
1728 for (j = 0; j < PT.size(); j++) {
1730 decayRate -= PR[j] * (
long double)taotime;
1752 parentNucleus = theIonTable->
GetIon(PZ,PA,PE);
1764 if (theDecayChannel == 0) {
1768 G4cerr <<
" G4RadioactiveDecay::DoIt : cannot determine decay channel ";
1769 G4cerr <<
" for this nucleus; decay as if no biasing active ";
1774 tempprods =
DoDecay(*parentNucleus);
1779 tempprods = theDecayChannel->DecayIt(tempmass);
1780 weight *= (theDecayChannel->GetBR())*(decayTable->
entries());
1783 tempprods =
DoDecay(*parentNucleus);
1787 numberOfSecondaries = tempprods->
entries();
1788 currentTime = finalGlobalTime + theDecayTime;
1789 for (index = 0; index < numberOfSecondaries; index++) {
1792 pw.push_back(weight);
1793 ptime.push_back(currentTime);
1794 secondaryparticles.push_back(asecondaryparticle);
1804 totalNumberOfSecondaries = pw.size();
1806 for (index=0; index < totalNumberOfSecondaries; index++) {
1808 ptime[index], currentPosition);
1846 if (theDecayChannel == 0) {
1848 G4cerr <<
"G4RadioactiveDecay::DoIt : can not determine decay channel";
1854 G4cerr <<
"G4RadioactiveDecay::DoIt : selected decay channel addr:";
1873 if (0 == products || 0 == products->
entries())
return;
1892 if (daughterType == electron || daughterType == positron ||
1893 daughterType == neutron || daughterType == gamma ||
1901 G4cout <<
"CollimateDecayProduct for daughter "
1926 dir.setPhi(dir.phi()+phi);
1927 dir.setTheta(dir.theta()+std::acos(cosTheta));
1932 G4cout <<
" ChooseCollimationDirection returns " << dir <<
G4endl;
void RegisterIsotopeTable(G4VIsotopeTable *table)
G4double halflifethreshold
G4double GetDaughterExcitation()
G4RadioactiveDecayRateVector theDecayRateTable
G4DecayProducts * DoDecay(const G4ParticleDefinition &theParticleDef)
void SetBR(G4double value)
static G4LossTableManager * Instance()
G4double GetLocalTime() const
void InitialiseAtomicDeexcitation()
void SelectAVolume(const G4String aVolume)
std::map< G4String, G4DecayTable * > DecayTableMap
std::ostringstream G4ExceptionDescription
G4double GetKineticEnergy() const
CLHEP::Hep3Vector G4ThreeVector
G4bool IsRateTableReady(const G4ParticleDefinition &)
const G4DynamicParticle * GetDynamicParticle() const
std::vector< G4String > ValidVolumes
G4double HalfLife() const
void SetTaos(std::vector< G4double > value)
G4String strip(G4int strip_Type=trailing, char c=' ')
void SetDecayRateC(std::vector< G4double > value)
void AddUserDecayDataFile(G4int Z, G4int A, G4String filename)
G4bool GetPDGStable() const
G4ParticleDefinition * GetIon(G4int Z, G4int A, G4int lvl=0)
static G4Alpha * Definition()
const G4ThreeVector & GetPosition() const
void AddSecondary(G4Track *aSecondary)
G4TrackStatus GetTrackStatus() const
const G4String & GetKinematicsName() const
G4RadioactiveDecayRates theDecayRateVector
static G4Electron * Definition()
void SetTouchableHandle(const G4TouchableHandle &apValue)
G4VDecayChannel * GetDecayChannel(G4int index) const
G4double GetMeanLifeTime(const G4Track &theTrack, G4ForceCondition *condition)
G4int GetVerboseLevel() const
void SetMomentumDirection(const G4ThreeVector &aDirection)
static G4NuclearLevelStore * GetInstance()
G4ParticleDefinition * GetDefinition() const
void SetSourceTimeProfile(G4String filename)
G4bool IsApplicable(const G4ParticleDefinition &)
void Boost(G4double totalEnergy, const G4ThreeVector &momentumDirection)
void SetGeneration(G4int value)
static G4Positron * Definition()
void ClearNumberOfInteractionLengthLeft()
#define G4MUTEX_INITIALIZER
const G4String & GetParticleName() const
void SetWeight(G4double aValue)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
void SetItsRates(G4RadioactiveDecayRates arate)
G4ParticleChangeForRadDecay fParticleChangeForRadDecay
G4double GetTotalMomentum() const
static G4Proton * Definition()
virtual void Initialize(const G4Track &)
G4IonTable * GetIonTable() const
G4GLOB_DLL std::ostream G4cout
void ProposeLocalTime(G4double t)
static const G4ThreeVector origin
void SetDecayRate(G4int, G4int, G4double, G4int, std::vector< G4double >, std::vector< G4double >)
const G4ThreeVector & GetMomentumDirection() const
void CollimateDecayProduct(G4DynamicParticle *product)
static G4LogicalVolumeStore * GetInstance()
G4ThreeVector ChooseCollimationDirection() const
G4int GetDecayTimeBin(const G4double aDecayTime)
void SetProcessSubType(G4int)
void DeselectAllVolumes()
const G4String & GetParticleType() const
const G4ParticleDefinition * GetParticleDefinition() const
G4double GetGlobalTime() const
static const G4double A[nN]
G4double GetTaoTime(const G4double, const G4double)
G4NucleusLimits theNucleusLimits
const G4TouchableHandle & GetTouchableHandle() const
G4VDecayChannel * SelectADecayChannel()
G4DecayTable * GetDecayTable(const G4ParticleDefinition *)
G4NuclearLevelManager * GetManager(G4int Z, G4int A)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
G4ParticleDefinition * GetDaughterNucleus()
void Insert(G4VDecayChannel *aChannel)
G4double GetMeanFreePath(const G4Track &theTrack, G4double previousStepSize, G4ForceCondition *condition)
G4RadioactiveDecayRate theDecayRate
static const G4double levelTolerance
G4RadioactiveDecayRateTable theDecayRateTableVector
std::map< G4int, G4String > theUserRadioactiveDataFiles
static const double nanosecond
G4LogicalVolume * GetLogicalVolume() const
G4double forceDecayHalfAngle
G4double GetPDGMass() const
static G4ParticleTable * GetParticleTable()
void GetDecayRateTable(const G4ParticleDefinition &)
G4RadioactiveDecaymessenger * theRadioactiveDecaymessenger
void SetNumberOfSecondaries(G4int totSecondaries)
G4DynamicParticle * PopProducts()
G4VParticleChange * pParticleChange
G4RadioactiveDecayMode GetDecayMode()
void AddDecayRateTable(const G4ParticleDefinition &)
G4DecayTable * LoadDecayTable(const G4ParticleDefinition &theParentNucleus)
static G4Neutron * Definition()
G4int NumberOfLevels() const
G4VPhysicalVolume * GetVolume() const
std::vector< G4RadioactivityTable * > theRadioactivityTables
G4double GetWeight() const
void SetIonName(G4String name)
G4double GetPDGLifeTime() const
G4RadioactiveDecay(const G4String &processName="RadioactiveDecay")
G4ThreeVector forceDecayDirection
G4VAtomDeexcitation * AtomDeexcitation()
void SetHLThreshold(G4double HLT)
virtual G4DecayProducts * DecayIt(G4double parentMass=-1.0)=0
void ProposeTrackStatus(G4TrackStatus status)
void BuildPhysicsTable(const G4ParticleDefinition &)
G4double ShapeFactor(const G4BetaDecayType &, const G4double &p_e, const G4double &e_nu)
void SetHLThreshold(G4double hl)
void SetAnalogueMonteCarlo(G4bool r)
static const G4double alpha
G4double FermiFunction(const G4double &W)
void DeselectAVolume(const G4String aVolume)
void SetE(G4double value)
const G4NuclearLevel * NearestLevel(G4double energy, G4double eDiffMax=1.e+8) const
G4RIsotopeTable * theIsotopeTable
void AddUserDecayDataFile(G4int Z, G4int A, G4String filename)
void CollimateDecay(G4DecayProducts *products)
void SetDecayBias(G4String filename)
static G4Gamma * Definition()
void SetGoodForTrackingFlag(G4bool value=true)
G4VParticleChange * DecayIt(const G4Track &theTrack, const G4Step &theStep)
G4GLOB_DLL std::ostream G4cerr
G4int GetBaryonNumber() const