Geant4 Cross Reference

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


  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 // Based on the work described in                  26 // Based on the work described in
 27 // Rad Res 163, 98-111 (2005)                      27 // Rad Res 163, 98-111 (2005)
 28 // D. Emfietzoglou, H. Nikjoo                      28 // D. Emfietzoglou, H. Nikjoo
 29 //                                                 29 //
 30 // Authors of the class (2014):                    30 // Authors of the class (2014):
 31 // I. Kyriakou (kyriak@cc.uoi.gr)                  31 // I. Kyriakou (kyriak@cc.uoi.gr)
 32 // D. Emfietzoglou (demfietz@cc.uoi.gr)            32 // D. Emfietzoglou (demfietz@cc.uoi.gr)
 33 // S. Incerti (incerti@cenbg.in2p3.fr)             33 // S. Incerti (incerti@cenbg.in2p3.fr)
 34 //                                                 34 //
 35                                                    35 
 36 #include "G4DNAEmfietzoglouIonisationModel.hh"     36 #include "G4DNAEmfietzoglouIonisationModel.hh"
 37 #include "G4PhysicalConstants.hh"                  37 #include "G4PhysicalConstants.hh"
 38 #include "G4SystemOfUnits.hh"                      38 #include "G4SystemOfUnits.hh"
 39 #include "G4UAtomicDeexcitation.hh"                39 #include "G4UAtomicDeexcitation.hh"
 40 #include "G4LossTableManager.hh"                   40 #include "G4LossTableManager.hh"
 41 #include "G4DNAChemistryManager.hh"                41 #include "G4DNAChemistryManager.hh"
 42 #include "G4DNAMolecularMaterial.hh"               42 #include "G4DNAMolecularMaterial.hh"
 43 #include "G4DNABornAngle.hh"                       43 #include "G4DNABornAngle.hh"
 44 #include "G4DeltaAngle.hh"                         44 #include "G4DeltaAngle.hh"
 45                                                    45 
 46 //....oooOO0OOooo........oooOO0OOooo........oo     46 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 47                                                    47 
 48 using namespace std;                               48 using namespace std;
 49                                                    49 
 50 //....oooOO0OOooo........oooOO0OOooo........oo     50 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 51                                                    51 
 52 G4DNAEmfietzoglouIonisationModel::G4DNAEmfietz     52 G4DNAEmfietzoglouIonisationModel::G4DNAEmfietzoglouIonisationModel(const G4ParticleDefinition*,
 53                                                    53                                                                    const G4String& nam) :
 54 G4VEmModel(nam)                                    54 G4VEmModel(nam) 
 55 {                                                  55 {
 56   verboseLevel = 0;                                56   verboseLevel = 0;
 57   // Verbosity scale:                              57   // Verbosity scale:
 58   // 0 = nothing                                   58   // 0 = nothing
 59   // 1 = warning for energy non-conservation       59   // 1 = warning for energy non-conservation
 60   // 2 = details of energy budget                  60   // 2 = details of energy budget
 61   // 3 = calculation of cross sections, file o     61   // 3 = calculation of cross sections, file openings, sampling of atoms
 62   // 4 = entering in methods                       62   // 4 = entering in methods
 63                                                    63 
 64   if(verboseLevel > 0)                             64   if(verboseLevel > 0)
 65   {                                                65   {
 66     G4cout << "Emfietzoglou ionisation model i     66     G4cout << "Emfietzoglou ionisation model is constructed " << G4endl;
 67   }                                                67   }
 68                                                    68 
 69   // Mark this model as "applicable" for atomi     69   // Mark this model as "applicable" for atomic deexcitation
 70   SetDeexcitationFlag(true);                       70   SetDeexcitationFlag(true);
 71   fAtomDeexcitation = nullptr;                     71   fAtomDeexcitation = nullptr;
 72   fParticleChangeForGamma = nullptr;               72   fParticleChangeForGamma = nullptr;
 73   fpMolWaterDensity = nullptr;                     73   fpMolWaterDensity = nullptr;
 74                                                    74 
 75   // Define default angular generator              75   // Define default angular generator
 76   SetAngularDistribution(new G4DNABornAngle())     76   SetAngularDistribution(new G4DNABornAngle());
 77                                                    77 
 78   SetLowEnergyLimit(10. * eV);                     78   SetLowEnergyLimit(10. * eV);
 79   SetHighEnergyLimit(10. * keV);                   79   SetHighEnergyLimit(10. * keV);
 80                                                    80 
 81   // Selection of computation method               81   // Selection of computation method
 82                                                    82 
 83   fasterCode = false;                              83   fasterCode = false;
 84                                                    84 
 85   // Selection of stationary mode                  85   // Selection of stationary mode
 86                                                    86 
 87   statCode = false;                                87   statCode = false;
 88 }                                                  88 }
 89                                                    89 
 90 //....oooOO0OOooo........oooOO0OOooo........oo     90 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 91                                                    91 
 92 G4DNAEmfietzoglouIonisationModel::~G4DNAEmfiet     92 G4DNAEmfietzoglouIonisationModel::~G4DNAEmfietzoglouIonisationModel()
 93 {                                                  93 {
 94   // Cross section                                 94   // Cross section
 95                                                    95 
 96   std::map<G4String, G4DNACrossSectionDataSet*     96   std::map<G4String, G4DNACrossSectionDataSet*, std::less<G4String> >::iterator pos;
 97   for(pos = tableData.begin(); pos != tableDat     97   for(pos = tableData.begin(); pos != tableData.end(); ++pos)
 98   {                                                98   {
 99     G4DNACrossSectionDataSet* table = pos->sec     99     G4DNACrossSectionDataSet* table = pos->second;
100     delete table;                                 100     delete table;
101   }                                               101   }
102                                                   102 
103   // Final state                                  103   // Final state
104                                                   104 
105   eVecm.clear();                                  105   eVecm.clear();
106                                                   106 
107 }                                                 107 }
108                                                   108 
109 //....oooOO0OOooo........oooOO0OOooo........oo    109 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
110                                                   110 
111 void G4DNAEmfietzoglouIonisationModel::Initial    111 void G4DNAEmfietzoglouIonisationModel::Initialise(const G4ParticleDefinition* particle,
112                                                   112                                                   const G4DataVector& /*cuts*/)
113 {                                                 113 {
114                                                   114 
115   if(verboseLevel > 3)                            115   if(verboseLevel > 3)
116   {                                               116   {
117     G4cout << "Calling G4DNAEmfietzoglouIonisa    117     G4cout << "Calling G4DNAEmfietzoglouIonisationModel::Initialise()" << G4endl;
118   }                                               118   }
119                                                   119 
120   // Energy limits                                120   // Energy limits
121                                                   121 
122   G4String fileElectron("dna/sigma_ionisation_    122   G4String fileElectron("dna/sigma_ionisation_e_emfietzoglou");
123                                                   123 
124   G4ParticleDefinition* electronDef = G4Electr    124   G4ParticleDefinition* electronDef = G4Electron::ElectronDefinition();
125                                                   125 
126   G4String electron;                              126   G4String electron;
127                                                   127 
128   G4double scaleFactor = (1.e-22 / 3.343) * m*    128   G4double scaleFactor = (1.e-22 / 3.343) * m*m;
129                                                   129 
130   const char *path = G4FindDataDir("G4LEDATA")    130   const char *path = G4FindDataDir("G4LEDATA");
131                                                   131 
132   // *** ELECTRON                                 132   // *** ELECTRON
133                                                   133 
134   electron = electronDef->GetParticleName();      134   electron = electronDef->GetParticleName();
135                                                   135 
136   tableFile[electron] = fileElectron;             136   tableFile[electron] = fileElectron;
137                                                   137 
138   // Cross section                                138   // Cross section
139                                                   139 
140   auto  tableE = new G4DNACrossSectionDataSet(    140   auto  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_emfietzoglou.dat";
150   if (!fasterCode) eFullFileName << path << "/    150   if (!fasterCode) eFullFileName << path << "/dna/sigmadiff_ionisation_e_emfietzoglou.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("G4DNAEmfietzo    156     if (fasterCode) G4Exception("G4DNAEmfietzoglouIonisationModel::Initialise","em0003",
157         FatalException,"Missing data file:/dna    157         FatalException,"Missing data file:/dna/sigmadiff_cumulated_ionisation_e_emfietzoglou.dat");
158                                                   158 
159     if (!fasterCode) G4Exception("G4DNAEmfietz    159     if (!fasterCode) G4Exception("G4DNAEmfietzoglouIonisationModel::Initialise","em0003",
160         FatalException,"Missing data file:/dna    160         FatalException,"Missing data file:/dna/sigmadiff_ionisation_e_emfietzoglou.dat");
161   }                                               161   }
162                                                   162 
163   //                                              163   //
164                                                   164 
165   // Clear the arrays for re-initialization ca    165   // Clear the arrays for re-initialization case (MT mode)
166   // March 25th, 2014 - Vaclav Stepan, Sebasti    166   // March 25th, 2014 - Vaclav Stepan, Sebastien Incerti
167                                                   167 
168   eTdummyVec.clear();                             168   eTdummyVec.clear();
169                                                   169 
170   eVecm.clear();                                  170   eVecm.clear();
171                                                   171 
172   eProbaShellMap->clear();                        172   eProbaShellMap->clear();
173                                                   173 
174   eDiffCrossSectionData->clear();                 174   eDiffCrossSectionData->clear();
175                                                   175 
176   eNrjTransfData->clear();                        176   eNrjTransfData->clear();
177                                                   177 
178   //                                              178   //
179                                                   179 
180   eTdummyVec.push_back(0.);                       180   eTdummyVec.push_back(0.);
181   while(!eDiffCrossSection.eof())                 181   while(!eDiffCrossSection.eof())
182   {                                               182   {
183     G4double tDummy;                              183     G4double tDummy;
184     G4double eDummy;                              184     G4double eDummy;
185     eDiffCrossSection>>tDummy>>eDummy;            185     eDiffCrossSection>>tDummy>>eDummy;
186     if (tDummy != eTdummyVec.back()) eTdummyVe    186     if (tDummy != eTdummyVec.back()) eTdummyVec.push_back(tDummy);
187     for (G4int j=0; j<5; j++)                     187     for (G4int j=0; j<5; j++)
188     {                                             188     {
189       eDiffCrossSection>>eDiffCrossSectionData    189       eDiffCrossSection>>eDiffCrossSectionData[j][tDummy][eDummy];
190                                                   190 
191       if (fasterCode)                             191       if (fasterCode)
192       {                                           192       {
193         eNrjTransfData[j][tDummy][eDiffCrossSe    193         eNrjTransfData[j][tDummy][eDiffCrossSectionData[j][tDummy][eDummy]]=eDummy;
194         eProbaShellMap[j][tDummy].push_back(eD    194         eProbaShellMap[j][tDummy].push_back(eDiffCrossSectionData[j][tDummy][eDummy]);
195       }                                           195       }
196                                                   196 
197       // SI - only if eof is not reached          197       // SI - only if eof is not reached
198       if (!eDiffCrossSection.eof() && !fasterC    198       if (!eDiffCrossSection.eof() && !fasterCode)
199       {                                           199       {
200         eDiffCrossSectionData[j][tDummy][eDumm    200         eDiffCrossSectionData[j][tDummy][eDummy]*=scaleFactor;
201       }                                           201       }
202                                                   202 
203       if (!fasterCode) eVecm[tDummy].push_back    203       if (!fasterCode) eVecm[tDummy].push_back(eDummy);
204                                                   204 
205     }                                             205     }
206   }                                               206   }
207                                                   207 
208   //                                              208   //
209                                                   209 
210   if( verboseLevel>0 )                            210   if( verboseLevel>0 )
211   {                                               211   {
212     G4cout << "Emfietzoglou ionisation model i    212     G4cout << "Emfietzoglou ionisation model is initialized " << G4endl
213     << "Energy range: "                           213     << "Energy range: "
214     << LowEnergyLimit() / eV << " eV - "          214     << LowEnergyLimit() / eV << " eV - "
215     << HighEnergyLimit() / keV << " keV for "     215     << HighEnergyLimit() / keV << " keV for "
216     << particle->GetParticleName()                216     << particle->GetParticleName()
217     << G4endl;                                    217     << G4endl;
218   }                                               218   }
219                                                   219 
220   // Initialize water density pointer             220   // Initialize water density pointer
221                                                   221 
222   fpMolWaterDensity =                             222   fpMolWaterDensity =
223       G4DNAMolecularMaterial::Instance()->        223       G4DNAMolecularMaterial::Instance()->
224         GetNumMolPerVolTableFor(G4Material::Ge    224         GetNumMolPerVolTableFor(G4Material::GetMaterial("G4_WATER"));
225                                                   225 
226   // AD                                           226   // AD
227                                                   227 
228   fAtomDeexcitation = G4LossTableManager::Inst    228   fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
229                                                   229 
230   if (isInitialised)                              230   if (isInitialised)
231   { return;}                                      231   { return;}
232   fParticleChangeForGamma = GetParticleChangeF    232   fParticleChangeForGamma = GetParticleChangeForGamma();
233   isInitialised = true;                           233   isInitialised = true;
234 }                                                 234 }
235                                                   235 
236 //....oooOO0OOooo........oooOO0OOooo........oo    236 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
237                                                   237 
238 G4double G4DNAEmfietzoglouIonisationModel::       238 G4double G4DNAEmfietzoglouIonisationModel::
239 CrossSectionPerVolume(const G4Material* materi    239 CrossSectionPerVolume(const G4Material* material,
240                       const G4ParticleDefiniti    240                       const G4ParticleDefinition* particleDefinition,
241                       G4double ekin,              241                       G4double ekin,
242                       G4double,                   242                       G4double,
243                       G4double)                   243                       G4double)
244 {                                                 244 {
245   if(verboseLevel > 3)                            245   if(verboseLevel > 3)
246   {                                               246   {
247     G4cout                                        247     G4cout
248         << "Calling CrossSectionPerVolume() of    248         << "Calling CrossSectionPerVolume() of G4DNAEmfietzoglouIonisationModel"
249         << G4endl;                                249         << G4endl;
250   }                                               250   }
251                                                   251 
252   if (particleDefinition != G4Electron::Electr    252   if (particleDefinition != G4Electron::ElectronDefinition()) return 0; // necessary ??
253                                                   253 
254   // Calculate total cross section for model      254   // Calculate total cross section for model
255                                                   255 
256   G4double sigma=0;                               256   G4double sigma=0;
257                                                   257 
258   G4double waterDensity = (*fpMolWaterDensity)    258   G4double waterDensity = (*fpMolWaterDensity)[material->GetIndex()];
259                                                   259 
260   const G4String& particleName = particleDefin    260   const G4String& particleName = particleDefinition->GetParticleName();
261                                                   261 
262   if (ekin >= LowEnergyLimit() && ekin <= High    262   if (ekin >= LowEnergyLimit() && ekin <= HighEnergyLimit())
263   {                                               263   {
264     std::map< G4String,G4DNACrossSectionDataSe    264     std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
265     pos = tableData.find(particleName);           265     pos = tableData.find(particleName);
266                                                   266 
267     if (pos != tableData.end())                   267     if (pos != tableData.end())
268     {                                             268     {
269       G4DNACrossSectionDataSet* table = pos->s    269       G4DNACrossSectionDataSet* table = pos->second;
270       if (table != nullptr)                       270       if (table != nullptr)
271       {                                           271       {
272         sigma = table->FindValue(ekin);           272         sigma = table->FindValue(ekin);
273       }                                           273       }
274     }                                             274     }
275     else                                          275     else
276     {                                             276     {
277       G4Exception("G4DNAEmfietzoglouIonisation    277       G4Exception("G4DNAEmfietzoglouIonisationModel::CrossSectionPerVolume","em0002",
278           FatalException,"Model not applicable    278           FatalException,"Model not applicable to particle type.");
279     }                                             279     }
280   }                                               280   }
281                                                   281 
282   if (verboseLevel > 2)                           282   if (verboseLevel > 2)
283   {                                               283   {
284     G4cout << "_______________________________    284     G4cout << "__________________________________" << G4endl;
285     G4cout << "G4DNAEmfietzoglouIonisationMode    285     G4cout << "G4DNAEmfietzoglouIonisationModel - XS INFO START" << G4endl;
286     G4cout << "Kinetic energy(eV)=" << ekin/eV    286     G4cout << "Kinetic energy(eV)=" << ekin/eV << " particle : " << particleName << G4endl;
287     G4cout << "Cross section per water molecul    287     G4cout << "Cross section per water molecule (cm^2)=" << sigma/cm/cm << G4endl;
288     G4cout << "Cross section per water molecul    288     G4cout << "Cross section per water molecule (cm^-1)=" << sigma*waterDensity/(1./cm) << G4endl;
289     G4cout << "G4DNAEmfietzoglouIonisationMode    289     G4cout << "G4DNAEmfietzoglouIonisationModel - XS INFO END" << G4endl;
290   }                                               290   }
291                                                   291 
292   return sigma*waterDensity;                      292   return sigma*waterDensity;
293 }                                                 293 }
294                                                   294 
295 //....oooOO0OOooo........oooOO0OOooo........oo    295 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
296                                                   296 
297 void G4DNAEmfietzoglouIonisationModel::           297 void G4DNAEmfietzoglouIonisationModel::
298 SampleSecondaries(std::vector<G4DynamicParticl    298 SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
299                   const G4MaterialCutsCouple*     299                   const G4MaterialCutsCouple* couple,
300                   const G4DynamicParticle* par    300                   const G4DynamicParticle* particle,
301                   G4double,                       301                   G4double,
302                   G4double)                       302                   G4double)
303 {                                                 303 {
304                                                   304 
305   if(verboseLevel > 3)                            305   if(verboseLevel > 3)
306   {                                               306   {
307     G4cout << "Calling SampleSecondaries() of     307     G4cout << "Calling SampleSecondaries() of G4DNAEmfietzoglouIonisationModel"
308            << G4endl;                             308            << G4endl;
309   }                                               309   }
310                                                   310 
311   G4double k = particle->GetKineticEnergy();      311   G4double k = particle->GetKineticEnergy();
312                                                   312 
313   const G4String& particleName = particle->Get    313   const G4String& particleName = particle->GetDefinition()->GetParticleName();
314                                                   314 
315   if (k >= LowEnergyLimit() && k <= HighEnergy    315   if (k >= LowEnergyLimit() && k <= HighEnergyLimit())
316   {                                               316   {
317     G4ParticleMomentum primaryDirection = part    317     G4ParticleMomentum primaryDirection = particle->GetMomentumDirection();
318     G4double particleMass = particle->GetDefin    318     G4double particleMass = particle->GetDefinition()->GetPDGMass();
319     G4double totalEnergy = k + particleMass;      319     G4double totalEnergy = k + particleMass;
320     G4double pSquare = k * (totalEnergy + part    320     G4double pSquare = k * (totalEnergy + particleMass);
321     G4double totalMomentum = std::sqrt(pSquare    321     G4double totalMomentum = std::sqrt(pSquare);
322                                                   322 
323     G4int ionizationShell = 0;                    323     G4int ionizationShell = 0;
324                                                   324 
325     ionizationShell = RandomSelect(k,particleN    325     ionizationShell = RandomSelect(k,particleName);
326                                                   326 
327     G4double bindingEnergy = 0;                   327     G4double bindingEnergy = 0;
328     bindingEnergy = waterStructure.IonisationE    328     bindingEnergy = waterStructure.IonisationEnergy(ionizationShell);
329                                                   329 
330     // SI : additional protection if tcs inter    330     // SI : additional protection if tcs interpolation method is modified
331     if (k<bindingEnergy) return;                  331     if (k<bindingEnergy) return;
332     //                                            332     //
333                                                   333 
334     G4double secondaryKinetic=-1000*eV;           334     G4double secondaryKinetic=-1000*eV;
335                                                   335 
336     if (!fasterCode) secondaryKinetic = Random    336     if (!fasterCode) secondaryKinetic = RandomizeEjectedElectronEnergy(particle->GetDefinition(),k,ionizationShell);
337                                                   337 
338     if (fasterCode)                               338     if (fasterCode)
339     secondaryKinetic = RandomizeEjectedElectro    339     secondaryKinetic = RandomizeEjectedElectronEnergyFromCumulatedDcs(particle->GetDefinition(),k,ionizationShell);
340                                                   340 
341     // SI - For atom. deexc. tagging - 23/05/2    341     // SI - For atom. deexc. tagging - 23/05/2017
342                                                   342 
343     G4int Z = 8;                                  343     G4int Z = 8;
344                                                   344 
345     G4ThreeVector deltaDirection =                345     G4ThreeVector deltaDirection =
346     GetAngularDistribution()->SampleDirectionF    346     GetAngularDistribution()->SampleDirectionForShell(particle, secondaryKinetic,
347         Z, ionizationShell,                       347         Z, ionizationShell,
348         couple->GetMaterial());                   348         couple->GetMaterial());
349                                                   349 
350     if (secondaryKinetic>0)                       350     if (secondaryKinetic>0)
351     {                                             351     {
352       auto  dp = new G4DynamicParticle (G4Elec    352       auto  dp = new G4DynamicParticle (G4Electron::Electron(),deltaDirection,secondaryKinetic);
353       fvect->push_back(dp);                       353       fvect->push_back(dp);
354     }                                             354     }
355                                                   355 
356     G4double deltaTotalMomentum = std::sqrt(se    356     G4double deltaTotalMomentum = std::sqrt(secondaryKinetic*(secondaryKinetic + 2.*electron_mass_c2 ));
357                                                   357 
358     G4double finalPx = totalMomentum*primaryDi    358     G4double finalPx = totalMomentum*primaryDirection.x() - deltaTotalMomentum*deltaDirection.x();
359     G4double finalPy = totalMomentum*primaryDi    359     G4double finalPy = totalMomentum*primaryDirection.y() - deltaTotalMomentum*deltaDirection.y();
360     G4double finalPz = totalMomentum*primaryDi    360     G4double finalPz = totalMomentum*primaryDirection.z() - deltaTotalMomentum*deltaDirection.z();
361     G4double finalMomentum = std::sqrt(finalPx    361     G4double finalMomentum = std::sqrt(finalPx*finalPx + finalPy*finalPy + finalPz*finalPz);
362     finalPx /= finalMomentum;                     362     finalPx /= finalMomentum;
363     finalPy /= finalMomentum;                     363     finalPy /= finalMomentum;
364     finalPz /= finalMomentum;                     364     finalPz /= finalMomentum;
365                                                   365 
366     G4ThreeVector direction;                      366     G4ThreeVector direction;
367     direction.set(finalPx,finalPy,finalPz);       367     direction.set(finalPx,finalPy,finalPz);
368                                                   368 
369     fParticleChangeForGamma->ProposeMomentumDi    369     fParticleChangeForGamma->ProposeMomentumDirection(direction.unit());
370                                                   370 
371     // AM: sample deexcitation                    371     // AM: sample deexcitation
372     // here we assume that H_{2}O electronic l    372     // here we assume that H_{2}O electronic levels are the same as Oxygen.
373     // this can be considered true with a roug    373     // this can be considered true with a rough 10% error in energy on K-shell,
374                                                   374 
375     size_t secNumberInit = 0;// need to know a    375     size_t secNumberInit = 0;// need to know at a certain point the energy of secondaries
376     size_t secNumberFinal = 0;// So I'll make     376     size_t secNumberFinal = 0;// So I'll make the diference and then sum the energies
377                                                   377 
378     G4double scatteredEnergy = k-bindingEnergy    378     G4double scatteredEnergy = k-bindingEnergy-secondaryKinetic;
379                                                   379 
380     // SI: only atomic deexcitation from K she    380     // SI: only atomic deexcitation from K shell is considered
381     if((fAtomDeexcitation != nullptr) && ioniz    381     if((fAtomDeexcitation != nullptr) && ionizationShell == 4)
382     {                                             382     {
383       const G4AtomicShell* shell                  383       const G4AtomicShell* shell
384         = fAtomDeexcitation->GetAtomicShell(Z,    384         = fAtomDeexcitation->GetAtomicShell(Z, G4AtomicShellEnumerator(0));
385       secNumberInit = fvect->size();              385       secNumberInit = fvect->size();
386       fAtomDeexcitation->GenerateParticles(fve    386       fAtomDeexcitation->GenerateParticles(fvect, shell, Z, 0, 0);
387       secNumberFinal = fvect->size();             387       secNumberFinal = fvect->size();
388                                                   388 
389       if(secNumberFinal > secNumberInit) {        389       if(secNumberFinal > secNumberInit) {
390   for (size_t i=secNumberInit; i<secNumberFina    390   for (size_t i=secNumberInit; i<secNumberFinal; ++i) {
391           //Check if there is enough residual     391           //Check if there is enough residual energy
392           if (bindingEnergy >= ((*fvect)[i])->    392           if (bindingEnergy >= ((*fvect)[i])->GetKineticEnergy())
393            {                                      393            {
394              //Ok, this is a valid secondary:     394              //Ok, this is a valid secondary: keep it
395        bindingEnergy -= ((*fvect)[i])->GetKine    395        bindingEnergy -= ((*fvect)[i])->GetKineticEnergy();
396            }                                      396            }
397           else                                    397           else
398            {                                      398            {
399        //Invalid secondary: not enough energy     399        //Invalid secondary: not enough energy to create it!
400        //Keep its energy in the local deposit     400        //Keep its energy in the local deposit
401              delete (*fvect)[i];                  401              delete (*fvect)[i];
402              (*fvect)[i]=nullptr;                 402              (*fvect)[i]=nullptr;
403            }                                      403            }
404   }                                               404   }
405       }                                           405       }
406                                                   406 
407     }                                             407     }
408                                                   408 
409     //This should never happen                    409     //This should never happen
410     if(bindingEnergy < 0.0)                       410     if(bindingEnergy < 0.0)
411      G4Exception("G4DNAEmfietzoglouIonisatioMo    411      G4Exception("G4DNAEmfietzoglouIonisatioModel1::SampleSecondaries()",
412                  "em2050",FatalException,"Nega    412                  "em2050",FatalException,"Negative local energy deposit");
413                                                   413 
414     //bindingEnergy has been decreased            414     //bindingEnergy has been decreased
415     //by the amount of energy taken away by de    415     //by the amount of energy taken away by deexc. products
416     if (!statCode)                                416     if (!statCode)
417     {                                             417     {
418       fParticleChangeForGamma->SetProposedKine    418       fParticleChangeForGamma->SetProposedKineticEnergy(scatteredEnergy);
419       fParticleChangeForGamma->ProposeLocalEne    419       fParticleChangeForGamma->ProposeLocalEnergyDeposit(bindingEnergy);
420     }                                             420     }
421     else                                          421     else
422     {                                             422     {
423       fParticleChangeForGamma->SetProposedKine    423       fParticleChangeForGamma->SetProposedKineticEnergy(k);
424       fParticleChangeForGamma->ProposeLocalEne    424       fParticleChangeForGamma->ProposeLocalEnergyDeposit(k-scatteredEnergy);
425     }                                             425     }
426     // TEST //////////////////////////            426     // TEST //////////////////////////
427     // if (secondaryKinetic<0) abort();           427     // if (secondaryKinetic<0) abort();
428     // if (scatteredEnergy<0) abort();            428     // if (scatteredEnergy<0) abort();
429     // if (k-scatteredEnergy-secondaryKinetic-    429     // if (k-scatteredEnergy-secondaryKinetic-deexSecEnergy<0) abort();
430     // if (k-scatteredEnergy<0) abort();          430     // if (k-scatteredEnergy<0) abort();
431     /////////////////////////////////             431     /////////////////////////////////
432                                                   432 
433     const G4Track * theIncomingTrack = fPartic    433     const G4Track * theIncomingTrack = fParticleChangeForGamma->GetCurrentTrack();
434     G4DNAChemistryManager::Instance()->CreateW    434     G4DNAChemistryManager::Instance()->CreateWaterMolecule(eIonizedMolecule,
435         ionizationShell,                          435         ionizationShell,
436         theIncomingTrack);                        436         theIncomingTrack);
437   }                                               437   }
438                                                   438 
439 }                                                 439 }
440                                                   440 
441 //....oooOO0OOooo........oooOO0OOooo........oo    441 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
442                                                   442 
443 G4double                                          443 G4double
444 G4DNAEmfietzoglouIonisationModel::                444 G4DNAEmfietzoglouIonisationModel::
445 RandomizeEjectedElectronEnergy(G4ParticleDefin    445 RandomizeEjectedElectronEnergy(G4ParticleDefinition* particleDefinition,
446                                G4double k,        446                                G4double k,
447                                G4int shell)       447                                G4int shell)
448 {                                                 448 {
449   // G4cout << "*** SLOW computation for "        449   // G4cout << "*** SLOW computation for "
450   //        << " " << particleDefinition->GetP    450   //        << " " << particleDefinition->GetParticleName() << G4endl;
451                                                   451 
452   if(particleDefinition == G4Electron::Electro    452   if(particleDefinition == G4Electron::ElectronDefinition())
453   {                                               453   {
454     G4double maximumEnergyTransfer = 0.;          454     G4double maximumEnergyTransfer = 0.;
455     if((k + waterStructure.IonisationEnergy(sh    455     if((k + waterStructure.IonisationEnergy(shell)) / 2. > k)
456       maximumEnergyTransfer =  k;                 456       maximumEnergyTransfer =  k;
457     else                                          457     else
458       maximumEnergyTransfer = (k + waterStruct    458       maximumEnergyTransfer = (k + waterStructure.IonisationEnergy(shell))/ 2.;
459                                                   459 
460     // SI : original method                       460     // SI : original method
461     /*                                            461     /*
462      G4double crossSectionMaximum = 0.;           462      G4double crossSectionMaximum = 0.;
463      for(G4double value=waterStructure.Ionisat    463      for(G4double value=waterStructure.IonisationEnergy(shell); value<=maximumEnergyTransfer; value+=0.1*eV)
464      {                                            464      {
465      G4double differentialCrossSection = Diffe    465      G4double differentialCrossSection = DifferentialCrossSection(particleDefinition, k/eV, value/eV, shell);
466      if(differentialCrossSection >= crossSecti    466      if(differentialCrossSection >= crossSectionMaximum) crossSectionMaximum = differentialCrossSection;
467      }                                            467      }
468     */                                            468     */
469                                                   469 
470     // SI : alternative method                    470     // SI : alternative method
471     G4double crossSectionMaximum = 0.;            471     G4double crossSectionMaximum = 0.;
472                                                   472 
473     G4double minEnergy = waterStructure.Ionisa    473     G4double minEnergy = waterStructure.IonisationEnergy(shell);
474     G4double maxEnergy = maximumEnergyTransfer    474     G4double maxEnergy = maximumEnergyTransfer;
475     G4int nEnergySteps = 50;                      475     G4int nEnergySteps = 50;
476                                                   476 
477     G4double value(minEnergy);                    477     G4double value(minEnergy);
478     G4double stpEnergy(std::pow(maxEnergy / va    478     G4double stpEnergy(std::pow(maxEnergy / value,
479                                 1. / static_ca    479                                 1. / static_cast<G4double>(nEnergySteps - 1)));
480     G4int step(nEnergySteps);                     480     G4int step(nEnergySteps);
481     while(step > 0)                               481     while(step > 0)
482     {                                             482     {
483       step--;                                     483       step--;
484       G4double differentialCrossSection =         484       G4double differentialCrossSection =
485           DifferentialCrossSection(particleDef    485           DifferentialCrossSection(particleDefinition,
486                                    k / eV,        486                                    k / eV,
487                                    value / eV,    487                                    value / eV,
488                                    shell);        488                                    shell);
489       if(differentialCrossSection >= crossSect    489       if(differentialCrossSection >= crossSectionMaximum) crossSectionMaximum =
490           differentialCrossSection;               490           differentialCrossSection;
491       value *= stpEnergy;                         491       value *= stpEnergy;
492     }                                             492     }
493     //                                            493     //
494                                                   494 
495     G4double secondaryElectronKineticEnergy =     495     G4double secondaryElectronKineticEnergy = 0.;
496     do                                            496     do
497     {                                             497     {
498       secondaryElectronKineticEnergy = G4Unifo    498       secondaryElectronKineticEnergy = G4UniformRand()* (maximumEnergyTransfer-waterStructure.IonisationEnergy(shell));
499     }while(G4UniformRand()*crossSectionMaximum    499     }while(G4UniformRand()*crossSectionMaximum >
500         DifferentialCrossSection(particleDefin    500         DifferentialCrossSection(particleDefinition, k/eV,
501             (secondaryElectronKineticEnergy+wa    501             (secondaryElectronKineticEnergy+waterStructure.IonisationEnergy(shell))/eV,shell));
502                                                   502 
503     return secondaryElectronKineticEnergy;        503     return secondaryElectronKineticEnergy;
504                                                   504 
505   }                                               505   }
506                                                   506 
507   return 0;                                       507   return 0;
508 }                                                 508 }
509                                                   509 
510 //....oooOO0OOooo........oooOO0OOooo........oo    510 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
511                                                   511 
512 // The following section is not used anymore b    512 // The following section is not used anymore but is kept for memory
513 // GetAngularDistribution()->SampleDirectionFo    513 // GetAngularDistribution()->SampleDirectionForShell is used instead
514                                                   514 
515 /*                                                515 /*
516  void G4DNAEmfietzoglouIonisationModel::Random    516  void G4DNAEmfietzoglouIonisationModel::RandomizeEjectedElectronDirection(G4ParticleDefinition* particleDefinition,
517  G4double k,                                      517  G4double k,
518  G4double secKinetic,                             518  G4double secKinetic,
519  G4double & cosTheta,                             519  G4double & cosTheta,
520  G4double & phi )                                 520  G4double & phi )
521  {                                                521  {
522  if (particleDefinition == G4Electron::Electro    522  if (particleDefinition == G4Electron::ElectronDefinition())
523  {                                                523  {
524  phi = twopi * G4UniformRand();                   524  phi = twopi * G4UniformRand();
525  if (secKinetic < 50.*eV) cosTheta = (2.*G4Uni    525  if (secKinetic < 50.*eV) cosTheta = (2.*G4UniformRand())-1.;
526  else if (secKinetic <= 200.*eV)                  526  else if (secKinetic <= 200.*eV)
527  {                                                527  {
528  if (G4UniformRand() <= 0.1) cosTheta = (2.*G4    528  if (G4UniformRand() <= 0.1) cosTheta = (2.*G4UniformRand())-1.;
529  else cosTheta = G4UniformRand()*(std::sqrt(2.    529  else cosTheta = G4UniformRand()*(std::sqrt(2.)/2);
530  }                                                530  }
531  else                                             531  else
532  {                                                532  {
533  G4double sin2O = (1.-secKinetic/k) / (1.+secK    533  G4double sin2O = (1.-secKinetic/k) / (1.+secKinetic/(2.*electron_mass_c2));
534  cosTheta = std::sqrt(1.-sin2O);                  534  cosTheta = std::sqrt(1.-sin2O);
535  }                                                535  }
536  }                                                536  }
537                                                   537 
538  else if (particleDefinition == G4Proton::Prot    538  else if (particleDefinition == G4Proton::ProtonDefinition())
539  {                                                539  {
540  G4double maxSecKinetic = 4.* (electron_mass_c    540  G4double maxSecKinetic = 4.* (electron_mass_c2 / proton_mass_c2) * k;
541  phi = twopi * G4UniformRand();                   541  phi = twopi * G4UniformRand();
542                                                   542 
543  // cosTheta = std::sqrt(secKinetic / maxSecKi    543  // cosTheta = std::sqrt(secKinetic / maxSecKinetic);
544                                                   544 
545  // Restriction below 100 eV from Emfietzoglou    545  // Restriction below 100 eV from Emfietzoglou (2000)
546                                                   546 
547  if (secKinetic>100*eV) cosTheta = std::sqrt(s    547  if (secKinetic>100*eV) cosTheta = std::sqrt(secKinetic / maxSecKinetic);
548  else cosTheta = (2.*G4UniformRand())-1.;         548  else cosTheta = (2.*G4UniformRand())-1.;
549                                                   549 
550  }                                                550  }
551  }                                                551  }
552  */                                               552  */
553                                                   553 
554 //....oooOO0OOooo........oooOO0OOooo........oo    554 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
555 G4double G4DNAEmfietzoglouIonisationModel::Dif    555 G4double G4DNAEmfietzoglouIonisationModel::DifferentialCrossSection(G4ParticleDefinition * particleDefinition,
556                                                   556                                                                   G4double k,
557                                                   557                                                                   G4double energyTransfer,
558                                                   558                                                                   G4int ionizationLevelIndex)
559 {                                                 559 {
560   G4double sigma = 0.;                            560   G4double sigma = 0.;
561                                                   561 
562   if(energyTransfer >= waterStructure.Ionisati    562   if(energyTransfer >= waterStructure.IonisationEnergy(ionizationLevelIndex)/eV)
563   {                                               563   {
564     G4double valueT1 = 0;                         564     G4double valueT1 = 0;
565     G4double valueT2 = 0;                         565     G4double valueT2 = 0;
566     G4double valueE21 = 0;                        566     G4double valueE21 = 0;
567     G4double valueE22 = 0;                        567     G4double valueE22 = 0;
568     G4double valueE12 = 0;                        568     G4double valueE12 = 0;
569     G4double valueE11 = 0;                        569     G4double valueE11 = 0;
570                                                   570 
571     G4double xs11 = 0;                            571     G4double xs11 = 0;
572     G4double xs12 = 0;                            572     G4double xs12 = 0;
573     G4double xs21 = 0;                            573     G4double xs21 = 0;
574     G4double xs22 = 0;                            574     G4double xs22 = 0;
575                                                   575 
576     if(particleDefinition == G4Electron::Elect    576     if(particleDefinition == G4Electron::ElectronDefinition())
577     {                                             577     {
578       // Protection against out of boundary ac    578       // Protection against out of boundary access
579       if (k==eTdummyVec.back()) k=k*(1.-1e-12)    579       if (k==eTdummyVec.back()) k=k*(1.-1e-12);
580       //                                          580       //
581                                                   581 
582       // k should be in eV and energy transfer    582       // k should be in eV and energy transfer eV also
583                                                   583 
584       auto t2 = std::upper_bound(eTdummyVec.be    584       auto t2 = std::upper_bound(eTdummyVec.begin(),
585                                                   585                                                           eTdummyVec.end(),
586                                                   586                                                           k);
587                                                   587 
588       auto t1 = t2 - 1;                           588       auto t1 = t2 - 1;
589                                                   589 
590       // SI : the following condition avoids s    590       // SI : the following condition avoids situations where energyTransfer >last vector element
591       // added strict limitations (09/08/2017)    591       // added strict limitations (09/08/2017)
592       if(energyTransfer < eVecm[(*t1)].back()     592       if(energyTransfer < eVecm[(*t1)].back() &&
593          energyTransfer < eVecm[(*t2)].back())    593          energyTransfer < eVecm[(*t2)].back())
594       {                                           594       {
595         auto e12 =                                595         auto e12 =
596             std::upper_bound(eVecm[(*t1)].begi    596             std::upper_bound(eVecm[(*t1)].begin(),
597                              eVecm[(*t1)].end(    597                              eVecm[(*t1)].end(),
598                              energyTransfer);     598                              energyTransfer);
599         auto e11 = e12 - 1;                       599         auto e11 = e12 - 1;
600                                                   600 
601         auto e22 =                                601         auto e22 =
602             std::upper_bound(eVecm[(*t2)].begi    602             std::upper_bound(eVecm[(*t2)].begin(),
603                              eVecm[(*t2)].end(    603                              eVecm[(*t2)].end(),
604                              energyTransfer);     604                              energyTransfer);
605         auto e21 = e22 - 1;                       605         auto e21 = e22 - 1;
606                                                   606 
607         valueT1 = *t1;                            607         valueT1 = *t1;
608         valueT2 = *t2;                            608         valueT2 = *t2;
609         valueE21 = *e21;                          609         valueE21 = *e21;
610         valueE22 = *e22;                          610         valueE22 = *e22;
611         valueE12 = *e12;                          611         valueE12 = *e12;
612         valueE11 = *e11;                          612         valueE11 = *e11;
613                                                   613 
614         xs11 = eDiffCrossSectionData[ionizatio    614         xs11 = eDiffCrossSectionData[ionizationLevelIndex][valueT1][valueE11];
615         xs12 = eDiffCrossSectionData[ionizatio    615         xs12 = eDiffCrossSectionData[ionizationLevelIndex][valueT1][valueE12];
616         xs21 = eDiffCrossSectionData[ionizatio    616         xs21 = eDiffCrossSectionData[ionizationLevelIndex][valueT2][valueE21];
617         xs22 = eDiffCrossSectionData[ionizatio    617         xs22 = eDiffCrossSectionData[ionizationLevelIndex][valueT2][valueE22];
618                                                   618 
619         //G4cout << "-------------------" << G    619         //G4cout << "-------------------" << G4endl;
620         //G4cout << "ionizationLevelIndex=" <<    620         //G4cout << "ionizationLevelIndex=" << ionizationLevelIndex << G4endl;
621         //G4cout << "valueT1/eV=" << valueT1 <    621         //G4cout << "valueT1/eV=" << valueT1 << " valueT2/eV=" << valueT2 << G4endl;
622         //G4cout << "valueE11/eV=" << valueE11    622         //G4cout << "valueE11/eV=" << valueE11 << " valueE12/eV=" << valueE12
623         //       << " valueE21/eV=" << valueE2    623         //       << " valueE21/eV=" << valueE21 << " valueE22/eV=" << valueE22 << G4endl;
624         //G4cout << "xs11=" << xs11 / ((1.e-22    624         //G4cout << "xs11=" << xs11 / ((1.e-22 / 3.343) * m*m) << G4endl;
625         //G4cout << "xs12=" << xs12 / ((1.e-22    625         //G4cout << "xs12=" << xs12 / ((1.e-22 / 3.343) * m*m) << G4endl;
626         //G4cout << "xs21=" << xs21 / ((1.e-22    626         //G4cout << "xs21=" << xs21 / ((1.e-22 / 3.343) * m*m) << G4endl;
627         //G4cout << "xs22=" << xs22 / ((1.e-22    627         //G4cout << "xs22=" << xs22 / ((1.e-22 / 3.343) * m*m) << G4endl;
628         //G4cout << "###################" << G    628         //G4cout << "###################" << G4endl;
629                                                   629 
630       }                                           630       }
631                                                   631 
632     }                                             632     }
633                                                   633 
634     G4double xsProduct = xs11 * xs12 * xs21 *     634     G4double xsProduct = xs11 * xs12 * xs21 * xs22;
635     if(xsProduct != 0.)                           635     if(xsProduct != 0.)
636     {                                             636     {
637       sigma = QuadInterpolator(valueE11,          637       sigma = QuadInterpolator(valueE11,
638                                valueE12,          638                                valueE12,
639                                valueE21,          639                                valueE21,
640                                valueE22,          640                                valueE22,
641                                xs11,              641                                xs11,
642                                xs12,              642                                xs12,
643                                xs21,              643                                xs21,
644                                xs22,              644                                xs22,
645                                valueT1,           645                                valueT1,
646                                valueT2,           646                                valueT2,
647                                k,                 647                                k,
648                                energyTransfer)    648                                energyTransfer);
649     }                                             649     }
650                                                   650 
651   }                                               651   }
652                                                   652 
653   return sigma;                                   653   return sigma;
654 }                                                 654 }
655                                                   655 
656 //....oooOO0OOooo........oooOO0OOooo........oo    656 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
657                                                   657 
658 G4double G4DNAEmfietzoglouIonisationModel::Int    658 G4double G4DNAEmfietzoglouIonisationModel::Interpolate(G4double e1,
659                                                   659                                                        G4double e2,
660                                                   660                                                        G4double e,
661                                                   661                                                        G4double xs1,
662                                                   662                                                        G4double xs2)
663 {                                                 663 {
664                                                   664 
665   G4double value = 0.;                            665   G4double value = 0.;
666                                                   666 
667   // Log-log interpolation by default             667   // Log-log interpolation by default
668                                                   668 
669   if(e1 != 0 && e2 != 0 && (std::log10(e2) - s    669   if(e1 != 0 && e2 != 0 && (std::log10(e2) - std::log10(e1)) != 0
670      && !fasterCode)                              670      && !fasterCode)
671   {                                               671   {
672     G4double a = (std::log10(xs2) - std::log10    672     G4double a = (std::log10(xs2) - std::log10(xs1))
673         / (std::log10(e2) - std::log10(e1));      673         / (std::log10(e2) - std::log10(e1));
674     G4double b = std::log10(xs2) - a * std::lo    674     G4double b = std::log10(xs2) - a * std::log10(e2);
675     G4double sigma = a * std::log10(e) + b;       675     G4double sigma = a * std::log10(e) + b;
676     value = (std::pow(10., sigma));               676     value = (std::pow(10., sigma));
677   }                                               677   }
678                                                   678 
679   // Switch to lin-lin interpolation              679   // Switch to lin-lin interpolation
680   /*                                              680   /*
681    if ((e2-e1)!=0)                                681    if ((e2-e1)!=0)
682    {                                              682    {
683    G4double d1 = xs1;                             683    G4double d1 = xs1;
684    G4double d2 = xs2;                             684    G4double d2 = xs2;
685    value = (d1 + (d2 - d1)*(e - e1)/ (e2 - e1)    685    value = (d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
686    }                                              686    }
687   */                                              687   */
688                                                   688 
689   // Switch to log-lin interpolation for faste    689   // Switch to log-lin interpolation for faster code
690   if((e2 - e1) != 0 && xs1 != 0 && xs2 != 0 &&    690   if((e2 - e1) != 0 && xs1 != 0 && xs2 != 0 && fasterCode)
691   {                                               691   {
692     G4double d1 = std::log10(xs1);                692     G4double d1 = std::log10(xs1);
693     G4double d2 = std::log10(xs2);                693     G4double d2 = std::log10(xs2);
694     value = std::pow(10., (d1 + (d2 - d1) * (e    694     value = std::pow(10., (d1 + (d2 - d1) * (e - e1) / (e2 - e1)));
695   }                                               695   }
696                                                   696 
697   // Switch to lin-lin interpolation for faste    697   // Switch to lin-lin interpolation for faster code
698   // in case one of xs1 or xs2 (=cum proba) va    698   // in case one of xs1 or xs2 (=cum proba) value is zero
699                                                   699 
700   if((e2 - e1) != 0 && (xs1 == 0 || xs2 == 0)     700   if((e2 - e1) != 0 && (xs1 == 0 || xs2 == 0) && fasterCode)
701   {                                               701   {
702     G4double d1 = xs1;                            702     G4double d1 = xs1;
703     G4double d2 = xs2;                            703     G4double d2 = xs2;
704     value = (d1 + (d2 - d1) * (e - e1) / (e2 -    704     value = (d1 + (d2 - d1) * (e - e1) / (e2 - e1));
705   }                                               705   }
706                                                   706 
707   /*                                              707   /*
708    G4cout                                         708    G4cout
709    << e1 << " "                                   709    << e1 << " "
710    << e2 << " "                                   710    << e2 << " "
711    << e  << " "                                   711    << e  << " "
712    << xs1 << " "                                  712    << xs1 << " "
713    << xs2 << " "                                  713    << xs2 << " "
714    << value                                       714    << value
715    << G4endl;                                     715    << G4endl;
716   */                                              716   */
717                                                   717 
718   return value;                                   718   return value;
719 }                                                 719 }
720                                                   720 
721 //....oooOO0OOooo........oooOO0OOooo........oo    721 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
722                                                   722 
723 G4double G4DNAEmfietzoglouIonisationModel::Qua    723 G4double G4DNAEmfietzoglouIonisationModel::QuadInterpolator(G4double e11,
724                                                   724                                                             G4double e12,
725                                                   725                                                             G4double e21,
726                                                   726                                                             G4double e22,
727                                                   727                                                             G4double xs11,
728                                                   728                                                             G4double xs12,
729                                                   729                                                             G4double xs21,
730                                                   730                                                             G4double xs22,
731                                                   731                                                             G4double t1,
732                                                   732                                                             G4double t2,
733                                                   733                                                             G4double t,
734                                                   734                                                             G4double e)
735 {                                                 735 {
736   G4double interpolatedvalue1 = Interpolate(e1    736   G4double interpolatedvalue1 = Interpolate(e11, e12, e, xs11, xs12);
737   G4double interpolatedvalue2 = Interpolate(e2    737   G4double interpolatedvalue2 = Interpolate(e21, e22, e, xs21, xs22);
738   G4double value = Interpolate(t1,                738   G4double value = Interpolate(t1,
739                                t2,                739                                t2,
740                                t,                 740                                t,
741                                interpolatedval    741                                interpolatedvalue1,
742                                interpolatedval    742                                interpolatedvalue2);
743                                                   743 
744   return value;                                   744   return value;
745 }                                                 745 }
746                                                   746 
747 //....oooOO0OOooo........oooOO0OOooo........oo    747 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
748                                                   748 
749 G4int G4DNAEmfietzoglouIonisationModel::Random    749 G4int G4DNAEmfietzoglouIonisationModel::RandomSelect(G4double k,
750                                                   750                                                      const G4String& particle)
751 {                                                 751 {
752   G4int level = 0;                                752   G4int level = 0;
753                                                   753 
754   auto pos = tableData.find(particle);            754   auto pos = tableData.find(particle);
755                                                   755 
756   if(pos != tableData.cend())                     756   if(pos != tableData.cend())
757   {                                               757   {
758     G4DNACrossSectionDataSet* table = pos->sec    758     G4DNACrossSectionDataSet* table = pos->second;
759                                                   759 
760     if(table != nullptr)                          760     if(table != nullptr)
761     {                                             761     {
762       auto  valuesBuffer = new G4double[table-    762       auto  valuesBuffer = new G4double[table->NumberOfComponents()];
763       const auto  n = (G4int)table->NumberOfCo    763       const auto  n = (G4int)table->NumberOfComponents();
764       G4int i(n);                                 764       G4int i(n);
765       G4double value = 0.;                        765       G4double value = 0.;
766                                                   766 
767       while(i > 0)                                767       while(i > 0)
768       {                                           768       {
769         i--;                                      769         i--;
770         valuesBuffer[i] = table->GetComponent(    770         valuesBuffer[i] = table->GetComponent(i)->FindValue(k);
771         value += valuesBuffer[i];                 771         value += valuesBuffer[i];
772       }                                           772       }
773                                                   773 
774       value *= G4UniformRand();                   774       value *= G4UniformRand();
775                                                   775 
776       i = n;                                      776       i = n;
777                                                   777 
778       while(i > 0)                                778       while(i > 0)
779       {                                           779       {
780         i--;                                      780         i--;
781                                                   781 
782         if(valuesBuffer[i] > value)               782         if(valuesBuffer[i] > value)
783         {                                         783         {
784           delete[] valuesBuffer;                  784           delete[] valuesBuffer;
785           return i;                               785           return i;
786         }                                         786         }
787         value -= valuesBuffer[i];                 787         value -= valuesBuffer[i];
788       }                                           788       }
789                                                   789 
790       delete[] valuesBuffer;                      790       delete[] valuesBuffer;
791                                                   791 
792     }                                             792     }
793   }                                               793   }
794   else                                            794   else
795   {                                               795   {
796     G4Exception("G4DNAEmfietzoglouIonisationMo    796     G4Exception("G4DNAEmfietzoglouIonisationModel::RandomSelect",
797                 "em0002",                         797                 "em0002",
798                 FatalException,                   798                 FatalException,
799                 "Model not applicable to parti    799                 "Model not applicable to particle type.");
800   }                                               800   }
801                                                   801 
802   return level;                                   802   return level;
803 }                                                 803 }
804                                                   804 
805 //....oooOO0OOooo........oooOO0OOooo........oo    805 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
806                                                   806 
807 G4double G4DNAEmfietzoglouIonisationModel::Ran    807 G4double G4DNAEmfietzoglouIonisationModel::RandomizeEjectedElectronEnergyFromCumulatedDcs(G4ParticleDefinition* particleDefinition,
808                                                   808                                                                                           G4double k,
809                                                   809                                                                                           G4int shell)
810 {                                                 810 {
811   //G4cout << "*** FAST computation for " << "    811   //G4cout << "*** FAST computation for " << " " << particleDefinition->GetParticleName() << G4endl;
812                                                   812 
813   G4double secondaryElectronKineticEnergy = 0.    813   G4double secondaryElectronKineticEnergy = 0.;
814                                                   814 
815   secondaryElectronKineticEnergy = RandomTrans    815   secondaryElectronKineticEnergy = RandomTransferedEnergy(particleDefinition,
816                                                   816                                                           k / eV,
817                                                   817                                                           shell)
818                                    * eV           818                                    * eV
819                                    - waterStru    819                                    - waterStructure.IonisationEnergy(shell);
820                                                   820 
821   //G4cout << RandomTransferedEnergy(particleD    821   //G4cout << RandomTransferedEnergy(particleDefinition, k/eV, shell) << G4endl;
822   if(secondaryElectronKineticEnergy < 0.) retu    822   if(secondaryElectronKineticEnergy < 0.) return 0.;
823                                                   823 
824   return secondaryElectronKineticEnergy;          824   return secondaryElectronKineticEnergy;
825 }                                                 825 }
826                                                   826 
827 //....oooOO0OOooo........oooOO0OOooo........oo    827 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
828                                                   828 
829 G4double G4DNAEmfietzoglouIonisationModel::Ran    829 G4double G4DNAEmfietzoglouIonisationModel::RandomTransferedEnergy(G4ParticleDefinition* particleDefinition,
830                                                   830                                                                   G4double k,
831                                                   831                                                                   G4int ionizationLevelIndex)
832 {                                                 832 {
833                                                   833 
834   G4double random = G4UniformRand();              834   G4double random = G4UniformRand();
835                                                   835 
836   G4double nrj = 0.;                              836   G4double nrj = 0.;
837                                                   837 
838   G4double valueK1 = 0;                           838   G4double valueK1 = 0;
839   G4double valueK2 = 0;                           839   G4double valueK2 = 0;
840   G4double valuePROB21 = 0;                       840   G4double valuePROB21 = 0;
841   G4double valuePROB22 = 0;                       841   G4double valuePROB22 = 0;
842   G4double valuePROB12 = 0;                       842   G4double valuePROB12 = 0;
843   G4double valuePROB11 = 0;                       843   G4double valuePROB11 = 0;
844                                                   844 
845   G4double nrjTransf11 = 0;                       845   G4double nrjTransf11 = 0;
846   G4double nrjTransf12 = 0;                       846   G4double nrjTransf12 = 0;
847   G4double nrjTransf21 = 0;                       847   G4double nrjTransf21 = 0;
848   G4double nrjTransf22 = 0;                       848   G4double nrjTransf22 = 0;
849                                                   849 
850   if (particleDefinition == G4Electron::Electr    850   if (particleDefinition == G4Electron::ElectronDefinition())
851   {                                               851   {
852     // Protection against out of boundary acce    852     // Protection against out of boundary access
853     if (k==eTdummyVec.back()) k=k*(1.-1e-12);     853     if (k==eTdummyVec.back()) k=k*(1.-1e-12);
854     //                                            854     //
855                                                   855 
856     // k should be in eV                          856     // k should be in eV
857     auto k2 = std::upper_bound(eTdummyVec.begi    857     auto k2 = std::upper_bound(eTdummyVec.begin(),eTdummyVec.end(), k);
858                                                   858 
859     auto k1 = k2-1;                               859     auto k1 = k2-1;
860                                                   860 
861     /*                                            861     /*
862      G4cout << "----> k=" << k                    862      G4cout << "----> k=" << k
863      << " " << *k1                                863      << " " << *k1
864      << " " << *k2                                864      << " " << *k2
865      << " " << random                             865      << " " << random
866      << " " << ionizationLevelIndex               866      << " " << ionizationLevelIndex
867      << " " << eProbaShellMap[ionizationLevelI    867      << " " << eProbaShellMap[ionizationLevelIndex][(*k1)].back()
868      << " " << eProbaShellMap[ionizationLevelI    868      << " " << eProbaShellMap[ionizationLevelIndex][(*k2)].back()
869      << G4endl;                                   869      << G4endl;
870      */                                           870      */
871                                                   871 
872     // SI : the following condition avoids sit    872     // SI : the following condition avoids situations where random >last vector element
873     if ( random <= eProbaShellMap[ionizationLe    873     if ( random <= eProbaShellMap[ionizationLevelIndex][(*k1)].back()
874         && random <= eProbaShellMap[ionization    874         && random <= eProbaShellMap[ionizationLevelIndex][(*k2)].back() )
875                                                   875 
876     {                                             876     {
877       auto prob12 = std::upper_bound(eProbaShe    877       auto prob12 = std::upper_bound(eProbaShellMap[ionizationLevelIndex][(*k1)].begin(),
878           eProbaShellMap[ionizationLevelIndex]    878           eProbaShellMap[ionizationLevelIndex][(*k1)].end(), random);
879                                                   879 
880       auto prob11 = prob12-1;                     880       auto prob11 = prob12-1;
881                                                   881 
882       auto prob22 = std::upper_bound(eProbaShe    882       auto prob22 = std::upper_bound(eProbaShellMap[ionizationLevelIndex][(*k2)].begin(),
883           eProbaShellMap[ionizationLevelIndex]    883           eProbaShellMap[ionizationLevelIndex][(*k2)].end(), random);
884                                                   884 
885       auto prob21 = prob22-1;                     885       auto prob21 = prob22-1;
886                                                   886 
887       valueK1 =*k1;                               887       valueK1 =*k1;
888       valueK2 =*k2;                               888       valueK2 =*k2;
889       valuePROB21 =*prob21;                       889       valuePROB21 =*prob21;
890       valuePROB22 =*prob22;                       890       valuePROB22 =*prob22;
891       valuePROB12 =*prob12;                       891       valuePROB12 =*prob12;
892       valuePROB11 =*prob11;                       892       valuePROB11 =*prob11;
893                                                   893 
894       /*                                          894       /*
895        G4cout << "        " << random << " " <    895        G4cout << "        " << random << " " << valuePROB11 << " "
896        << valuePROB12 << " " << valuePROB21 <<    896        << valuePROB12 << " " << valuePROB21 << " " << valuePROB22 << G4endl;
897        */                                         897        */
898                                                   898 
899       nrjTransf11 = eNrjTransfData[ionizationL    899       nrjTransf11 = eNrjTransfData[ionizationLevelIndex][valueK1][valuePROB11];
900       nrjTransf12 = eNrjTransfData[ionizationL    900       nrjTransf12 = eNrjTransfData[ionizationLevelIndex][valueK1][valuePROB12];
901       nrjTransf21 = eNrjTransfData[ionizationL    901       nrjTransf21 = eNrjTransfData[ionizationLevelIndex][valueK2][valuePROB21];
902       nrjTransf22 = eNrjTransfData[ionizationL    902       nrjTransf22 = eNrjTransfData[ionizationLevelIndex][valueK2][valuePROB22];
903                                                   903 
904       /*                                          904       /*
905        G4cout << "        " << ionizationLevel    905        G4cout << "        " << ionizationLevelIndex << " "
906        << random << " " <<valueK1 << " " << va    906        << random << " " <<valueK1 << " " << valueK2 << G4endl;
907                                                   907 
908        G4cout << "        " << random << " " <    908        G4cout << "        " << random << " " << nrjTransf11 << " "
909        << nrjTransf12 << " " << nrjTransf21 <<    909        << nrjTransf12 << " " << nrjTransf21 << " " <<nrjTransf22 << G4endl;
910        */                                         910        */
911                                                   911 
912     }                                             912     }
913                                                   913 
914     // Avoids cases where cum xs is zero for k    914     // Avoids cases where cum xs is zero for k1 and is not for k2 (with always k1<k2)
915                                                   915 
916     if ( random > eProbaShellMap[ionizationLev    916     if ( random > eProbaShellMap[ionizationLevelIndex][(*k1)].back() )
917                                                   917 
918     {                                             918     {
919       auto prob22 = std::upper_bound(eProbaShe    919       auto prob22 = std::upper_bound(eProbaShellMap[ionizationLevelIndex][(*k2)].begin(),
920           eProbaShellMap[ionizationLevelIndex]    920           eProbaShellMap[ionizationLevelIndex][(*k2)].end(), random);
921                                                   921 
922       auto prob21 = prob22-1;                     922       auto prob21 = prob22-1;
923                                                   923 
924       valueK1 =*k1;                               924       valueK1 =*k1;
925       valueK2 =*k2;                               925       valueK2 =*k2;
926       valuePROB21 =*prob21;                       926       valuePROB21 =*prob21;
927       valuePROB22 =*prob22;                       927       valuePROB22 =*prob22;
928                                                   928 
929       //G4cout << "        " << random << " "     929       //G4cout << "        " << random << " " << valuePROB21 << " " << valuePROB22 << G4endl;
930                                                   930 
931       nrjTransf21 = eNrjTransfData[ionizationL    931       nrjTransf21 = eNrjTransfData[ionizationLevelIndex][valueK2][valuePROB21];
932       nrjTransf22 = eNrjTransfData[ionizationL    932       nrjTransf22 = eNrjTransfData[ionizationLevelIndex][valueK2][valuePROB22];
933                                                   933 
934       G4double interpolatedvalue2 = Interpolat    934       G4double interpolatedvalue2 = Interpolate(valuePROB21, valuePROB22, random, nrjTransf21, nrjTransf22);
935                                                   935 
936       // zeros are explicitly set                 936       // zeros are explicitly set
937                                                   937 
938       G4double value = Interpolate(valueK1, va    938       G4double value = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
939                                                   939 
940       /*                                          940       /*
941        G4cout << "        " << ionizationLevel    941        G4cout << "        " << ionizationLevelIndex << " "
942        << random << " " <<valueK1 << " " << va    942        << random << " " <<valueK1 << " " << valueK2 << G4endl;
943                                                   943 
944        G4cout << "        " << random << " " <    944        G4cout << "        " << random << " " << nrjTransf11 << " "
945        << nrjTransf12 << " " << nrjTransf21 <<    945        << nrjTransf12 << " " << nrjTransf21 << " " <<nrjTransf22 << G4endl;
946                                                   946 
947        G4cout << "ici" << " " << value << G4en    947        G4cout << "ici" << " " << value << G4endl;
948        */                                         948        */
949                                                   949 
950       return value;                               950       return value;
951     }                                             951     }
952                                                   952 
953   }                                               953   }
954                                                   954 
955   // End electron                                 955   // End electron
956                                                   956 
957   G4double nrjTransfProduct = nrjTransf11 * nr    957   G4double nrjTransfProduct = nrjTransf11 * nrjTransf12 * nrjTransf21 * nrjTransf22;
958                                                   958 
959   //G4cout << "nrjTransfProduct=" << nrjTransf    959   //G4cout << "nrjTransfProduct=" << nrjTransfProduct << G4endl;
960                                                   960 
961   if (nrjTransfProduct != 0.)                     961   if (nrjTransfProduct != 0.)
962   {                                               962   {
963     nrj = QuadInterpolator( valuePROB11, value    963     nrj = QuadInterpolator( valuePROB11, valuePROB12,
964         valuePROB21, valuePROB22,                 964         valuePROB21, valuePROB22,
965         nrjTransf11, nrjTransf12,                 965         nrjTransf11, nrjTransf12,
966         nrjTransf21, nrjTransf22,                 966         nrjTransf21, nrjTransf22,
967         valueK1, valueK2,                         967         valueK1, valueK2,
968         k, random);                               968         k, random);
969   }                                               969   }
970                                                   970 
971   //G4cout << nrj << endl;                        971   //G4cout << nrj << endl;
972                                                   972 
973   return nrj;                                     973   return nrj;
974 }                                                 974 }
975                                                   975