102G4int& G4RadioactiveDecayBase::NumberOfInstances()
104 static G4int numberOfInstances = 0;
105 return numberOfInstances;
111 forceDecayDirection(0.,0.,0.), forceDecayHalfAngle(0.*deg), dirPath(
""),
116 G4cout <<
"G4RadioactiveDecayBase constructor: processName = " << processName
135 char* path_var = std::getenv(
"G4RADIOACTIVEDATA");
138 "Environment variable G4RADIOACTIVEDATA is not set");
141 std::ostringstream os;
142 os << dirPath <<
"/z1.a3";
143 std::ifstream testFile;
144 testFile.open(os.str() );
145 if (!testFile.is_open() )
147 "Environment variable G4RADIOACTIVEDATA is set, but does not point to correct directory");
151 theUserRadioactiveDataFiles.clear();
154#ifdef G4MULTITHREADED
155 G4AutoLock lk(&G4RadioactiveDecayBase::radioactiveDecayMutex);
156 NumberOfInstances()++;
173 outFile <<
"The radioactive decay process (G4RadioactiveDecay) handles the\n"
174 <<
"alpha, beta+, beta-, electron capture and isomeric transition\n"
175 <<
"decays of nuclei (G4GenericIon) with masses A > 4.\n"
176 <<
"The required half-lives and decay schemes are retrieved from\n"
177 <<
"the RadioactiveDecay database which was derived from ENSDF.\n";
185 for (DecayTableMap::iterator i =
dkmap->begin(); i !=
dkmap->end(); i++) {
190#ifdef G4MULTITHREADED
191 G4AutoLock lk(&G4RadioactiveDecayBase::radioactiveDecayMutex);
192 --NumberOfInstances();
193 if(NumberOfInstances()==0)
195 for (DecayTableMap::iterator i = master_dkmap->begin(); i != master_dkmap->end(); i++) {
198 master_dkmap->clear();
208 if (((
const G4Ions*)(&aParticle))->GetExcitationEnergy() > 0.) {
return true;}
217 G4int A = ((
const G4Ions*) (&aParticle))->GetAtomicMass();
218 G4int Z = ((
const G4Ions*) (&aParticle))->GetAtomicNumber();
222 else if (Z > theNucleusLimits.
GetZMax() || Z < theNucleusLimits.
GetZMin())
230 DecayTableMap::iterator table_ptr =
dkmap->find(key);
233 if (table_ptr ==
dkmap->end() ) {
235 if(theDecayTable) (*dkmap)[key] = theDecayTable;
237 theDecayTable = table_ptr->second;
239 return theDecayTable;
248 for (
size_t i = 0; i < theLogicalVolumes->size(); i++) {
249 volume = (*theLogicalVolumes)[i];
250 if (volume->
GetName() == aVolume) {
256 G4cout <<
" Radioactive decay applied to " << aVolume <<
G4endl;
258 }
else if (i == theLogicalVolumes->size() ) {
260 ed << aVolume <<
" is not a valid logical volume name. Decay not activated for it."
262 G4Exception(
"G4RadioactiveDecayBase::SelectAVolume()",
"HAD_RDM_300",
274 for (
size_t i = 0; i < theLogicalVolumes->size(); i++) {
275 volume = (*theLogicalVolumes)[i];
276 if (volume->
GetName() == aVolume) {
277 std::vector<G4String>::iterator location;
284 G4cout <<
" G4RadioactiveDecay::DeselectAVolume: " << aVolume
285 <<
" is removed from list " <<
G4endl;
288 ed << aVolume <<
" is not in the list. No action taken." <<
G4endl;
289 G4Exception(
"G4RadioactiveDecayBase::DeselectAVolume()",
"HAD_RDM_300",
292 }
else if (i == theLogicalVolumes->size()) {
294 ed << aVolume <<
" is not a valid logical volume name. No action taken."
296 G4Exception(
"G4RadioactiveDecayBase::DeselectAVolume()",
"HAD_RDM_300",
313 for (
size_t i = 0; i < theLogicalVolumes->size(); i++){
314 volume = (*theLogicalVolumes)[i];
352 G4cout <<
"G4RadioactiveDecay::GetMeanLifeTime() " <<
G4endl;
354 <<
" GeV, Mass: " << theParticle->
GetMass()/GeV
355 <<
" GeV, Life time: " << theLife/
ns <<
" ns " <<
G4endl;
359 else if (theLife < 0.0) {meanlife =
DBL_MAX;}
360 else {meanlife = theLife;}
363 if (((
const G4Ions*)(theParticleDef))->GetExcitationEnergy() > 0. &&
364 meanlife ==
DBL_MAX) {meanlife = 0.;}
367 G4cout <<
" mean life time: " << meanlife/s <<
" s " <<
G4endl;
389 G4cout <<
"G4RadioactiveDecay::GetMeanFreePath() " <<
G4endl;
391 <<
" GeV, Mass: " << aMass/GeV <<
" GeV, tau: " << tau <<
" ns "
402 }
else if (tau < 0.0) {
405 ed <<
"Ion has negative lifetime " << tau
406 <<
" but is not stable. Setting mean free path to DBL_MAX" <<
G4endl;
407 G4Exception(
"G4RadioactiveDecay::GetMeanFreePath()",
"HAD_RDM_011",
414 pathlength = c_light*tau*betaGamma;
420 G4cout <<
"G4Decay::GetMeanFreePath: "
422 <<
" stops, kinetic energy = "
432 G4cout <<
"mean free path: "<< pathlength/m <<
" m" <<
G4endl;
446 if (!isInitialised) {
447 isInitialised =
true;
464G4RadioactiveDecayBase::StreamInfo(std::ostream& os,
const G4String& endline)
470 G4int prec = os.precision(5);
471 os <<
"======================================================================"
473 os <<
"====== Radioactive Decay Physics Parameters ======="
475 os <<
"======================================================================"
477 os <<
"Max life time "
479 os <<
"Internal e- conversion flag "
481 os <<
"Stored internal conversion coefficients "
483 os <<
"Enable correlated gamma emission "
485 os <<
"Max 2J for sampling of angular correlations "
487 os <<
"Atomic de-excitation enabled "
488 << emparam->
Fluo() << endline;
489 os <<
"Auger electron emission enabled "
490 << emparam->
Auger() << endline;
491 os <<
"Auger cascade enabled "
493 os <<
"Check EM cuts disabled for atomic de-excitation "
495 os <<
"Use Bearden atomic level energies "
497 os <<
"======================================================================"
515 G4int A = ((
const G4Ions*)(&theParentNucleus))->GetAtomicMass();
516 G4int Z = ((
const G4Ions*)(&theParentNucleus))->GetAtomicNumber();
518 G4double levelEnergy = ((
const G4Ions*)(&theParentNucleus))->GetExcitationEnergy();
520 ((
const G4Ions*)(&theParentNucleus))->GetFloatLevelBase();
522#ifdef G4MULTITHREADED
523 G4AutoLock lk(&G4RadioactiveDecayBase::radioactiveDecayMutex);
526 DecayTableMap::iterator master_table_ptr = master_dkmap->find(key);
528 if (master_table_ptr != master_dkmap->end() ) {
529 return master_table_ptr->second;
534 G4String file = theUserRadioactiveDataFiles[1000*
A+Z];
537 std::ostringstream os;
538 os << dirPath <<
"/z" << Z <<
".a" <<
A <<
'\0';
545 std::ifstream DecaySchemeFile;
546 DecaySchemeFile.open(file);
548 if (DecaySchemeFile.good()) {
551 const G4int nMode = 12;
552 G4double modeTotalBR[nMode] = {0.0};
554 for (
G4int i = 0; i < nMode; i++) {
558 char inputChars[120]={
' '};
579 while (!complete && !DecaySchemeFile.getline(inputChars, 120).eof()) {
582 G4Exception(
"G4RadioactiveDecay::LoadDecayTable()",
"HAD_RDM_100",
587 inputLine = inputChars;
588 inputLine = inputLine.
strip(1);
589 if (inputChars[0] !=
'#' && inputLine.length() != 0) {
590 std::istringstream tmpStream(inputLine);
592 if (inputChars[0] ==
'P') {
595 tmpStream >> recordType >> parentExcitation >> floatingFlag >> dummy;
603 found = (std::abs(parentExcitation*keV - levelEnergy) <
levelTolerance);
604 if (floatingLevel !=
noFloat) {
607 if (!floatMatch) found =
false;
616 if (inputLine.length() < 72) {
617 tmpStream >> theDecayMode >> dummy >> decayModeTotal;
618 switch (theDecayMode) {
624 anITChannel->
SetARM(applyARM);
625 theDecayTable->
Insert(anITChannel);
630 modeTotalBR[1] = decayModeTotal;
break;
632 modeTotalBR[2] = decayModeTotal;
break;
634 modeTotalBR[3] = decayModeTotal;
break;
636 modeTotalBR[4] = decayModeTotal;
break;
638 modeTotalBR[5] = decayModeTotal;
break;
640 modeTotalBR[6] = decayModeTotal;
break;
642 modeTotalBR[7] = decayModeTotal;
break;
644 modeTotalBR[8] = decayModeTotal;
break;
646 modeTotalBR[9] = decayModeTotal;
break;
660 modeTotalBR[10] = decayModeTotal;
break;
662 modeTotalBR[11] = decayModeTotal;
break;
666 G4Exception(
"G4RadioactiveDecay::LoadDecayTable()",
"HAD_RDM_000",
671 if (inputLine.length() < 84) {
672 tmpStream >> theDecayMode >> a >> daughterFloatFlag >> b >> c;
675 tmpStream >> theDecayMode >> a >> daughterFloatFlag >> b >> c >> betaType;
685 switch (theDecayMode) {
690 daughterFloatLevel, betaType);
693 theDecayTable->
Insert(aBetaMinusChannel);
702 daughterFloatLevel, betaType);
705 theDecayTable->
Insert(aBetaPlusChannel);
713 new G4ECDecay(&theParentNucleus, b, c*MeV, a*MeV,
717 aKECChannel->
SetARM(applyARM);
718 theDecayTable->
Insert(aKECChannel);
726 new G4ECDecay(&theParentNucleus, b, c*MeV, a*MeV,
730 aLECChannel->
SetARM(applyARM);
731 theDecayTable->
Insert(aLECChannel);
739 new G4ECDecay(&theParentNucleus, b, c*MeV, a*MeV,
743 aMECChannel->
SetARM(applyARM);
744 theDecayTable->
Insert(aMECChannel);
752 new G4ECDecay(&theParentNucleus, b, c*MeV, a*MeV,
756 aNECChannel->
SetARM(applyARM);
757 theDecayTable->
Insert(aNECChannel);
769 theDecayTable->
Insert(anAlphaChannel);
781 theDecayTable->
Insert(aProtonChannel);
793 theDecayTable->
Insert(aNeutronChannel);
826 new G4SFDecay(&theParentNucleus, b, c*MeV, a*MeV,
828 theDecayTable->
Insert(aSpontFissChannel);
839 theDecayTable->
Insert(aTritonChannel);
847 G4Exception(
"G4RadioactiveDecay::LoadDecayTable()",
"HAD_RDM_000",
865 theNuclearDecayChannel =
static_cast<G4NuclearDecay*
>(theChannel);
868 if (theDecayMode !=
IT) {
869 theBR = theChannel->
GetBR();
870 theChannel->
SetBR(theBR*modeTotalBR[theDecayMode]/modeSumBR[theDecayMode]);
875 DecaySchemeFile.close();
877 if (!found && levelEnergy > 0) {
883 anITChannel->
SetARM(applyARM);
884 theDecayTable->
Insert(anITChannel);
891#ifdef G4MULTITHREADED
894 return theDecayTable;
900 if (Z < 1 ||
A < 2)
G4cout <<
"Z and A not valid!" <<
G4endl;
902 std::ifstream DecaySchemeFile(filename);
903 if (DecaySchemeFile) {
904 G4int ID_ion =
A*1000 + Z;
905 theUserRadioactiveDataFiles[ID_ion] = filename;
908 ed << filename <<
" does not exist! " <<
G4endl;
909 G4Exception(
"G4RadioactiveDecayBase::AddUserDecayDataFile()",
"HAD_RDM_001",
935 G4cout <<
"G4RadioactiveDecay::DecayIt : "
937 <<
" is not selected for the RDM"<<
G4endl;
959 G4cout <<
"G4RadioactiveDecay::DecayIt : "
961 <<
" is not an ion or is outside (Z,A) limits set for the decay. "
962 <<
" Set particle change accordingly. "
977 if (theDecayTable == 0 || theDecayTable->
entries() == 0) {
982 G4cout <<
"G4RadioactiveDecay::DecayIt : "
983 <<
"decay table not defined for "
985 <<
". Set particle change accordingly. "
1096 if (products->
entries() == 1) {
1128 if (temptime < 0.) temptime = 0.;
1129 finalGlobalTime += temptime;
1130 finalLocalTime += temptime;
1133 products->
Boost(ParentEnergy, ParentDirection);
1140 G4cout <<
"G4RadioactiveDecay::DecayAnalog: Decay vertex :";
1141 G4cout <<
" Time: " << finalGlobalTime/
ns <<
"[ns]";
1146 G4cout <<
"G4Decay::DecayIt : decay products in Lab. Frame" <<
G4endl;
1151 for (
G4int index = 0; index < numberOfSecondaries; index++) {
1156 if (theRadDecayMode ==
IT && index>0){
1161 && index <numberOfSecondaries-1){
1194 if (theDecayChannel == 0) {
1198 G4Exception(
"G4RadioactiveDecay::DoDecay",
"HAD_RDM_013",
1204 G4cout <<
"G4RadioactiveDecay::DoIt : selected decay channel addr: "
1205 << theDecayChannel <<
G4endl;
1208 theRadDecayMode = (
static_cast<G4NuclearDecay*
>(theDecayChannel))->GetDecayMode();
1222 if (origin == forceDecayDirection)
return;
1223 if (180.*deg == forceDecayHalfAngle)
return;
1224 if (0 == products || 0 == products->
entries())
return;
1244 if (daughterType == electron || daughterType == positron ||
1245 daughterType == neutron || daughterType == gamma ||
1246 daughterType == alpha || daughterType == triton || daughterType == proton)
CollimateDecayProduct(daughter);
1253 G4cout <<
"CollimateDecayProduct for daughter "
1266 if (origin == forceDecayDirection)
return origin;
1267 if (forceDecayHalfAngle == 180.*deg)
return origin;
1272 if (forceDecayHalfAngle > 0.) {
1275 G4double cosMin = std::cos(forceDecayHalfAngle);
1284 G4cout <<
" ChooseCollimationDirection returns " << dir <<
G4endl;
double A(double temperature)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
std::map< G4String, G4DecayTable * > DecayTableMap
std::map< G4String, G4DecayTable * > DecayTableMap
#define G4MUTEX_INITIALIZER
G4GLOB_DLL std::ostream G4cout
static G4Alpha * Definition()
G4DynamicParticle * PopProducts()
void Boost(G4double totalEnergy, const G4ThreeVector &momentumDirection)
G4VDecayChannel * GetDecayChannel(G4int index) const
void Insert(G4VDecayChannel *aChannel)
G4VDecayChannel * SelectADecayChannel(G4double parentMass=-1.)
G4bool CorrelatedGamma() const
G4bool StoreICLevelData() const
G4double GetMaxLifeTime() const
G4bool GetInternalConversionFlag() const
void SetMomentumDirection(const G4ThreeVector &aDirection)
const G4ThreeVector & GetMomentumDirection() const
const G4ParticleDefinition * GetParticleDefinition() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
G4double GetTotalMomentum() const
void SetARM(G4bool onoff)
static G4Electron * Definition()
static G4EmParameters * Instance()
G4bool BeardenFluoDir() const
G4bool AugerCascade() const
G4bool DeexcitationIgnoreCut() const
static G4Gamma * Definition()
static G4GenericIon * GenericIon()
static G4HadronicParameters * Instance()
void RegisterExtraProcess(G4VProcess *)
void RegisterParticleForExtraProcess(G4VProcess *, const G4ParticleDefinition *)
static G4HadronicProcessStore * Instance()
void SetARM(G4bool onoff)
static G4Ions::G4FloatLevelBase FloatLevelBase(char flbChar)
static G4LogicalVolumeStore * GetInstance()
const G4String & GetName() const
static G4Neutron * Definition()
G4RadioactiveDecayMode GetDecayMode()
G4DeexPrecoParameters * GetParameters()
static G4NuclearLevelData * GetInstance()
void ProposeLocalTime(G4double t)
virtual void Initialize(const G4Track &)
void AddSecondary(G4Track *aSecondary)
G4bool GetPDGStable() const
const G4String & GetParticleType() const
G4double GetPDGMass() const
G4double GetPDGLifeTime() const
const G4String & GetParticleName() const
virtual void SetICM(G4bool)
virtual void RDMForced(G4bool)
static G4Positron * Definition()
static G4Proton * Definition()
void CollimateDecay(G4DecayProducts *products)
void AddUserDecayDataFile(G4int Z, G4int A, G4String filename)
std::vector< G4String > ValidVolumes
G4int GetVerboseLevel() const
G4bool IsApplicable(const G4ParticleDefinition &)
void DeselectAVolume(const G4String aVolume)
G4double GetMeanLifeTime(const G4Track &theTrack, G4ForceCondition *condition)
G4DecayTable * LoadDecayTable(const G4ParticleDefinition &theParentNucleus)
void SelectAVolume(const G4String aVolume)
void DecayAnalog(const G4Track &theTrack)
G4double GetMeanFreePath(const G4Track &theTrack, G4double previousStepSize, G4ForceCondition *condition)
static const G4double levelTolerance
G4VParticleChange * DecayIt(const G4Track &theTrack, const G4Step &theStep)
G4ThreeVector ChooseCollimationDirection() const
~G4RadioactiveDecayBase()
void CollimateDecayProduct(G4DynamicParticle *product)
G4DecayProducts * DoDecay(const G4ParticleDefinition &theParticleDef)
G4DecayTable * GetDecayTable(const G4ParticleDefinition *)
virtual void ProcessDescription(std::ostream &outFile) const
G4ParticleChangeForRadDecay fParticleChangeForRadDecay
void BuildPhysicsTable(const G4ParticleDefinition &)
G4PhotonEvaporation * photonEvaporation
void DeselectAllVolumes()
G4RadioactiveDecayBase(const G4String &processName="RadioactiveDecayBase")
G4RadioactiveDecayBaseMessenger * theRadioactiveDecayBaseMessenger
G4String strip(G4int strip_Type=trailing, char c=' ')
G4TrackStatus GetTrackStatus() const
G4VPhysicalVolume * GetVolume() const
G4double GetWeight() const
const G4ThreeVector & GetPosition() const
void SetTouchableHandle(const G4TouchableHandle &apValue)
G4double GetGlobalTime() const
G4double GetLocalTime() const
const G4DynamicParticle * GetDynamicParticle() const
const G4TouchableHandle & GetTouchableHandle() const
void SetCreatorModelIndex(G4int idx)
void SetGoodForTrackingFlag(G4bool value=true)
static G4Triton * Definition()
void SetBR(G4double value)
virtual G4DecayProducts * DecayIt(G4double parentMass=-1.0)=0
void ProposeTrackStatus(G4TrackStatus status)
void ProposeWeight(G4double finalWeight)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
void SetNumberOfSecondaries(G4int totSecondaries)
G4LogicalVolume * GetLogicalVolume() const
void ClearNumberOfInteractionLengthLeft()
void SetProcessSubType(G4int)
G4VParticleChange * pParticleChange