43 if (verboseLevel > 0) {
44 G4cout <<
"PTB Elastic model is constructed : " <<
G4endl;
70 G4cout <<
"Calling G4DNAPTBElasticModel::Initialise()" <<
G4endl;
73 std::ostringstream oss;
74 oss <<
" Model is not applied for this particle " << particle->
GetParticleName();
78 G4double scaleFactor = 1e-16 * cm * cm;
85 if (fpN2 !=
nullptr) {
88 "dna/sigmadiff_cumulated_elastic_e-_PTB_N2", scaleFactor);
94 if (fpTHF !=
nullptr) {
97 "dna/sigmadiff_cumulated_elastic_e-_PTB_THF", scaleFactor);
102 if (fpPY !=
nullptr) {
105 "dna/sigmadiff_cumulated_elastic_e-_PTB_PY", scaleFactor);
110 if (fpPU !=
nullptr) {
113 "dna/sigmadiff_cumulated_elastic_e-_PTB_PU", scaleFactor);
118 if (fpTMP !=
nullptr) {
121 "dna/sigmadiff_cumulated_elastic_e-_PTB_TMP", scaleFactor);
126 if (fpG4_WATER !=
nullptr) {
129 "dna/sigmadiff_cumulated_elastic_e_champion", scaleFactor);
135 if (fpBackbone_THF !=
nullptr) {
138 "dna/sigmadiff_cumulated_elastic_e-_PTB_THF", scaleFactor * 33. / 30);
143 if (fpCytosine_PY !=
nullptr) {
146 "dna/sigmadiff_cumulated_elastic_e-_PTB_PY", scaleFactor * 42. / 30);
151 if (fpThymine_PY !=
nullptr) {
154 "dna/sigmadiff_cumulated_elastic_e-_PTB_PY", scaleFactor * 48. / 30);
159 if (fpAdenine_PU !=
nullptr) {
162 "dna/sigmadiff_cumulated_elastic_e-_PTB_PU", scaleFactor * 50. / 44);
166 if (fpGuanine_PU !=
nullptr) {
169 "dna/sigmadiff_cumulated_elastic_e-_PTB_PU", scaleFactor * 56. / 44);
174 if (fpBackbone_TMP !=
nullptr) {
177 "dna/sigmadiff_cumulated_elastic_e-_PTB_TMP", scaleFactor * 33. / 50);
191 if (dataModel ==
nullptr) {
192 G4cout <<
"G4DNAPTBElasticModel::Initialise:: not good modelData" <<
G4endl;
194 "not good modelData");
197 fpModelData = dataModel;
201 if (verboseLevel > 2) {
202 G4cout <<
"Loaded cross section files for PTB Elastic model" <<
G4endl;
211void G4DNAPTBElasticModel::ReadDiffCSFile(
const std::size_t& materialName,
221 if (path ==
nullptr) {
223 "G4LEDATA environment variable not set.");
228 std::ostringstream fullFileName;
229 fullFileName << path <<
"/" << file <<
".dat";
232 std::ifstream diffCrossSection(fullFileName.str().c_str());
234 std::stringstream endPath;
235 if (!diffCrossSection) {
236 endPath <<
"Missing data file: " << file;
238 endPath.str().c_str());
241 tValuesVec[materialName][particleName].push_back(0.);
246 while (std::getline(diffCrossSection, line)) {
249 std::istringstream testIss(line);
266 std::istringstream iss(line);
273 iss >> tDummy >> eDummy;
285 if (tDummy != tValuesVec[materialName][particleName].back()) {
287 tValuesVec[materialName][particleName].push_back(tDummy);
289 eValuesVect[materialName][particleName][tDummy].push_back(0.);
294 iss >> diffCrossSectionData[materialName][particleName][tDummy][eDummy];
298 if (eDummy != eValuesVect[materialName][particleName][tDummy].back()) {
299 eValuesVect[materialName][particleName][tDummy].push_back(eDummy);
310 if (verboseLevel > 3){
311 G4cout <<
"Calling CrossSectionPerVolume() of G4DNAPTBElasticModel" <<
G4endl;
316 const std::size_t& materialID = pMaterial->
GetIndex();
319 fKillBelowEnergy = fpModelData->
GetLowELimit(materialID, p);
331 if (ekin < fKillBelowEnergy) {
336 auto tableData = fpModelData->
GetData();
337 if ((*tableData)[materialID][p] ==
nullptr) {
339 "No model is registered");
342 sigma = (*tableData)[materialID][p]->FindValue(ekin);
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;
356 return sigma * MolDensity;
366 if (verboseLevel > 3) {
367 G4cout <<
"Calling SampleSecondaries() of G4DNAPTBElasticModel" <<
G4endl;
371 const std::size_t& materialID = couple->
GetIndex();
375 fKillBelowEnergy = fpModelData->
GetLowELimit(materialID, p);
379 if (electronEnergy0 < fKillBelowEnergy) {
385 else if (electronEnergy0 >= fKillBelowEnergy && electronEnergy0 <
GetHighELimit(materialID, p)) {
387 G4double cosTheta = fpModelData->RandomizeCosTheta(electronEnergy0, materialID);
394 auto yVers = zVers.
cross(xVers);
396 G4double xDir = std::sqrt(1. - cosTheta * cosTheta);
398 xDir *= std::cos(phi);
399 yDir *= std::sin(phi);
402 G4ThreeVector zPrikeVers((xDir * xVers + yDir * yVers + cosTheta * zVers));
415 const std::size_t& materialID)
430 std::upper_bound(tValuesVec[materialID][p].begin(), tValuesVec[materialID][p].end(), k);
433 auto e12 = std::upper_bound(eValuesVect[materialID][p][(*t1)].begin(),
434 eValuesVect[materialID][p][(*t1)].end(), integrDiff);
437 auto e22 = std::upper_bound(eValuesVect[materialID][p][(*t2)].begin(),
438 eValuesVect[materialID][p][(*t2)].end(), integrDiff);
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];
454 if (xs11 == 0 && xs12 == 0 && xs21 == 0 && xs22 == 0) {
458 theta = QuadInterpolator(valueE11, valueE12, valueE21, valueE22, xs11, xs12, xs21, xs22, valueT1,
459 valueT2, k, integrDiff);
471 G4double value = std::exp(d1 + (d2 - d1) * (e - e1) / (e2 - e1));
482 G4double value = (d1 + (d2 - d1) * (e - e1) / (e2 - e1));
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));
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);
528G4double G4DNAPTBElasticModel::RandomizeCosTheta(
const G4double& k,
const std::size_t& materialID)
532 integrdiff = uniformRand;
538 cosTheta = std::cos(theta * CLHEP::pi / 180);
const char * G4FindDataDir(const char *)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4GLOB_DLL std::ostream G4cout
Hep3Vector orthogonal() const
Hep3Vector cross(const Hep3Vector &) const
static G4DNAMaterialManager * Instance()
void SetMasterDataModel(const DNAModelType &t, G4VEmModel *m)
G4VEmModel * GetModel(const DNAModelType &t)
const std::vector< G4double > * GetNumMolPerVolTableFor(const G4Material *) const
Retrieve a table of molecular densities (number of molecules per unit volume) in the G4 unit system f...
static G4DNAMolecularMaterial * Instance()
The G4DNAPTBElasticModel class This class implements the elastic model for the DNA materials and prec...
G4double CrossSectionPerVolume(const G4Material *material, const G4ParticleDefinition *p, G4double ekin, G4double emin, G4double emax) override
CrossSectionPerVolume This method is mandatory for any model class. It finds and return the cross sec...
G4ParticleChangeForGamma * fParticleChangeForGamma
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double tmax) override
SampleSecondaries Method called after CrossSectionPerVolume if the process is the one which is select...
void Initialise(const G4ParticleDefinition *particle, const G4DataVector &) override
Initialise Mandatory method for every model class. The material/particle for which the model can be u...
G4DNAPTBElasticModel(const G4String &applyToMaterial="all", const G4ParticleDefinition *p=nullptr, const G4String &nam="DNAPTBElasticModel")
G4DNAPTBElasticModel Constructor.
const G4ThreeVector & GetMomentumDirection() const
const G4ParticleDefinition * GetParticleDefinition() const
G4double GetKineticEnergy() const
static G4Electron * ElectronDefinition()
std::size_t GetIndex() const
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
const G4String & GetParticleName() const
void LoadCrossSectionData(const G4ParticleDefinition *particleName)
LoadCrossSectionData Method to loop on all the registered materials in the model and load the corresp...
void SetLowELimit(const size_t &materialID, const G4ParticleDefinition *particle, G4double lim)
SetLowEnergyLimit.
void SetHighELimit(const size_t &materialID, const G4ParticleDefinition *particle, G4double lim)
SetHighEnergyLimit.
G4double GetHighELimit(const size_t &materialID, const G4ParticleDefinition *particle)
GetHighEnergyLimit.
void AddCrossSectionData(const size_t &materialName, const G4ParticleDefinition *particleName, const G4String &fileCS, const G4String &fileDiffCS, const G4double &scaleFactor)
AddCrossSectionData Method used during the initialization of the model class to add a new material....
G4double GetLowELimit(const size_t &materialID, const G4ParticleDefinition *particle)
GetLowEnergyLimit.
MaterialParticleMapData * GetData()
GetTableData.
G4ParticleChangeForGamma * GetParticleChangeForGamma()
void ProposeTrackStatus(G4TrackStatus status)
void ProposeLocalEnergyDeposit(G4double anEnergyPart)