Geant4 Cross Reference

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


  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 // $Id: G4VEnergyLossProcess.cc,v 1.174 2010-12-27 17:42:21 vnivanch Exp $
                                                   >>  27 // GEANT4 tag $Name: not supported by cvs2svn $
                                                   >>  28 //
 26 // -------------------------------------------     29 // -------------------------------------------------------------------
 27 //                                                 30 //
 28 // GEANT4 Class file                               31 // GEANT4 Class file
 29 //                                                 32 //
 30 //                                                 33 //
 31 // File name:     G4VEnergyLossProcess             34 // File name:     G4VEnergyLossProcess
 32 //                                                 35 //
 33 // Author:        Vladimir Ivanchenko              36 // Author:        Vladimir Ivanchenko
 34 //                                                 37 //
 35 // Creation date: 03.01.2002                       38 // Creation date: 03.01.2002
 36 //                                                 39 //
 37 // Modifications: Vladimir Ivanchenko          <<  40 // Modifications:
 38 //                                                 41 //
                                                   >>  42 // 13-11-02 Minor fix - use normalised direction (V.Ivanchenko)
                                                   >>  43 // 04-12-02 Minor change in PostStepDoIt (V.Ivanchenko)
                                                   >>  44 // 23-12-02 Change interface in order to move to cut per region (V.Ivanchenko)
                                                   >>  45 // 26-12-02 Secondary production moved to derived classes (V.Ivanchenko)
                                                   >>  46 // 04-01-03 Fix problem of very small steps for ions (V.Ivanchenko)
                                                   >>  47 // 20-01-03 Migrade to cut per region (V.Ivanchenko)
                                                   >>  48 // 24-01-03 Temporarily close a control on usage of couples (V.Ivanchenko)
                                                   >>  49 // 24-01-03 Make models region aware (V.Ivanchenko)
                                                   >>  50 // 05-02-03 Fix compilation warnings (V.Ivanchenko)
                                                   >>  51 // 06-02-03 Add control on tmax in PostStepDoIt (V.Ivanchenko)
                                                   >>  52 // 13-02-03 SubCutoffProcessors defined for regions (V.Ivanchenko)
                                                   >>  53 // 15-02-03 Lambda table can be scaled (V.Ivanchenko)
                                                   >>  54 // 17-02-03 Fix problem of store/restore tables (V.Ivanchenko)
                                                   >>  55 // 18-02-03 Add control on CutCouple usage (V.Ivanchenko)
                                                   >>  56 // 26-02-03 Simplify control on GenericIons (V.Ivanchenko)
                                                   >>  57 // 06-03-03 Control on GenericIons using SubType + update verbose (V.Ivanchenko)
                                                   >>  58 // 10-03-03 Add Ion registration (V.Ivanchenko)
                                                   >>  59 // 22-03-03 Add Initialisation of cash (V.Ivanchenko)
                                                   >>  60 // 26-03-03 Remove finalRange modification (V.Ivanchenko)
                                                   >>  61 // 09-04-03 Fix problem of negative range limit for non integral (V.Ivanchenko)
                                                   >>  62 // 26-04-03 Fix retrieve tables (V.Ivanchenko)
                                                   >>  63 // 06-05-03 Set defalt finalRange = 1 mm (V.Ivanchenko)
                                                   >>  64 // 12-05-03 Update range calculations + lowKinEnergy (V.Ivanchenko)
                                                   >>  65 // 13-05-03 Add calculation of precise range (V.Ivanchenko)
                                                   >>  66 // 23-05-03 Remove tracking cuts (V.Ivanchenko)
                                                   >>  67 // 03-06-03 Fix initialisation problem for STD ionisation (V.Ivanchenko)
                                                   >>  68 // 21-07-03 Add UpdateEmModel method (V.Ivanchenko)
                                                   >>  69 // 03-11-03 Fix initialisation problem in RetrievePhysicsTable (V.Ivanchenko)
                                                   >>  70 // 04-11-03 Add checks in RetrievePhysicsTable (V.Ivanchenko)
                                                   >>  71 // 12-11-03 G4EnergyLossSTD -> G4EnergyLossProcess (V.Ivanchenko)
                                                   >>  72 // 21-01-04 Migrade to G4ParticleChangeForLoss (V.Ivanchenko)
                                                   >>  73 // 27-02-04 Fix problem of loss in low presure gases, cleanup precise range
                                                   >>  74 //          calculation, use functions ForLoss in AlongStepDoIt (V.Ivanchenko)
                                                   >>  75 // 10-03-04 Fix a problem of Precise Range table (V.Ivanchenko)
                                                   >>  76 // 19-03-04 Fix a problem energy below lowestKinEnergy (V.Ivanchenko)
                                                   >>  77 // 31-03-04 Fix a problem of retrieve tables (V.Ivanchenko)
                                                   >>  78 // 21-07-04 Check weather AtRest are active or not (V.Ivanchenko)
                                                   >>  79 // 03-08-04 Add pointer of DEDX table to all processes (V.Ivanchenko)
                                                   >>  80 // 06-08-04 Clear up names of member functions (V.Ivanchenko)
                                                   >>  81 // 06-08-04 Clear up names of member functions (V.Ivanchenko)
                                                   >>  82 // 27-08-04 Add NeedBuildTables method (V.Ivanchneko)
                                                   >>  83 // 08-11-04 Migration to new interface of Store/Retrieve tables (V.Ivantchenko)
                                                   >>  84 // 11-03-05 Shift verbose level by 1 (V.Ivantchenko)
                                                   >>  85 // 08-04-05 Major optimisation of internal interfaces (V.Ivantchenko)
                                                   >>  86 // 11-04-05 Use MaxSecondaryEnergy from a model (V.Ivanchenko)
                                                   >>  87 // 25-07-05 Add extra protection PostStep for non-integral mode (V.Ivanchenko)
                                                   >>  88 // 12-08-05 Integral=false; SetStepFunction(0.2, 0.1*mm) (mma)
                                                   >>  89 // 18-08-05 Return back both AlongStep and PostStep from 7.0 (V.Ivanchenko)
                                                   >>  90 // 02-09-05 Default StepFunction 0.2 1 mm + integral (V.Ivanchenko)
                                                   >>  91 // 04-09-05 default lambdaFactor 0.8 (V.Ivanchenko)
                                                   >>  92 // 05-10-05 protection against 0 energy loss added (L.Urban)
                                                   >>  93 // 17-10-05 protection above has been removed (L.Urban)
                                                   >>  94 // 06-01-06 reset currentCouple when StepFunction is changed (V.Ivanchenko)
                                                   >>  95 // 10-01-06 PreciseRange -> CSDARange (V.Ivantchenko)
                                                   >>  96 // 18-01-06 Clean up subcutoff including recalculation of presafety (VI)
                                                   >>  97 // 20-01-06 Introduce G4EmTableType and reducing number of methods (VI)
                                                   >>  98 // 22-03-06 Add control on warning printout AlongStep (VI)
                                                   >>  99 // 23-03-06 Use isIonisation flag (V.Ivanchenko)
                                                   >> 100 // 07-06-06 Do not reflect AlongStep in subcutoff regime (V.Ivanchenko)
                                                   >> 101 // 14-01-07 add SetEmModel(index) and SetFluctModel() (mma)
                                                   >> 102 // 16-01-07 add IonisationTable and IonisationSubTable (V.Ivanchenko)
                                                   >> 103 // 16-02-07 set linLossLimit=1.e-6 (V.Ivanchenko)
                                                   >> 104 // 13-03-07 use SafetyHelper instead of navigator (V.Ivanchenko)
                                                   >> 105 // 10-04-07 use unique SafetyHelper (V.Ivanchenko)
                                                   >> 106 // 12-04-07 Add verbosity at destruction (V.Ivanchenko)
                                                   >> 107 // 25-04-07 move initialisation of safety helper to BuildPhysicsTable (VI)
                                                   >> 108 // 27-10-07 Virtual functions moved to source (V.Ivanchenko)
                                                   >> 109 // 24-06-09 Removed hidden bin in G4PhysicsVector (V.Ivanchenko)
                                                   >> 110 // 15-10-10 Fixed 4-momentum balance if deexcitation is active (L.Pandola)
 39 //                                                111 //
 40 // Class Description:                             112 // Class Description:
 41 //                                                113 //
 42 // It is the unified energy loss process it ca    114 // It is the unified energy loss process it calculates the continuous
 43 // energy loss for charged particles using a s    115 // energy loss for charged particles using a set of Energy Loss
 44 // models valid for different energy regions.     116 // models valid for different energy regions. There are a possibility
 45 // to create and access to dE/dx and range tab    117 // to create and access to dE/dx and range tables, or to calculate
 46 // that information on fly.                       118 // that information on fly.
 47 // -------------------------------------------    119 // -------------------------------------------------------------------
 48 //                                                120 //
 49 //....oooOO0OOooo........oooOO0OOooo........oo    121 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 50 //....oooOO0OOooo........oooOO0OOooo........oo    122 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 51                                                   123 
 52 #include "G4VEnergyLossProcess.hh"                124 #include "G4VEnergyLossProcess.hh"
 53 #include "G4PhysicalConstants.hh"              << 
 54 #include "G4SystemOfUnits.hh"                  << 
 55 #include "G4ProcessManager.hh"                    125 #include "G4ProcessManager.hh"
 56 #include "G4LossTableManager.hh"                  126 #include "G4LossTableManager.hh"
 57 #include "G4LossTableBuilder.hh"                  127 #include "G4LossTableBuilder.hh"
 58 #include "G4Step.hh"                              128 #include "G4Step.hh"
 59 #include "G4ParticleDefinition.hh"                129 #include "G4ParticleDefinition.hh"
 60 #include "G4ParticleTable.hh"                  << 
 61 #include "G4EmParameters.hh"                   << 
 62 #include "G4EmUtility.hh"                      << 
 63 #include "G4EmTableUtil.hh"                    << 
 64 #include "G4VEmModel.hh"                          130 #include "G4VEmModel.hh"
 65 #include "G4VEmFluctuationModel.hh"               131 #include "G4VEmFluctuationModel.hh"
 66 #include "G4DataVector.hh"                        132 #include "G4DataVector.hh"
 67 #include "G4PhysicsLogVector.hh"                  133 #include "G4PhysicsLogVector.hh"
 68 #include "G4VParticleChange.hh"                   134 #include "G4VParticleChange.hh"
                                                   >> 135 #include "G4Gamma.hh"
 69 #include "G4Electron.hh"                          136 #include "G4Electron.hh"
                                                   >> 137 #include "G4Positron.hh"
                                                   >> 138 #include "G4Proton.hh"
 70 #include "G4ProcessManager.hh"                    139 #include "G4ProcessManager.hh"
 71 #include "G4UnitsTable.hh"                        140 #include "G4UnitsTable.hh"
                                                   >> 141 #include "G4GenericIon.hh"
                                                   >> 142 #include "G4ProductionCutsTable.hh"
 72 #include "G4Region.hh"                            143 #include "G4Region.hh"
 73 #include "G4RegionStore.hh"                       144 #include "G4RegionStore.hh"
 74 #include "G4PhysicsTableHelper.hh"                145 #include "G4PhysicsTableHelper.hh"
 75 #include "G4SafetyHelper.hh"                      146 #include "G4SafetyHelper.hh"
 76 #include "G4EmDataHandler.hh"                  << 
 77 #include "G4TransportationManager.hh"             147 #include "G4TransportationManager.hh"
                                                   >> 148 #include "G4EmConfigurator.hh"
 78 #include "G4VAtomDeexcitation.hh"                 149 #include "G4VAtomDeexcitation.hh"
 79 #include "G4VSubCutProducer.hh"                << 
 80 #include "G4EmBiasingManager.hh"                  150 #include "G4EmBiasingManager.hh"
 81 #include "G4Log.hh"                            << 
 82 #include <iostream>                            << 
 83                                                   151 
 84 //....oooOO0OOooo........oooOO0OOooo........oo    152 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 85                                                   153 
 86 namespace                                      << 
 87 {                                              << 
 88   G4String tnames[7] =                         << 
 89     {"DEDX","Ionisation","DEDXnr","CSDARange", << 
 90 }                                              << 
 91                                                << 
 92                                                << 
 93 G4VEnergyLossProcess::G4VEnergyLossProcess(con    154 G4VEnergyLossProcess::G4VEnergyLossProcess(const G4String& name, 
 94                                            G4P << 155              G4ProcessType type): 
 95   G4VContinuousDiscreteProcess(name, type)     << 156   G4VContinuousDiscreteProcess(name, type),
                                                   >> 157   secondaryParticle(0),
                                                   >> 158   nSCoffRegions(0),
                                                   >> 159   idxSCoffRegions(0),
                                                   >> 160   nProcesses(0),
                                                   >> 161   theDEDXTable(0),
                                                   >> 162   theDEDXSubTable(0),
                                                   >> 163   theDEDXunRestrictedTable(0),
                                                   >> 164   theIonisationTable(0),
                                                   >> 165   theIonisationSubTable(0),
                                                   >> 166   theRangeTableForLoss(0),
                                                   >> 167   theCSDARangeTable(0),
                                                   >> 168   theSecondaryRangeTable(0),
                                                   >> 169   theInverseRangeTable(0),
                                                   >> 170   theLambdaTable(0),
                                                   >> 171   theSubLambdaTable(0),
                                                   >> 172   theDensityFactor(0),
                                                   >> 173   theDensityIdx(0),
                                                   >> 174   baseParticle(0),
                                                   >> 175   minSubRange(0.1),
                                                   >> 176   lossFluctuationFlag(true),
                                                   >> 177   rndmStepFlag(false),
                                                   >> 178   tablesAreBuilt(false),
                                                   >> 179   integral(true),
                                                   >> 180   isIon(false),
                                                   >> 181   isIonisation(true),
                                                   >> 182   useSubCutoff(false),
                                                   >> 183   useDeexcitation(false),
                                                   >> 184   particle(0),
                                                   >> 185   currentCouple(0),
                                                   >> 186   nWarnings(0),
                                                   >> 187   mfpKinEnergy(0.0)
 96 {                                                 188 {
 97   theParameters = G4EmParameters::Instance();  << 
 98   SetVerboseLevel(1);                             189   SetVerboseLevel(1);
 99                                                   190 
100   // low energy limit                             191   // low energy limit
101   lowestKinEnergy = theParameters->LowestElect << 192   lowestKinEnergy  = 1.*eV;
102                                                   193 
103   // Size of tables                            << 194   // Size of tables assuming spline
104   minKinEnergy     = 0.1*CLHEP::keV;           << 195   minKinEnergy     = 0.1*keV;
105   maxKinEnergy     = 100.0*CLHEP::TeV;         << 196   maxKinEnergy     = 10.0*TeV;
106   maxKinEnergyCSDA = 1.0*CLHEP::GeV;           << 197   nBins            = 77;
107   nBins            = 84;                       << 198   maxKinEnergyCSDA = 1.0*GeV;
108   nBinsCSDA        = 35;                          199   nBinsCSDA        = 35;
109                                                   200 
110   invLambdaFactor = 1.0/lambdaFactor;          << 201   // default linear loss limit for spline
                                                   >> 202   linLossLimit  = 0.01;
                                                   >> 203 
                                                   >> 204   // default dRoverRange and finalRange
                                                   >> 205   SetStepFunction(0.2, 1.0*mm);
                                                   >> 206 
                                                   >> 207   // default lambda factor
                                                   >> 208   lambdaFactor  = 0.8;
111                                                   209 
112   // default linear loss limit                 << 210   // cross section biasing
113   finalRange = 1.*CLHEP::mm;                   << 211   biasFactor = 1.0;
                                                   >> 212 
                                                   >> 213   // particle types
                                                   >> 214   theElectron   = G4Electron::Electron();
                                                   >> 215   thePositron   = G4Positron::Positron();
                                                   >> 216   theGamma      = G4Gamma::Gamma();
                                                   >> 217   theGenericIon = 0;
114                                                   218 
115   // run time objects                             219   // run time objects
116   pParticleChange = &fParticleChange;             220   pParticleChange = &fParticleChange;
117   fParticleChange.SetSecondaryWeightByProcess(    221   fParticleChange.SetSecondaryWeightByProcess(true);
118   modelManager = new G4EmModelManager();          222   modelManager = new G4EmModelManager();
119   safetyHelper = G4TransportationManager::GetT    223   safetyHelper = G4TransportationManager::GetTransportationManager()
120     ->GetSafetyHelper();                          224     ->GetSafetyHelper();
121   aGPILSelection = CandidateForSelection;         225   aGPILSelection = CandidateForSelection;
122                                                   226 
123   // initialise model                             227   // initialise model
124   lManager = G4LossTableManager::Instance();   << 228   (G4LossTableManager::Instance())->Register(this);
125   lManager->Register(this);                    << 229   fluctModel = 0;
126   isMaster = lManager->IsMaster();             << 230   atomDeexcitation = 0;
                                                   >> 231 
                                                   >> 232   biasManager  = 0;
                                                   >> 233   biasFlag     = false; 
                                                   >> 234   weightFlag   = false; 
127                                                   235 
128   G4LossTableBuilder* bld = lManager->GetTable << 236   scTracks.reserve(5);
129   theDensityFactor = bld->GetDensityFactors(); << 237   secParticles.reserve(5);
130   theDensityIdx = bld->GetCoupleIndexes();     << 
131                                                << 
132   scTracks.reserve(10);                        << 
133   secParticles.reserve(12);                    << 
134   emModels = new std::vector<G4VEmModel*>;     << 
135 }                                                 238 }
136                                                   239 
137 //....oooOO0OOooo........oooOO0OOooo........oo    240 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
138                                                   241 
139 G4VEnergyLossProcess::~G4VEnergyLossProcess()     242 G4VEnergyLossProcess::~G4VEnergyLossProcess()
140 {                                                 243 {
141   if (isMaster) {                              << 244   if(1 < verboseLevel) {
142     if(nullptr == baseParticle) { delete theDa << 245     G4cout << "G4VEnergyLossProcess destruct " << GetProcessName()
143     delete theEnergyOfCrossSectionMax;         << 246      << "  " << this << "  " << baseParticle << G4endl;
144     if(nullptr != fXSpeaks) {                  << 247   }
145       for(auto const & v : *fXSpeaks) { delete << 248   Clean();
146       delete fXSpeaks;                         << 249 
                                                   >> 250   if ( !baseParticle ) {
                                                   >> 251     if(theDEDXTable) {
                                                   >> 252       if(theIonisationTable == theDEDXTable) { theIonisationTable = 0; }
                                                   >> 253       theDEDXTable->clearAndDestroy();
                                                   >> 254       delete theDEDXTable;
                                                   >> 255       if(theDEDXSubTable) {
                                                   >> 256   if(theIonisationSubTable == theDEDXSubTable) 
                                                   >> 257     theIonisationSubTable = 0;
                                                   >> 258   theDEDXSubTable->clearAndDestroy();
                                                   >> 259         delete theDEDXSubTable;
                                                   >> 260       }
                                                   >> 261     }
                                                   >> 262     if(theIonisationTable) {
                                                   >> 263       theIonisationTable->clearAndDestroy(); 
                                                   >> 264       delete theIonisationTable;
                                                   >> 265     }
                                                   >> 266     if(theIonisationSubTable) {
                                                   >> 267       theIonisationSubTable->clearAndDestroy(); 
                                                   >> 268       delete theIonisationSubTable;
                                                   >> 269     }
                                                   >> 270     if(theDEDXunRestrictedTable && theCSDARangeTable) {
                                                   >> 271        theDEDXunRestrictedTable->clearAndDestroy();
                                                   >> 272        delete theDEDXunRestrictedTable;
                                                   >> 273     }
                                                   >> 274     if(theCSDARangeTable) {
                                                   >> 275       theCSDARangeTable->clearAndDestroy();
                                                   >> 276       delete theCSDARangeTable;
                                                   >> 277     }
                                                   >> 278     if(theRangeTableForLoss) {
                                                   >> 279       theRangeTableForLoss->clearAndDestroy();
                                                   >> 280       delete theRangeTableForLoss;
                                                   >> 281     }
                                                   >> 282     if(theInverseRangeTable) {
                                                   >> 283       theInverseRangeTable->clearAndDestroy();
                                                   >> 284       delete theInverseRangeTable;
                                                   >> 285     }
                                                   >> 286     if(theLambdaTable) {
                                                   >> 287       theLambdaTable->clearAndDestroy();
                                                   >> 288       delete theLambdaTable;
                                                   >> 289     }
                                                   >> 290     if(theSubLambdaTable) {
                                                   >> 291       theSubLambdaTable->clearAndDestroy();
                                                   >> 292       delete theSubLambdaTable;
147     }                                             293     }
148   }                                               294   }
                                                   >> 295 
149   delete modelManager;                            296   delete modelManager;
150   delete biasManager;                             297   delete biasManager;
151   delete scoffRegions;                         << 298   (G4LossTableManager::Instance())->DeRegister(this);
152   delete emModels;                             << 299 }
153   lManager->DeRegister(this);                  << 300 
                                                   >> 301 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
                                                   >> 302 
                                                   >> 303 void G4VEnergyLossProcess::Clean()
                                                   >> 304 {
                                                   >> 305   if(1 < verboseLevel) { 
                                                   >> 306     G4cout << "G4VEnergyLossProcess::Clear() for " << GetProcessName() 
                                                   >> 307      << G4endl;
                                                   >> 308   }
                                                   >> 309   delete [] idxSCoffRegions;
                                                   >> 310 
                                                   >> 311   tablesAreBuilt = false;
                                                   >> 312 
                                                   >> 313   scProcesses.clear();
                                                   >> 314   nProcesses = 0;
154 }                                                 315 }
155                                                   316 
156 //....oooOO0OOooo........oooOO0OOooo........oo    317 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
157                                                   318 
158 G4double G4VEnergyLossProcess::MinPrimaryEnerg    319 G4double G4VEnergyLossProcess::MinPrimaryEnergy(const G4ParticleDefinition*, 
159                                                << 320             const G4Material*, 
160                                                << 321             G4double cut)
161 {                                                 322 {
162   return cut;                                     323   return cut;
163 }                                                 324 }
164                                                   325 
165 //....oooOO0OOooo........oooOO0OOooo........oo    326 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
166                                                   327 
167 void G4VEnergyLossProcess::AddEmModel(G4int or << 328 void G4VEnergyLossProcess::AddEmModel(G4int order, G4VEmModel* p, 
168                                       G4VEmFlu << 329               G4VEmFluctuationModel* fluc,
169                                       const G4 << 330               const G4Region* region)
170 {                                                 331 {
171   if(nullptr == ptr) { return; }               << 332   modelManager->AddEmModel(order, p, fluc, region);
172   G4VEmFluctuationModel* afluc = (nullptr == f << 333   if(p) { p->SetParticleChange(pParticleChange, fluc); }
173   modelManager->AddEmModel(order, ptr, afluc,  << 
174   ptr->SetParticleChange(pParticleChange, aflu << 
175 }                                                 334 }
176                                                   335 
177 //....oooOO0OOooo........oooOO0OOooo........oo    336 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
178                                                   337 
179 void G4VEnergyLossProcess::SetEmModel(G4VEmMod << 338 void G4VEnergyLossProcess::UpdateEmModel(const G4String& nam, 
                                                   >> 339            G4double emin, G4double emax)
180 {                                                 340 {
181   if(nullptr == ptr) { return; }               << 341   modelManager->UpdateEmModel(nam, emin, emax);
182   if(!emModels->empty()) {                     << 
183     for(auto & em : *emModels) { if(em == ptr) << 
184   }                                            << 
185   emModels->push_back(ptr);                    << 
186 }                                                 342 }
187                                                   343 
188 //....oooOO0OOooo........oooOO0OOooo........oo    344 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
189                                                   345 
190 void G4VEnergyLossProcess::SetDynamicMassCharg << 346 void G4VEnergyLossProcess::SetEmModel(G4VEmModel* p, G4int index)
191                                                << 
192 {                                                 347 {
193   massRatio = massratio;                       << 348   G4int n = emModels.size();
194   logMassRatio = G4Log(massRatio);             << 349   if(index >= n) { for(G4int i=n; i<=index; ++i) {emModels.push_back(0);} }
195   fFactor = charge2ratio*biasFactor;           << 350   emModels[index] = p;
196   if(baseMat) { fFactor *= (*theDensityFactor) << 351 }
197   chargeSqRatio = charge2ratio;                << 352 
198   reduceFactor  = 1.0/(fFactor*massRatio);     << 353 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
                                                   >> 354 
                                                   >> 355 G4VEmModel* G4VEnergyLossProcess::EmModel(G4int index)
                                                   >> 356 {
                                                   >> 357   G4VEmModel* p = 0;
                                                   >> 358   if(index >= 0 && index <  G4int(emModels.size())) { p = emModels[index]; }
                                                   >> 359   return p;
                                                   >> 360 }
                                                   >> 361 
                                                   >> 362 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
                                                   >> 363 
                                                   >> 364 G4VEmModel* G4VEnergyLossProcess::GetModelByIndex(G4int idx, G4bool ver)
                                                   >> 365 {
                                                   >> 366   return modelManager->GetModel(idx, ver);
                                                   >> 367 }
                                                   >> 368 
                                                   >> 369 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
                                                   >> 370 
                                                   >> 371 G4int G4VEnergyLossProcess::NumberOfModels()
                                                   >> 372 {
                                                   >> 373   return modelManager->NumberOfModels();
199 }                                                 374 }
200                                                   375 
201 //....oooOO0OOooo........oooOO0OOooo........oo    376 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
202                                                   377 
203 void                                              378 void 
204 G4VEnergyLossProcess::PreparePhysicsTable(cons    379 G4VEnergyLossProcess::PreparePhysicsTable(const G4ParticleDefinition& part)
205 {                                                 380 {
206   particle = G4EmTableUtil::CheckIon(this, &pa << 381   if(1 < verboseLevel) {
207                                      verboseLe << 382     G4cout << "G4VEnergyLossProcess::PreparePhysicsTable for "
                                                   >> 383            << GetProcessName() << " for " << part.GetParticleName() 
                                                   >> 384      << "  " << this << G4endl;
                                                   >> 385   }
                                                   >> 386 
                                                   >> 387   currentCouple = 0;
                                                   >> 388   preStepLambda = 0.0;
                                                   >> 389   mfpKinEnergy  = DBL_MAX;
                                                   >> 390   fRange        = DBL_MAX;
                                                   >> 391   preStepKinEnergy = 0.0;
                                                   >> 392   chargeSqRatio = 1.0;
                                                   >> 393   massRatio = 1.0;
                                                   >> 394   reduceFactor = 1.0;
                                                   >> 395   fFactor = 1.0;
                                                   >> 396 
                                                   >> 397   G4LossTableManager* lManager = G4LossTableManager::Instance();
                                                   >> 398 
                                                   >> 399   // Are particle defined?
                                                   >> 400   if( !particle ) { particle = &part; }
                                                   >> 401 
                                                   >> 402   if(part.GetParticleType() == "nucleus") {
                                                   >> 403 
                                                   >> 404     // if generic ion or nucleus with Z>=2 
                                                   >> 405     if(part.GetPDGCharge() > 1.5*eplus || 
                                                   >> 406        part.GetParticleName() == "GenericIon") { 
                                                   >> 407       theGenericIon = G4GenericIon::GenericIon();
                                                   >> 408       isIon = true; 
                                                   >> 409       // process is shared between all ions inheriting G4GenericIon
                                                   >> 410       if(part.GetPDGCharge() > 2.5*eplus) { particle = theGenericIon; }
                                                   >> 411     }
                                                   >> 412   }
208                                                   413 
209   if( particle != &part ) {                       414   if( particle != &part ) {
210     if(!isIon) { lManager->RegisterExtraPartic << 415     if(isIon) {
                                                   >> 416       lManager->RegisterIon(&part, this);
                                                   >> 417     } else { 
                                                   >> 418       lManager->RegisterExtraParticle(&part, this);
                                                   >> 419     }
211     if(1 < verboseLevel) {                        420     if(1 < verboseLevel) {
212       G4cout << "### G4VEnergyLossProcess::Pre << 421       G4cout << "### G4VEnergyLossProcess::PreparePhysicsTable() interrupted for "
213              << " interrupted for " << GetProc << 422        << part.GetParticleName() << "  isIon= " << isIon 
214              << part.GetParticleName() << " is << 423        << "  particle " << particle << "  GenericIon " << theGenericIon 
215              << " spline=" << spline << G4endl << 424        << G4endl;
216     }                                             425     }
217     return;                                       426     return;
218   }                                               427   }
219                                                   428 
220   tablesAreBuilt = false;                      << 429   Clean();
221   if (GetProcessSubType() == fIonisation) { Se << 
222                                                << 
223   G4LossTableBuilder* bld = lManager->GetTable << 
224   lManager->PreparePhysicsTable(&part, this);     430   lManager->PreparePhysicsTable(&part, this);
                                                   >> 431   G4LossTableBuilder* bld = lManager->GetTableBuilder();
225                                                   432 
226   // Base particle and set of models can be de    433   // Base particle and set of models can be defined here
227   InitialiseEnergyLossProcess(particle, basePa    434   InitialiseEnergyLossProcess(particle, baseParticle);
228                                                   435 
229   // parameters of the process                 << 436   const G4ProductionCutsTable* theCoupleTable=
230   if(!actLossFluc) { lossFluctuationFlag = the << 437     G4ProductionCutsTable::GetProductionCutsTable();
231   useCutAsFinalRange = theParameters->UseCutAs << 438   size_t n = theCoupleTable->GetTableSize();
232   if(!actMinKinEnergy) { minKinEnergy = thePar << 439 
233   if(!actMaxKinEnergy) { maxKinEnergy = thePar << 440   theDEDXAtMaxEnergy.resize(n, 0.0);
234   if(!actBinning) { nBins = theParameters->Num << 441   theRangeAtMaxEnergy.resize(n, 0.0);
235   maxKinEnergyCSDA = theParameters->MaxEnergyF << 442   theEnergyOfCrossSectionMax.resize(n, 0.0);
236   nBinsCSDA = theParameters->NumberOfBinsPerDe << 443   theCrossSectionMax.resize(n, DBL_MAX);
237     *G4lrint(std::log10(maxKinEnergyCSDA/minKi << 
238   if(!actLinLossLimit) { linLossLimit = thePar << 
239   lambdaFactor = theParameters->LambdaFactor() << 
240   invLambdaFactor = 1.0/lambdaFactor;          << 
241   if(isMaster) { SetVerboseLevel(theParameters << 
242   else { SetVerboseLevel(theParameters->Worker << 
243   // integral option may be disabled           << 
244   if(!theParameters->Integral()) { fXSType = f << 
245                                                << 
246   theParameters->DefineRegParamForLoss(this);  << 
247                                                << 
248   fRangeEnergy = 0.0;                          << 
249                                                << 
250   G4double initialCharge = particle->GetPDGCha << 
251   G4double initialMass   = particle->GetPDGMas << 
252                                                << 
253   theParameters->FillStepFunction(particle, th << 
254                                                << 
255   // parameters for scaling from the base part << 
256   if (nullptr != baseParticle) {               << 
257     massRatio    = (baseParticle->GetPDGMass() << 
258     logMassRatio = G4Log(massRatio);           << 
259     G4double q = initialCharge/baseParticle->G << 
260     chargeSqRatio = q*q;                       << 
261     if(chargeSqRatio > 0.0) { reduceFactor = 1 << 
262   }                                            << 
263   lowestKinEnergy = (initialMass < CLHEP::MeV) << 
264     ? theParameters->LowestElectronEnergy()    << 
265     : theParameters->LowestMuHadEnergy();      << 
266                                                   444 
267   // Tables preparation                           445   // Tables preparation
268   if (isMaster && nullptr == baseParticle) {   << 446   if (!baseParticle) {
269     if(nullptr == theData) { theData = new G4E << 
270                                                << 
271     if(nullptr != theDEDXTable && isIonisation << 
272       if(nullptr != theIonisationTable && theD << 
273   theData->CleanTable(0);                      << 
274   theDEDXTable = theIonisationTable;           << 
275   theIonisationTable = nullptr;                << 
276       }                                        << 
277     }                                          << 
278                                                   447     
279     theDEDXTable = theData->MakeTable(theDEDXT << 448     theDEDXTable = G4PhysicsTableHelper::PreparePhysicsTable(theDEDXTable);
280     bld->InitialiseBaseMaterials(theDEDXTable)    449     bld->InitialiseBaseMaterials(theDEDXTable);
281     theData->UpdateTable(theIonisationTable, 1 << 
282                                                   450 
283     if (theParameters->BuildCSDARange()) {     << 451     if (lManager->BuildCSDARange()) {
284       theDEDXunRestrictedTable = theData->Make << 452       theDEDXunRestrictedTable = 
285       if(isIonisation) { theCSDARangeTable = t << 453   G4PhysicsTableHelper::PreparePhysicsTable(theDEDXunRestrictedTable);
                                                   >> 454       theCSDARangeTable = 
                                                   >> 455   G4PhysicsTableHelper::PreparePhysicsTable(theCSDARangeTable);
                                                   >> 456       //bld->InitialiseBaseMaterials(theDEDXunRestrictedTable);
                                                   >> 457       //bld->InitialiseBaseMaterials(theCSDARangeTable);
286     }                                             458     }
287                                                   459 
288     theLambdaTable = theData->MakeTable(4);    << 460     theLambdaTable = G4PhysicsTableHelper::PreparePhysicsTable(theLambdaTable);
                                                   >> 461     bld->InitialiseBaseMaterials(theLambdaTable);  
                                                   >> 462 
289     if(isIonisation) {                            463     if(isIonisation) {
290       theRangeTableForLoss = theData->MakeTabl << 464       theRangeTableForLoss = 
291       theInverseRangeTable = theData->MakeTabl << 465   G4PhysicsTableHelper::PreparePhysicsTable(theRangeTableForLoss);
                                                   >> 466       theInverseRangeTable = 
                                                   >> 467   G4PhysicsTableHelper::PreparePhysicsTable(theInverseRangeTable);  
                                                   >> 468       //bld->InitialiseBaseMaterials(theRangeTableForLoss);
                                                   >> 469       //bld->InitialiseBaseMaterials(theInverseRangeTable);
                                                   >> 470     }
                                                   >> 471 
                                                   >> 472     if (nSCoffRegions) {
                                                   >> 473       theDEDXSubTable = 
                                                   >> 474   G4PhysicsTableHelper::PreparePhysicsTable(theDEDXSubTable);
                                                   >> 475       theSubLambdaTable = 
                                                   >> 476   G4PhysicsTableHelper::PreparePhysicsTable(theSubLambdaTable);
                                                   >> 477       //bld->InitialiseBaseMaterials(theDEDXSubTable);  
                                                   >> 478       //bld->InitialiseBaseMaterials(theSubLambdaTable);  
292     }                                             479     }
293   }                                               480   }
294                                                   481 
                                                   >> 482   theDensityFactor = bld->GetDensityFactors();
                                                   >> 483   theDensityIdx = bld->GetCoupleIndexes();
                                                   >> 484 
295   // forced biasing                               485   // forced biasing
296   if(nullptr != biasManager) {                 << 486   if(biasManager) { 
297     biasManager->Initialise(part,GetProcessNam    487     biasManager->Initialise(part,GetProcessName(),verboseLevel); 
298     biasFlag = false;                             488     biasFlag = false; 
299   }                                               489   }
300   baseMat = bld->GetBaseMaterialFlag();        << 490 
301   numberOfModels = modelManager->NumberOfModel << 491   G4double initialCharge = particle->GetPDGCharge();
302   currentModel = modelManager->GetModel(0);    << 492   G4double initialMass   = particle->GetPDGMass();
303   G4EmTableUtil::UpdateModels(this, modelManag << 493 
304                               numberOfModels,  << 494   if (baseParticle) {
305                               mainSecondaries, << 495     massRatio = (baseParticle->GetPDGMass())/initialMass;
306                               theParameters->U << 496     G4double q = initialCharge/baseParticle->GetPDGCharge();
307   theCuts = modelManager->Initialise(particle, << 497     chargeSqRatio = q*q;
308                                      verboseLe << 498     if(chargeSqRatio > 0.0) { reduceFactor = 1.0/(chargeSqRatio*massRatio); }
309   // subcut processor                          << 
310   if(isIonisation) {                           << 
311     subcutProducer = lManager->SubCutProducer( << 
312   }                                               499   }
313   if(1 == nSCoffRegions) {                     << 500 
314     if((*scoffRegions)[0]->GetName() == "Defau << 501   // initialisation of models
315       delete scoffRegions;                     << 502   G4int nmod = modelManager->NumberOfModels();
316       scoffRegions = nullptr;                  << 503   for(G4int i=0; i<nmod; ++i) {
317       nSCoffRegions = 0;                       << 504     G4VEmModel* mod = modelManager->GetModel(i);
                                                   >> 505     if(mod->HighEnergyLimit() > maxKinEnergy) {
                                                   >> 506       mod->SetHighEnergyLimit(maxKinEnergy);
318     }                                             507     }
319   }                                               508   }
320                                                   509 
321   if(1 < verboseLevel) {                       << 510   theCuts = modelManager->Initialise(particle, secondaryParticle, 
322     G4cout << "G4VEnergyLossProcess::PrepearPh << 511              minSubRange, verboseLevel);
323            << " for " << GetProcessName() << " << 512 
324            << " isIon= " << isIon << " spline= << 513   // Sub Cutoff 
325     if(baseParticle) {                         << 514   if (nSCoffRegions>0) {
326       G4cout << "; base: " << baseParticle->Ge << 515     theSubCuts = modelManager->SubCutoff();
                                                   >> 516 
                                                   >> 517     if(nSCoffRegions>0) { idxSCoffRegions = new G4bool[n]; }
                                                   >> 518     for (size_t j=0; j<n; ++j) {
                                                   >> 519 
                                                   >> 520       const G4MaterialCutsCouple* couple = 
                                                   >> 521   theCoupleTable->GetMaterialCutsCouple(j);
                                                   >> 522       const G4ProductionCuts* pcuts = couple->GetProductionCuts();
                                                   >> 523       
                                                   >> 524       if(nSCoffRegions>0) {
                                                   >> 525   G4bool reg = false;
                                                   >> 526   for(G4int i=0; i<nSCoffRegions; ++i) {
                                                   >> 527     if( pcuts == scoffRegions[i]->GetProductionCuts()) { reg = true; }
                                                   >> 528   }
                                                   >> 529   idxSCoffRegions[j] = reg;
                                                   >> 530       }
327     }                                             531     }
328     G4cout << G4endl;                          << 532   }
                                                   >> 533 
                                                   >> 534   if(1 < verboseLevel) {
                                                   >> 535     G4cout << "G4VEnergyLossProcess::Initialise() is done "
                                                   >> 536            << " for local " << particle->GetParticleName()
                                                   >> 537      << " isIon= " << isIon;
                                                   >> 538     if(baseParticle) { G4cout << "; base: " << baseParticle->GetParticleName(); }
329     G4cout << " chargeSqRatio= " << chargeSqRa    539     G4cout << " chargeSqRatio= " << chargeSqRatio
330            << " massRatio= " << massRatio         540            << " massRatio= " << massRatio
331            << " reduceFactor= " << reduceFacto    541            << " reduceFactor= " << reduceFactor << G4endl;
332     if (nSCoffRegions > 0) {                   << 542     if (nSCoffRegions) {
333       G4cout << " SubCut secondary production  << 543       G4cout << " SubCutoff Regime is ON for regions: " << G4endl;
334       for (G4int i=0; i<nSCoffRegions; ++i) {     544       for (G4int i=0; i<nSCoffRegions; ++i) {
335         const G4Region* r = (*scoffRegions)[i] << 545         const G4Region* r = scoffRegions[i];
336         G4cout << "           " << r->GetName( << 546   G4cout << "           " << r->GetName() << G4endl;
337       }                                           547       }
338     } else if(nullptr != subcutProducer) {     << 
339       G4cout << " SubCut secondary production  << 
340     }                                             548     }
341   }                                               549   }
342 }                                                 550 }
343                                                   551 
344 //....oooOO0OOooo........oooOO0OOooo........oo    552 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
345                                                   553 
346 void G4VEnergyLossProcess::BuildPhysicsTable(c    554 void G4VEnergyLossProcess::BuildPhysicsTable(const G4ParticleDefinition& part)
347 {                                                 555 {
348   if(1 < verboseLevel) {                       << 556   if(1 < verboseLevel) {
349     G4cout << "### G4VEnergyLossProcess::Build    557     G4cout << "### G4VEnergyLossProcess::BuildPhysicsTable() for "
350            << GetProcessName()                    558            << GetProcessName()
351            << " and particle " << part.GetPart    559            << " and particle " << part.GetParticleName()
352            << "; the first particle " << parti << 560            << "; local: " << particle->GetParticleName();
353     if(baseParticle) {                         << 561     if(baseParticle) { G4cout << "; base: " << baseParticle->GetParticleName(); }
354       G4cout << "; base: " << baseParticle->Ge << 562     G4cout << " TablesAreBuilt= " << tablesAreBuilt
355     }                                          << 563            << " isIon= " << isIon << "  " << this << G4endl;
356     G4cout << G4endl;                          << 
357     G4cout << "    TablesAreBuilt= " << tables << 
358            << " spline=" << spline << " ptr: " << 
359   }                                               564   }
360                                                   565 
361   if(&part == particle) {                         566   if(&part == particle) {
362     if(isMaster) {                             << 567     if(!tablesAreBuilt) {
363       lManager->BuildPhysicsTable(particle, th << 568       G4LossTableManager::Instance()->BuildPhysicsTable(particle, this);
364                                                << 569     }
365     } else {                                   << 570     if(!baseParticle) {
366       const auto masterProcess =               << 571       if(0 < verboseLevel) { PrintInfoDefinition(); }
367         static_cast<const G4VEnergyLossProcess << 572     
368                                                << 573       // needs to be done only once
369       numberOfModels = modelManager->NumberOfM << 574       safetyHelper->InitialiseHelper();
370       G4EmTableUtil::BuildLocalElossProcess(th << 
371                                             pa << 
372       tablesAreBuilt = true;                   << 
373       baseMat = masterProcess->UseBaseMaterial << 
374       lManager->LocalPhysicsTables(particle, t << 
375     }                                             575     }
376                                                << 
377     // needs to be done only once              << 
378     safetyHelper->InitialiseHelper();          << 
379   }                                               576   }
                                                   >> 577 
380   // Added tracking cut to avoid tracking arti    578   // Added tracking cut to avoid tracking artifacts
381   // and identified deexcitation flag          << 579   // identify deexcitation flag
382   if(isIonisation) {                              580   if(isIonisation) { 
383     atomDeexcitation = lManager->AtomDeexcitat << 581     fParticleChange.SetLowEnergyLimit(lowestKinEnergy); 
384     if(nullptr != atomDeexcitation) {          << 582     atomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
                                                   >> 583     if(atomDeexcitation) { 
385       if(atomDeexcitation->IsPIXEActive()) { u    584       if(atomDeexcitation->IsPIXEActive()) { useDeexcitation = true; } 
386     }                                             585     }
387   }                                               586   }
388                                                   587 
389   // protection against double printout        << 
390   if(theParameters->IsPrintLocked()) { return; << 
391                                                << 
392   // explicitly defined printout by particle n << 
393   G4String num = part.GetParticleName();       << 
394   if(1 < verboseLevel ||                       << 
395      (0 < verboseLevel && (num == "e-" ||      << 
396                            num == "e+"    || n << 
397                            num == "mu-"   || n << 
398                            num == "pi+"   || n << 
399                            num == "kaon+" || n << 
400                            num == "alpha" || n << 
401                            num == "GenericIon" << 
402     StreamInfo(G4cout, part);                  << 
403   }                                            << 
404   if(1 < verboseLevel) {                          588   if(1 < verboseLevel) {
405     G4cout << "### G4VEnergyLossProcess::Build    589     G4cout << "### G4VEnergyLossProcess::BuildPhysicsTable() done for "
406            << GetProcessName()                    590            << GetProcessName()
407            << " and particle " << part.GetPart    591            << " and particle " << part.GetParticleName();
408     if(isIonisation) { G4cout << "  isIonisati << 592     if(isIonisation) { G4cout << "  isIonisation  flag = 1"; }
409     G4cout << " baseMat=" << baseMat << G4endl << 593     G4cout << G4endl;
410   }                                               594   }
411 }                                                 595 }
412                                                   596 
413 //....oooOO0OOooo........oooOO0OOooo........oo    597 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
414                                                   598 
415 G4PhysicsTable* G4VEnergyLossProcess::BuildDED    599 G4PhysicsTable* G4VEnergyLossProcess::BuildDEDXTable(G4EmTableType tType)
416 {                                                 600 {
417   G4PhysicsTable* table = nullptr;             << 601   if(1 < verboseLevel) {
                                                   >> 602     G4cout << "G4VEnergyLossProcess::BuildDEDXTable() of type " << tType
                                                   >> 603      << " for " << GetProcessName()
                                                   >> 604            << " and particle " << particle->GetParticleName()
                                                   >> 605            << G4endl;
                                                   >> 606   }
                                                   >> 607   G4PhysicsTable* table = 0;
418   G4double emax = maxKinEnergy;                   608   G4double emax = maxKinEnergy;
419   G4int bin = nBins;                              609   G4int bin = nBins;
420                                                   610 
421   if(fTotal == tType) {                           611   if(fTotal == tType) {
422     emax  = maxKinEnergyCSDA;                     612     emax  = maxKinEnergyCSDA;
423     bin   = nBinsCSDA;                            613     bin   = nBinsCSDA;
424     table = theDEDXunRestrictedTable;             614     table = theDEDXunRestrictedTable;
425   } else if(fRestricted == tType) {               615   } else if(fRestricted == tType) {
426     table = theDEDXTable;                         616     table = theDEDXTable;
                                                   >> 617     if(theIonisationTable) 
                                                   >> 618       table = G4PhysicsTableHelper::PreparePhysicsTable(theIonisationTable); 
                                                   >> 619   } else if(fSubRestricted == tType) {    
                                                   >> 620     table = theDEDXSubTable;
                                                   >> 621     if(theIonisationSubTable) 
                                                   >> 622       table = G4PhysicsTableHelper::PreparePhysicsTable(theIonisationSubTable); 
427   } else {                                        623   } else {
428     G4cout << "G4VEnergyLossProcess::BuildDEDX    624     G4cout << "G4VEnergyLossProcess::BuildDEDXTable WARNING: wrong type "
429            << tType << G4endl;                 << 625      << tType << G4endl;
430   }                                               626   }
                                                   >> 627 
                                                   >> 628   // Access to materials
                                                   >> 629   const G4ProductionCutsTable* theCoupleTable=
                                                   >> 630         G4ProductionCutsTable::GetProductionCutsTable();
                                                   >> 631   size_t numOfCouples = theCoupleTable->GetTableSize();
                                                   >> 632 
431   if(1 < verboseLevel) {                          633   if(1 < verboseLevel) {
432     G4cout << "G4VEnergyLossProcess::BuildDEDX << 634     G4cout << numOfCouples << " materials"
433            << " for " << GetProcessName()      << 635            << " minKinEnergy= " << minKinEnergy
434            << " and " << particle->GetParticle << 636            << " maxKinEnergy= " << emax
435      << "spline=" << spline << G4endl;         << 637            << " nbin= " << bin
                                                   >> 638            << " EmTableType= " << tType
                                                   >> 639            << " table= " << table << "  " << this 
                                                   >> 640            << G4endl;
436   }                                               641   }
437   if(nullptr == table) { return table; }       << 642   if(!table) return table;
438                                                   643 
439   G4LossTableBuilder* bld = lManager->GetTable << 644   G4LossTableBuilder* bld = (G4LossTableManager::Instance())->GetTableBuilder();
440   G4EmTableUtil::BuildDEDXTable(this, particle << 645   G4bool splineFlag = (G4LossTableManager::Instance())->SplineFlag();
441                                 table, minKinE << 646   G4PhysicsLogVector* aVector = 0;
442                                 verboseLevel,  << 647   G4PhysicsLogVector* bVector = 0;
443   return table;                                << 
444 }                                              << 
445                                                   648 
446 //....oooOO0OOooo........oooOO0OOooo........oo << 649   for(size_t i=0; i<numOfCouples; ++i) {
447                                                   650 
448 G4PhysicsTable* G4VEnergyLossProcess::BuildLam << 651     if(1 < verboseLevel) {
449 {                                              << 652       G4cout << "G4VEnergyLossProcess::BuildDEDXVector flagTable=  " 
450   if(nullptr == theLambdaTable) { return theLa << 653        << table->GetFlag(i) << " Flag= " << bld->GetFlag(i) << G4endl;
                                                   >> 654     }
                                                   >> 655     if(bld->GetFlag(i)) {
451                                                   656 
452   G4double scale = theParameters->MaxKinEnergy << 657       // create physics vector and fill it
453   G4int nbin =                                 << 658       const G4MaterialCutsCouple* couple = 
454     theParameters->NumberOfBinsPerDecade()*G4l << 659   theCoupleTable->GetMaterialCutsCouple(i);
455   scale = nbin/G4Log(scale);                   << 660       delete (*table)[i];
456                                                << 661       if(!bVector) {
457   G4LossTableBuilder* bld = lManager->GetTable << 662   aVector = new G4PhysicsLogVector(minKinEnergy, emax, bin);
458   G4EmTableUtil::BuildLambdaTable(this, partic << 663         bVector = aVector;
459                                   bld, theLamb << 664       } else {
460                                   minKinEnergy << 665         aVector = new G4PhysicsLogVector(*bVector);
461                                   verboseLevel << 666       }
462   return theLambdaTable;                       << 667       aVector->SetSpline(splineFlag);
463 }                                              << 
464                                                   668 
465 //....oooOO0OOooo........oooOO0OOooo........oo << 669       modelManager->FillDEDXVector(aVector, couple, tType);
                                                   >> 670       if(splineFlag) { aVector->FillSecondDerivatives(); }
466                                                   671 
467 void G4VEnergyLossProcess::StreamInfo(std::ost << 672       // Insert vector for this material into the table
468                 const G4ParticleDefinition& pa << 673       G4PhysicsTableHelper::SetPhysicsVector(table, i, aVector);
469 {                                              << 
470   G4String indent = (rst ? "  " : "");         << 
471   out << std::setprecision(6);                 << 
472   out << G4endl << indent << GetProcessName()  << 
473   if (!rst) out << " for " << part.GetParticle << 
474   out << "  XStype:" << fXSType                << 
475       << "  SubType=" << GetProcessSubType() < << 
476       << "      dE/dx and range tables from "  << 
477       << G4BestUnit(minKinEnergy,"Energy")     << 
478       << " to " << G4BestUnit(maxKinEnergy,"En << 
479       << " in " << nBins << " bins" << G4endl  << 
480       << "      Lambda tables from threshold t << 
481       << G4BestUnit(maxKinEnergy,"Energy")     << 
482       << ", " << theParameters->NumberOfBinsPe << 
483       << " bins/decade, spline: " << spline    << 
484       << G4endl;                               << 
485   if(nullptr != theRangeTableForLoss && isIoni << 
486     out << "      StepFunction=(" << dRoverRan << 
487         << finalRange/mm << " mm)"             << 
488         << ", integ: " << fXSType              << 
489         << ", fluct: " << lossFluctuationFlag  << 
490         << ", linLossLim= " << linLossLimit    << 
491         << G4endl;                             << 
492   }                                            << 
493   StreamProcessInfo(out);                      << 
494   modelManager->DumpModelList(out, verboseLeve << 
495   if(nullptr != theCSDARangeTable && isIonisat << 
496     out << "      CSDA range table up"         << 
497         << " to " << G4BestUnit(maxKinEnergyCS << 
498         << " in " << nBinsCSDA << " bins" << G << 
499   }                                            << 
500   if(nSCoffRegions>0 && isIonisation) {        << 
501     out << "      Subcutoff sampling in " << n << 
502         << " regions" << G4endl;               << 
503   }                                            << 
504   if(2 < verboseLevel) {                       << 
505     for(std::size_t i=0; i<7; ++i) {           << 
506       auto ta = theData->Table(i);             << 
507       out << "      " << tnames[i] << " addres << 
508       if(nullptr != ta) { out << *ta << G4endl << 
509     }                                             674     }
510   }                                               675   }
                                                   >> 676 
                                                   >> 677   if(1 < verboseLevel) {
                                                   >> 678     G4cout << "G4VEnergyLossProcess::BuildDEDXTable(): table is built for "
                                                   >> 679            << particle->GetParticleName()
                                                   >> 680            << " and process " << GetProcessName()
                                                   >> 681            << G4endl;
                                                   >> 682     //    if(2 < verboseLevel) G4cout << (*table) << G4endl;
                                                   >> 683   }
                                                   >> 684 
                                                   >> 685   return table;
511 }                                                 686 }
512                                                   687 
513 //....oooOO0OOooo........oooOO0OOooo........oo    688 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
514                                                   689 
515 void G4VEnergyLossProcess::ActivateSubCutoff(c << 690 G4PhysicsTable* G4VEnergyLossProcess::BuildLambdaTable(G4EmTableType tType)
516 {                                                 691 {
517   if(nullptr == scoffRegions) {                << 692   G4PhysicsTable* table = 0;
518     scoffRegions = new std::vector<const G4Reg << 693 
                                                   >> 694   if(fRestricted == tType) {
                                                   >> 695     table = theLambdaTable;
                                                   >> 696   } else if(fSubRestricted == tType) {    
                                                   >> 697     table = theSubLambdaTable;
                                                   >> 698   } else {
                                                   >> 699     G4cout << "G4VEnergyLossProcess::BuildLambdaTable WARNING: wrong type "
                                                   >> 700      << tType << G4endl;
519   }                                               701   }
520   // the region is in the list                 << 702 
521   if(!scoffRegions->empty()) {                 << 703   if(1 < verboseLevel) {
522     for (auto & reg : *scoffRegions) {         << 704     G4cout << "G4VEnergyLossProcess::BuildLambdaTable() of type "
523       if (reg == r) { return; }                << 705      << tType << " for process "
                                                   >> 706            << GetProcessName() << " and particle "
                                                   >> 707            << particle->GetParticleName()
                                                   >> 708            << " EmTableType= " << tType
                                                   >> 709            << " table= " << table
                                                   >> 710            << G4endl;
                                                   >> 711   }
                                                   >> 712   if(!table) {return table;}
                                                   >> 713 
                                                   >> 714   // Access to materials
                                                   >> 715   const G4ProductionCutsTable* theCoupleTable=
                                                   >> 716         G4ProductionCutsTable::GetProductionCutsTable();
                                                   >> 717   size_t numOfCouples = theCoupleTable->GetTableSize();
                                                   >> 718 
                                                   >> 719   G4LossTableBuilder* bld = (G4LossTableManager::Instance())->GetTableBuilder();
                                                   >> 720   G4bool splineFlag = (G4LossTableManager::Instance())->SplineFlag();
                                                   >> 721   G4PhysicsLogVector* aVector = 0;
                                                   >> 722   G4double scale = std::log(maxKinEnergy/minKinEnergy);
                                                   >> 723 
                                                   >> 724   for(size_t i=0; i<numOfCouples; ++i) {
                                                   >> 725 
                                                   >> 726     if (bld->GetFlag(i)) {
                                                   >> 727 
                                                   >> 728       // create physics vector and fill it
                                                   >> 729       const G4MaterialCutsCouple* couple = 
                                                   >> 730   theCoupleTable->GetMaterialCutsCouple(i);
                                                   >> 731       delete (*table)[i];
                                                   >> 732       G4double emin = MinPrimaryEnergy(particle,couple->GetMaterial(),(*theCuts)[i]);
                                                   >> 733       if(0.0 >= emin) { emin = eV; }
                                                   >> 734       else if(maxKinEnergy <= emin) { emin = 0.5*maxKinEnergy; }
                                                   >> 735       G4int bin = G4int(nBins*std::log(maxKinEnergy/emin)/scale + 0.5);
                                                   >> 736       if(bin < 3) { bin = 3; }
                                                   >> 737       aVector = new G4PhysicsLogVector(emin, maxKinEnergy, bin);
                                                   >> 738       aVector->SetSpline(splineFlag);
                                                   >> 739 
                                                   >> 740       modelManager->FillLambdaVector(aVector, couple, true, tType);
                                                   >> 741       if(splineFlag) { aVector->FillSecondDerivatives(); }
                                                   >> 742 
                                                   >> 743       // Insert vector for this material into the table
                                                   >> 744       G4PhysicsTableHelper::SetPhysicsVector(table, i, aVector);
524     }                                             745     }
525   }                                               746   }
526   // new region                                << 747 
527   scoffRegions->push_back(r);                  << 748   if(1 < verboseLevel) {
528   ++nSCoffRegions;                             << 749     G4cout << "Lambda table is built for "
                                                   >> 750            << particle->GetParticleName()
                                                   >> 751            << G4endl;
                                                   >> 752   }
                                                   >> 753 
                                                   >> 754   return table;
529 }                                                 755 }
530                                                   756 
531 //....oooOO0OOooo........oooOO0OOooo........oo    757 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
532                                                   758 
533 G4bool G4VEnergyLossProcess::IsRegionForCubcut << 759 void G4VEnergyLossProcess::PrintInfoDefinition()
534 {                                                 760 {
535   if(0 == nSCoffRegions) { return true; }      << 761   if(0 < verboseLevel) {
536   const G4Region* r = aTrack.GetVolume()->GetL << 762     G4cout << G4endl << GetProcessName() << ":   for  "
537   for(auto & reg : *scoffRegions) {            << 763            << particle->GetParticleName()
538     if(r == reg) { return true; }              << 764      << "    SubType= " << GetProcessSubType() 
                                                   >> 765            << G4endl
                                                   >> 766            << "      dE/dx and range tables from "
                                                   >> 767      << G4BestUnit(minKinEnergy,"Energy")
                                                   >> 768            << " to " << G4BestUnit(maxKinEnergy,"Energy")
                                                   >> 769            << " in " << nBins << " bins" << G4endl
                                                   >> 770            << "      Lambda tables from threshold to "
                                                   >> 771            << G4BestUnit(maxKinEnergy,"Energy")
                                                   >> 772            << " in " << nBins << " bins, spline: " 
                                                   >> 773      << (G4LossTableManager::Instance())->SplineFlag()
                                                   >> 774            << G4endl;
                                                   >> 775     if(theRangeTableForLoss && isIonisation) {
                                                   >> 776       G4cout << "      finalRange(mm)= " << finalRange/mm
                                                   >> 777              << ", dRoverRange= " << dRoverRange
                                                   >> 778              << ", integral: " << integral
                                                   >> 779              << ", fluct: " << lossFluctuationFlag
                                                   >> 780        << ", linLossLimit= " << linLossLimit
                                                   >> 781              << G4endl;
                                                   >> 782     }
                                                   >> 783     PrintInfo();
                                                   >> 784     modelManager->DumpModelList(verboseLevel);
                                                   >> 785     if(theCSDARangeTable && isIonisation) {
                                                   >> 786       G4cout << "      CSDA range table up"
                                                   >> 787              << " to " << G4BestUnit(maxKinEnergyCSDA,"Energy")
                                                   >> 788              << " in " << nBinsCSDA << " bins" << G4endl;
                                                   >> 789     }
                                                   >> 790     if(nSCoffRegions>0 && isIonisation) {
                                                   >> 791       G4cout << "      Subcutoff sampling in " << nSCoffRegions 
                                                   >> 792        << " regions" << G4endl;
                                                   >> 793     }
                                                   >> 794     if(2 < verboseLevel) {
                                                   >> 795       G4cout << "      DEDXTable address= " << theDEDXTable << G4endl;
                                                   >> 796       if(theDEDXTable && isIonisation) G4cout << (*theDEDXTable) << G4endl;
                                                   >> 797       G4cout << "non restricted DEDXTable address= " 
                                                   >> 798        << theDEDXunRestrictedTable << G4endl;
                                                   >> 799       if(theDEDXunRestrictedTable && isIonisation) {
                                                   >> 800            G4cout << (*theDEDXunRestrictedTable) << G4endl;
                                                   >> 801       }
                                                   >> 802       if(theDEDXSubTable && isIonisation) {
                                                   >> 803   G4cout << (*theDEDXSubTable) << G4endl;
                                                   >> 804       }
                                                   >> 805       G4cout << "      CSDARangeTable address= " << theCSDARangeTable 
                                                   >> 806        << G4endl;
                                                   >> 807       if(theCSDARangeTable && isIonisation) {
                                                   >> 808   G4cout << (*theCSDARangeTable) << G4endl;
                                                   >> 809       }
                                                   >> 810       G4cout << "      RangeTableForLoss address= " << theRangeTableForLoss 
                                                   >> 811        << G4endl;
                                                   >> 812       if(theRangeTableForLoss && isIonisation) {
                                                   >> 813              G4cout << (*theRangeTableForLoss) << G4endl;
                                                   >> 814       }
                                                   >> 815       G4cout << "      InverseRangeTable address= " << theInverseRangeTable 
                                                   >> 816        << G4endl;
                                                   >> 817       if(theInverseRangeTable && isIonisation) {
                                                   >> 818              G4cout << (*theInverseRangeTable) << G4endl;
                                                   >> 819       }
                                                   >> 820       G4cout << "      LambdaTable address= " << theLambdaTable << G4endl;
                                                   >> 821       if(theLambdaTable && isIonisation) {
                                                   >> 822   G4cout << (*theLambdaTable) << G4endl;
                                                   >> 823       }
                                                   >> 824       G4cout << "      SubLambdaTable address= " << theSubLambdaTable << G4endl;
                                                   >> 825       if(theSubLambdaTable && isIonisation) {
                                                   >> 826   G4cout << (*theSubLambdaTable) << G4endl;
                                                   >> 827       }
                                                   >> 828     }
539   }                                               829   }
540   return false;                                << 
541 }                                                 830 }
542                                                   831 
543 //....oooOO0OOooo........oooOO0OOooo........oo    832 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
544                                                   833 
545 void G4VEnergyLossProcess::StartTracking(G4Tra << 834 void G4VEnergyLossProcess::ActivateSubCutoff(G4bool val, const G4Region* r)
546 {                                                 835 {
547   // reset parameters for the new track        << 836   G4RegionStore* regionStore = G4RegionStore::GetInstance();
548   theNumberOfInteractionLengthLeft = -1.0;     << 837   const G4Region* reg = r;
549   mfpKinEnergy = DBL_MAX;                      << 838   if (!reg) {reg = regionStore->GetRegion("DefaultRegionForTheWorld", false);}
550   preStepLambda = 0.0;                         << 
551   currentCouple = nullptr;                     << 
552                                                   839 
553   // reset ion                                 << 840   // the region is in the list
554   if(isIon) {                                  << 841   if (nSCoffRegions) {
555     const G4double newmass = track->GetDefinit << 842     for (G4int i=0; i<nSCoffRegions; ++i) {
556     massRatio = (nullptr == baseParticle) ? CL << 843       if (reg == scoffRegions[i]) {
557       : baseParticle->GetPDGMass()/newmass;    << 844         return;
558     logMassRatio = G4Log(massRatio);           << 845       }
559   }                                            << 
560   // forced biasing only for primary particles << 
561   if(nullptr != biasManager) {                 << 
562     if(0 == track->GetParentID()) {            << 
563       biasFlag = true;                         << 
564       biasManager->ResetForcedInteraction();   << 
565     }                                             846     }
566   }                                               847   }
                                                   >> 848 
                                                   >> 849   // new region 
                                                   >> 850   if(val) {
                                                   >> 851     useSubCutoff = true;
                                                   >> 852     scoffRegions.push_back(reg);
                                                   >> 853     ++nSCoffRegions;
                                                   >> 854   } else {
                                                   >> 855     useSubCutoff = false;
                                                   >> 856   }
567 }                                                 857 }
568                                                   858 
569 //....oooOO0OOooo........oooOO0OOooo........oo    859 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
570                                                   860 
571 G4double G4VEnergyLossProcess::AlongStepGetPhy    861 G4double G4VEnergyLossProcess::AlongStepGetPhysicalInteractionLength(
572                              const G4Track& tr << 862                              const G4Track&,G4double,G4double,G4double&,
573                              G4GPILSelection*     863                              G4GPILSelection* selection)
574 {                                                 864 {
575   G4double x = DBL_MAX;                           865   G4double x = DBL_MAX;
576   *selection = aGPILSelection;                    866   *selection = aGPILSelection;
577   if(isIonisation && currentModel->IsActive(pr << 867   if(isIonisation) {
578     GetScaledRangeForScaledEnergy(preStepScale << 868     fRange = GetScaledRangeForScaledEnergy(preStepScaledEnergy)*reduceFactor;
579     x = (useCutAsFinalRange) ? std::min(finalR << 869 
580       currentCouple->GetProductionCuts()->GetP << 870     x = fRange;
581     x = (fRange > x) ? fRange*dRoverRange + x* << 871     G4double y = x*dRoverRange;
582       : fRange;                                << 872     G4double finR = finalRange;
583     /*                                         << 873     if(rndmStepFlag) { 
584       G4cout<<"AlongStepGPIL: " << GetProcessN << 874       finR = std::min(finR,currentCouple->GetProductionCuts()->GetProductionCut(1)); 
585   << " fRange=" << fRange << " finR=" << finR  << 875     }
                                                   >> 876     if(x > finR) { x = y + finR*(1.0 - dRoverRange)*(2.0 - finR/fRange); }
                                                   >> 877     /*
                                                   >> 878     G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy
                                                   >> 879     <<" range= "<<fRange << " idx= " << basedCoupleIndex
                                                   >> 880         << " y= " << y << " finR= " << finR
                                                   >> 881     << " limit= " << x <<G4endl;
586     */                                            882     */
587   }                                               883   }
                                                   >> 884   //G4cout<<GetProcessName()<<": e= "<<preStepKinEnergy <<" stepLimit= "<<x<<G4endl;
588   return x;                                       885   return x;
589 }                                                 886 }
590                                                   887 
591 //....oooOO0OOooo........oooOO0OOooo........oo    888 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
592                                                   889 
593 G4double G4VEnergyLossProcess::PostStepGetPhys    890 G4double G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength(
594                              const G4Track& tr    891                              const G4Track& track,
595                              G4double   previo    892                              G4double   previousStepSize,
596                              G4ForceCondition*    893                              G4ForceCondition* condition)
597 {                                                 894 {
598   // condition is set to "Not Forced"             895   // condition is set to "Not Forced"
599   *condition = NotForced;                         896   *condition = NotForced;
600   G4double x = DBL_MAX;                           897   G4double x = DBL_MAX;
601                                                   898 
602   // initialisation of material, mass, charge, << 899   // initialisation of material, mass, charge, model at the beginning of the step
603   // at the beginning of the step              << 900   const G4ParticleDefinition* currPart = track.GetParticleDefinition();
                                                   >> 901   if(isIon) {
                                                   >> 902     if(baseParticle) {
                                                   >> 903       massRatio = baseParticle->GetPDGMass()/currPart->GetPDGMass();
                                                   >> 904     } else {
                                                   >> 905       massRatio = proton_mass_c2/currPart->GetPDGMass();
                                                   >> 906     }
                                                   >> 907   }  
                                                   >> 908   /*
                                                   >> 909   if(!theDensityFactor || !theDensityIdx) {
                                                   >> 910     G4cout << "G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength 1: "
                                                   >> 911      <<  theDensityFactor << "  " << theDensityIdx
                                                   >> 912      << G4endl;
                                                   >> 913     G4cout << track.GetDefinition()->GetParticleName() 
                                                   >> 914      << " e(MeV)= " << track.GetKineticEnergy()
                                                   >> 915      << " mat " << track.GetMaterialCutsCouple()->GetMaterial()->GetName()
                                                   >> 916      << G4endl;
                                                   >> 917   }
                                                   >> 918   */
604   DefineMaterial(track.GetMaterialCutsCouple()    919   DefineMaterial(track.GetMaterialCutsCouple());
605   preStepKinEnergy       = track.GetKineticEne << 920   preStepKinEnergy    = track.GetKineticEnergy();
606   preStepScaledEnergy    = preStepKinEnergy*ma << 921   preStepScaledEnergy = preStepKinEnergy*massRatio;
607   SelectModel(preStepScaledEnergy);               922   SelectModel(preStepScaledEnergy);
                                                   >> 923   if(!currentModel->IsActive(preStepScaledEnergy)) { return x; }
608                                                   924 
609   if(!currentModel->IsActive(preStepScaledEner << 925   // change effective charge of an ion on fly
610     theNumberOfInteractionLengthLeft = -1.0;   << 
611     mfpKinEnergy = DBL_MAX;                    << 
612     preStepLambda = 0.0;                       << 
613     currentInteractionLength = DBL_MAX;        << 
614     return x;                                  << 
615   }                                            << 
616                                                << 
617   // change effective charge of a charged part << 
618   if(isIon) {                                     926   if(isIon) {
619     const G4double q2 = currentModel->ChargeSq << 927     G4double q2 = currentModel->ChargeSquareRatio(track);
620     fFactor = q2*biasFactor;                   << 928     if(q2 != chargeSqRatio) {
621     if(baseMat) { fFactor *= (*theDensityFacto << 929       chargeSqRatio = q2;
622     reduceFactor = 1.0/(fFactor*massRatio);    << 930       fFactor = q2*biasFactor*(*theDensityFactor)[currentCoupleIndex];
623     if (lossFluctuationFlag) {                 << 931       reduceFactor = 1.0/(fFactor*massRatio);
624       auto fluc = currentModel->GetModelOfFluc << 
625       fluc->SetParticleAndCharge(track.GetDefi << 
626     }                                             932     }
627   }                                               933   }
                                                   >> 934   //G4cout << "q2= " << chargeSqRatio << " massRatio= " << massRatio << G4endl; 
                                                   >> 935   // initialisation for sampling of the interaction length 
                                                   >> 936   if(previousStepSize <= 0.0) { theNumberOfInteractionLengthLeft = -1.0; }
                                                   >> 937   if(theNumberOfInteractionLengthLeft < 0.0) { mfpKinEnergy = DBL_MAX; }
628                                                   938 
629   // forced biasing only for primary particles    939   // forced biasing only for primary particles
630   if(biasManager) {                               940   if(biasManager) {
631     if(0 == track.GetParentID() && biasFlag && << 941     if(0 == track.GetParentID()) {
632        biasManager->ForcedInteractionRegion((G << 942       if(0 == track.GetCurrentStepNumber()) {
633       return biasManager->GetStepLimit((G4int) << 943         biasFlag = true; 
                                                   >> 944   biasManager->ResetForcedInteraction(); 
                                                   >> 945       }
                                                   >> 946       if(biasFlag && biasManager->ForcedInteractionRegion(currentCoupleIndex)) {
                                                   >> 947         return biasManager->GetStepLimit(currentCoupleIndex, previousStepSize);
                                                   >> 948       }
634     }                                             949     }
635   }                                               950   }
636                                                   951 
637   ComputeLambdaForScaledEnergy(preStepScaledEn << 952   // compute mean free path
638                                                << 953   if(preStepScaledEnergy < mfpKinEnergy) {
639   // zero cross section                        << 954     if (integral) { ComputeLambdaForScaledEnergy(preStepScaledEnergy); }
640   if(preStepLambda <= 0.0) {                   << 955     else  { preStepLambda = GetLambdaForScaledEnergy(preStepScaledEnergy); }
641     theNumberOfInteractionLengthLeft = -1.0;   << 956     if(preStepLambda <= 0.0) { mfpKinEnergy = 0.0; }
642     currentInteractionLength = DBL_MAX;        << 957   }
643   } else {                                     << 
644                                                   958 
645     // non-zero cross section                  << 959   // non-zero cross section
                                                   >> 960   if(preStepLambda > 0.0) { 
646     if (theNumberOfInteractionLengthLeft < 0.0    961     if (theNumberOfInteractionLengthLeft < 0.0) {
647                                                << 
648       // beggining of tracking (or just after     962       // beggining of tracking (or just after DoIt of this process)
649       theNumberOfInteractionLengthLeft = -G4Lo << 963       ResetNumberOfInteractionLengthLeft();
650       theInitialNumberOfInteractionLength = th << 
651                                                << 
652     } else if(currentInteractionLength < DBL_M    964     } else if(currentInteractionLength < DBL_MAX) {
653                                                << 965       // subtract NumberOfInteractionLengthLeft
654       // subtract NumberOfInteractionLengthLef << 966       SubtractNumberOfInteractionLengthLeft(previousStepSize);
655       theNumberOfInteractionLengthLeft -=      << 967       if(theNumberOfInteractionLengthLeft < 0.) {
656         previousStepSize/currentInteractionLen << 968   theNumberOfInteractionLengthLeft = perMillion;
657                                                << 969       }
658       theNumberOfInteractionLengthLeft =       << 
659         std::max(theNumberOfInteractionLengthL << 
660     }                                             970     }
661                                                   971 
662     // new mean free path and step limit       << 972     // get mean free path and step limit
663     currentInteractionLength = 1.0/preStepLamb    973     currentInteractionLength = 1.0/preStepLambda;
664     x = theNumberOfInteractionLengthLeft * cur    974     x = theNumberOfInteractionLengthLeft * currentInteractionLength;
665   }                                            << 
666 #ifdef G4VERBOSE                               << 
667   if (verboseLevel>2) {                        << 
668     G4cout << "G4VEnergyLossProcess::PostStepG << 
669     G4cout << "[ " << GetProcessName() << "]"  << 
670     G4cout << " for " << track.GetDefinition() << 
671            << " in Material  " <<  currentMate << 
672            << " Ekin(MeV)= " << preStepKinEner << 
673            << " track material: " << track.Get << 
674            <<G4endl;                           << 
675     G4cout << "MeanFreePath = " << currentInte << 
676            << "InteractionLength= " << x/cm << << 
677   }                                            << 
678 #endif                                         << 
679   return x;                                    << 
680 }                                              << 
681                                                << 
682 //....oooOO0OOooo........oooOO0OOooo........oo << 
683                                                   975 
684 void                                           << 976 #ifdef G4VERBOSE
685 G4VEnergyLossProcess::ComputeLambdaForScaledEn << 977     if (verboseLevel>2){
686 {                                              << 978       G4cout << "G4VEnergyLossProcess::PostStepGetPhysicalInteractionLength ";
687   // cross section increased with energy       << 979       G4cout << "[ " << GetProcessName() << "]" << G4endl; 
688   if(fXSType == fEmIncreasing) {               << 980       G4cout << " for " << currPart->GetParticleName() 
689     if(e*invLambdaFactor < mfpKinEnergy) {     << 981              << " in Material  " <<  currentMaterial->GetName()
690       preStepLambda = GetLambdaForScaledEnergy << 982        << " Ekin(MeV)= " << preStepKinEnergy/MeV 
691       mfpKinEnergy = (preStepLambda > 0.0) ? e << 983        <<G4endl;
692     }                                          << 984       G4cout << "MeanFreePath = " << currentInteractionLength/cm << "[cm]" 
693                                                << 985        << "InteractionLength= " << x/cm <<"[cm] " <<G4endl;
694     // cross section has one peak              << 
695   } else if(fXSType == fEmOnePeak) {           << 
696     const G4double epeak = (*theEnergyOfCrossS << 
697     if(e <= epeak) {                           << 
698       if(e*invLambdaFactor < mfpKinEnergy) {   << 
699         preStepLambda = GetLambdaForScaledEner << 
700         mfpKinEnergy = (preStepLambda > 0.0) ? << 
701       }                                        << 
702     } else if(e < mfpKinEnergy) {              << 
703       const G4double e1 = std::max(epeak, e*la << 
704       mfpKinEnergy = e1;                       << 
705       preStepLambda = GetLambdaForScaledEnergy << 
706     }                                          << 
707                                                << 
708     // cross section has more than one peaks   << 
709   } else if(fXSType == fEmTwoPeaks) {          << 
710     G4TwoPeaksXS* xs = (*fXSpeaks)[basedCouple << 
711     const G4double e1peak = xs->e1peak;        << 
712                                                << 
713     // below the 1st peak                      << 
714     if(e <= e1peak) {                          << 
715       if(e*invLambdaFactor < mfpKinEnergy) {   << 
716         preStepLambda = GetLambdaForScaledEner << 
717         mfpKinEnergy = (preStepLambda > 0.0) ? << 
718       }                                        << 
719       return;                                  << 
720     }                                          << 
721     const G4double e1deep = xs->e1deep;        << 
722     // above the 1st peak, below the deep      << 
723     if(e <= e1deep) {                          << 
724       if(mfpKinEnergy >= e1deep || e <= mfpKin << 
725         const G4double e1 = std::max(e1peak, e << 
726         mfpKinEnergy = e1;                     << 
727         preStepLambda = GetLambdaForScaledEner << 
728       }                                        << 
729       return;                                  << 
730     }                                          << 
731     const G4double e2peak = xs->e2peak;        << 
732     // above the deep, below 2nd peak          << 
733     if(e <= e2peak) {                          << 
734       if(e*invLambdaFactor < mfpKinEnergy) {   << 
735         mfpKinEnergy = e;                      << 
736         preStepLambda = GetLambdaForScaledEner << 
737       }                                        << 
738       return;                                  << 
739     }                                          << 
740     const G4double e2deep = xs->e2deep;        << 
741     // above the 2nd peak, below the deep      << 
742     if(e <= e2deep) {                          << 
743       if(mfpKinEnergy >= e2deep || e <= mfpKin << 
744         const G4double e1 = std::max(e2peak, e << 
745         mfpKinEnergy = e1;                     << 
746         preStepLambda = GetLambdaForScaledEner << 
747       }                                        << 
748       return;                                  << 
749     }                                          << 
750     const G4double e3peak = xs->e3peak;        << 
751     // above the deep, below 3d peak           << 
752     if(e <= e3peak) {                          << 
753       if(e*invLambdaFactor < mfpKinEnergy) {   << 
754         mfpKinEnergy = e;                      << 
755         preStepLambda = GetLambdaForScaledEner << 
756       }                                        << 
757       return;                                  << 
758     }                                          << 
759     // above 3d peak                           << 
760     if(e <= mfpKinEnergy) {                    << 
761       const G4double e1 = std::max(e3peak, e*l << 
762       mfpKinEnergy = e1;                       << 
763       preStepLambda = GetLambdaForScaledEnergy << 
764     }                                             986     }
765     // integral method is not used             << 987 #endif
                                                   >> 988     // zero cross section case
766   } else {                                        989   } else {
767     preStepLambda = GetLambdaForScaledEnergy(e << 990     if(theNumberOfInteractionLengthLeft > DBL_MIN && 
                                                   >> 991        currentInteractionLength < DBL_MAX) {
                                                   >> 992       // subtract NumberOfInteractionLengthLeft
                                                   >> 993       SubtractNumberOfInteractionLengthLeft(previousStepSize);
                                                   >> 994       if(theNumberOfInteractionLengthLeft < 0.) {
                                                   >> 995   theNumberOfInteractionLengthLeft = perMillion;
                                                   >> 996       }
                                                   >> 997     }
                                                   >> 998     currentInteractionLength = DBL_MAX;
768   }                                               999   }
                                                   >> 1000   return x;
769 }                                                 1001 }
770                                                   1002 
771 //....oooOO0OOooo........oooOO0OOooo........oo    1003 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
772                                                   1004 
773 G4VParticleChange* G4VEnergyLossProcess::Along    1005 G4VParticleChange* G4VEnergyLossProcess::AlongStepDoIt(const G4Track& track,
774                                                   1006                                                        const G4Step& step)
775 {                                                 1007 {
776   fParticleChange.InitializeForAlongStep(track    1008   fParticleChange.InitializeForAlongStep(track);
777   // The process has range table - calculate e    1009   // The process has range table - calculate energy loss
778   if(!isIonisation || !currentModel->IsActive(    1010   if(!isIonisation || !currentModel->IsActive(preStepScaledEnergy)) {
779     return &fParticleChange;                      1011     return &fParticleChange;
780   }                                               1012   }
781                                                   1013 
                                                   >> 1014   // Get the actual (true) Step length
782   G4double length = step.GetStepLength();         1015   G4double length = step.GetStepLength();
                                                   >> 1016   if(length <= 0.0) { return &fParticleChange; }
783   G4double eloss  = 0.0;                          1017   G4double eloss  = 0.0;
784                                                   1018  
785   /*                                           << 1019   /*
786   if(-1 < verboseLevel) {                      << 1020   if(1 < verboseLevel) {
787     const G4ParticleDefinition* d = track.GetP    1021     const G4ParticleDefinition* d = track.GetParticleDefinition();
788     G4cout << "AlongStepDoIt for "                1022     G4cout << "AlongStepDoIt for "
789            << GetProcessName() << " and partic << 1023            << GetProcessName() << " and particle "
790            << "  eScaled(MeV)=" << preStepScal << 1024            << d->GetParticleName()
791            << "  range(mm)=" << fRange/mm << " << 1025            << "  eScaled(MeV)= " << preStepScaledEnergy/MeV
792            << "  rf=" << reduceFactor << "  q^ << 1026            << "  range(mm)= " << fRange/mm
793            << " md=" << d->GetPDGMass() << "   << 1027            << "  s(mm)= " << length/mm
794            << "  " << track.GetMaterial()->Get << 1028      << "  rf= " << reduceFactor
                                                   >> 1029            << "  q^2= " << chargeSqRatio
                                                   >> 1030            << " md= " << d->GetPDGMass()
                                                   >> 1031            << "  status= " << track.GetTrackStatus()
                                                   >> 1032            << G4endl;
795   }                                               1033   }
796   */                                              1034   */
                                                   >> 1035 
797   const G4DynamicParticle* dynParticle = track    1036   const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
798                                                   1037 
799   // define new weight for primary and seconda    1038   // define new weight for primary and secondaries
800   G4double weight = fParticleChange.GetParentW    1039   G4double weight = fParticleChange.GetParentWeight();
801   if(weightFlag) {                                1040   if(weightFlag) {
802     weight /= biasFactor;                         1041     weight /= biasFactor;
803     fParticleChange.ProposeWeight(weight);     << 1042     fParticleChange.ProposeParentWeight(weight);
804   }                                               1043   }
805                                                   1044 
806   // stopping, check actual range and kinetic  << 1045   // stopping
807   if (length >= fRange || preStepKinEnergy <=  << 1046   if (length >= fRange) {
808     eloss = preStepKinEnergy;                     1047     eloss = preStepKinEnergy;
809     if (useDeexcitation) {                        1048     if (useDeexcitation) {
810       atomDeexcitation->AlongStepDeexcitation(    1049       atomDeexcitation->AlongStepDeexcitation(scTracks, step, 
811                                                << 1050                 eloss, currentCoupleIndex);
812       if(scTracks.size() > 0) { FillSecondarie << 1051       FillSecondariesAlongStep(eloss, weight);
813       eloss = std::max(eloss, 0.0);            << 
814     }                                             1052     }
815     fParticleChange.SetProposedKineticEnergy(0    1053     fParticleChange.SetProposedKineticEnergy(0.0);
816     fParticleChange.ProposeLocalEnergyDeposit(    1054     fParticleChange.ProposeLocalEnergyDeposit(eloss);
817     return &fParticleChange;                      1055     return &fParticleChange;
818   }                                               1056   }
819   // zero step length with non-zero range      << 
820   if(length <= 0.0) { return &fParticleChange; << 
821                                                   1057 
822   // Short step                                   1058   // Short step
823   eloss = length*GetDEDXForScaledEnergy(preSte << 1059   eloss = GetDEDXForScaledEnergy(preStepScaledEnergy)*length;
824                                         LogSca << 1060 
825   /*                                           << 
826   G4cout << "##### Short STEP: eloss= " << elo << 
827    << " Escaled=" << preStepScaledEnergy       << 
828    << " R=" << fRange                          << 
829    << " L=" << length                          << 
830    << " fFactor=" << fFactor << " minE=" << mi << 
831    << " idxBase=" << basedCoupleIndex << G4end << 
832   */                                           << 
833   // Long step                                    1061   // Long step
834   if(eloss > preStepKinEnergy*linLossLimit) {     1062   if(eloss > preStepKinEnergy*linLossLimit) {
835                                                   1063 
836     const G4double x = (fRange - length)/reduc << 1064     G4double x = GetScaledRangeForScaledEnergy(preStepScaledEnergy) 
837     const G4double de = preStepKinEnergy - Sca << 1065       - length/reduceFactor;
838     if(de > 0.0) { eloss = de; }               << 1066     eloss = preStepKinEnergy - ScaledKinEnergyForLoss(x)/massRatio;
                                                   >> 1067    
839     /*                                            1068     /*
840     if(-1 < verboseLevel)                         1069     if(-1 < verboseLevel) 
841       G4cout << "  Long STEP: rPre(mm)="       << 1070       G4cout << "Long STEP: rPre(mm)= " 
842              << GetScaledRangeForScaledEnergy(    1071              << GetScaledRangeForScaledEnergy(preStepScaledEnergy)/mm
843              << " x(mm)=" << x/mm              << 1072              << " rPost(mm)= " << x/mm
844              << " eloss(MeV)=" << eloss/MeV    << 1073              << " ePre(MeV)= " << preStepScaledEnergy/MeV
845        << " rFactor=" << reduceFactor          << 1074              << " eloss(MeV)= " << eloss/MeV
846        << " massRatio=" << massRatio           << 1075              << " eloss0(MeV)= "
                                                   >> 1076              << GetDEDXForScaledEnergy(preStepScaledEnergy)*length/MeV
                                                   >> 1077        << " lim(MeV)= " << preStepKinEnergy*linLossLimit/MeV
847              << G4endl;                           1078              << G4endl;
848     */                                            1079     */
849   }                                               1080   }
850                                                   1081 
851   /*                                           << 1082   /*   
                                                   >> 1083   G4double eloss0 = eloss;
852   if(-1 < verboseLevel ) {                        1084   if(-1 < verboseLevel ) {
853     G4cout << "Before fluct: eloss(MeV)= " <<     1085     G4cout << "Before fluct: eloss(MeV)= " << eloss/MeV
854            << " e-eloss= " << preStepKinEnergy    1086            << " e-eloss= " << preStepKinEnergy-eloss
855            << " step(mm)= " << length/mm << "  << 1087            << " step(mm)= " << length/mm
856            << " fluct= " << lossFluctuationFla << 1088            << " range(mm)= " << fRange/mm
                                                   >> 1089            << " fluct= " << lossFluctuationFlag
                                                   >> 1090            << G4endl;
857   }                                               1091   }
858   */                                              1092   */
859                                                   1093 
860   const G4double cut = (*theCuts)[currentCoupl << 1094   G4double cut  = (*theCuts)[currentCoupleIndex];
861   G4double esec = 0.0;                            1095   G4double esec = 0.0;
862                                                   1096 
                                                   >> 1097   // SubCutOff 
                                                   >> 1098   if(useSubCutoff) {
                                                   >> 1099     if(idxSCoffRegions[currentCoupleIndex]) {
                                                   >> 1100 
                                                   >> 1101       G4bool yes = false;
                                                   >> 1102       G4StepPoint* prePoint = step.GetPreStepPoint();
                                                   >> 1103 
                                                   >> 1104       // Check boundary
                                                   >> 1105       if(prePoint->GetStepStatus() == fGeomBoundary) { yes = true; }
                                                   >> 1106 
                                                   >> 1107       // Check PrePoint
                                                   >> 1108       else {
                                                   >> 1109   G4double preSafety  = prePoint->GetSafety();
                                                   >> 1110   G4double rcut = currentCouple->GetProductionCuts()->GetProductionCut(1);
                                                   >> 1111 
                                                   >> 1112   // recompute presafety
                                                   >> 1113         if(preSafety < rcut) {
                                                   >> 1114     preSafety = safetyHelper->ComputeSafety(prePoint->GetPosition());
                                                   >> 1115   }
                                                   >> 1116 
                                                   >> 1117         if(preSafety < rcut) { yes = true; }
                                                   >> 1118 
                                                   >> 1119   // Check PostPoint
                                                   >> 1120   else {
                                                   >> 1121     G4double postSafety = preSafety - length; 
                                                   >> 1122     if(postSafety < rcut) {
                                                   >> 1123       postSafety = 
                                                   >> 1124         safetyHelper->ComputeSafety(step.GetPostStepPoint()->GetPosition());
                                                   >> 1125       if(postSafety < rcut) { yes = true; }
                                                   >> 1126     }
                                                   >> 1127   }
                                                   >> 1128       }
                                                   >> 1129   
                                                   >> 1130       // Decided to start subcut sampling
                                                   >> 1131       if(yes) {
                                                   >> 1132 
                                                   >> 1133         cut = (*theSubCuts)[currentCoupleIndex];
                                                   >> 1134   eloss -= GetSubDEDXForScaledEnergy(preStepScaledEnergy)*length;
                                                   >> 1135   esec = SampleSubCutSecondaries(scTracks, step, 
                                                   >> 1136                currentModel,currentCoupleIndex);
                                                   >> 1137   // add bremsstrahlung sampling
                                                   >> 1138   /*
                                                   >> 1139   if(nProcesses > 0) {
                                                   >> 1140     for(G4int i=0; i<nProcesses; ++i) {
                                                   >> 1141       (scProcesses[i])->SampleSubCutSecondaries(
                                                   >> 1142     scTracks, step, (scProcesses[i])->
                                                   >> 1143     SelectModelForMaterial(preStepKinEnergy, currentCoupleIndex),
                                                   >> 1144     currentCoupleIndex);
                                                   >> 1145     }
                                                   >> 1146   } 
                                                   >> 1147   */
                                                   >> 1148       }   
                                                   >> 1149     }
                                                   >> 1150   }
                                                   >> 1151 
863   // Corrections, which cannot be tabulated       1152   // Corrections, which cannot be tabulated
864   if(isIon) {                                     1153   if(isIon) {
                                                   >> 1154     G4double eadd = 0.0;
                                                   >> 1155     G4double eloss_before = eloss;
865     currentModel->CorrectionsAlongStep(current    1156     currentModel->CorrectionsAlongStep(currentCouple, dynParticle, 
866                                        length, << 1157                eloss, eadd, length);
867     eloss = std::max(eloss, 0.0);              << 1158     if(eloss < 0.0) { eloss = 0.5*eloss_before; }
868   }                                               1159   }
869                                                   1160 
870   // Sample fluctuations if not full energy lo << 1161   // Sample fluctuations
871   if(eloss >= preStepKinEnergy) {              << 1162   if (lossFluctuationFlag) {
872     eloss = preStepKinEnergy;                  << 
873                                                << 
874   } else if (lossFluctuationFlag) {            << 
875     const G4double tmax = currentModel->MaxSec << 
876     const G4double tcut = std::min(cut, tmax); << 
877     G4VEmFluctuationModel* fluc = currentModel    1163     G4VEmFluctuationModel* fluc = currentModel->GetModelOfFluctuations();
878     eloss = fluc->SampleFluctuations(currentCo << 1164     if(fluc && 
879                                      tcut, tma << 1165       (eloss + esec + lowestKinEnergy) < preStepKinEnergy) {
880     /*                                         << 1166 
881     if(-1 < verboseLevel)                      << 1167       G4double tmax = 
                                                   >> 1168   std::min(currentModel->MaxSecondaryKinEnergy(dynParticle),cut);
                                                   >> 1169       G4double emean = eloss;
                                                   >> 1170       eloss = fluc->SampleFluctuations(currentMaterial,dynParticle,
                                                   >> 1171                tmax,length,emean);
                                                   >> 1172       /*                            
                                                   >> 1173       if(-1 < verboseLevel) 
882       G4cout << "After fluct: eloss(MeV)= " <<    1174       G4cout << "After fluct: eloss(MeV)= " << eloss/MeV
883              << " fluc= " << (eloss-eloss0)/Me    1175              << " fluc= " << (eloss-eloss0)/MeV
884              << " ChargeSqRatio= " << chargeSq    1176              << " ChargeSqRatio= " << chargeSqRatio
885              << " massRatio= " << massRatio << << 1177              << " massRatio= " << massRatio
886     */                                         << 1178              << " tmax= " << tmax
                                                   >> 1179              << G4endl;
                                                   >> 1180       */
                                                   >> 1181     }
887   }                                               1182   }
888                                                   1183 
889   // deexcitation                                 1184   // deexcitation
890   if (useDeexcitation) {                          1185   if (useDeexcitation) {
891     G4double esecfluo = preStepKinEnergy;      << 1186     G4double eloss_before = eloss;
892     G4double de = esecfluo;                    << 
893     atomDeexcitation->AlongStepDeexcitation(sc    1187     atomDeexcitation->AlongStepDeexcitation(scTracks, step, 
894                                             de << 1188               eloss, currentCoupleIndex);
895                                                << 1189     esec += eloss_before - eloss;
896     // sum of de-excitation energies           << 
897     esecfluo -= de;                            << 
898                                                << 
899     // subtracted from energy loss             << 
900     if(eloss >= esecfluo) {                    << 
901       esec  += esecfluo;                       << 
902       eloss -= esecfluo;                       << 
903     } else {                                   << 
904       esec += esecfluo;                        << 
905       eloss = 0.0;                             << 
906     }                                          << 
907   }                                            << 
908   if(nullptr != subcutProducer && IsRegionForC << 
909     subcutProducer->SampleSecondaries(step, sc << 
910   }                                               1190   }
911   // secondaries from atomic de-excitation and << 
912   if(!scTracks.empty()) { FillSecondariesAlong << 
913                                                   1191 
914   // Energy balance                            << 1192   // Energy balanse
915   G4double finalT = preStepKinEnergy - eloss -    1193   G4double finalT = preStepKinEnergy - eloss - esec;
916   if (finalT <= lowestKinEnergy) {                1194   if (finalT <= lowestKinEnergy) {
917     eloss += finalT;                              1195     eloss += finalT;
918     finalT = 0.0;                                 1196     finalT = 0.0;
919   } else if(isIon) {                              1197   } else if(isIon) {
920     fParticleChange.SetProposedCharge(            1198     fParticleChange.SetProposedCharge(
921       currentModel->GetParticleCharge(track.Ge    1199       currentModel->GetParticleCharge(track.GetParticleDefinition(),
922                                       currentM << 1200               currentMaterial,finalT));
923   }                                               1201   }
924   eloss = std::max(eloss, 0.0);                << 
925                                                   1202 
                                                   >> 1203   FillSecondariesAlongStep(eloss, weight);
926   fParticleChange.SetProposedKineticEnergy(fin    1204   fParticleChange.SetProposedKineticEnergy(finalT);
927   fParticleChange.ProposeLocalEnergyDeposit(el    1205   fParticleChange.ProposeLocalEnergyDeposit(eloss);
928   /*                                           << 1206 
                                                   >> 1207   /*  
929   if(-1 < verboseLevel) {                         1208   if(-1 < verboseLevel) {
930     G4double del = finalT + eloss + esec - pre << 
931     G4cout << "Final value eloss(MeV)= " << el    1209     G4cout << "Final value eloss(MeV)= " << eloss/MeV
932            << " preStepKinEnergy= " << preStep    1210            << " preStepKinEnergy= " << preStepKinEnergy
933            << " postStepKinEnergy= " << finalT    1211            << " postStepKinEnergy= " << finalT
934            << " de(keV)= " << del/keV          << 
935            << " lossFlag= " << lossFluctuation    1212            << " lossFlag= " << lossFluctuationFlag
936            << "  status= " << track.GetTrackSt    1213            << "  status= " << track.GetTrackStatus()
937            << G4endl;                             1214            << G4endl;
938   }                                               1215   }
939   */                                           << 1216   */  
                                                   >> 1217 
940   return &fParticleChange;                        1218   return &fParticleChange;
941 }                                                 1219 }
942                                                   1220 
943 //....oooOO0OOooo........oooOO0OOooo........oo    1221 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
944                                                   1222 
945 void G4VEnergyLossProcess::FillSecondariesAlon << 1223 void 
                                                   >> 1224 G4VEnergyLossProcess::FillSecondariesAlongStep(G4double& eloss, G4double& weight)
946 {                                                 1225 {
947   const std::size_t n0 = scTracks.size();      << 1226   if(eloss < 0.0) { eloss = 0.0; }
948   G4double weight = wt;                        << 1227   G4int n = scTracks.size();
                                                   >> 1228   if(0 == n) { return; }
                                                   >> 1229 
949   // weight may be changed by biasing manager     1230   // weight may be changed by biasing manager
                                                   >> 1231   G4bool weightNotChanged = true;
950   if(biasManager) {                               1232   if(biasManager) {
951     if(biasManager->SecondaryBiasingRegion((G4 << 1233     if(biasManager->SecondaryBiasingRegion(currentCoupleIndex)) {
952       weight *=                                << 1234       biasManager->ApplySecondaryBiasing(scTracks,weight,currentCoupleIndex);
953         biasManager->ApplySecondaryBiasing(scT << 1235       weightNotChanged = false;
954     }                                             1236     }
955   }                                            << 1237   }   
956                                                   1238 
957   // fill secondaries                             1239   // fill secondaries
958   const std::size_t n = scTracks.size();       << 1240   fParticleChange.SetNumberOfSecondaries(n);
959   fParticleChange.SetNumberOfSecondaries((G4in << 1241   for(G4int i=0; i<n; ++i) {
960                                                << 
961   for(std::size_t i=0; i<n; ++i) {             << 
962     G4Track* t = scTracks[i];                     1242     G4Track* t = scTracks[i];
963     if(nullptr != t) {                         << 1243     if(t) {
964       t->SetWeight(weight);                    << 1244       if(weightNotChanged) { t->SetWeight(weight); }
965       pParticleChange->AddSecondary(t);           1245       pParticleChange->AddSecondary(t);
966       G4int pdg = t->GetDefinition()->GetPDGEn << 
967       if (i < n0) {                            << 
968         if (pdg == 22) {                       << 
969     t->SetCreatorModelID(gpixeID);             << 
970         } else if (pdg == 11) {                << 
971           t->SetCreatorModelID(epixeID);       << 
972         } else {                               << 
973           t->SetCreatorModelID(biasID);        << 
974   }                                            << 
975       } else {                                 << 
976   t->SetCreatorModelID(biasID);                << 
977       }                                        << 
978     }                                             1246     }
979   }                                               1247   }
980   scTracks.clear();                               1248   scTracks.clear();
981 }                                                 1249 }
982                                                   1250 
983 //....oooOO0OOooo........oooOO0OOooo........oo    1251 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
984                                                   1252 
                                                   >> 1253 G4double 
                                                   >> 1254 G4VEnergyLossProcess::SampleSubCutSecondaries(std::vector<G4Track*>& tracks, 
                                                   >> 1255                 const G4Step& step, 
                                                   >> 1256                 G4VEmModel* model,
                                                   >> 1257                 G4int idx) 
                                                   >> 1258 {
                                                   >> 1259   // Fast check weather subcutoff can work
                                                   >> 1260   G4double esec = 0.0;
                                                   >> 1261   G4double subcut = (*theSubCuts)[idx];
                                                   >> 1262   G4double cut = (*theCuts)[idx];
                                                   >> 1263   if(cut <= subcut) { return esec; }
                                                   >> 1264 
                                                   >> 1265   const G4Track* track = step.GetTrack();
                                                   >> 1266   const G4DynamicParticle* dp = track->GetDynamicParticle();
                                                   >> 1267   G4double e = dp->GetKineticEnergy()*massRatio;
                                                   >> 1268   G4double cross = (*theDensityFactor)[idx]*chargeSqRatio
                                                   >> 1269     *(((*theSubLambdaTable)[(*theDensityIdx)[idx]])->Value(e));
                                                   >> 1270   G4double length = step.GetStepLength();
                                                   >> 1271 
                                                   >> 1272   // negligible probability to get any interaction
                                                   >> 1273   if(length*cross < perMillion) { return esec; }
                                                   >> 1274   /*      
                                                   >> 1275   if(-1 < verboseLevel) 
                                                   >> 1276     G4cout << "<<< Subcutoff for " << GetProcessName()
                                                   >> 1277      << " cross(1/mm)= " << cross*mm << ">>>"
                                                   >> 1278      << " e(MeV)= " << preStepScaledEnergy
                                                   >> 1279      << " matIdx= " << currentCoupleIndex
                                                   >> 1280      << G4endl;
                                                   >> 1281   */
                                                   >> 1282 
                                                   >> 1283   // Sample subcutoff secondaries
                                                   >> 1284   G4StepPoint* preStepPoint = step.GetPreStepPoint();
                                                   >> 1285   G4StepPoint* postStepPoint = step.GetPostStepPoint();
                                                   >> 1286   G4ThreeVector prepoint = preStepPoint->GetPosition();
                                                   >> 1287   G4ThreeVector dr = postStepPoint->GetPosition() - prepoint;
                                                   >> 1288   G4double pretime = preStepPoint->GetGlobalTime();
                                                   >> 1289   G4double dt = postStepPoint->GetGlobalTime() - pretime;
                                                   >> 1290   //G4double dt = length/preStepPoint->GetVelocity();
                                                   >> 1291   G4double fragment = 0.0;
                                                   >> 1292 
                                                   >> 1293   do {
                                                   >> 1294     G4double del = -std::log(G4UniformRand())/cross;
                                                   >> 1295     fragment += del/length;
                                                   >> 1296     if (fragment > 1.0) break;
                                                   >> 1297 
                                                   >> 1298     // sample secondaries
                                                   >> 1299     secParticles.clear();
                                                   >> 1300     model->SampleSecondaries(&secParticles,track->GetMaterialCutsCouple(),
                                                   >> 1301            dp,subcut,cut);
                                                   >> 1302 
                                                   >> 1303     // position of subcutoff particles
                                                   >> 1304     G4ThreeVector r = prepoint + fragment*dr;
                                                   >> 1305     std::vector<G4DynamicParticle*>::iterator it;
                                                   >> 1306     for(it=secParticles.begin(); it!=secParticles.end(); ++it) {
                                                   >> 1307 
                                                   >> 1308       G4bool addSec = true;
                                                   >> 1309       /*
                                                   >> 1310       // do not track very low-energy delta-electrons
                                                   >> 1311       if(theSecondaryRangeTable && (*it)->GetParticleDefinition() == theElectron) {
                                                   >> 1312   G4double ekin = (*it)->GetKineticEnergy();
                                                   >> 1313   G4double rg = ((*theSecondaryRangeTable)[idx]->Value(ekin));
                                                   >> 1314   //          if(rg < currentMinSafety) {
                                                   >> 1315   if(rg < safetyHelper->ComputeSafety(r)) {
                                                   >> 1316     extraEdep += ekin;
                                                   >> 1317     delete (*it);
                                                   >> 1318     addSec = false;
                                                   >> 1319   }
                                                   >> 1320       }
                                                   >> 1321       */
                                                   >> 1322       if(addSec) {
                                                   >> 1323   G4Track* t = new G4Track((*it), pretime + fragment*dt, r);
                                                   >> 1324   t->SetTouchableHandle(track->GetTouchableHandle());
                                                   >> 1325   tracks.push_back(t);
                                                   >> 1326   esec += t->GetKineticEnergy();
                                                   >> 1327   if (t->GetParticleDefinition() == thePositron) { 
                                                   >> 1328     esec += 2.0*electron_mass_c2; 
                                                   >> 1329   }
                                                   >> 1330 
                                                   >> 1331   /*  
                                                   >> 1332   if(-1 < verboseLevel) 
                                                   >> 1333     G4cout << "New track " << t->GetParticleDefinition()->GetParticleName()
                                                   >> 1334      << " e(keV)= " << t->GetKineticEnergy()/keV
                                                   >> 1335      << " fragment= " << fragment
                                                   >> 1336      << G4endl;
                                                   >> 1337   */
                                                   >> 1338       }
                                                   >> 1339     }
                                                   >> 1340   } while (fragment <= 1.0);
                                                   >> 1341   return esec;
                                                   >> 1342 } 
                                                   >> 1343 
                                                   >> 1344 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
                                                   >> 1345 
985 G4VParticleChange* G4VEnergyLossProcess::PostS    1346 G4VParticleChange* G4VEnergyLossProcess::PostStepDoIt(const G4Track& track,
986                                                << 1347                                                       const G4Step&)
987 {                                                 1348 {
988   // clear number of interaction lengths in an << 1349   // In all cases clear number of interaction lengths
989   theNumberOfInteractionLengthLeft = -1.0;        1350   theNumberOfInteractionLengthLeft = -1.0;
990   mfpKinEnergy = DBL_MAX;                      << 
991                                                   1351 
992   fParticleChange.InitializeForPostStep(track)    1352   fParticleChange.InitializeForPostStep(track);
993   const G4double finalT = track.GetKineticEner << 1353   G4double finalT = track.GetKineticEnergy();
                                                   >> 1354   if(finalT <= lowestKinEnergy) { return &fParticleChange; }
994                                                   1355 
995   const G4double postStepScaledEnergy = finalT << 1356   G4double postStepScaledEnergy = finalT*massRatio;
996   SelectModel(postStepScaledEnergy);           << 
997                                                   1357 
998   if(!currentModel->IsActive(postStepScaledEne << 1358   if(!currentModel->IsActive(postStepScaledEnergy)) { return &fParticleChange; }
999     return &fParticleChange;                   << 
1000   }                                           << 
1001   /*                                             1359   /*
1002   if(1 < verboseLevel) {                      << 1360   if(-1 < verboseLevel) {
1003     G4cout<<GetProcessName()<<" PostStepDoIt: << 1361     G4cout << GetProcessName()
                                                   >> 1362            << "::PostStepDoIt: E(MeV)= " << finalT/MeV
                                                   >> 1363      << G4endl;
1004   }                                              1364   }
1005   */                                             1365   */
                                                   >> 1366 
1006   // forced process - should happen only once    1367   // forced process - should happen only once per track
1007   if(biasFlag) {                                 1368   if(biasFlag) {
1008     if(biasManager->ForcedInteractionRegion(( << 1369     if(biasManager->ForcedInteractionRegion(currentCoupleIndex)) {
1009       biasFlag = false;                          1370       biasFlag = false;
1010     }                                            1371     }
1011   }                                              1372   }
1012   const G4DynamicParticle* dp = track.GetDyna << 
1013                                                  1373 
1014   // Integral approach                           1374   // Integral approach
1015   if (fXSType != fEmNoIntegral) {             << 1375   if (integral) {
1016     const G4double logFinalT = dp->GetLogKine << 1376     G4double lx = GetLambdaForScaledEnergy(postStepScaledEnergy);
1017     G4double lx = GetLambdaForScaledEnergy(po << 1377     /*
1018                                            lo << 1378     if(preStepLambda<lx && 1 < verboseLevel && nWarnings<200) {
1019     lx = std::max(lx, 0.0);                   << 1379       G4cout << "WARNING: for " << particle->GetParticleName()
1020                                               << 1380              << " and " << GetProcessName()
1021     // if both lg and lx are zero then no int << 1381              << " E(MeV)= " << finalT/MeV
1022     if(preStepLambda*G4UniformRand() >= lx) { << 1382              << " preLambda= " << preStepLambda 
                                                   >> 1383        << " < " << lx << " (postLambda) "
                                                   >> 1384        << G4endl;
                                                   >> 1385       ++nWarnings;
                                                   >> 1386     }
                                                   >> 1387     */
                                                   >> 1388     if(lx <= 0.0) {
                                                   >> 1389       return &fParticleChange;
                                                   >> 1390     } else if(preStepLambda*G4UniformRand() > lx) {
1023       return &fParticleChange;                   1391       return &fParticleChange;
1024     }                                            1392     }
1025   }                                              1393   }
1026                                                  1394 
                                                   >> 1395   SelectModel(postStepScaledEnergy);
                                                   >> 1396 
1027   // define new weight for primary and second    1397   // define new weight for primary and secondaries
1028   G4double weight = fParticleChange.GetParent    1398   G4double weight = fParticleChange.GetParentWeight();
1029   if(weightFlag) {                               1399   if(weightFlag) {
1030     weight /= biasFactor;                        1400     weight /= biasFactor;
1031     fParticleChange.ProposeWeight(weight);    << 1401     fParticleChange.ProposeParentWeight(weight);
1032   }                                              1402   }
1033                                                  1403 
1034   const G4double tcut = (*theCuts)[currentCou << 1404   const G4DynamicParticle* dynParticle = track.GetDynamicParticle();
                                                   >> 1405   G4double tcut = (*theCuts)[currentCoupleIndex];
1035                                                  1406 
1036   // sample secondaries                          1407   // sample secondaries
1037   secParticles.clear();                          1408   secParticles.clear();
1038   currentModel->SampleSecondaries(&secParticl << 1409   currentModel->SampleSecondaries(&secParticles, currentCouple, dynParticle, tcut);
1039                                               << 
1040   const G4int num0 = (G4int)secParticles.size << 
1041                                                  1410 
1042   // bremsstrahlung splitting or Russian roul    1411   // bremsstrahlung splitting or Russian roulette  
1043   if(biasManager) {                              1412   if(biasManager) {
1044     if(biasManager->SecondaryBiasingRegion((G << 1413     if(biasManager->SecondaryBiasingRegion(currentCoupleIndex)) {
1045       G4double eloss = 0.0;                   << 1414       weight *= biasManager->ApplySecondaryBiasing(secParticles,currentCoupleIndex);
1046       weight *= biasManager->ApplySecondaryBi << 
1047                                       secPart << 
1048                                       track,  << 
1049                                       &fParti << 
1050                                       (G4int) << 
1051                                       step.Ge << 
1052       if(eloss > 0.0) {                       << 
1053         eloss += fParticleChange.GetLocalEner << 
1054         fParticleChange.ProposeLocalEnergyDep << 
1055       }                                       << 
1056     }                                            1415     }
1057   }                                              1416   }
1058                                                  1417 
1059   // save secondaries                            1418   // save secondaries
1060   const G4int num = (G4int)secParticles.size( << 1419   G4int num = secParticles.size();
1061   if(num > 0) {                                  1420   if(num > 0) {
1062                                               << 
1063     fParticleChange.SetNumberOfSecondaries(nu    1421     fParticleChange.SetNumberOfSecondaries(num);
1064     G4double time = track.GetGlobalTime();    << 
1065                                               << 
1066     G4int n1(0), n2(0);                       << 
1067     if(num0 > mainSecondaries) {              << 
1068       currentModel->FillNumberOfSecondaries(n << 
1069     }                                         << 
1070                                               << 
1071     for (G4int i=0; i<num; ++i) {                1422     for (G4int i=0; i<num; ++i) {
1072       if(nullptr != secParticles[i]) {        << 1423 
1073         G4Track* t = new G4Track(secParticles << 1424       if(secParticles[i]) {
1074         t->SetTouchableHandle(track.GetToucha << 1425   G4Track* t = new G4Track(secParticles[i], track.GetGlobalTime(), 
1075         if (biasManager) {                    << 1426          track.GetPosition());
1076           t->SetWeight(weight * biasManager-> << 1427   t->SetTouchableHandle(track.GetTouchableHandle());
1077         } else {                              << 1428   t->SetWeight(weight); 
1078           t->SetWeight(weight);               << 1429   pParticleChange->AddSecondary(t);
1079         }                                     << 
1080         if(i < num0) {                        << 
1081           t->SetCreatorModelID(secID);        << 
1082         } else if(i < num0 + n1) {            << 
1083           t->SetCreatorModelID(tripletID);    << 
1084         } else {                              << 
1085           t->SetCreatorModelID(biasID);       << 
1086         }                                     << 
1087                                               << 
1088         //G4cout << "Secondary(post step) has << 
1089         //       << ", kenergy " << t->GetKin << 
1090         //       << " time= " << time/ns << " << 
1091         pParticleChange->AddSecondary(t);     << 
1092       }                                          1430       }
1093     }                                            1431     }
1094   }                                              1432   }
1095                                                  1433 
1096   if(0.0 == fParticleChange.GetProposedKineti    1434   if(0.0 == fParticleChange.GetProposedKineticEnergy() &&
1097      fAlive == fParticleChange.GetTrackStatus    1435      fAlive == fParticleChange.GetTrackStatus()) {
1098     if(particle->GetProcessManager()->GetAtRe    1436     if(particle->GetProcessManager()->GetAtRestProcessVector()->size() > 0)
1099          { fParticleChange.ProposeTrackStatus    1437          { fParticleChange.ProposeTrackStatus(fStopButAlive); }
1100     else { fParticleChange.ProposeTrackStatus    1438     else { fParticleChange.ProposeTrackStatus(fStopAndKill); }
1101   }                                              1439   }
1102                                                  1440 
1103   /*                                             1441   /*
1104   if(-1 < verboseLevel) {                        1442   if(-1 < verboseLevel) {
1105     G4cout << "::PostStepDoIt: Sample seconda    1443     G4cout << "::PostStepDoIt: Sample secondary; Efin= " 
1106     << fParticleChange.GetProposedKineticEner    1444     << fParticleChange.GetProposedKineticEnergy()/MeV
1107            << " MeV; model= (" << currentMode    1445            << " MeV; model= (" << currentModel->LowEnergyLimit()
1108            << ", " <<  currentModel->HighEner    1446            << ", " <<  currentModel->HighEnergyLimit() << ")"
1109            << "  preStepLambda= " << preStepL    1447            << "  preStepLambda= " << preStepLambda
1110            << "  dir= " << track.GetMomentumD    1448            << "  dir= " << track.GetMomentumDirection()
1111            << "  status= " << track.GetTrackS    1449            << "  status= " << track.GetTrackStatus()
1112            << G4endl;                            1450            << G4endl;
1113   }                                              1451   }
1114   */                                             1452   */
1115   return &fParticleChange;                       1453   return &fParticleChange;
1116 }                                                1454 }
1117                                                  1455 
1118 //....oooOO0OOooo........oooOO0OOooo........o    1456 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1119                                                  1457 
1120 G4bool G4VEnergyLossProcess::StorePhysicsTabl    1458 G4bool G4VEnergyLossProcess::StorePhysicsTable(
1121        const G4ParticleDefinition* part, cons << 1459        const G4ParticleDefinition* part, const G4String& directory, 
                                                   >> 1460        G4bool ascii)
1122 {                                                1461 {
1123   if (!isMaster || nullptr != baseParticle || << 1462   G4bool res = true;
1124   for(std::size_t i=0; i<7; ++i) {            << 1463   if ( baseParticle || part != particle ) return res;
1125     // ionisation table only for ionisation p << 1464 
1126     if (nullptr == theData->Table(i) || (!isI << 1465   if(!StoreTable(part,theDEDXTable,ascii,directory,"DEDX")) 
1127       continue;                               << 1466     {res = false;}
1128     }                                         << 1467 
1129     if (-1 < verboseLevel) {                  << 1468   if(!StoreTable(part,theDEDXunRestrictedTable,ascii,directory,"DEDXnr")) 
1130       G4cout << "G4VEnergyLossProcess::StoreP << 1469     {res = false;}
1131        << "  " << particle->GetParticleName() << 1470 
1132        << "  " << GetProcessName()            << 1471   if(!StoreTable(part,theDEDXSubTable,ascii,directory,"SubDEDX")) 
1133        << "  " << tnames[i] << "  " << theDat << 1472     {res = false;}
1134     }                                         << 1473 
1135     if (!G4EmTableUtil::StoreTable(this, part << 1474   if(!StoreTable(part,theIonisationTable,ascii,directory,"Ionisation")) 
1136            dir, tnames[i], verboseLevel, asci << 1475     {res = false;}
1137       return false;                           << 1476 
                                                   >> 1477   if(!StoreTable(part,theIonisationSubTable,ascii,directory,"SubIonisation")) 
                                                   >> 1478     {res = false;}
                                                   >> 1479 
                                                   >> 1480   if(isIonisation &&
                                                   >> 1481      !StoreTable(part,theCSDARangeTable,ascii,directory,"CSDARange")) 
                                                   >> 1482     {res = false;}
                                                   >> 1483 
                                                   >> 1484   if(isIonisation &&
                                                   >> 1485      !StoreTable(part,theRangeTableForLoss,ascii,directory,"Range")) 
                                                   >> 1486     {res = false;}
                                                   >> 1487   
                                                   >> 1488   if(isIonisation &&
                                                   >> 1489      !StoreTable(part,theInverseRangeTable,ascii,directory,"InverseRange")) 
                                                   >> 1490     {res = false;}
                                                   >> 1491   
                                                   >> 1492   if(!StoreTable(part,theLambdaTable,ascii,directory,"Lambda")) 
                                                   >> 1493     {res = false;}
                                                   >> 1494 
                                                   >> 1495   if(!StoreTable(part,theSubLambdaTable,ascii,directory,"SubLambda")) 
                                                   >> 1496     {res = false;}
                                                   >> 1497 
                                                   >> 1498   if ( res ) {
                                                   >> 1499     if(0 < verboseLevel) {
                                                   >> 1500       G4cout << "Physics tables are stored for " << particle->GetParticleName()
                                                   >> 1501              << " and process " << GetProcessName()
                                                   >> 1502        << " in the directory <" << directory
                                                   >> 1503        << "> " << G4endl;
1138     }                                            1504     }
                                                   >> 1505   } else {
                                                   >> 1506     G4cout << "Fail to store Physics Tables for " 
                                                   >> 1507      << particle->GetParticleName()
                                                   >> 1508            << " and process " << GetProcessName()
                                                   >> 1509      << " in the directory <" << directory
                                                   >> 1510      << "> " << G4endl;
1139   }                                              1511   }
1140   return true;                                << 1512   return res;
1141 }                                                1513 }
1142                                                  1514 
1143 //....oooOO0OOooo........oooOO0OOooo........o    1515 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1144                                                  1516 
1145 G4bool                                           1517 G4bool 
1146 G4VEnergyLossProcess::RetrievePhysicsTable(co    1518 G4VEnergyLossProcess::RetrievePhysicsTable(const G4ParticleDefinition* part, 
1147                                            co << 1519              const G4String& directory,
                                                   >> 1520              G4bool ascii)
1148 {                                                1521 {
1149   if (!isMaster || nullptr != baseParticle || << 1522   G4bool res = true;
1150   for(std::size_t i=0; i<7; ++i) {            << 1523   const G4String particleName = part->GetParticleName();
1151     // ionisation table only for ionisation p << 1524 
1152     if (!isIonisation && 1 == i) { continue;  << 1525   if(1 < verboseLevel) {
1153     if(!G4EmTableUtil::RetrieveTable(this, pa << 1526     G4cout << "G4VEnergyLossProcess::RetrievePhysicsTable() for "
1154                                      verboseL << 1527            << particleName << " and process " << GetProcessName()
1155       return false;                           << 1528            << "; tables_are_built= " << tablesAreBuilt
                                                   >> 1529            << G4endl;
                                                   >> 1530   }
                                                   >> 1531   if(particle == part) {
                                                   >> 1532 
                                                   >> 1533     if ( !baseParticle ) {
                                                   >> 1534 
                                                   >> 1535       G4bool fpi = true;
                                                   >> 1536       if(!RetrieveTable(part,theDEDXTable,ascii,directory,"DEDX",fpi)) 
                                                   >> 1537   {fpi = false;}
                                                   >> 1538 
                                                   >> 1539       // ionisation table keeps individual dEdx and not sum of sub-processes
                                                   >> 1540       if(!RetrieveTable(part,theDEDXTable,ascii,directory,"Ionisation",false)) 
                                                   >> 1541   {fpi = false;}
                                                   >> 1542 
                                                   >> 1543       if(!RetrieveTable(part,theRangeTableForLoss,ascii,directory,"Range",fpi)) 
                                                   >> 1544         {res = false;}
                                                   >> 1545 
                                                   >> 1546       if(!RetrieveTable(part,theDEDXunRestrictedTable,ascii,directory,"DEDXnr",false)) 
                                                   >> 1547   {res = false;}
                                                   >> 1548 
                                                   >> 1549       if(!RetrieveTable(part,theCSDARangeTable,ascii,directory,"CSDARange",false)) 
                                                   >> 1550   {res = false;}
                                                   >> 1551 
                                                   >> 1552       if(!RetrieveTable(part,theInverseRangeTable,ascii,directory,"InverseRange",fpi)) 
                                                   >> 1553         {res = false;}
                                                   >> 1554 
                                                   >> 1555       if(!RetrieveTable(part,theLambdaTable,ascii,directory,"Lambda",true)) 
                                                   >> 1556         {res = false;}
                                                   >> 1557 
                                                   >> 1558       G4bool yes = false;
                                                   >> 1559       if(nSCoffRegions > 0) {yes = true;}
                                                   >> 1560 
                                                   >> 1561       if(!RetrieveTable(part,theDEDXSubTable,ascii,directory,"SubDEDX",yes)) 
                                                   >> 1562         {res = false;}
                                                   >> 1563 
                                                   >> 1564       if(!RetrieveTable(part,theSubLambdaTable,ascii,directory,"SubLambda",yes)) 
                                                   >> 1565         {res = false;}
                                                   >> 1566 
                                                   >> 1567       if(!fpi) yes = false;
                                                   >> 1568       if(!RetrieveTable(part,theIonisationSubTable,ascii,directory,"SubIonisation",yes))
                                                   >> 1569         {res = false;}
                                                   >> 1570     }
                                                   >> 1571   }
                                                   >> 1572 
                                                   >> 1573   return res;
                                                   >> 1574 }
                                                   >> 1575 
                                                   >> 1576 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
                                                   >> 1577 
                                                   >> 1578 G4bool G4VEnergyLossProcess::StoreTable(const G4ParticleDefinition* part, 
                                                   >> 1579           G4PhysicsTable* aTable, G4bool ascii,
                                                   >> 1580           const G4String& directory,
                                                   >> 1581           const G4String& tname)
                                                   >> 1582 {
                                                   >> 1583   G4bool res = true;
                                                   >> 1584   if ( aTable ) {
                                                   >> 1585     const G4String name = GetPhysicsTableFileName(part,directory,tname,ascii);
                                                   >> 1586     if( !aTable->StorePhysicsTable(name,ascii)) res = false;
                                                   >> 1587   }
                                                   >> 1588   return res;
                                                   >> 1589 }
                                                   >> 1590 
                                                   >> 1591 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
                                                   >> 1592 
                                                   >> 1593 G4bool 
                                                   >> 1594 G4VEnergyLossProcess::RetrieveTable(const G4ParticleDefinition* part, 
                                                   >> 1595             G4PhysicsTable* aTable, 
                                                   >> 1596             G4bool ascii,
                                                   >> 1597             const G4String& directory,
                                                   >> 1598             const G4String& tname,
                                                   >> 1599             G4bool mandatory)
                                                   >> 1600 {
                                                   >> 1601   G4bool isRetrieved = false;
                                                   >> 1602   G4String filename = GetPhysicsTableFileName(part,directory,tname,ascii);
                                                   >> 1603   if(aTable) {
                                                   >> 1604     if(aTable->ExistPhysicsTable(filename)) {
                                                   >> 1605       if(G4PhysicsTableHelper::RetrievePhysicsTable(aTable,filename,ascii)) {
                                                   >> 1606   isRetrieved = true;
                                                   >> 1607   if((G4LossTableManager::Instance())->SplineFlag()) {
                                                   >> 1608     size_t n = aTable->length();
                                                   >> 1609     for(size_t i=0; i<n; ++i) {
                                                   >> 1610       if((*aTable)[i]) { (*aTable)[i]->SetSpline(true); }
                                                   >> 1611     }
                                                   >> 1612   }
                                                   >> 1613   if (0 < verboseLevel) {
                                                   >> 1614     G4cout << tname << " table for " << part->GetParticleName() 
                                                   >> 1615      << " is Retrieved from <" << filename << ">"
                                                   >> 1616      << G4endl;
                                                   >> 1617   }
                                                   >> 1618       }
                                                   >> 1619     }
                                                   >> 1620   }
                                                   >> 1621   if(mandatory && !isRetrieved) {
                                                   >> 1622     if(0 < verboseLevel) {
                                                   >> 1623       G4cout << tname << " table for " << part->GetParticleName() 
                                                   >> 1624        << " from file <"
                                                   >> 1625        << filename << "> is not Retrieved"
                                                   >> 1626        << G4endl;
1156     }                                            1627     }
                                                   >> 1628     return false;
1157   }                                              1629   }
1158   return true;                                   1630   return true;
1159 }                                                1631 }
1160                                                  1632 
1161 //....oooOO0OOooo........oooOO0OOooo........o    1633 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1162                                                  1634 
1163 G4double G4VEnergyLossProcess::GetDEDXDispers    1635 G4double G4VEnergyLossProcess::GetDEDXDispersion(
1164                                   const G4Mat    1636                                   const G4MaterialCutsCouple *couple,
1165                                   const G4Dyn    1637                                   const G4DynamicParticle* dp,
1166                                         G4dou    1638                                         G4double length)
1167 {                                                1639 {
1168   DefineMaterial(couple);                        1640   DefineMaterial(couple);
1169   G4double ekin = dp->GetKineticEnergy();        1641   G4double ekin = dp->GetKineticEnergy();
1170   SelectModel(ekin*massRatio);                   1642   SelectModel(ekin*massRatio);
1171   G4double tmax = currentModel->MaxSecondaryK    1643   G4double tmax = currentModel->MaxSecondaryKinEnergy(dp);
1172   G4double tcut = std::min(tmax,(*theCuts)[cu << 1644   tmax = std::min(tmax,(*theCuts)[currentCoupleIndex]);
1173   G4double d = 0.0;                              1645   G4double d = 0.0;
1174   G4VEmFluctuationModel* fm = currentModel->G    1646   G4VEmFluctuationModel* fm = currentModel->GetModelOfFluctuations();
1175   if(nullptr != fm) { d = fm->Dispersion(curr << 1647   if(fm) { d = fm->Dispersion(currentMaterial,dp,tmax,length); }
1176   return d;                                      1648   return d;
1177 }                                                1649 }
1178                                                  1650 
1179 //....oooOO0OOooo........oooOO0OOooo........o    1651 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1180                                                  1652 
1181 G4double                                      << 1653 G4double G4VEnergyLossProcess::CrossSectionPerVolume(
1182 G4VEnergyLossProcess::CrossSectionPerVolume(G << 1654    G4double kineticEnergy, const G4MaterialCutsCouple* couple)
1183                                             c << 
1184                                             G << 
1185 {                                                1655 {
1186   // Cross section per volume is calculated      1656   // Cross section per volume is calculated
1187   DefineMaterial(couple);                        1657   DefineMaterial(couple);
1188   G4double cross = 0.0;                          1658   G4double cross = 0.0;
1189   if (nullptr != theLambdaTable) {            << 1659   if(theLambdaTable) {
1190     cross = GetLambdaForScaledEnergy(kineticE << 1660     cross = (*theDensityFactor)[currentCoupleIndex]*
1191                                      logKinet << 1661       ((*theLambdaTable)[basedCoupleIndex])->Value(kineticEnergy);
1192   } else {                                       1662   } else {
1193     SelectModel(kineticEnergy*massRatio);     << 1663     SelectModel(kineticEnergy);
1194     cross = (!baseMat) ? biasFactor : biasFac << 1664     cross = currentModel->CrossSectionPerVolume(currentMaterial,
1195     cross *= (currentModel->CrossSectionPerVo << 1665             particle, kineticEnergy,
1196                                               << 1666             (*theCuts)[currentCoupleIndex]);
1197   }                                              1667   }
1198   return std::max(cross, 0.0);                << 1668   if(cross < 0.0) { cross = 0.0; }
                                                   >> 1669   return cross;
1199 }                                                1670 }
1200                                                  1671 
1201 //....oooOO0OOooo........oooOO0OOooo........o    1672 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1202                                                  1673 
1203 G4double G4VEnergyLossProcess::MeanFreePath(c    1674 G4double G4VEnergyLossProcess::MeanFreePath(const G4Track& track)
1204 {                                                1675 {
1205   DefineMaterial(track.GetMaterialCutsCouple(    1676   DefineMaterial(track.GetMaterialCutsCouple());
1206   const G4double kinEnergy    = track.GetKine << 1677   preStepLambda = GetLambdaForScaledEnergy(track.GetKineticEnergy()*massRatio);
1207   const G4double logKinEnergy = track.GetDyna << 1678   G4double x = DBL_MAX;
1208   const G4double cs = GetLambdaForScaledEnerg << 1679   if(0.0 < preStepLambda) { x = 1.0/preStepLambda; }
1209                                               << 1680   return x;
1210   return (0.0 < cs) ? 1.0/cs : DBL_MAX;       << 
1211 }                                                1681 }
1212                                                  1682 
1213 //....oooOO0OOooo........oooOO0OOooo........o    1683 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1214                                                  1684 
1215 G4double G4VEnergyLossProcess::ContinuousStep    1685 G4double G4VEnergyLossProcess::ContinuousStepLimit(const G4Track& track, 
1216                                               << 1686                G4double x, G4double y, 
1217                                               << 1687                G4double& z)
1218 {                                                1688 {
1219   return AlongStepGetPhysicalInteractionLengt << 1689   G4GPILSelection sel;
                                                   >> 1690   return AlongStepGetPhysicalInteractionLength(track, x, y, z, &sel);
1220 }                                                1691 }
1221                                                  1692 
1222 //....oooOO0OOooo........oooOO0OOooo........o    1693 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1223                                                  1694 
1224 G4double G4VEnergyLossProcess::GetMeanFreePat    1695 G4double G4VEnergyLossProcess::GetMeanFreePath(
1225                              const G4Track& t    1696                              const G4Track& track,
1226                              G4double,           1697                              G4double,
1227                              G4ForceCondition    1698                              G4ForceCondition* condition)
1228                                                  1699 
1229 {                                                1700 {
1230   *condition = NotForced;                        1701   *condition = NotForced;
1231   return MeanFreePath(track);                    1702   return MeanFreePath(track);
1232 }                                                1703 }
1233                                                  1704 
1234 //....oooOO0OOooo........oooOO0OOooo........o    1705 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1235                                                  1706 
1236 G4double G4VEnergyLossProcess::GetContinuousS    1707 G4double G4VEnergyLossProcess::GetContinuousStepLimit(
1237                 const G4Track&,               << 1708     const G4Track&,
1238                 G4double, G4double, G4double&    1709                 G4double, G4double, G4double&)
1239 {                                                1710 {
1240   return DBL_MAX;                                1711   return DBL_MAX;
1241 }                                                1712 }
1242                                                  1713 
1243 //....oooOO0OOooo........oooOO0OOooo........o    1714 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1244                                                  1715 
1245 G4PhysicsVector*                                 1716 G4PhysicsVector* 
1246 G4VEnergyLossProcess::LambdaPhysicsVector(con << 1717 G4VEnergyLossProcess::LambdaPhysicsVector(const G4MaterialCutsCouple* /*couple*/, 
1247                                           G4d << 1718             G4double /*cut*/)
1248 {                                                1719 {
1249   DefineMaterial(couple);                     << 1720   G4PhysicsVector* v = new G4PhysicsLogVector(minKinEnergy, maxKinEnergy, nBins);
1250   G4PhysicsVector* v = (*theLambdaTable)[base << 1721   v->SetSpline((G4LossTableManager::Instance())->SplineFlag());
1251   return new G4PhysicsVector(*v);             << 1722   return v;
1252 }                                                1723 }
1253                                                  1724 
1254 //....oooOO0OOooo........oooOO0OOooo........o    1725 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1255                                               << 1726   
1256 void                                          << 1727 void G4VEnergyLossProcess::AddCollaborativeProcess(
1257 G4VEnergyLossProcess::SetDEDXTable(G4PhysicsT << 1728             G4VEnergyLossProcess* p)
1258 {                                                1729 {
1259   if(1 < verboseLevel) {                      << 1730   G4bool add = true;
1260     G4cout << "### Set DEDX table " << p << " << 1731   if(p->GetProcessName() != "eBrem") { add = false; }
1261      << "  " <<  theDEDXunRestrictedTable <<  << 1732   if(add && nProcesses > 0) {
1262            << " for " << particle->GetParticl << 1733     for(G4int i=0; i<nProcesses; ++i) {
1263            << " and process " << GetProcessNa << 1734       if(p == scProcesses[i]) {
1264      << " type=" << tType << " isIonisation:" << 1735         add = false;
                                                   >> 1736         break;
                                                   >> 1737       }
                                                   >> 1738     }
1265   }                                              1739   }
1266   if(fTotal == tType) {                       << 1740   if(add) {
                                                   >> 1741     scProcesses.push_back(p);
                                                   >> 1742     ++nProcesses;
                                                   >> 1743     if (1 < verboseLevel) { 
                                                   >> 1744       G4cout << "### The process " << p->GetProcessName() 
                                                   >> 1745        << " is added to the list of collaborative processes of "
                                                   >> 1746        << GetProcessName() << G4endl; 
                                                   >> 1747     }
                                                   >> 1748   }
                                                   >> 1749 }
                                                   >> 1750 
                                                   >> 1751 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
                                                   >> 1752 
                                                   >> 1753 void G4VEnergyLossProcess::SetDEDXTable(G4PhysicsTable* p, G4EmTableType tType)
                                                   >> 1754 {
                                                   >> 1755   if(fTotal == tType && theDEDXunRestrictedTable != p && !baseParticle) {
                                                   >> 1756     if(theDEDXunRestrictedTable) {
                                                   >> 1757       theDEDXunRestrictedTable->clearAndDestroy();
                                                   >> 1758       delete theDEDXunRestrictedTable;
                                                   >> 1759     } 
1267     theDEDXunRestrictedTable = p;                1760     theDEDXunRestrictedTable = p;
1268   } else if(fRestricted == tType) {           << 1761     if(p) {
                                                   >> 1762       size_t n = p->length();
                                                   >> 1763       G4PhysicsVector* pv = (*p)[0];
                                                   >> 1764       G4double emax = maxKinEnergyCSDA;
                                                   >> 1765 
                                                   >> 1766       for (size_t i=0; i<n; ++i) {
                                                   >> 1767   G4double dedx = 0.0; 
                                                   >> 1768   pv = (*p)[i];
                                                   >> 1769   if(pv) { dedx = pv->Value(emax); }
                                                   >> 1770   else {
                                                   >> 1771     pv = (*p)[(*theDensityIdx)[i]];
                                                   >> 1772     if(pv) { dedx = pv->Value(emax)*(*theDensityFactor)[i]; }
                                                   >> 1773   }
                                                   >> 1774   theDEDXAtMaxEnergy[i] = dedx;
                                                   >> 1775   //G4cout << "i= " << i << " emax(MeV)= " << emax/MeV<< " dedx= " 
                                                   >> 1776   //<< dedx << G4endl;
                                                   >> 1777       }
                                                   >> 1778     }
                                                   >> 1779 
                                                   >> 1780   } else if(fRestricted == tType && theDEDXTable != p) {
                                                   >> 1781     //G4cout << "G4VEnergyLossProcess::SetDEDXTable " << particle->GetParticleName()
                                                   >> 1782     //     << " old table " << theDEDXTable << " new table " << p 
                                                   >> 1783     //     << " ion " << theIonisationTable << " bp " << baseParticle << G4endl;
                                                   >> 1784     if(theDEDXTable && !baseParticle) {
                                                   >> 1785       if(theDEDXTable == theIonisationTable) { theIonisationTable = 0; }
                                                   >> 1786       theDEDXTable->clearAndDestroy();
                                                   >> 1787       delete theDEDXTable;
                                                   >> 1788     }
1269     theDEDXTable = p;                            1789     theDEDXTable = p;
1270     if(isMaster && nullptr == baseParticle) { << 1790   } else if(fSubRestricted == tType && theDEDXSubTable != p) {    
1271       theData->UpdateTable(theDEDXTable, 0);  << 1791     if(theDEDXSubTable && !baseParticle) {
                                                   >> 1792       if(theDEDXSubTable == theIonisationSubTable) { theIonisationSubTable = 0; }
                                                   >> 1793       theDEDXSubTable->clearAndDestroy();
                                                   >> 1794       delete theDEDXSubTable;
                                                   >> 1795     }
                                                   >> 1796     theDEDXSubTable = p;
                                                   >> 1797   } else if(fIsIonisation == tType && theIonisationTable != p) {    
                                                   >> 1798     if(theIonisationTable && theIonisationTable != theDEDXTable && !baseParticle) {
                                                   >> 1799       theIonisationTable->clearAndDestroy();
                                                   >> 1800       delete theIonisationTable;
1272     }                                            1801     }
1273   } else if(fIsIonisation == tType) {         << 
1274     theIonisationTable = p;                      1802     theIonisationTable = p;
1275     if(isMaster && nullptr == baseParticle) { << 1803   } else if(fIsSubIonisation == tType && theIonisationSubTable != p) {    
1276       theData->UpdateTable(theIonisationTable << 1804     if(theIonisationSubTable && theIonisationSubTable != theDEDXSubTable && !baseParticle) {
                                                   >> 1805       theIonisationSubTable->clearAndDestroy();
                                                   >> 1806       delete theIonisationSubTable;
1277     }                                            1807     }
                                                   >> 1808     theIonisationSubTable = p;
1278   }                                              1809   }
1279 }                                                1810 }
1280                                                  1811 
1281 //....oooOO0OOooo........oooOO0OOooo........o    1812 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1282                                                  1813 
1283 void G4VEnergyLossProcess::SetCSDARangeTable(    1814 void G4VEnergyLossProcess::SetCSDARangeTable(G4PhysicsTable* p)
1284 {                                                1815 {
1285   theCSDARangeTable = p;                      << 1816   if(theCSDARangeTable != p) { theCSDARangeTable = p; }
                                                   >> 1817 
                                                   >> 1818   if(p) {
                                                   >> 1819     size_t n = p->length();
                                                   >> 1820     G4PhysicsVector* pv;
                                                   >> 1821     G4double emax = maxKinEnergyCSDA;
                                                   >> 1822 
                                                   >> 1823     for (size_t i=0; i<n; ++i) {
                                                   >> 1824       pv = (*p)[i];
                                                   >> 1825       G4double rmax = 0.0;
                                                   >> 1826       if(pv) { rmax = pv->Value(emax); }
                                                   >> 1827       else {
                                                   >> 1828   pv = (*p)[(*theDensityIdx)[i]];
                                                   >> 1829         if(pv) { rmax = pv->Value(emax)/(*theDensityFactor)[i]; }
                                                   >> 1830       }
                                                   >> 1831       theRangeAtMaxEnergy[i] = rmax;
                                                   >> 1832       //G4cout << "i= " << i << " Emax(MeV)= " << emax/MeV << " Rmax= " 
                                                   >> 1833       //<< rmax<< G4endl;
                                                   >> 1834     }
                                                   >> 1835   }
1286 }                                                1836 }
1287                                                  1837 
1288 //....oooOO0OOooo........oooOO0OOooo........o    1838 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1289                                                  1839 
1290 void G4VEnergyLossProcess::SetRangeTableForLo    1840 void G4VEnergyLossProcess::SetRangeTableForLoss(G4PhysicsTable* p)
1291 {                                                1841 {
1292   theRangeTableForLoss = p;                   << 1842   if(theRangeTableForLoss != p) {
                                                   >> 1843     theRangeTableForLoss = p;
                                                   >> 1844     if(1 < verboseLevel) {
                                                   >> 1845       G4cout << "### Set Range table " << p 
                                                   >> 1846        << " for " << particle->GetParticleName()
                                                   >> 1847              << " and process " << GetProcessName() << G4endl;
                                                   >> 1848     }
                                                   >> 1849   }
                                                   >> 1850 }
                                                   >> 1851 
                                                   >> 1852 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
                                                   >> 1853 
                                                   >> 1854 void G4VEnergyLossProcess::SetSecondaryRangeTable(G4PhysicsTable* p)
                                                   >> 1855 {
                                                   >> 1856   if(theSecondaryRangeTable != p) {
                                                   >> 1857     theSecondaryRangeTable = p;
                                                   >> 1858     if(1 < verboseLevel) {
                                                   >> 1859       G4cout << "### Set SecondaryRange table " << p 
                                                   >> 1860        << " for " << particle->GetParticleName()
                                                   >> 1861              << " and process " << GetProcessName() << G4endl;
                                                   >> 1862     }
                                                   >> 1863   }
1293 }                                                1864 }
1294                                                  1865 
1295 //....oooOO0OOooo........oooOO0OOooo........o    1866 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1296                                                  1867 
1297 void G4VEnergyLossProcess::SetInverseRangeTab    1868 void G4VEnergyLossProcess::SetInverseRangeTable(G4PhysicsTable* p)
1298 {                                                1869 {
1299   theInverseRangeTable = p;                   << 1870   if(theInverseRangeTable != p) {
                                                   >> 1871     theInverseRangeTable = p;
                                                   >> 1872     if(1 < verboseLevel) {
                                                   >> 1873       G4cout << "### Set InverseRange table " << p 
                                                   >> 1874        << " for " << particle->GetParticleName()
                                                   >> 1875              << " and process " << GetProcessName() << G4endl;
                                                   >> 1876     }
                                                   >> 1877   }
1300 }                                                1878 }
1301                                                  1879 
1302 //....oooOO0OOooo........oooOO0OOooo........o    1880 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1303                                                  1881 
1304 void G4VEnergyLossProcess::SetLambdaTable(G4P    1882 void G4VEnergyLossProcess::SetLambdaTable(G4PhysicsTable* p)
1305 {                                                1883 {
1306   if(1 < verboseLevel) {                         1884   if(1 < verboseLevel) {
1307     G4cout << "### Set Lambda table " << p << << 1885     G4cout << "### Set Lambda table " << p 
1308            << " for " << particle->GetParticl << 1886      << " for " << particle->GetParticleName()
1309            << " and process " << GetProcessNa    1887            << " and process " << GetProcessName() << G4endl;
1310   }                                              1888   }
1311   theLambdaTable = p;                         << 1889   if(theLambdaTable != p) { theLambdaTable = p; }
1312   tablesAreBuilt = true;                         1890   tablesAreBuilt = true;
1313                                                  1891 
1314   if(isMaster && nullptr != p) {              << 1892   if(theLambdaTable) {
1315     delete theEnergyOfCrossSectionMax;        << 1893     size_t n = theLambdaTable->length();
1316     theEnergyOfCrossSectionMax = nullptr;     << 1894     G4PhysicsVector* pv = (*theLambdaTable)[0];
1317     if(fEmTwoPeaks == fXSType) {              << 1895     G4double e, s, smax, emax;
1318       if(nullptr != fXSpeaks) {               << 1896 
1319   for(auto & ptr : *fXSpeaks) { delete ptr; } << 1897     size_t i;
1320   delete fXSpeaks;                            << 1898 
                                                   >> 1899     // first loop on existing vectors
                                                   >> 1900     for (i=0; i<n; ++i) {
                                                   >> 1901       pv = (*theLambdaTable)[i];
                                                   >> 1902       if(pv) {
                                                   >> 1903   size_t nb = pv->GetVectorLength();
                                                   >> 1904   emax = DBL_MAX;
                                                   >> 1905   smax = 0.0;
                                                   >> 1906   if(nb > 0) {
                                                   >> 1907     for (size_t j=0; j<nb; ++j) {
                                                   >> 1908       e = pv->Energy(j);
                                                   >> 1909       s = (*pv)(j);
                                                   >> 1910       if(s > smax) {
                                                   >> 1911         smax = s;
                                                   >> 1912         emax = e;
                                                   >> 1913       }
                                                   >> 1914     }
                                                   >> 1915   }
                                                   >> 1916   theEnergyOfCrossSectionMax[i] = emax;
                                                   >> 1917   theCrossSectionMax[i] = smax;
                                                   >> 1918   if(1 < verboseLevel) {
                                                   >> 1919     G4cout << "For " << particle->GetParticleName() 
                                                   >> 1920      << " Max CS at i= " << i << " emax(MeV)= " << emax/MeV
                                                   >> 1921      << " lambda= " << smax << G4endl;
                                                   >> 1922   }
1321       }                                          1923       }
1322       G4LossTableBuilder* bld = lManager->Get << 
1323       fXSpeaks = G4EmUtility::FillPeaksStruct << 
1324       if(nullptr == fXSpeaks) { fXSType = fEm << 
1325     }                                            1924     }
1326     if(fXSType == fEmOnePeak) {               << 1925     // second loop using base materials
1327       theEnergyOfCrossSectionMax = G4EmUtilit << 1926     for (size_t i=0; i<n; ++i) {
1328       if(nullptr == theEnergyOfCrossSectionMa << 1927       pv = (*theLambdaTable)[i];
                                                   >> 1928       if(!pv){
                                                   >> 1929   G4int j = (*theDensityIdx)[i];
                                                   >> 1930   theEnergyOfCrossSectionMax[i] = theEnergyOfCrossSectionMax[j];
                                                   >> 1931   theCrossSectionMax[i] = (*theDensityFactor)[i]*theCrossSectionMax[j];
                                                   >> 1932       }
1329     }                                            1933     }
1330   }                                              1934   }
1331 }                                                1935 }
1332                                                  1936 
1333 //....oooOO0OOooo........oooOO0OOooo........o    1937 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1334                                                  1938 
1335 void G4VEnergyLossProcess::SetEnergyOfCrossSe << 1939 void G4VEnergyLossProcess::SetSubLambdaTable(G4PhysicsTable* p)
1336 {                                             << 
1337   theEnergyOfCrossSectionMax = p;             << 
1338 }                                             << 
1339                                               << 
1340 //....oooOO0OOooo........oooOO0OOooo........o << 
1341                                               << 
1342 void G4VEnergyLossProcess::SetTwoPeaksXS(std: << 
1343 {                                                1940 {
1344   fXSpeaks = ptr;                             << 1941   if(theSubLambdaTable != p) {
                                                   >> 1942     theSubLambdaTable = p;
                                                   >> 1943     if(1 < verboseLevel) {
                                                   >> 1944       G4cout << "### Set SebLambda table " << p 
                                                   >> 1945        << " for " << particle->GetParticleName()
                                                   >> 1946              << " and process " << GetProcessName() << G4endl;
                                                   >> 1947     }
                                                   >> 1948   }
1345 }                                                1949 }
1346                                                  1950 
1347 //....oooOO0OOooo........oooOO0OOooo........o    1951 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1348                                                  1952 
1349 const G4Element* G4VEnergyLossProcess::GetCur    1953 const G4Element* G4VEnergyLossProcess::GetCurrentElement() const
1350 {                                                1954 {
1351   return (nullptr != currentModel)            << 1955   const G4Element* elm = 0;
1352     ? currentModel->GetCurrentElement(current << 1956   if(currentModel) { elm = currentModel->GetCurrentElement(); }
                                                   >> 1957   return elm;
1353 }                                                1958 }
1354                                                  1959 
1355 //....oooOO0OOooo........oooOO0OOooo........o    1960 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1356                                                  1961 
1357 void G4VEnergyLossProcess::SetCrossSectionBia    1962 void G4VEnergyLossProcess::SetCrossSectionBiasingFactor(G4double f, 
1358                                               << 1963               G4bool flag)
1359 {                                                1964 {
1360   if(f > 0.0) {                                  1965   if(f > 0.0) { 
1361     biasFactor = f;                              1966     biasFactor = f; 
1362     weightFlag = flag;                           1967     weightFlag = flag;
1363     if(1 < verboseLevel) {                       1968     if(1 < verboseLevel) {
1364       G4cout << "### SetCrossSectionBiasingFa    1969       G4cout << "### SetCrossSectionBiasingFactor: for " 
1365              << " process " << GetProcessName << 1970        << " process " << GetProcessName()
1366              << " biasFactor= " << f << " wei << 1971        << " biasFactor= " << f << " weightFlag= " << flag 
1367              << G4endl;                       << 1972        << G4endl; 
1368     }                                            1973     }
1369   }                                              1974   }
1370 }                                                1975 }
1371                                                  1976 
1372 //....oooOO0OOooo........oooOO0OOooo........o    1977 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1373                                                  1978 
1374 void G4VEnergyLossProcess::ActivateForcedInte << 1979 void 
1375                                               << 1980 G4VEnergyLossProcess::ActivateForcedInteraction(G4double length, 
1376                                               << 1981             const G4String& region,
                                                   >> 1982             G4bool flag)
1377 {                                                1983 {
1378   if(nullptr == biasManager) { biasManager =  << 1984   if(!biasManager) { biasManager = new G4EmBiasingManager(); }
1379   if(1 < verboseLevel) {                         1985   if(1 < verboseLevel) {
1380     G4cout << "### ActivateForcedInteraction:    1986     G4cout << "### ActivateForcedInteraction: for " 
1381            << " process " << GetProcessName() << 1987      << " process " << GetProcessName()
1382            << " length(mm)= " << length/mm    << 1988      << " length(mm)= " << length/mm
1383            << " in G4Region <" << region      << 1989      << " in G4Region <" << region
1384            << "> weightFlag= " << flag        << 1990      << "> weightFlag= " << flag 
1385            << G4endl;                         << 1991      << G4endl; 
1386   }                                              1992   }
1387   weightFlag = flag;                             1993   weightFlag = flag;
1388   biasManager->ActivateForcedInteraction(leng    1994   biasManager->ActivateForcedInteraction(length, region);
1389 }                                                1995 }
1390                                                  1996 
1391 //....oooOO0OOooo........oooOO0OOooo........o    1997 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1392                                                  1998 
1393 void                                             1999 void 
1394 G4VEnergyLossProcess::ActivateSecondaryBiasin    2000 G4VEnergyLossProcess::ActivateSecondaryBiasing(const G4String& region, 
1395                                               << 2001                  G4double factor, 
1396                                               << 2002                  G4double energyLimit)
1397 {                                                2003 {
1398   if (0.0 <= factor) {                        << 2004   if (0.0 < factor) { 
1399     // Range cut can be applied only for e-   << 2005     if(!biasManager) { biasManager = new G4EmBiasingManager(); }
1400     if(0.0 == factor && secondaryParticle !=  << 
1401       { return; }                             << 
1402                                               << 
1403     if(nullptr == biasManager) { biasManager  << 
1404     biasManager->ActivateSecondaryBiasing(reg    2006     biasManager->ActivateSecondaryBiasing(region, factor, energyLimit);
1405     if(1 < verboseLevel) {                       2007     if(1 < verboseLevel) {
1406       G4cout << "### ActivateSecondaryBiasing    2008       G4cout << "### ActivateSecondaryBiasing: for " 
1407              << " process " << GetProcessName << 2009        << " process " << GetProcessName()
1408              << " factor= " << factor         << 2010        << " factor= " << factor
1409              << " in G4Region <" << region    << 2011        << " in G4Region <" << region 
1410              << "> energyLimit(MeV)= " << ene << 2012        << "> energyLimit(MeV)= " << energyLimit/MeV
1411              << G4endl;                       << 2013        << G4endl; 
1412     }                                            2014     }
1413   }                                              2015   }
1414 }                                                2016 }
1415                                                  2017 
1416 //....oooOO0OOooo........oooOO0OOooo........o    2018 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1417                                                  2019 
1418 void G4VEnergyLossProcess::SetIonisation(G4bo << 
1419 {                                             << 
1420   isIonisation = val;                         << 
1421   aGPILSelection = (val) ? CandidateForSelect << 
1422 }                                             << 
1423                                               << 
1424 //....oooOO0OOooo........oooOO0OOooo........o << 
1425                                               << 
1426  void G4VEnergyLossProcess::SetLinearLossLimi << 
1427 {                                             << 
1428   if(0.0 < val && val < 1.0) {                << 
1429     linLossLimit = val;                       << 
1430     actLinLossLimit = true;                   << 
1431   } else { PrintWarning("SetLinearLossLimit", << 
1432 }                                             << 
1433                                               << 
1434 //....oooOO0OOooo........oooOO0OOooo........o << 
1435                                               << 
1436 void G4VEnergyLossProcess::SetStepFunction(G4 << 
1437 {                                             << 
1438   if(0.0 < v1 && 0.0 < v2) {                  << 
1439     dRoverRange = std::min(1.0, v1);          << 
1440     finalRange = std::min(v2, 1.e+50);        << 
1441   } else {                                    << 
1442     PrintWarning("SetStepFunctionV1", v1);    << 
1443     PrintWarning("SetStepFunctionV2", v2);    << 
1444   }                                           << 
1445 }                                             << 
1446                                               << 
1447 //....oooOO0OOooo........oooOO0OOooo........o << 
1448                                               << 
1449 void G4VEnergyLossProcess::SetLowestEnergyLim << 
1450 {                                             << 
1451   if(1.e-18 < val && val < 1.e+50) { lowestKi << 
1452   else { PrintWarning("SetLowestEnergyLimit", << 
1453 }                                             << 
1454                                               << 
1455 //....oooOO0OOooo........oooOO0OOooo........o << 
1456                                               << 
1457 void G4VEnergyLossProcess::SetDEDXBinning(G4i << 
1458 {                                             << 
1459   if(2 < n && n < 1000000000) {               << 
1460     nBins = n;                                << 
1461     actBinning = true;                        << 
1462   } else {                                    << 
1463     G4double e = (G4double)n;                 << 
1464     PrintWarning("SetDEDXBinning", e);        << 
1465   }                                           << 
1466 }                                             << 
1467                                               << 
1468 //....oooOO0OOooo........oooOO0OOooo........o << 
1469                                               << 
1470 void G4VEnergyLossProcess::SetMinKinEnergy(G4 << 
1471 {                                             << 
1472   if(1.e-18 < e && e < maxKinEnergy) {        << 
1473     minKinEnergy = e;                         << 
1474     actMinKinEnergy = true;                   << 
1475   } else { PrintWarning("SetMinKinEnergy", e) << 
1476 }                                             << 
1477                                               << 
1478 //....oooOO0OOooo........oooOO0OOooo........o << 
1479                                               << 
1480 void G4VEnergyLossProcess::SetMaxKinEnergy(G4 << 
1481 {                                             << 
1482   if(minKinEnergy < e && e < 1.e+50) {        << 
1483     maxKinEnergy = e;                         << 
1484     actMaxKinEnergy = true;                   << 
1485     if(e < maxKinEnergyCSDA) { maxKinEnergyCS << 
1486   } else { PrintWarning("SetMaxKinEnergy", e) << 
1487 }                                             << 
1488                                               << 
1489 //....oooOO0OOooo........oooOO0OOooo........o << 
1490                                               << 
1491 void G4VEnergyLossProcess::PrintWarning(const << 
1492 {                                             << 
1493   G4String ss = "G4VEnergyLossProcess::" + ti << 
1494   G4ExceptionDescription ed;                  << 
1495   ed << "Parameter is out of range: " << val  << 
1496      << " it will have no effect!\n" << "  Pr << 
1497      << GetProcessName() << "  nbins= " << nB << 
1498      << " Emin(keV)= " << minKinEnergy/keV    << 
1499      << " Emax(GeV)= " << maxKinEnergy/GeV;   << 
1500   G4Exception(ss, "em0044", JustWarning, ed); << 
1501 }                                             << 
1502                                               << 
1503 //....oooOO0OOooo........oooOO0OOooo........o << 
1504                                               << 
1505 void G4VEnergyLossProcess::ProcessDescription << 
1506 {                                             << 
1507   if(nullptr != particle) { StreamInfo(out, * << 
1508 }                                             << 
1509                                               << 
1510 //....oooOO0OOooo........oooOO0OOooo........o << 
1511                                                  2020