Geant4 Cross Reference

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


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 //                                                 26 //
 27 // Geant4 class G4EmTableUtil                      27 // Geant4 class G4EmTableUtil
 28 //                                                 28 //
 29 // Author V.Ivanchenko 14.03.2022                  29 // Author V.Ivanchenko 14.03.2022
 30 //                                                 30 //
 31                                                    31 
 32 #include "G4EmTableUtil.hh"                        32 #include "G4EmTableUtil.hh"
 33 #include "G4RegionStore.hh"                        33 #include "G4RegionStore.hh"
 34 #include "G4ProductionCutsTable.hh"                34 #include "G4ProductionCutsTable.hh"
 35 #include "G4EmParameters.hh"                       35 #include "G4EmParameters.hh"
 36 #include "G4EmUtility.hh"                          36 #include "G4EmUtility.hh"
 37 #include "G4LossTableManager.hh"                   37 #include "G4LossTableManager.hh"
 38 #include "G4EmTableType.hh"                        38 #include "G4EmTableType.hh"
 39 #include "G4PhysicsModelCatalog.hh"                39 #include "G4PhysicsModelCatalog.hh"
 40 #include "G4LowEnergyEmProcessSubType.hh"          40 #include "G4LowEnergyEmProcessSubType.hh"
 41 #include "G4PhysicsTableHelper.hh"                 41 #include "G4PhysicsTableHelper.hh"
 42 #include "G4PhysicsLogVector.hh"                   42 #include "G4PhysicsLogVector.hh"
 43 #include "G4ProcessManager.hh"                     43 #include "G4ProcessManager.hh"
 44 #include "G4UIcommand.hh"                          44 #include "G4UIcommand.hh"
 45 #include "G4GenericIon.hh"                         45 #include "G4GenericIon.hh"
 46 #include <iostream>                                46 #include <iostream>
 47                                                    47 
 48 //....oooOO0OOooo........oooOO0OOooo........oo     48 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
 49                                                    49 
 50 const G4DataVector*                                50 const G4DataVector*
 51 G4EmTableUtil::PrepareEmProcess(G4VEmProcess*      51 G4EmTableUtil::PrepareEmProcess(G4VEmProcess* proc,
 52                                 const G4Partic     52                                 const G4ParticleDefinition* part,
 53                                 const G4Partic     53                                 const G4ParticleDefinition* secPart,
 54               G4EmModelManager* modelManager,      54               G4EmModelManager* modelManager,
 55                                 const G4double     55                                 const G4double& maxKinEnergy,
 56               G4int& secID, G4int& tripletID,      56               G4int& secID, G4int& tripletID,
 57                                 G4int& mainSec     57                                 G4int& mainSec, const G4int& verb,
 58                                 const G4bool&      58                                 const G4bool& master)
 59 {                                                  59 {
 60   G4EmParameters* param = G4EmParameters::Inst     60   G4EmParameters* param = G4EmParameters::Instance();
 61                                                    61 
 62   // initialisation of models                      62   // initialisation of models
 63   G4double plimit = param->MscThetaLimit();        63   G4double plimit = param->MscThetaLimit();
 64   G4int nModels = modelManager->NumberOfModels     64   G4int nModels = modelManager->NumberOfModels();
 65   for(G4int i=0; i<nModels; ++i) {                 65   for(G4int i=0; i<nModels; ++i) {
 66     G4VEmModel* mod = modelManager->GetModel(i     66     G4VEmModel* mod = modelManager->GetModel(i);
 67     if(nullptr == mod) { continue; }               67     if(nullptr == mod) { continue; }
 68     mod->SetPolarAngleLimit(plimit);               68     mod->SetPolarAngleLimit(plimit);
                                                   >>  69     mod->SetMasterThread(master);
 69     if(mod->HighEnergyLimit() > maxKinEnergy)      70     if(mod->HighEnergyLimit() > maxKinEnergy) {
 70       mod->SetHighEnergyLimit(maxKinEnergy);       71       mod->SetHighEnergyLimit(maxKinEnergy);
 71     }                                              72     }
 72     proc->SetEmModel(mod);                         73     proc->SetEmModel(mod);
 73   }                                                74   }
 74                                                    75 
 75   // defined ID of secondary particles and ver     76   // defined ID of secondary particles and verbosity
 76   G4int stype = proc->GetProcessSubType();         77   G4int stype = proc->GetProcessSubType();
 77   if(stype == fAnnihilation) {                     78   if(stype == fAnnihilation) {
 78     secID = _Annihilation;                         79     secID = _Annihilation;
 79     tripletID = _TripletGamma;                     80     tripletID = _TripletGamma;
 80   } else if(stype == fGammaConversion) {           81   } else if(stype == fGammaConversion) {
 81     secID = _PairProduction;                       82     secID = _PairProduction;
 82     mainSec = 2;                                   83     mainSec = 2;
 83   } else if(stype == fPhotoElectricEffect) {       84   } else if(stype == fPhotoElectricEffect) {
 84     secID = _PhotoElectron;                        85     secID = _PhotoElectron;
 85   } else if(stype == fComptonScattering) {         86   } else if(stype == fComptonScattering) {
 86     secID = _ComptonElectron;                      87     secID = _ComptonElectron;
 87   } else if(stype >= fLowEnergyElastic) {          88   } else if(stype >= fLowEnergyElastic) {
 88     secID = fDNAUnknownModel;                      89     secID = fDNAUnknownModel;
 89   }                                                90   }
 90   if(master) {                                     91   if(master) { 
 91     proc->SetVerboseLevel(param->Verbose());       92     proc->SetVerboseLevel(param->Verbose());
 92   } else {                                         93   } else {  
 93     proc->SetVerboseLevel(param->WorkerVerbose     94     proc->SetVerboseLevel(param->WorkerVerbose()); 
 94   }                                                95   }
 95                                                    96 
 96   // model initialisation                          97   // model initialisation
 97   const G4DataVector* cuts = modelManager->Ini     98   const G4DataVector* cuts = modelManager->Initialise(part, secPart, verb);
 98                                                    99 
 99   if(1 < verb) {                                  100   if(1 < verb) {
100     G4cout << "### G4EmTableUtil::PreparePhysi << 101     G4cout << "### G4VEmProcess::PreparePhysicsTable() done for " 
101            << proc->GetProcessName()              102            << proc->GetProcessName()
102            << " and particle " << part->GetPar    103            << " and particle " << part->GetParticleName()
103            << G4endl;                             104            << G4endl;
104   }                                               105   }
105   return cuts;                                    106   return cuts;
106 }                                                 107 }
107                                                   108 
108 //....oooOO0OOooo........oooOO0OOooo........oo    109 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
109                                                   110 
110 void G4EmTableUtil::BuildEmProcess(G4VEmProces    111 void G4EmTableUtil::BuildEmProcess(G4VEmProcess* proc,
111                                    const G4VEm    112                                    const G4VEmProcess* masterProc,
112                  const G4ParticleDefinition* f    113                  const G4ParticleDefinition* firstPart,
113                  const G4ParticleDefinition* p    114                  const G4ParticleDefinition* part,
114                  const G4int nModels, const G4    115                  const G4int nModels, const G4int verb,
115                                    const G4boo    116                                    const G4bool master, const G4bool isLocked,
116                                    const G4boo    117                                    const G4bool toBuild, G4bool& baseMat)
117 {                                                 118 {
118   G4String num = part->GetParticleName();         119   G4String num = part->GetParticleName();
119   if(1 < verb) {                                  120   if(1 < verb) {
120     G4cout << "### G4EmTableUtil::BuildPhysics << 121     G4cout << "### G4VEmProcess::BuildPhysicsTable() for "
121            << proc->GetProcessName() << " and     122            << proc->GetProcessName() << " and particle " << num
122            << " buildLambdaTable=" << toBuild     123            << " buildLambdaTable=" << toBuild << " master= " << master 
123            << G4endl;                             124            << G4endl;
124   }                                               125   }
125                                                   126 
126   if(firstPart == part) {                         127   if(firstPart == part) { 
127                                                   128 
128     // worker initialisation                      129     // worker initialisation
129     if(!master) {                                 130     if(!master) { 
130       proc->SetLambdaTable(masterProc->LambdaT    131       proc->SetLambdaTable(masterProc->LambdaTable());
131       proc->SetLambdaTablePrim(masterProc->Lam    132       proc->SetLambdaTablePrim(masterProc->LambdaTablePrim());
132       proc->SetCrossSectionType(masterProc->Cr    133       proc->SetCrossSectionType(masterProc->CrossSectionType());
133       proc->SetEnergyOfCrossSectionMax(masterP    134       proc->SetEnergyOfCrossSectionMax(masterProc->EnergyOfCrossSectionMax());
134                                                   135 
135       // local initialisation of models           136       // local initialisation of models
136       baseMat = masterProc->UseBaseMaterial();    137       baseMat = masterProc->UseBaseMaterial();
137       G4bool printing = true;                     138       G4bool printing = true;
138       for(G4int i=0; i<nModels; ++i) {            139       for(G4int i=0; i<nModels; ++i) {
139         G4VEmModel* mod = proc->GetModelByInde    140         G4VEmModel* mod = proc->GetModelByIndex(i, printing);
140         G4VEmModel* mod0= masterProc->GetModel    141         G4VEmModel* mod0= masterProc->GetModelByIndex(i, printing);
141         mod->SetUseBaseMaterials(baseMat);        142         mod->SetUseBaseMaterials(baseMat);
142         mod->InitialiseLocal(part, mod0);         143         mod->InitialiseLocal(part, mod0);
143       }                                           144       }
144       // master thread                            145       // master thread
145     } else {                                      146     } else {
146       if(toBuild) { proc->BuildLambdaTable();     147       if(toBuild) { proc->BuildLambdaTable(); }
147       auto fXSType = proc->CrossSectionType();    148       auto fXSType = proc->CrossSectionType();
148       auto v = proc->EnergyOfCrossSectionMax()    149       auto v = proc->EnergyOfCrossSectionMax();
149       delete v;                                   150       delete v;
150       v = nullptr;                                151       v = nullptr;
151       if(fXSType == fEmOnePeak) {                 152       if(fXSType == fEmOnePeak) {
152         auto table = proc->LambdaTable();         153         auto table = proc->LambdaTable();
153         if(nullptr == table) {                    154         if(nullptr == table) {
154     v = G4EmUtility::FindCrossSectionMax(proc,    155     v = G4EmUtility::FindCrossSectionMax(proc, part);
155   } else {                                        156   } else {
156     v = G4EmUtility::FindCrossSectionMax(table    157     v = G4EmUtility::FindCrossSectionMax(table);
157   }                                               158   }
158         if(nullptr == v) { proc->SetCrossSecti    159         if(nullptr == v) { proc->SetCrossSectionType(fEmIncreasing); }
159       }                                           160       }
160       proc->SetEnergyOfCrossSectionMax(v);        161       proc->SetEnergyOfCrossSectionMax(v);
161     }                                             162     }
162   }                                               163   }
163   // protection against double printout           164   // protection against double printout
164   if(isLocked) { return; }                        165   if(isLocked) { return; }
165                                                   166 
166   // explicitly defined printout by particle n    167   // explicitly defined printout by particle name
167   if(1 < verb || (0 < verb && (num == "gamma"     168   if(1 < verb || (0 < verb && (num == "gamma" || num == "e-" || 
168              num == "e+"    || num == "mu+" ||    169              num == "e+"    || num == "mu+" || 
169              num == "mu-"   || num == "proton"    170              num == "mu-"   || num == "proton"|| 
170              num == "pi+"   || num == "pi-" ||    171              num == "pi+"   || num == "pi-" || 
171              num == "kaon+" || num == "kaon-"     172              num == "kaon+" || num == "kaon-" || 
172              num == "alpha" || num == "anti_pr    173              num == "alpha" || num == "anti_proton" || 
173              num == "GenericIon" ||               174              num == "GenericIon" ||
174              num == "alpha+" || num == "helium    175              num == "alpha+" || num == "helium" ||
175              num == "hydrogen"))) {               176              num == "hydrogen"))) { 
176     proc->StreamInfo(G4cout, *part);              177     proc->StreamInfo(G4cout, *part);
177   }                                               178   }
178                                                   179 
179   if(1 < verb) {                                  180   if(1 < verb) {
180     G4cout << "### G4EmTableUtil::BuildPhysics << 181     G4cout << "### G4VEmProcess::BuildPhysicsTable() done for "
181            << proc->GetProcessName() << " and     182            << proc->GetProcessName() << " and particle " << num
182            << " baseMat=" << baseMat << G4endl    183            << " baseMat=" << baseMat << G4endl;
183   }                                               184   }
184 }                                                 185 }
185                                                   186 
186 //....oooOO0OOooo........oooOO0OOooo........oo    187 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
187                                                   188 
188 void G4EmTableUtil::BuildLambdaTable(G4VEmProc    189 void G4EmTableUtil::BuildLambdaTable(G4VEmProcess* proc,
189                                      const G4P    190                                      const G4ParticleDefinition* part,
190                                      G4EmModel    191                                      G4EmModelManager* modelManager,
191                    G4LossTableBuilder* bld,       192                    G4LossTableBuilder* bld,
192                                      G4Physics    193                                      G4PhysicsTable* theLambdaTable,
193                                      G4Physics    194                                      G4PhysicsTable* theLambdaTablePrim,
194                                      const G4d    195                                      const G4double minKinEnergy,
195                                      const G4d    196                                      const G4double minKinEnergyPrim,
196                                      const G4d    197                                      const G4double maxKinEnergy,
197                                      const G4d    198                                      const G4double scale,
198              const G4int verboseLevel,            199              const G4int verboseLevel,
199                                      const G4b    200                                      const G4bool startFromNull,
200                                      const G4b    201                                      const G4bool splineFlag)
201 {                                                 202 {
202   if(1 < verboseLevel) {                          203   if(1 < verboseLevel) {
203     G4cout << "G4EmTableUtil::BuildLambdaTable << 204     G4cout << "G4EmProcess::BuildLambdaTable() for process "
204            << proc->GetProcessName() << " and     205            << proc->GetProcessName() << " and particle "
205            << part->GetParticleName() << G4end    206            << part->GetParticleName() << G4endl;
206   }                                               207   }
207                                                   208 
208   // Access to materials                          209   // Access to materials
209   const G4ProductionCutsTable* theCoupleTable=    210   const G4ProductionCutsTable* theCoupleTable=
210         G4ProductionCutsTable::GetProductionCu    211         G4ProductionCutsTable::GetProductionCutsTable();
211   std::size_t numOfCouples = theCoupleTable->G    212   std::size_t numOfCouples = theCoupleTable->GetTableSize();
212                                                   213 
213   G4PhysicsLogVector* aVector = nullptr;          214   G4PhysicsLogVector* aVector = nullptr;
214   G4PhysicsLogVector* aVectorPrim = nullptr;      215   G4PhysicsLogVector* aVectorPrim = nullptr;
215   G4PhysicsLogVector* bVectorPrim = nullptr;      216   G4PhysicsLogVector* bVectorPrim = nullptr;
216                                                   217 
217   G4double emax1 = std::min(maxKinEnergy, minK    218   G4double emax1 = std::min(maxKinEnergy, minKinEnergyPrim);
218                                                   219     
219   for(std::size_t i=0; i<numOfCouples; ++i) {     220   for(std::size_t i=0; i<numOfCouples; ++i) {
220                                                   221 
221     if (bld->GetFlag(i)) {                        222     if (bld->GetFlag(i)) {
222       // create physics vector and fill it        223       // create physics vector and fill it
223       const G4MaterialCutsCouple* couple =        224       const G4MaterialCutsCouple* couple = 
224         theCoupleTable->GetMaterialCutsCouple(    225         theCoupleTable->GetMaterialCutsCouple((G4int)i);
225                                                   226 
226       // build main table                         227       // build main table
227       if(nullptr != theLambdaTable) {             228       if(nullptr != theLambdaTable) {
228         delete (*theLambdaTable)[i];              229         delete (*theLambdaTable)[i];
229                                                   230 
230         // if start from zero then change the     231         // if start from zero then change the scale
231         G4double emin = minKinEnergy;             232         G4double emin = minKinEnergy;
232         G4bool startNull = false;                 233         G4bool startNull = false;
233         if(startFromNull) {                       234         if(startFromNull) {
234           G4double e = proc->MinPrimaryEnergy(    235           G4double e = proc->MinPrimaryEnergy(part, couple->GetMaterial());
235           if(e >= emin) {                         236           if(e >= emin) {
236             emin = e;                             237             emin = e;
237             startNull = true;                     238             startNull = true;
238           }                                       239           }
239         }                                         240         }
240         G4double emax = emax1;                    241         G4double emax = emax1;
241         if(emax <= emin) { emax = 2*emin; }       242         if(emax <= emin) { emax = 2*emin; }
242         G4int bin = G4lrint(scale*G4Log(emax/e    243         G4int bin = G4lrint(scale*G4Log(emax/emin));
243         bin = std::max(bin, 5);                   244         bin = std::max(bin, 5);
244         aVector = new G4PhysicsLogVector(emin,    245         aVector = new G4PhysicsLogVector(emin, emax, bin, splineFlag);
245         modelManager->FillLambdaVector(aVector    246         modelManager->FillLambdaVector(aVector, couple, startNull);
246         if(splineFlag) { aVector->FillSecondDe    247         if(splineFlag) { aVector->FillSecondDerivatives(); }
247         G4PhysicsTableHelper::SetPhysicsVector    248         G4PhysicsTableHelper::SetPhysicsVector(theLambdaTable, i, aVector);
248       }                                           249       }
249       // build high energy table                  250       // build high energy table
250       if(nullptr != theLambdaTablePrim && minK << 251       if(nullptr != theLambdaTablePrim) {
251         delete (*theLambdaTablePrim)[i];          252         delete (*theLambdaTablePrim)[i];
252                                                   253 
253         // start not from zero and always use     254         // start not from zero and always use spline
254         if(nullptr == bVectorPrim) {              255         if(nullptr == bVectorPrim) {
255           G4int bin = G4lrint(scale*G4Log(maxK    256           G4int bin = G4lrint(scale*G4Log(maxKinEnergy/minKinEnergyPrim));
256           bin = std::max(bin, 5);                 257           bin = std::max(bin, 5);
257           aVectorPrim =                           258           aVectorPrim = 
258             new G4PhysicsLogVector(minKinEnerg    259             new G4PhysicsLogVector(minKinEnergyPrim, maxKinEnergy, bin, true);
259           bVectorPrim = aVectorPrim;              260           bVectorPrim = aVectorPrim;
260         } else {                                  261         } else {
261           aVectorPrim = new G4PhysicsLogVector    262           aVectorPrim = new G4PhysicsLogVector(*bVectorPrim);
262         }                                         263         }
263         modelManager->FillLambdaVector(aVector    264         modelManager->FillLambdaVector(aVectorPrim, couple, false, 
264                                        fIsCros    265                                        fIsCrossSectionPrim);
265         aVectorPrim->FillSecondDerivatives();     266         aVectorPrim->FillSecondDerivatives();
266         G4PhysicsTableHelper::SetPhysicsVector    267         G4PhysicsTableHelper::SetPhysicsVector(theLambdaTablePrim, i, 
267                                                   268                                                aVectorPrim);
268       }                                           269       }
269     }                                             270     }
270   }                                               271   }
271                                                   272 
272   if(1 < verboseLevel) {                          273   if(1 < verboseLevel) {
273     G4cout << "Lambda table is built for " <<     274     G4cout << "Lambda table is built for " << part->GetParticleName() << G4endl;
274   }                                               275   }
275 }                                                 276 }
276                                                   277 
277 //....oooOO0OOooo........oooOO0OOooo........oo    278 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
278                                                   279 
279 void  G4EmTableUtil::BuildLambdaTable(G4VEnerg    280 void  G4EmTableUtil::BuildLambdaTable(G4VEnergyLossProcess* proc,
280                                      const G4P    281                                      const G4ParticleDefinition* part,
281                                      G4EmModel    282                                      G4EmModelManager* modelManager,
282                    G4LossTableBuilder* bld,       283                    G4LossTableBuilder* bld,
283                                      G4Physics    284                                      G4PhysicsTable* theLambdaTable,
284                                      const G4D    285                                      const G4DataVector* theCuts,
285                                      const G4d    286                                      const G4double minKinEnergy,
286                                      const G4d    287                                      const G4double maxKinEnergy,
287                                      const G4d    288                                      const G4double scale,
288              const G4int verboseLevel,            289              const G4int verboseLevel,
289                                      const G4b    290                                      const G4bool splineFlag)
290 {                                                 291 {
291   if(1 < verboseLevel) {                          292   if(1 < verboseLevel) {
292     G4cout << "G4EmTableUtil::BuildLambdaTable << 293     G4cout << "G4EnergyLossProcess::BuildLambdaTable() for process "
293            << proc->GetProcessName() << " and     294            << proc->GetProcessName() << " and particle "
294            << part->GetParticleName() << G4end    295            << part->GetParticleName() << G4endl;
295   }                                               296   }
296                                                   297 
297   const G4ProductionCutsTable* theCoupleTable=    298   const G4ProductionCutsTable* theCoupleTable=
298         G4ProductionCutsTable::GetProductionCu    299         G4ProductionCutsTable::GetProductionCutsTable();
299   std::size_t numOfCouples = theCoupleTable->G    300   std::size_t numOfCouples = theCoupleTable->GetTableSize();
300                                                   301 
301   G4PhysicsLogVector* aVector = nullptr;          302   G4PhysicsLogVector* aVector = nullptr;
302   for(std::size_t i=0; i<numOfCouples; ++i) {     303   for(std::size_t i=0; i<numOfCouples; ++i) {
303     if (bld->GetFlag(i)) {                        304     if (bld->GetFlag(i)) {
304       // create physics vector and fill it        305       // create physics vector and fill it
305       const G4MaterialCutsCouple* couple =        306       const G4MaterialCutsCouple* couple = 
306         theCoupleTable->GetMaterialCutsCouple(    307         theCoupleTable->GetMaterialCutsCouple((G4int)i);
307                                                   308 
308       delete (*theLambdaTable)[i];                309       delete (*theLambdaTable)[i];
309       G4bool startNull = true;                    310       G4bool startNull = true;
310       G4double emin =                             311       G4double emin = 
311         proc->MinPrimaryEnergy(part, couple->G    312         proc->MinPrimaryEnergy(part, couple->GetMaterial(), (*theCuts)[i]);
312       if(minKinEnergy > emin) {                   313       if(minKinEnergy > emin) { 
313         emin = minKinEnergy;                      314         emin = minKinEnergy; 
314         startNull = false;                        315         startNull = false;
315       }                                           316       }
316                                                   317 
317       G4double emax = maxKinEnergy;               318       G4double emax = maxKinEnergy;
318       if(emax <= emin) { emax = 2*emin; }         319       if(emax <= emin) { emax = 2*emin; }
319       G4int bin = G4lrint(scale*G4Log(emax/emi    320       G4int bin = G4lrint(scale*G4Log(emax/emin));
320       bin = std::max(bin, 5);                     321       bin = std::max(bin, 5);
321       aVector = new G4PhysicsLogVector(emin, e    322       aVector = new G4PhysicsLogVector(emin, emax, bin, splineFlag);
322       modelManager->FillLambdaVector(aVector,     323       modelManager->FillLambdaVector(aVector, couple, startNull, fRestricted);
323       if(splineFlag) { aVector->FillSecondDeri    324       if(splineFlag) { aVector->FillSecondDerivatives(); }
324       G4PhysicsTableHelper::SetPhysicsVector(t    325       G4PhysicsTableHelper::SetPhysicsVector(theLambdaTable, i, aVector);
325     }                                             326     }
326   }                                               327   }
327                                                   328 
328   if(1 < verboseLevel) {                          329   if(1 < verboseLevel) {
329     G4cout << "Lambda table is built for " <<     330     G4cout << "Lambda table is built for " << part->GetParticleName() << G4endl;
330   }                                               331   }
331 }                                                 332 }
332                                                   333 
333 //....oooOO0OOooo........oooOO0OOooo........oo    334 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
334                                                   335 
335 const G4ParticleDefinition*                       336 const G4ParticleDefinition*
336 G4EmTableUtil::CheckIon(G4VEnergyLossProcess*     337 G4EmTableUtil::CheckIon(G4VEnergyLossProcess* proc,
337                         const G4ParticleDefini    338                         const G4ParticleDefinition* part,
338                         const G4ParticleDefini    339                         const G4ParticleDefinition* partLocal,
339                         const G4int verb, G4bo    340                         const G4int verb, G4bool& isIon)
340 {                                                 341 {
341   if(1 < verb) {                                  342   if(1 < verb) {
342     G4cout << "G4EmTableUtil::CheckIon for "   << 343     G4cout << "G4VEnergyLossProcess::PreparePhysicsTable for "
343            << proc->GetProcessName() << " for     344            << proc->GetProcessName() << " for " << part->GetParticleName() 
344            << " should be called from G4VEnerg << 
345            << G4endl;                             345            << G4endl;
346   }                                               346   }
347   const G4ParticleDefinition* particle = partL    347   const G4ParticleDefinition* particle = partLocal;
348                                                   348 
349   // Are particle defined?                        349   // Are particle defined?
350   if(nullptr == particle) { particle = part; }    350   if(nullptr == particle) { particle = part; }
351   if(part->GetParticleType() == "nucleus") {      351   if(part->GetParticleType() == "nucleus") {
352     G4String pname = part->GetParticleName();     352     G4String pname = part->GetParticleName();
353     if(pname != "deuteron" && pname != "triton    353     if(pname != "deuteron" && pname != "triton" &&
354        pname != "He3" && pname != "alpha+" &&  << 354        pname != "alpha+"   && pname != "alpha") {
355                                                   355 
356       const G4ParticleDefinition* theGIon = G4    356       const G4ParticleDefinition* theGIon = G4GenericIon::GenericIon();
357       isIon = true;                               357       isIon = true; 
358                                                   358 
359       // this is a loop to compare pointers of << 
360       // to confirm that for given particle th << 
361       if(particle != theGIon) {                   359       if(particle != theGIon) {
362         G4ProcessManager* pm = theGIon->GetPro    360         G4ProcessManager* pm = theGIon->GetProcessManager();
363         G4ProcessVector* v = pm->GetAlongStepP    361         G4ProcessVector* v = pm->GetAlongStepProcessVector();
364         G4int n = (G4int)v->size();               362         G4int n = (G4int)v->size();
365         for(G4int j=0; j<n; ++j) {                363         for(G4int j=0; j<n; ++j) {
366           if((*v)[j] == proc) {                   364           if((*v)[j] == proc) {
367             particle = theGIon;                   365             particle = theGIon;
368             break;                                366             break;
369           }                                       367           } 
370         }                                         368         }
371       }                                           369       }
372     }                                             370     }
373   }                                               371   }
374   return particle;                                372   return particle;
375 }                                                 373 }
376                                                   374 
377 //....oooOO0OOooo........oooOO0OOooo........oo    375 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
378                                                   376 
379 void G4EmTableUtil::UpdateModels(G4VEnergyLoss    377 void G4EmTableUtil::UpdateModels(G4VEnergyLossProcess* proc,
380                G4EmModelManager* modelManager,    378                G4EmModelManager* modelManager,
381                                  const G4doubl    379                                  const G4double maxKinEnergy,
382                                  const G4int n    380                                  const G4int nModels,
383                                  G4int& secID,    381                                  G4int& secID, G4int& biasID,
384                                  G4int& mainSe    382                                  G4int& mainSec, const G4bool baseMat,
385                                  const G4bool, << 383                                  const G4bool isMaster, const G4bool useAGen)
386 {                                                 384 {
387   // defined ID of secondary particles            385   // defined ID of secondary particles
388   G4int stype = proc->GetProcessSubType();        386   G4int stype = proc->GetProcessSubType();
389   if(stype == fBremsstrahlung) {                  387   if(stype == fBremsstrahlung) {
390     secID = _Bremsstrahlung;                      388     secID = _Bremsstrahlung;
391     biasID = _SplitBremsstrahlung;                389     biasID = _SplitBremsstrahlung;
392   } else if(stype == fPairProdByCharged) {        390   } else if(stype == fPairProdByCharged) {
393     secID = _PairProduction;                      391     secID = _PairProduction;
394     mainSec = 2;                                  392     mainSec = 2;
395   }                                               393   }
396                                                   394 
397   // initialisation of models                     395   // initialisation of models
398   for(G4int i=0; i<nModels; ++i) {                396   for(G4int i=0; i<nModels; ++i) {
399     G4VEmModel* mod = modelManager->GetModel(i    397     G4VEmModel* mod = modelManager->GetModel(i);
                                                   >> 398     mod->SetMasterThread(isMaster);
400     mod->SetAngularGeneratorFlag(useAGen);        399     mod->SetAngularGeneratorFlag(useAGen);
401     if(mod->HighEnergyLimit() > maxKinEnergy)     400     if(mod->HighEnergyLimit() > maxKinEnergy) {
402       mod->SetHighEnergyLimit(maxKinEnergy);      401       mod->SetHighEnergyLimit(maxKinEnergy);
403     }                                             402     }
404     mod->SetUseBaseMaterials(baseMat);            403     mod->SetUseBaseMaterials(baseMat);
405   }                                               404   }
406 }                                                 405 }
407                                                   406 
408 //....oooOO0OOooo........oooOO0OOooo........oo    407 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
409                                                   408 
410 void                                              409 void 
411 G4EmTableUtil::BuildLocalElossProcess(G4VEnerg    410 G4EmTableUtil::BuildLocalElossProcess(G4VEnergyLossProcess* proc,
412               const G4VEnergyLossProcess* mast    411               const G4VEnergyLossProcess* masterProc,
413               const G4ParticleDefinition* part    412               const G4ParticleDefinition* part,
414               const G4int nModels)                413               const G4int nModels)
415 {                                                 414 {
416   // copy table pointers from master thread       415   // copy table pointers from master thread
417   proc->SetDEDXTable(masterProc->DEDXTable(),f    416   proc->SetDEDXTable(masterProc->DEDXTable(),fRestricted);
418   proc->SetDEDXTable(masterProc->DEDXunRestric    417   proc->SetDEDXTable(masterProc->DEDXunRestrictedTable(),fTotal);
419   proc->SetDEDXTable(masterProc->IonisationTab    418   proc->SetDEDXTable(masterProc->IonisationTable(),fIsIonisation);
420   proc->SetRangeTableForLoss(masterProc->Range    419   proc->SetRangeTableForLoss(masterProc->RangeTableForLoss());
421   proc->SetCSDARangeTable(masterProc->CSDARang    420   proc->SetCSDARangeTable(masterProc->CSDARangeTable());
422   proc->SetInverseRangeTable(masterProc->Inver    421   proc->SetInverseRangeTable(masterProc->InverseRangeTable());
423   proc->SetLambdaTable(masterProc->LambdaTable    422   proc->SetLambdaTable(masterProc->LambdaTable());
424   proc->SetCrossSectionType(masterProc->CrossS    423   proc->SetCrossSectionType(masterProc->CrossSectionType());
425   proc->SetEnergyOfCrossSectionMax(masterProc-    424   proc->SetEnergyOfCrossSectionMax(masterProc->EnergyOfCrossSectionMax());
426   proc->SetTwoPeaksXS(masterProc->TwoPeaksXS()    425   proc->SetTwoPeaksXS(masterProc->TwoPeaksXS());
427   proc->SetIonisation(masterProc->IsIonisation    426   proc->SetIonisation(masterProc->IsIonisationProcess());
428   G4bool baseMat = masterProc->UseBaseMaterial    427   G4bool baseMat = masterProc->UseBaseMaterial();
429                                                   428 
430   // local initialisation of models               429   // local initialisation of models
431   G4bool printing = true;                         430   G4bool printing = true;
432   for(G4int i=0; i<nModels; ++i) {                431   for(G4int i=0; i<nModels; ++i) {
433     G4VEmModel* mod = proc->GetModelByIndex(i,    432     G4VEmModel* mod = proc->GetModelByIndex(i, printing);
434     G4VEmModel* mod0= masterProc->GetModelByIn    433     G4VEmModel* mod0= masterProc->GetModelByIndex(i, printing);
435     mod->SetUseBaseMaterials(baseMat);            434     mod->SetUseBaseMaterials(baseMat);
436     mod->InitialiseLocal(part, mod0);             435     mod->InitialiseLocal(part, mod0);
437   }                                               436   }
438 }                                                 437 }
439                                                   438 
440 //....oooOO0OOooo........oooOO0OOooo........oo    439 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
441                                                   440 
442 void G4EmTableUtil::BuildDEDXTable(G4VEnergyLo    441 void G4EmTableUtil::BuildDEDXTable(G4VEnergyLossProcess* proc,
443            const G4ParticleDefinition* part,      442            const G4ParticleDefinition* part,
444            G4EmModelManager* modelManager,        443            G4EmModelManager* modelManager,
445            G4LossTableBuilder* bld,               444            G4LossTableBuilder* bld,
446            G4PhysicsTable* table,                 445            G4PhysicsTable* table,
447            const G4double emin,                   446            const G4double emin,
448            const G4double emax,                   447            const G4double emax,
449            const G4int nbins,                     448            const G4int nbins,
450            const G4int verbose,                   449            const G4int verbose,
451            const G4EmTableType tType,             450            const G4EmTableType tType,
452            const G4bool spline)                   451            const G4bool spline)
453 {                                                 452 {
454   // Access to materials                          453   // Access to materials
455   const G4ProductionCutsTable* theCoupleTable=    454   const G4ProductionCutsTable* theCoupleTable=
456         G4ProductionCutsTable::GetProductionCu    455         G4ProductionCutsTable::GetProductionCutsTable();
457   std::size_t numOfCouples = theCoupleTable->G    456   std::size_t numOfCouples = theCoupleTable->GetTableSize();
458                                                   457 
459   if(1 < verbose) {                               458   if(1 < verbose) {
460     G4cout << numOfCouples << " couples" << "     459     G4cout << numOfCouples << " couples" << " minKinEnergy(MeV)= " << emin
461            << " maxKinEnergy(MeV)= " << emax <    460            << " maxKinEnergy(MeV)= " << emax << " nbins= " << nbins << G4endl;
462   }                                               461   }
463   G4PhysicsLogVector* aVector = nullptr;          462   G4PhysicsLogVector* aVector = nullptr;
464   G4PhysicsLogVector* bVector = nullptr;          463   G4PhysicsLogVector* bVector = nullptr;
465                                                   464 
466   for(std::size_t i=0; i<numOfCouples; ++i) {     465   for(std::size_t i=0; i<numOfCouples; ++i) {
467                                                   466 
468     if(1 < verbose) {                             467     if(1 < verbose) {
469       G4cout << "G4EmTableUtil::BuildDEDXVecto << 468       G4cout << "G4VEnergyLossProcess::BuildDEDXVector idx= " << i 
470              << "  flagTable=" << table->GetFl    469              << "  flagTable=" << table->GetFlag(i) 
471              << " flagBuilder=" << bld->GetFla    470              << " flagBuilder=" << bld->GetFlag(i) << G4endl;
472     }                                             471     }
473     if(bld->GetFlag(i)) {                         472     if(bld->GetFlag(i)) {
474                                                   473 
475       // create physics vector and fill it        474       // create physics vector and fill it
476       const G4MaterialCutsCouple* couple =        475       const G4MaterialCutsCouple* couple = 
477         theCoupleTable->GetMaterialCutsCouple(    476         theCoupleTable->GetMaterialCutsCouple((G4int)i);
478       delete (*table)[i];                         477       delete (*table)[i];
479       if(nullptr != bVector) {                    478       if(nullptr != bVector) {
480         aVector = new G4PhysicsLogVector(*bVec    479         aVector = new G4PhysicsLogVector(*bVector);
481       } else {                                    480       } else {
482         bVector = new G4PhysicsLogVector(emin,    481         bVector = new G4PhysicsLogVector(emin, emax, nbins, spline);
483         aVector = bVector;                        482         aVector = bVector;
484       }                                           483       }
485                                                   484 
486       modelManager->FillDEDXVector(aVector, co    485       modelManager->FillDEDXVector(aVector, couple, tType);
487       if(spline) { aVector->FillSecondDerivati    486       if(spline) { aVector->FillSecondDerivatives(); }
488                                                   487 
489       // Insert vector for this material into     488       // Insert vector for this material into the table
490       G4PhysicsTableHelper::SetPhysicsVector(t    489       G4PhysicsTableHelper::SetPhysicsVector(table, i, aVector);
491     }                                             490     }
492   }                                               491   }
493                                                   492 
494   if(1 < verbose) {                               493   if(1 < verbose) {
495     G4cout << "G4EmTableUtil::BuildDEDXTable() << 494     G4cout << "G4VEnergyLossProcess::BuildDEDXTable(): table is built for "
496            << part->GetParticleName()             495            << part->GetParticleName()
497            << " and process " << proc->GetProc    496            << " and process " << proc->GetProcessName()
498            << G4endl;                             497            << G4endl;
499     if(2 < verbose) G4cout << (*table) << G4en    498     if(2 < verbose) G4cout << (*table) << G4endl;
500   }                                               499   }
501 }                                                 500 }
502                                                   501 
503 //....oooOO0OOooo........oooOO0OOooo........oo    502 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
504                                                   503 
505 void G4EmTableUtil::PrepareMscProcess(G4VMulti    504 void G4EmTableUtil::PrepareMscProcess(G4VMultipleScattering* proc,
506               const G4ParticleDefinition& part    505               const G4ParticleDefinition& part,
507               G4EmModelManager* modelManager,     506               G4EmModelManager* modelManager,
508               G4MscStepLimitType& stepLimit,      507               G4MscStepLimitType& stepLimit,
509                                       G4double    508                                       G4double& facrange,
510               G4bool& latDisplacement, G4bool&    509               G4bool& latDisplacement, G4bool& master,
511               G4bool& isIon, G4bool& baseMat)     510               G4bool& isIon, G4bool& baseMat)
512 {                                                 511 {
513   auto param = G4EmParameters::Instance();        512   auto param = G4EmParameters::Instance();
514   G4int verb = (master) ? param->Verbose() : p    513   G4int verb = (master) ? param->Verbose() : param->WorkerVerbose(); 
515   proc->SetVerboseLevel(verb);                    514   proc->SetVerboseLevel(verb);
516                                                   515 
517   if(part.GetPDGMass() > CLHEP::GeV ||            516   if(part.GetPDGMass() > CLHEP::GeV ||
518      part.GetParticleName() == "GenericIon") {    517      part.GetParticleName() == "GenericIon") { isIon = true; }
519                                                   518 
520   if(1 < verb) {                                  519   if(1 < verb) {
521     G4cout << "### G4EmTableUtil::PrepearPhysi << 520     G4cout << "### G4VMultipleScattering::PrepearPhysicsTable() for "
522            << proc->GetProcessName()              521            << proc->GetProcessName()
523            << " and particle " << part.GetPart    522            << " and particle " << part.GetParticleName()
524            << " isIon: " << isIon << " isMaste    523            << " isIon: " << isIon << " isMaster: " << master
525      << G4endl;                                   524      << G4endl;
526   }                                               525   }
527                                                   526 
528   // initialise process                           527   // initialise process
529   proc->InitialiseProcess(&part);                 528   proc->InitialiseProcess(&part);
530                                                   529 
531   // heavy particles                              530   // heavy particles 
532   if(part.GetPDGMass() > CLHEP::MeV) {            531   if(part.GetPDGMass() > CLHEP::MeV) {
533     stepLimit = param->MscMuHadStepLimitType()    532     stepLimit = param->MscMuHadStepLimitType(); 
534     facrange = param->MscMuHadRangeFactor();      533     facrange = param->MscMuHadRangeFactor(); 
535     latDisplacement = param->MuHadLateralDispl    534     latDisplacement = param->MuHadLateralDisplacement();
536   } else {                                        535   } else {
537     stepLimit = param->MscStepLimitType();        536     stepLimit = param->MscStepLimitType(); 
538     facrange = param->MscRangeFactor();           537     facrange = param->MscRangeFactor(); 
539     latDisplacement = param->LateralDisplaceme    538     latDisplacement = param->LateralDisplacement();
540   }                                               539   }
541                                                   540 
542   // initialisation of models                     541   // initialisation of models
543   auto numberOfModels = modelManager->NumberOf    542   auto numberOfModels = modelManager->NumberOfModels();
544   for(G4int i=0; i<numberOfModels; ++i) {         543   for(G4int i=0; i<numberOfModels; ++i) {
545     G4VMscModel* msc = proc->GetModelByIndex(i    544     G4VMscModel* msc = proc->GetModelByIndex(i);
546     msc->SetIonisation(nullptr, &part);           545     msc->SetIonisation(nullptr, &part);
                                                   >> 546     msc->SetMasterThread(master);
547     msc->SetPolarAngleLimit(param->MscThetaLim    547     msc->SetPolarAngleLimit(param->MscThetaLimit());
548     G4double emax = std::min(msc->HighEnergyLi    548     G4double emax = std::min(msc->HighEnergyLimit(),param->MaxKinEnergy());
549     msc->SetHighEnergyLimit(emax);                549     msc->SetHighEnergyLimit(emax);
550     msc->SetUseBaseMaterials(baseMat);            550     msc->SetUseBaseMaterials(baseMat);
551   }                                               551   }
552   modelManager->Initialise(&part, nullptr, ver    552   modelManager->Initialise(&part, nullptr, verb);
553 }                                                 553 }
554                                                   554 
555 //....oooOO0OOooo........oooOO0OOooo........oo    555 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
556                                                   556 
557 void G4EmTableUtil::BuildMscProcess(G4VMultipl    557 void G4EmTableUtil::BuildMscProcess(G4VMultipleScattering* proc,
558                                     const G4VM    558                                     const G4VMultipleScattering* masterProc,
559                         const G4ParticleDefini    559                         const G4ParticleDefinition& part,
560                         const G4ParticleDefini    560                         const G4ParticleDefinition* firstPart,
561             G4int nModels, G4bool master)         561             G4int nModels, G4bool master)
562 {                                                 562 {
563   auto param = G4EmParameters::Instance();        563   auto param = G4EmParameters::Instance();
564   G4int verb = param->Verbose();                  564   G4int verb = param->Verbose(); 
565                                                   565 
566   if (firstPart == &part) {                    << 566   if(!master && firstPart == &part) {
567     G4LossTableBuilder* bld = G4LossTableManag << 567     // initialisation of models
568     G4bool baseMat = bld->GetBaseMaterialFlag( << 568     G4bool baseMat = masterProc->UseBaseMaterial();
569     if (master) {                              << 569     for(G4int i=0; i<nModels; ++i) {
570       for (G4int i=0; i<nModels; ++i) {        << 570       G4VMscModel* msc = proc->GetModelByIndex(i);
571   G4VMscModel* msc = proc->GetModelByIndex(i); << 571       G4VMscModel* msc0 = masterProc->GetModelByIndex(i);
572   msc->SetUseBaseMaterials(baseMat);           << 572       msc->SetUseBaseMaterials(baseMat);
573   // table is always built for low mass partic << 573       msc->SetCrossSectionTable(msc0->GetCrossSectionTable(), false);
574         if (part.GetParticleName() != "Generic << 574       msc->InitialiseLocal(&part, msc0);
575       (part.GetPDGMass() < CLHEP::GeV || msc-> << 
576     G4double emin =                            << 
577       std::max(msc->LowEnergyLimit(), msc->Low << 
578     G4double emax =                            << 
579       std::min(msc->HighEnergyLimit(), msc->Hi << 
580     emin = std::max(emin, param->MinKinEnergy( << 
581     emax = std::min(emax, param->MaxKinEnergy( << 
582     if (emin < emax) {                         << 
583       auto table = bld->BuildTableForModel(msc << 
584              msc, &part, emin, emax, true);    << 
585       msc->SetCrossSectionTable(table, true);  << 
586     }                                          << 
587   }                                            << 
588       }                                        << 
589     } else {                                   << 
590       for (G4int i=0; i<nModels; ++i) {        << 
591   G4VMscModel* msc = proc->GetModelByIndex(i); << 
592   G4VMscModel* msc0 = masterProc->GetModelByIn << 
593   msc->SetUseBaseMaterials(baseMat);           << 
594   msc->SetCrossSectionTable(msc0->GetCrossSect << 
595   msc->InitialiseLocal(&part, msc0);           << 
596       }                                        << 
597     }                                             575     }
598   }                                               576   }
599   if(!param->IsPrintLocked()) {                   577   if(!param->IsPrintLocked()) {
600     const G4String& num = part.GetParticleName    578     const G4String& num = part.GetParticleName();
601                                                   579 
602     // explicitly defined printout by particle    580     // explicitly defined printout by particle name
603     if(1 < verb || (0 < verb && (num == "e-" |    581     if(1 < verb || (0 < verb && (num == "e-" || 
604          num == "e+"    || num == "mu+" ||        582          num == "e+"    || num == "mu+" || 
605          num == "mu-"   || num == "proton"||      583          num == "mu-"   || num == "proton"|| 
606          num == "pi+"   || num == "pi-" ||        584          num == "pi+"   || num == "pi-" || 
607          num == "kaon+" || num == "kaon-" ||      585          num == "kaon+" || num == "kaon-" || 
608          num == "alpha" || num == "anti_proton    586          num == "alpha" || num == "anti_proton" || 
609          num == "GenericIon" || num == "alpha+    587          num == "GenericIon" || num == "alpha+" || 
610          num == "alpha" ))) {                     588          num == "alpha" ))) { 
611       proc->StreamInfo(G4cout, part);             589       proc->StreamInfo(G4cout, part);
612     }                                             590     }
613   }                                               591   }
614   if(1 < verb) {                                  592   if(1 < verb) {
615     G4cout << "### G4EmTableUtil::BuildPhysics << 593     G4cout << "### G4VMultipleScattering::BuildPhysicsTable() done for "
616      << proc->GetProcessName()                    594      << proc->GetProcessName()
617      << " and particle " << part.GetParticleNa    595      << " and particle " << part.GetParticleName() << G4endl;
618   }                                               596   }
619 }                                                 597 }
620                                                   598 
621 //....oooOO0OOooo........oooOO0OOooo........oo    599 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
622                                                   600 
623 G4bool G4EmTableUtil::StoreMscTable(G4VMultipl    601 G4bool G4EmTableUtil::StoreMscTable(G4VMultipleScattering* proc,
624                                     const G4Pa    602                                     const G4ParticleDefinition* part,
625                                     const G4St    603                                     const G4String& dir,
626                                     const G4in    604                                     const G4int nModels, const G4int verb,
627                         const G4bool ascii)       605                         const G4bool ascii)
628 {                                                 606 {
629   G4bool ok = true;                               607   G4bool ok = true;
630   for(G4int i=0; i<nModels; ++i) {                608   for(G4int i=0; i<nModels; ++i) {
631     G4VMscModel* msc = proc->GetModelByIndex(i    609     G4VMscModel* msc = proc->GetModelByIndex(i);
632     G4PhysicsTable* table = msc->GetCrossSecti    610     G4PhysicsTable* table = msc->GetCrossSectionTable();
633     if (nullptr != table) {                       611     if (nullptr != table) {
634       G4String ss = G4UIcommand::ConvertToStri    612       G4String ss = G4UIcommand::ConvertToString(i);
635       G4String name =                             613       G4String name = 
636         proc->GetPhysicsTableFileName(part, di    614         proc->GetPhysicsTableFileName(part, dir, "LambdaMod"+ss, ascii);
637       G4bool yes = table->StorePhysicsTable(na    615       G4bool yes = table->StorePhysicsTable(name,ascii);
638                                                   616 
639       if ( yes ) {                                617       if ( yes ) {
640         if ( verb > 0 ) {                         618         if ( verb > 0 ) {
641           G4cout << "Physics table are stored     619           G4cout << "Physics table are stored for " 
642                  << part->GetParticleName()       620                  << part->GetParticleName()
643                  << " and process " << proc->G    621                  << " and process " << proc->GetProcessName()
644                  << " with a name <" << name <    622                  << " with a name <" << name << "> " << G4endl;
645         }                                         623         }
646       } else {                                    624       } else {
647         G4cout << "Fail to store Physics Table    625         G4cout << "Fail to store Physics Table for " 
648                << part->GetParticleName()         626                << part->GetParticleName()
649                << " and process " << proc->Get    627                << " and process " << proc->GetProcessName()
650                << " in the directory <" << dir    628                << " in the directory <" << dir
651                << "> " << G4endl;                 629                << "> " << G4endl;
652   ok = false;                                     630   ok = false;
653       }                                           631       }
654     }                                             632     }
655   }                                               633   }
656   return ok;                                      634   return ok;
657 }                                                 635 }
658                                                   636 
659 //....oooOO0OOooo........oooOO0OOooo........oo    637 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
660                                                   638 
661 G4bool G4EmTableUtil::StoreTable(G4VProcess* p    639 G4bool G4EmTableUtil::StoreTable(G4VProcess* ptr,
662                                  const G4Parti    640                                  const G4ParticleDefinition* part, 
663                                  G4PhysicsTabl    641                                  G4PhysicsTable* aTable, 
664                                  const G4Strin    642                                  const G4String& dir,
665                                  const G4Strin    643                                  const G4String& tname,
666                                  const G4int v    644                                  const G4int verb, const G4bool ascii)
667 {                                                 645 {
668   G4bool res = true;                              646   G4bool res = true;
669   if (nullptr != aTable) {                        647   if (nullptr != aTable) {
670     const G4String& name =                        648     const G4String& name = 
671       ptr->GetPhysicsTableFileName(part, dir,     649       ptr->GetPhysicsTableFileName(part, dir, tname, ascii);
672     if ( aTable->StorePhysicsTable(name, ascii    650     if ( aTable->StorePhysicsTable(name, ascii) ) {
673       if (1 < verb) G4cout << "Stored: " << na    651       if (1 < verb) G4cout << "Stored: " << name << G4endl;
674     } else {                                      652     } else {
675       res = false;                                653       res = false;
676       G4cout << "G4EmTableUtil::StoreTable fai << 654       G4cout << "Fail to store: " << name << G4endl;
677     }                                             655     }
678   }                                               656   }
679   return res;                                     657   return res;
680 }                                                 658 }
681                                                   659 
682 //....oooOO0OOooo........oooOO0OOooo........oo    660 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
683                                                   661 
684 G4bool G4EmTableUtil::RetrieveTable(G4VProcess    662 G4bool G4EmTableUtil::RetrieveTable(G4VProcess* ptr,
685                                     const G4Pa    663                                     const G4ParticleDefinition* part, 
686                                     G4PhysicsT    664                                     G4PhysicsTable* aTable, 
687                                     const G4St    665                                     const G4String& dir, const G4String& tname,
688                                     const G4in    666                                     const G4int verb, const G4bool ascii,
689                                     const G4bo    667                                     const G4bool spline)
690 {                                                 668 {
691   G4bool res = true;                              669   G4bool res = true;
692   if (nullptr == aTable) { return res; }          670   if (nullptr == aTable) { return res; }
693   if (1 < verb) {                              << 671   G4cout << tname << " table for " << part->GetParticleName() 
694     G4cout << tname << " table for " << part-> << 672    << " will be retrieved " << G4endl;
695            << " will be retrieved " << G4endl; << 
696   }                                            << 
697   const G4String& name =                          673   const G4String& name = 
698     ptr->GetPhysicsTableFileName(part, dir, tn    674     ptr->GetPhysicsTableFileName(part, dir, tname, ascii);
699   if(G4PhysicsTableHelper::RetrievePhysicsTabl    675   if(G4PhysicsTableHelper::RetrievePhysicsTable(aTable, name, ascii, spline)) {
700     if(spline) {                                  676     if(spline) {
701       for(auto & v : *aTable) {                   677       for(auto & v : *aTable) {
702   if(nullptr != v) { v->FillSecondDerivatives(    678   if(nullptr != v) { v->FillSecondDerivatives(); }
703       }                                           679       }
704     }                                             680     }
705     if (0 < verb) {                               681     if (0 < verb) {
706       G4cout << tname << " table for " << part    682       G4cout << tname << " table for " << part->GetParticleName() 
707        << " is retrieved from <" << name << "> << 683        << " is Retrieved from <" << name << ">"
708        << G4endl;                                 684        << G4endl;
709     }                                             685     }
710   } else {                                        686   } else {
711     res = false;                                  687     res = false;
712     G4cout << "G4EmTableUtil::RetrieveTable fa << 688     G4cout << "Fail to retrieve: " << tname << " from " << name << " for " 
713            << " from " << name << " for " << p << 689      << part->GetParticleName() << G4endl;
714   }                                               690   }
715   return res;                                     691   return res;
716 }                                                 692 }
717                                                   693 
718 //....oooOO0OOooo........oooOO0OOooo........oo    694 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
719                                                   695 
720                                                   696