Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/models/src/G4DNABornIonisationModel1.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/dna/models/src/G4DNABornIonisationModel1.cc (Version 11.3.0) and /processes/electromagnetic/dna/models/src/G4DNABornIonisationModel1.cc (Version 10.4.p1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
                                                   >>  26 // $Id: G4DNABornIonisationModel1.cc 87631 2014-12-14 12:42:05Z matkara $
 26 //                                                 27 //
 27                                                    28 
 28 #include "G4DNABornIonisationModel1.hh"            29 #include "G4DNABornIonisationModel1.hh"
 29 #include "G4PhysicalConstants.hh"                  30 #include "G4PhysicalConstants.hh"
 30 #include "G4SystemOfUnits.hh"                      31 #include "G4SystemOfUnits.hh"
 31 #include "G4UAtomicDeexcitation.hh"                32 #include "G4UAtomicDeexcitation.hh"
 32 #include "G4LossTableManager.hh"                   33 #include "G4LossTableManager.hh"
 33 #include "G4DNAChemistryManager.hh"                34 #include "G4DNAChemistryManager.hh"
 34 #include "G4DNAMolecularMaterial.hh"               35 #include "G4DNAMolecularMaterial.hh"
 35 #include "G4DNABornAngle.hh"                       36 #include "G4DNABornAngle.hh"
 36 #include "G4DeltaAngle.hh"                         37 #include "G4DeltaAngle.hh"
 37 #include "G4Exp.hh"                                38 #include "G4Exp.hh"
 38                                                    39 
 39 //....oooOO0OOooo........oooOO0OOooo........oo     40 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 40                                                    41 
 41 using namespace std;                               42 using namespace std;
 42                                                    43 
 43 //....oooOO0OOooo........oooOO0OOooo........oo     44 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 44                                                    45 
 45 G4DNABornIonisationModel1::G4DNABornIonisation     46 G4DNABornIonisationModel1::G4DNABornIonisationModel1(const G4ParticleDefinition*,
 46                                                    47                                                      const G4String& nam) :
 47 G4VEmModel(nam)                                <<  48     G4VEmModel(nam), isInitialised(false)
 48 {                                                  49 {
 49   verboseLevel = 0;                                50   verboseLevel = 0;
 50   // Verbosity scale:                              51   // Verbosity scale:
 51   // 0 = nothing                                   52   // 0 = nothing
 52   // 1 = warning for energy non-conservation       53   // 1 = warning for energy non-conservation
 53   // 2 = details of energy budget                  54   // 2 = details of energy budget
 54   // 3 = calculation of cross sections, file o     55   // 3 = calculation of cross sections, file openings, sampling of atoms
 55   // 4 = entering in methods                       56   // 4 = entering in methods
 56                                                    57 
 57   if (verboseLevel > 0)                            58   if (verboseLevel > 0)
 58   {                                                59   {
 59     G4cout << "Born ionisation model is constr     60     G4cout << "Born ionisation model is constructed " << G4endl;
 60   }                                                61   }
 61                                                    62 
 62   // Mark this model as "applicable" for atomi     63   // Mark this model as "applicable" for atomic deexcitation
 63   SetDeexcitationFlag(true);                       64   SetDeexcitationFlag(true);
 64   fAtomDeexcitation = nullptr;                 <<  65   fAtomDeexcitation = 0;
 65   fParticleChangeForGamma = nullptr;           <<  66   fParticleChangeForGamma = 0;
 66   fpMolWaterDensity = nullptr;                 <<  67   fpMolWaterDensity = 0;
 67                                                    68 
 68   // Define default angular generator              69   // Define default angular generator
 69   SetAngularDistribution(new G4DNABornAngle())     70   SetAngularDistribution(new G4DNABornAngle());
 70                                                    71 
 71   // Selection of computation method               72   // Selection of computation method
 72                                                    73 
 73   fasterCode = false;                              74   fasterCode = false;
 74                                                    75 
 75   // Selection of stationary mode                  76   // Selection of stationary mode
 76                                                    77 
 77   statCode = false;                                78   statCode = false;
 78                                                    79 
 79   // Selection of SP scaling                       80   // Selection of SP scaling
 80                                                    81 
 81   spScaling = true;                                82   spScaling = true;
 82 }                                                  83 }
 83                                                    84 
 84 //....oooOO0OOooo........oooOO0OOooo........oo     85 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 85                                                    86 
 86 G4DNABornIonisationModel1::~G4DNABornIonisatio     87 G4DNABornIonisationModel1::~G4DNABornIonisationModel1()
 87 {                                                  88 {
 88   // Cross section                                 89   // Cross section
 89                                                    90 
 90   std::map<G4String, G4DNACrossSectionDataSet*     91   std::map<G4String, G4DNACrossSectionDataSet*, std::less<G4String> >::iterator pos;
 91   for (pos = tableData.begin(); pos != tableDa     92   for (pos = tableData.begin(); pos != tableData.end(); ++pos)
 92   {                                                93   {
 93     G4DNACrossSectionDataSet* table = pos->sec     94     G4DNACrossSectionDataSet* table = pos->second;
 94     delete table;                                  95     delete table;
 95   }                                                96   }
 96                                                    97 
 97   // Final state                                   98   // Final state
 98                                                    99 
 99   eVecm.clear();                                  100   eVecm.clear();
100   pVecm.clear();                                  101   pVecm.clear();
101 }                                                 102 }
102                                                   103 
103 //....oooOO0OOooo........oooOO0OOooo........oo    104 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
104                                                   105 
105 void G4DNABornIonisationModel1::Initialise(con    106 void G4DNABornIonisationModel1::Initialise(const G4ParticleDefinition* particle,
106                                            con    107                                            const G4DataVector& /*cuts*/)
107 {                                                 108 {
108                                                   109 
109   if (verboseLevel > 3)                           110   if (verboseLevel > 3)
110   {                                               111   {
111     G4cout << "Calling G4DNABornIonisationMode    112     G4cout << "Calling G4DNABornIonisationModel1::Initialise()" << G4endl;
112   }                                               113   }
113                                                   114 
114   // Energy limits                                115   // Energy limits
115                                                   116 
116   G4String fileElectron("dna/sigma_ionisation_    117   G4String fileElectron("dna/sigma_ionisation_e_born");
117   G4String fileProton("dna/sigma_ionisation_p_    118   G4String fileProton("dna/sigma_ionisation_p_born");
118                                                   119 
119   G4ParticleDefinition* electronDef = G4Electr    120   G4ParticleDefinition* electronDef = G4Electron::ElectronDefinition();
120   G4ParticleDefinition* protonDef = G4Proton::    121   G4ParticleDefinition* protonDef = G4Proton::ProtonDefinition();
121                                                   122 
122   G4String electron;                              123   G4String electron;
123   G4String proton;                                124   G4String proton;
124                                                   125 
125   G4double scaleFactor = (1.e-22 / 3.343) * m*    126   G4double scaleFactor = (1.e-22 / 3.343) * m*m;
126                                                   127 
127   const char *path = G4FindDataDir("G4LEDATA") << 128   char *path = getenv("G4LEDATA");
128                                                   129 
129   // *** ELECTRON                                 130   // *** ELECTRON
130                                                   131 
131   electron = electronDef->GetParticleName();      132   electron = electronDef->GetParticleName();
132                                                   133 
133   tableFile[electron] = fileElectron;             134   tableFile[electron] = fileElectron;
134                                                   135 
135   lowEnergyLimit[electron] = 11. * eV;            136   lowEnergyLimit[electron] = 11. * eV;
136   highEnergyLimit[electron] = 1. * MeV;           137   highEnergyLimit[electron] = 1. * MeV;
137                                                   138 
138   // Cross section                                139   // Cross section
139                                                   140 
140   auto  tableE = new G4DNACrossSectionDataSet( << 141   G4DNACrossSectionDataSet* tableE = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, eV,scaleFactor );
141   tableE->LoadData(fileElectron);                 142   tableE->LoadData(fileElectron);
142                                                   143 
143   tableData[electron] = tableE;                   144   tableData[electron] = tableE;
144                                                   145 
145   // Final state                                  146   // Final state
146                                                   147 
147   std::ostringstream eFullFileName;               148   std::ostringstream eFullFileName;
148                                                   149 
149   if (fasterCode) eFullFileName << path << "/d    150   if (fasterCode) eFullFileName << path << "/dna/sigmadiff_cumulated_ionisation_e_born_hp.dat";
150   if (!fasterCode) eFullFileName << path << "/    151   if (!fasterCode) eFullFileName << path << "/dna/sigmadiff_ionisation_e_born.dat";
151                                                   152 
152   std::ifstream eDiffCrossSection(eFullFileNam    153   std::ifstream eDiffCrossSection(eFullFileName.str().c_str());
153                                                   154 
154   if (!eDiffCrossSection)                         155   if (!eDiffCrossSection)
155   {                                               156   {
156     if (fasterCode) G4Exception("G4DNABornIoni    157     if (fasterCode) G4Exception("G4DNABornIonisationModel1::Initialise","em0003",
157         FatalException,"Missing data file:/dna    158         FatalException,"Missing data file:/dna/sigmadiff_cumulated_ionisation_e_born_hp.dat");
158                                                   159 
159     if (!fasterCode) G4Exception("G4DNABornIon    160     if (!fasterCode) G4Exception("G4DNABornIonisationModel1::Initialise","em0003",
160         FatalException,"Missing data file:/dna    161         FatalException,"Missing data file:/dna/sigmadiff_ionisation_e_born.dat");
161   }                                               162   }
162                                                   163 
163   // Clear the arrays for re-initialization ca    164   // Clear the arrays for re-initialization case (MT mode)
164   // March 25th, 2014 - Vaclav Stepan, Sebasti    165   // March 25th, 2014 - Vaclav Stepan, Sebastien Incerti
165                                                   166 
166   eTdummyVec.clear();                             167   eTdummyVec.clear();
167   pTdummyVec.clear();                             168   pTdummyVec.clear();
168                                                   169 
169   eVecm.clear();                                  170   eVecm.clear();
170   pVecm.clear();                                  171   pVecm.clear();
171                                                   172 
172   for (G4int j=0; j<5; j++)                       173   for (G4int j=0; j<5; j++)
173   {                                               174   {
174     eProbaShellMap[j].clear();                    175     eProbaShellMap[j].clear();
175     pProbaShellMap[j].clear();                    176     pProbaShellMap[j].clear();
176                                                   177 
177     eDiffCrossSectionData[j].clear();             178     eDiffCrossSectionData[j].clear();
178     pDiffCrossSectionData[j].clear();             179     pDiffCrossSectionData[j].clear();
179                                                   180 
180     eNrjTransfData[j].clear();                    181     eNrjTransfData[j].clear();
181     pNrjTransfData[j].clear();                    182     pNrjTransfData[j].clear();
182   }                                               183   }
183                                                   184 
184   //                                              185   //
185                                                   186 
186   eTdummyVec.push_back(0.);                       187   eTdummyVec.push_back(0.);
187   while(!eDiffCrossSection.eof())                 188   while(!eDiffCrossSection.eof())
188   {                                               189   {
189     G4double tDummy;                              190     G4double tDummy;
190     G4double eDummy;                              191     G4double eDummy;
191     eDiffCrossSection>>tDummy>>eDummy;            192     eDiffCrossSection>>tDummy>>eDummy;
192     if (tDummy != eTdummyVec.back()) eTdummyVe    193     if (tDummy != eTdummyVec.back()) eTdummyVec.push_back(tDummy);
193                                                   194 
194     G4double tmp;                                 195     G4double tmp;
195     for (G4int j=0; j<5; j++)                     196     for (G4int j=0; j<5; j++)
196     {                                             197     {
197       eDiffCrossSection>> tmp;                    198       eDiffCrossSection>> tmp;
198                                                   199 
199       eDiffCrossSectionData[j][tDummy][eDummy]    200       eDiffCrossSectionData[j][tDummy][eDummy] = tmp;
200                                                   201 
201       if (fasterCode)                             202       if (fasterCode)
202       {                                           203       {
203         eNrjTransfData[j][tDummy][eDiffCrossSe    204         eNrjTransfData[j][tDummy][eDiffCrossSectionData[j][tDummy][eDummy]]=eDummy;
204         eProbaShellMap[j][tDummy].push_back(eD    205         eProbaShellMap[j][tDummy].push_back(eDiffCrossSectionData[j][tDummy][eDummy]);
205       }                                           206       }
206                                                   207 
207       // SI - only if eof is not reached          208       // SI - only if eof is not reached
208       if (!eDiffCrossSection.eof() && !fasterC    209       if (!eDiffCrossSection.eof() && !fasterCode) eDiffCrossSectionData[j][tDummy][eDummy]*=scaleFactor;
209                                                   210 
210       if (!fasterCode) eVecm[tDummy].push_back    211       if (!fasterCode) eVecm[tDummy].push_back(eDummy);
211                                                   212 
212     }                                             213     }
213   }                                               214   }
214                                                   215 
215   // *** PROTON                                   216   // *** PROTON
216                                                   217 
217   proton = protonDef->GetParticleName();          218   proton = protonDef->GetParticleName();
218                                                   219 
219   tableFile[proton] = fileProton;                 220   tableFile[proton] = fileProton;
220                                                   221 
221   lowEnergyLimit[proton] = 500. * keV;            222   lowEnergyLimit[proton] = 500. * keV;
222   highEnergyLimit[proton] = 100. * MeV;           223   highEnergyLimit[proton] = 100. * MeV;
223                                                   224 
224   // Cross section                                225   // Cross section
225                                                   226 
226   auto  tableP = new G4DNACrossSectionDataSet( << 227   G4DNACrossSectionDataSet* tableP = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, eV,scaleFactor );
227   tableP->LoadData(fileProton);                   228   tableP->LoadData(fileProton);
228                                                   229 
229   tableData[proton] = tableP;                     230   tableData[proton] = tableP;
230                                                   231 
231   // Final state                                  232   // Final state
232                                                   233 
233   std::ostringstream pFullFileName;               234   std::ostringstream pFullFileName;
234                                                   235 
235   if (fasterCode) pFullFileName << path << "/d    236   if (fasterCode) pFullFileName << path << "/dna/sigmadiff_cumulated_ionisation_p_born_hp.dat";
236                                                   237 
237   if (!fasterCode) pFullFileName << path << "/    238   if (!fasterCode) pFullFileName << path << "/dna/sigmadiff_ionisation_p_born.dat";
238                                                   239 
239   std::ifstream pDiffCrossSection(pFullFileNam    240   std::ifstream pDiffCrossSection(pFullFileName.str().c_str());
240                                                   241 
241   if (!pDiffCrossSection)                         242   if (!pDiffCrossSection)
242   {                                               243   {
243     if (fasterCode) G4Exception("G4DNABornIoni    244     if (fasterCode) G4Exception("G4DNABornIonisationModel1::Initialise","em0003",
244         FatalException,"Missing data file:/dna    245         FatalException,"Missing data file:/dna/sigmadiff_cumulated_ionisation_p_born_hp.dat");
245                                                   246 
246     if (!fasterCode) G4Exception("G4DNABornIon    247     if (!fasterCode) G4Exception("G4DNABornIonisationModel1::Initialise","em0003",
247         FatalException,"Missing data file:/dna    248         FatalException,"Missing data file:/dna/sigmadiff_ionisation_p_born.dat");
248   }                                               249   }
249                                                   250 
250   pTdummyVec.push_back(0.);                       251   pTdummyVec.push_back(0.);
251   while(!pDiffCrossSection.eof())                 252   while(!pDiffCrossSection.eof())
252   {                                               253   {
253     G4double tDummy;                              254     G4double tDummy;
254     G4double eDummy;                              255     G4double eDummy;
255     pDiffCrossSection>>tDummy>>eDummy;            256     pDiffCrossSection>>tDummy>>eDummy;
256     if (tDummy != pTdummyVec.back()) pTdummyVe    257     if (tDummy != pTdummyVec.back()) pTdummyVec.push_back(tDummy);
257     for (G4int j=0; j<5; j++)                     258     for (G4int j=0; j<5; j++)
258     {                                             259     {
259       pDiffCrossSection>>pDiffCrossSectionData    260       pDiffCrossSection>>pDiffCrossSectionData[j][tDummy][eDummy];
260                                                   261 
261       if (fasterCode)                             262       if (fasterCode)
262       {                                           263       {
263         pNrjTransfData[j][tDummy][pDiffCrossSe    264         pNrjTransfData[j][tDummy][pDiffCrossSectionData[j][tDummy][eDummy]]=eDummy;
264         pProbaShellMap[j][tDummy].push_back(pD    265         pProbaShellMap[j][tDummy].push_back(pDiffCrossSectionData[j][tDummy][eDummy]);
265       }                                           266       }
266                                                   267 
267       // SI - only if eof is not reached !        268       // SI - only if eof is not reached !
268       if (!pDiffCrossSection.eof() && !fasterC    269       if (!pDiffCrossSection.eof() && !fasterCode) pDiffCrossSectionData[j][tDummy][eDummy]*=scaleFactor;
269                                                   270 
270       if (!fasterCode) pVecm[tDummy].push_back    271       if (!fasterCode) pVecm[tDummy].push_back(eDummy);
271     }                                             272     }
272   }                                               273   }
273                                                   274 
274   //                                              275   //
275                                                   276 
276   if (particle==electronDef)                      277   if (particle==electronDef)
277   {                                               278   {
278     SetLowEnergyLimit(lowEnergyLimit[electron]    279     SetLowEnergyLimit(lowEnergyLimit[electron]);
279     SetHighEnergyLimit(highEnergyLimit[electro    280     SetHighEnergyLimit(highEnergyLimit[electron]);
280   }                                               281   }
281                                                   282 
282   if (particle==protonDef)                        283   if (particle==protonDef)
283   {                                               284   {
284     SetLowEnergyLimit(lowEnergyLimit[proton]);    285     SetLowEnergyLimit(lowEnergyLimit[proton]);
285     SetHighEnergyLimit(highEnergyLimit[proton]    286     SetHighEnergyLimit(highEnergyLimit[proton]);
286   }                                               287   }
287                                                   288 
288   if( verboseLevel>0 )                            289   if( verboseLevel>0 )
289   {                                               290   {
290     G4cout << "Born ionisation model is initia    291     G4cout << "Born ionisation model is initialized " << G4endl
291     << "Energy range: "                           292     << "Energy range: "
292     << LowEnergyLimit() / eV << " eV - "          293     << LowEnergyLimit() / eV << " eV - "
293     << HighEnergyLimit() / keV << " keV for "     294     << HighEnergyLimit() / keV << " keV for "
294     << particle->GetParticleName()                295     << particle->GetParticleName()
295     << G4endl;                                    296     << G4endl;
296   }                                               297   }
297                                                   298 
298   // Initialize water density pointer             299   // Initialize water density pointer
299                                                   300   
300   fpMolWaterDensity = G4DNAMolecularMaterial::    301   fpMolWaterDensity = G4DNAMolecularMaterial::Instance()->
301   GetNumMolPerVolTableFor(G4Material::GetMater    302   GetNumMolPerVolTableFor(G4Material::GetMaterial("G4_WATER"));
302                                                   303 
303   // AD                                           304   // AD
304                                                   305   
305   fAtomDeexcitation = G4LossTableManager::Inst    306   fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
306                                                   307 
307   //                                              308   //
308                                                   309 
309   if (isInitialised)                              310   if (isInitialised)
310   { return;}                                      311   { return;}
311   fParticleChangeForGamma = GetParticleChangeF    312   fParticleChangeForGamma = GetParticleChangeForGamma();
312   isInitialised = true;                           313   isInitialised = true;
313 }                                                 314 }
314                                                   315 
315 //....oooOO0OOooo........oooOO0OOooo........oo    316 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
316                                                   317 
317 G4double G4DNABornIonisationModel1::CrossSecti    318 G4double G4DNABornIonisationModel1::CrossSectionPerVolume(const G4Material* material,
318                                                   319                                                           const G4ParticleDefinition* particleDefinition,
319                                                   320                                                           G4double ekin,
320                                                   321                                                           G4double,
321                                                   322                                                           G4double)
322 {                                                 323 {
323   if (verboseLevel > 3)                           324   if (verboseLevel > 3)
324   {                                               325   {
325     G4cout << "Calling CrossSectionPerVolume()    326     G4cout << "Calling CrossSectionPerVolume() of G4DNABornIonisationModel1"
326         << G4endl;                                327         << G4endl;
327   }                                               328   }
328                                                   329 
329   if (                                            330   if (
330       particleDefinition != G4Proton::ProtonDe    331       particleDefinition != G4Proton::ProtonDefinition()
331       &&                                          332       &&
332       particleDefinition != G4Electron::Electr    333       particleDefinition != G4Electron::ElectronDefinition()
333   )                                               334   )
334                                                   335 
335   return 0;                                       336   return 0;
336                                                   337 
337   // Calculate total cross section for model      338   // Calculate total cross section for model
338                                                   339 
339   G4double lowLim = 0;                            340   G4double lowLim = 0;
340   G4double highLim = 0;                           341   G4double highLim = 0;
341   G4double sigma=0;                               342   G4double sigma=0;
342                                                   343 
343   G4double waterDensity = (*fpMolWaterDensity)    344   G4double waterDensity = (*fpMolWaterDensity)[material->GetIndex()];
344                                                   345 
345   const G4String& particleName = particleDefin << 346   if(waterDensity!= 0.0)
346                                                << 347   //  if (material == nistwater || material->GetBaseMaterial() == nistwater)
347   std::map< G4String,G4double,std::less<G4Stri << 
348   pos1 = lowEnergyLimit.find(particleName);    << 
349   if (pos1 != lowEnergyLimit.end())            << 
350   {                                               348   {
351     lowLim = pos1->second;                     << 349     const G4String& particleName = particleDefinition->GetParticleName();
352   }                                            << 
353                                                   350 
354   std::map< G4String,G4double,std::less<G4Stri << 351     std::map< G4String,G4double,std::less<G4String> >::iterator pos1;
355   pos2 = highEnergyLimit.find(particleName);   << 352     pos1 = lowEnergyLimit.find(particleName);
356   if (pos2 != highEnergyLimit.end())           << 353     if (pos1 != lowEnergyLimit.end())
357   {                                            << 354     {
358     highLim = pos2->second;                    << 355       lowLim = pos1->second;
359   }                                            << 356     }
360                                                   357 
361   if (ekin >= lowLim && ekin <= highLim)       << 358     std::map< G4String,G4double,std::less<G4String> >::iterator pos2;
362   {                                            << 359     pos2 = highEnergyLimit.find(particleName);
363     std::map< G4String,G4DNACrossSectionDataSe << 360     if (pos2 != highEnergyLimit.end())
364     pos = tableData.find(particleName);        << 361     {
                                                   >> 362       highLim = pos2->second;
                                                   >> 363     }
365                                                   364 
366     if (pos != tableData.end())                << 365     if (ekin >= lowLim && ekin < highLim)
367     {                                             366     {
368       G4DNACrossSectionDataSet* table = pos->s << 367       std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
369       if (table != nullptr)                    << 368       pos = tableData.find(particleName);
                                                   >> 369 
                                                   >> 370       if (pos != tableData.end())
370       {                                           371       {
371         sigma = table->FindValue(ekin);        << 372         G4DNACrossSectionDataSet* table = pos->second;
                                                   >> 373         if (table != 0)
                                                   >> 374         {
                                                   >> 375           sigma = table->FindValue(ekin);
372                                                   376 
373         // ICRU49 electronic SP scaling - ZF,  << 377           // ICRU49 electronic SP scaling - ZF, SI
374                                                   378 
375         if (particleDefinition == G4Proton::Pr << 379           if (particleDefinition == G4Proton::ProtonDefinition() && ekin < 70*MeV && spScaling)
376         {                                      << 380           {
377          G4double A = 1.39241700556072800000E- << 381            G4double A = 1.39241700556072800000E-009 ;
378          G4double B = -8.52610412942622630000E << 382            G4double B = -8.52610412942622630000E-002 ;
379          sigma = sigma * G4Exp(A*(ekin/eV)+B); << 383            sigma = sigma * G4Exp(A*(ekin/eV)+B);
380         }                                      << 384           }
381         //                                     << 385           //
382                                                   386 
                                                   >> 387         }
                                                   >> 388       }
                                                   >> 389       else
                                                   >> 390       {
                                                   >> 391         G4Exception("G4DNABornIonisationModel1::CrossSectionPerVolume","em0002",
                                                   >> 392             FatalException,"Model not applicable to particle type.");
383       }                                           393       }
384     }                                             394     }
385     else                                       << 395 
                                                   >> 396     if (verboseLevel > 2)
386     {                                             397     {
387       G4Exception("G4DNABornIonisationModel1:: << 398       G4cout << "__________________________________" << G4endl;
388           FatalException,"Model not applicable << 399       G4cout << "G4DNABornIonisationModel1 - XS INFO START" << G4endl;
                                                   >> 400       G4cout << "Kinetic energy(eV)=" << ekin/eV << " particle : " << particleName << G4endl;
                                                   >> 401       G4cout << "Cross section per water molecule (cm^2)=" << sigma/cm/cm << G4endl;
                                                   >> 402       G4cout << "Cross section per water molecule (cm^-1)=" << sigma*waterDensity/(1./cm) << G4endl;
                                                   >> 403       G4cout << "G4DNABornIonisationModel1 - XS INFO END" << G4endl;
389     }                                             404     }
390   }                                            << 405   } // if (waterMaterial)
391                                                << 
392   if (verboseLevel > 2)                        << 
393   {                                            << 
394     G4cout << "_______________________________ << 
395     G4cout << "G4DNABornIonisationModel1 - XS  << 
396     G4cout << "Kinetic energy(eV)=" << ekin/eV << 
397     G4cout << "Cross section per water molecul << 
398     G4cout << "Cross section per water molecul << 
399     G4cout << "G4DNABornIonisationModel1 - XS  << 
400   }                                            << 
401                                                   406 
402   return sigma*waterDensity;                      407   return sigma*waterDensity;
403 }                                                 408 }
404                                                   409 
405 //....oooOO0OOooo........oooOO0OOooo........oo    410 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
406                                                   411 
407 void G4DNABornIonisationModel1::SampleSecondar    412 void G4DNABornIonisationModel1::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
408                                                   413                                                   const G4MaterialCutsCouple* couple,
409                                                   414                                                   const G4DynamicParticle* particle,
410                                                   415                                                   G4double,
411                                                   416                                                   G4double)
412 {                                                 417 {
413                                                   418 
414   if (verboseLevel > 3)                           419   if (verboseLevel > 3)
415   {                                               420   {
416     G4cout << "Calling SampleSecondaries() of     421     G4cout << "Calling SampleSecondaries() of G4DNABornIonisationModel1"
417         << G4endl;                                422         << G4endl;
418   }                                               423   }
419                                                   424 
420   G4double lowLim = 0;                            425   G4double lowLim = 0;
421   G4double highLim = 0;                           426   G4double highLim = 0;
422                                                   427 
423   G4double k = particle->GetKineticEnergy();      428   G4double k = particle->GetKineticEnergy();
424                                                   429 
425   const G4String& particleName = particle->Get    430   const G4String& particleName = particle->GetDefinition()->GetParticleName();
426                                                   431 
427   std::map< G4String,G4double,std::less<G4Stri    432   std::map< G4String,G4double,std::less<G4String> >::iterator pos1;
428   pos1 = lowEnergyLimit.find(particleName);       433   pos1 = lowEnergyLimit.find(particleName);
429                                                   434 
430   if (pos1 != lowEnergyLimit.end())               435   if (pos1 != lowEnergyLimit.end())
431   {                                               436   {
432     lowLim = pos1->second;                        437     lowLim = pos1->second;
433   }                                               438   }
434                                                   439 
435   std::map< G4String,G4double,std::less<G4Stri    440   std::map< G4String,G4double,std::less<G4String> >::iterator pos2;
436   pos2 = highEnergyLimit.find(particleName);      441   pos2 = highEnergyLimit.find(particleName);
437                                                   442 
438   if (pos2 != highEnergyLimit.end())              443   if (pos2 != highEnergyLimit.end())
439   {                                               444   {
440     highLim = pos2->second;                       445     highLim = pos2->second;
441   }                                               446   }
442                                                   447 
443   if (k >= lowLim && k <= highLim)             << 448   if (k >= lowLim && k < highLim)
444   {                                               449   {
445     G4ParticleMomentum primaryDirection = part    450     G4ParticleMomentum primaryDirection = particle->GetMomentumDirection();
446     G4double particleMass = particle->GetDefin    451     G4double particleMass = particle->GetDefinition()->GetPDGMass();
447     G4double totalEnergy = k + particleMass;      452     G4double totalEnergy = k + particleMass;
448     G4double pSquare = k * (totalEnergy + part    453     G4double pSquare = k * (totalEnergy + particleMass);
449     G4double totalMomentum = std::sqrt(pSquare    454     G4double totalMomentum = std::sqrt(pSquare);
450                                                   455 
451     G4int ionizationShell = 0;                    456     G4int ionizationShell = 0;
452                                                   457 
453     if (!fasterCode) ionizationShell = RandomS    458     if (!fasterCode) ionizationShell = RandomSelect(k,particleName);
454                                                   459 
455     // SI: The following protection is necessa    460     // SI: The following protection is necessary to avoid infinite loops :
456     //  sigmadiff_ionisation_e_born.dat has no    461     //  sigmadiff_ionisation_e_born.dat has non zero partial xs at 18 eV for shell 3 (ionizationShell ==2)
457     //  sigmadiff_cumulated_ionisation_e_born.    462     //  sigmadiff_cumulated_ionisation_e_born.dat has zero cumulated partial xs at 18 eV for shell 3 (ionizationShell ==2)
458     //  this is due to the fact that the max a    463     //  this is due to the fact that the max allowed transfered energy is (18+10.79)/2=17.025 eV and only transfered energies
459     //  strictly above this value have non zer    464     //  strictly above this value have non zero partial xs in sigmadiff_ionisation_e_born.dat (starting at trans = 17.12 eV)
460                                                   465 
461     if (fasterCode)                               466     if (fasterCode)
462     do                                            467     do
463     {                                             468     {
464       ionizationShell = RandomSelect(k,particl    469       ionizationShell = RandomSelect(k,particleName);
465     } while (k<19*eV && ionizationShell==2 &&  << 470     }while (k<19*eV && ionizationShell==2 && particle->GetDefinition()==G4Electron::ElectronDefinition());
466                                                   471 
467     G4double bindingEnergy = 0;                   472     G4double bindingEnergy = 0;
468     bindingEnergy = waterStructure.IonisationE    473     bindingEnergy = waterStructure.IonisationEnergy(ionizationShell);
469                                                   474 
470     // SI: additional protection if tcs interp    475     // SI: additional protection if tcs interpolation method is modified
471     if (k<bindingEnergy) return;                  476     if (k<bindingEnergy) return;
472     //                                            477     //
473                                                   478 
474     G4double secondaryKinetic=-1000*eV;           479     G4double secondaryKinetic=-1000*eV;
475                                                   480 
476     if (!fasterCode)                           << 481     if (fasterCode == false)
477     {                                             482     {
478       secondaryKinetic = RandomizeEjectedElect    483       secondaryKinetic = RandomizeEjectedElectronEnergy(particle->GetDefinition(),k,ionizationShell);
479     }                                             484     }
480     else                                          485     else
481     {                                             486     {
482       secondaryKinetic = RandomizeEjectedElect    487       secondaryKinetic = RandomizeEjectedElectronEnergyFromCumulatedDcs(particle->GetDefinition(),k,ionizationShell);
483     }                                             488     }
484     //                                            489     //
485                                                   490 
486     G4int Z = 8;                                  491     G4int Z = 8;
487                                                   492     
488     G4ThreeVector deltaDirection =                493     G4ThreeVector deltaDirection =
489     GetAngularDistribution()->SampleDirectionF    494     GetAngularDistribution()->SampleDirectionForShell(particle, secondaryKinetic,
490         Z, ionizationShell,                       495         Z, ionizationShell,
491         couple->GetMaterial());                   496         couple->GetMaterial());
492                                                   497 
493     if (secondaryKinetic>0)                       498     if (secondaryKinetic>0)
494     {                                             499     {
495       auto  dp = new G4DynamicParticle (G4Elec << 500       G4DynamicParticle* dp = new G4DynamicParticle (G4Electron::Electron(),deltaDirection,secondaryKinetic);
496       fvect->push_back(dp);                       501       fvect->push_back(dp);
497     }                                             502     }
498                                                   503 
499     if (particle->GetDefinition() == G4Electro    504     if (particle->GetDefinition() == G4Electron::ElectronDefinition())
500     {                                             505     {
501       G4double deltaTotalMomentum = std::sqrt(    506       G4double deltaTotalMomentum = std::sqrt(secondaryKinetic*(secondaryKinetic + 2.*electron_mass_c2 ));
502                                                   507 
503       G4double finalPx = totalMomentum*primary    508       G4double finalPx = totalMomentum*primaryDirection.x() - deltaTotalMomentum*deltaDirection.x();
504       G4double finalPy = totalMomentum*primary    509       G4double finalPy = totalMomentum*primaryDirection.y() - deltaTotalMomentum*deltaDirection.y();
505       G4double finalPz = totalMomentum*primary    510       G4double finalPz = totalMomentum*primaryDirection.z() - deltaTotalMomentum*deltaDirection.z();
506       G4double finalMomentum = std::sqrt(final    511       G4double finalMomentum = std::sqrt(finalPx*finalPx + finalPy*finalPy + finalPz*finalPz);
507       finalPx /= finalMomentum;                   512       finalPx /= finalMomentum;
508       finalPy /= finalMomentum;                   513       finalPy /= finalMomentum;
509       finalPz /= finalMomentum;                   514       finalPz /= finalMomentum;
510                                                   515 
511       G4ThreeVector direction;                    516       G4ThreeVector direction;
512       direction.set(finalPx,finalPy,finalPz);     517       direction.set(finalPx,finalPy,finalPz);
513                                                   518 
514       fParticleChangeForGamma->ProposeMomentum    519       fParticleChangeForGamma->ProposeMomentumDirection(direction.unit());
515     }                                             520     }
516                                                   521 
517     else fParticleChangeForGamma->ProposeMomen    522     else fParticleChangeForGamma->ProposeMomentumDirection(primaryDirection);
518                                                   523 
519     // AM: sample deexcitation                    524     // AM: sample deexcitation
520     // here we assume that H_{2}O electronic l    525     // here we assume that H_{2}O electronic levels are the same as Oxygen.
521     // this can be considered true with a roug    526     // this can be considered true with a rough 10% error in energy on K-shell,
522                                                   527 
523     std::size_t secNumberInit = 0;// need to k << 528     G4int secNumberInit = 0;// need to know at a certain point the energy of secondaries
524     std::size_t secNumberFinal = 0;// So I'll  << 529     G4int secNumberFinal = 0;// So I'll make the diference and then sum the energies
525                                                   530 
526     G4double scatteredEnergy = k-bindingEnergy << 531     if(fAtomDeexcitation)
527                                                << 
528     // SI: only atomic deexcitation from K she << 
529     if((fAtomDeexcitation != nullptr) && ioniz << 
530     {                                             532     {
531       const G4AtomicShell* shell =             << 533       G4AtomicShellEnumerator as = fKShell;
532         fAtomDeexcitation->GetAtomicShell(Z, G << 
533       secNumberInit = fvect->size();           << 
534       fAtomDeexcitation->GenerateParticles(fve << 
535       secNumberFinal = fvect->size();          << 
536                                                << 
537       //TEST                                   << 
538       //G4cout << "ionizationShell=" << ioniza << 
539       //G4cout << "bindingEnergy=" << bindingE << 
540                                                   534 
541       if(secNumberFinal > secNumberInit)       << 535       if (ionizationShell <5 && ionizationShell >1)
542       {                                           536       {
543   for (std::size_t i=secNumberInit; i<secNumbe << 537         as = G4AtomicShellEnumerator(4-ionizationShell);
544         {                                      << 538       }
545           //Check if there is enough residual  << 539       else if (ionizationShell <2)
546           if (bindingEnergy >= ((*fvect)[i])-> << 540       {
547           {                                    << 541         as = G4AtomicShellEnumerator(3);
548              //Ok, this is a valid secondary:  << 
549        bindingEnergy -= ((*fvect)[i])->GetKine << 
550        //G4cout << "--deex nrj=" << ((*fvect)[ << 
551        //<< G4endl;                            << 
552           }                                    << 
553           else                                 << 
554           {                                    << 
555        //Invalid secondary: not enough energy  << 
556        //Keep its energy in the local deposit  << 
557              delete (*fvect)[i];               << 
558              (*fvect)[i]=nullptr;              << 
559           }                                    << 
560   }                                            << 
561       }                                           542       }
562                                                   543 
563     //TEST                                     << 544       //  FOR DEBUG ONLY
564     //G4cout << "k=" << k/eV<< G4endl;         << 545       //  if (ionizationShell == 4) {
565     //G4cout << "secondaryKinetic=" << seconda << 546       //
566     //G4cout << "scatteredEnergy=" << scattere << 547       //    G4cout << "Z: " << Z << " as: " << as
567     //G4cout << "deposited energy=" << binding << 548       //               << " ionizationShell: " << ionizationShell << " bindingEnergy: "<< bindingEnergy/eV << G4endl;
568     //                                         << 549       //        G4cout << "Press <Enter> key to continue..." << G4endl;
                                                   >> 550       //    G4cin.ignore();
                                                   >> 551       //  }
569                                                   552 
                                                   >> 553       const G4AtomicShell* shell = fAtomDeexcitation->GetAtomicShell(Z, as);
                                                   >> 554       secNumberInit = fvect->size();
                                                   >> 555       fAtomDeexcitation->GenerateParticles(fvect, shell, Z, 0, 0);
                                                   >> 556       secNumberFinal = fvect->size();
                                                   >> 557     }
                                                   >> 558 
                                                   >> 559     // Note that secondaryKinetic is the energy of the delta ray, not of all secondaries.
                                                   >> 560 
                                                   >> 561     G4double scatteredEnergy = k-bindingEnergy-secondaryKinetic;
                                                   >> 562     G4double deexSecEnergy = 0;
                                                   >> 563     for (G4int j=secNumberInit; j < secNumberFinal; j++)
                                                   >> 564     {
                                                   >> 565       deexSecEnergy = deexSecEnergy + (*fvect)[j]->GetKineticEnergy();
570     }                                             566     }
571                                                   567 
572     //This should never happen                 << 
573     if(bindingEnergy < 0.0)                    << 
574      G4Exception("G4DNABornIonisatioModel1::Sa << 
575                  "em2050",FatalException,"Nega << 
576                                                << 
577     //bindingEnergy has been decreased         << 
578     //by the amount of energy taken away by de << 
579     if (!statCode)                                568     if (!statCode)
580     {                                             569     {
581       fParticleChangeForGamma->SetProposedKine    570       fParticleChangeForGamma->SetProposedKineticEnergy(scatteredEnergy);
582       fParticleChangeForGamma->ProposeLocalEne << 571       fParticleChangeForGamma->ProposeLocalEnergyDeposit(k-scatteredEnergy-secondaryKinetic-deexSecEnergy);
583     }                                             572     }
584     else                                          573     else
585     {                                             574     {
586       fParticleChangeForGamma->SetProposedKine    575       fParticleChangeForGamma->SetProposedKineticEnergy(k);
587       fParticleChangeForGamma->ProposeLocalEne    576       fParticleChangeForGamma->ProposeLocalEnergyDeposit(k-scatteredEnergy);
588     }                                             577     }
589                                                   578 
590     // TEST //////////////////////////            579     // TEST //////////////////////////
591     // if (secondaryKinetic<0) abort();           580     // if (secondaryKinetic<0) abort();
592     // if (scatteredEnergy<0) abort();            581     // if (scatteredEnergy<0) abort();
593     // if (k-scatteredEnergy-secondaryKinetic-    582     // if (k-scatteredEnergy-secondaryKinetic-deexSecEnergy<0) abort();
594     // if (k-scatteredEnergy<0) abort();          583     // if (k-scatteredEnergy<0) abort();
595     /////////////////////////////////             584     /////////////////////////////////
596                                                   585     
597     const G4Track * theIncomingTrack = fPartic    586     const G4Track * theIncomingTrack = fParticleChangeForGamma->GetCurrentTrack();
598     G4DNAChemistryManager::Instance()->CreateW    587     G4DNAChemistryManager::Instance()->CreateWaterMolecule(eIonizedMolecule,
599         ionizationShell,                          588         ionizationShell,
600         theIncomingTrack);                        589         theIncomingTrack);
601   }                                               590   }
602 }                                                 591 }
603                                                   592 
604 //....oooOO0OOooo........oooOO0OOooo........oo    593 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
605                                                   594 
606 G4double G4DNABornIonisationModel1::RandomizeE    595 G4double G4DNABornIonisationModel1::RandomizeEjectedElectronEnergy(G4ParticleDefinition* particleDefinition,
607                                                   596                                                                    G4double k,
608                                                   597                                                                    G4int shell)
609 {                                                 598 {
610   // G4cout << "*** SLOW computation for " <<     599   // G4cout << "*** SLOW computation for " << " " << particleDefinition->GetParticleName() << G4endl;
611                                                   600 
612   if (particleDefinition == G4Electron::Electr    601   if (particleDefinition == G4Electron::ElectronDefinition())
613   {                                               602   {
614     G4double maximumEnergyTransfer = 0.;          603     G4double maximumEnergyTransfer = 0.;
615     if ((k + waterStructure.IonisationEnergy(s    604     if ((k + waterStructure.IonisationEnergy(shell)) / 2. > k)
616       maximumEnergyTransfer = k;                  605       maximumEnergyTransfer = k;
617     else                                          606     else
618       maximumEnergyTransfer = (k + waterStruct    607       maximumEnergyTransfer = (k + waterStructure.IonisationEnergy(shell)) / 2.;
619                                                   608 
620     // SI : original method                       609     // SI : original method
621     /*                                            610     /*
622     G4double crossSectionMaximum = 0.;         << 611      G4double crossSectionMaximum = 0.;
623     for(G4double value=waterStructure.Ionisati << 612      for(G4double value=waterStructure.IonisationEnergy(shell); value<=maximumEnergyTransfer; value+=0.1*eV)
624     {                                          << 613      {
625      G4double differentialCrossSection = Diffe    614      G4double differentialCrossSection = DifferentialCrossSection(particleDefinition, k/eV, value/eV, shell);
626      if(differentialCrossSection >= crossSecti    615      if(differentialCrossSection >= crossSectionMaximum) crossSectionMaximum = differentialCrossSection;
627     }                                          << 616      }
628     */                                         << 617      */
629                                                   618 
630     // SI : alternative method                    619     // SI : alternative method
631     G4double crossSectionMaximum = 0.;            620     G4double crossSectionMaximum = 0.;
632                                                   621 
633     G4double minEnergy = waterStructure.Ionisa    622     G4double minEnergy = waterStructure.IonisationEnergy(shell);
634     G4double maxEnergy = maximumEnergyTransfer    623     G4double maxEnergy = maximumEnergyTransfer;
635     G4int nEnergySteps = 50;                      624     G4int nEnergySteps = 50;
636                                                   625 
637     G4double value(minEnergy);                    626     G4double value(minEnergy);
638     G4double stpEnergy(std::pow(maxEnergy / va    627     G4double stpEnergy(std::pow(maxEnergy / value,
639                                 1. / static_ca    628                                 1. / static_cast<G4double>(nEnergySteps - 1)));
640     G4int step(nEnergySteps);                     629     G4int step(nEnergySteps);
641     while (step > 0)                              630     while (step > 0)
642     {                                             631     {
643       step--;                                     632       step--;
644       G4double differentialCrossSection =         633       G4double differentialCrossSection =
645           DifferentialCrossSection(particleDef    634           DifferentialCrossSection(particleDefinition,
646                                    k / eV,        635                                    k / eV,
647                                    value / eV,    636                                    value / eV,
648                                    shell);        637                                    shell);
649       if (differentialCrossSection >= crossSec    638       if (differentialCrossSection >= crossSectionMaximum)
650         crossSectionMaximum = differentialCros    639         crossSectionMaximum = differentialCrossSection;
651       value *= stpEnergy;                         640       value *= stpEnergy;
652     }                                             641     }
653     //                                            642     //
654                                                   643 
655     G4double secondaryElectronKineticEnergy =     644     G4double secondaryElectronKineticEnergy = 0.;
656     do                                            645     do
657     {                                             646     {
658       secondaryElectronKineticEnergy = G4Unifo    647       secondaryElectronKineticEnergy = G4UniformRand()* (maximumEnergyTransfer-waterStructure.IonisationEnergy(shell));
659     } while(G4UniformRand()*crossSectionMaximu << 648     }while(G4UniformRand()*crossSectionMaximum >
660         DifferentialCrossSection(particleDefin    649         DifferentialCrossSection(particleDefinition, k/eV,
661             (secondaryElectronKineticEnergy+wa    650             (secondaryElectronKineticEnergy+waterStructure.IonisationEnergy(shell))/eV,shell));
662                                                   651 
663     return secondaryElectronKineticEnergy;        652     return secondaryElectronKineticEnergy;
664                                                   653 
665   }                                               654   }
666                                                   655 
667   if (particleDefinition == G4Proton::ProtonDe << 656   else if (particleDefinition == G4Proton::ProtonDefinition())
668   {                                               657   {
669     G4double maximumKineticEnergyTransfer = 4.    658     G4double maximumKineticEnergyTransfer = 4.
670         * (electron_mass_c2 / proton_mass_c2)     659         * (electron_mass_c2 / proton_mass_c2) * k;
671                                                   660 
672     G4double crossSectionMaximum = 0.;            661     G4double crossSectionMaximum = 0.;
673     for (G4double value = waterStructure.Ionis    662     for (G4double value = waterStructure.IonisationEnergy(shell);
674         value <= 4. * waterStructure.Ionisatio    663         value <= 4. * waterStructure.IonisationEnergy(shell); value += 0.1 * eV)
675     {                                             664     {
676       G4double differentialCrossSection =         665       G4double differentialCrossSection =
677           DifferentialCrossSection(particleDef    666           DifferentialCrossSection(particleDefinition,
678                                    k / eV,        667                                    k / eV,
679                                    value / eV,    668                                    value / eV,
680                                    shell);        669                                    shell);
681       if (differentialCrossSection >= crossSec    670       if (differentialCrossSection >= crossSectionMaximum)
682         crossSectionMaximum = differentialCros    671         crossSectionMaximum = differentialCrossSection;
683     }                                             672     }
684                                                   673 
685     G4double secondaryElectronKineticEnergy =     674     G4double secondaryElectronKineticEnergy = 0.;
686     do                                            675     do
687     {                                             676     {
688       secondaryElectronKineticEnergy = G4Unifo    677       secondaryElectronKineticEnergy = G4UniformRand()* maximumKineticEnergyTransfer;
689     } while(G4UniformRand()*crossSectionMaximu << 678     }while(G4UniformRand()*crossSectionMaximum >=
690         DifferentialCrossSection(particleDefin    679         DifferentialCrossSection(particleDefinition, k/eV,
691             (secondaryElectronKineticEnergy+wa    680             (secondaryElectronKineticEnergy+waterStructure.IonisationEnergy(shell))/eV,shell));
692                                                   681 
693     return secondaryElectronKineticEnergy;        682     return secondaryElectronKineticEnergy;
694   }                                               683   }
695                                                   684 
696   return 0;                                       685   return 0;
697 }                                                 686 }
698                                                   687 
699 //....oooOO0OOooo........oooOO0OOooo........oo    688 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
700                                                   689 
701 // The following section is not used anymore b    690 // The following section is not used anymore but is kept for memory
702 // GetAngularDistribution()->SampleDirectionFo    691 // GetAngularDistribution()->SampleDirectionForShell is used instead
703                                                   692 
704 /*                                                693 /*
705  void G4DNABornIonisationModel1::RandomizeEjec    694  void G4DNABornIonisationModel1::RandomizeEjectedElectronDirection(G4ParticleDefinition* particleDefinition,
706  G4double k,                                      695  G4double k,
707  G4double secKinetic,                             696  G4double secKinetic,
708  G4double & cosTheta,                             697  G4double & cosTheta,
709  G4double & phi )                                 698  G4double & phi )
710  {                                                699  {
711  if (particleDefinition == G4Electron::Electro    700  if (particleDefinition == G4Electron::ElectronDefinition())
712  {                                                701  {
713  phi = twopi * G4UniformRand();                   702  phi = twopi * G4UniformRand();
714  if (secKinetic < 50.*eV) cosTheta = (2.*G4Uni    703  if (secKinetic < 50.*eV) cosTheta = (2.*G4UniformRand())-1.;
715  else if (secKinetic <= 200.*eV)                  704  else if (secKinetic <= 200.*eV)
716  {                                                705  {
717  if (G4UniformRand() <= 0.1) cosTheta = (2.*G4    706  if (G4UniformRand() <= 0.1) cosTheta = (2.*G4UniformRand())-1.;
718  else cosTheta = G4UniformRand()*(std::sqrt(2.    707  else cosTheta = G4UniformRand()*(std::sqrt(2.)/2);
719  }                                                708  }
720  else                                             709  else
721  {                                                710  {
722  G4double sin2O = (1.-secKinetic/k) / (1.+secK    711  G4double sin2O = (1.-secKinetic/k) / (1.+secKinetic/(2.*electron_mass_c2));
723  cosTheta = std::sqrt(1.-sin2O);                  712  cosTheta = std::sqrt(1.-sin2O);
724  }                                                713  }
725  }                                                714  }
726                                                   715 
727  else if (particleDefinition == G4Proton::Prot    716  else if (particleDefinition == G4Proton::ProtonDefinition())
728  {                                                717  {
729  G4double maxSecKinetic = 4.* (electron_mass_c    718  G4double maxSecKinetic = 4.* (electron_mass_c2 / proton_mass_c2) * k;
730  phi = twopi * G4UniformRand();                   719  phi = twopi * G4UniformRand();
731                                                   720 
732  // cosTheta = std::sqrt(secKinetic / maxSecKi    721  // cosTheta = std::sqrt(secKinetic / maxSecKinetic);
733                                                   722 
734  // Restriction below 100 eV from Emfietzoglou    723  // Restriction below 100 eV from Emfietzoglou (2000)
735                                                   724 
736  if (secKinetic>100*eV) cosTheta = std::sqrt(s    725  if (secKinetic>100*eV) cosTheta = std::sqrt(secKinetic / maxSecKinetic);
737  else cosTheta = (2.*G4UniformRand())-1.;         726  else cosTheta = (2.*G4UniformRand())-1.;
738                                                   727 
739  }                                                728  }
740  }                                                729  }
741  */                                               730  */
742                                                   731 
743 //....oooOO0OOooo........oooOO0OOooo........oo    732 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
744 G4double G4DNABornIonisationModel1::Differenti    733 G4double G4DNABornIonisationModel1::DifferentialCrossSection(G4ParticleDefinition * particleDefinition,
745                                                   734                                                            G4double k,
746                                                   735                                                            G4double energyTransfer,
747                                                   736                                                            G4int ionizationLevelIndex)
748 {                                                 737 {
749   G4double sigma = 0.;                            738   G4double sigma = 0.;
750                                                   739 
751   if (energyTransfer >= waterStructure.Ionisat    740   if (energyTransfer >= waterStructure.IonisationEnergy(ionizationLevelIndex)/eV)
752   {                                               741   {
753     G4double valueT1 = 0;                         742     G4double valueT1 = 0;
754     G4double valueT2 = 0;                         743     G4double valueT2 = 0;
755     G4double valueE21 = 0;                        744     G4double valueE21 = 0;
756     G4double valueE22 = 0;                        745     G4double valueE22 = 0;
757     G4double valueE12 = 0;                        746     G4double valueE12 = 0;
758     G4double valueE11 = 0;                        747     G4double valueE11 = 0;
759                                                   748 
760     G4double xs11 = 0;                            749     G4double xs11 = 0;
761     G4double xs12 = 0;                            750     G4double xs12 = 0;
762     G4double xs21 = 0;                            751     G4double xs21 = 0;
763     G4double xs22 = 0;                            752     G4double xs22 = 0;
764                                                   753 
765     if (particleDefinition == G4Electron::Elec    754     if (particleDefinition == G4Electron::ElectronDefinition())
766     {                                             755     {
767                                                << 
768       // Protection against out of boundary ac << 
769       if (k==eTdummyVec.back()) k=k*(1.-1e-12) << 
770       //                                       << 
771                                                << 
772       // k should be in eV and energy transfer    756       // k should be in eV and energy transfer eV also
773                                                   757 
774       auto t2 = std::upper_bound(eTdummyVec.be << 758       std::vector<G4double>::iterator t2 = std::upper_bound(eTdummyVec.begin(),
775                                                   759                                                           eTdummyVec.end(),
776                                                   760                                                           k);
777                                                   761 
778       auto t1 = t2 - 1;                        << 762       std::vector<G4double>::iterator t1 = t2 - 1;
779                                                   763 
780       // SI : the following condition avoids s    764       // SI : the following condition avoids situations where energyTransfer >last vector element
781       if (energyTransfer <= eVecm[(*t1)].back(    765       if (energyTransfer <= eVecm[(*t1)].back()
782           && energyTransfer <= eVecm[(*t2)].ba    766           && energyTransfer <= eVecm[(*t2)].back())
783       {                                           767       {
784         auto e12 =                             << 768         std::vector<G4double>::iterator e12 =
785             std::upper_bound(eVecm[(*t1)].begi    769             std::upper_bound(eVecm[(*t1)].begin(),
786                              eVecm[(*t1)].end(    770                              eVecm[(*t1)].end(),
787                              energyTransfer);     771                              energyTransfer);
788         auto e11 = e12 - 1;                    << 772         std::vector<G4double>::iterator e11 = e12 - 1;
789                                                   773 
790         auto e22 =                             << 774         std::vector<G4double>::iterator e22 =
791             std::upper_bound(eVecm[(*t2)].begi    775             std::upper_bound(eVecm[(*t2)].begin(),
792                              eVecm[(*t2)].end(    776                              eVecm[(*t2)].end(),
793                              energyTransfer);     777                              energyTransfer);
794         auto e21 = e22 - 1;                    << 778         std::vector<G4double>::iterator e21 = e22 - 1;
795                                                   779 
796         valueT1 = *t1;                            780         valueT1 = *t1;
797         valueT2 = *t2;                            781         valueT2 = *t2;
798         valueE21 = *e21;                          782         valueE21 = *e21;
799         valueE22 = *e22;                          783         valueE22 = *e22;
800         valueE12 = *e12;                          784         valueE12 = *e12;
801         valueE11 = *e11;                          785         valueE11 = *e11;
802                                                   786 
803         xs11 = eDiffCrossSectionData[ionizatio    787         xs11 = eDiffCrossSectionData[ionizationLevelIndex][valueT1][valueE11];
804         xs12 = eDiffCrossSectionData[ionizatio    788         xs12 = eDiffCrossSectionData[ionizationLevelIndex][valueT1][valueE12];
805         xs21 = eDiffCrossSectionData[ionizatio    789         xs21 = eDiffCrossSectionData[ionizationLevelIndex][valueT2][valueE21];
806         xs22 = eDiffCrossSectionData[ionizatio    790         xs22 = eDiffCrossSectionData[ionizationLevelIndex][valueT2][valueE22];
807                                                   791 
808       }                                           792       }
809                                                   793 
810     }                                             794     }
811                                                   795 
812     if (particleDefinition == G4Proton::Proton    796     if (particleDefinition == G4Proton::ProtonDefinition())
813     {                                             797     {
814       // Protection against out of boundary ac << 
815       if (k==pTdummyVec.back()) k=k*(1.-1e-12) << 
816       //                                       << 
817                                                << 
818       // k should be in eV and energy transfer    798       // k should be in eV and energy transfer eV also
819       auto t2 = std::upper_bound(pTdummyVec.be << 799       std::vector<G4double>::iterator t2 = std::upper_bound(pTdummyVec.begin(),
820                                                   800                                                           pTdummyVec.end(),
821                                                   801                                                           k);
822       auto t1 = t2 - 1;                        << 802       std::vector<G4double>::iterator t1 = t2 - 1;
823                                                   803 
824       auto e12 = std::upper_bound(pVecm[(*t1)] << 804       std::vector<G4double>::iterator e12 = std::upper_bound(pVecm[(*t1)].begin(),
825                                                   805                                                            pVecm[(*t1)].end(),
826                                                   806                                                            energyTransfer);
827       auto e11 = e12 - 1;                      << 807       std::vector<G4double>::iterator e11 = e12 - 1;
828                                                   808 
829       auto e22 = std::upper_bound(pVecm[(*t2)] << 809       std::vector<G4double>::iterator e22 = std::upper_bound(pVecm[(*t2)].begin(),
830                                                   810                                                            pVecm[(*t2)].end(),
831                                                   811                                                            energyTransfer);
832       auto e21 = e22 - 1;                      << 812       std::vector<G4double>::iterator e21 = e22 - 1;
833                                                   813 
834       valueT1 = *t1;                              814       valueT1 = *t1;
835       valueT2 = *t2;                              815       valueT2 = *t2;
836       valueE21 = *e21;                            816       valueE21 = *e21;
837       valueE22 = *e22;                            817       valueE22 = *e22;
838       valueE12 = *e12;                            818       valueE12 = *e12;
839       valueE11 = *e11;                            819       valueE11 = *e11;
840                                                   820 
841       xs11 = pDiffCrossSectionData[ionizationL    821       xs11 = pDiffCrossSectionData[ionizationLevelIndex][valueT1][valueE11];
842       xs12 = pDiffCrossSectionData[ionizationL    822       xs12 = pDiffCrossSectionData[ionizationLevelIndex][valueT1][valueE12];
843       xs21 = pDiffCrossSectionData[ionizationL    823       xs21 = pDiffCrossSectionData[ionizationLevelIndex][valueT2][valueE21];
844       xs22 = pDiffCrossSectionData[ionizationL    824       xs22 = pDiffCrossSectionData[ionizationLevelIndex][valueT2][valueE22];
845                                                   825 
846     }                                             826     }
847                                                   827 
848     G4double xsProduct = xs11 * xs12 * xs21 *     828     G4double xsProduct = xs11 * xs12 * xs21 * xs22;
849     if (xsProduct != 0.)                          829     if (xsProduct != 0.)
850     {                                             830     {
851       sigma = QuadInterpolator(valueE11,          831       sigma = QuadInterpolator(valueE11,
852                                valueE12,          832                                valueE12,
853                                valueE21,          833                                valueE21,
854                                valueE22,          834                                valueE22,
855                                xs11,              835                                xs11,
856                                xs12,              836                                xs12,
857                                xs21,              837                                xs21,
858                                xs22,              838                                xs22,
859                                valueT1,           839                                valueT1,
860                                valueT2,           840                                valueT2,
861                                k,                 841                                k,
862                                energyTransfer)    842                                energyTransfer);
863     }                                             843     }
864   }                                               844   }
865                                                   845 
866   return sigma;                                   846   return sigma;
867 }                                                 847 }
868                                                   848 
869 //....oooOO0OOooo........oooOO0OOooo........oo    849 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
870                                                   850 
871 G4double G4DNABornIonisationModel1::Interpolat    851 G4double G4DNABornIonisationModel1::Interpolate(G4double e1,
872                                                   852                                                 G4double e2,
873                                                   853                                                 G4double e,
874                                                   854                                                 G4double xs1,
875                                                   855                                                 G4double xs2)
876 {                                                 856 {
877   G4double value = 0.;                            857   G4double value = 0.;
878                                                   858 
879   // Log-log interpolation by default             859   // Log-log interpolation by default
880                                                   860 
881   if (e1 != 0 && e2 != 0 && (std::log10(e2) -     861   if (e1 != 0 && e2 != 0 && (std::log10(e2) - std::log10(e1)) != 0
882       && !fasterCode)                             862       && !fasterCode)
883   {                                               863   {
884     G4double a = (std::log10(xs2) - std::log10    864     G4double a = (std::log10(xs2) - std::log10(xs1))
885         / (std::log10(e2) - std::log10(e1));      865         / (std::log10(e2) - std::log10(e1));
886     G4double b = std::log10(xs2) - a * std::lo    866     G4double b = std::log10(xs2) - a * std::log10(e2);
887     G4double sigma = a * std::log10(e) + b;       867     G4double sigma = a * std::log10(e) + b;
888     value = (std::pow(10., sigma));               868     value = (std::pow(10., sigma));
889   }                                               869   }
890                                                   870 
891   // Switch to lin-lin interpolation              871   // Switch to lin-lin interpolation
892   /*                                              872   /*
893    if ((e2-e1)!=0)                                873    if ((e2-e1)!=0)
894    {                                              874    {
895    G4double d1 = xs1;                             875    G4double d1 = xs1;
896    G4double d2 = xs2;                             876    G4double d2 = xs2;
897    value = (d1 + (d2 - d1)*(e - e1)/ (e2 - e1)    877    value = (d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
898    }                                              878    }
899   */                                              879   */
900                                                   880 
901   // Switch to log-lin interpolation for faste    881   // Switch to log-lin interpolation for faster code
902   if ((e2 - e1) != 0 && xs1 != 0 && xs2 != 0 &    882   if ((e2 - e1) != 0 && xs1 != 0 && xs2 != 0 && fasterCode)
903   {                                               883   {
904     G4double d1 = std::log10(xs1);                884     G4double d1 = std::log10(xs1);
905     G4double d2 = std::log10(xs2);                885     G4double d2 = std::log10(xs2);
906     value = std::pow(10., (d1 + (d2 - d1) * (e    886     value = std::pow(10., (d1 + (d2 - d1) * (e - e1) / (e2 - e1)));
907   }                                               887   }
908                                                   888 
909   // Switch to lin-lin interpolation for faste    889   // Switch to lin-lin interpolation for faster code
910   // in case one of xs1 or xs2 (=cum proba) va    890   // in case one of xs1 or xs2 (=cum proba) value is zero
911                                                   891 
912   if ((e2 - e1) != 0 && (xs1 == 0 || xs2 == 0)    892   if ((e2 - e1) != 0 && (xs1 == 0 || xs2 == 0) && fasterCode)
913   {                                               893   {
914     G4double d1 = xs1;                            894     G4double d1 = xs1;
915     G4double d2 = xs2;                            895     G4double d2 = xs2;
916     value = (d1 + (d2 - d1) * (e - e1) / (e2 -    896     value = (d1 + (d2 - d1) * (e - e1) / (e2 - e1));
917   }                                               897   }
918                                                   898 
919   /*                                              899   /*
920    G4cout                                         900    G4cout
921    << e1 << " "                                   901    << e1 << " "
922    << e2 << " "                                   902    << e2 << " "
923    << e  << " "                                   903    << e  << " "
924    << xs1 << " "                                  904    << xs1 << " "
925    << xs2 << " "                                  905    << xs2 << " "
926    << value                                       906    << value
927    << G4endl;                                     907    << G4endl;
928    */                                             908    */
929                                                   909 
930   return value;                                   910   return value;
931 }                                                 911 }
932                                                   912 
933 //....oooOO0OOooo........oooOO0OOooo........oo    913 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
934                                                   914 
935 G4double G4DNABornIonisationModel1::QuadInterp    915 G4double G4DNABornIonisationModel1::QuadInterpolator(G4double e11,
936                                                   916                                                      G4double e12,
937                                                   917                                                      G4double e21,
938                                                   918                                                      G4double e22,
939                                                   919                                                      G4double xs11,
940                                                   920                                                      G4double xs12,
941                                                   921                                                      G4double xs21,
942                                                   922                                                      G4double xs22,
943                                                   923                                                      G4double t1,
944                                                   924                                                      G4double t2,
945                                                   925                                                      G4double t,
946                                                   926                                                      G4double e)
947 {                                                 927 {
948   G4double interpolatedvalue1 = Interpolate(e1    928   G4double interpolatedvalue1 = Interpolate(e11, e12, e, xs11, xs12);
949   G4double interpolatedvalue2 = Interpolate(e2    929   G4double interpolatedvalue2 = Interpolate(e21, e22, e, xs21, xs22);
950   G4double value = Interpolate(t1,                930   G4double value = Interpolate(t1,
951                                t2,                931                                t2,
952                                t,                 932                                t,
953                                interpolatedval    933                                interpolatedvalue1,
954                                interpolatedval    934                                interpolatedvalue2);
955                                                   935 
956   return value;                                   936   return value;
957 }                                                 937 }
958                                                   938 
959 G4double G4DNABornIonisationModel1::GetPartial    939 G4double G4DNABornIonisationModel1::GetPartialCrossSection(const G4Material* /*material*/,
960                                                   940                                                            G4int level,
961                                                   941                                                            const G4ParticleDefinition* particle,
962                                                   942                                                            G4double kineticEnergy)
963 {                                                 943 {
964   std::map<G4String, G4DNACrossSectionDataSet*    944   std::map<G4String, G4DNACrossSectionDataSet*, std::less<G4String> >::iterator pos;
965   pos = tableData.find(particle->GetParticleNa    945   pos = tableData.find(particle->GetParticleName());
966                                                   946 
967   if (pos != tableData.end())                     947   if (pos != tableData.end())
968   {                                               948   {
969     G4DNACrossSectionDataSet* table = pos->sec    949     G4DNACrossSectionDataSet* table = pos->second;
970     return table->GetComponent(level)->FindVal    950     return table->GetComponent(level)->FindValue(kineticEnergy);
971   }                                               951   }
972                                                   952 
973   return 0;                                       953   return 0;
974 }                                                 954 }
975                                                   955 
976 //....oooOO0OOooo........oooOO0OOooo........oo    956 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
977                                                   957 
978 G4int G4DNABornIonisationModel1::RandomSelect(    958 G4int G4DNABornIonisationModel1::RandomSelect(G4double k,
979                                                   959                                               const G4String& particle)
980 {                                                 960 {
981   G4int level = 0;                                961   G4int level = 0;
982                                                   962 
983   std::map<G4String, G4DNACrossSectionDataSet*    963   std::map<G4String, G4DNACrossSectionDataSet*, std::less<G4String> >::iterator pos;
984   pos = tableData.find(particle);                 964   pos = tableData.find(particle);
985                                                   965 
986   if (pos != tableData.end())                     966   if (pos != tableData.end())
987   {                                               967   {
988     G4DNACrossSectionDataSet* table = pos->sec    968     G4DNACrossSectionDataSet* table = pos->second;
989                                                   969 
990     if (table != nullptr)                      << 970     if (table != 0)
991     {                                             971     {
992       auto  valuesBuffer = new G4double[table- << 972       G4double* valuesBuffer = new G4double[table->NumberOfComponents()];
993       const auto  n = (G4int)table->NumberOfCo << 973       const size_t n(table->NumberOfComponents());
994       G4int i(n);                              << 974       size_t i(n);
995       G4double value = 0.;                        975       G4double value = 0.;
996                                                   976 
997       while (i > 0)                               977       while (i > 0)
998       {                                           978       {
999         i--;                                      979         i--;
1000         valuesBuffer[i] = table->GetComponent    980         valuesBuffer[i] = table->GetComponent(i)->FindValue(k);
1001         value += valuesBuffer[i];                981         value += valuesBuffer[i];
1002       }                                          982       }
1003                                                  983 
1004       value *= G4UniformRand();                  984       value *= G4UniformRand();
1005                                                  985 
1006       i = n;                                     986       i = n;
1007                                                  987 
1008       while (i > 0)                              988       while (i > 0)
1009       {                                          989       {
1010         i--;                                     990         i--;
1011                                                  991 
1012         if (valuesBuffer[i] > value)             992         if (valuesBuffer[i] > value)
1013         {                                        993         {
1014           delete[] valuesBuffer;                 994           delete[] valuesBuffer;
1015           return i;                              995           return i;
1016         }                                        996         }
1017         value -= valuesBuffer[i];                997         value -= valuesBuffer[i];
1018       }                                          998       }
1019                                                  999 
1020                                               << 1000       if (valuesBuffer)
1021         delete[] valuesBuffer;                   1001         delete[] valuesBuffer;
1022                                                  1002 
1023     }                                            1003     }
1024   } else                                         1004   } else
1025   {                                              1005   {
1026     G4Exception("G4DNABornIonisationModel1::R    1006     G4Exception("G4DNABornIonisationModel1::RandomSelect",
1027                 "em0002",                        1007                 "em0002",
1028                 FatalException,                  1008                 FatalException,
1029                 "Model not applicable to part    1009                 "Model not applicable to particle type.");
1030   }                                              1010   }
1031                                                  1011 
1032   return level;                                  1012   return level;
1033 }                                                1013 }
1034                                                  1014 
1035 //....oooOO0OOooo........oooOO0OOooo........o    1015 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1036                                                  1016 
1037 G4double G4DNABornIonisationModel1::Randomize    1017 G4double G4DNABornIonisationModel1::RandomizeEjectedElectronEnergyFromCumulatedDcs(G4ParticleDefinition* particleDefinition,
1038                                                  1018                                                                                    G4double k,
1039                                                  1019                                                                                    G4int shell)
1040 {                                                1020 {
1041   //G4cout << "*** FAST computation for " <<     1021   //G4cout << "*** FAST computation for " << " " << particleDefinition->GetParticleName() << G4endl;
1042                                                  1022 
1043   G4double secondaryElectronKineticEnergy = 0    1023   G4double secondaryElectronKineticEnergy = 0.;
1044                                                  1024 
1045   G4double random = G4UniformRand();             1025   G4double random = G4UniformRand();
1046                                                  1026 
1047   secondaryElectronKineticEnergy = Transfered    1027   secondaryElectronKineticEnergy = TransferedEnergy(particleDefinition,
1048                                                  1028                                                     k / eV,
1049                                                  1029                                                     shell,
1050                                                  1030                                                     random) * eV
1051       - waterStructure.IonisationEnergy(shell    1031       - waterStructure.IonisationEnergy(shell);
1052                                                  1032 
1053   //G4cout << RandomTransferedEnergy(particle    1033   //G4cout << RandomTransferedEnergy(particleDefinition, k/eV, shell) << G4endl;
1054                                               << 
1055   if (secondaryElectronKineticEnergy < 0.)       1034   if (secondaryElectronKineticEnergy < 0.)
1056     return 0.;                                   1035     return 0.;
1057   //                                             1036   //
1058                                                  1037 
1059   return secondaryElectronKineticEnergy;         1038   return secondaryElectronKineticEnergy;
1060 }                                                1039 }
1061                                                  1040 
1062 //....oooOO0OOooo........oooOO0OOooo........o    1041 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1063                                                  1042 
1064 G4double G4DNABornIonisationModel1::Transfere    1043 G4double G4DNABornIonisationModel1::TransferedEnergy(G4ParticleDefinition* particleDefinition,
1065                                                  1044                                                      G4double k,
1066                                                  1045                                                      G4int ionizationLevelIndex,
1067                                                  1046                                                      G4double random)
1068 {                                                1047 {
1069   G4double nrj = 0.;                             1048   G4double nrj = 0.;
1070                                                  1049 
1071   G4double valueK1 = 0;                          1050   G4double valueK1 = 0;
1072   G4double valueK2 = 0;                          1051   G4double valueK2 = 0;
1073   G4double valuePROB21 = 0;                      1052   G4double valuePROB21 = 0;
1074   G4double valuePROB22 = 0;                      1053   G4double valuePROB22 = 0;
1075   G4double valuePROB12 = 0;                      1054   G4double valuePROB12 = 0;
1076   G4double valuePROB11 = 0;                      1055   G4double valuePROB11 = 0;
1077                                                  1056 
1078   G4double nrjTransf11 = 0;                      1057   G4double nrjTransf11 = 0;
1079   G4double nrjTransf12 = 0;                      1058   G4double nrjTransf12 = 0;
1080   G4double nrjTransf21 = 0;                      1059   G4double nrjTransf21 = 0;
1081   G4double nrjTransf22 = 0;                      1060   G4double nrjTransf22 = 0;
1082                                                  1061 
1083   if (particleDefinition == G4Electron::Elect    1062   if (particleDefinition == G4Electron::ElectronDefinition())
1084   {                                              1063   {
1085     // Protection against out of boundary acc << 
1086     if (k==eTdummyVec.back()) k=k*(1.-1e-12); << 
1087     //                                        << 
1088                                               << 
1089     // k should be in eV                         1064     // k should be in eV
1090     auto k2 = std::upper_bound(eTdummyVec.beg << 1065     std::vector<G4double>::iterator k2 = std::upper_bound(eTdummyVec.begin(),
1091                                                  1066                                                         eTdummyVec.end(),
1092                                                  1067                                                         k);
1093     auto k1 = k2 - 1;                         << 1068     std::vector<G4double>::iterator k1 = k2 - 1;
1094                                                  1069 
1095     /*                                           1070     /*
1096      G4cout << "----> k=" << k                   1071      G4cout << "----> k=" << k
1097      << " " << *k1                               1072      << " " << *k1
1098      << " " << *k2                               1073      << " " << *k2
1099      << " " << random                            1074      << " " << random
1100      << " " << ionizationLevelIndex              1075      << " " << ionizationLevelIndex
1101      << " " << eProbaShellMap[ionizationLevel    1076      << " " << eProbaShellMap[ionizationLevelIndex][(*k1)].back()
1102      << " " << eProbaShellMap[ionizationLevel    1077      << " " << eProbaShellMap[ionizationLevelIndex][(*k2)].back()
1103      << G4endl;                                  1078      << G4endl;
1104      */                                          1079      */
1105                                                  1080 
1106     // SI : the following condition avoids si    1081     // SI : the following condition avoids situations where random >last vector element
1107     if (random <= eProbaShellMap[ionizationLe    1082     if (random <= eProbaShellMap[ionizationLevelIndex][(*k1)].back()
1108         && random <= eProbaShellMap[ionizatio    1083         && random <= eProbaShellMap[ionizationLevelIndex][(*k2)].back())
1109     {                                            1084     {
1110       auto prob12 =                           << 1085       std::vector<G4double>::iterator prob12 =
1111           std::upper_bound(eProbaShellMap[ion    1086           std::upper_bound(eProbaShellMap[ionizationLevelIndex][(*k1)].begin(),
1112                            eProbaShellMap[ion    1087                            eProbaShellMap[ionizationLevelIndex][(*k1)].end(),
1113                            random);              1088                            random);
1114                                                  1089 
1115       auto prob11 = prob12 - 1;               << 1090       std::vector<G4double>::iterator prob11 = prob12 - 1;
1116                                                  1091 
1117       auto prob22 =                           << 1092       std::vector<G4double>::iterator prob22 =
1118           std::upper_bound(eProbaShellMap[ion    1093           std::upper_bound(eProbaShellMap[ionizationLevelIndex][(*k2)].begin(),
1119                            eProbaShellMap[ion    1094                            eProbaShellMap[ionizationLevelIndex][(*k2)].end(),
1120                            random);              1095                            random);
1121                                                  1096 
1122       auto prob21 = prob22 - 1;               << 1097       std::vector<G4double>::iterator prob21 = prob22 - 1;
1123                                                  1098 
1124       valueK1 = *k1;                             1099       valueK1 = *k1;
1125       valueK2 = *k2;                             1100       valueK2 = *k2;
1126       valuePROB21 = *prob21;                     1101       valuePROB21 = *prob21;
1127       valuePROB22 = *prob22;                     1102       valuePROB22 = *prob22;
1128       valuePROB12 = *prob12;                     1103       valuePROB12 = *prob12;
1129       valuePROB11 = *prob11;                     1104       valuePROB11 = *prob11;
1130                                                  1105 
1131       /*                                         1106       /*
1132        G4cout << "        " << random << " "     1107        G4cout << "        " << random << " " << valuePROB11 << " "
1133        << valuePROB12 << " " << valuePROB21 <    1108        << valuePROB12 << " " << valuePROB21 << " " << valuePROB22 << G4endl;
1134        */                                        1109        */
1135                                                  1110 
1136       nrjTransf11 = eNrjTransfData[ionization    1111       nrjTransf11 = eNrjTransfData[ionizationLevelIndex][valueK1][valuePROB11];
1137       nrjTransf12 = eNrjTransfData[ionization    1112       nrjTransf12 = eNrjTransfData[ionizationLevelIndex][valueK1][valuePROB12];
1138       nrjTransf21 = eNrjTransfData[ionization    1113       nrjTransf21 = eNrjTransfData[ionizationLevelIndex][valueK2][valuePROB21];
1139       nrjTransf22 = eNrjTransfData[ionization    1114       nrjTransf22 = eNrjTransfData[ionizationLevelIndex][valueK2][valuePROB22];
1140                                                  1115 
1141       /*                                         1116       /*
1142        G4cout << "        " << ionizationLeve    1117        G4cout << "        " << ionizationLevelIndex << " "
1143        << random << " " <<valueK1 << " " << v    1118        << random << " " <<valueK1 << " " << valueK2 << G4endl;
1144                                                  1119 
1145        G4cout << "        " << random << " "     1120        G4cout << "        " << random << " " << nrjTransf11 << " "
1146        << nrjTransf12 << " " << nrjTransf21 <    1121        << nrjTransf12 << " " << nrjTransf21 << " " <<nrjTransf22 << G4endl;
1147        */                                        1122        */
1148                                                  1123 
1149     }                                            1124     }
1150                                               << 
1151     // Avoids cases where cum xs is zero for     1125     // Avoids cases where cum xs is zero for k1 and is not for k2 (with always k1<k2)
1152     if (random > eProbaShellMap[ionizationLev    1126     if (random > eProbaShellMap[ionizationLevelIndex][(*k1)].back())
1153     {                                            1127     {
1154       auto prob22 =                           << 1128       std::vector<G4double>::iterator prob22 =
1155           std::upper_bound(eProbaShellMap[ion    1129           std::upper_bound(eProbaShellMap[ionizationLevelIndex][(*k2)].begin(),
1156                            eProbaShellMap[ion    1130                            eProbaShellMap[ionizationLevelIndex][(*k2)].end(),
1157                            random);              1131                            random);
1158                                                  1132 
1159       auto prob21 = prob22 - 1;               << 1133       std::vector<G4double>::iterator prob21 = prob22 - 1;
1160                                                  1134 
1161       valueK1 = *k1;                             1135       valueK1 = *k1;
1162       valueK2 = *k2;                             1136       valueK2 = *k2;
1163       valuePROB21 = *prob21;                     1137       valuePROB21 = *prob21;
1164       valuePROB22 = *prob22;                     1138       valuePROB22 = *prob22;
1165                                                  1139 
1166       //G4cout << "        " << random << " "    1140       //G4cout << "        " << random << " " << valuePROB21 << " " << valuePROB22 << G4endl;
1167                                                  1141 
1168       nrjTransf21 = eNrjTransfData[ionization    1142       nrjTransf21 = eNrjTransfData[ionizationLevelIndex][valueK2][valuePROB21];
1169       nrjTransf22 = eNrjTransfData[ionization    1143       nrjTransf22 = eNrjTransfData[ionizationLevelIndex][valueK2][valuePROB22];
1170                                                  1144 
1171       G4double interpolatedvalue2 = Interpola    1145       G4double interpolatedvalue2 = Interpolate(valuePROB21,
1172                                                  1146                                                 valuePROB22,
1173                                                  1147                                                 random,
1174                                                  1148                                                 nrjTransf21,
1175                                                  1149                                                 nrjTransf22);
1176                                                  1150 
1177       // zeros are explicitly set             << 1151       // zeros are explicitely set
1178                                                  1152 
1179       G4double value = Interpolate(valueK1, v    1153       G4double value = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
1180                                                  1154 
1181       /*                                         1155       /*
1182        G4cout << "        " << ionizationLeve    1156        G4cout << "        " << ionizationLevelIndex << " "
1183        << random << " " <<valueK1 << " " << v    1157        << random << " " <<valueK1 << " " << valueK2 << G4endl;
1184                                                  1158 
1185        G4cout << "        " << random << " "     1159        G4cout << "        " << random << " " << nrjTransf11 << " "
1186        << nrjTransf12 << " " << nrjTransf21 <    1160        << nrjTransf12 << " " << nrjTransf21 << " " <<nrjTransf22 << G4endl;
1187                                                  1161 
1188        G4cout << "ici" << " " << value << G4e    1162        G4cout << "ici" << " " << value << G4endl;
1189        */                                        1163        */
1190                                                  1164 
1191       return value;                              1165       return value;
1192     }                                            1166     }
1193   }                                              1167   }
1194   //                                             1168   //
1195   else if (particleDefinition == G4Proton::Pr    1169   else if (particleDefinition == G4Proton::ProtonDefinition())
1196   {                                              1170   {
1197     // Protection against out of boundary acc << 
1198     if (k==pTdummyVec.back()) k=k*(1.-1e-12); << 
1199     //                                        << 
1200                                               << 
1201     // k should be in eV                         1171     // k should be in eV
1202                                                  1172 
1203     auto k2 = std::upper_bound(pTdummyVec.beg << 1173     std::vector<G4double>::iterator k2 = std::upper_bound(pTdummyVec.begin(),
1204                                                  1174                                                         pTdummyVec.end(),
1205                                                  1175                                                         k);
1206                                                  1176 
1207     auto k1 = k2 - 1;                         << 1177     std::vector<G4double>::iterator k1 = k2 - 1;
1208                                                  1178 
1209     /*                                           1179     /*
1210      G4cout << "----> k=" << k                   1180      G4cout << "----> k=" << k
1211      << " " << *k1                               1181      << " " << *k1
1212      << " " << *k2                               1182      << " " << *k2
1213      << " " << random                            1183      << " " << random
1214      << " " << ionizationLevelIndex              1184      << " " << ionizationLevelIndex
1215      << " " << pProbaShellMap[ionizationLevel    1185      << " " << pProbaShellMap[ionizationLevelIndex][(*k1)].back()
1216      << " " << pProbaShellMap[ionizationLevel    1186      << " " << pProbaShellMap[ionizationLevelIndex][(*k2)].back()
1217      << G4endl;                                  1187      << G4endl;
1218      */                                          1188      */
1219                                                  1189 
1220     // SI : the following condition avoids si    1190     // SI : the following condition avoids situations where random > last vector element,
1221     //      for eg. when the last element is     1191     //      for eg. when the last element is zero
1222     if (random <= pProbaShellMap[ionizationLe    1192     if (random <= pProbaShellMap[ionizationLevelIndex][(*k1)].back()
1223         && random <= pProbaShellMap[ionizatio    1193         && random <= pProbaShellMap[ionizationLevelIndex][(*k2)].back())
1224     {                                            1194     {
1225       auto prob12 =                           << 1195       std::vector<G4double>::iterator prob12 =
1226           std::upper_bound(pProbaShellMap[ion    1196           std::upper_bound(pProbaShellMap[ionizationLevelIndex][(*k1)].begin(),
1227                            pProbaShellMap[ion    1197                            pProbaShellMap[ionizationLevelIndex][(*k1)].end(),
1228                            random);              1198                            random);
1229                                                  1199 
1230       auto prob11 = prob12 - 1;               << 1200       std::vector<G4double>::iterator prob11 = prob12 - 1;
1231                                                  1201 
1232       auto prob22 =                           << 1202       std::vector<G4double>::iterator prob22 =
1233           std::upper_bound(pProbaShellMap[ion    1203           std::upper_bound(pProbaShellMap[ionizationLevelIndex][(*k2)].begin(),
1234                            pProbaShellMap[ion    1204                            pProbaShellMap[ionizationLevelIndex][(*k2)].end(),
1235                            random);              1205                            random);
1236                                                  1206 
1237       auto prob21 = prob22 - 1;               << 1207       std::vector<G4double>::iterator prob21 = prob22 - 1;
1238                                                  1208 
1239       valueK1 = *k1;                             1209       valueK1 = *k1;
1240       valueK2 = *k2;                             1210       valueK2 = *k2;
1241       valuePROB21 = *prob21;                     1211       valuePROB21 = *prob21;
1242       valuePROB22 = *prob22;                     1212       valuePROB22 = *prob22;
1243       valuePROB12 = *prob12;                     1213       valuePROB12 = *prob12;
1244       valuePROB11 = *prob11;                     1214       valuePROB11 = *prob11;
1245                                                  1215 
1246       /*                                         1216       /*
1247        G4cout << "        " << random << " "     1217        G4cout << "        " << random << " " << valuePROB11 << " "
1248        << valuePROB12 << " " << valuePROB21 <    1218        << valuePROB12 << " " << valuePROB21 << " " << valuePROB22 << G4endl;
1249        */                                        1219        */
1250                                                  1220 
1251       nrjTransf11 = pNrjTransfData[ionization    1221       nrjTransf11 = pNrjTransfData[ionizationLevelIndex][valueK1][valuePROB11];
1252       nrjTransf12 = pNrjTransfData[ionization    1222       nrjTransf12 = pNrjTransfData[ionizationLevelIndex][valueK1][valuePROB12];
1253       nrjTransf21 = pNrjTransfData[ionization    1223       nrjTransf21 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB21];
1254       nrjTransf22 = pNrjTransfData[ionization    1224       nrjTransf22 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB22];
1255                                                  1225 
1256       /*                                         1226       /*
1257        G4cout << "        " << ionizationLeve    1227        G4cout << "        " << ionizationLevelIndex << " "
1258        << random << " " <<valueK1 << " " << v    1228        << random << " " <<valueK1 << " " << valueK2 << G4endl;
1259                                                  1229 
1260        G4cout << "        " << random << " "     1230        G4cout << "        " << random << " " << nrjTransf11 << " "
1261        << nrjTransf12 << " " << nrjTransf21 <    1231        << nrjTransf12 << " " << nrjTransf21 << " " <<nrjTransf22 << G4endl;
1262        */                                        1232        */
1263     }                                            1233     }
1264                                                  1234 
1265     // Avoids cases where cum xs is zero for     1235     // Avoids cases where cum xs is zero for k1 and is not for k2 (with always k1<k2)
1266                                                  1236 
1267     if (random > pProbaShellMap[ionizationLev    1237     if (random > pProbaShellMap[ionizationLevelIndex][(*k1)].back())
1268     {                                            1238     {
1269       auto prob22 =                           << 1239       std::vector<G4double>::iterator prob22 =
1270           std::upper_bound(pProbaShellMap[ion    1240           std::upper_bound(pProbaShellMap[ionizationLevelIndex][(*k2)].begin(),
1271                            pProbaShellMap[ion    1241                            pProbaShellMap[ionizationLevelIndex][(*k2)].end(),
1272                            random);              1242                            random);
1273                                                  1243 
1274       auto prob21 = prob22 - 1;               << 1244       std::vector<G4double>::iterator prob21 = prob22 - 1;
1275                                                  1245 
1276       valueK1 = *k1;                             1246       valueK1 = *k1;
1277       valueK2 = *k2;                             1247       valueK2 = *k2;
1278       valuePROB21 = *prob21;                     1248       valuePROB21 = *prob21;
1279       valuePROB22 = *prob22;                     1249       valuePROB22 = *prob22;
1280                                                  1250 
1281       //G4cout << "        " << random << " "    1251       //G4cout << "        " << random << " " << valuePROB21 << " " << valuePROB22 << G4endl;
1282                                                  1252 
1283       nrjTransf21 = pNrjTransfData[ionization    1253       nrjTransf21 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB21];
1284       nrjTransf22 = pNrjTransfData[ionization    1254       nrjTransf22 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB22];
1285                                                  1255 
1286       G4double interpolatedvalue2 = Interpola    1256       G4double interpolatedvalue2 = Interpolate(valuePROB21,
1287                                                  1257                                                 valuePROB22,
1288                                                  1258                                                 random,
1289                                                  1259                                                 nrjTransf21,
1290                                                  1260                                                 nrjTransf22);
1291                                                  1261 
1292       // zeros are explicitly set             << 1262       // zeros are explicitely set
1293                                                  1263 
1294       G4double value = Interpolate(valueK1, v    1264       G4double value = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
1295                                                  1265 
1296       /*                                         1266       /*
1297        G4cout << "        " << ionizationLeve    1267        G4cout << "        " << ionizationLevelIndex << " "
1298        << random << " " <<valueK1 << " " << v    1268        << random << " " <<valueK1 << " " << valueK2 << G4endl;
1299                                                  1269 
1300        G4cout << "        " << random << " "     1270        G4cout << "        " << random << " " << nrjTransf11 << " "
1301        << nrjTransf12 << " " << nrjTransf21 <    1271        << nrjTransf12 << " " << nrjTransf21 << " " <<nrjTransf22 << G4endl;
1302                                                  1272 
1303        G4cout << "ici" << " " << value << G4e    1273        G4cout << "ici" << " " << value << G4endl;
1304        */                                        1274        */
1305                                                  1275 
1306       return value;                              1276       return value;
1307     }                                            1277     }
1308   }                                              1278   }
1309   // End electron and proton cases               1279   // End electron and proton cases
1310                                                  1280 
1311   G4double nrjTransfProduct = nrjTransf11 * n    1281   G4double nrjTransfProduct = nrjTransf11 * nrjTransf12 * nrjTransf21
1312       * nrjTransf22;                             1282       * nrjTransf22;
1313   //G4cout << "nrjTransfProduct=" << nrjTrans    1283   //G4cout << "nrjTransfProduct=" << nrjTransfProduct << G4endl;
1314                                                  1284 
1315   if (nrjTransfProduct != 0.)                    1285   if (nrjTransfProduct != 0.)
1316   {                                              1286   {
1317     nrj = QuadInterpolator(valuePROB11,          1287     nrj = QuadInterpolator(valuePROB11,
1318                            valuePROB12,          1288                            valuePROB12,
1319                            valuePROB21,          1289                            valuePROB21,
1320                            valuePROB22,          1290                            valuePROB22,
1321                            nrjTransf11,          1291                            nrjTransf11,
1322                            nrjTransf12,          1292                            nrjTransf12,
1323                            nrjTransf21,          1293                            nrjTransf21,
1324                            nrjTransf22,          1294                            nrjTransf22,
1325                            valueK1,              1295                            valueK1,
1326                            valueK2,              1296                            valueK2,
1327                            k,                    1297                            k,
1328                            random);              1298                            random);
1329   }                                              1299   }
1330   //G4cout << nrj << endl;                       1300   //G4cout << nrj << endl;
1331                                                  1301 
1332   return nrj;                                    1302   return nrj;
1333 }                                                1303 }
1334                                                  1304