Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/models/src/G4DNAELSEPAElasticModel.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 ]

  1 //
  2 // ********************************************************************
  3 // * License and Disclaimer                                           *
  4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.                             *
 10 // *                                                                  *
 11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                                                  *
 18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // ********************************************************************
 25 //
 26 // Created on 2016/01/18
 27 //
 28 // Authors: D. Sakata, W.G. Shin, S. Incerti
 29 //
 30 // Based on a recent release of the ELSEPA code 
 31 // developed and provided kindly by F. Salvat et al. 
 32 // See
 33 // Computer Physics Communications, 165(2), 157-190. (2005)
 34 // http://dx.doi.org/10.1016/j.cpc.2004.09.006
 35 //
 36 
 37 #include "G4DNAELSEPAElasticModel.hh"
 38 #include "G4PhysicalConstants.hh"
 39 #include "G4SystemOfUnits.hh"
 40 #include "G4DNAMolecularMaterial.hh"
 41 #include "G4EmParameters.hh"
 42 
 43 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 44 
 45 using namespace std;
 46 
 47 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 48 
 49 G4DNAELSEPAElasticModel::G4DNAELSEPAElasticModel(const G4ParticleDefinition*,
 50 const G4String& nam) :
 51 G4VEmModel(nam) 
 52 {
 53   verboseLevel = 0;
 54 
 55   G4ProductionCutsTable* theCoupleTable =
 56   G4ProductionCutsTable::GetProductionCutsTable();
 57   auto  numOfCouples = (G4int)theCoupleTable->GetTableSize();
 58     
 59   fpBaseWater = G4Material::GetMaterial("G4_WATER");
 60 
 61   for(G4int i=0; i<numOfCouples; ++i)
 62   {
 63     const G4MaterialCutsCouple* couple =
 64          theCoupleTable->GetMaterialCutsCouple(i);
 65       
 66     const G4Material* material = couple->GetMaterial()->GetBaseMaterial();
 67     if(!material) material = couple->GetMaterial();
 68 
 69     auto  nelm = (G4int)material->GetNumberOfElements();
 70 
 71     if(nelm==1)
 72     {// Protection: only for single element
 73       G4int Z = 79;
 74       const G4ElementVector* theElementVector = material->GetElementVector();
 75       Z =  G4lrint((*theElementVector)[0]->GetZ());
 76       // Protection: only for GOLD
 77       if (Z==79){
 78         fkillBelowEnergy_Au = 10. * eV;  // Kills e- tracking
 79         flowEnergyLimit  = 0   * eV;  // Must stay at zero for killing
 80         fhighEnergyLimit = 1   * GeV; // Default
 81         SetLowEnergyLimit (flowEnergyLimit);
 82         SetHighEnergyLimit(fhighEnergyLimit);
 83       }else{
 84         //continue;
 85       }
 86     }else{// Protection: H2O only is available
 87       if(material==fpBaseWater){
 88         flowEnergyLimit  = 10. * eV;
 89         fhighEnergyLimit = 1   * MeV; 
 90         SetLowEnergyLimit (flowEnergyLimit);
 91         SetHighEnergyLimit(fhighEnergyLimit);
 92       }else{
 93         //continue;
 94       }
 95     }
 96 
 97     if (verboseLevel > 0)
 98     {
 99       G4cout << "ELSEPA Elastic model is constructed for " 
100       << material->GetName() << G4endl 
101       << "Energy range: "
102       << flowEnergyLimit / eV << " eV - "
103       << fhighEnergyLimit / MeV << " MeV"
104       << G4endl;
105     }
106   }
107 
108   fParticleChangeForGamma = nullptr;
109   fpMolDensity = nullptr;
110 
111   fpData_Au=nullptr;
112   fpData_H2O=nullptr;
113 }
114 
115 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
116 
117 G4DNAELSEPAElasticModel::~G4DNAELSEPAElasticModel()
118 {
119   delete fpData_Au;
120   delete fpData_H2O;
121 
122   eEdummyVec_Au.clear();
123   eEdummyVec_H2O.clear();
124   eCum_Au.clear();
125   eCum_H2O.clear();
126   fAngleData_Au.clear();
127   fAngleData_H2O.clear();
128 }
129 
130 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
131 
132 void G4DNAELSEPAElasticModel::Initialise(const G4ParticleDefinition* particle,
133 const G4DataVector& )
134 {
135   if (verboseLevel > 3)
136   G4cout << "Calling G4DNAELSEPAElasticModel::Initialise()" << G4endl;
137 
138   if (isInitialised) {return;}
139 
140   if(particle->GetParticleName() != "e-")
141   {
142     G4Exception("G4DNAELSEPAElasticModel::Initialise","em0001",
143       FatalException,"Model not applicable to particle type.");
144     return;
145   }
146  
147   G4ProductionCutsTable* theCoupleTable =
148   G4ProductionCutsTable::GetProductionCutsTable();
149   auto  numOfCouples = (G4int)theCoupleTable->GetTableSize();
150   
151   // UNIT OF TCS
152   G4double scaleFactor = 1.*cm*cm;
153 
154   fpData_Au=nullptr;
155   fpData_H2O=nullptr;
156   fpBaseWater = G4Material::GetMaterial("G4_WATER");
157 
158   for(G4int i=0; i<numOfCouples; ++i) 
159   {
160     const G4MaterialCutsCouple* couple = 
161          theCoupleTable->GetMaterialCutsCouple(i);
162     const G4Material* material = couple->GetMaterial()->GetBaseMaterial();
163     if(!material) material = couple->GetMaterial();
164 
165     auto  nelm = (G4int)material->GetNumberOfElements();
166     if (nelm==1){// Protection: only for single element
167       const G4ElementVector* theElementVector = material->GetElementVector();
168       G4int Z =  G4lrint((*theElementVector)[0]->GetZ());
169       if (Z!=79)// Protection: only for GOLD
170       {
171         continue;
172       }
173       
174       if (Z>0) 
175       {
176         G4String fileZElectron("dna/sigma_elastic_e_elsepa_Z");
177         std::ostringstream oss;
178         oss.str("");
179         oss.clear(stringstream::goodbit);
180         oss << Z;
181         fileZElectron += oss.str()+"_muffintin";
182 
183         fpData_Au = new G4DNACrossSectionDataSet(new G4LogLogInterpolation,
184                                                  eV,
185                                                  scaleFactor );
186         fpData_Au->LoadData(fileZElectron);
187       
188         std::ostringstream eFullFileNameZ;
189         const char *path = G4EmParameters::Instance()->GetDirLEDATA();
190 
191         if (path == nullptr)
192         {
193           G4Exception("G4DNAELSEPAElasticModel::Initialise","em0002",
194             FatalException,"G4LEDATA environment variable not set.");
195           return;
196         }
197 
198         eFullFileNameZ.str("");
199         eFullFileNameZ.clear(stringstream::goodbit);
200       
201         eFullFileNameZ 
202           << path 
203           << "/dna/sigmadiff_cumulated_elastic_e_elsepa_Z" 
204           << Z << "_muffintin.dat";
205       
206         std::ifstream eDiffCrossSectionZ(eFullFileNameZ.str().c_str());
207       
208         if (!eDiffCrossSectionZ)
209         {
210           G4Exception("G4DNAELSEPAElasticModel::Initialise","em0003",
211             FatalException,"Missing data file for cumulated DCS");
212           return;
213         }
214       
215         eEdummyVec_Au.clear();
216         eCum_Au.clear();
217         fAngleData_Au.clear();
218         
219         eEdummyVec_Au.push_back(0.);
220         do
221         {
222           G4double eDummy;
223           G4double cumDummy;
224           eDiffCrossSectionZ>>eDummy>>cumDummy;
225           if (eDummy != eEdummyVec_Au.back())
226           {
227            eEdummyVec_Au.push_back(eDummy);
228            eCum_Au[eDummy].push_back(0.);
229           }
230           eDiffCrossSectionZ>>fAngleData_Au[eDummy][cumDummy];
231           if (cumDummy != eCum_Au[eDummy].back())
232           {
233             eCum_Au[eDummy].push_back(cumDummy);
234           }
235         }while(!eDiffCrossSectionZ.eof());
236       } 
237 
238     }else{// Protection: H2O only is available
239       if(material == fpBaseWater && !fpData_H2O){
240         if (LowEnergyLimit() < 10*eV)
241         {
242           G4cout<<"G4DNAELSEPAElasticModel: low energy limit increased from "
243                 << LowEnergyLimit()/eV << " eV to " << 10 << " eV"
244                 << G4endl;
245           SetLowEnergyLimit(10.*eV);
246         }
247 
248         if (HighEnergyLimit() > 1.*MeV)
249         {
250           G4cout<<"G4DNAELSEPAElasticModel: high energy limit decreased from "
251                 << HighEnergyLimit()/MeV << " MeV to " << 1. << " MeV"
252                 << G4endl;
253           SetHighEnergyLimit(1.*MeV);
254         }
255 
256         G4String fileZElectron("dna/sigma_elastic_e_elsepa_muffin");
257 
258         fpData_H2O = new G4DNACrossSectionDataSet(new G4LogLogInterpolation,
259                                                  eV,
260                                                  scaleFactor );
261         fpData_H2O->LoadData(fileZElectron);
262 
263         std::ostringstream eFullFileNameZ;
264 
265         const char *path = G4EmParameters::Instance()->GetDirLEDATA();
266         if (path == nullptr)
267         {
268           G4Exception("G4DNAELSEPAElasticModel::Initialise","em0004",
269             FatalException,"G4LEDATA environment variable not set.");
270           return;
271         }
272 
273         eFullFileNameZ.str("");
274         eFullFileNameZ.clear(stringstream::goodbit);
275 
276         eFullFileNameZ
277           << path
278           <<  "/dna/sigmadiff_cumulated_elastic_e_elsepa_muffin.dat";
279 
280         std::ifstream eDiffCrossSectionZ(eFullFileNameZ.str().c_str());
281 
282         if (!eDiffCrossSectionZ)
283          G4Exception("G4DNAELSEPAElasticModel::Initialise","em0005",
284          FatalException,
285          "Missing data file for cumulated DCS");
286 
287         eEdummyVec_H2O.clear();
288         eCum_H2O.clear();
289         fAngleData_H2O.clear();
290 
291         eEdummyVec_H2O.push_back(0.);
292 
293         do
294         {
295           G4double eDummy;
296           G4double cumDummy;
297           eDiffCrossSectionZ>>eDummy>>cumDummy;
298           if (eDummy != eEdummyVec_H2O.back())
299           {
300            eEdummyVec_H2O.push_back(eDummy);
301            eCum_H2O[eDummy].push_back(0.);
302           }
303           eDiffCrossSectionZ>>fAngleData_H2O[eDummy][cumDummy];
304           if (cumDummy != eCum_H2O[eDummy].back()){
305             eCum_H2O[eDummy].push_back(cumDummy);
306           }
307         }while(!eDiffCrossSectionZ.eof());
308       }
309     }
310     if (verboseLevel > 2)
311     G4cout << "Loaded cross section files of ELSEPA Elastic model for"
312            << material->GetName() << G4endl;
313 
314     if( verboseLevel>0 )
315     {
316       G4cout << "ELSEPA elastic model is initialized " << G4endl
317       << "Energy range: "
318       << LowEnergyLimit() /  eV << " eV - "
319       << HighEnergyLimit()/ MeV << " MeV"
320       << G4endl;
321     }
322   } // Loop on couples
323 
324 
325   fParticleChangeForGamma = GetParticleChangeForGamma();
326 
327   fpMolDensity =
328   G4DNAMolecularMaterial::Instance()->
329   GetNumMolPerVolTableFor(G4Material::GetMaterial("G4_WATER"));
330 
331   isInitialised = true;
332 }
333 
334 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
335 
336 G4double G4DNAELSEPAElasticModel::CrossSectionPerVolume
337 (const G4Material* material,
338  const G4ParticleDefinition* particle,
339  G4double ekin,
340  G4double,
341  G4double)
342 {
343 
344   if (verboseLevel > 3)
345   {
346     G4cout <<
347     "Calling CrossSectionPerVolume() of G4DNAELSEPAElasticModel"
348     << G4endl;
349   }
350 
351   G4double atomicNDensity=0.0;
352   G4double sigma=0;
353 
354   std::size_t nelm = material->GetNumberOfElements();
355   if (nelm==1)  // Protection: only for single element
356   {
357     // Protection: only for GOLD
358     if (material->GetZ()!=79) return 0.0;
359       
360     const G4ElementVector* theElementVector = material->GetElementVector();
361     G4int Z = G4lrint((*theElementVector)[0]->GetZ());
362 
363     const G4String& particleName = particle->GetParticleName();
364     atomicNDensity = material->GetAtomicNumDensityVector()[0];
365     if(atomicNDensity!= 0.0)
366     {
367       if (ekin < fhighEnergyLimit)
368       {
369         if (ekin < fkillBelowEnergy_Au) return DBL_MAX;
370 
371         if (ekin < 10*eV) sigma = fpData_Au->FindValue(10*eV);
372         else              sigma = fpData_Au->FindValue(ekin);
373       }
374     }
375     if (verboseLevel > 2)
376     {
377       G4cout << "__________________________________" << G4endl;
378       G4cout << "=== G4DNAELSEPAElasticModel - XS INFO START" << G4endl;
379       G4cout << "=== Material is made of one element with Z =" << Z << G4endl;
380       G4cout << "=== Kinetic energy(eV)=" << ekin/eV << " particle : " 
381              << particleName << G4endl;
382       G4cout << "=== Cross section per atom for Z="<<Z<<" is (cm^2)" 
383              << sigma/cm/cm << G4endl;
384       G4cout << "=== Cross section per atom for Z="<<Z<<" is (cm^-1)=" 
385              << sigma*atomicNDensity/(1./cm) << G4endl;
386       G4cout << "=== G4DNAELSEPAElasticModel - XS INFO END" << G4endl;
387     }
388   }
389   else
390   {
391     atomicNDensity = (*fpMolDensity)[material->GetIndex()];
392     if(atomicNDensity!= 0.0)
393     {
394       if (ekin < HighEnergyLimit() && ekin >= LowEnergyLimit())
395       {
396         sigma = fpData_H2O->FindValue(ekin);
397       }
398     }
399     if (verboseLevel > 2)
400     {
401       G4cout << "__________________________________" << G4endl;
402       G4cout << "=== G4DNAELSEPAElasticModel - XS INFO START" << G4endl;
403       G4cout << "=== Kinetic energy(eV)=" << ekin/eV 
404              << " particle : " << particle->GetParticleName() << G4endl;
405       G4cout << "=== Cross section per water molecule (cm^2)=" 
406              << sigma/cm/cm << G4endl;
407       G4cout << "=== Cross section per water molecule (cm^-1)=" 
408              << sigma*atomicNDensity/(1./cm) << G4endl;
409       G4cout << "=== G4DNAELSEPAElasticModel - XS INFO END" << G4endl;
410     }
411   }
412 
413   return sigma*atomicNDensity;
414 }
415 
416 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
417 
418 void G4DNAELSEPAElasticModel::SampleSecondaries(
419       std::vector<G4DynamicParticle*>*,
420       const G4MaterialCutsCouple* couple,
421       const G4DynamicParticle* aDynamicElectron,
422       G4double,
423       G4double)
424 {
425 
426   if (verboseLevel > 3){
427     G4cout << 
428     "Calling SampleSecondaries() of G4DNAELSEPAElasticModel" 
429     << G4endl;
430   }
431 
432   G4double electronEnergy0 = aDynamicElectron->GetKineticEnergy();
433 
434   const G4Material* material = couple->GetMaterial()->GetBaseMaterial();
435   if(!material) material = couple->GetMaterial();
436     
437   std::size_t nelm = material->GetNumberOfElements();
438   if (nelm==1) // Protection: only for single element
439   {
440     const G4ElementVector* theElementVector = material->GetElementVector();
441     G4int Z =  G4lrint((*theElementVector)[0]->GetZ());
442     if (Z!=79) return;
443     if (electronEnergy0 < fkillBelowEnergy_Au)
444     {
445       fParticleChangeForGamma->SetProposedKineticEnergy(0.);
446       fParticleChangeForGamma->ProposeMomentumDirection(G4ThreeVector(0,0,0));
447       fParticleChangeForGamma->ProposeTrackStatus(fStopAndKill);
448       fParticleChangeForGamma->ProposeLocalEnergyDeposit(electronEnergy0);
449       return;
450     }
451 
452     if(electronEnergy0>= fkillBelowEnergy_Au && electronEnergy0 < fhighEnergyLimit)
453     {
454       G4double cosTheta = 0;
455       if (electronEnergy0>=10*eV)
456       {
457         cosTheta = RandomizeCosTheta(Z,electronEnergy0);
458       }
459       else
460       { 
461         cosTheta = RandomizeCosTheta(Z,10*eV);
462       }
463 
464       G4double phi = 2. * CLHEP::pi * G4UniformRand();
465       
466       G4ThreeVector zVers = aDynamicElectron->GetMomentumDirection();
467       G4ThreeVector xVers = zVers.orthogonal();
468       G4ThreeVector yVers = zVers.cross(xVers);
469 
470       G4double xDir = std::sqrt(1. - cosTheta*cosTheta);
471       G4double yDir = xDir;
472       xDir *= std::cos(phi);
473       yDir *= std::sin(phi);
474 
475       G4ThreeVector zPrimeVers((xDir*xVers + yDir*yVers + cosTheta*zVers));
476       fParticleChangeForGamma->ProposeMomentumDirection(zPrimeVers.unit());
477       fParticleChangeForGamma->SetProposedKineticEnergy(electronEnergy0);
478       
479     }
480   }
481   else
482   {
483     if(material == fpBaseWater)
484     {
485       //The data for water is stored as Z=0
486       G4double cosTheta = RandomizeCosTheta(0,electronEnergy0);
487 
488       G4double phi = 2. * pi * G4UniformRand();
489 
490       G4ThreeVector zVers = aDynamicElectron->GetMomentumDirection();
491       G4ThreeVector xVers = zVers.orthogonal();
492       G4ThreeVector yVers = zVers.cross(xVers);
493 
494       G4double xDir = std::sqrt(1. - cosTheta*cosTheta);
495       G4double yDir = xDir;
496       xDir *= std::cos(phi);
497       yDir *= std::sin(phi);
498 
499       G4ThreeVector zPrimeVers((xDir*xVers + yDir*yVers + cosTheta*zVers));
500       fParticleChangeForGamma->ProposeMomentumDirection(zPrimeVers.unit());
501       fParticleChangeForGamma->SetProposedKineticEnergy(electronEnergy0);
502     }
503   }
504 }
505 
506 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
507 
508 G4double G4DNAELSEPAElasticModel::Theta(G4int Z,
509          G4ParticleDefinition * particleDefinition,
510          G4double k,
511          G4double integrDiff)
512 {
513 
514  G4double theta   = 0.;
515  G4double valueE1 = 0.;
516  G4double valueE2 = 0.;
517  G4double valuecum21 = 0.;
518  G4double valuecum22 = 0.;
519  G4double valuecum12 = 0.;
520  G4double valuecum11 = 0.;
521  G4double a11 = 0.;
522  G4double a12 = 0.;
523  G4double a21 = 0.;
524  G4double a22 = 0.;
525 
526  if (particleDefinition == G4Electron::ElectronDefinition())
527  {
528 
529   std::vector<G4double>::iterator e2;
530   if(Z==0){
531     e2 = std::upper_bound(eEdummyVec_H2O.begin(),
532                           eEdummyVec_H2O.end(), k);
533   }else if (Z==79){
534     e2 = std::upper_bound(eEdummyVec_Au.begin(),
535                           eEdummyVec_Au.end(), k);
536   }
537 
538   auto e1 = e2 - 1;
539 
540   std::vector<G4double>::iterator cum12;
541   if(Z==0){
542     cum12   = std::upper_bound(eCum_H2O[(*e1)].begin(),
543                                eCum_H2O[(*e1)].end(),integrDiff);
544   }else if (Z==79){
545     cum12   = std::upper_bound(eCum_Au[(*e1)].begin(),
546                                eCum_Au[(*e1)].end(),integrDiff);
547   }
548   
549   auto cum11 = cum12 - 1;
550 
551   //std::vector<G4double>::iterator cum22 
552   //           = std::upper_bound(eCumZ[Z][(*e2)].begin(),
553   //           eCumZ[Z][(*e2)].end(),integrDiff);
554   std::vector<G4double>::iterator cum22;
555   if(Z==0){
556     cum22  = std::upper_bound(eCum_H2O[(*e2)].begin(),
557                               eCum_H2O[(*e2)].end(),integrDiff);
558   }else if(Z==79){
559     cum22  = std::upper_bound(eCum_Au[(*e2)].begin(),
560                               eCum_Au[(*e2)].end(),integrDiff);
561   }
562   
563   auto cum21 = cum22 - 1;
564 
565   valueE1  = *e1;
566   valueE2  = *e2;
567   valuecum11 = *cum11;
568   valuecum12 = *cum12;
569   valuecum21 = *cum21;
570   valuecum22 = *cum22;
571 
572   if(Z==0){
573     a11 = fAngleData_H2O[valueE1][valuecum11];
574     a12 = fAngleData_H2O[valueE1][valuecum12];
575     a21 = fAngleData_H2O[valueE2][valuecum21];
576     a22 = fAngleData_H2O[valueE2][valuecum22];
577   }else if (Z==79){
578     a11 = fAngleData_Au[valueE1][valuecum11];
579     a12 = fAngleData_Au[valueE1][valuecum12];
580     a21 = fAngleData_Au[valueE2][valuecum21];
581     a22 = fAngleData_Au[valueE2][valuecum22];
582   }
583 
584  }
585 
586  if (a11 == 0 && a12 == 0 && a21 == 0 && a22 == 0) return (0.);
587 
588  theta = QuadInterpolator(valuecum11, valuecum12, valuecum21, valuecum22, 
589           a11, a12,a21, a22, valueE1, valueE2, k, integrDiff);
590  return theta;
591 }
592 
593 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
594 //
595 G4double G4DNAELSEPAElasticModel::LogLinInterpolate(G4double e1,
596 G4double e2,
597 G4double e,
598 G4double xs1,
599 G4double xs2)
600 {
601  G4double value=0.;
602  if(e1!=0){
603    G4double a = std::log10(e)  - std::log10(e1);
604    G4double b = std::log10(e2) - std::log10(e);
605    value = xs1 + a/(a+b)*(xs2-xs1);
606  }
607  else{
608    G4double d1 = xs1;
609    G4double d2 = xs2;
610    value = (d1 + (d2 - d1) * (e - e1) / (e2 - e1));
611  }
612 
613  return value;
614 }
615 
616 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
617 
618 G4double G4DNAELSEPAElasticModel::LinLogInterpolate(G4double e1,
619 G4double e2,
620 G4double e,
621 G4double xs1,
622 G4double xs2)
623 {
624  G4double d1 = std::log10(xs1);
625  G4double d2 = std::log10(xs2);
626  G4double value = std::pow(10,(d1 + (d2 - d1) * (e - e1) / (e2 - e1)));
627  return value;
628 }
629 
630 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
631 
632 G4double G4DNAELSEPAElasticModel::LinLinInterpolate(G4double e1,
633 G4double e2,
634 G4double e,
635 G4double xs1,
636 G4double xs2)
637 {
638  G4double d1 = xs1;
639  G4double d2 = xs2;
640  G4double value = (d1 + (d2 - d1) * (e - e1) / (e2 - e1));
641  return value;
642 }
643 
644 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
645 
646 G4double G4DNAELSEPAElasticModel::LogLogInterpolate(G4double e1,
647 G4double e2,
648 G4double e,
649 G4double xs1,
650 G4double xs2)
651 {
652  G4double a = (std::log10(xs2) - std::log10(xs1))
653              / (std::log10(e2) - std::log10(e1));
654  G4double b = std::log10(xs2) - a * std::log10(e2);
655  G4double sigma = a * std::log10(e) + b;
656  G4double value = (std::pow(10., sigma));
657  return value;
658 }
659 
660 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
661 
662 G4double G4DNAELSEPAElasticModel::QuadInterpolator(
663 G4double cum11,
664 G4double cum12,
665 G4double cum21,
666 G4double cum22,
667 G4double a11,
668 G4double a12,
669 G4double a21,
670 G4double a22,
671 G4double e1,
672 G4double e2,
673 G4double t,
674 G4double cum)
675 {
676    G4double value=0;
677    G4double interpolatedvalue1=0;
678    G4double interpolatedvalue2=0;
679 
680    if(cum11!=0){
681      interpolatedvalue1 = LinLogInterpolate(cum11, cum12, cum, a11, a12);
682    }
683    else{
684      interpolatedvalue1 = LinLinInterpolate(cum11, cum12, cum, a11, a12);
685    }
686    if(cum21!=0){
687      interpolatedvalue2 = LinLogInterpolate(cum21, cum22, cum, a21, a22);
688    }
689    else{
690      interpolatedvalue2 = LinLinInterpolate(cum21, cum22, cum, a21, a22);
691    }
692 
693    value = LogLinInterpolate(e1,e2,t,interpolatedvalue1,interpolatedvalue2);
694 
695  return value;
696 }
697 
698 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
699 
700 G4double G4DNAELSEPAElasticModel::RandomizeCosTheta(G4int Z, G4double k)
701 {
702 
703   G4double integrdiff = 0.;
704   G4double uniformRand = G4UniformRand();
705   integrdiff = uniformRand;
706 
707   G4double theta = 0.;
708   G4double cosTheta = 0.;
709   theta = Theta(Z, G4Electron::ElectronDefinition(), k / eV, integrdiff);
710 
711   cosTheta = std::cos(theta * CLHEP::pi / 180.); 
712 
713   return cosTheta;
714 }
715 
716 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
717 
718 void G4DNAELSEPAElasticModel::SetKillBelowThreshold(G4double threshold)
719 {
720   fkillBelowEnergy_Au = threshold;
721 
722   if (threshold < 10 * eV)
723   {
724     G4cout<< "*** WARNING : the G4DNAELSEPAElasticModel model is not "
725     "defined below 10 eV !" << G4endl;
726   }
727 }
728