Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4DNACPA100ExcitationModel.cc
Go to the documentation of this file.
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// CPA100 excitation model class for electrons
27//
28// Based on the work of M. Terrissol and M. C. Bordage
29//
30// Users are requested to cite the following papers:
31// - M. Terrissol, A. Baudre, Radiat. Prot. Dosim. 31 (1990) 175-177
32// - M.C. Bordage, J. Bordes, S. Edel, M. Terrissol, X. Franceries,
33// M. Bardies, N. Lampe, S. Incerti, Phys. Med. 32 (2016) 1833-1840
34//
35// Authors of this class:
36// M.C. Bordage, M. Terrissol, S. Edel, J. Bordes, S. Incerti
37//
38// 15.01.2014: creation
39//
40// 1/2/2023 : Hoang added modification for DNA cross sections
41
43
47#include "G4EnvironmentUtils.hh"
49#include "G4SystemOfUnits.hh"
50
51//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
52
53using namespace std;
54
55//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
56
58 const G4String& nam)
59 : G4VDNAModel(nam, "all")
60{
61 fpGuanine = G4Material::GetMaterial("G4_GUANINE", false);
62 fpG4_WATER = G4Material::GetMaterial("G4_WATER", false);
63 fpDeoxyribose = G4Material::GetMaterial("G4_DEOXYRIBOSE", false);
64 fpCytosine = G4Material::GetMaterial("G4_CYTOSINE", false);
65 fpThymine = G4Material::GetMaterial("G4_THYMINE", false);
66 fpAdenine = G4Material::GetMaterial("G4_ADENINE", false);
67 fpPhosphate = G4Material::GetMaterial("G4_PHOSPHORIC_ACID", false);
68 fpParticle = G4Electron::ElectronDefinition();
69}
70
71//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
72
74 const G4DataVector& /*cuts*/)
75{
76 if (isInitialised) {
77 return;
78 }
79 if (verboseLevel > 3) {
80 G4cout << "Calling G4DNACPA100ExcitationModel::Initialise()" << G4endl;
81 }
82
84 if (p != fpParticle) {
85 std::ostringstream oss;
86 oss << " Model is not applied for this particle " << p->GetParticleName();
87 G4Exception("G4DNACPA100ExcitationModel::G4DNACPA100ExcitationModel", "CPA001",
88 FatalException, oss.str().c_str());
89 }
90
91 const char* path = G4FindDataDir("G4LEDATA");
92
93 if (path == nullptr) {
94 G4Exception("G4DNACPA100ExcitationModel::Initialise", "em0006", FatalException,
95 "G4LEDATA environment variable not set.");
96 return;
97 }
98
99 std::size_t index;
100 if (fpG4_WATER != nullptr) {
101 index = fpG4_WATER->GetIndex();
102 AddCrossSectionData(index, p, "dna/sigma_excitation_e_cpa100", 1.e-20 * m * m);
103 SetLowELimit(index, p, 11 * eV);
104 SetHighELimit(index, p, 255955 * eV);
105 }
106 if (fpGuanine != nullptr) {
107 index = fpGuanine->GetIndex();
108 AddCrossSectionData(index, p, "dna/sigma_excitation_e_cpa100_guanine", 1. * cm * cm);
109 SetLowELimit(index, p, 11 * eV);
110 SetHighELimit(index, p, 1 * MeV);
111 }
112 if (fpDeoxyribose != nullptr) {
113 index = fpDeoxyribose->GetIndex();
114 AddCrossSectionData(index, p, "dna/sigma_excitation_e_cpa100_deoxyribose", 1. * cm * cm);
115 SetLowELimit(index, p, 11 * eV);
116 SetHighELimit(index, p, 1 * MeV);
117 }
118 if (fpCytosine != nullptr) {
119 index = fpCytosine->GetIndex();
120 AddCrossSectionData(index, p, "dna/sigma_excitation_e_cpa100_cytosine", 1. * cm * cm);
121 SetLowELimit(index, p, 11 * eV);
122 SetHighELimit(index, p, 1 * MeV);
123 }
124 if (fpThymine != nullptr) {
125 index = fpThymine->GetIndex();
126 AddCrossSectionData(index, p, "dna/sigma_excitation_e_cpa100_thymine", 1. * cm * cm);
127 SetLowELimit(index, p, 11 * eV);
128 SetHighELimit(index, p, 1 * MeV);
129 }
130 if (fpAdenine != nullptr) {
131 index = fpAdenine->GetIndex();
132 AddCrossSectionData(index, p, "dna/sigma_excitation_e_cpa100_adenine", 1. * cm * cm);
133 SetLowELimit(index, p, 11 * eV);
134 SetHighELimit(index, p, 1 * MeV);
135 }
136 if (fpPhosphate != nullptr) {
137 index = fpPhosphate->GetIndex();
138 AddCrossSectionData(index, p, "dna/sigma_excitation_e_cpa100_phosphoric_acid", 1. * cm * cm);
139 SetLowELimit(index, p, 11 * eV);
140 SetHighELimit(index, p, 1 * MeV);
141 }
142
145 fpModelData = this;
146 }
147 else {
148 auto dataModel = dynamic_cast<G4DNACPA100ExcitationModel*>(
150 if (dataModel == nullptr) {
151 G4cout << "G4DNACPA100ExcitationModel::CrossSectionPerVolume:: not good modelData" << G4endl;
152 throw;
153 }
154 fpModelData = dataModel;
155 }
156 fParticleChangeForGamma = GetParticleChangeForGamma();
157 isInitialised = true;
158}
159
160//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
161
163 const G4ParticleDefinition* p,
165{
166 // Get the name of the current particle
167 G4String particleName = p->GetParticleName();
168 auto MatID = material->GetIndex();
169 // initialise variables
170 G4double lowLim;
171 G4double highLim;
172 G4double sigma = 0;
173
174 // Get the low energy limit for the current particle
175 lowLim = fpModelData->GetLowELimit(MatID, p);
176
177 // Get the high energy limit for the current particle
178 highLim = fpModelData->GetHighELimit(MatID, p);
179
180 // Check that we are in the correct energy range
181 if (ekin >= lowLim && ekin < highLim) {
182 // Get the map with all the data tables
183 auto Data = fpModelData->GetData();
184
185 if ((*Data)[MatID][p] == nullptr) {
186 G4Exception("G4DNACPA100ExcitationModel::CrossSectionPerVolume", "em00236", FatalException,
187 "No model is registered");
188 }
189 // Retrieve the cross section value
190 sigma = (*Data)[MatID][p]->FindValue(ekin);
191
192 if (verboseLevel > 2) {
193 auto MolDensity =
195 G4cout << "__________________________________" << G4endl;
196 G4cout << "°°° G4DNACPA100ExcitationModel - XS INFO START" << G4endl;
197 G4cout << "°°° Kinetic energy(eV)=" << ekin / eV << " particle : " << particleName << G4endl;
198 G4cout << "°°° lowLim (eV) = " << lowLim / eV << " highLim (eV) : " << highLim / eV << G4endl;
199 G4cout << "°°° Materials = " << (*G4Material::GetMaterialTable())[MatID]->GetName() << G4endl;
200 G4cout << "°°° Cross section per " << MatID << " ID molecule (cm^2)=" << sigma / cm / cm
201 << G4endl;
202 G4cout << "°°° Cross section per Phosphate molecule (cm^-1)="
203 << sigma * MolDensity / (1. / cm) << G4endl;
204 G4cout << "°°° G4DNACPA100ExcitationModel - XS INFO END" << G4endl;
205 }
206 }
207
208 // Return the cross section value
209 auto MolDensity = (*G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(material))[MatID];
210 return sigma * MolDensity;
211}
212
213//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
214
215void G4DNACPA100ExcitationModel::SampleSecondaries(std::vector<G4DynamicParticle*>*,
216 const G4MaterialCutsCouple* couple,
217 const G4DynamicParticle* aDynamicParticle,
219{
220 auto materialID = couple->GetMaterial()->GetIndex();
221 G4double k = aDynamicParticle->GetKineticEnergy();
222 const auto& particle = aDynamicParticle->GetDefinition();
223 G4double lowLim = fpModelData->GetLowELimit(materialID, particle);
224 G4double highLim = fpModelData->GetHighELimit(materialID, particle);
225
226 // Check if we are in the correct energy range
227 if (k >= lowLim && k < highLim) {
228 G4int level;
229 G4double excitationEnergy;
230 G4double newEnergy;
231 if (materialID == fpG4_WATER->GetIndex()) {
232 level = fpModelData->RandomSelectShell(k, particle, materialID);
233 excitationEnergy = eStructure.ExcitationEnergy(level, materialID);
234 }
235 else {
236 do {
237 level = eStructure.NumberOfLevels(materialID) * G4UniformRand();
238 excitationEnergy = eStructure.ExcitationEnergy(level, materialID);
239 } while ((k - eStructure.ExcitationEnergy(level, materialID)) < 0);
240 }
241 newEnergy = k - excitationEnergy;
242
243 if (k - newEnergy <= 0) {
244 G4cout << "k : " << k << " newEnergy : " << newEnergy << G4endl;
245 G4cout << "newEnergy : " << newEnergy << " k : " << k
246 << " excitationEnergy: " << excitationEnergy << G4endl;
247 G4cout << "G4DNACPA100ExcitationModel::level : " << eStructure.NumberOfLevels(materialID)
248 << " excitationEnergy : " << excitationEnergy << G4endl;
249 G4cout << "°°° Materials = " << (*G4Material::GetMaterialTable())[materialID]->GetName()
250 << G4endl;
251 G4cout << "Attention an error occured !!!" << G4endl;
252 abort();
253 }
254
255 if (newEnergy >= 0) {
256 // We take into account direction change as described page 87 (II.92) in thesis by S. Edel
257
258 G4double cosTheta =
259 (excitationEnergy / k) / (1. + (k / (2 * electron_mass_c2)) * (1. - excitationEnergy / k));
260
261 cosTheta = std::sqrt(1. - cosTheta);
262 G4double phi = 2. * pi * G4UniformRand();
263 const G4ThreeVector& zVers = aDynamicParticle->GetMomentumDirection();
264 // Computation of scattering angles (from Subroutine DIRAN in CPA100)
265
266 G4double CT1, ST1, CF1, SF1, CT2, ST2, CF2, SF2;
267 G4double sinTheta = std::sqrt(1 - cosTheta * cosTheta);
268 CT1 = zVers.z();
269 ST1 = std::sqrt(1. - CT1 * CT1);
270
271 ST1 != 0 ? CF1 = zVers.x() / ST1 : CF1 = std::cos(2. * pi * G4UniformRand());
272 ST1 != 0 ? SF1 = zVers.y() / ST1 : SF1 = std::sqrt(1. - CF1 * CF1);
273 G4double A3, A4, A5, A2, A1;
274 A3 = sinTheta * std::cos(phi);
275 A4 = A3 * CT1 + ST1 * cosTheta;
276 A5 = sinTheta * std::sin(phi);
277 A2 = A4 * SF1 + A5 * CF1;
278 A1 = A4 * CF1 - A5 * SF1;
279
280 CT2 = CT1 * cosTheta - ST1 * A3;
281 ST2 = std::sqrt(1. - CT2 * CT2);
282
283 if (ST2 == 0) {
284 ST2 = 1E-6;
285 }
286 CF2 = A1 / ST2;
287 SF2 = A2 / ST2;
288
289 G4ThreeVector zPrimeVers(ST2 * CF2, ST2 * SF2, CT2);
290 fParticleChangeForGamma->ProposeMomentumDirection(zPrimeVers.unit());
291 if (!statCode) {
292 fParticleChangeForGamma->SetProposedKineticEnergy(newEnergy);
293 }
294 else {
295 fParticleChangeForGamma->SetProposedKineticEnergy(k);
296 }
297
298 fParticleChangeForGamma->ProposeLocalEnergyDeposit(excitationEnergy);
299
300 // Chemistry only for water;
301 if (materialID == fpG4_WATER->GetIndex()) {
302 const G4Track* theIncomingTrack = fParticleChangeForGamma->GetCurrentTrack();
304 theIncomingTrack);
305 }
306 }
307 else {
308 G4cerr << "newEnergy : " << newEnergy << " k : " << k
309 << " excitationEnergy: " << excitationEnergy << G4endl;
310 G4cerr << "G4DNACPA100ExcitationModel::level : " << eStructure.NumberOfLevels(materialID)
311 << " excitationEnergy : " << excitationEnergy << G4endl;
312 G4cerr << "°°° Materials = " << (*G4Material::GetMaterialTable())[materialID]->GetName()
313 << G4endl;
314 G4cerr << "Attention an error occured !!!" << G4endl;
315 G4Exception("G4DNACPA100ExcitationModel::SampleSecondaries", "em00236", FatalException,
316 "model is not registered for this energy");
317 }
318 }
319 else {
320 G4cerr << "k : " << k << " lowLim : " << lowLim << " highLim : " << highLim << G4endl;
321 G4Exception("G4DNACPA100ExcitationModel::SampleSecondaries", "em00236", FatalException,
322 "model is not registered for this energy");
323 }
324}
@ eExcitedMolecule
const char * G4FindDataDir(const char *)
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition Randomize.hh:52
double z() const
Hep3Vector unit() const
double x() const
double y() const
void Initialise(const G4ParticleDefinition *, const G4DataVector &) override
Initialise Each model must implement an Initialize method.
G4DNACPA100ExcitationModel(const G4ParticleDefinition *p=nullptr, const G4String &nam="DNACPA100ExcitationModel")
void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy) override
SampleSecondaries Each model must implement SampleSecondaries to decide if a particle will be created...
G4double CrossSectionPerVolume(const G4Material *material, const G4ParticleDefinition *p, G4double ekin, G4double emin, G4double emax) override
CrossSectionPerVolume Every model must implement its own CrossSectionPerVolume method....
std::size_t NumberOfLevels(const std::size_t &MatID)
G4double ExcitationEnergy(const std::size_t &level, const std::size_t &MatID)
static G4DNAChemistryManager * Instance()
void CreateWaterMolecule(ElectronicModification, G4int, const G4Track *)
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()
const G4ThreeVector & GetMomentumDirection() const
G4ParticleDefinition * GetDefinition() const
G4double GetKineticEnergy() const
static G4Electron * ElectronDefinition()
Definition G4Electron.cc:86
const G4Material * GetMaterial() const
std::size_t GetIndex() const
static G4MaterialTable * GetMaterialTable()
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
void SetProposedKineticEnergy(G4double proposedKinEnergy)
void ProposeMomentumDirection(const G4ThreeVector &Pfinal)
const G4String & GetParticleName() const
The G4VDNAModel class.
G4String GetName()
GetName.
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.
G4int RandomSelectShell(const G4double &k, const G4ParticleDefinition *particle, const size_t &materialName)
RandomSelectShell Method to randomely select a shell from the data table uploaded....
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()
G4bool IsLocked() const
const G4Track * GetCurrentTrack() const
void ProposeLocalEnergyDeposit(G4double anEnergyPart)