Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/models/src/G4DNAPTBElasticModel.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 // Authors: S. Meylan and C. Villagrasa (IRSN, France)
 27 // Models come from
 28 // M. Bug et al, Rad. Phys and Chem. 130, 459-479 (2017)
 29 //
 30 
 31 #include "G4DNAPTBElasticModel.hh"
 32 
 33 #include "G4DNAChampionElasticModel.hh"
 34 #include "G4DNAMaterialManager.hh"
 35 #include "G4DNAMolecularMaterial.hh"
 36 #include "G4Proton.hh"
 37 #include "G4SystemOfUnits.hh"
 38 
 39 G4DNAPTBElasticModel::G4DNAPTBElasticModel(const G4String& applyToMaterial,
 40                                            const G4ParticleDefinition*, const G4String& nam)
 41   : G4VDNAModel(nam, applyToMaterial)
 42 {
 43   if (verboseLevel > 0) {
 44     G4cout << "PTB Elastic model is constructed : " << G4endl;
 45   }
 46   fpTHF = G4Material::GetMaterial("THF", false);
 47   fpPY = G4Material::GetMaterial("PY", false);
 48   fpPU = G4Material::GetMaterial("PU", false);
 49   fpTMP = G4Material::GetMaterial("TMP", false);
 50   fpG4_WATER = G4Material::GetMaterial("G4_WATER", false);
 51   fpBackbone_THF = G4Material::GetMaterial("backbone_THF", false);
 52   fpCytosine_PY = G4Material::GetMaterial("cytosine_PY", false);
 53   fpThymine_PY = G4Material::GetMaterial("thymine_PY", false);
 54   fpAdenine_PU = G4Material::GetMaterial("adenine_PU", false);
 55   fpBackbone_TMP = G4Material::GetMaterial("backbone_TMP", false);
 56   fpGuanine_PU = G4Material::GetMaterial("guanine_PU", false);
 57   fpN2 = G4Material::GetMaterial("N2", false);
 58 }
 59 
 60 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 61 
 62 void G4DNAPTBElasticModel::Initialise(const G4ParticleDefinition* particle,
 63                                       const G4DataVector& /*cuts*/)
 64 {
 65   if (isInitialised) {
 66     return;
 67   }
 68   if (verboseLevel > 3)
 69   {
 70     G4cout << "Calling G4DNAPTBElasticModel::Initialise()" << G4endl;
 71   }
 72   if (particle != G4Electron::ElectronDefinition()) {
 73     std::ostringstream oss;
 74     oss << " Model is not applied for this particle " << particle->GetParticleName();
 75     G4Exception("G4DNAPTBElasticModel::G4DNAPTBElasticModel", "PTB001", FatalException,
 76                 oss.str().c_str());
 77   }
 78   G4double scaleFactor = 1e-16 * cm * cm;
 79   //*******************************************************
 80   // Cross section data
 81   //*******************************************************
 82 
 83   std::size_t index;
 84   // MPietrzak, adding paths for N2
 85   if (fpN2 != nullptr) {
 86     index = fpN2->GetIndex();
 87     AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_N2",
 88                         "dna/sigmadiff_cumulated_elastic_e-_PTB_N2", scaleFactor);
 89     SetLowELimit(index, particle, 10 * eV);
 90     SetHighELimit(index, particle, 1.02 * MeV);
 91   }
 92   // MPietrzak
 93 
 94   if (fpTHF != nullptr) {
 95     index = fpTHF->GetIndex();
 96     AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_THF",
 97                         "dna/sigmadiff_cumulated_elastic_e-_PTB_THF", scaleFactor);
 98     SetLowELimit(index, particle, 10 * eV);
 99     SetHighELimit(index, particle, 1 * keV);
