Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/radioactive_decay/src/G4VRadioactiveDecay.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /processes/hadronic/models/radioactive_decay/src/G4VRadioactiveDecay.cc (Version 11.3.0) and /processes/hadronic/models/radioactive_decay/src/G4VRadioactiveDecay.cc (Version 10.6)


  1 //                                                  1 
  2 // *******************************************    
  3 // * License and Disclaimer                       
  4 // *                                              
  5 // * The  Geant4 software  is  copyright of th    
  6 // * the Geant4 Collaboration.  It is provided    
  7 // * conditions of the Geant4 Software License    
  8 // * LICENSE and available at  http://cern.ch/    
  9 // * include a list of copyright holders.         
 10 // *                                              
 11 // * Neither the authors of this software syst    
 12 // * institutes,nor the agencies providing fin    
 13 // * work  make  any representation or  warran    
 14 // * regarding  this  software system or assum    
 15 // * use.  Please see the license in the file     
 16 // * for the full disclaimer and the limitatio    
 17 // *                                              
 18 // * This  code  implementation is the result     
 19 // * technical work of the GEANT4 collaboratio    
 20 // * By using,  copying,  modifying or  distri    
 21 // * any work based  on the software)  you  ag    
 22 // * use  in  resulting  scientific  publicati    
 23 // * acceptance of all terms of the Geant4 Sof    
 24 // *******************************************    
 25 //                                                
 26 //////////////////////////////////////////////    
 27 //                                                
 28 //  GEANT4 Class source file                      
 29 //                                                
 30 //  G4VRadioactiveDecay                           
 31 //                                                
 32 //  Author: D.H. Wright (SLAC)                    
 33 //  Date:   9 August 2017                         
 34 //                                                
 35 //  Based on the code of F. Lei and P.R. Trusc    
 36 //                                                
 37 //////////////////////////////////////////////    
 38                                                   
 39 #include "G4VRadioactiveDecay.hh"                 
 40 #include "G4RadioactiveDecayMessenger.hh"         
 41                                                   
 42 #include "G4SystemOfUnits.hh"                     
 43 #include "G4UnitsTable.hh"                        
 44 #include "G4NuclideTable.hh"                      
 45 #include "G4DynamicParticle.hh"                   
 46 #include "G4DecayProducts.hh"                     
 47 #include "G4DecayTable.hh"                        
 48 #include "G4ParticleChangeForRadDecay.hh"         
 49 #include "G4ITDecay.hh"                           
 50 #include "G4BetaDecayType.hh"                     
 51 #include "G4BetaMinusDecay.hh"                    
 52 #include "G4BetaPlusDecay.hh"                     
 53 #include "G4ECDecay.hh"                           
 54 #include "G4AlphaDecay.hh"                        
 55 #include "G4TritonDecay.hh"                       
 56 #include "G4ProtonDecay.hh"                       
 57 #include "G4NeutronDecay.hh"                      
 58 #include "G4SFDecay.hh"                           
 59 #include "G4VDecayChannel.hh"                     
 60 #include "G4NuclearDecay.hh"                      
 61 #include "G4RadioactiveDecayMode.hh"              
 62 #include "G4Fragment.hh"                          
 63 #include "G4Ions.hh"                              
 64 #include "G4IonTable.hh"                          
 65 #include "G4BetaDecayType.hh"                     
 66 #include "Randomize.hh"                           
 67 #include "G4LogicalVolumeStore.hh"                
 68 #include "G4NuclearLevelData.hh"                  
 69 #include "G4DeexPrecoParameters.hh"               
 70 #include "G4LevelManager.hh"                      
 71 #include "G4ThreeVector.hh"                       
 72 #include "G4Electron.hh"                          
 73 #include "G4Positron.hh"                          
 74 #include "G4Neutron.hh"                           
 75 #include "G4Gamma.hh"                             
 76 #include "G4Alpha.hh"                             
 77 #include "G4Triton.hh"                            
 78 #include "G4Proton.hh"                            
 79                                                   
 80 #include "G4HadronicProcessType.hh"               
 81 #include "G4HadronicProcessStore.hh"              
 82 #include "G4HadronicException.hh"                 
 83 #include "G4LossTableManager.hh"                  
 84 #include "G4VAtomDeexcitation.hh"                 
 85 #include "G4UAtomicDeexcitation.hh"               
 86 #include "G4PhotonEvaporation.hh"                 
 87 #include "G4HadronicParameters.hh"                
 88                                                   
 89 #include "G4PhysicsModelCatalog.hh"               
 90 #include "G4AutoLock.hh"                          
 91                                                   
 92 #include <vector>                                 
 93 #include <sstream>                                
 94 #include <algorithm>                              
 95 #include <fstream>                                
 96                                                   
 97 using namespace CLHEP;                            
 98                                                   
 99 const G4double G4VRadioactiveDecay::levelToler    
