53 G4cout <<
"PTB ionisation model is constructed " <<
G4endl;
64 fDNAPTBAugerModel = 0;
73 if(fDNAPTBAugerModel)
delete fDNAPTBAugerModel;
83 G4cout <<
"Calling G4DNAPTBIonisationModel::Initialise()" <<
G4endl;
85 G4double scaleFactor = 1e-16 * cm*cm;
86 G4double scaleFactorBorn = (1.e-22 / 3.343) * m*m;
95 if(particle == electronDef)
104 "dna/sigma_ionisation_e-_PTB_N2",
105 "dna/sigmadiff_cumulated_ionisation_e-_PTB_N2",
113 "dna/sigma_ionisation_e-_PTB_THF",
114 "dna/sigmadiff_cumulated_ionisation_e-_PTB_THF",
121 "dna/sigma_ionisation_e-_PTB_PY",
122 "dna/sigmadiff_cumulated_ionisation_e-_PTB_PY",
129 "dna/sigma_ionisation_e-_PTB_PU",
130 "dna/sigmadiff_cumulated_ionisation_e-_PTB_PU",
137 "dna/sigma_ionisation_e-_PTB_TMP",
138 "dna/sigmadiff_cumulated_ionisation_e-_PTB_TMP",
145 "dna/sigma_ionisation_e_born",
146 "dna/sigmadiff_ionisation_e_born",
155 "dna/sigma_ionisation_e-_PTB_THF",
156 "dna/sigmadiff_cumulated_ionisation_e-_PTB_THF",
163 "dna/sigma_ionisation_e-_PTB_PY",
164 "dna/sigmadiff_cumulated_ionisation_e-_PTB_PY",
171 "dna/sigma_ionisation_e-_PTB_PY",
172 "dna/sigmadiff_cumulated_ionisation_e-_PTB_PY",
179 "dna/sigma_ionisation_e-_PTB_PU",
180 "dna/sigmadiff_cumulated_ionisation_e-_PTB_PU",
187 "dna/sigma_ionisation_e-_PTB_PU",
188 "dna/sigmadiff_cumulated_ionisation_e-_PTB_PU",
195 "dna/sigma_ionisation_e-_PTB_TMP",
196 "dna/sigmadiff_cumulated_ionisation_e-_PTB_TMP",
202 else if (particle == protonDef)
210 "dna/sigma_ionisation_p_HKS_THF",
211 "dna/sigmadiff_cumulated_ionisation_p_PTB_THF",
219 "dna/sigma_ionisation_p_HKS_PY",
220 "dna/sigmadiff_cumulated_ionisation_p_PTB_PY",
237 "dna/sigma_ionisation_p_HKS_TMP",
238 "dna/sigmadiff_cumulated_ionisation_p_PTB_TMP",
255 if(fDNAPTBAugerModel) fDNAPTBAugerModel->
Initialise();
268 G4cout <<
"Calling CrossSectionPerVolume() of G4DNAPTBIonisationModel" <<
G4endl;
281 if (ekin >= lowLim && ekin < highLim)
287 sigma = (*tableData)[materialName][particleName]->FindValue(ekin);
289 if (verboseLevel > 2)
291 G4cout <<
"__________________________________" <<
G4endl;
292 G4cout <<
"°°° G4DNAPTBIonisationModel - XS INFO START" <<
G4endl;
293 G4cout <<
"°°° Kinetic energy(eV)=" << ekin/eV <<
" particle : " << particleName <<
G4endl;
294 G4cout <<
"°°° Cross section per "<< materialName <<
" molecule (cm^2)=" << sigma/cm/cm <<
G4endl;
295 G4cout <<
"°°° G4DNAPTBIonisationModel - XS INFO END" <<
G4endl;
313 if (verboseLevel > 3)
314 G4cout <<
"Calling SampleSecondaries() of G4DNAPTBIonisationModel" <<
G4endl;
327 if (k >= lowLim && k < highLim)
331 G4double totalEnergy = k + particleMass;
332 G4double pSquare = k * (totalEnergy + particleMass);
333 G4double totalMomentum = std::sqrt(pSquare);
342 G4double secondaryKinetic (-1000*eV);
344 if(materialName!=
"G4_WATER")
347 secondaryKinetic = RandomizeEjectedElectronEnergyFromCumulated(aDynamicParticle->
GetDefinition(),k/eV,ionizationShell, materialName);
351 secondaryKinetic = RandomizeEjectedElectronEnergy(aDynamicParticle->
GetDefinition(),k,ionizationShell, materialName);
354 if(secondaryKinetic<=0)
356 G4cout<<
"Fatal error *************************************** "<<secondaryKinetic/eV<<
G4endl;
357 G4cout<<
"secondaryKinetic: "<<secondaryKinetic/eV<<
G4endl;
366 RandomizeEjectedElectronDirection(aDynamicParticle->
GetDefinition(), k, secondaryKinetic, cosTheta, phi);
368 G4double sinTheta = std::sqrt(1.-cosTheta*cosTheta);
369 G4double dirX = sinTheta*std::cos(phi);
370 G4double dirY = sinTheta*std::sin(phi);
373 deltaDirection.
rotateUz(primaryDirection);
383 G4double deltaTotalMomentum = std::sqrt(secondaryKinetic*(secondaryKinetic + 2.*electron_mass_c2 ));
384 G4double finalPx = totalMomentum*primaryDirection.
x() - deltaTotalMomentum*deltaDirection.
x();
385 G4double finalPy = totalMomentum*primaryDirection.
y() - deltaTotalMomentum*deltaDirection.
y();
386 G4double finalPz = totalMomentum*primaryDirection.
z() - deltaTotalMomentum*deltaDirection.
z();
387 G4double finalMomentum = std::sqrt(finalPx*finalPx + finalPy*finalPy + finalPz*finalPz);
388 finalPx /= finalMomentum;
389 finalPy /= finalMomentum;
390 finalPz /= finalMomentum;
395 G4cout<<
"Fatal error ****************************"<<
G4endl;
407 G4double scatteredEnergy = k-bindingEnergy-secondaryKinetic;
409 if(scatteredEnergy<=0)
411 G4cout<<
"Fatal error ****************************"<<
G4endl;
413 G4cout<<
"secondaryKinetic: "<<secondaryKinetic/eV<<
G4endl;
416 G4cout<<
"scatteredEnergy: "<<scatteredEnergy/eV<<
G4endl;
429 fvect->push_back(dp);
432 if(fDNAPTBAugerModel)
435 if(materialName!=
"G4_WATER") fDNAPTBAugerModel->
ComputeAugerEffect(fvect, materialName, bindingEnergy);
442void G4DNAPTBIonisationModel::ReadDiffCSFile(
const G4String& materialName,
454 G4Exception(
"G4DNAPTBIonisationModel::ReadAllDiffCSFiles",
"em0006",
460 std::ostringstream fullFileName;
461 fullFileName << path <<
"/"<< file<<
".dat";
464 std::ifstream diffCrossSection (fullFileName.str().c_str());
466 std::stringstream endPath;
467 if (!diffCrossSection)
469 endPath <<
"Missing data file: "<<file;
470 G4Exception(
"G4DNAPTBIonisationModel::Initialise",
"em0003",
475 fTMapWithVec[materialName][particleName].push_back(0.);
481 while(std::getline(diffCrossSection, line))
485 std::istringstream testIss(line);
495 else if(line.empty())
504 std::istringstream iss(line);
515 if (T != fTMapWithVec[materialName][particleName].back()) fTMapWithVec[materialName][particleName].push_back(T);
518 for (
int shell=0, eshell=ptbStructure.
NumberOfLevels(materialName); shell<eshell; ++shell)
522 iss>>diffCrossSectionData[materialName][particleName][shell][T][E];
524 if(materialName!=
"G4_WATER")
528 fEnergySecondaryData[materialName][particleName][shell][T][diffCrossSectionData[materialName][particleName][shell][T][E] ]=E;
532 fProbaShellMap[materialName][particleName][shell][T].push_back(diffCrossSectionData[materialName][particleName][shell][T][E]);
536 diffCrossSectionData[materialName][particleName][shell][T][E]*=scaleFactor;
538 fEMapWithVector[materialName][particleName][T].push_back(E);
554 if ((k+ptbStructure.
IonisationEnergy(shell, materialName))/2. > k) maximumEnergyTransfer=k;
555 else maximumEnergyTransfer = (k+ptbStructure.
IonisationEnergy(shell,materialName))/2.;
575 G4double maxEnergy = maximumEnergyTransfer;
576 G4int nEnergySteps = 50;
578 G4double stpEnergy(std::pow(maxEnergy/value, 1./
static_cast<G4double>(nEnergySteps-1)));
579 G4int step(nEnergySteps);
583 G4double differentialCrossSection = DifferentialCrossSection(particleDefinition, k/eV, value/eV, shell, materialName);
584 if(differentialCrossSection >= crossSectionMaximum) crossSectionMaximum = differentialCrossSection;
591 G4double secondaryElectronKineticEnergy=0.;
598 DifferentialCrossSection(particleDefinition, k/eV,(secondaryElectronKineticEnergy+ptbStructure.
IonisationEnergy(shell, materialName))/eV,shell, materialName));
600 return secondaryElectronKineticEnergy;
618 G4double maximumKineticEnergyTransfer = 4.* (electron_mass_c2 / proton_mass_c2) * k;
625 G4double differentialCrossSection = DifferentialCrossSection(particleDefinition, k/eV, value/eV, shell, materialName);
626 if (differentialCrossSection >= crossSectionMaximum) crossSectionMaximum = differentialCrossSection;
629 G4double secondaryElectronKineticEnergy = 0.;
632 secondaryElectronKineticEnergy =
G4UniformRand() * maximumKineticEnergyTransfer;
634 DifferentialCrossSection(particleDefinition, k/eV,(secondaryElectronKineticEnergy+ptbStructure.
IonisationEnergy(shell, materialName))/eV,shell, materialName));
636 return secondaryElectronKineticEnergy;
644void G4DNAPTBIonisationModel::RandomizeEjectedElectronDirection(
G4ParticleDefinition* particleDefinition,
654 else if (secKinetic <= 200.*eV)
661 G4double sin2O = (1.-secKinetic/k) / (1.+secKinetic/(2.*electron_mass_c2));
662 cosTheta = std::sqrt(1.-sin2O);
668 G4double maxSecKinetic = 4.* (electron_mass_c2 / proton_mass_c2) * k;
675 if (secKinetic>100*eV) cosTheta = std::sqrt(secKinetic / maxSecKinetic);
683double G4DNAPTBIonisationModel::DifferentialCrossSection(
G4ParticleDefinition * particleDefinition,
686 G4int ionizationLevelIndex,
693 G4double kSE (energyTransfer-shellEnergy);
695 if (energyTransfer >= shellEnergy)
712 std::vector<double>::iterator t2 = std::upper_bound(fTMapWithVec[materialName][particleName].begin(),fTMapWithVec[materialName][particleName].end(), k);
713 std::vector<double>::iterator t1 = t2-1;
716 if (kSE <= fEMapWithVector[materialName][particleName][(*t1)].back() && kSE <= fEMapWithVector[materialName][particleName][(*t2)].back() )
718 std::vector<double>::iterator e12 = std::upper_bound(fEMapWithVector[materialName][particleName][(*t1)].begin(),fEMapWithVector[materialName][particleName][(*t1)].end(), kSE);
719 std::vector<double>::iterator e11 = e12-1;
721 std::vector<double>::iterator e22 = std::upper_bound(fEMapWithVector[materialName][particleName][(*t2)].begin(),fEMapWithVector[materialName][particleName][(*t2)].end(), kSE);
722 std::vector<double>::iterator e21 = e22-1;
731 xs11 = diffCrossSectionData[materialName][particleName][ionizationLevelIndex][valueT1][valueE11];
732 xs12 = diffCrossSectionData[materialName][particleName][ionizationLevelIndex][valueT1][valueE12];
733 xs21 = diffCrossSectionData[materialName][particleName][ionizationLevelIndex][valueT2][valueE21];
734 xs22 = diffCrossSectionData[materialName][particleName][ionizationLevelIndex][valueT2][valueE22];
741 std::vector<double>::iterator t2 = std::upper_bound(fTMapWithVec[materialName][particleName].begin(),fTMapWithVec[materialName][particleName].end(), k);
742 std::vector<double>::iterator t1 = t2-1;
744 std::vector<double>::iterator e12 = std::upper_bound(fEMapWithVector[materialName][particleName][(*t1)].begin(),fEMapWithVector[materialName][particleName][(*t1)].end(), kSE);
745 std::vector<double>::iterator e11 = e12-1;
747 std::vector<double>::iterator e22 = std::upper_bound(fEMapWithVector[materialName][particleName][(*t2)].begin(),fEMapWithVector[materialName][particleName][(*t2)].end(), kSE);
748 std::vector<double>::iterator e21 = e22-1;
757 xs11 = diffCrossSectionData[materialName][particleName][ionizationLevelIndex][valueT1][valueE11];
758 xs12 = diffCrossSectionData[materialName][particleName][ionizationLevelIndex][valueT1][valueE12];
759 xs21 = diffCrossSectionData[materialName][particleName][ionizationLevelIndex][valueT2][valueE21];
760 xs22 = diffCrossSectionData[materialName][particleName][ionizationLevelIndex][valueT2][valueE22];
763 G4double xsProduct = xs11 * xs12 * xs21 * xs22;
767 sigma = QuadInterpolator(valueE11, valueE12,
809 G4double ejectedElectronEnergy = 0.;
839 std::vector<double>::iterator k2 = std::upper_bound(fTMapWithVec[materialName][particleName].begin(),fTMapWithVec[materialName][particleName].end(), k);
840 std::vector<double>::iterator k1 = k2-1;
850 G4cerr<<
"**************** Fatal error ******************"<<
G4endl;
851 G4cerr<<
"G4DNAPTBIonisationModel::RandomizeEjectedElectronEnergyFromCumulated"<<
G4endl;
852 G4cerr<<
"You have *k1 > *k2 with k1 "<<*k1<<
" and k2 "<<*k2<<
G4endl;
853 G4cerr<<
"This may be because the energy of the incident particle is to high for the data table."<<
G4endl;
863 std::vector<double>::iterator cumulCS12 = std::upper_bound(fProbaShellMap[materialName][particleName][ionizationLevelIndex][(*k1)].begin(),
864 fProbaShellMap[materialName][particleName][ionizationLevelIndex][(*k1)].end(), random);
865 std::vector<double>::iterator cumulCS11 = cumulCS12-1;
867 std::vector<double>::iterator cumulCS22 = std::upper_bound(fProbaShellMap[materialName][particleName][ionizationLevelIndex][(*k2)].begin(),
868 fProbaShellMap[materialName][particleName][ionizationLevelIndex][(*k2)].end(), random);
869 std::vector<double>::iterator cumulCS21 = cumulCS22-1;
874 valueCumulCS11 = *cumulCS11;
875 valueCumulCS12 = *cumulCS12;
876 valueCumulCS21 = *cumulCS21;
877 valueCumulCS22 = *cumulCS22;
893 if(cumulCS12==fProbaShellMap[materialName][particleName][ionizationLevelIndex][(*k1)].end())
898 secElecE21 = fEnergySecondaryData[materialName][particleName][ionizationLevelIndex][valueK2][valueCumulCS21];
899 secElecE22 = fEnergySecondaryData[materialName][particleName][ionizationLevelIndex][valueK2][valueCumulCS22];
907 secElecE11 = fEnergySecondaryData[materialName][particleName][ionizationLevelIndex][valueK1][valueCumulCS11];
908 secElecE12 = fEnergySecondaryData[materialName][particleName][ionizationLevelIndex][valueK1][valueCumulCS12];
909 secElecE21 = fEnergySecondaryData[materialName][particleName][ionizationLevelIndex][valueK2][valueCumulCS21];
910 secElecE22 = fEnergySecondaryData[materialName][particleName][ionizationLevelIndex][valueK2][valueCumulCS22];
913 ejectedElectronEnergy = QuadInterpolator(valueCumulCS11, valueCumulCS12,
914 valueCumulCS21, valueCumulCS22,
915 secElecE11, secElecE12,
916 secElecE21, secElecE22,
925 if(k-ejectedElectronEnergy-bindingEnergy<=0 || ejectedElectronEnergy<=0)
934 G4cout<<
"surrounding k values: valueK1 valueK2\n"<<valueK1<<
" "<<valueK2<<
G4endl;
935 G4cout<<
"surrounding E values: secElecE11 secElecE12 secElecE21 secElecE22\n"
936 <<secElecE11<<
" "<<secElecE12<<
" "<<secElecE21<<
" "<<secElecE22<<
" "<<
G4endl;
937 G4cout<<
"surrounding cumulCS values: valueCumulCS11 valueCumulCS12 valueCumulCS21 valueCumulCS22\n"
938 <<valueCumulCS11<<
" "<<valueCumulCS12<<
" "<<valueCumulCS21<<
" "<<valueCumulCS22<<
" "<<
G4endl;
944 return ejectedElectronEnergy*eV;
959 if ((e2-e1)!=0 && xs1 !=0 && xs2 !=0)
963 value = std::pow(10.,(d1 + (d2 - d1)*(e - e1)/ (e2 - e1)) );
969 if ((e2-e1)!=0 && (xs1 ==0 || xs2 ==0))
973 value = (d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
989 if(xs11!=xs12) interpolatedvalue1 = LogLogInterpolate(e11, e12, e, xs11, xs12);
990 else interpolatedvalue1 = xs11;
993 if(xs21!=xs22) interpolatedvalue2 = LogLogInterpolate(e21, e22, e, xs21, xs22);
994 else interpolatedvalue2 = xs21;
997 if(interpolatedvalue1!=interpolatedvalue2) value = LogLogInterpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
998 else value = interpolatedvalue1;
const char * G4FindDataDir(const char *)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4GLOB_DLL std::ostream G4cerr
G4GLOB_DLL std::ostream G4cout
Hep3Vector & rotateUz(const Hep3Vector &)
The G4DNAPTBAugerModel class Implement the PTB Auger model.
void ComputeAugerEffect(std::vector< G4DynamicParticle * > *fvect, const G4String &materialNameIni, G4double bindingEnergy)
ComputeAugerEffect Main method to be called by the ionisation model.
virtual void Initialise()
Initialise Set the verbose value.
virtual void Initialise(const G4ParticleDefinition *particle, const G4DataVector &= *(new G4DataVector()), G4ParticleChangeForGamma *fpChangeForGamme=nullptr)
Initialise Method called once at the beginning of the simulation. It is used to setup the list of the...
virtual G4double CrossSectionPerVolume(const G4Material *material, const G4String &materialName, const G4ParticleDefinition *p, G4double ekin, G4double emin, G4double emax)
CrossSectionPerVolume Mandatory for every model the CrossSectionPerVolume method is in charge of retu...
G4DNAPTBIonisationModel(const G4String &applyToMaterial="all", const G4ParticleDefinition *p=0, const G4String &nam="DNAPTBIonisationModel", const G4bool isAuger=true)
G4DNAPTBIonisationModel Constructor.
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4String &materialName, const G4DynamicParticle *, G4ParticleChangeForGamma *particleChangeForGamma, G4double tmin, G4double tmax)
SampleSecondaries If the model is selected for the ModelInterface then SampleSecondaries will be call...
virtual ~G4DNAPTBIonisationModel()
~G4DNAPTBIonisationModel Destructor
G4double IonisationEnergy(G4int level, const G4String &materialName)
G4int NumberOfLevels(const G4String &materialName)
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4Electron * ElectronDefinition()
static G4Electron * Electron()
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
G4double GetPDGMass() const
const G4String & GetParticleName() const
static G4Proton * ProtonDefinition()
G4int RandomSelectShell(G4double k, const G4String &particle, const G4String &materialName)
RandomSelectShell Method to randomely select a shell from the data table uploaded....
TableMapData * GetTableData()
GetTableData.
void SetHighELimit(const G4String &material, const G4String &particle, G4double lim)
SetHighEnergyLimit.
std::map< G4String, std::map< G4String, G4DNACrossSectionDataSet *, std::less< G4String > > > TableMapData
void AddCrossSectionData(G4String materialName, G4String particleName, G4String fileCS, G4String fileDiffCS, G4double scaleFactor)
AddCrossSectionData Method used during the initialization of the model class to add a new material....
void SetLowELimit(const G4String &material, const G4String &particle, G4double lim)
SetLowEnergyLimit.
G4double GetHighELimit(const G4String &material, const G4String &particle)
GetHighEnergyLimit.
void LoadCrossSectionData(const G4String &particleName)
LoadCrossSectionData Method to loop on all the registered materials in the model and load the corresp...
G4double GetLowELimit(const G4String &material, const G4String &particle)
GetLowEnergyLimit.
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
G4double bindingEnergy(G4int A, G4int Z)