Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/utils/src/G4VEmProcess.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/electromagnetic/utils/src/G4VEmProcess.cc (Version 11.3.0) and /processes/electromagnetic/utils/src/G4VEmProcess.cc (Version 5.2)


  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 file                              
 29 //                                                
 30 //                                                
 31 // File name:     G4VEmProcess                    
 32 //                                                
 33 // Author:        Vladimir Ivanchenko on base     
 34 //                                                
 35 // Creation date: 01.10.2003                      
 36 //                                                
 37 // Modifications: by V.Ivanchenko                 
 38 //                                                
 39 // Class Description: based class for discrete    
 40 //                                                
 41                                                   
 42 // -------------------------------------------    
 43 //                                                
 44 //....oooOO0OOooo........oooOO0OOooo........oo    
 45 //....oooOO0OOooo........oooOO0OOooo........oo    
 46                                                   
 47 #include "G4VEmProcess.hh"                        
 48 #include "G4PhysicalConstants.hh"                 
 49 #include "G4SystemOfUnits.hh"                     
 50 #include "G4ProcessManager.hh"                    
 51 #include "G4LossTableManager.hh"                  
 52 #include "G4LossTableBuilder.hh"                  
 53 #include "G4Step.hh"                              
 54 #include "G4ParticleDefinition.hh"                
 55 #include "G4VEmModel.hh"                          
 56 #include "G4DataVector.hh"                        
 57 #include "G4PhysicsTable.hh"                      
 58 #include "G4EmDataHandler.hh"                     
 59 #include "G4PhysicsLogVector.hh"                  
 60 #include "G4VParticleChange.hh"                   
 61 #include "G4ProductionCutsTable.hh"               
 62 #include "G4Region.hh"                            
 63 #include "G4Gamma.hh"                             
 64 #include "G4Electron.hh"                          
 65 #include "G4Positron.hh"                          
 66 #include "G4PhysicsTableHelper.hh"                
 67 #include "G4EmBiasingManager.hh"                  
 68 #include "G4EmParameters.hh"                      
 69 #include "G4EmProcessSubType.hh"                  
 70 #include "G4EmTableUtil.hh"                       
 71 #include "G4EmUtility.hh"                         
 72 #include "G4DNAModelSubType.hh"                   
 73 #include "G4GenericIon.hh"                        
 74 #include "G4Log.hh"                               
 75 #include <iostream>                               
 76                                                   
 77 //....oooOO0OOooo........oooOO0OOooo........oo    
 78                                                   
 79 G4VEmProcess::G4VEmProcess(const G4String& nam    
 80   G4VDiscreteProcess(name, type)                  
 81 {                                                 
 82   theParameters = G4EmParameters::Instance();     
 83   SetVerboseLevel(1);                             
 84                                                   
 85   // Size of tables                               
 86   minKinEnergy = 0.1*CLHEP::keV;                  
 87   maxKinEnergy = 100.0*CLHEP::TeV;                
 88                                                   
 89   // default lambda factor                        
 90   invLambdaFactor = 1.0/lambdaFactor;             
 91                                                   
 92   // particle types                               
 93   theGamma = G4Gamma::Gamma();                    
 94   theElectron = G4Electron::Electron();           
 95   thePositron = G4Positron::Positron();           
 96                                                   
 97   pParticleChange = &fParticleChange;             
 98   fParticleChange.SetSecondaryWeightByProcess(    
 99   secParticles.reserve(5);                        
100                                                   
101   modelManager = new G4EmModelManager();          
102   lManager = G4LossTableManager::Instance();      
103   lManager->Register(this);                       
104   isTheMaster = lManager->IsMaster();             
105   G4LossTableBuilder* bld = lManager->GetTable    
106   theDensityFactor = bld->GetDensityFactors();    
107   theDensityIdx = bld->GetCoupleIndexes();        
108 }                                                 
109                                                   
110 //....oooOO0OOooo........oooOO0OOooo........oo    
111                                                   
112 G4VEmProcess::~G4VEmProcess()                     
113 {                                                 
114   if(isTheMaster) {                               
115     delete theData;                               
116     delete theEnergyOfCrossSectionMax;            
117   }                                               
118   delete modelManager;                            
119   delete biasManager;                             
120   lManager->DeRegister(this);                     
121 }                                                 
122                                                   
123 //....oooOO0OOooo........oooOO0OOooo........oo    
124                                                   
125 void G4VEmProcess::AddEmModel(G4int order, G4V    
126                               const G4Region*     
127 {                                                 
128   if(nullptr == ptr) { return; }                  
129   G4VEmFluctuationModel* fm = nullptr;            
130   modelManager->AddEmModel(order, ptr, fm, reg    
131   ptr->SetParticleChange(pParticleChange);        
132 }                                                 
133                                                   
134 //....oooOO0OOooo........oooOO0OOooo........oo    
135                                                   
136 void G4VEmProcess::SetEmModel(G4VEmModel* ptr,    
137 {                                                 
138   if(nullptr == ptr) { return; }                  
139   if(!emModels.empty()) {                         
140     for(auto & em : emModels) { if(em == ptr)     
141   }                                               
142   emModels.push_back(ptr);                        
143 }                                                 
144                                                   
145 //....oooOO0OOooo........oooOO0OOooo........oo    
146                                                   
147 void G4VEmProcess::PreparePhysicsTable(const G    
148 {                                                 
149   if(nullptr == particle) { SetParticle(&part)    
150                                                   
151   if(part.GetParticleType() == "nucleus" &&       
152      part.GetParticleSubType() == "generic") {    
153                                                   
154     G4String pname = part.GetParticleName();      
155     if(pname != "deuteron" && pname != "triton    
156        pname != "He3" && pname != "alpha" && p    
157        pname != "helium" && pname != "hydrogen    
158                                                   
159       particle = G4GenericIon::GenericIon();      
160       isIon = true;                               
161     }                                             
162   }                                               
163   if(particle != &part) { return; }               
164                                                   
165   lManager->PreparePhysicsTable(&part, this);     
166                                                   
167   // for new run                                  
168   currentCouple = nullptr;                        
169   preStepLambda = 0.0;                            
170   fLambdaEnergy = 0.0;                            
171                                                   
172   InitialiseProcess(particle);                    
173                                                   
174   G4LossTableBuilder* bld = lManager->GetTable    
175   const G4ProductionCutsTable* theCoupleTable=    
176     G4ProductionCutsTable::GetProductionCutsTa    
177   theCutsGamma    = theCoupleTable->GetEnergyC    
178   theCutsElectron = theCoupleTable->GetEnergyC    
179   theCutsPositron = theCoupleTable->GetEnergyC    
180                                                   
181   // initialisation of the process                
182   if(!actMinKinEnergy) { minKinEnergy = thePar    
183   if(!actMaxKinEnergy) { maxKinEnergy = thePar    
184                                                   
185   applyCuts       = theParameters->ApplyCuts()    
186   lambdaFactor    = theParameters->LambdaFacto    
187   invLambdaFactor = 1.0/lambdaFactor;             
188   theParameters->DefineRegParamForEM(this);       
189                                                   
190   // integral option may be disabled              
191   if(!theParameters->Integral()) { fXSType = f    
192                                                   
193   // prepare tables                               
194   if(isTheMaster) {                               
195     if(nullptr == theData) { theData = new G4E    
196                                                   
197     if(buildLambdaTable) {                        
198       theLambdaTable = theData->MakeTable(0);     
199       bld->InitialiseBaseMaterials(theLambdaTa    
200     }                                             
201     // high energy table                          
202     if(minKinEnergyPrim < maxKinEnergy) {         
203       theLambdaTablePrim = theData->MakeTable(    
204       bld->InitialiseBaseMaterials(theLambdaTa    
205     }                                             
206   }                                               
207   // models                                       
208   baseMat = bld->GetBaseMaterialFlag();           
209   numberOfModels = modelManager->NumberOfModel    
210   currentModel = modelManager->GetModel(0);       
211   if(nullptr != lManager->AtomDeexcitation())     
212     modelManager->SetFluoFlag(true);              
213   }                                               
214   // forced biasing                               
215   if(nullptr != biasManager) {                    
216     biasManager->Initialise(part, GetProcessNa    
217     biasFlag = false;                             
218   }                                               
219                                                   
220   theCuts =                                       
221     G4EmTableUtil::PrepareEmProcess(this, part    
222                                     modelManag    
223                                     secID, tri    
224                                     verboseLev    
225 }                                                 
226                                                   
227 //....oooOO0OOooo........oooOO0OOooo........oo    
228                                                   
229 void G4VEmProcess::BuildPhysicsTable(const G4P    
230 {                                                 
231   if(nullptr == masterProc) {                     
232     if(isTheMaster) { masterProc = this; }        
233     else { masterProc = static_cast<const G4VE    
234   }                                               
235   G4int nModels = modelManager->NumberOfModels    
236   G4bool isLocked = theParameters->IsPrintLock    
237   G4bool toBuild = (buildLambdaTable || minKin    
238                                                   
239   G4EmTableUtil::BuildEmProcess(this, masterPr    
240                                 nModels, verbo    
241                                 isLocked, toBu    
242 }                                                 
243                                                   
244 //....oooOO0OOooo........oooOO0OOooo........oo    
245                                                   
246 void G4VEmProcess::BuildLambdaTable()             
247 {                                                 
248   G4double scale = theParameters->MaxKinEnergy    
249   G4int nbin =                                    
250     theParameters->NumberOfBinsPerDecade()*G4l    
251   if(actBinning) { nbin = std::max(nbin, nLamb    
252   scale = nbin/G4Log(scale);                      
253                                                   
254   G4LossTableBuilder* bld = lManager->GetTable    
255   G4EmTableUtil::BuildLambdaTable(this, partic    
256                                   bld, theLamb    
257                                   minKinEnergy    
258                                   maxKinEnergy    
259                                   startFromNul    
260 }                                                 
261                                                   
262 //....oooOO0OOooo........oooOO0OOooo........oo    
263                                                   
264 void G4VEmProcess::StreamInfo(std::ostream& ou    
265                   const G4ParticleDefinition&     
266 {                                                 
267   G4String indent = (rst ? "  " : "");            
268   out << std::setprecision(6);                    
269   out << G4endl << indent << GetProcessName()     
270   if (!rst) {                                     
271     out << " for " << part.GetParticleName();     
272   }                                               
273   if(fXSType != fEmNoIntegral)  { out << " XSt    
274   if(applyCuts) { out << " applyCuts:1 "; }       
275   G4int subtype = GetProcessSubType();            
276   out << " SubType=" << subtype;                  
277   if (subtype == fAnnihilation) {                 
278     G4int mod = theParameters->PositronAtRestM    
279     const G4String namp[2] = {"Simple", "Allis    
280     out << " AtRestModel:" << namp[mod];          
281   }                                               
282   if(biasFactor != 1.0) { out << "  BiasingFac    
283   out << " BuildTable=" << buildLambdaTable <<    
284   if(buildLambdaTable) {                          
285     if(particle == &part) {                       
286       for(auto & v : *theLambdaTable) {           
287         if(nullptr != v) {                        
288           out << "      Lambda table from ";      
289           G4double emin = v->Energy(0);           
290           G4double emax = v->GetMaxEnergy();      
291           G4int nbin = G4int(v->GetVectorLengt    
292           if(emin > minKinEnergy) { out << "th    
293           else { out << G4BestUnit(emin,"Energ    
294           out << " to "                           
295               << G4BestUnit(emax,"Energy")        
296               << ", " << G4lrint(nbin/std::log    
297               << " bins/decade, spline: "         
298               << splineFlag << G4endl;            
299           break;                                  
300         }                                         
301       }                                           
302     } else {                                      
303       out << "      Used Lambda table of "        
304       << particle->GetParticleName() << G4endl    
305     }                                             
306   }                                               
307   if(minKinEnergyPrim < maxKinEnergy) {           
308     if(particle == &part) {                       
309       for(auto & v : *theLambdaTablePrim) {       
310         if(nullptr != v) {                        
311           out << "      LambdaPrime table from    
312               << G4BestUnit(v->Energy(0),"Ener    
313               << " to "                           
314               << G4BestUnit(v->GetMaxEnergy(),    
315               << " in " << v->GetVectorLength(    
316               << " bins " << G4endl;              
317           break;                                  
318         }                                         
319       }                                           
320     } else {                                      
321       out << "      Used LambdaPrime table of     
322                << particle->GetParticleName()     
323     }                                             
324   }                                               
325   StreamProcessInfo(out);                         
326   modelManager->DumpModelList(out, verboseLeve    
327                                                   
328   if(verboseLevel > 2 && buildLambdaTable) {      
329     out << "      LambdaTable address= " << th    
330     if(theLambdaTable && particle == &part) {     
331       out << (*theLambdaTable) << G4endl;         
332     }                                             
333   }                                               
334 }                                                 
335                                                   
336 //....oooOO0OOooo........oooOO0OOooo........oo    
337                                                   
338 void G4VEmProcess::StartTracking(G4Track* trac    
339 {                                                 
340   // reset parameters for the new track           
341   currentParticle = track->GetParticleDefiniti    
342   theNumberOfInteractionLengthLeft = -1.0;        
343   mfpKinEnergy = DBL_MAX;                         
344   preStepLambda = 0.0;                            
345                                                   
346   if(isIon) { massRatio = proton_mass_c2/curre    
347                                                   
348   // forced biasing only for primary particles    
349   if(biasManager) {                               
350     if(0 == track->GetParentID()) {               
351       // primary particle                         
352       biasFlag = true;                            
353       biasManager->ResetForcedInteraction();      
354     }                                             
355   }                                               
356 }                                                 
357                                                   
358 //....oooOO0OOooo........oooOO0OOooo........oo    
359                                                   
360 G4double G4VEmProcess::PostStepGetPhysicalInte    
361                              const G4Track& tr    
362                              G4double   previo    
363                              G4ForceCondition*    
364 {                                                 
365   *condition = NotForced;                         
366   G4double x = DBL_MAX;                           
367                                                   
368   DefineMaterial(track.GetMaterialCutsCouple()    
369   preStepKinEnergy = track.GetKineticEnergy();    
370   const G4double scaledEnergy = preStepKinEner    
371   SelectModel(scaledEnergy, currentCoupleIndex    
372   /*                                              
373   G4cout << "PostStepGetPhysicalInteractionLen    
374          << "  couple: " << currentCouple << G    
375   */                                              
376   if(!currentModel->IsActive(scaledEnergy)) {     
377     theNumberOfInteractionLengthLeft = -1.0;      
378     currentInteractionLength = DBL_MAX;           
379     mfpKinEnergy = DBL_MAX;                       
380     preStepLambda = 0.0;                          
381     return x;                                     
382   }                                               
383                                                   
384   // forced biasing only for primary particles    
385   if(biasManager) {                               
386     if(0 == track.GetParentID()) {                
387       if(biasFlag &&                              
388          biasManager->ForcedInteractionRegion(    
389         return biasManager->GetStepLimit((G4in    
390       }                                           
391     }                                             
392   }                                               
393                                                   
394   // compute mean free path                       
395                                                   
396   ComputeIntegralLambda(preStepKinEnergy, trac    
397                                                   
398   // zero cross section                           
399   if(preStepLambda <= 0.0) {                      
400     theNumberOfInteractionLengthLeft = -1.0;      
401     currentInteractionLength = DBL_MAX;           
402                                                   
403   } else {                                        
404                                                   
405     // non-zero cross section                     
406     if (theNumberOfInteractionLengthLeft < 0.0    
407                                                   
408       // beggining of tracking (or just after     
409       theNumberOfInteractionLengthLeft = -G4Lo    
410       theInitialNumberOfInteractionLength = th    
411                                                   
412     } else {                                      
413                                                   
414       theNumberOfInteractionLengthLeft -=         
415         previousStepSize/currentInteractionLen    
416       theNumberOfInteractionLengthLeft =          
417         std::max(theNumberOfInteractionLengthL    
418     }                                             
419                                                   
420     // new mean free path and step limit for t    
421     currentInteractionLength = 1.0/preStepLamb    
422     x = theNumberOfInteractionLengthLeft * cur    
423   }                                               
424   return x;                                       
425 }                                                 
426                                                   
427 //....oooOO0OOooo........oooOO0OOooo........oo    
428                                                   
429 void G4VEmProcess::ComputeIntegralLambda(G4dou    
430 {                                                 
431   if (fXSType == fEmNoIntegral) {                 
432     preStepLambda = GetCurrentLambda(e, LogEki    
433                                                   
434   } else if (fXSType == fEmIncreasing) {          
435     if(e*invLambdaFactor < mfpKinEnergy) {        
436       preStepLambda = GetCurrentLambda(e, LogE    
437       mfpKinEnergy = (preStepLambda > 0.0) ? e    
438     }                                             
439                                                   
440   } else if(fXSType == fEmDecreasing) {           
441     if(e < mfpKinEnergy) {                        
442       const G4double e1 = e*lambdaFactor;         
443       preStepLambda = GetCurrentLambda(e1);       
444       mfpKinEnergy = e1;                          
445     }                                             
446                                                   
447   } else if(fXSType == fEmOnePeak) {              
448     const G4double epeak = (*theEnergyOfCrossS    
449     if(e <= epeak) {                              
450       if(e*invLambdaFactor < mfpKinEnergy) {      
451         preStepLambda = GetCurrentLambda(e, Lo    
452         mfpKinEnergy = (preStepLambda > 0.0) ?    
453       }                                           
454     } else if(e < mfpKinEnergy) {                 
455       const G4double e1 = std::max(epeak, e*la    
456       preStepLambda = GetCurrentLambda(e1);       
457       mfpKinEnergy = e1;                          
458     }                                             
459   } else {                                        
460     preStepLambda = GetCurrentLambda(e, LogEki    
461   }                                               
462 }                                                 
463                                                   
464 //....oooOO0OOooo........oooOO0OOooo........oo    
465                                                   
466 G4VParticleChange* G4VEmProcess::PostStepDoIt(    
467                                                   
468 {                                                 
469   // clear number of interaction lengths in an    
470   theNumberOfInteractionLengthLeft = -1.0;        
471   mfpKinEnergy = DBL_MAX;                         
472                                                   
473   fParticleChange.InitializeForPostStep(track)    
474                                                   
475   // Do not make anything if particle is stopp    
476   // should be performed by the AtRestDoIt!       
477   if (track.GetTrackStatus() == fStopButAlive)    
478                                                   
479   const G4double finalT = track.GetKineticEner    
480                                                   
481   // forced process - should happen only once     
482   if(biasFlag) {                                  
483     if(biasManager->ForcedInteractionRegion((G    
484       biasFlag = false;                           
485     }                                             
486   }                                               
487                                                   
488   // check active and select model                
489   const G4double scaledEnergy = finalT*massRat    
490   SelectModel(scaledEnergy, currentCoupleIndex    
491   if(!currentModel->IsActive(scaledEnergy)) {     
492                                                   
493   // Integral approach                            
494   if (fXSType != fEmNoIntegral) {                 
495     const G4double logFinalT =                    
496       track.GetDynamicParticle()->GetLogKineti    
497     const G4double lx = std::max(GetCurrentLam    
498 #ifdef G4VERBOSE                                  
499     if(preStepLambda < lx && 1 < verboseLevel)    
500       G4cout << "WARNING: for " << currentPart    
501              << " and " << GetProcessName() <<    
502              << " preLambda= " << preStepLambd    
503              << " < " << lx << " (postLambda)     
504     }                                             
505 #endif                                            
506     // if false interaction then use new cross    
507     // if both values are zero - no interactio    
508     if(preStepLambda*G4UniformRand() >= lx) {     
509       return &fParticleChange;                    
510     }                                             
511   }                                               
512                                                   
513   // define new weight for primary and seconda    
514   G4double weight = fParticleChange.GetParentW    
515   if(weightFlag) {                                
516     weight /= biasFactor;                         
517     fParticleChange.ProposeWeight(weight);        
518   }                                               
519                                                   
520 #ifdef G4VERBOSE                                  
521   if(1 < verboseLevel) {                          
522     G4cout << "G4VEmProcess::PostStepDoIt: Sam    
523            << finalT/MeV                          
524            << " MeV; model= (" << currentModel    
525            << ", " <<  currentModel->HighEnerg    
526            << G4endl;                             
527   }                                               
528 #endif                                            
529                                                   
530   // sample secondaries                           
531   secParticles.clear();                           
532   currentModel->SampleSecondaries(&secParticle    
533                                   currentCoupl    
534                                   track.GetDyn    
535                                   (*theCuts)[c    
536                                                   
537   G4int num0 = (G4int)secParticles.size();        
538                                                   
539   // splitting or Russian roulette                
540   if(biasManager) {                               
541     if(biasManager->SecondaryBiasingRegion((G4    
542       G4double eloss = 0.0;                       
543       weight *= biasManager->ApplySecondaryBia    
544         secParticles, track, currentModel, &fP    
545         (G4int)currentCoupleIndex, (*theCuts)[    
546         step.GetPostStepPoint()->GetSafety());    
547       if(eloss > 0.0) {                           
548         eloss += fParticleChange.GetLocalEnerg    
549         fParticleChange.ProposeLocalEnergyDepo    
550       }                                           
551     }                                             
552   }                                               
553                                                   
554   // save secondaries                             
555   G4int num = (G4int)secParticles.size();         
556   if(num > 0) {                                   
557                                                   
558     fParticleChange.SetNumberOfSecondaries(num    
559     G4double edep = fParticleChange.GetLocalEn    
560     G4double time = track.GetGlobalTime();        
561                                                   
562     G4int n1(0), n2(0);                           
563     if(num0 > mainSecondaries) {                  
564       currentModel->FillNumberOfSecondaries(n1    
565     }                                             
566                                                   
567     for (G4int i=0; i<num; ++i) {                 
568       G4DynamicParticle* dp = secParticles[i];    
569       if (nullptr != dp) {                        
570         const G4ParticleDefinition* p = dp->Ge    
571         G4double e = dp->GetKineticEnergy();      
572         G4bool good = true;                       
573         if(applyCuts) {                           
574           if (p == theGamma) {                    
575             if (e < (*theCutsGamma)[currentCou    
576                                                   
577           } else if (p == theElectron) {          
578             if (e < (*theCutsElectron)[current    
579                                                   
580           } else if (p == thePositron) {          
581             if (electron_mass_c2 < (*theCutsGa    
582                 e < (*theCutsPositron)[current    
583               good = false;                       
584               e += 2.0*electron_mass_c2;          
585             }                                     
586           }                                       
587           // added secondary if it is good        
588         }                                         
589         if (good) {                               
590           G4Track* t = new G4Track(dp, time, t    
591           t->SetTouchableHandle(track.GetTouch    
592           if (biasManager) {                      
593             t->SetWeight(weight * biasManager-    
594           } else {                                
595             t->SetWeight(weight);                 
596           }                                       
597           pParticleChange->AddSecondary(t);       
598                                                   
599           // define type of secondary             
600           if(i < mainSecondaries) {               
601             t->SetCreatorModelID(secID);          
602             if(GetProcessSubType() == fCompton    
603               t->SetCreatorModelID(_ComptonGam    
604             }                                     
605           } else if(i < mainSecondaries + n1)     
606             t->SetCreatorModelID(tripletID);      
607           } else if(i < mainSecondaries + n1 +    
608             t->SetCreatorModelID(_IonRecoil);     
609           } else {                                
610             if(i < num0) {                        
611               if(p == theGamma) {                 
612                 t->SetCreatorModelID(fluoID);     
613               } else {                            
614                 t->SetCreatorModelID(augerID);    
615               }                                   
616             } else {                              
617               t->SetCreatorModelID(biasID);       
618             }                                     
619           }                                       
620           /*                                      
621           G4cout << "Secondary(post step) has     
622                  << ", Ekin= " << t->GetKineti    
623                  << GetProcessName() << " fluo    
624                  << " augerID= " << augerID <<    
625           */                                      
626         } else {                                  
627           delete dp;                              
628           edep += e;                              
629         }                                         
630       }                                           
631     }                                             
632     fParticleChange.ProposeLocalEnergyDeposit(    
633   }                                               
634                                                   
635   if(0.0 == fParticleChange.GetProposedKinetic    
636      fAlive == fParticleChange.GetTrackStatus(    
637     if(particle->GetProcessManager()->GetAtRes    
638          { fParticleChange.ProposeTrackStatus(    
639     else { fParticleChange.ProposeTrackStatus(    
640   }                                               
641                                                   
642   return &fParticleChange;                        
643 }                                                 
644                                                   
645 //....oooOO0OOooo........oooOO0OOooo........oo    
646                                                   
647 G4bool G4VEmProcess::StorePhysicsTable(const G    
648                                        const G    
649                                        G4bool     
650 {                                                 
651   if(!isTheMaster || part != particle) { retur    
652   if(G4EmTableUtil::StoreTable(this, part, the    
653              directory, "Lambda",                 
654                                verboseLevel, a    
655      G4EmTableUtil::StoreTable(this, part, the    
656              directory, "LambdaPrim",             
657                                verboseLevel, a    
658      return true;                                 
659   }                                               
660   return false;                                   
661 }                                                 
662                                                   
663 //....oooOO0OOooo........oooOO0OOooo........oo    
664                                                   
665 G4bool G4VEmProcess::RetrievePhysicsTable(cons    
666                                           cons    
667                                           G4bo    
668 {                                                 
669   if(!isTheMaster || part != particle) { retur    
670   G4bool yes = true;                              
671   if(buildLambdaTable) {                          
672     yes = G4EmTableUtil::RetrieveTable(this, p    
673                                        "Lambda    
674                                        ascii,     
675   }                                               
676   if(yes && minKinEnergyPrim < maxKinEnergy) {    
677     yes = G4EmTableUtil::RetrieveTable(this, p    
678                                        "Lambda    
679                                        ascii,     
680   }                                               
681   return yes;                                     
682 }                                                 
683                                                   
684 //....oooOO0OOooo........oooOO0OOooo........oo    
685                                                   
686 G4double G4VEmProcess::GetCrossSection(G4doubl    
687                                        const G    
688 {                                                 
689   CurrentSetup(couple, kinEnergy);                
690   return GetCurrentLambda(kinEnergy, G4Log(kin    
691 }                                                 
692                                                   
693 //....oooOO0OOooo........oooOO0OOooo........oo    
694                                                   
695 G4double G4VEmProcess::GetMeanFreePath(const G    
696                                        G4doubl    
697                                        G4Force    
698 {                                                 
699   *condition = NotForced;                         
700   return G4VEmProcess::MeanFreePath(track);       
701 }                                                 
702                                                   
703 //....oooOO0OOooo........oooOO0OOooo........oo    
704                                                   
705 G4double                                          
706 G4VEmProcess::ComputeCrossSectionPerAtom(G4dou    
707                                          G4dou    
708 {                                                 
709   SelectModel(kinEnergy, currentCoupleIndex);     
710   return (currentModel) ?                         
711     currentModel->ComputeCrossSectionPerAtom(c    
712                                              Z    
713 }                                                 
714                                                   
715 //....oooOO0OOooo........oooOO0OOooo........oo    
716                                                   
717 G4PhysicsVector*                                  
718 G4VEmProcess::LambdaPhysicsVector(const G4Mate    
719 {                                                 
720   DefineMaterial(couple);                         
721   G4PhysicsVector* newv = new G4PhysicsLogVect    
722                                                   
723   return newv;                                    
724 }                                                 
725                                                   
726 //....oooOO0OOooo........oooOO0OOooo........oo    
727                                                   
728 const G4Element* G4VEmProcess::GetCurrentEleme    
729 {                                                 
730   return (nullptr != currentModel) ?              
731     currentModel->GetCurrentElement(currentMat    
732 }                                                 
733                                                   
734 //....oooOO0OOooo........oooOO0OOooo........oo    
735                                                   
736 const G4Element* G4VEmProcess::GetTargetElemen    
737 {                                                 
738   return (nullptr != currentModel) ?              
739     currentModel->GetCurrentElement(currentMat    
740 }                                                 
741                                                   
742 //....oooOO0OOooo........oooOO0OOooo........oo    
743                                                   
744 const G4Isotope* G4VEmProcess::GetTargetIsotop    
745 {                                                 
746   return (nullptr != currentModel) ?              
747     currentModel->GetCurrentIsotope(GetCurrent    
748 }                                                 
749                                                   
750 //....oooOO0OOooo........oooOO0OOooo........oo    
751                                                   
752 void G4VEmProcess::SetCrossSectionBiasingFacto    
753 {                                                 
754   if(f > 0.0) {                                   
755     biasFactor = f;                               
756     weightFlag = flag;                            
757     if(1 < verboseLevel) {                        
758       G4cout << "### SetCrossSectionBiasingFac    
759              << particle->GetParticleName()       
760              << " and process " << GetProcessN    
761              << " biasFactor= " << f << " weig    
762              << G4endl;                           
763     }                                             
764   }                                               
765 }                                                 
766                                                   
767 //....oooOO0OOooo........oooOO0OOooo........oo    
768                                                   
769 void                                              
770 G4VEmProcess::ActivateForcedInteraction(G4doub    
771                                         G4bool    
772 {                                                 
773   if(nullptr == biasManager) { biasManager = n    
774   if(1 < verboseLevel) {                          
775     G4cout << "### ActivateForcedInteraction:     
776            << particle->GetParticleName()         
777            << " and process " << GetProcessNam    
778            << " length(mm)= " << length/mm        
779            << " in G4Region <" << r               
780            << "> weightFlag= " << flag            
781            << G4endl;                             
782   }                                               
783   weightFlag = flag;                              
784   biasManager->ActivateForcedInteraction(lengt    
785 }                                                 
786                                                   
787 //....oooOO0OOooo........oooOO0OOooo........oo    
788                                                   
789 void                                              
790 G4VEmProcess::ActivateSecondaryBiasing(const G    
791                  G4double factor,                 
792                  G4double energyLimit)            
793 {                                                 
794   if (0.0 <= factor) {                            
795                                                   
796     // Range cut can be applied only for e-       
797     if(0.0 == factor && secondaryParticle != G    
798       { return; }                                 
799                                                   
800     if(!biasManager) { biasManager = new G4EmB    
801     biasManager->ActivateSecondaryBiasing(regi    
802     if(1 < verboseLevel) {                        
803       G4cout << "### ActivateSecondaryBiasing:    
804        << " process " << GetProcessName()         
805        << " factor= " << factor                   
806        << " in G4Region <" << region              
807        << "> energyLimit(MeV)= " << energyLimi    
808        << G4endl;                                 
809     }                                             
810   }                                               
811 }                                                 
812                                                   
813 //....oooOO0OOooo........oooOO0OOooo........oo    
814                                                   
815 void G4VEmProcess::SetLambdaBinning(G4int n)      
816 {                                                 
817   if(5 < n && n < 10000000) {                     
818     nLambdaBins = n;                              
819     actBinning = true;                            
820   } else {                                        
821     G4double e = (G4double)n;                     
822     PrintWarning("SetLambdaBinning", e);          
823   }                                               
824 }                                                 
825                                                   
826 //....oooOO0OOooo........oooOO0OOooo........oo    
827                                                   
828 void G4VEmProcess::SetMinKinEnergy(G4double e)    
829 {                                                 
830   if(1.e-3*eV < e && e < maxKinEnergy) {          
831     nLambdaBins = G4lrint(nLambdaBins*G4Log(ma    
832                           /G4Log(maxKinEnergy/    
833     minKinEnergy = e;                             
834     actMinKinEnergy = true;                       
835   } else { PrintWarning("SetMinKinEnergy", e);    
836 }                                                 
837                                                   
838 //....oooOO0OOooo........oooOO0OOooo........oo    
839                                                   
840 void G4VEmProcess::SetMaxKinEnergy(G4double e)    
841 {                                                 
842   if(minKinEnergy < e && e < 1.e+6*TeV) {         
843     nLambdaBins = G4lrint(nLambdaBins*G4Log(e/    
844                           /G4Log(maxKinEnergy/    
845     maxKinEnergy = e;                             
846     actMaxKinEnergy = true;                       
847   } else { PrintWarning("SetMaxKinEnergy", e);    
848 }                                                 
849                                                   
850 //....oooOO0OOooo........oooOO0OOooo........oo    
851                                                   
852 void G4VEmProcess::SetMinKinEnergyPrim(G4doubl    
853 {                                                 
854   if(theParameters->MinKinEnergy() <= e &&        
855      e <= theParameters->MaxKinEnergy()) { min    
856   else { PrintWarning("SetMinKinEnergyPrim", e    
857 }                                                 
858                                                   
859 //....oooOO0OOooo........oooOO0OOooo........oo    
860                                                   
861 G4VEmProcess* G4VEmProcess::GetEmProcess(const    
862 {                                                 
863   return (nam == GetProcessName()) ? this : nu    
864 }                                                 
865                                                   
866 //....oooOO0OOooo........oooOO0OOooo........oo    
867                                                   
868 G4double G4VEmProcess::PolarAngleLimit() const    
869 {                                                 
870   return theParameters->MscThetaLimit();          
871 }                                                 
872                                                   
873 //....oooOO0OOooo........oooOO0OOooo........oo    
874                                                   
875 void G4VEmProcess::PrintWarning(G4String tit,     
876 {                                                 
877   G4String ss = "G4VEmProcess::" + tit;           
878   G4ExceptionDescription ed;                      
879   ed << "Parameter is out of range: " << val      
880      << " it will have no effect!\n" << "  Pro    
881      << GetProcessName() << "  nbins= " << the    
882      << " Emin(keV)= " << theParameters->MinKi    
883      << " Emax(GeV)= " << theParameters->MaxKi    
884   G4Exception(ss, "em0044", JustWarning, ed);     
885 }                                                 
886                                                   
887 //....oooOO0OOooo........oooOO0OOooo........oo    
888                                                   
889 void G4VEmProcess::ProcessDescription(std::ost    
890 {                                                 
891   if(nullptr != particle) {                       
892     StreamInfo(out, *particle, true);             
893   }                                               
894 }                                                 
895                                                   
896 //....oooOO0OOooo........oooOO0OOooo........oo    
897