100 const G4ThreeVector G4VRadioactiveDecay::origi    
101                                                   
102 DecayTableMap* G4VRadioactiveDecay::master_dkm    
103 std::map<G4int, G4String>* G4VRadioactiveDecay    
104 G4String G4VRadioactiveDecay::dirPath = "";       
105                                                   
106 namespace                                         
107 {                                                 
108   G4Mutex radioactiveDecayMutex = G4MUTEX_INIT    
109 }                                                 
110                                                   
111 G4VRadioactiveDecay::G4VRadioactiveDecay(const    
112                                          const    
113  : G4VRestDiscreteProcess(processName, fDecay)    
114    fThresholdForVeryLongDecayTime( 1.0*CLHEP::    
115 {                                                 
116   if (GetVerboseLevel() > 1) {                    
117     G4cout << "G4VRadioactiveDecay constructor    
118            << G4endl;                             
119   }                                               
120                                                   
121   SetProcessSubType(fRadioactiveDecay);           
122                                                   
123   theRadioactiveDecayMessenger = new G4Radioac    
124   pParticleChange = &fParticleChangeForRadDeca    
125                                                   
126   // Check data directory                         
127   if (dirPath.empty()) {                          
128     const char* path_var = G4FindDataDir("G4RA    
129     if (nullptr == path_var) {                    
130       G4Exception("G4VRadioactiveDecay()", "HA    
131                   "Environment variable G4RADI    
132     } else {                                      
133       dirPath = path_var;   // convert to stri    
134       std::ostringstream os;                      
135       os << dirPath << "/z1.a3";   // used as     
136       std::ifstream testFile;                     
137       testFile.open(os.str() );                   
138       if ( !testFile.is_open() )                  
139         G4Exception("G4VRadioactiveDecay()","H    
140                     "Environment variable G4RA    
141     }                                             
142   }                                               
143   // Set up photon evaporation for use in G4IT    
144   photonEvaporation = new G4PhotonEvaporation(    
145   photonEvaporation->RDMForced(true);             
146   photonEvaporation->SetICM(true);                
147   decayIT = new G4ITDecay(photonEvaporation);     
148                                                   
149   // Instantiate the map of decay tables          
150   if (nullptr == master_dkmap) {                  
151     master_dkmap = new DecayTableMap();           
152   }                                               
153   if (nullptr == theUserRDataFiles) {             
154     theUserRDataFiles = new std::map<G4int, G4    
155   }                                               
156                                                   
157   // RDM applies to all logical volumes by def    
158   SelectAllVolumes();                             
159   G4HadronicProcessStore::Instance()->Register    
160                                                   
161   // The time threshold for radioactive decays    
162   // 1. Via C++ interface: G4HadronicParameter    
163   // 2. Via the second parameter of the G4VRad    
164   // 3. Via UI command: /process/had/rdm/thres    
165   // If both 1. and 2. are specified (at the m    
166   // then we take the larger value, to be cons    
167   // If, later on (after invoking the G4VRadio    
168   // then this value is used (and the eventual    
169   G4double timeThresholdBis = G4HadronicParame    
170   if ( timeThreshold > 0.0 || timeThresholdBis    
171     if ( timeThreshold > timeThresholdBis ) ti    
172     fThresholdForVeryLongDecayTime = timeThres    
173   }                                               
174 }                                                 
175                                                   
176 G4VRadioactiveDecay::~G4VRadioactiveDecay()       
177 {                                                 
178   delete theRadioactiveDecayMessenger;            
179   delete photonEvaporation;                       
180   delete decayIT;                                 
181   if (nullptr != master_dkmap) {                  
182     G4AutoLock lk(&radioactiveDecayMutex);        
183     if (nullptr != master_dkmap) {                
184       for (auto const & i : *master_dkmap) {      
185   delete i.second;                                
186       }                                           
187       master_dkmap->clear();                      
188       delete master_dkmap;                        
189       master_dkmap = nullptr;                     
190     }                                             
191     delete theUserRDataFiles;                     
192     theUserRDataFiles = nullptr;                  
193     lk.unlock();                                  
194   }                                               
195 }                                                 
196                                                   
197                                                   
198 G4bool G4VRadioactiveDecay::IsApplicable(const    
199 {                                                 
200   const G4String& pname = aParticle.GetParticl    
201   if (pname == "GenericIon" || pname == "trito    
202   // All particles other than G4Ions, are reje    
203   const G4Ions* p = dynamic_cast<const G4Ions*    
204   if (nullptr == p) { return false; }             
205                                                   
206   // excited isomere may decay via gamma evapo    
207   if (p->GetExcitationEnergy() > 0.0) { return    
208                                                   
209   // Check on life time                           
210   G4double lifeTime = p->GetPDGLifeTime();        
211   if (lifeTime < 0.0 || lifeTime > fThresholdF    
212     return false;                                 
213   }                                               
214                                                   
215   // Determine whether the nuclide falls into     
216   G4int A = p->GetAtomicMass();                   
217   G4int Z = p->GetAtomicNumber();                 
218                                                   
219   if (A > theNucleusLimits.GetAMax() || A < th    
220       Z > theNucleusLimits.GetZMax() || Z < th    
221     return false;                                 
222   }                                               
223                                                   
224   return true;                                    
225 }                                                 
226                                                   
227                                                   
228 G4VParticleChange* G4VRadioactiveDecay::AtRest    
229                                                   
230 {                                                 
231   return DecayIt(theTrack, theStep);              
232 }                                                 
233                                                   
234                                                   
235 G4VParticleChange* G4VRadioactiveDecay::PostSt    
236                                                   
237 {                                                 
238   return DecayIt(theTrack, theStep);              
239 }                                                 
240                                                   
241                                                   
242 void G4VRadioactiveDecay::ProcessDescription(s    
243 {                                                 
244   outFile << "The radioactive decay process (G    
245           << "alpha, beta+, beta-, electron ca    
246           << "decays of nuclei (G4GenericIon)     
247           << "The required half-lives and deca    
248           << "the RadioactiveDecay database wh    
249 }                                                 
250                                                   
251                                                   
252                                                   
253                                                   
254 G4DecayTable* G4VRadioactiveDecay::GetDecayTab    
255 {                                                 
256   G4String key = aNucleus->GetParticleName();     
257   auto ptr = master_dkmap->find(key);             
258                                                   
259   G4DecayTable* theDecayTable = nullptr;          
260   if ( ptr == master_dkmap->end() ) {             
261     // Load new file if table not there           
262     const G4Ions* ion = dynamic_cast<const G4I    
263     if (nullptr != ion) {                         
264       theDecayTable = LoadDecayTable(ion);        
265     }                                             
266   } else {                                        
267     theDecayTable = ptr->second;                  
268   }                                               
269   return theDecayTable;                           
270 }                                                 
271                                                   
272                                                   
273 void G4VRadioactiveDecay::SelectAVolume(const     
274 {                                                 
275   G4LogicalVolumeStore* theLogicalVolumes = G4    
276   G4LogicalVolume* volume = nullptr;              
277   volume = theLogicalVolumes->GetVolume(aVolum    
278   if (volume != nullptr)                          
279   {                                               
280     ValidVolumes.push_back(aVolume);              
281     std::sort(ValidVolumes.begin(), ValidVolum    
282     // sort need for performing binary_search     
283                                                   
284     if (GetVerboseLevel() > 0)                    
285       G4cout << " Radioactive decay applied to    
286   }                                               
287   else                                            
288   {                                               
289     G4ExceptionDescription ed;                    
290     ed << aVolume << " is not a valid logical     
291        << " Decay not activated for it."          
292        << G4endl;                                 
293     G4Exception("G4VRadioactiveDecay::SelectAV    
294                 JustWarning, ed);                 
295   }                                               
296 }                                                 
297                                                   
298                                                   
299 void G4VRadioactiveDecay::DeselectAVolume(cons    
300 {                                                 
301   G4LogicalVolumeStore* theLogicalVolumes = G4    
302   G4LogicalVolume* volume = nullptr;              
303   volume = theLogicalVolumes->GetVolume(aVolum    
304   if (volume != nullptr)                          
305   {                                               
306     auto location= std::find(ValidVolumes.cbeg    
307     if (location != ValidVolumes.cend() )         
308     {                                             
309       ValidVolumes.erase(location);               
310       std::sort(ValidVolumes.begin(), ValidVol    
311       isAllVolumesMode = false;                   
312       if (GetVerboseLevel() > 0)                  
313         G4cout << " G4VRadioactiveDecay::Desel    
314                << " is removed from list " <<     
315     }                                             
316     else                                          
317     {                                             
318       G4ExceptionDescription ed;                  
319       ed << aVolume << " is not in the list.      
320       G4Exception("G4VRadioactiveDecay::Desele    
321                   JustWarning, ed);               
322     }                                             
323   }                                               
324   else                                            
325   {                                               
326     G4ExceptionDescription ed;                    
327     ed << aVolume << " is not a valid logical     
328        << G4endl;                                 
329     G4Exception("G4VRadioactiveDecay::Deselect    
330                 JustWarning, ed);                 
331   }                                               
332 }                                                 
333                                                   
334                                                   
335 void G4VRadioactiveDecay::SelectAllVolumes()      
336 {                                                 
337   G4LogicalVolumeStore* theLogicalVolumes = G4    
338   G4LogicalVolume* volume = nullptr;              
339   ValidVolumes.clear();                           
340 #ifdef G4VERBOSE                                  
341   if (GetVerboseLevel()>1)                        
342     G4cout << " RDM Applies to all Volumes"  <    
343 #endif                                            
344   for (std::size_t i = 0; i < theLogicalVolume    
345     volume = (*theLogicalVolumes)[i];             
346     ValidVolumes.push_back(volume->GetName());    
347 #ifdef G4VERBOSE                                  
348     if (GetVerboseLevel()>1)                      
349       G4cout << "       RDM Applies to Volume     
350 #endif                                            
351   }                                               
352   std::sort(ValidVolumes.begin(), ValidVolumes    
353   // sort needed in order to allow binary_sear    
354   isAllVolumesMode=true;                          
355 }                                                 
356                                                   
357                                                   
358 void G4VRadioactiveDecay::DeselectAllVolumes()    
359 {                                                 
360   ValidVolumes.clear();                           
361   isAllVolumesMode=false;                         
362 #ifdef G4VERBOSE                                  
363   if (GetVerboseLevel() > 1) G4cout << "RDM re    
364 #endif                                            
365 }                                                 
366                                                   
367                                                   
368 //  GetMeanLifeTime (required by the base clas    
369 G4double G4VRadioactiveDecay::GetMeanLifeTime(    
370                                              G    
371 {                                                 
372   G4double meanlife = DBL_MAX;                    
373   const G4ParticleDefinition* theParticleDef =    
374   if (!IsApplicable(*theParticleDef)) { return    
375   G4double theLife = theParticleDef->GetPDGLif    
376 #ifdef G4VERBOSE                                  
377   if (GetVerboseLevel() > 2) {                    
378     G4cout << "G4VRadioactiveDecay::GetMeanLif    
379      << theParticleDef->GetParticleName() << G    
380     G4cout << "KineticEnergy(GeV)=" << theTrac    
381            << " Mass(GeV)=" << theParticleDef-    
382            << " LifeTime(ns)=" << theLife/CLHE    
383   }                                               
384 #endif                                            
385   if (theLife >= 0.0 && theLife <= fThresholdF    
386     meanlife = theLife;                           
387   }                                               
388                                                   
389   if (meanlife == DBL_MAX) {                      
390     const G4Ions* ion = dynamic_cast<const G4I    
391     if (nullptr != ion && ion->GetExcitationEn    
392       meanlife = 0.0;                             
393     }                                             
394   }                                               
395                                                   
396 #ifdef G4VERBOSE                                  
397   if (GetVerboseLevel() > 2)                      
398     G4cout << "G4VRadioactiveDecay::GetMeanLif    
399      << meanlife/CLHEP::s << " second " << G4e    
400 #endif                                            
401                                                   
402   return meanlife;                                
403 }                                                 
404                                                   
405                                                   
406 //////////////////////////////////////////////    
407 //                                                
408 //  GetMeanFreePath for decay in flight           
409 //                                                
410 //////////////////////////////////////////////    
411                                                   
412 G4double G4VRadioactiveDecay::GetMeanFreePath(    
413                                              G    
414 {                                                 
415   G4double res = DBL_MAX;                         
416   G4double lifeTime = GetMeanLifeTime(aTrack,     
417   if (lifeTime > 0.0 && lifeTime < DBL_MAX) {     
418     auto dParticle = aTrack.GetDynamicParticle    
419     res = lifeTime*dParticle->GetTotalEnergy()    
420   } else {                                        
421     res = lifeTime;                               
422   }                                               
423                                                   
424 #ifdef G4VERBOSE                                  
425   if (GetVerboseLevel() > 2) {                    
426     G4cout << "G4VRadioactiveDecay::GetMeanFre    
427      << aTrack.GetDefinition()->GetParticleNam    
428     G4cout << "  kinEnergy(GeV)=" << aTrack.Ge    
429            << " lifeTime(ns)=" << lifeTime        
430            << " mean free path(cm)=" << res/CL    
431   }                                               
432 #endif                                            
433   return res;                                     
434 }                                                 
435                                                   
436 //////////////////////////////////////////////    
437 //                                                
438 //  BuildPhysicsTable - initialization of atom    
439 //                                                
440 //////////////////////////////////////////////    
441                                                   
442 void G4VRadioactiveDecay::BuildPhysicsTable(co    
443 {                                                 
444   if (isInitialised) { return; }                  
445   isInitialised = true;                           
446   if (G4HadronicParameters::Instance()->GetVer    
447       G4Threading::IsMasterThread() && "Generi    
448     StreamInfo(G4cout, "\n");                     
449   }                                               
450   photonEvaporation->Initialise();                
451   photonEvaporation->RDMForced(true);             
452   photonEvaporation->SetICM(true);                
453   decayIT->SetARM(applyARM);                      
454                                                   
455   G4HadronicProcessStore::Instance()->Register    
456   G4HadronicProcessStore::Instance()->PrintInf    
457 }                                                 
458                                                   
459 //////////////////////////////////////////////    
460 //                                                
461 //  StreamInfo - stream out parameters            
462 //                                                
463 //////////////////////////////////////////////    
464                                                   
465 void                                              
466 G4VRadioactiveDecay::StreamInfo(std::ostream&     
467 {                                                 
468   G4DeexPrecoParameters* deex =                   
469     G4NuclearLevelData::GetInstance()->GetPara    
470   G4EmParameters* emparam = G4EmParameters::In    
471   G4double minMeanLife = G4NuclideTable::GetIn    
472                                                   
473   G4long prec = os.precision(5);                  
474   os << "=====================================    
475      << endline;                                  
476   os << "======          Radioactive Decay Phy    
477      << endline;                                  
478   os << "=====================================    
479      << endline;                                  
480   os << "min MeanLife (from G4NuclideTable)       
481      << G4BestUnit(minMeanLife, "Time") << end    
482   os << "Max life time (from G4DeexPrecoParame    
483      << G4BestUnit(deex->GetMaxLifeTime(), "Ti    
484   os << "Internal e- conversion flag              
485      << deex->GetInternalConversionFlag() << e    
486   os << "Stored internal conversion coefficien    
487      << deex->StoreICLevelData() << endline;      
488   os << "Enabled atomic relaxation mode           
489      << applyARM << endline;                      
490   os << "Enable correlated gamma emission         
491      << deex->CorrelatedGamma() << endline;       
492   os << "Max 2J for sampling of angular correl    
493      << deex->GetTwoJMAX() << endline;            
494   os << "Atomic de-excitation enabled             
495      << emparam->Fluo() << endline;               
496   os << "Auger electron emission enabled          
497      << emparam->Auger() << endline;              
498   os << "Check EM cuts disabled for atomic de-    
499      << emparam->DeexcitationIgnoreCut() << en    
500   os << "Use Bearden atomic level energies        
501      << emparam->BeardenFluoDir() << endline;     
502   os << "Use ANSTO fluorescence model             
503      << emparam->ANSTOFluoDir() << endline;       
504   os << "Threshold for very long decay time at    
505      << G4BestUnit(fThresholdForVeryLongDecayT    
506   os << "=====================================    
507      << G4endl;                                   
508   os.precision(prec);                             
509 }                                                 
510                                                   
511                                                   
512 //////////////////////////////////////////////    
513 //                                                
514 //  LoadDecayTable loads the decay scheme from    
515 //  for the parent nucleus.                       
516 //                                                
517 //////////////////////////////////////////////    
518                                                   
519 G4DecayTable* G4VRadioactiveDecay::LoadDecayTa    
520 {                                                 
521   G4AutoLock lk(&radioactiveDecayMutex);          
522   const G4String key = theIon->GetParticleName    
523   auto dtptr = master_dkmap->find(key);           
524   if (dtptr != master_dkmap->end()) {             
525     lk.unlock();                                  
526     return dtptr->second;                         
527   }                                               
528                                                   
529   // Generate input data file name using Z and    
530   // file containing radioactive decay data.      
531   G4int A = theIon->GetAtomicMass();              
532   G4int Z = theIon->GetAtomicNumber();            
533                                                   
534   //G4cout << "LoadDecayTable for " << key <<     
535                                                   
536   G4double levelEnergy = theIon->GetExcitation    
537   G4Ions::G4FloatLevelBase floatingLevel = the    
538                                                   
539   //Check if data have been provided by the us    
540   G4String file;                                  
541   G4int ke = 1000*A + Z;                          
542   auto ptr = theUserRDataFiles->find(ke);         
543   if (ptr != theUserRDataFiles->end()) {          
544     file = ptr->second;                           
545   } else {                                        
546     std::ostringstream os;                        
547     os << dirPath << "/z" << Z << ".a" << A <<    
548     file = os.str();                              
549   }                                               
550                                                   
551   G4DecayTable* theDecayTable = new G4DecayTab    
552   G4bool found(false);     // True if energy l    
553                                                   
554   std::ifstream DecaySchemeFile;                  
555   DecaySchemeFile.open(file);                     
556                                                   
557   if (DecaySchemeFile.good()) {                   
558     // Initialize variables used for reading i    
559     G4bool floatMatch(false);                     
560     const G4int nMode = G4RadioactiveDecayMode    
561     G4double modeTotalBR[nMode] = {0.0};          
562     G4double modeSumBR[nMode];                    
563     for (G4int i = 0; i < nMode; ++i) {           
564       modeSumBR[i] = 0.0;                         
565     }                                             
566                                                   
567     char inputChars[120]={' '};                   
568     G4String inputLine;                           
569     G4String recordType("");                      
570     G4String floatingFlag("");                    
571     G4String daughterFloatFlag("");               
572     G4Ions::G4FloatLevelBase daughterFloatLeve    
573     G4RadioactiveDecayMode theDecayMode;          
574     G4double decayModeTotal(0.0);                 
575     G4double parentExcitation(0.0);               
576     G4double a(0.0);                              
577     G4double b(0.0);                              
578     G4double c(0.0);                              
579     G4double dummy(0.0);                          
580     G4BetaDecayType betaType(allowed);            
581                                                   
582     // Loop through each data file record unti    
583     // data relating to the nuclide of concern    
584                                                   
585     G4bool complete(false);  // bool insures o    
586                              // given parent e    
587     G4int loop = 0;                               
588     /* Loop checking, 01.09.2015, D.Wright */     
589     while (!complete && !DecaySchemeFile.getli    
590       loop++;                                     
591       if (loop > 100000) {                        
592         G4Exception("G4VRadioactiveDecay::Load    
593                     JustWarning, "While loop c    
594         break;                                    
595       }                                           
596                                                   
597       inputLine = inputChars;                     
598       G4StrUtil::rstrip(inputLine);               
599       if (inputChars[0] != '#' && inputLine.le    
600         std::istringstream tmpStream(inputLine    
601                                                   
602         if (inputChars[0] == 'P') {               
603           // Nucleus is a parent type.  Check     
604           // matches that of theParentNucleus     
605           tmpStream >> recordType >> parentExc    
606           // "dummy" takes the place of half-l    
607           //  Now read in from ENSDFSTATE in p    
608                                                   
609           if (found) {                            
610             complete = true;                      
611           } else {                                
612             // Take first level which matches     
613             found = (std::abs(parentExcitation    
614             if (floatingLevel != noFloat) {       
615               // If floating level specificed,    
616               floatMatch = (floatingLevel == G    
617               if (!floatMatch) found = false;     
618             }                                     
619           }                                       
620                                                   
621         } else if (found) {                       
622           // The right part of the radioactive    
623           // through it to determine the mode     
624                                                   
625           // Store for later the total decay p    
626           if (inputLine.length() < 72) {          
627             tmpStream >> theDecayMode >> dummy    
628                                                   
629             switch (theDecayMode) {               
630               case IT:                            
631                 {                                 
632       G4ITDecay* anITChannel = new G4ITDecay(t    
633       theDecayTable->Insert(anITChannel);         
634                 }                                 
635                 break;                            
636               case BetaMinus:                     
637                 modeTotalBR[BetaMinus] = decay    
638               case BetaPlus:                      
639                 modeTotalBR[BetaPlus] = decayM    
640               case KshellEC:                      
641                 modeTotalBR[KshellEC] = decayM    
642               case LshellEC:                      
643                 modeTotalBR[LshellEC] = decayM    
644               case MshellEC:                      
645                 modeTotalBR[MshellEC] = decayM    
646               case NshellEC:                      
647                 modeTotalBR[NshellEC] = decayM    
648               case Alpha:                         
649                 modeTotalBR[Alpha] = decayMode    
650               case Proton:                        
651                 modeTotalBR[Proton] = decayMod    
652               case Neutron:                       
653                 modeTotalBR[Neutron] = decayMo    
654               case SpFission:                     
655                 modeTotalBR[SpFission] = decay    
656               case BDProton:                      
657                 /* Not yet implemented */  bre    
658               case BDNeutron:                     
659                 /* Not yet implemented */  bre    
660               case Beta2Minus:                    
661                 /* Not yet implemented */  bre    
662               case Beta2Plus:                     
663                 /* Not yet implemented */  bre    
664               case Proton2:                       
665                 /* Not yet implemented */  bre    
666               case Neutron2:                      
667                 /* Not yet implemented */  bre    
668               case Triton:                        
669                 modeTotalBR[Triton] = decayMod    
670               case RDM_ERROR:                     
671                                                   
672               default:                            
673                 G4Exception("G4VRadioactiveDec    
674                             FatalException, "S    
675             }  // switch                          
676                                                   
677           } else {                                
678             if (inputLine.length() < 84) {        
679               tmpStream >> theDecayMode >> a >    
680               betaType = allowed;                 
681             } else {                              
682               tmpStream >> theDecayMode >> a >    
683             }                                     
684                                                   
685             // Allowed transitions are the def    
686             // indicated in the last column.      
687             a /= 1000.;                           
688             c /= 1000.;                           
689             b /= 100.;                            
690             daughterFloatLevel = G4Ions::Float    
691                                                   
692             switch (theDecayMode) {               
693               case BetaMinus:                     
694               {                                   
695                 G4BetaMinusDecay* aBetaMinusCh    
696                   new G4BetaMinusDecay(theIon,    
697                                        daughte    
698     //aBetaMinusChannel->DumpNuclearInfo();       
699                 theDecayTable->Insert(aBetaMin    
700     modeSumBR[BetaMinus] += b;                    
701               }                                   
702               break;                              
703                                                   
704               case BetaPlus:                      
705               {                                   
706                 G4BetaPlusDecay* aBetaPlusChan    
707                   new G4BetaPlusDecay(theIon,     
708                                       daughter    
709     //aBetaPlusChannel->DumpNuclearInfo();        
710                 theDecayTable->Insert(aBetaPlu    
711     modeSumBR[BetaPlus] += b;                     
712               }                                   
713               break;                              
714                                                   
715               case KshellEC:  // K-shell elect    
716               {                                   
717                 G4ECDecay* aKECChannel =          
718                   new G4ECDecay(theIon, b, c*M    
719                                 daughterFloatL    
720     //aKECChannel->DumpNuclearInfo();             
721                 aKECChannel->SetARM(applyARM);    
722                 theDecayTable->Insert(aKECChan    
723                 modeSumBR[KshellEC] += b;         
724               }                                   
725               break;                              
726                                                   
727               case LshellEC:  // L-shell elect    
728               {                                   
729                 G4ECDecay* aLECChannel =          
730                   new G4ECDecay(theIon, b, c*M    
731                                 daughterFloatL    
732 //              aLECChannel->DumpNuclearInfo()    
733                 aLECChannel->SetARM(applyARM);    
734                 theDecayTable->Insert(aLECChan    
735                 modeSumBR[LshellEC] += b;         
736               }                                   
737               break;                              
738                                                   
739               case MshellEC:  // M-shell elect    
740               {                                   
741                 G4ECDecay* aMECChannel =          
742                   new G4ECDecay(theIon, b, c*M    
743                                 daughterFloatL    
744 //              aMECChannel->DumpNuclearInfo()    
745                 aMECChannel->SetARM(applyARM);    
746                 theDecayTable->Insert(aMECChan    
747                 modeSumBR[MshellEC] += b;         
748               }                                   
749               break;                              
750                                                   
751               case NshellEC:  // N-shell elect    
752               {                                   
753                 G4ECDecay* aNECChannel =          
754                   new G4ECDecay(theIon, b, c*M    
755                                 daughterFloatL    
756 //              aNECChannel->DumpNuclearInfo()    
757                 aNECChannel->SetARM(applyARM);    
758                 theDecayTable->Insert(aNECChan    
759                 modeSumBR[NshellEC] += b;         
760               }                                   
761               break;                              
762                                                   
763               case Alpha:                         
764               {                                   
765                 G4AlphaDecay* anAlphaChannel =    
766                   new G4AlphaDecay(theIon, b,     
767                                    daughterFlo    
768 //              anAlphaChannel->DumpNuclearInf    
769                 theDecayTable->Insert(anAlphaC    
770                 modeSumBR[Alpha] += b;            
771               }                                   
772               break;                              
773                                                   
774         case Proton:                              
775               {                                   
776                 G4ProtonDecay* aProtonChannel     
777                   new G4ProtonDecay(theIon, b,    
778                                     daughterFl    
779 //              aProtonChannel->DumpNuclearInf    
780                 theDecayTable->Insert(aProtonC    
781                 modeSumBR[Proton] += b;           
782               }                                   
783               break;                              
784                                                   
785               case Neutron:                       
786               {                                   
787                 G4NeutronDecay* aNeutronChanne    
788                   new G4NeutronDecay(theIon, b    
789                                      daughterF    
790 //              aNeutronChannel->DumpNuclearIn    
791                 theDecayTable->Insert(aNeutron    
792                 modeSumBR[Neutron] += b;          
793               }                                   
794               break;                              
795                                                   
796               case SpFission:                     
797               {                                   
798                 G4SFDecay* aSpontFissChannel =    
799                   new G4SFDecay(theIon, b, c*M    
800                 theDecayTable->Insert(aSpontFi    
801                 modeSumBR[SpFission] += b;        
802               }                                   
803               break;                              
804                                                   
805               case BDProton:                      
806                   // Not yet implemented          
807                   // G4cout << " beta-delayed     
808                   break;                          
809                                                   
810               case BDNeutron:                     
811                   // Not yet implemented          
812                   // G4cout << " beta-delayed     
813                   break;                          
814                                                   
815               case Beta2Minus:                    
816                   // Not yet implemented          
817                   // G4cout << " Double beta-     
818                   break;                          
819                                                   
820               case Beta2Plus:                     
821                   // Not yet implemented          
822                   // G4cout << " Double beta+     
823                   break;                          
824                                                   
825               case Proton2:                       
826                   // Not yet implemented          
827                   // G4cout << " Double proton    
828                   break;                          
829                                                   
830               case Neutron2:                      
831                   // Not yet implemented          
832                   // G4cout << " Double beta-     
833                   break;                          
834                                                   
835               case Triton:                        
836                 {                                 
837       G4TritonDecay* aTritonChannel =             
838                     new G4TritonDecay(theIon,     
839       theDecayTable->Insert(aTritonChannel);      
840       modeSumBR[Triton] += b;                     
841                 }                                 
842               break;                              
843                                                   
844               case RDM_ERROR:                     
845                                                   
846               default:                            
847                 G4Exception("G4VRadioactiveDec    
848                             FatalException, "S    
849             }  // switch                          
850           }  // line < 72                         
851         }  // if char == P                        
852       }  // if char != #                          
853     }  // While                                   
854                                                   
855     // Go through the decay table and make sur    
856     // correctly normalised.                      
857                                                   
858     G4VDecayChannel* theChannel = 0;              
859     G4NuclearDecay* theNuclearDecayChannel = 0    
860     G4String mode = "";                           
861                                                   
862     G4double theBR = 0.0;                         
863     for (G4int i = 0; i < theDecayTable->entri    
864       theChannel = theDecayTable->GetDecayChan    
865       theNuclearDecayChannel = static_cast<G4N    
866       theDecayMode = theNuclearDecayChannel->G    
867                                                   
868       if (theDecayMode != IT) {                   
869   theBR = theChannel->GetBR();                    
870   theChannel->SetBR(theBR*modeTotalBR[theDecay    
871       }                                           
872     }                                             
873   }  // decay file exists                         
874                                                   
875   DecaySchemeFile.close();                        
876                                                   
877   if (!found && levelEnergy > 0) {                
878     // Case where IT cascade for excited isoto    
879     // Decay mode is isomeric transition.         
880     G4ITDecay* anITChannel = new G4ITDecay(the    
881     theDecayTable->Insert(anITChannel);           
882   }                                               
883                                                   
884   if (GetVerboseLevel() > 1) {                    
885     theDecayTable->DumpInfo();                    
886   }                                               
887                                                   
888   // store in master library                      
889   (*master_dkmap)[theIon->GetParticleName()] =    
890   lk.unlock();                                    
891   return theDecayTable;                           
892 }                                                 
893                                                   
894 void G4VRadioactiveDecay::AddUserDecayDataFile    
895                                                   
896 {                                                 
897   if (Z < 1 || A < 2) G4cout << "Z and A not v    
898                                                   
899   std::ifstream DecaySchemeFile(filename);        
900   if (DecaySchemeFile) {                          
901     G4int ID_ion = A*1000 + Z;                    
902     (*theUserRDataFiles)[ID_ion] = filename;      
903   } else {                                        
904     G4ExceptionDescription ed;                    
905     ed << filename << " does not exist! " << G    
906     G4Exception("G4VRadioactiveDecay::AddUserD    
907                 FatalException, ed);              
908   }                                               
909 }                                                 
910                                                   
911 //////////////////////////////////////////////    
912 //                                                
913 //  DecayIt                                       
914 //                                                
915 //////////////////////////////////////////////    
916                                                   
917 G4VParticleChange*                                
918 G4VRadioactiveDecay::DecayIt(const G4Track& th    
919 {                                                 
920   // Initialize G4ParticleChange object, get p    
921   fParticleChangeForRadDecay.Initialize(theTra    
922   fParticleChangeForRadDecay.ProposeWeight(the    
923   const G4DynamicParticle* theParticle = theTr    
924   const G4ParticleDefinition* theParticleDef =    
925                                                   
926   // First check whether RDM applies to the cu    
927   if (!isAllVolumesMode) {                        
928     if (!std::binary_search(ValidVolumes.begin    
929                      theTrack.GetVolume()->Get    
930 #ifdef G4VERBOSE                                  
931       if (GetVerboseLevel()>1) {                  
932         G4cout <<"G4VRadioactiveDecay::DecayIt    
933                << theTrack.GetVolume()->GetLog    
934                << " is not selected for the RD    
935         G4cout << " There are " << ValidVolume    
936         G4cout << " The Valid volumes are: ";     
937   for (auto const & vol : ValidVolumes) { G4co    
938         G4cout << G4endl;                         
939       }                                           
940 #endif                                            
941       fParticleChangeForRadDecay.SetNumberOfSe    
942                                                   
943       // Kill the parent particle.                
944       fParticleChangeForRadDecay.ProposeTrackS    
945       fParticleChangeForRadDecay.ProposeLocalE    
946       ClearNumberOfInteractionLengthLeft();       
947       return &fParticleChangeForRadDecay;         
948     }                                             
949   }                                               
950                                                   
951   // Now check if particle is valid for RDM       
952   G4DecayTable* theDecayTable = GetDecayTable(    
953   if ( theDecayTable == nullptr || theDecayTab    
954     // Particle is not an ion or is outside th    
955 #ifdef G4VERBOSE                                  
956     if (GetVerboseLevel() > 1) {                  
957       G4cout << "G4VRadioactiveDecay::DecayIt     
958              << theParticleDef->GetParticleNam    
959              << " is outside (Z,A) limits set     
960              << G4endl;                           
961     }                                             
962 #endif                                            
963     fParticleChangeForRadDecay.SetNumberOfSeco    
964                                                   
965     // Kill the parent particle                   
966     fParticleChangeForRadDecay.ProposeTrackSta    
967     fParticleChangeForRadDecay.ProposeLocalEne    
968     ClearNumberOfInteractionLengthLeft();         
969     return &fParticleChangeForRadDecay;           
970   }                                               
971   //G4cout << "DecayIt for " << theParticleDef    
972   //   << " isAllVolumesMode:" << isAllVolumes    
973   //   << " decayTable=" << theDecayTable << G    
974                                                   
975   // Data found. Decay nucleus without varianc    
976   DecayAnalog(theTrack, theDecayTable);           
977   return &fParticleChangeForRadDecay;             
978 }                                                 
979                                                   
980 void G4VRadioactiveDecay::DecayAnalog(const G4    
981                                       G4DecayT    
982 {                                                 
983   const G4DynamicParticle* theParticle = theTr    
984   const G4ParticleDefinition* theParticleDef =    
985   //G4cout << "DecayIt for " << theParticleDef    
986   G4DecayProducts* products = DoDecay(*thePart    
987                                                   
988   // Check if the product is the same as input    
989   // necessary to prevent infinite loop (11/05    
990   if (nullptr == products || products->entries    
991     fParticleChangeForRadDecay.SetNumberOfSeco    
992     fParticleChangeForRadDecay.ProposeTrackSta    
993     fParticleChangeForRadDecay.ProposeLocalEne    
994     ClearNumberOfInteractionLengthLeft();         
995     delete products;                              
996     return;                                       
997   }                                               
998                                                   
999   G4double energyDeposit = 0.0;                   
1000   G4double finalGlobalTime = theTrack.GetGlob    
1001   G4double finalLocalTime = theTrack.GetLocal    
1002                                                  
1003   // Get parent particle information and boos    
1004   // laboratory frame                            
1005                                                  
1006   // ParentEnergy used for the boost should b    
1007   // of the parent ion without the energy of     
1008   // (correction for bug 1359 by L. Desorgher    
1009   G4double ParentEnergy = theParticle->GetKin    
1010                         + theParticle->GetPar    
1011   G4ThreeVector ParentDirection(theParticle->    
1012                                                  
1013   if (theTrack.GetTrackStatus() == fStopButAl    
1014     // this condition seems to be always True    
1015                                                  
1016     // The particle is decayed at rest           
1017     // Since the time is for the particle at     
1018     // lapsed between particle coming to rest    
1019     // is sampled with the mean-life of the p    
1020     // PDGTime < 0.  (F.Lei 11/05/10)            
1021     G4double temptime = -std::log(G4UniformRa    
1022                         theParticleDef->GetPD    
1023     if (temptime < 0.) temptime = 0.;            
1024     finalGlobalTime += temptime;                 
1025     finalLocalTime += temptime;                  
1026     energyDeposit += theParticle->GetKineticE    
1027                                                  
1028     // Kill the parent particle, and ignore i    
1029     // threshold fThresholdForVeryLongDecayTi    
1030     // to more than twice the age of the univ    
1031     // This kind of cut has been introduced (    
1032     // account energy depositions happening a    
1033     // ordinary materials used in calorimetry    
1034     // (via their natural unstable, but very     
1035     // W183, W180 and Pb204).                    
1036     // Note that the cut is not on the averag    
1037     // sampled global decay time.                
1038     if ( finalGlobalTime > fThresholdForVeryL    
1039       fParticleChangeForRadDecay.SetNumberOfS    
1040       fParticleChangeForRadDecay.ProposeTrack    
1041       fParticleChangeForRadDecay.ProposeLocal    
1042       ClearNumberOfInteractionLengthLeft();      
1043       delete products;                           
1044       return;                                    
1045     }                                            
1046   }                                              
1047   products->Boost(ParentEnergy, ParentDirecti    
1048                                                  
1049   // Add products in theParticleChangeForRadD    
1050   G4int numberOfSecondaries = products->entri    
1051   fParticleChangeForRadDecay.SetNumberOfSecon    
1052                                                  
1053   if (GetVerboseLevel() > 1) {                   
1054     G4cout << "G4VRadioactiveDecay::DecayAnal    
1055     G4cout << " Time: " << finalGlobalTime/ns    
1056     G4cout << " X:" << (theTrack.GetPosition(    
1057     G4cout << " Y:" << (theTrack.GetPosition(    
1058     G4cout << " Z:" << (theTrack.GetPosition(    
1059     G4cout << G4endl;                            
1060     G4cout << "G4Decay::DecayIt : decay produ    
1061     products->DumpInfo();                        
1062     products->IsChecked();                       
1063   }                                              
1064                                                  
1065   const G4int modelID_forIT = G4PhysicsModelC    
1066   G4int modelID = modelID_forIT + 10*theRadDe    
1067   const G4int modelID_forAtomicRelaxation =      
1068     G4PhysicsModelCatalog::GetModelID( "model    
1069   for ( G4int index = 0; index < numberOfSeco    
1070     G4Track* secondary = new G4Track( product    
1071                                       theTrac    
1072     secondary->SetWeight( theTrack.GetWeight(    
1073     secondary->SetCreatorModelID( modelID );     
1074     // Change for atomics relaxation             
1075     if ( theRadDecayMode == IT  &&  index > 0    
1076       if ( index == numberOfSecondaries-1 ) {    
1077   secondary->SetCreatorModelID( modelID_forIT    
1078       } else {                                   
1079   secondary->SetCreatorModelID( modelID_forAt    
1080       }                                          
1081     } else if ( theRadDecayMode >= KshellEC      
1082     index < numberOfSecondaries-1 ) {            
1083       secondary->SetCreatorModelID( modelID_f    
1084     }                                            
1085     secondary->SetGoodForTrackingFlag();         
1086     secondary->SetTouchableHandle( theTrack.G    
1087     fParticleChangeForRadDecay.AddSecondary(     
1088   }                                              
1089                                                  
1090   delete products;                               
1091                                                  
1092   // Kill the parent particle                    
1093   fParticleChangeForRadDecay.ProposeTrackStat    
1094   fParticleChangeForRadDecay.ProposeLocalEner    
1095   fParticleChangeForRadDecay.ProposeLocalTime    
1096                                                  
1097   // Reset NumberOfInteractionLengthLeft.        
1098   ClearNumberOfInteractionLengthLeft();          
1099 }                                                
1100                                                  
1101                                                  
1102 G4DecayProducts*                                 
1103 G4VRadioactiveDecay::DoDecay(const G4Particle    
1104                              G4DecayTable* th    
1105 {                                                
1106   G4DecayProducts* products = nullptr;           
1107                                                  
1108   // Choose a decay channel.                     
1109   // G4DecayTable::SelectADecayChannel checks    
1110   // exceeds parent mass. Pass it the parent     
1111   // for difference in mass defect.              
1112   G4double parentPlusQ = theParticleDef.GetPD    
1113   G4VDecayChannel* theDecayChannel = theDecay    
1114                                                  
1115   if (theDecayChannel == nullptr) {              
1116     // Decay channel not found.                  
1117     G4ExceptionDescription ed;                   
1118     ed << " Cannot determine decay channel fo    
1119     G4Exception("G4VRadioactiveDecay::DoDecay    
1120                 FatalException, ed);             
1121   } else {                                       
1122     // A decay channel has been identified, s    
1123 #ifdef G4VERBOSE                                 
1124     if (GetVerboseLevel() > 1) {                 
1125       G4cout << "G4VRadioactiveDecay::DoIt :     
1126              << theDecayChannel << G4endl;       
1127     }                                            
1128 #endif                                           
1129     theRadDecayMode = static_cast<G4NuclearDe    
1130                                                  
1131     // for IT decay use local G4ITDecay class    
1132     if (theRadDecayMode == IT) {                 
1133       decayIT->SetupDecay(&theParticleDef);      
1134       products = decayIT->DecayIt(0.0);          
1135     } else {                                     
1136       // for others decayes use shared  class    
1137       products = theDecayChannel->DecayIt(the    
1138     }                                            
1139                                                  
1140     // Apply directional bias if requested by    
1141     CollimateDecay(products);                    
1142   }                                              
1143                                                  
1144   return products;                               
1145 }                                                
1146                                                  
1147                                                  
1148 // Apply directional bias for "visible" daugh    
1149 void G4VRadioactiveDecay::CollimateDecay(G4De    
1150                                                  
1151   if (origin == forceDecayDirection) return;     
1152   if (180.*deg == forceDecayHalfAngle) return    
1153   if (0 == products || 0 == products->entries    
1154                                                  
1155 #ifdef G4VERBOSE                                 
1156   if (GetVerboseLevel() > 1) G4cout << "Begin    
1157 #endif                                           
1158                                                  
1159   // Particles suitable for directional biasi    
1160   static const G4ParticleDefinition* electron    
1161   static const G4ParticleDefinition* positron    
1162   static const G4ParticleDefinition* neutron     
1163   static const G4ParticleDefinition* gamma       
1164   static const G4ParticleDefinition* alpha       
1165   static const G4ParticleDefinition* triton      
1166   static const G4ParticleDefinition* proton      
1167                                                  
1168   G4ThreeVector newDirection;   // Re-use to     
1169   for (G4int i=0; i<products->entries(); ++i)    
1170     G4DynamicParticle* daughter = (*products)    
1171     const G4ParticleDefinition* daughterType     
1172                                   daughter->G    
1173     if (daughterType == electron || daughterT    
1174   daughterType == neutron || daughterType ==     
1175   daughterType == alpha || daughterType == tr    
1176       CollimateDecayProduct(daughter);           
1177     }                                            
1178   }                                              
1179 }                                                
1180                                                  
1181 void G4VRadioactiveDecay::CollimateDecayProdu    
1182 #ifdef G4VERBOSE                                 
1183   if (GetVerboseLevel() > 1) {                   
1184     G4cout << "CollimateDecayProduct for daug    
1185      << daughter->GetParticleDefinition()->Ge    
1186   }                                              
1187 #endif                                           
1188                                                  
1189   G4ThreeVector collimate = ChooseCollimation    
1190   if (origin != collimate) daughter->SetMomen    
1191 }                                                
1192                                                  
1193                                                  
1194 // Choose random direction within collimation    
1195                                                  
1196 G4ThreeVector G4VRadioactiveDecay::ChooseColl    
1197   if (origin == forceDecayDirection) return o    
1198   if (forceDecayHalfAngle == 180.*deg) return    
1199                                                  
1200   G4ThreeVector dir = forceDecayDirection;       
1201                                                  
1202   // Return direction offset by random throw     
1203   if (forceDecayHalfAngle > 0.) {                
1204     // Generate uniform direction around cent    
1205     G4double phi = 2.*pi*G4UniformRand();        
1206     G4double cosMin = std::cos(forceDecayHalf    
1207     G4double cosTheta = (1.-cosMin)*G4Uniform    
1208                                                  
1209     dir.setPhi(dir.phi()+phi);                   
1210     dir.setTheta(dir.theta()+std::acos(cosThe    
1211   }                                              
1212                                                  
1213 #ifdef G4VERBOSE                                 
1214   if (GetVerboseLevel()>1)                       
1215     G4cout << " ChooseCollimationDirection re    
1216 #endif                                           
1217                                                  
1218   return dir;                                    
1219 }                                                
1220                                                  
1221