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.2.p2)


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