Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/lowenergy/src/G4MicroElecInelasticModel.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/lowenergy/src/G4MicroElecInelasticModel.cc (Version 11.3.0) and /processes/electromagnetic/lowenergy/src/G4MicroElecInelasticModel.cc (Version 10.0.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 //                                                 26 //
 27 // G4MicroElecInelasticModel.cc, 2011/08/29 A.     27 // G4MicroElecInelasticModel.cc, 2011/08/29 A.Valentin, M. Raine
 28 //                                                 28 //
 29 // Based on the following publications             29 // Based on the following publications
 30 //                                                 30 //
 31 //          - Inelastic cross-sections of low      31 //          - Inelastic cross-sections of low energy electrons in silicon
 32 //      for the simulation of heavy ion tracks     32 //      for the simulation of heavy ion tracks with theGeant4-DNA toolkit,
 33 //      NSS Conf. Record 2010, pp. 80-85.          33 //      NSS Conf. Record 2010, pp. 80-85.
 34 //      - Geant4 physics processes for microdo     34 //      - Geant4 physics processes for microdosimetry simulation:
 35 //      very low energy electromagnetic models     35 //      very low energy electromagnetic models for electrons in Si,
 36 //      NIM B, vol. 288, pp. 66 - 73, 2012.        36 //      NIM B, vol. 288, pp. 66 - 73, 2012.
 37 //      - Geant4 physics processes for microdo     37 //      - Geant4 physics processes for microdosimetry simulation:
 38 //      very low energy electromagnetic models     38 //      very low energy electromagnetic models for protons and
 39 //      heavy ions in Si, NIM B, vol. 287, pp.     39 //      heavy ions in Si, NIM B, vol. 287, pp. 124 - 129, 2012.
 40 //                                                 40 //
 41 //....oooOO0OOooo........oooOO0OOooo........oo <<  41 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 
 42                                                    42 
 43 #include "G4MicroElecInelasticModel.hh"            43 #include "G4MicroElecInelasticModel.hh"
 44                                                    44 
 45 #include "globals.hh"                              45 #include "globals.hh"
 46 #include "G4PhysicalConstants.hh"                  46 #include "G4PhysicalConstants.hh"
 47 #include "G4SystemOfUnits.hh"                      47 #include "G4SystemOfUnits.hh"
 48 #include "G4ios.hh"                                48 #include "G4ios.hh"
 49 #include "G4UnitsTable.hh"                         49 #include "G4UnitsTable.hh"
 50 #include "G4UAtomicDeexcitation.hh"                50 #include "G4UAtomicDeexcitation.hh"
 51 #include "G4MicroElecSiStructure.hh"           << 
 52 #include "G4LossTableManager.hh"                   51 #include "G4LossTableManager.hh"
 53 #include "G4ionEffectiveCharge.hh"                 52 #include "G4ionEffectiveCharge.hh"
 54 #include "G4MicroElecCrossSectionDataSet.hh"   << 
 55 #include "G4Electron.hh"                       << 
 56 #include "G4Proton.hh"                         << 
 57 #include "G4GenericIon.hh"                     << 
 58 #include "G4ParticleDefinition.hh"             << 
 59 #include "G4NistManager.hh"                    << 
 60 #include "G4LogLogInterpolation.hh"            << 
 61 #include "G4DeltaAngle.hh"                     << 
 62                                                    53 
 63 //....oooOO0OOooo........oooOO0OOooo........oo     54 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 64                                                    55 
 65 using namespace std;                               56 using namespace std;
 66                                                    57 
 67 //....oooOO0OOooo........oooOO0OOooo........oo     58 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 68                                                    59 
 69 G4MicroElecInelasticModel::G4MicroElecInelasti     60 G4MicroElecInelasticModel::G4MicroElecInelasticModel(const G4ParticleDefinition*,
 70                                                <<  61                                              const G4String& nam)
 71 :G4VEmModel(nam),isInitialised(false)          <<  62 :G4VEmModel(nam),fAtomDeexcitation(0),isInitialised(false)
 72 {                                                  63 {
 73   nistSi = G4NistManager::Instance()->FindOrBu     64   nistSi = G4NistManager::Instance()->FindOrBuildMaterial("G4_Si");
 74                                                    65   
 75   verboseLevel= 0;                                 66   verboseLevel= 0;
 76   // Verbosity scale:                              67   // Verbosity scale:
 77   // 0 = nothing                               <<  68   // 0 = nothing 
 78   // 1 = warning for energy non-conservation   <<  69   // 1 = warning for energy non-conservation 
 79   // 2 = details of energy budget                  70   // 2 = details of energy budget
 80   // 3 = calculation of cross sections, file o     71   // 3 = calculation of cross sections, file openings, sampling of atoms
 81   // 4 = entering in methods                       72   // 4 = entering in methods
 82                                                    73   
 83   if( verboseLevel>0 )                         <<  74   if( verboseLevel>0 ) 
 84   {                                            <<  75   { 
 85     G4cout << "MicroElec inelastic model is co     76     G4cout << "MicroElec inelastic model is constructed " << G4endl;
 86   }                                                77   }
 87                                                <<  78 
 88   //Mark this model as "applicable" for atomic     79   //Mark this model as "applicable" for atomic deexcitation
 89   SetDeexcitationFlag(true);                       80   SetDeexcitationFlag(true);
 90   fAtomDeexcitation = nullptr;                 <<  81   fParticleChangeForGamma = 0;
 91   fParticleChangeForGamma = nullptr;           << 
 92                                                << 
 93   // default generator                         << 
 94   SetAngularDistribution(new G4DeltaAngle());  << 
 95                                                << 
 96   // Selection of computation method           << 
 97   fasterCode = true; //false;                  << 
 98 }                                                  82 }
 99                                                    83 
100 //....oooOO0OOooo........oooOO0OOooo........oo     84 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
101                                                    85 
102 G4MicroElecInelasticModel::~G4MicroElecInelast     86 G4MicroElecInelasticModel::~G4MicroElecInelasticModel()
103 {                                              <<  87 {  
104   // Cross section                                 88   // Cross section
105   for (auto & pos : tableData)                 <<  89   
                                                   >>  90   std::map< G4String,G4MicroElecCrossSectionDataSet*,std::less<G4String> >::iterator pos;
                                                   >>  91   for (pos = tableData.begin(); pos != tableData.end(); ++pos)
106   {                                                92   {
107     G4MicroElecCrossSectionDataSet* table = po <<  93     G4MicroElecCrossSectionDataSet* table = pos->second;
108     delete table;                                  94     delete table;
109   }                                                95   }
110                                                    96   
111   // Final state                                   97   // Final state
                                                   >>  98   
112   eVecm.clear();                                   99   eVecm.clear();
113   pVecm.clear();                                  100   pVecm.clear();
114                                                << 101 
115 }                                                 102 }
116                                                   103 
117 //....oooOO0OOooo........oooOO0OOooo........oo    104 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
118                                                   105 
119 void G4MicroElecInelasticModel::Initialise(con    106 void G4MicroElecInelasticModel::Initialise(const G4ParticleDefinition* particle,
120                                            con << 107                                        const G4DataVector& /*cuts*/)
121 {                                                 108 {
122                                                << 109 
123   if (verboseLevel > 3)                           110   if (verboseLevel > 3)
124     G4cout << "Calling G4MicroElecInelasticMod    111     G4cout << "Calling G4MicroElecInelasticModel::Initialise()" << G4endl;
125                                                << 112 
126   // Energy limits                                113   // Energy limits
127                                                << 114 
128   G4String fileElectron("microelec/sigma_inela    115   G4String fileElectron("microelec/sigma_inelastic_e_Si");
129   G4String fileProton("microelec/sigma_inelast    116   G4String fileProton("microelec/sigma_inelastic_p_Si");
130                                                << 117 
131   G4ParticleDefinition* electronDef = G4Electr    118   G4ParticleDefinition* electronDef = G4Electron::ElectronDefinition();
132   G4ParticleDefinition* protonDef = G4Proton::    119   G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
133   G4String electron = electronDef->GetParticle << 120 
134   G4String proton = protonDef->GetParticleName << 121   G4String electron;
                                                   >> 122   G4String proton;
135                                                   123   
136   G4double scaleFactor = 1e-18 * cm *cm;          124   G4double scaleFactor = 1e-18 * cm *cm;
137                                                   125 
138   const char* path = G4FindDataDir("G4LEDATA") << 126   char *path = getenv("G4LEDATA");
139                                                   127 
140   // *** ELECTRON                                 128   // *** ELECTRON
141   tableFile[electron] = fileElectron;          << 129     electron = electronDef->GetParticleName();
142   lowEnergyLimit[electron] = 16.7 * eV;        << 
143   highEnergyLimit[electron] = 100.0 * MeV;     << 
144                                                << 
145   // Cross section                             << 
146   G4MicroElecCrossSectionDataSet* tableE = new << 
147   tableE->LoadData(fileElectron);              << 
148                                                << 
149   tableData[electron] = tableE;                << 
150                                                << 
151   // Final state                               << 
152                                                << 
153   std::ostringstream eFullFileName;            << 
154                                                << 
155   if (fasterCode) eFullFileName << path << "/m << 
156   else eFullFileName << path << "/microelec/si << 
157                                                << 
158   std::ifstream eDiffCrossSection(eFullFileNam << 
159                                                << 
160   if (!eDiffCrossSection)                      << 
161   {                                            << 
162      if (fasterCode) G4Exception("G4MicroElecI << 
163      FatalException,"Missing data file:/microe << 
164                                                   130 
165      else G4Exception("G4MicroElecInelasticMod << 131     tableFile[electron] = fileElectron;
166      FatalException,"Missing data file:/microe << 
167   }                                            << 
168                                                   132 
169   // Clear the arrays for re-initialization ca << 133     lowEnergyLimit[electron] = 16.7 * eV; 
170   // Octobre 22nd, 2014 - Melanie Raine        << 134     highEnergyLimit[electron] = 100.0 * MeV;
171   eTdummyVec.clear();                          << 
172   pTdummyVec.clear();                          << 
173                                                << 
174   eVecm.clear();                               << 
175   pVecm.clear();                               << 
176                                                << 
177   for (int j=0; j<6; j++)                      << 
178   {                                            << 
179     eProbaShellMap[j].clear();                 << 
180     pProbaShellMap[j].clear();                 << 
181                                                   135 
182     eDiffCrossSectionData[j].clear();          << 136     // Cross section
183     pDiffCrossSectionData[j].clear();          << 
184                                                << 
185     eNrjTransfData[j].clear();                 << 
186     pNrjTransfData[j].clear();                 << 
187   }                                            << 
188                                                << 
189   //                                           << 
190   eTdummyVec.push_back(0.);                    << 
191   while(!eDiffCrossSection.eof())              << 
192   {                                            << 
193     G4double tDummy;                           << 
194     G4double eDummy;                           << 
195     eDiffCrossSection>>tDummy>>eDummy;         << 
196     if (tDummy != eTdummyVec.back()) eTdummyVe << 
197                                                   137     
198     G4double tmp;                              << 138     G4MicroElecCrossSectionDataSet* tableE = new G4MicroElecCrossSectionDataSet(new G4LogLogInterpolation, eV,scaleFactor );
199     for (int j=0; j<6; j++)                    << 139     tableE->LoadData(fileElectron);
200     {                                          << 
201       eDiffCrossSection>> tmp;                 << 
202                                                   140       
203       eDiffCrossSectionData[j][tDummy][eDummy] << 141     tableData[electron] = tableE;
                                                   >> 142     
                                                   >> 143     // Final state
                                                   >> 144     
                                                   >> 145     std::ostringstream eFullFileName;
                                                   >> 146     eFullFileName << path << "/microelec/sigmadiff_inelastic_e_Si.dat";
                                                   >> 147     std::ifstream eDiffCrossSection(eFullFileName.str().c_str());
                                                   >> 148 
                                                   >> 149     if (!eDiffCrossSection)
                                                   >> 150     { 
                                                   >> 151             G4Exception("G4MicroElecInelasticModel::Initialise","em0003",FatalException,"Missing data file:/microelec/sigmadiff_inelastic_e_Si.dat");
                                                   >> 152     }
204                                                   153       
205       if (fasterCode)                          << 154     eTdummyVec.push_back(0.);
206       {                                        << 155     while(!eDiffCrossSection.eof())
207         eNrjTransfData[j][tDummy][eDiffCrossSe << 156     {
208         eProbaShellMap[j][tDummy].push_back(eD << 157       double tDummy;
209       }                                        << 158       double eDummy;
210       else                                     << 159       eDiffCrossSection>>tDummy>>eDummy;
                                                   >> 160       if (tDummy != eTdummyVec.back()) eTdummyVec.push_back(tDummy);
                                                   >> 161       for (int j=0; j<6; j++)
211       {                                           162       {
212       // SI - only if eof is not reached !     << 163         eDiffCrossSection>>eDiffCrossSectionData[j][tDummy][eDummy];
213   if (!eDiffCrossSection.eof()) eDiffCrossSect << 164 
214   eVecm[tDummy].push_back(eDummy);             << 165         // SI - only if eof is not reached !
                                                   >> 166         if (!eDiffCrossSection.eof()) eDiffCrossSectionData[j][tDummy][eDummy]*=scaleFactor;
                                                   >> 167 
                                                   >> 168         eVecm[tDummy].push_back(eDummy);
                                                   >> 169 
215       }                                           170       }
216                                                << 
217     }                                             171     }
218   }                                            << 172     //
219   //                                           << 
220                                                << 
221   // *** PROTON                                << 
222   tableFile[proton] = fileProton;              << 
223   lowEnergyLimit[proton] = 50. * keV;          << 
224   highEnergyLimit[proton] = 10. * GeV;         << 
225                                                << 
226   // Cross section                             << 
227   G4MicroElecCrossSectionDataSet* tableP = new << 
228   tableP->LoadData(fileProton);                << 
229   tableData[proton] = tableP;                  << 
230                                                << 
231   // Final state                               << 
232   std::ostringstream pFullFileName;            << 
233                                                << 
234   if (fasterCode) pFullFileName << path << "/m << 
235   else pFullFileName << path << "/microelec/si << 
236                                                   173 
237   std::ifstream pDiffCrossSection(pFullFileNam << 174   // *** PROTON
238                                                << 
239   if (!pDiffCrossSection)                      << 
240   {                                            << 
241     if (fasterCode) G4Exception("G4MicroElecIn << 
242       FatalException,"Missing data file:/micro << 
243                                                   175 
244     else G4Exception("G4MicroElecInelasticMode << 176     proton = protonDef->GetParticleName();
245       FatalException,"Missing data file:/micro << 177 
246   }                                            << 178     tableFile[proton] = fileProton;
247                                                << 179 
248   pTdummyVec.push_back(0.);                    << 180     lowEnergyLimit[proton] = 50. * keV;
249   while(!pDiffCrossSection.eof())              << 181     highEnergyLimit[proton] = 10. * GeV;
250   {                                            << 182 
251     G4double tDummy;                           << 183     // Cross section
252     G4double eDummy;                           << 184     
253     pDiffCrossSection>>tDummy>>eDummy;         << 185     G4MicroElecCrossSectionDataSet* tableP = new G4MicroElecCrossSectionDataSet(new G4LogLogInterpolation, eV,scaleFactor );
254     if (tDummy != pTdummyVec.back()) pTdummyVe << 186     tableP->LoadData(fileProton);
255     for (int j=0; j<6; j++)                    << 
256     {                                          << 
257       pDiffCrossSection>>pDiffCrossSectionData << 
258                                                   187       
259       if (fasterCode)                          << 188     tableData[proton] = tableP;
260       {                                        << 189     
261         pNrjTransfData[j][tDummy][pDiffCrossSe << 190     // Final state
262         pProbaShellMap[j][tDummy].push_back(pD << 191 
263       }                                        << 192     std::ostringstream pFullFileName;
264       else                                     << 193     pFullFileName << path << "/microelec/sigmadiff_inelastic_p_Si.dat";
                                                   >> 194     std::ifstream pDiffCrossSection(pFullFileName.str().c_str());
                                                   >> 195     
                                                   >> 196     if (!pDiffCrossSection)
                                                   >> 197     { 
                                                   >> 198             G4Exception("G4MicroElecInelasticModel::Initialise","em0003",FatalException,"Missing data file:/microelec/sigmadiff_inelastic_p_Si.dat");
                                                   >> 199     }
                                                   >> 200       
                                                   >> 201     pTdummyVec.push_back(0.);
                                                   >> 202     while(!pDiffCrossSection.eof())
                                                   >> 203     {
                                                   >> 204       double tDummy;
                                                   >> 205       double eDummy;
                                                   >> 206       pDiffCrossSection>>tDummy>>eDummy;
                                                   >> 207       if (tDummy != pTdummyVec.back()) pTdummyVec.push_back(tDummy);
                                                   >> 208       for (int j=0; j<6; j++)
265       {                                           209       {
266   // SI - only if eof is not reached !         << 210         pDiffCrossSection>>pDiffCrossSectionData[j][tDummy][eDummy];
267   if (!pDiffCrossSection.eof()) pDiffCrossSect << 211 
268   pVecm[tDummy].push_back(eDummy);             << 212         // SI - only if eof is not reached !
                                                   >> 213         if (!pDiffCrossSection.eof()) pDiffCrossSectionData[j][tDummy][eDummy]*=scaleFactor;
                                                   >> 214 
                                                   >> 215         pVecm[tDummy].push_back(eDummy); 
269       }                                           216       }
270     }                                             217     }
271   }                                            << 
272                                                   218   
273   if (particle==electronDef)                   << 219 
                                                   >> 220   if (particle==electronDef) 
274   {                                               221   {
275     SetLowEnergyLimit(lowEnergyLimit[electron]    222     SetLowEnergyLimit(lowEnergyLimit[electron]);
276     SetHighEnergyLimit(highEnergyLimit[electro    223     SetHighEnergyLimit(highEnergyLimit[electron]);
277   }                                               224   }
278                                                << 225 
279   if (particle==protonDef)                     << 226   if (particle==protonDef) 
280   {                                               227   {
281     SetLowEnergyLimit(lowEnergyLimit[proton]);    228     SetLowEnergyLimit(lowEnergyLimit[proton]);
282     SetHighEnergyLimit(highEnergyLimit[proton]    229     SetHighEnergyLimit(highEnergyLimit[proton]);
283   }                                               230   }
284                                                << 231 
285   if( verboseLevel>0 )                         << 232   if( verboseLevel>0 ) 
286   {                                            << 233   { 
287     G4cout << "MicroElec Inelastic model is in    234     G4cout << "MicroElec Inelastic model is initialized " << G4endl
288     << "Energy range: "                        << 235            << "Energy range: "
289     << LowEnergyLimit() / keV << " keV - "     << 236            << LowEnergyLimit() / eV << " eV - "
290     << HighEnergyLimit() / MeV << " MeV for "  << 237            << HighEnergyLimit() / keV << " keV for "
291     << particle->GetParticleName()             << 238            << particle->GetParticleName()
292      << " with mass (amu) " << particle->GetPD    239      << " with mass (amu) " << particle->GetPDGMass()/proton_mass_c2
293      << " and charge " << particle->GetPDGChar    240      << " and charge " << particle->GetPDGCharge()
294     << G4endl << G4endl ;                      << 241            << G4endl << G4endl ;
295   }                                               242   }
296                                                   243   
297   //                                              244   //
298   fAtomDeexcitation  = G4LossTableManager::Ins << 245 
299                                                << 246   fAtomDeexcitation  = G4LossTableManager::Instance()->AtomDeexcitation(); 
                                                   >> 247 
300   if (isInitialised) { return; }                  248   if (isInitialised) { return; }
301   fParticleChangeForGamma = GetParticleChangeF    249   fParticleChangeForGamma = GetParticleChangeForGamma();
302   isInitialised = true;                           250   isInitialised = true;
                                                   >> 251 
303 }                                                 252 }
304                                                   253 
305 //....oooOO0OOooo........oooOO0OOooo........oo    254 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
306                                                   255 
307 G4double G4MicroElecInelasticModel::CrossSecti    256 G4double G4MicroElecInelasticModel::CrossSectionPerVolume(const G4Material* material,
308                                                << 257              const G4ParticleDefinition* particleDefinition,
309                                                << 258              G4double ekin,
310                                                << 259              G4double,
311                                                << 260              G4double)
312 {                                                 261 {
313   if (verboseLevel > 3)                           262   if (verboseLevel > 3)
314     G4cout << "Calling CrossSectionPerVolume()    263     G4cout << "Calling CrossSectionPerVolume() of G4MicroElecInelasticModel" << G4endl;
315                                                << 264 
316   G4double density = material->GetTotNbOfAtoms    265   G4double density = material->GetTotNbOfAtomsPerVolume();
                                                   >> 266 
                                                   >> 267  /* if (
                                                   >> 268       particleDefinition != G4Proton::ProtonDefinition()
                                                   >> 269       &&
                                                   >> 270       particleDefinition != G4Electron::ElectronDefinition()
                                                   >> 271       &&
                                                   >> 272       particleDefinition != G4GenericIon::GenericIonDefinition()
                                                   >> 273      )
                                                   >> 274         
                                                   >> 275     return 0;*/
317                                                   276   
318   // Calculate total cross section for model   << 277   // Calculate total cross section for model
                                                   >> 278 
319   G4double lowLim = 0;                            279   G4double lowLim = 0;
320   G4double highLim = 0;                           280   G4double highLim = 0;
321   G4double sigma=0;                               281   G4double sigma=0;
322                                                << 282 
323   const G4String& particleName = particleDefin    283   const G4String& particleName = particleDefinition->GetParticleName();
324   G4String nameLocal = particleName ;             284   G4String nameLocal = particleName ;
325                                                << 285 
326   G4double Zeff2 = 1.0;                           286   G4double Zeff2 = 1.0;
327   G4double Mion_c2 = particleDefinition->GetPD    287   G4double Mion_c2 = particleDefinition->GetPDGMass();
328                                                << 288 
329   if (Mion_c2 > proton_mass_c2)                   289   if (Mion_c2 > proton_mass_c2)
330   {                                               290   {
331     G4ionEffectiveCharge EffCharge ;           << 291     G4ionEffectiveCharge EffCharge ; 
332     G4double Zeff = EffCharge.EffectiveCharge(    292     G4double Zeff = EffCharge.EffectiveCharge(particleDefinition, material,ekin);
333     Zeff2 = Zeff*Zeff;                            293     Zeff2 = Zeff*Zeff;
334                                                << 294 
335     if (verboseLevel > 3)                      << 295     if (verboseLevel > 3) 
336       G4cout << "Before scaling : " << G4endl  << 296     G4cout << "Before scaling : " << G4endl
337       << "Particle : " << nameLocal << ", mass << 297     << "Particle : " << nameLocal << ", mass : " << Mion_c2/proton_mass_c2 << "*mp, charge " << Zeff 
338       << ", Ekin (eV) = " << ekin/eV << G4endl << 298     << ", Ekin (eV) = " << ekin/eV << G4endl ;
339                                                << 299 
340     ekin *= proton_mass_c2/Mion_c2 ;              300     ekin *= proton_mass_c2/Mion_c2 ;
341     nameLocal = "proton" ;                        301     nameLocal = "proton" ;
342                                                << 302 
343     if (verboseLevel > 3)                      << 303     if (verboseLevel > 3) 
344       G4cout << "After scaling : " << G4endl   << 304     G4cout << "After scaling : " << G4endl
345       << "Particle : " << nameLocal  << ", Eki << 305      << "Particle : " << nameLocal  << ", Ekin (eV) = " << ekin/eV << G4endl ;
346   }                                               306   }
347                                                << 307 
348   if (material == nistSi || material->GetBaseM    308   if (material == nistSi || material->GetBaseMaterial() == nistSi)
349   {                                            << 309   {
350     auto pos1 = lowEnergyLimit.find(nameLocal) << 310 
                                                   >> 311     std::map< G4String,G4double,std::less<G4String> >::iterator pos1;
                                                   >> 312     pos1 = lowEnergyLimit.find(nameLocal);
351     if (pos1 != lowEnergyLimit.end())             313     if (pos1 != lowEnergyLimit.end())
352     {                                             314     {
353       lowLim = pos1->second;                      315       lowLim = pos1->second;
354     }                                             316     }
355                                                << 317   
356     auto pos2 = highEnergyLimit.find(nameLocal << 318     std::map< G4String,G4double,std::less<G4String> >::iterator pos2;
                                                   >> 319     pos2 = highEnergyLimit.find(nameLocal);
357     if (pos2 != highEnergyLimit.end())            320     if (pos2 != highEnergyLimit.end())
358     {                                             321     {
359       highLim = pos2->second;                     322       highLim = pos2->second;
360     }                                             323     }
361                                                << 324 
362     if (ekin >= lowLim && ekin < highLim)         325     if (ekin >= lowLim && ekin < highLim)
363     {                                             326     {
364       auto pos = tableData.find(nameLocal);    << 327       std::map< G4String,G4MicroElecCrossSectionDataSet*,std::less<G4String> >::iterator pos;
                                                   >> 328       pos = tableData.find(nameLocal);
                                                   >> 329   
365       if (pos != tableData.end())                 330       if (pos != tableData.end())
366       {                                           331       {
367         G4MicroElecCrossSectionDataSet* table     332         G4MicroElecCrossSectionDataSet* table = pos->second;
368         if (table != nullptr)                  << 333         if (table != 0)
369         {                                         334         {
370           sigma = table->FindValue(ekin);      << 335     sigma = table->FindValue(ekin);
371         }                                         336         }
372       }                                           337       }
373       else                                        338       else
374       {                                           339       {
375         G4Exception("G4MicroElecInelasticModel << 340   G4Exception("G4MicroElecInelasticModel::CrossSectionPerVolume","em0002",FatalException,"Model not applicable to particle type.");
376         FatalException,"Model not applicable t << 
377       }                                           341       }
378     }                                             342     }
379     else                                       << 343     else 
380     {                                             344     {
381       if (nameLocal!="e-")                     << 345   if (nameLocal!="e-")
382       {                                        << 346   {
383         // G4cout << "Particle : " << nameLoca << 347     // G4cout << "Particle : " << nameLocal << ", Ekin (eV) = " << ekin/eV << G4endl;
384         // G4cout << "### Warning: particle en << 348     // G4cout << "### Warning: particle energy out of bounds! ###" << G4endl;
385       }                                        << 349   }
386     }                                             350     }
387                                                << 351 
388     if (verboseLevel > 3)                         352     if (verboseLevel > 3)
389     {                                             353     {
390       G4cout << "---> Kinetic energy (eV)=" <<    354       G4cout << "---> Kinetic energy (eV)=" << ekin/eV << G4endl;
391       G4cout << " - Cross section per Si atom     355       G4cout << " - Cross section per Si atom (cm^2)=" << sigma*Zeff2/cm2 << G4endl;
392       G4cout << " - Cross section per Si atom     356       G4cout << " - Cross section per Si atom (cm^-1)=" << sigma*density*Zeff2/(1./cm) << G4endl;
393     }                                          << 357     } 
394                                                << 358  
395   } // if (SiMaterial)                            359   } // if (SiMaterial)
396   return sigma*density*Zeff2;                  << 360  return sigma*density*Zeff2;
                                                   >> 361      
                                                   >> 362 
397 }                                                 363 }
398                                                   364 
399 //....oooOO0OOooo........oooOO0OOooo........oo    365 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
400                                                   366 
401 void G4MicroElecInelasticModel::SampleSecondar    367 void G4MicroElecInelasticModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
402                                                << 368                 const G4MaterialCutsCouple* /*couple*/,
403                                                << 369                 const G4DynamicParticle* particle,
404                                                << 370                 G4double,
405                                                << 371                 G4double)
406 {                                                 372 {
407                                                << 373 
408   if (verboseLevel > 3)                           374   if (verboseLevel > 3)
409     G4cout << "Calling SampleSecondaries() of     375     G4cout << "Calling SampleSecondaries() of G4MicroElecInelasticModel" << G4endl;
410                                                << 376 
411   G4double lowLim = 0;                            377   G4double lowLim = 0;
412   G4double highLim = 0;                           378   G4double highLim = 0;
413                                                << 379 
414   G4double ekin = particle->GetKineticEnergy()    380   G4double ekin = particle->GetKineticEnergy();
415   G4double k = ekin ;                             381   G4double k = ekin ;
416                                                << 382 
417   G4ParticleDefinition* PartDef = particle->Ge    383   G4ParticleDefinition* PartDef = particle->GetDefinition();
418   const G4String& particleName = PartDef->GetP    384   const G4String& particleName = PartDef->GetParticleName();
419   G4String nameLocal2 = particleName ;            385   G4String nameLocal2 = particleName ;
420   G4double particleMass = particle->GetDefinit    386   G4double particleMass = particle->GetDefinition()->GetPDGMass();
421                                                << 387 
422   if (particleMass > proton_mass_c2)              388   if (particleMass > proton_mass_c2)
423   {                                               389   {
424     k *= proton_mass_c2/particleMass ;            390     k *= proton_mass_c2/particleMass ;
425     PartDef = G4Proton::ProtonDefinition();       391     PartDef = G4Proton::ProtonDefinition();
426     nameLocal2 = "proton" ;                       392     nameLocal2 = "proton" ;
427   }                                               393   }
428                                                << 394 
429   auto pos1 = lowEnergyLimit.find(nameLocal2); << 395   std::map< G4String,G4double,std::less<G4String> >::iterator pos1;
                                                   >> 396   pos1 = lowEnergyLimit.find(nameLocal2);
                                                   >> 397 
430   if (pos1 != lowEnergyLimit.end())               398   if (pos1 != lowEnergyLimit.end())
431   {                                               399   {
432     lowLim = pos1->second;                        400     lowLim = pos1->second;
433   }                                               401   }
434                                                << 402 
435   auto pos2 = highEnergyLimit.find(nameLocal2) << 403   std::map< G4String,G4double,std::less<G4String> >::iterator pos2;
                                                   >> 404   pos2 = highEnergyLimit.find(nameLocal2);
                                                   >> 405 
436   if (pos2 != highEnergyLimit.end())              406   if (pos2 != highEnergyLimit.end())
437   {                                               407   {
438     highLim = pos2->second;                       408     highLim = pos2->second;
439   }                                               409   }
440                                                << 410 
441   if (k >= lowLim && k < highLim)                 411   if (k >= lowLim && k < highLim)
442   {                                               412   {
443     G4ParticleMomentum primaryDirection = part    413     G4ParticleMomentum primaryDirection = particle->GetMomentumDirection();
444     G4double totalEnergy = ekin + particleMass    414     G4double totalEnergy = ekin + particleMass;
445     G4double pSquare = ekin * (totalEnergy + p    415     G4double pSquare = ekin * (totalEnergy + particleMass);
446     G4double totalMomentum = std::sqrt(pSquare    416     G4double totalMomentum = std::sqrt(pSquare);
447                                                << 417 
448     G4int Shell = 0;                           << 418     G4int Shell = RandomSelect(k,nameLocal2);
449                                                << 
450     /* if (!fasterCode)*/ Shell = RandomSelect << 
451                                                << 
452     // SI: The following protection is necessa << 
453     //  sigmadiff_ionisation_e_born.dat has no << 
454     //  sigmadiff_cumulated_ionisation_e_born. << 
455     //  this is due to the fact that the max a << 
456     //  strictly above this value have non zer << 
457                                                << 
458     G4double bindingEnergy = SiStructure.Energ    419     G4double bindingEnergy = SiStructure.Energy(Shell);
459                                                << 
460     if (verboseLevel > 3)                         420     if (verboseLevel > 3)
461     {                                             421     {
462       G4cout << "---> Kinetic energy (eV)=" << << 422   G4cout << "---> Kinetic energy (eV)=" << k/eV << G4endl ;
463       G4cout << "Shell: " << Shell << ", energ << 423   G4cout << "Shell: " << Shell << ", energy: " << bindingEnergy/eV << G4endl;
464     }                                             424     }
465                                                << 425 
466     // sample deexcitation                     << 426    // sample deexcitation
467     std::size_t secNumberInit = 0;  // need to << 427 
468     std::size_t secNumberFinal = 0; // So I'll << 428     G4int secNumberInit = 0;  // need to know at a certain point the energy of secondaries   
469                                                << 429     G4int secNumberFinal = 0; // So I'll make the difference and then sum the energies
470     //SI: additional protection if tcs interpo << 430 
471     if (k<bindingEnergy) return;               << 
472                                                << 
473     G4int Z = 14;                              << 
474                                                << 
475     if(fAtomDeexcitation && Shell > 2) {          431     if(fAtomDeexcitation && Shell > 2) {
476                                                << 432       G4int Z = 14;
477       G4AtomicShellEnumerator as = fKShell;       433       G4AtomicShellEnumerator as = fKShell;
478                                                << 434 
479       if (Shell == 4)                          << 435       if (Shell == 4) 
480       {                                        << 436   {
481         as = G4AtomicShellEnumerator(1);       << 437     as = G4AtomicShellEnumerator(1);
482       }                                        << 438   }
483       else if (Shell == 3)                        439       else if (Shell == 3)
484       {                                        << 440   {
485         as = G4AtomicShellEnumerator(3);       << 441     as = G4AtomicShellEnumerator(3);
486       }                                        << 442   }
487                                                << 443 
488       const G4AtomicShell* shell = fAtomDeexci << 444       const G4AtomicShell* shell = fAtomDeexcitation->GetAtomicShell(Z, as);    
489       secNumberInit = fvect->size();              445       secNumberInit = fvect->size();
490       fAtomDeexcitation->GenerateParticles(fve    446       fAtomDeexcitation->GenerateParticles(fvect, shell, Z, 0, 0);
491       secNumberFinal = fvect->size();             447       secNumberFinal = fvect->size();
492     }                                             448     }
493                                                << 
494     G4double secondaryKinetic=-1000*eV;        << 
495                                                   449 
496     if (!fasterCode)                           << 450     G4double secondaryKinetic = RandomizeEjectedElectronEnergy(PartDef,k,Shell);
497     {                                          << 451 
498       secondaryKinetic = RandomizeEjectedElect << 
499     }                                          << 
500     else                                       << 
501     {                                          << 
502       secondaryKinetic = RandomizeEjectedElect << 
503     }                                          << 
504                                                << 
505     if (verboseLevel > 3)                         452     if (verboseLevel > 3)
506     {                                             453     {
507       G4cout << "Ionisation process" << G4endl << 454   G4cout << "Ionisation process" << G4endl;
508       G4cout << "Shell: " << Shell << " Kin. e << 455   G4cout << "Shell: " << Shell << " Kin. energy (eV)=" << k/eV 
509       << " Sec. energy (eV)=" << secondaryKine << 456   << " Sec. energy (eV)=" << secondaryKinetic/eV << G4endl;
510     }                                          << 457     }
511                                                << 458 
512     G4ThreeVector deltaDirection =             << 459     G4double cosTheta = 0.;
513     GetAngularDistribution()->SampleDirectionF << 460     G4double phi = 0.; 
514                                                << 461     RandomizeEjectedElectronDirection(PartDef, k, secondaryKinetic, cosTheta, phi);
515                                                << 462 
516                                                << 463     G4double sinTheta = std::sqrt(1.-cosTheta*cosTheta);
517     if (particle->GetDefinition() == G4Electro << 464     G4double dirX = sinTheta*std::cos(phi);
518     {                                          << 465     G4double dirY = sinTheta*std::sin(phi);
519       G4double deltaTotalMomentum = std::sqrt( << 466     G4double dirZ = cosTheta;
                                                   >> 467     G4ThreeVector deltaDirection(dirX,dirY,dirZ);
                                                   >> 468     deltaDirection.rotateUz(primaryDirection);
                                                   >> 469 
                                                   >> 470     //if (particle->GetDefinition() == G4Electron::ElectronDefinition())
                                                   >> 471     //{
                                                   >> 472       G4double deltaTotalMomentum = std::sqrt(secondaryKinetic*(secondaryKinetic + 2.*electron_mass_c2 ));
                                                   >> 473 
520       G4double finalPx = totalMomentum*primary    474       G4double finalPx = totalMomentum*primaryDirection.x() - deltaTotalMomentum*deltaDirection.x();
521       G4double finalPy = totalMomentum*primary    475       G4double finalPy = totalMomentum*primaryDirection.y() - deltaTotalMomentum*deltaDirection.y();
522       G4double finalPz = totalMomentum*primary    476       G4double finalPz = totalMomentum*primaryDirection.z() - deltaTotalMomentum*deltaDirection.z();
523       G4double finalMomentum = std::sqrt(final    477       G4double finalMomentum = std::sqrt(finalPx*finalPx + finalPy*finalPy + finalPz*finalPz);
524       finalPx /= finalMomentum;                   478       finalPx /= finalMomentum;
525       finalPy /= finalMomentum;                   479       finalPy /= finalMomentum;
526       finalPz /= finalMomentum;                   480       finalPz /= finalMomentum;
527                                                << 481     
528       G4ThreeVector direction;                    482       G4ThreeVector direction;
529       direction.set(finalPx,finalPy,finalPz);     483       direction.set(finalPx,finalPy,finalPz);
530                                                << 
531       fParticleChangeForGamma->ProposeMomentum << 
532     }                                          << 
533     else                                       << 
534       fParticleChangeForGamma->ProposeMomentum << 
535                                                   484     
                                                   >> 485       fParticleChangeForGamma->ProposeMomentumDirection(direction.unit()) ;
                                                   >> 486     //}
                                                   >> 487     //else fParticleChangeForGamma->ProposeMomentumDirection(primaryDirection) ;
                                                   >> 488 
536     // note that secondaryKinetic is the energ    489     // note that secondaryKinetic is the energy of the delta ray, not of all secondaries.
537     G4double deexSecEnergy = 0;                   490     G4double deexSecEnergy = 0;
538     for (std::size_t j=secNumberInit; j < secN << 491     for (G4int j=secNumberInit; j < secNumberFinal; j++) {
539       deexSecEnergy = deexSecEnergy + (*fvect) << 492       deexSecEnergy = deexSecEnergy + (*fvect)[j]->GetKineticEnergy();} 
540                                                << 493 
541     fParticleChangeForGamma->SetProposedKineti    494     fParticleChangeForGamma->SetProposedKineticEnergy(ekin-bindingEnergy-secondaryKinetic);
542     fParticleChangeForGamma->ProposeLocalEnerg    495     fParticleChangeForGamma->ProposeLocalEnergyDeposit(bindingEnergy-deexSecEnergy);
543                                                << 496 
544     if (secondaryKinetic>0)                    << 497     G4DynamicParticle* dp = new G4DynamicParticle (G4Electron::Electron(),deltaDirection,secondaryKinetic) ;
545     {                                          << 498     fvect->push_back(dp);
546       G4DynamicParticle* dp = new G4DynamicPar << 499 
547       fvect->push_back(dp);                    << 
548     }                                          << 
549   }                                               500   }
                                                   >> 501 
550 }                                                 502 }
551                                                   503 
552 //....oooOO0OOooo........oooOO0OOooo........oo    504 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
553                                                   505 
554 G4double G4MicroElecInelasticModel::RandomizeE << 506 G4double G4MicroElecInelasticModel::RandomizeEjectedElectronEnergy(G4ParticleDefinition* particleDefinition, 
555                                                << 507 G4double k, G4int shell)
556 {                                                 508 {
557   if (particleDefinition == G4Electron::Electr << 509   if (particleDefinition == G4Electron::ElectronDefinition()) 
558   {                                               510   {
559     G4double maximumEnergyTransfer=0.;            511     G4double maximumEnergyTransfer=0.;
560     if ((k+SiStructure.Energy(shell))/2. > k)     512     if ((k+SiStructure.Energy(shell))/2. > k) maximumEnergyTransfer=k;
561     else maximumEnergyTransfer = (k+SiStructur    513     else maximumEnergyTransfer = (k+SiStructure.Energy(shell))/2.;
562                                                << 514 
563     G4double crossSectionMaximum = 0.;            515     G4double crossSectionMaximum = 0.;
564                                                << 516 
565     G4double minEnergy = SiStructure.Energy(sh    517     G4double minEnergy = SiStructure.Energy(shell);
566     G4double maxEnergy = maximumEnergyTransfer    518     G4double maxEnergy = maximumEnergyTransfer;
567     G4int nEnergySteps = 100;                     519     G4int nEnergySteps = 100;
568                                                << 520 
569     G4double value(minEnergy);                    521     G4double value(minEnergy);
570     G4double stpEnergy(std::pow(maxEnergy/valu    522     G4double stpEnergy(std::pow(maxEnergy/value, 1./static_cast<G4double>(nEnergySteps-1)));
571     G4int step(nEnergySteps);                     523     G4int step(nEnergySteps);
572     while (step>0)                                524     while (step>0)
573     {                                             525     {
574       step--;                                     526       step--;
575       G4double differentialCrossSection = Diff    527       G4double differentialCrossSection = DifferentialCrossSection(particleDefinition, k/eV, value/eV, shell);
576       if(differentialCrossSection >= crossSect    528       if(differentialCrossSection >= crossSectionMaximum) crossSectionMaximum = differentialCrossSection;
577       value*=stpEnergy;                           529       value*=stpEnergy;
578     }                                             530     }
579                                                << 531 
                                                   >> 532  
580     G4double secondaryElectronKineticEnergy=0.    533     G4double secondaryElectronKineticEnergy=0.;
581     do                                         << 534     do 
582     {                                             535     {
583       secondaryElectronKineticEnergy = G4Unifo    536       secondaryElectronKineticEnergy = G4UniformRand() * (maximumEnergyTransfer-SiStructure.Energy(shell));
584     } while(G4UniformRand()*crossSectionMaximu    537     } while(G4UniformRand()*crossSectionMaximum >
585             DifferentialCrossSection(particleD << 538       DifferentialCrossSection(particleDefinition, k/eV,(secondaryElectronKineticEnergy+SiStructure.Energy(shell))/eV,shell));
586                                                << 539 
587     return secondaryElectronKineticEnergy;     << 540     return secondaryElectronKineticEnergy;
                                                   >> 541  
588   }                                               542   }
589                                                << 543 
590   if (particleDefinition == G4Proton::ProtonDe << 544   if (particleDefinition == G4Proton::ProtonDefinition()) 
591   {                                               545   {
592     G4double maximumEnergyTransfer = 4.* (elec    546     G4double maximumEnergyTransfer = 4.* (electron_mass_c2 / proton_mass_c2) * k;
593     G4double crossSectionMaximum = 0.;            547     G4double crossSectionMaximum = 0.;
594                                                << 548 
595     G4double minEnergy = SiStructure.Energy(sh    549     G4double minEnergy = SiStructure.Energy(shell);
596     G4double maxEnergy = maximumEnergyTransfer << 550     G4double maxEnergy = maximumEnergyTransfer; 
597     G4int nEnergySteps = 100;                     551     G4int nEnergySteps = 100;
598                                                << 552 
599     G4double value(minEnergy);                    553     G4double value(minEnergy);
600     G4double stpEnergy(std::pow(maxEnergy/valu    554     G4double stpEnergy(std::pow(maxEnergy/value, 1./static_cast<G4double>(nEnergySteps-1)));
601     G4int step(nEnergySteps);                     555     G4int step(nEnergySteps);
602     while (step>0)                                556     while (step>0)
603     {                                             557     {
604       step--;                                  << 558       step--; 
605       G4double differentialCrossSection = Diff    559       G4double differentialCrossSection = DifferentialCrossSection(particleDefinition, k/eV, value/eV, shell);
606       if(differentialCrossSection >= crossSect    560       if(differentialCrossSection >= crossSectionMaximum) crossSectionMaximum = differentialCrossSection;
607       value*=stpEnergy;                           561       value*=stpEnergy;
608     }                                             562     }
609                                                << 
610     G4double secondaryElectronKineticEnergy =     563     G4double secondaryElectronKineticEnergy = 0.;
611     do                                            564     do
612     {                                             565     {
613       secondaryElectronKineticEnergy = G4Unifo    566       secondaryElectronKineticEnergy = G4UniformRand() * (maximumEnergyTransfer-SiStructure.Energy(shell));
614                                                << 567 
615     } while(G4UniformRand()*crossSectionMaximu << 568     } while(G4UniformRand()*crossSectionMaximum >= 
616             DifferentialCrossSection(particleD << 569         DifferentialCrossSection(particleDefinition, k/eV,(secondaryElectronKineticEnergy+SiStructure.Energy(shell))/eV,shell));
617     return secondaryElectronKineticEnergy;        570     return secondaryElectronKineticEnergy;
618   }                                               571   }
619                                                << 572  
620   return 0;                                       573   return 0;
621 }                                                 574 }
622                                                   575 
623 //....oooOO0OOooo........oooOO0OOooo........oo    576 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
624                                                   577 
625 // The following section is not used anymore b << 578 void G4MicroElecInelasticModel::RandomizeEjectedElectronDirection(G4ParticleDefinition* particleDefinition, 
626 // GetAngularDistribution()->SampleDirectionFo << 579                    G4double k, 
627                                                << 580                    G4double secKinetic, 
628 /*void G4MicroElecInelasticModel::RandomizeEje << 581                    G4double & cosTheta, 
629  G4double k,                                   << 582                    G4double & phi )
630  G4double secKinetic,                          << 583 {
631  G4double & cosTheta,                          << 584   if (particleDefinition == G4Electron::ElectronDefinition()) 
632  G4double & phi )                              << 585   {
633  {                                             << 586     phi = twopi * G4UniformRand();
634  if (particleDefinition == G4Electron::Electro << 587     G4double sin2O = (1.-secKinetic/k) / (1.+secKinetic/(2.*electron_mass_c2));
635  {                                             << 588     cosTheta = std::sqrt(1.-sin2O);
636  phi = twopi * G4UniformRand();                << 589   }
637  G4double sin2O = (1.-secKinetic/k) / (1.+secK << 
638  cosTheta = std::sqrt(1.-sin2O);               << 
639  }                                             << 
640                                                << 
641  if (particleDefinition == G4Proton::ProtonDef << 
642  {                                             << 
643  G4double maxSecKinetic = 4.* (electron_mass_c << 
644  phi = twopi * G4UniformRand();                << 
645  cosTheta = std::sqrt(secKinetic / maxSecKinet << 
646  }                                             << 
647                                                   590  
648  else                                          << 591   if (particleDefinition == G4Proton::ProtonDefinition()) 
649  {                                             << 592   {
650  G4double maxSecKinetic = 4.* (electron_mass_c << 593     G4double maxSecKinetic = 4.* (electron_mass_c2 / proton_mass_c2) * k;
651  phi = twopi * G4UniformRand();                << 594     phi = twopi * G4UniformRand();
652  cosTheta = std::sqrt(secKinetic / maxSecKinet << 595     cosTheta = std::sqrt(secKinetic / maxSecKinetic);
653  }                                             << 596   }
654  }                                             << 597 
655  */                                            << 598   else
                                                   >> 599   {
                                                   >> 600     G4double maxSecKinetic = 4.* (electron_mass_c2 / particleDefinition->GetPDGMass()) * k;
                                                   >> 601     phi = twopi * G4UniformRand();
                                                   >> 602     cosTheta = std::sqrt(secKinetic / maxSecKinetic);
                                                   >> 603   }
                                                   >> 604 }
656                                                   605 
657 //....oooOO0OOooo........oooOO0OOooo........oo    606 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
658                                                   607 
659 G4double G4MicroElecInelasticModel::Differenti << 608 double G4MicroElecInelasticModel::DifferentialCrossSection(G4ParticleDefinition * particleDefinition, 
660                                                << 609                   G4double k, 
661                                                << 610                   G4double energyTransfer, 
662                                                << 611                   G4int LevelIndex)
663 {                                                 612 {
664   G4double sigma = 0.;                            613   G4double sigma = 0.;
665                                                << 614 
666   if (energyTransfer >= SiStructure.Energy(Lev    615   if (energyTransfer >= SiStructure.Energy(LevelIndex))
667   {                                               616   {
668     G4double valueT1 = 0;                         617     G4double valueT1 = 0;
669     G4double valueT2 = 0;                         618     G4double valueT2 = 0;
670     G4double valueE21 = 0;                        619     G4double valueE21 = 0;
671     G4double valueE22 = 0;                        620     G4double valueE22 = 0;
672     G4double valueE12 = 0;                        621     G4double valueE12 = 0;
673     G4double valueE11 = 0;                        622     G4double valueE11 = 0;
674                                                << 623 
675     G4double xs11 = 0;                         << 624     G4double xs11 = 0;   
676     G4double xs12 = 0;                         << 625     G4double xs12 = 0; 
677     G4double xs21 = 0;                         << 626     G4double xs21 = 0; 
678     G4double xs22 = 0;                         << 627     G4double xs22 = 0; 
679                                                << 628 
680     if (particleDefinition == G4Electron::Elec << 629     if (particleDefinition == G4Electron::ElectronDefinition()) 
681     {                                             630     {
682       // k should be in eV and energy transfer << 631       // k should be in eV and energy transfer eV also
683       auto t2 = std::upper_bound(eTdummyVec.be << 632 
684       auto t1 = t2-1;                          << 633       std::vector<double>::iterator t2 = std::upper_bound(eTdummyVec.begin(),eTdummyVec.end(), k);
685       // The following condition avoids situat << 634       std::vector<double>::iterator t1 = t2-1;
                                                   >> 635       // SI : the following condition avoids situations where energyTransfer >last vector element
686       if (energyTransfer <= eVecm[(*t1)].back(    636       if (energyTransfer <= eVecm[(*t1)].back() && energyTransfer <= eVecm[(*t2)].back() )
687       {                                           637       {
688         auto e12 = std::upper_bound(eVecm[(*t1 << 638         std::vector<double>::iterator e12 = std::upper_bound(eVecm[(*t1)].begin(),eVecm[(*t1)].end(), energyTransfer);
689         auto e11 = e12-1;                      << 639         std::vector<double>::iterator e11 = e12-1;
690         auto e22 = std::upper_bound(eVecm[(*t2 << 640 
691         auto e21 = e22-1;                      << 641         std::vector<double>::iterator e22 = std::upper_bound(eVecm[(*t2)].begin(),eVecm[(*t2)].end(), energyTransfer);
692                                                << 642         std::vector<double>::iterator e21 = e22-1;
                                                   >> 643 
693         valueT1  =*t1;                            644         valueT1  =*t1;
694         valueT2  =*t2;                            645         valueT2  =*t2;
695         valueE21 =*e21;                           646         valueE21 =*e21;
696         valueE22 =*e22;                           647         valueE22 =*e22;
697         valueE12 =*e12;                           648         valueE12 =*e12;
698         valueE11 =*e11;                           649         valueE11 =*e11;
699                                                << 650 
700         xs11 = eDiffCrossSectionData[LevelInde    651         xs11 = eDiffCrossSectionData[LevelIndex][valueT1][valueE11];
701         xs12 = eDiffCrossSectionData[LevelInde    652         xs12 = eDiffCrossSectionData[LevelIndex][valueT1][valueE12];
702         xs21 = eDiffCrossSectionData[LevelInde    653         xs21 = eDiffCrossSectionData[LevelIndex][valueT2][valueE21];
703         xs22 = eDiffCrossSectionData[LevelInde    654         xs22 = eDiffCrossSectionData[LevelIndex][valueT2][valueE22];
704       }                                        << 655       }
                                                   >> 656 
705     }                                             657     }
706                                                << 658   
707     if (particleDefinition == G4Proton::Proton << 659    if (particleDefinition == G4Proton::ProtonDefinition()) 
708     {                                          << 660    {
709       // k should be in eV and energy transfer    661       // k should be in eV and energy transfer eV also
710       auto t2 = std::upper_bound(pTdummyVec.be << 662       std::vector<double>::iterator t2 = std::upper_bound(pTdummyVec.begin(),pTdummyVec.end(), k);
711       auto t1 = t2-1;                          << 663       std::vector<double>::iterator t1 = t2-1;
712       if (energyTransfer <= pVecm[(*t1)].back(    664       if (energyTransfer <= pVecm[(*t1)].back() && energyTransfer <= pVecm[(*t2)].back() )
713       {                                           665       {
714         auto e12 = std::upper_bound(pVecm[(*t1 << 666         std::vector<double>::iterator e12 = std::upper_bound(pVecm[(*t1)].begin(),pVecm[(*t1)].end(), energyTransfer);
715         auto e11 = e12-1;                      << 667     std::vector<double>::iterator e11 = e12-1;
716                                                << 668 
717         auto e22 = std::upper_bound(pVecm[(*t2 << 669         std::vector<double>::iterator e22 = std::upper_bound(pVecm[(*t2)].begin(),pVecm[(*t2)].end(), energyTransfer);
718         auto e21 = e22-1;                      << 670         std::vector<double>::iterator e21 = e22-1;
719                                                << 671  
720         valueT1  =*t1;                            672         valueT1  =*t1;
721         valueT2  =*t2;                            673         valueT2  =*t2;
722         valueE21 =*e21;                           674         valueE21 =*e21;
723         valueE22 =*e22;                           675         valueE22 =*e22;
724         valueE12 =*e12;                           676         valueE12 =*e12;
725         valueE11 =*e11;                           677         valueE11 =*e11;
726                                                << 678 
727         xs11 = pDiffCrossSectionData[LevelInde << 679         xs11 = pDiffCrossSectionData[LevelIndex][valueT1][valueE11]; 
728         xs12 = pDiffCrossSectionData[LevelInde    680         xs12 = pDiffCrossSectionData[LevelIndex][valueT1][valueE12];
729         xs21 = pDiffCrossSectionData[LevelInde    681         xs21 = pDiffCrossSectionData[LevelIndex][valueT2][valueE21];
730         xs22 = pDiffCrossSectionData[LevelInde    682         xs22 = pDiffCrossSectionData[LevelIndex][valueT2][valueE22];
731       }                                        << 683     }
732     }                                          << 684    }
733                                                << 685 
734     sigma = QuadInterpolator(     valueE11, va << 686    G4double xsProduct = xs11 * xs12 * xs21 * xs22;
735           valueE21, valueE22,                  << 687    if (xsProduct != 0.)
736           xs11, xs12,                          << 688    {
737           xs21, xs22,                          << 689      sigma = QuadInterpolator(     valueE11, valueE12, 
738           valueT1, valueT2,                    << 690            valueE21, valueE22, 
739           k, energyTransfer);                  << 691            xs11, xs12, 
740   }                                            << 692            xs21, xs22, 
                                                   >> 693            valueT1, valueT2, 
                                                   >> 694            k, energyTransfer);
                                                   >> 695    }
                                                   >> 696 
                                                   >> 697  }
                                                   >> 698   
741   return sigma;                                   699   return sigma;
742 }                                                 700 }
743                                                   701 
744 //....oooOO0OOooo........oooOO0OOooo........oo    702 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
745                                                   703 
746 G4double G4MicroElecInelasticModel::Interpolat << 704 G4double G4MicroElecInelasticModel::LogLogInterpolate(G4double e1, 
747                                                << 705                    G4double e2, 
748                                                << 706                    G4double e, 
749                                                << 707                    G4double xs1, 
750                                                << 708                    G4double xs2)
751 {                                              << 709 {
752   G4double value = 0.;                         << 710   G4double a = (std::log10(xs2)-std::log10(xs1)) / (std::log10(e2)-std::log10(e1));
753                                                << 711   G4double b = std::log10(xs2) - a*std::log10(e2);
754   // Log-log interpolation by default          << 712   G4double sigma = a*std::log10(e) + b;
755   if (e1 != 0 && e2 != 0 && (std::log10(e2) -  << 713   G4double value = (std::pow(10.,sigma));
756       && !fasterCode)                          << 
757   {                                            << 
758     G4double a = (std::log10(xs2)-std::log10(x << 
759     G4double b = std::log10(xs2) - a*std::log1 << 
760     G4double sigma = a*std::log10(e) + b;      << 
761     value = (std::pow(10.,sigma));             << 
762                                                << 
763   }                                            << 
764                                                << 
765   // Switch to log-lin interpolation for faste << 
766   if ((e2 - e1) != 0 && xs1 != 0 && xs2 != 0 & << 
767   {                                            << 
768     G4double d1 = std::log10(xs1);             << 
769     G4double d2 = std::log10(xs2);             << 
770     value = std::pow(10., (d1 + (d2 - d1) * (e << 
771   }                                            << 
772                                                << 
773   // Switch to lin-lin interpolation for faste << 
774   // in case one of xs1 or xs2 (=cum proba) va << 
775   if ((e2 - e1) != 0 && (xs1 == 0 || xs2 == 0) << 
776   {                                            << 
777     G4double d1 = xs1;                         << 
778     G4double d2 = xs2;                         << 
779     value = (d1 + (d2 - d1) * (e - e1) / (e2 - << 
780   }                                            << 
781                                                << 
782   return value;                                   714   return value;
783 }                                                 715 }
784                                                   716 
785 //....oooOO0OOooo........oooOO0OOooo........oo    717 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
786                                                   718 
787 G4double G4MicroElecInelasticModel::QuadInterp << 719 G4double G4MicroElecInelasticModel::QuadInterpolator(G4double e11, G4double e12, 
788                                                << 720                   G4double e21, G4double e22, 
789                                                << 721                   G4double xs11, G4double xs12, 
790                                                << 722                   G4double xs21, G4double xs22, 
791                                                << 723                   G4double t1, G4double t2, 
792                                                << 724                   G4double t, G4double e)
793 {                                              << 725 {
794   G4double interpolatedvalue1 = Interpolate(e1 << 726   G4double interpolatedvalue1 = LogLogInterpolate(e11, e12, e, xs11, xs12);
795   G4double interpolatedvalue2 = Interpolate(e2 << 727   G4double interpolatedvalue2 = LogLogInterpolate(e21, e22, e, xs21, xs22);
796   G4double value = Interpolate(t1, t2, t, inte << 728   G4double value = LogLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
797   return value;                                   729   return value;
798 }                                                 730 }
799                                                   731 
800 //....oooOO0OOooo........oooOO0OOooo........oo    732 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
801                                                   733 
802 G4int G4MicroElecInelasticModel::RandomSelect(    734 G4int G4MicroElecInelasticModel::RandomSelect(G4double k, const G4String& particle )
803 {                                              << 735 {   
804   G4int level = 0;                                736   G4int level = 0;
805                                                << 737 
806   auto pos = tableData.find(particle);         << 738   std::map< G4String,G4MicroElecCrossSectionDataSet*,std::less<G4String> >::iterator pos;
807   if (pos != tableData.cend())                 << 739   pos = tableData.find(particle);
                                                   >> 740 
                                                   >> 741   if (pos != tableData.end())
808   {                                               742   {
809     G4MicroElecCrossSectionDataSet* table = po    743     G4MicroElecCrossSectionDataSet* table = pos->second;
810                                                << 744 
811     if (table != nullptr)                      << 745     if (table != 0)
812     {                                             746     {
813       G4double* valuesBuffer = new G4double[ta    747       G4double* valuesBuffer = new G4double[table->NumberOfComponents()];
814       const G4int n = (G4int)table->NumberOfCo << 748       const size_t n(table->NumberOfComponents());
815       G4int i(n);                              << 749       size_t i(n);
816       G4double value = 0.;                        750       G4double value = 0.;
817                                                << 751       
818       while (i>0)                                 752       while (i>0)
819       {                                        << 753       { 
820         --i;                                   << 754   i--;
821         valuesBuffer[i] = table->GetComponent( << 755   valuesBuffer[i] = table->GetComponent(i)->FindValue(k);
822         value += valuesBuffer[i];              << 756   value += valuesBuffer[i];
823       }                                           757       }
824                                                << 758       
825       value *= G4UniformRand();                   759       value *= G4UniformRand();
826                                                << 760     
827       i = n;                                      761       i = n;
828                                                << 762       
829       while (i > 0)                               763       while (i > 0)
830       {                                           764       {
831         --i;                                   << 765   i--;
832                                                << 766 
833         if (valuesBuffer[i] > value)           << 767   if (valuesBuffer[i] > value)
834         {                                         768         {
835           delete[] valuesBuffer;                  769           delete[] valuesBuffer;
836           return i;                               770           return i;
837         }                                         771         }
838         value -= valuesBuffer[i];              << 772   value -= valuesBuffer[i];
839       }                                           773       }
840                                                << 774       
841       if (valuesBuffer) delete[] valuesBuffer;    775       if (valuesBuffer) delete[] valuesBuffer;
842                                                << 776     
843     }                                             777     }
844   }                                               778   }
845   else                                            779   else
846   {                                               780   {
847     G4Exception("G4MicroElecInelasticModel::Ra    781     G4Exception("G4MicroElecInelasticModel::RandomSelect","em0002",FatalException,"Model not applicable to particle type.");
848   }                                               782   }
849                                                << 783       
850   return level;                                   784   return level;
851 }                                                 785 }
852                                                   786 
853 //....oooOO0OOooo........oooOO0OOooo........oo    787 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
854                                                << 
855 G4double G4MicroElecInelasticModel::RandomizeE << 
856                                                << 
857                                                << 
858 {                                              << 
859                                                << 
860   G4double secondaryElectronKineticEnergy = 0. << 
861   G4double random = G4UniformRand();           << 
862   secondaryElectronKineticEnergy = TransferedE << 
863                                                << 
864                                                << 
865                                                << 
866       - SiStructure.Energy(shell);             << 
867                                                << 
868   if (secondaryElectronKineticEnergy < 0.)     << 
869     return 0.;                                 << 
870   //                                           << 
871   return secondaryElectronKineticEnergy;       << 
872 }                                              << 
873                                                << 
874 //....oooOO0OOooo........oooOO0OOooo........oo << 
875                                                << 
876 G4double G4MicroElecInelasticModel::Transfered << 
877                                                << 
878                                                << 
879                                                << 
880 {                                              << 
881   G4double nrj = 0.;                           << 
882                                                << 
883   G4double valueK1 = 0;                        << 
884   G4double valueK2 = 0;                        << 
885   G4double valuePROB21 = 0;                    << 
886   G4double valuePROB22 = 0;                    << 
887   G4double valuePROB12 = 0;                    << 
888   G4double valuePROB11 = 0;                    << 
889                                                << 
890   G4double nrjTransf11 = 0;                    << 
891   G4double nrjTransf12 = 0;                    << 
892   G4double nrjTransf21 = 0;                    << 
893   G4double nrjTransf22 = 0;                    << 
894                                                << 
895   G4double maximumEnergyTransfer1 = 0;         << 
896   G4double maximumEnergyTransfer2 = 0;         << 
897   G4double maximumEnergyTransferP = 4.* (elect << 
898   G4double bindingEnergy = SiStructure.Energy( << 
899                                                << 
900   if (particleDefinition == G4Electron::Electr << 
901   {                                            << 
902     // k should be in eV                       << 
903     auto k2 = std::upper_bound(eTdummyVec.begi << 
904              eTdummyVec.end(),                 << 
905              k);                               << 
906     auto k1 = k2 - 1;                          << 
907                                                << 
908     /*                                         << 
909      G4cout << "----> k=" << k                 << 
910      << " " << *k1                             << 
911      << " " << *k2                             << 
912      << " " << random                          << 
913      << " " << ionizationLevelIndex            << 
914      << " " << eProbaShellMap[ionizationLevelI << 
915      << " " << eProbaShellMap[ionizationLevelI << 
916      << G4endl;                                << 
917      */                                        << 
918                                                << 
919     // SI : the following condition avoids sit << 
920     if (random <= eProbaShellMap[ionizationLev << 
921         && random <= eProbaShellMap[ionization << 
922     {                                          << 
923       auto prob12 =                            << 
924           std::upper_bound(eProbaShellMap[ioni << 
925                            eProbaShellMap[ioni << 
926                            random);            << 
927       auto prob11 = prob12 - 1;                << 
928       auto prob22 =                            << 
929           std::upper_bound(eProbaShellMap[ioni << 
930                            eProbaShellMap[ioni << 
931                            random);            << 
932       auto prob21 = prob22 - 1;                << 
933                                                << 
934       valueK1 = *k1;                           << 
935       valueK2 = *k2;                           << 
936       valuePROB21 = *prob21;                   << 
937       valuePROB22 = *prob22;                   << 
938       valuePROB12 = *prob12;                   << 
939       valuePROB11 = *prob11;                   << 
940                                                << 
941       // The following condition avoid getting << 
942       if(valuePROB11 == 0) nrjTransf11 = bindi << 
943       else nrjTransf11 = eNrjTransfData[ioniza << 
944       if(valuePROB12 == 1)                     << 
945       {                                        << 
946   if ((valueK1+bindingEnergy)/2. > valueK1) ma << 
947       else maximumEnergyTransfer1 = (valueK1+b << 
948                                                << 
949   nrjTransf12 = maximumEnergyTransfer1;        << 
950       }                                        << 
951       else nrjTransf12 = eNrjTransfData[ioniza << 
952                                                << 
953       if(valuePROB21 == 0) nrjTransf21 = bindi << 
954       else nrjTransf21 = eNrjTransfData[ioniza << 
955       if(valuePROB22 == 1)                     << 
956       {                                        << 
957   if ((valueK2+bindingEnergy)/2. > valueK2) ma << 
958       else maximumEnergyTransfer2 = (valueK2+b << 
959                                                << 
960   nrjTransf22 = maximumEnergyTransfer2;        << 
961       }                                        << 
962       else                                     << 
963   nrjTransf22 = eNrjTransfData[ionizationLevel << 
964     }                                          << 
965     // Avoids cases where cum xs is zero for k << 
966     if (random > eProbaShellMap[ionizationLeve << 
967     {                                          << 
968       auto prob22 =                            << 
969           std::upper_bound(eProbaShellMap[ioni << 
970                            eProbaShellMap[ioni << 
971                            random);            << 
972                                                << 
973       auto prob21 = prob22 - 1;                << 
974                                                << 
975       valueK1 = *k1;                           << 
976       valueK2 = *k2;                           << 
977       valuePROB21 = *prob21;                   << 
978       valuePROB22 = *prob22;                   << 
979                                                << 
980       nrjTransf21 = eNrjTransfData[ionizationL << 
981       nrjTransf22 = eNrjTransfData[ionizationL << 
982                                                << 
983       G4double interpolatedvalue2 = Interpolat << 
984                                                << 
985                                                << 
986                                                << 
987                                                << 
988                                                << 
989       // zeros are explicitly set              << 
990       G4double value = Interpolate(valueK1, va << 
991       return value;                            << 
992     }                                          << 
993   }                                            << 
994   //                                           << 
995   else if (particleDefinition == G4Proton::Pro << 
996   {                                            << 
997     // k should be in eV                       << 
998     auto k2 = std::upper_bound(pTdummyVec.begi << 
999              pTdummyVec.end(),                 << 
1000              k);                              << 
1001                                               << 
1002     auto k1 = k2 - 1;                         << 
1003                                               << 
1004     /*                                        << 
1005      G4cout << "----> k=" << k                << 
1006      << " " << *k1                            << 
1007      << " " << *k2                            << 
1008      << " " << random                         << 
1009      << " " << ionizationLevelIndex           << 
1010      << " " << pProbaShellMap[ionizationLevel << 
1011      << " " << pProbaShellMap[ionizationLevel << 
1012      << G4endl;                               << 
1013      */                                       << 
1014                                               << 
1015     // SI : the following condition avoids si << 
1016     //      for eg. when the last element is  << 
1017     if (random <= pProbaShellMap[ionizationLe << 
1018         && random <= pProbaShellMap[ionizatio << 
1019     {                                         << 
1020       auto prob12 =                           << 
1021           std::upper_bound(pProbaShellMap[ion << 
1022                            pProbaShellMap[ion << 
1023                            random);           << 
1024                                               << 
1025       auto prob11 = prob12 - 1;               << 
1026                                               << 
1027       auto prob22 =                           << 
1028   std::upper_bound(pProbaShellMap[ionizationL << 
1029        pProbaShellMap[ionizationLevelIndex][( << 
1030        random);                               << 
1031                                               << 
1032       auto prob21 = prob22 - 1;               << 
1033                                               << 
1034       valueK1 = *k1;                          << 
1035       valueK2 = *k2;                          << 
1036       valuePROB21 = *prob21;                  << 
1037       valuePROB22 = *prob22;                  << 
1038       valuePROB12 = *prob12;                  << 
1039       valuePROB11 = *prob11;                  << 
1040                                               << 
1041       // The following condition avoid gettin << 
1042       if(valuePROB11 == 0) nrjTransf11 = bind << 
1043       else nrjTransf11 = pNrjTransfData[ioniz << 
1044       if(valuePROB12 == 1) nrjTransf12 = maxi << 
1045       else nrjTransf12 = pNrjTransfData[ioniz << 
1046       if(valuePROB21 == 0) nrjTransf21 = bind << 
1047       else nrjTransf21 = pNrjTransfData[ioniz << 
1048       if(valuePROB22 == 1) nrjTransf22 = maxi << 
1049       else nrjTransf22 = pNrjTransfData[ioniz << 
1050                                               << 
1051     }                                         << 
1052                                               << 
1053     // Avoids cases where cum xs is zero for  << 
1054     if (random > pProbaShellMap[ionizationLev << 
1055     {                                         << 
1056       auto prob22 =                           << 
1057           std::upper_bound(pProbaShellMap[ion << 
1058                            pProbaShellMap[ion << 
1059                            random);           << 
1060                                               << 
1061       auto prob21 = prob22 - 1;               << 
1062                                               << 
1063       valueK1 = *k1;                          << 
1064       valueK2 = *k2;                          << 
1065       valuePROB21 = *prob21;                  << 
1066       valuePROB22 = *prob22;                  << 
1067                                               << 
1068       nrjTransf21 = pNrjTransfData[ionization << 
1069       nrjTransf22 = pNrjTransfData[ionization << 
1070                                               << 
1071       G4double interpolatedvalue2 = Interpola << 
1072                                               << 
1073                                               << 
1074                                               << 
1075                                               << 
1076                                               << 
1077       // zeros are explicitly set             << 
1078       G4double value = Interpolate(valueK1, v << 
1079                                               << 
1080       return value;                           << 
1081     }                                         << 
1082   }                                           << 
1083   // End electron and proton cases            << 
1084                                               << 
1085   G4double nrjTransfProduct = nrjTransf11 * n << 
1086       * nrjTransf22;                          << 
1087                                               << 
1088   if (nrjTransfProduct != 0.)                 << 
1089   {                                           << 
1090     nrj = QuadInterpolator(valuePROB11,       << 
1091                            valuePROB12,       << 
1092                            valuePROB21,       << 
1093                            valuePROB22,       << 
1094                            nrjTransf11,       << 
1095                            nrjTransf12,       << 
1096                            nrjTransf21,       << 
1097                            nrjTransf22,       << 
1098                            valueK1,           << 
1099                            valueK2,           << 
1100                            k,                 << 
1101                            random);           << 
1102   }                                           << 
1103                                               << 
1104   return nrj;                                 << 
1105 }                                             << 
1106                                                  788 
1107                                                  789 
1108                                                  790