100   }
101 
102   if (fpPY != nullptr) {
103     index = fpPY->GetIndex();
104     AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_PY",
105                         "dna/sigmadiff_cumulated_elastic_e-_PTB_PY", scaleFactor);
106     SetLowELimit(index, particle, 10 * eV);
107     SetHighELimit(index, particle, 1 * keV);
108   }
109 
110   if (fpPU != nullptr) {
111     index = fpPU->GetIndex();
112     AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_PU",
113                         "dna/sigmadiff_cumulated_elastic_e-_PTB_PU", scaleFactor);
114     SetLowELimit(index, particle, 10 * eV);
115     SetHighELimit(index, particle, 1 * keV);
116   }
117 
118   if (fpTMP != nullptr) {
119     index = fpTMP->GetIndex();
120     AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_TMP",
121                         "dna/sigmadiff_cumulated_elastic_e-_PTB_TMP", scaleFactor);
122     SetLowELimit(index, particle, 10 * eV);
123     SetHighELimit(index, particle, 1 * keV);
124   }
125   //????
126   if (fpG4_WATER != nullptr) {
127     index = fpG4_WATER->GetIndex();
128     AddCrossSectionData(index, particle, "dna/sigma_elastic_e_champion",
129                         "dna/sigmadiff_cumulated_elastic_e_champion", scaleFactor);
130     SetLowELimit(index, particle, 10 * eV);
131     SetHighELimit(index, particle, 1 * keV);
132   }
133   // DNA materials
134   //
135   if (fpBackbone_THF != nullptr) {
136     index = fpBackbone_THF->GetIndex();
137     AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_THF",
138                         "dna/sigmadiff_cumulated_elastic_e-_PTB_THF", scaleFactor * 33. / 30);
139     SetLowELimit(index, particle, 10 * eV);
140     SetHighELimit(index, particle, 1 * keV);
141   }
142 
143   if (fpCytosine_PY != nullptr) {
144     index = fpCytosine_PY->GetIndex();
145     AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_PY",
146                         "dna/sigmadiff_cumulated_elastic_e-_PTB_PY", scaleFactor * 42. / 30);
147     SetLowELimit(index, particle, 10 * eV);
148     SetHighELimit(index, particle, 1 * keV);
149   }
150 
151   if (fpThymine_PY != nullptr) {
152     index = fpThymine_PY->GetIndex();
153     AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_PY",
154                         "dna/sigmadiff_cumulated_elastic_e-_PTB_PY", scaleFactor * 48. / 30);
155     SetLowELimit(index, particle, 10 * eV);
156     SetHighELimit(index, particle, 1 * keV);
157   }
158 
159   if (fpAdenine_PU != nullptr) {
160     index = fpAdenine_PU->GetIndex();
161     AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_PU",
162                         "dna/sigmadiff_cumulated_elastic_e-_PTB_PU", scaleFactor * 50. / 44);
163     SetLowELimit(index, particle, 10 * eV);
164     SetHighELimit(index, particle, 1 * keV);
165   }
166   if (fpGuanine_PU != nullptr) {
167     index = fpGuanine_PU->GetIndex();
168     AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_PU",
169                         "dna/sigmadiff_cumulated_elastic_e-_PTB_PU", scaleFactor * 56. / 44);
170     SetLowELimit(index, particle, 10 * eV);
171     SetHighELimit(index, particle, 1 * keV);
172   }
173 
174   if (fpBackbone_TMP != nullptr) {
175     index = fpBackbone_TMP->GetIndex();
176     AddCrossSectionData(index, particle, "dna/sigma_elastic_e-_PTB_TMP",
177                         "dna/sigmadiff_cumulated_elastic_e-_PTB_TMP", scaleFactor * 33. / 50);
178     SetLowELimit(index, particle, 10 * eV);
179     SetHighELimit(index, particle, 1 * keV);
180   }
181 
182   if (!G4DNAMaterialManager::Instance()->IsLocked()) {
183     // Load the data
184     LoadCrossSectionData(particle);
185     G4DNAMaterialManager::Instance()->SetMasterDataModel(DNAModelType::fDNAElastics, this);
186     fpModelData = this;
187   }
188   else {
189     auto dataModel = dynamic_cast<G4DNAPTBElasticModel*>(
190       G4DNAMaterialManager::Instance()->GetModel(DNAModelType::fDNAElastics));
191     if (dataModel == nullptr) {
192       G4cout << "G4DNAPTBElasticModel::Initialise:: not good modelData" << G4endl;
193       G4Exception("G4DNAPTBElasticModel::Initialise", "PTB0006", FatalException,
194                   "not good modelData");
195     }
196     else {
197       fpModelData = dataModel;
198     }
199   }
200 
201   if (verboseLevel > 2) {
202     G4cout << "Loaded cross section files for PTB Elastic model" << G4endl;
203   }
204 
205   fParticleChangeForGamma = GetParticleChangeForGamma();
206   isInitialised = true;
207 }
208 
209 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
210 
211 void G4DNAPTBElasticModel::ReadDiffCSFile(const std::size_t& materialName,
212                                           const G4ParticleDefinition* particleName,
213                                           const G4String& file, const G4double&)
214 {
215   // Method to read and save the information contained within the differential cross section files.
216   // This method is not yet standard.
217 
218   // get the path of the G4LEDATA data folder
219   const char* path = G4FindDataDir("G4LEDATA");
220   // if it is not found then quit and print error message
221   if (path == nullptr) {
222     G4Exception("G4DNAPTBElasticModel::ReadAllDiffCSFiles", "em0006", FatalException,
223                 "G4LEDATA environment variable not set.");
224     return;
225   }
226 
227   // build the fullFileName path of the data file
228   std::ostringstream fullFileName;
229   fullFileName << path << "/" << file << ".dat";
230 
231   // open the data file
232   std::ifstream diffCrossSection(fullFileName.str().c_str());
233   // error if file is not there
234   std::stringstream endPath;
235   if (!diffCrossSection) {
236     endPath << "Missing data file: " << file;
237     G4Exception("G4DNAPTBElasticModel::Initialise", "em0003", FatalException,
238                 endPath.str().c_str());
239   }
240 
241   tValuesVec[materialName][particleName].push_back(0.);
242 
243   G4String line;
244 
245   // read the file line by line until we reach the end of file point
246   while (std::getline(diffCrossSection, line)) {
247     // check if the line is comment or empty
248     //
249     std::istringstream testIss(line);
250     G4String test;
251     testIss >> test;
252     // check first caracter to determine if following information is data or comments
253     if (test == "#") {
254       // skip the line by beginning a new while loop.
255       continue;
256     }
257     // check if line is empty
258     if (line.empty()) {
259       // skip the line by beginning a new while loop.
260       continue;
261     }
262     //
263     // end of the check
264 
265     // transform the line into a iss
266     std::istringstream iss(line);
267 
268     // Variables to be filled by the input file
269     G4double tDummy;
270     G4double eDummy;
271 
272     // fill the variables with the content of the line
273     iss >> tDummy >> eDummy;
274 
275     // SI : mandatory Vecm initialization
276 
277     // Fill two vectors contained in maps of types:
278     // [materialName][particleName]=vector
279     // [materialName][particleName][T]=vector
280     // to list all the incident energies (tValues) and all the output energies (eValues) within the
281     // file
282     //
283     // Check if we already have the current T value in the vector.
284     // If not then add it
285     if (tDummy != tValuesVec[materialName][particleName].back()) {
286       // Add the current T value
287       tValuesVec[materialName][particleName].push_back(tDummy);
288       // Make it correspond to a default zero E value
289       eValuesVect[materialName][particleName][tDummy].push_back(0.);
290     }
291 
292     // Put the differential cross section value of the input file within the diffCrossSectionData
293     // map
294     iss >> diffCrossSectionData[materialName][particleName][tDummy][eDummy];
295 
296     // If the current E value (eDummy) is different from the one already registered in the eVector
297     // then add it to the vector
298     if (eDummy != eValuesVect[materialName][particleName][tDummy].back()) {
299       eValuesVect[materialName][particleName][tDummy].push_back(eDummy);
300     }
301   }
302 }
303 
304 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
305 
306 G4double G4DNAPTBElasticModel::CrossSectionPerVolume(const G4Material* pMaterial,
307                                                      const G4ParticleDefinition* p, G4double ekin,
308                                                      G4double /*emin*/, G4double /*emax*/)
309 {
310   if (verboseLevel > 3){
311     G4cout << "Calling CrossSectionPerVolume() of G4DNAPTBElasticModel" << G4endl;
312   }
313 
314   // Get the name of the current particle
315   const G4String& particleName = p->GetParticleName();
316   const std::size_t& materialID = pMaterial->GetIndex();
317 
318   // set killBelowEnergy value for current material
319   fKillBelowEnergy = fpModelData->GetLowELimit(materialID, p);
320   // initialise the return value (cross section) to zero
321   G4double sigma = 0.;
322 
323   // check if we are below the high energy limit
324   if (ekin < fpModelData->GetHighELimit(materialID, p)) {
325     // This is used to kill the particle if its kinetic energy is below fKillBelowEnergy.
326     // If the energy is lower then we return a maximum cross section and thus the SampleSecondaries
327     // method will be called for sure. SampleSecondaries will remove the particle from the
328     // simulation.
329     //
330     // SI : XS must not be zero otherwise sampling of secondaries method ignored
331     if (ekin < fKillBelowEnergy) {
332       return DBL_MAX;
333     }
334 
335     // Get the tables with the cross section data
336     auto tableData = fpModelData->GetData();
337     if ((*tableData)[materialID][p] == nullptr) {
338       G4Exception("G4DNAPTBElasticModel::CrossSectionPerVolume", "em00236", FatalException,
339                   "No model is registered");
340     }
341     // Retrieve the cross section value
342     sigma = (*tableData)[materialID][p]->FindValue(ekin);
343   }
344 
345   if (verboseLevel > 2) {
346     G4cout << "__________________________________" << G4endl;
347     G4cout << "°°° G4DNAPTBElasticModel - XS INFO START" << G4endl;
348     G4cout << "°°° Kinetic energy(eV)=" << ekin / eV << " particle : " << particleName << G4endl;
349     G4cout << "°°° Cross section per molecule (cm^2)=" << sigma / cm / cm << G4endl;
350     G4cout << "°°° G4DNAPTBElasticModel - XS INFO END" << G4endl;
351   }
352 
353   // Return the cross section
354   auto MolDensity =
355     (*G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(pMaterial))[materialID];
356   return sigma * MolDensity;
357 }
358 
359 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
360 
361 void G4DNAPTBElasticModel::SampleSecondaries(std::vector<G4DynamicParticle*>* /*fvect*/,
362                                              const G4MaterialCutsCouple* couple,
363                                              const G4DynamicParticle* aDynamicElectron,
364                                              G4double /*tmin*/, G4double /*tmax*/)
365 {
366   if (verboseLevel > 3) {
367     G4cout << "Calling SampleSecondaries() of G4DNAPTBElasticModel" << G4endl;
368   }
369 
370   G4double electronEnergy0 = aDynamicElectron->GetKineticEnergy();
371   const std::size_t& materialID = couple->GetMaterial()->GetIndex();
372   auto p = aDynamicElectron->GetParticleDefinition();
373 
374   // set killBelowEnergy value for material
375   fKillBelowEnergy = fpModelData->GetLowELimit(materialID, p);
376 
377   // If the particle (electron here) energy is below the kill limit then we remove it from the
378   // simulation
379   if (electronEnergy0 < fKillBelowEnergy) {
380     fParticleChangeForGamma->SetProposedKineticEnergy(0.);
381     fParticleChangeForGamma->ProposeTrackStatus(fStopAndKill);
382     fParticleChangeForGamma->ProposeLocalEnergyDeposit(electronEnergy0);
383   }
384   // If we are above the kill limite and below the high limit then we proceed
385   else if (electronEnergy0 >= fKillBelowEnergy && electronEnergy0 < GetHighELimit(materialID, p)) {
386     // Random sampling of the cosTheta
387     G4double cosTheta = fpModelData->RandomizeCosTheta(electronEnergy0, materialID);
388 
389     // Random sampling of phi
390     G4double phi = 2. * CLHEP::pi * G4UniformRand();
391 
392     auto zVers = aDynamicElectron->GetMomentumDirection();
393     auto xVers = zVers.orthogonal();
394     auto yVers = zVers.cross(xVers);
395 
396     G4double xDir = std::sqrt(1. - cosTheta * cosTheta);
397     G4double yDir = xDir;
398     xDir *= std::cos(phi);
399     yDir *= std::sin(phi);
400 
401     // Particle direction after ModelInterface
402     G4ThreeVector zPrikeVers((xDir * xVers + yDir * yVers + cosTheta * zVers));
403 
404     // Give the new direction
405     fParticleChangeForGamma->ProposeMomentumDirection(zPrikeVers.unit());
406 
407     // Update the energy which does not change here
408     fParticleChangeForGamma->SetProposedKineticEnergy(electronEnergy0);
409   }
410 }
411 
412 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
413 
414 G4double G4DNAPTBElasticModel::Theta(const G4ParticleDefinition* p, G4double k, G4double integrDiff,
415                                      const std::size_t& materialID)
416 {
417   G4double theta = 0.;
418   G4double valueT1 = 0;
419   G4double valueT2 = 0;
420   G4double valueE21 = 0;
421   G4double valueE22 = 0;
422   G4double valueE12 = 0;
423   G4double valueE11 = 0;
424   G4double xs11 = 0;
425   G4double xs12 = 0;
426   G4double xs21 = 0;
427   G4double xs22 = 0;
428   if (p == G4Electron::ElectronDefinition()) {
429     auto t2 =
430       std::upper_bound(tValuesVec[materialID][p].begin(), tValuesVec[materialID][p].end(), k);
431     auto t1 = t2 - 1;
432 
433     auto e12 = std::upper_bound(eValuesVect[materialID][p][(*t1)].begin(),
434                                 eValuesVect[materialID][p][(*t1)].end(), integrDiff);
435     auto e11 = e12 - 1;
436 
437     auto e22 = std::upper_bound(eValuesVect[materialID][p][(*t2)].begin(),
438                                 eValuesVect[materialID][p][(*t2)].end(), integrDiff);
439     auto e21 = e22 - 1;
440 
441     valueT1 = *t1;
442     valueT2 = *t2;
443     valueE21 = *e21;
444     valueE22 = *e22;
445     valueE12 = *e12;
446     valueE11 = *e11;
447 
448     xs11 = diffCrossSectionData[materialID][p][valueT1][valueE11];
449     xs12 = diffCrossSectionData[materialID][p][valueT1][valueE12];
450     xs21 = diffCrossSectionData[materialID][p][valueT2][valueE21];
451     xs22 = diffCrossSectionData[materialID][p][valueT2][valueE22];
452   }
453 
454   if (xs11 == 0 && xs12 == 0 && xs21 == 0 && xs22 == 0) {
455     return (0.);
456   }
457 
458   theta = QuadInterpolator(valueE11, valueE12, valueE21, valueE22, xs11, xs12, xs21, xs22, valueT1,
459                            valueT2, k, integrDiff);
460 
461   return theta;
462 }
463 
464 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
465 
466 G4double G4DNAPTBElasticModel::LinLogInterpolate(G4double e1, G4double e2, G4double e, G4double xs1,
467                                                  G4double xs2)
468 {
469   G4double d1 = std::log(xs1);
470   G4double d2 = std::log(xs2);
471   G4double value = std::exp(d1 + (d2 - d1) * (e - e1) / (e2 - e1));
472   return value;
473 }
474 
475 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
476 
477 G4double G4DNAPTBElasticModel::LinLinInterpolate(G4double e1, G4double e2, G4double e, G4double xs1,
478                                                  G4double xs2)
479 {
480   G4double d1 = xs1;
481   G4double d2 = xs2;
482   G4double value = (d1 + (d2 - d1) * (e - e1) / (e2 - e1));
483   return value;
484 }
485 
486 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
487 
488 G4double G4DNAPTBElasticModel::LogLogInterpolate(G4double e1, G4double e2, G4double e, G4double xs1,
489                                                  G4double xs2)
490 {
491   G4double a = (std::log10(xs2) - std::log10(xs1)) / (std::log10(e2) - std::log10(e1));
492   G4double b = std::log10(xs2) - a * std::log10(e2);
493   G4double sigma = a * std::log10(e) + b;
494   G4double value = (std::pow(10., sigma));
495   return value;
496 }
497 
498 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
499 
500 G4double G4DNAPTBElasticModel::QuadInterpolator(G4double e11, G4double e12, G4double e21,
501                                                 G4double e22, G4double xs11, G4double xs12,
502                                                 G4double xs21, G4double xs22, G4double t1,
503                                                 G4double t2, G4double t, G4double e)
504 {
505   // Log-Log
506   /*
507    G4double interpolatedvalue1 = LogLogInterpolate(e11, e12, e, xs11, xs12);
508    G4double interpolatedvalue2 = LogLogInterpolate(e21, e22, e, xs21, xs22);
509    G4double value = LogLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
510 
511 
512    // Lin-Log
513    G4double interpolatedvalue1 = LinLogInterpolate(e11, e12, e, xs11, xs12);
514    G4double interpolatedvalue2 = LinLogInterpolate(e21, e22, e, xs21, xs22);
515    G4double value = LinLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
516  */
517 
518   // Lin-Lin
519   G4double interpolatedvalue1 = LinLinInterpolate(e11, e12, e, xs11, xs12);
520   G4double interpolatedvalue2 = LinLinInterpolate(e21, e22, e, xs21, xs22);
521   G4double value = LinLinInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
522 
523   return value;
524 }
525 
526 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
527 
528 G4double G4DNAPTBElasticModel::RandomizeCosTheta(const G4double& k, const std::size_t& materialID)
529 {
530   G4double integrdiff = 0;
531   G4double uniformRand = G4UniformRand();
532   integrdiff = uniformRand;
533 
534   G4double theta = 0.;
535   G4double cosTheta = 0.;
536   theta = Theta(G4Electron::ElectronDefinition(), k / eV, integrdiff, materialID);
537 
538   cosTheta = std::cos(theta * CLHEP::pi / 180);
539 
540   return cosTheta;
541 }
542