Geant4  10.01.p03
G4DNABornIonisationModel.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 // $Id: G4DNABornIonisationModel.cc 90769 2015-06-09 10:33:41Z gcosmo $
27 //
28 
30 #include "G4PhysicalConstants.hh"
31 #include "G4SystemOfUnits.hh"
32 #include "G4UAtomicDeexcitation.hh"
33 #include "G4LossTableManager.hh"
34 #include "G4DNAChemistryManager.hh"
36 #include "G4DNABornAngle.hh"
37 #include "G4DeltaAngle.hh"
38 
39 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
40 
41 using namespace std;
42 
43 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
44 
46  const G4String& nam) :
47  G4VEmModel(nam), isInitialised(false)
48 {
49  verboseLevel = 0;
50  // Verbosity scale:
51  // 0 = nothing
52  // 1 = warning for energy non-conservation
53  // 2 = details of energy budget
54  // 3 = calculation of cross sections, file openings, sampling of atoms
55  // 4 = entering in methods
56 
57  if (verboseLevel > 0)
58  {
59  G4cout << "Born ionisation model is constructed " << G4endl;
60  }
61 
62  //Mark this model as "applicable" for atomic deexcitation
63  SetDeexcitationFlag(true);
67 
68  // define default angular generator
70 
71  // Selection of computation method
72 
73  fasterCode = false;
74 }
75 
76 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
77 
79 {
80  // Cross section
81 
82  std::map<G4String, G4DNACrossSectionDataSet*, std::less<G4String> >::iterator pos;
83  for (pos = tableData.begin(); pos != tableData.end(); ++pos)
84  {
85  G4DNACrossSectionDataSet* table = pos->second;
86  delete table;
87  }
88 
89  // Final state
90 
91  eVecm.clear();
92  pVecm.clear();
93 }
94 
95 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
96 
98  const G4DataVector& /*cuts*/)
99 {
100 
101  if (verboseLevel > 3)
102  G4cout << "Calling G4DNABornIonisationModel::Initialise()" << G4endl;
103 
104  // Energy limits
105 
106  G4String fileElectron("dna/sigma_ionisation_e_born");
107  G4String fileProton("dna/sigma_ionisation_p_born");
108 
111 
114 
115  G4double scaleFactor = (1.e-22 / 3.343) * m*m;
116 
117  char *path = getenv("G4LEDATA");
118 
119  // *** ELECTRON
120 
121  electron = electronDef->GetParticleName();
122 
123  tableFile[electron] = fileElectron;
124 
125  lowEnergyLimit[electron] = 11. * eV;
126  highEnergyLimit[electron] = 1. * MeV;
127 
128  // Cross section
129 
131  tableE->LoadData(fileElectron);
132 
133  tableData[electron] = tableE;
134 
135  // Final state
136 
137  std::ostringstream eFullFileName;
138 
139  if (fasterCode) eFullFileName << path << "/dna/sigmadiff_cumulated_ionisation_e_born_hp.dat";
140  if (!fasterCode) eFullFileName << path << "/dna/sigmadiff_ionisation_e_born.dat";
141 
142  std::ifstream eDiffCrossSection(eFullFileName.str().c_str());
143 
144  if (!eDiffCrossSection)
145  {
146  if (fasterCode) G4Exception("G4DNABornIonisationModel::Initialise","em0003",
147  FatalException,"Missing data file:/dna/sigmadiff_cumulated_ionisation_e_born_hp.dat");
148 
149  if (!fasterCode) G4Exception("G4DNABornIonisationModel::Initialise","em0003",
150  FatalException,"Missing data file:/dna/sigmadiff_ionisation_e_born.dat");
151  }
152 
153  //
154 
155  // Clear the arrays for re-initialization case (MT mode)
156  // March 25th, 2014 - Vaclav Stepan, Sebastien Incerti
157 
158  eTdummyVec.clear();
159  pTdummyVec.clear();
160 
161  eVecm.clear();
162  pVecm.clear();
163 
164  for (int j=0; j<5; j++)
165  {
166  eProbaShellMap[j].clear();
167  pProbaShellMap[j].clear();
168 
169  eDiffCrossSectionData[j].clear();
170  pDiffCrossSectionData[j].clear();
171 
172  eNrjTransfData[j].clear();
173  pNrjTransfData[j].clear();
174  }
175  //
176 
177  eTdummyVec.push_back(0.);
178  while(!eDiffCrossSection.eof())
179  {
180  double tDummy;
181  double eDummy;
182  eDiffCrossSection>>tDummy>>eDummy;
183  if (tDummy != eTdummyVec.back()) eTdummyVec.push_back(tDummy);
184 
185  double tmp;
186  for (int j=0; j<5; j++)
187  {
188  eDiffCrossSection>> tmp;
189 
190  eDiffCrossSectionData[j][tDummy][eDummy] = tmp;
191 
192  if (fasterCode)
193  {
194  eNrjTransfData[j][tDummy][eDiffCrossSectionData[j][tDummy][eDummy]]=eDummy;
195  eProbaShellMap[j][tDummy].push_back(eDiffCrossSectionData[j][tDummy][eDummy]);
196  }
197 
198  // SI - only if eof is not reached
199  if (!eDiffCrossSection.eof() && !fasterCode) eDiffCrossSectionData[j][tDummy][eDummy]*=scaleFactor;
200 
201  if (!fasterCode) eVecm[tDummy].push_back(eDummy);
202 
203  }
204  }
205 
206  // *** PROTON
207 
208  proton = protonDef->GetParticleName();
209 
210  tableFile[proton] = fileProton;
211 
212  lowEnergyLimit[proton] = 500. * keV;
213  highEnergyLimit[proton] = 100. * MeV;
214 
215  // Cross section
216 
218  tableP->LoadData(fileProton);
219 
220  tableData[proton] = tableP;
221 
222  // Final state
223 
224  std::ostringstream pFullFileName;
225 
226  if (fasterCode) pFullFileName << path << "/dna/sigmadiff_cumulated_ionisation_p_born_hp.dat";
227 
228  if (!fasterCode) pFullFileName << path << "/dna/sigmadiff_ionisation_p_born.dat";
229 
230  std::ifstream pDiffCrossSection(pFullFileName.str().c_str());
231 
232  if (!pDiffCrossSection)
233  {
234  if (fasterCode) G4Exception("G4DNABornIonisationModel::Initialise","em0003",
235  FatalException,"Missing data file:/dna/sigmadiff_cumulated_ionisation_p_born_hp.dat");
236 
237  if (!fasterCode) G4Exception("G4DNABornIonisationModel::Initialise","em0003",
238  FatalException,"Missing data file:/dna/sigmadiff_ionisation_p_born.dat");
239  }
240 
241  pTdummyVec.push_back(0.);
242  while(!pDiffCrossSection.eof())
243  {
244  double tDummy;
245  double eDummy;
246  pDiffCrossSection>>tDummy>>eDummy;
247  if (tDummy != pTdummyVec.back()) pTdummyVec.push_back(tDummy);
248  for (int j=0; j<5; j++)
249  {
250  pDiffCrossSection>>pDiffCrossSectionData[j][tDummy][eDummy];
251 
252  if (fasterCode)
253  {
254  pNrjTransfData[j][tDummy][pDiffCrossSectionData[j][tDummy][eDummy]]=eDummy;
255  pProbaShellMap[j][tDummy].push_back(pDiffCrossSectionData[j][tDummy][eDummy]);
256  }
257 
258  // SI - only if eof is not reached !
259  if (!pDiffCrossSection.eof() && !fasterCode) pDiffCrossSectionData[j][tDummy][eDummy]*=scaleFactor;
260 
261  if (!fasterCode) pVecm[tDummy].push_back(eDummy);
262  }
263  }
264 
265  //
266 
267  if (particle==electronDef)
268  {
271  }
272 
273  if (particle==protonDef)
274  {
277  }
278 
279  if( verboseLevel>0 )
280  {
281  G4cout << "Born ionisation model is initialized " << G4endl
282  << "Energy range: "
283  << LowEnergyLimit() / eV << " eV - "
284  << HighEnergyLimit() / keV << " keV for "
285  << particle->GetParticleName()
286  << G4endl;
287  }
288 
289  // Initialize water density pointer
291  GetNumMolPerVolTableFor(G4Material::GetMaterial("G4_WATER"));
292 
293  //
295 
296  if (isInitialised)
297  { return;}
299  isInitialised = true;
300 }
301 
302 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
303 
305  const G4ParticleDefinition* particleDefinition,
306  G4double ekin,
307  G4double,
308  G4double)
309 {
310  if (verboseLevel > 3)
311  G4cout << "Calling CrossSectionPerVolume() of G4DNABornIonisationModel"
312  << G4endl;
313 
314  if (
315  particleDefinition != G4Proton::ProtonDefinition()
316  &&
317  particleDefinition != G4Electron::ElectronDefinition()
318  )
319 
320  return 0;
321 
322  // Calculate total cross section for model
323 
324  G4double lowLim = 0;
325  G4double highLim = 0;
326  G4double sigma=0;
327 
328  G4double waterDensity = (*fpMolWaterDensity)[material->GetIndex()];
329 
330  if(waterDensity!= 0.0)
331  // if (material == nistwater || material->GetBaseMaterial() == nistwater)
332  {
333  const G4String& particleName = particleDefinition->GetParticleName();
334 
335  std::map< G4String,G4double,std::less<G4String> >::iterator pos1;
336  pos1 = lowEnergyLimit.find(particleName);
337  if (pos1 != lowEnergyLimit.end())
338  {
339  lowLim = pos1->second;
340  }
341 
342  std::map< G4String,G4double,std::less<G4String> >::iterator pos2;
343  pos2 = highEnergyLimit.find(particleName);
344  if (pos2 != highEnergyLimit.end())
345  {
346  highLim = pos2->second;
347  }
348 
349  if (ekin >= lowLim && ekin < highLim)
350  {
351  std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
352  pos = tableData.find(particleName);
353 
354  if (pos != tableData.end())
355  {
356  G4DNACrossSectionDataSet* table = pos->second;
357  if (table != 0)
358  {
359  sigma = table->FindValue(ekin);
360  }
361  }
362  else
363  {
364  G4Exception("G4DNABornIonisationModel::CrossSectionPerVolume","em0002",
365  FatalException,"Model not applicable to particle type.");
366  }
367  }
368 
369  if (verboseLevel > 2)
370  {
371  G4cout << "__________________________________" << G4endl;
372  G4cout << "G4DNABornIonisationModel - XS INFO START" << G4endl;
373  G4cout << "Kinetic energy(eV)=" << ekin/eV << " particle : " << particleName << G4endl;
374  G4cout << "Cross section per water molecule (cm^2)=" << sigma/cm/cm << G4endl;
375  G4cout << "Cross section per water molecule (cm^-1)=" << sigma*waterDensity/(1./cm) << G4endl;
376  G4cout << "G4DNABornIonisationModel - XS INFO END" << G4endl;
377  }
378  } // if (waterMaterial)
379 
380  return sigma*waterDensity;
381 }
382 
383 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
384 
385 void G4DNABornIonisationModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
386  const G4MaterialCutsCouple* couple,
387  const G4DynamicParticle* particle,
388  G4double,
389  G4double)
390 {
391 
392  if (verboseLevel > 3)
393  G4cout << "Calling SampleSecondaries() of G4DNABornIonisationModel" << G4endl;
394 
395  G4double lowLim = 0;
396  G4double highLim = 0;
397 
398  G4double k = particle->GetKineticEnergy();
399 
400  const G4String& particleName = particle->GetDefinition()->GetParticleName();
401 
402  std::map< G4String,G4double,std::less<G4String> >::iterator pos1;
403  pos1 = lowEnergyLimit.find(particleName);
404 
405  if (pos1 != lowEnergyLimit.end())
406  {
407  lowLim = pos1->second;
408  }
409 
410  std::map< G4String,G4double,std::less<G4String> >::iterator pos2;
411  pos2 = highEnergyLimit.find(particleName);
412 
413  if (pos2 != highEnergyLimit.end())
414  {
415  highLim = pos2->second;
416  }
417 
418  if (k >= lowLim && k < highLim)
419  {
420  G4ParticleMomentum primaryDirection = particle->GetMomentumDirection();
421  G4double particleMass = particle->GetDefinition()->GetPDGMass();
422  G4double totalEnergy = k + particleMass;
423  G4double pSquare = k * (totalEnergy + particleMass);
424  G4double totalMomentum = std::sqrt(pSquare);
425 
426  G4int ionizationShell = 0;
427 
428  if (!fasterCode) ionizationShell = RandomSelect(k,particleName);
429 
430  // SI: The following protection is necessary to avoid infinite loops :
431  // sigmadiff_ionisation_e_born.dat has non zero partial xs at 18 eV for shell 3 (ionizationShell ==2)
432  // sigmadiff_cumulated_ionisation_e_born.dat has zero cumulated partial xs at 18 eV for shell 3 (ionizationShell ==2)
433  // this is due to the fact that the max allowed transfered energy is (18+10.79)/2=17.025 eV and only transfered energies
434  // strictly above this value have non zero partial xs in sigmadiff_ionisation_e_born.dat (starting at trans = 17.12 eV)
435 
436  if (fasterCode)
437  do
438  {
439  ionizationShell = RandomSelect(k,particleName);
440  }while (k<19*eV && ionizationShell==2 && particle->GetDefinition()==G4Electron::ElectronDefinition());
441 
442  // AM: sample deexcitation
443  // here we assume that H_{2}O electronic levels are the same of Oxigen.
444  // this can be considered true with a rough 10% error in energy on K-shell,
445 
446  G4int secNumberInit = 0;// need to know at a certain point the enrgy of secondaries
447  G4int secNumberFinal = 0;// So I'll make the diference and then sum the energies
448 
450  bindingEnergy = waterStructure.IonisationEnergy(ionizationShell);
451 
452  G4int Z = 8;
454  {
456 
457  if (ionizationShell <5 && ionizationShell >1)
458  {
459  as = G4AtomicShellEnumerator(4-ionizationShell);
460  }
461  else if (ionizationShell <2)
462  {
463  as = G4AtomicShellEnumerator(3);
464  }
465 
466  // FOR DEBUG ONLY
467  // if (ionizationShell == 4) {
468  //
469  // G4cout << "Z: " << Z << " as: " << as
470  // << " ionizationShell: " << ionizationShell << " bindingEnergy: "<< bindingEnergy/eV << G4endl;
471  // G4cout << "Press <Enter> key to continue..." << G4endl;
472  // G4cin.ignore();
473  // }
474 
475  const G4AtomicShell* shell = fAtomDeexcitation->GetAtomicShell(Z, as);
476  secNumberInit = fvect->size();
477  fAtomDeexcitation->GenerateParticles(fvect, shell, Z, 0, 0);
478  secNumberFinal = fvect->size();
479  }
480 
481  G4double secondaryKinetic=-1000*eV;
482 
483  if (fasterCode == false)
484  {
485  secondaryKinetic = RandomizeEjectedElectronEnergy(particle->GetDefinition(),k,ionizationShell);
486  }
487  // SI - 01/04/2014
488  else
489  {
490  secondaryKinetic = RandomizeEjectedElectronEnergyFromCumulatedDcs(particle->GetDefinition(),k,ionizationShell);
491  }
492  //
493 
494  G4ThreeVector deltaDirection =
495  GetAngularDistribution()->SampleDirectionForShell(particle, secondaryKinetic,
496  Z, ionizationShell,
497  couple->GetMaterial());
498 
499  if (particle->GetDefinition() == G4Electron::ElectronDefinition())
500  {
501  G4double deltaTotalMomentum = std::sqrt(secondaryKinetic*(secondaryKinetic + 2.*electron_mass_c2 ));
502 
503  G4double finalPx = totalMomentum*primaryDirection.x() - deltaTotalMomentum*deltaDirection.x();
504  G4double finalPy = totalMomentum*primaryDirection.y() - deltaTotalMomentum*deltaDirection.y();
505  G4double finalPz = totalMomentum*primaryDirection.z() - deltaTotalMomentum*deltaDirection.z();
506  G4double finalMomentum = std::sqrt(finalPx*finalPx + finalPy*finalPy + finalPz*finalPz);
507  finalPx /= finalMomentum;
508  finalPy /= finalMomentum;
509  finalPz /= finalMomentum;
510 
511  G4ThreeVector direction;
512  direction.set(finalPx,finalPy,finalPz);
513 
515  }
516 
517  else fParticleChangeForGamma->ProposeMomentumDirection(primaryDirection);
518 
519  // note thta secondaryKinetic is the nergy of the delta ray, not of all secondaries.
520  G4double scatteredEnergy = k-bindingEnergy-secondaryKinetic;
521  G4double deexSecEnergy = 0;
522  for (G4int j=secNumberInit; j < secNumberFinal; j++)
523  {
524  deexSecEnergy = deexSecEnergy + (*fvect)[j]->GetKineticEnergy();
525  }
526 
528  fParticleChangeForGamma->ProposeLocalEnergyDeposit(k-scatteredEnergy-secondaryKinetic-deexSecEnergy);
529 
530  // SI - 01/04/2014
531  if (secondaryKinetic>0)
532  {
533  G4DynamicParticle* dp = new G4DynamicParticle (G4Electron::Electron(),deltaDirection,secondaryKinetic);
534  fvect->push_back(dp);
535  }
536  //
537 
538  const G4Track * theIncomingTrack = fParticleChangeForGamma->GetCurrentTrack();
540  ionizationShell,
541  theIncomingTrack);
542  }
543 }
544 
545 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
546 
548  G4double k,
549  G4int shell)
550 {
551  // G4cout << "*** SLOW computation for " << " " << particleDefinition->GetParticleName() << G4endl;
552 
553  if (particleDefinition == G4Electron::ElectronDefinition())
554  {
555  G4double maximumEnergyTransfer = 0.;
556  if ((k + waterStructure.IonisationEnergy(shell)) / 2. > k) maximumEnergyTransfer =
557  k;
558  else maximumEnergyTransfer = (k + waterStructure.IonisationEnergy(shell))
559  / 2.;
560 
561  // SI : original method
562  /*
563  G4double crossSectionMaximum = 0.;
564  for(G4double value=waterStructure.IonisationEnergy(shell); value<=maximumEnergyTransfer; value+=0.1*eV)
565  {
566  G4double differentialCrossSection = DifferentialCrossSection(particleDefinition, k/eV, value/eV, shell);
567  if(differentialCrossSection >= crossSectionMaximum) crossSectionMaximum = differentialCrossSection;
568  }
569  */
570 
571  // SI : alternative method
572  G4double crossSectionMaximum = 0.;
573 
574  G4double minEnergy = waterStructure.IonisationEnergy(shell);
575  G4double maxEnergy = maximumEnergyTransfer;
576  G4int nEnergySteps = 50;
577 
578  G4double value(minEnergy);
579  G4double stpEnergy(
580  std::pow(maxEnergy / value,
581  1. / static_cast<G4double>(nEnergySteps - 1)));
582  G4int step(nEnergySteps);
583  while (step > 0)
584  {
585  step--;
586  G4double differentialCrossSection = DifferentialCrossSection(
587  particleDefinition, k / eV, value / eV, shell);
588  if (differentialCrossSection >= crossSectionMaximum) crossSectionMaximum =
589  differentialCrossSection;
590  value *= stpEnergy;
591  }
592  //
593 
594  G4double secondaryElectronKineticEnergy = 0.;
595  do
596  {
597  secondaryElectronKineticEnergy = G4UniformRand()* (maximumEnergyTransfer-waterStructure.IonisationEnergy(shell));
598  }while(G4UniformRand()*crossSectionMaximum >
599  DifferentialCrossSection(particleDefinition, k/eV,
600  (secondaryElectronKineticEnergy+waterStructure.IonisationEnergy(shell))/eV,shell));
601 
602  return secondaryElectronKineticEnergy;
603 
604  }
605 
606  else if (particleDefinition == G4Proton::ProtonDefinition())
607  {
608  G4double maximumKineticEnergyTransfer = 4.
609  * (electron_mass_c2 / proton_mass_c2) * k;
610 
611  G4double crossSectionMaximum = 0.;
612  for (G4double value = waterStructure.IonisationEnergy(shell);
613  value <= 4. * waterStructure.IonisationEnergy(shell); value += 0.1 * eV)
614  {
615  G4double differentialCrossSection = DifferentialCrossSection(
616  particleDefinition, k / eV, value / eV, shell);
617  if (differentialCrossSection >= crossSectionMaximum) crossSectionMaximum =
618  differentialCrossSection;
619  }
620 
621  G4double secondaryElectronKineticEnergy = 0.;
622  do
623  {
624  secondaryElectronKineticEnergy = G4UniformRand()* maximumKineticEnergyTransfer;
625  }while(G4UniformRand()*crossSectionMaximum >=
626  DifferentialCrossSection(particleDefinition, k/eV,
627  (secondaryElectronKineticEnergy+waterStructure.IonisationEnergy(shell))/eV,shell));
628 
629  return secondaryElectronKineticEnergy;
630  }
631 
632  return 0;
633 }
634 
635 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
636 
637 // The following section is not used anymore but is kept for memory
638 // GetAngularDistribution()->SampleDirectionForShell is used instead
639 
640 /*
641 void G4DNABornIonisationModel::RandomizeEjectedElectronDirection(G4ParticleDefinition* particleDefinition,
642  G4double k,
643  G4double secKinetic,
644  G4double & cosTheta,
645  G4double & phi )
646 {
647  if (particleDefinition == G4Electron::ElectronDefinition())
648  {
649  phi = twopi * G4UniformRand();
650  if (secKinetic < 50.*eV) cosTheta = (2.*G4UniformRand())-1.;
651  else if (secKinetic <= 200.*eV)
652  {
653  if (G4UniformRand() <= 0.1) cosTheta = (2.*G4UniformRand())-1.;
654  else cosTheta = G4UniformRand()*(std::sqrt(2.)/2);
655  }
656  else
657  {
658  G4double sin2O = (1.-secKinetic/k) / (1.+secKinetic/(2.*electron_mass_c2));
659  cosTheta = std::sqrt(1.-sin2O);
660  }
661  }
662 
663  else if (particleDefinition == G4Proton::ProtonDefinition())
664  {
665  G4double maxSecKinetic = 4.* (electron_mass_c2 / proton_mass_c2) * k;
666  phi = twopi * G4UniformRand();
667 
668  // cosTheta = std::sqrt(secKinetic / maxSecKinetic);
669 
670  // Restriction below 100 eV from Emfietzoglou (2000)
671 
672  if (secKinetic>100*eV) cosTheta = std::sqrt(secKinetic / maxSecKinetic);
673  else cosTheta = (2.*G4UniformRand())-1.;
674 
675  }
676 }
677 */
678 
679 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
680 
682  G4double k,
683  G4double energyTransfer,
684  G4int ionizationLevelIndex)
685 {
686  G4double sigma = 0.;
687 
688  if (energyTransfer >= waterStructure.IonisationEnergy(ionizationLevelIndex))
689  {
690  G4double valueT1 = 0;
691  G4double valueT2 = 0;
692  G4double valueE21 = 0;
693  G4double valueE22 = 0;
694  G4double valueE12 = 0;
695  G4double valueE11 = 0;
696 
697  G4double xs11 = 0;
698  G4double xs12 = 0;
699  G4double xs21 = 0;
700  G4double xs22 = 0;
701 
702  if (particleDefinition == G4Electron::ElectronDefinition())
703  {
704  // k should be in eV and energy transfer eV also
705 
706  std::vector<double>::iterator t2 = std::upper_bound(eTdummyVec.begin(),
707  eTdummyVec.end(), k);
708 
709  std::vector<double>::iterator t1 = t2 - 1;
710 
711  // SI : the following condition avoids situations where energyTransfer >last vector element
712  if (energyTransfer <= eVecm[(*t1)].back() && energyTransfer
713  <= eVecm[(*t2)].back())
714  {
715  std::vector<double>::iterator e12 = std::upper_bound(
716  eVecm[(*t1)].begin(), eVecm[(*t1)].end(), energyTransfer);
717  std::vector<double>::iterator e11 = e12 - 1;
718 
719  std::vector<double>::iterator e22 = std::upper_bound(
720  eVecm[(*t2)].begin(), eVecm[(*t2)].end(), energyTransfer);
721  std::vector<double>::iterator e21 = e22 - 1;
722 
723  valueT1 = *t1;
724  valueT2 = *t2;
725  valueE21 = *e21;
726  valueE22 = *e22;
727  valueE12 = *e12;
728  valueE11 = *e11;
729 
730  xs11 = eDiffCrossSectionData[ionizationLevelIndex][valueT1][valueE11];
731  xs12 = eDiffCrossSectionData[ionizationLevelIndex][valueT1][valueE12];
732  xs21 = eDiffCrossSectionData[ionizationLevelIndex][valueT2][valueE21];
733  xs22 = eDiffCrossSectionData[ionizationLevelIndex][valueT2][valueE22];
734 
735  }
736 
737  }
738 
739  if (particleDefinition == G4Proton::ProtonDefinition())
740  {
741  // k should be in eV and energy transfer eV also
742  std::vector<double>::iterator t2 = std::upper_bound(pTdummyVec.begin(),
743  pTdummyVec.end(), k);
744  std::vector<double>::iterator t1 = t2 - 1;
745 
746  std::vector<double>::iterator e12 = std::upper_bound(pVecm[(*t1)].begin(),
747  pVecm[(*t1)].end(),
748  energyTransfer);
749  std::vector<double>::iterator e11 = e12 - 1;
750 
751  std::vector<double>::iterator e22 = std::upper_bound(pVecm[(*t2)].begin(),
752  pVecm[(*t2)].end(),
753  energyTransfer);
754  std::vector<double>::iterator e21 = e22 - 1;
755 
756  valueT1 = *t1;
757  valueT2 = *t2;
758  valueE21 = *e21;
759  valueE22 = *e22;
760  valueE12 = *e12;
761  valueE11 = *e11;
762 
763  xs11 = pDiffCrossSectionData[ionizationLevelIndex][valueT1][valueE11];
764  xs12 = pDiffCrossSectionData[ionizationLevelIndex][valueT1][valueE12];
765  xs21 = pDiffCrossSectionData[ionizationLevelIndex][valueT2][valueE21];
766  xs22 = pDiffCrossSectionData[ionizationLevelIndex][valueT2][valueE22];
767 
768  }
769 
770  G4double xsProduct = xs11 * xs12 * xs21 * xs22;
771  if (xsProduct != 0.)
772  {
773  sigma = QuadInterpolator(valueE11, valueE12, valueE21, valueE22, xs11,
774  xs12, xs21, xs22, valueT1, valueT2, k,
775  energyTransfer);
776  }
777  }
778 
779  return sigma;
780 }
781 
782 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
783 
785  G4double e2,
786  G4double e,
787  G4double xs1,
788  G4double xs2)
789 {
790  G4double value = 0.;
791 
792  // Log-log interpolation by default
793 
794  if (e1!=0 && e2!=0 && (std::log10(e2)-std::log10(e1)) !=0 && !fasterCode)
795  {
796  G4double a = (std::log10(xs2)-std::log10(xs1)) / (std::log10(e2)-std::log10(e1));
797  G4double b = std::log10(xs2) - a*std::log10(e2);
798  G4double sigma = a*std::log10(e) + b;
799  value = (std::pow(10.,sigma));
800  }
801 
802  // Switch to lin-lin interpolation
803  /*
804  if ((e2-e1)!=0)
805  {
806  G4double d1 = xs1;
807  G4double d2 = xs2;
808  value = (d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
809  }
810  */
811 
812  // Switch to log-lin interpolation for faster code
813 
814  if ((e2-e1)!=0 && xs1 !=0 && xs2 !=0 && fasterCode )
815  {
816  G4double d1 = std::log10(xs1);
817  G4double d2 = std::log10(xs2);
818  value = std::pow(10.,(d1 + (d2 - d1)*(e - e1)/ (e2 - e1)) );
819  }
820 
821  // Switch to lin-lin interpolation for faster code
822  // in case one of xs1 or xs2 (=cum proba) value is zero
823 
824  if ((e2-e1)!=0 && (xs1 ==0 || xs2 ==0) && fasterCode )
825  {
826  G4double d1 = xs1;
827  G4double d2 = xs2;
828  value = (d1 + (d2 - d1)*(e - e1)/ (e2 - e1));
829  }
830 
831  /*
832  G4cout
833  << e1 << " "
834  << e2 << " "
835  << e << " "
836  << xs1 << " "
837  << xs2 << " "
838  << value
839  << G4endl;
840  */
841 
842  return value;
843 }
844 
845 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
846 
848  G4double e21, G4double e22,
849  G4double xs11, G4double xs12,
850  G4double xs21, G4double xs22,
851  G4double t1, G4double t2,
852  G4double t, G4double e)
853 {
854  G4double interpolatedvalue1 = Interpolate(e11, e12, e, xs11, xs12);
855  G4double interpolatedvalue2 = Interpolate(e21, e22, e, xs21, xs22);
856  G4double value = Interpolate(t1, t2, t, interpolatedvalue1, interpolatedvalue2);
857 
858  return value;
859 }
860 
861 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
862 
864 {
865  G4int level = 0;
866 
867  std::map< G4String,G4DNACrossSectionDataSet*,std::less<G4String> >::iterator pos;
868  pos = tableData.find(particle);
869 
870  if (pos != tableData.end())
871  {
872  G4DNACrossSectionDataSet* table = pos->second;
873 
874  if (table != 0)
875  {
876  G4double* valuesBuffer = new G4double[table->NumberOfComponents()];
877  const size_t n(table->NumberOfComponents());
878  size_t i(n);
879  G4double value = 0.;
880 
881  while (i>0)
882  {
883  i--;
884  valuesBuffer[i] = table->GetComponent(i)->FindValue(k);
885  value += valuesBuffer[i];
886  }
887 
888  value *= G4UniformRand();
889 
890  i = n;
891 
892  while (i > 0)
893  {
894  i--;
895 
896  if (valuesBuffer[i] > value)
897  {
898  delete[] valuesBuffer;
899  return i;
900  }
901  value -= valuesBuffer[i];
902  }
903 
904  if (valuesBuffer) delete[] valuesBuffer;
905 
906  }
907  }
908  else
909  {
910  G4Exception("G4DNABornIonisationModel::RandomSelect","em0002",
911  FatalException,"Model not applicable to particle type.");
912  }
913 
914  return level;
915 }
916 
917 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
918 
920 (G4ParticleDefinition* particleDefinition, G4double k, G4int shell)
921 {
922  //G4cout << "*** FAST computation for " << " " << particleDefinition->GetParticleName() << G4endl;
923 
924  G4double secondaryElectronKineticEnergy = 0.;
925 
926  secondaryElectronKineticEnergy=
927  RandomTransferedEnergy(particleDefinition, k/eV, shell)*eV-waterStructure.IonisationEnergy(shell);
928 
929  //G4cout << RandomTransferedEnergy(particleDefinition, k/eV, shell) << G4endl;
930  // SI - 01/04/2014
931  if (secondaryElectronKineticEnergy<0.) return 0.;
932  //
933 
934  return secondaryElectronKineticEnergy;
935 }
936 
937 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
938 
940 (G4ParticleDefinition* particleDefinition,G4double k, G4int ionizationLevelIndex)
941 {
942  G4double random = G4UniformRand();
943 
944  G4double nrj = 0.;
945 
946  G4double valueK1 = 0;
947  G4double valueK2 = 0;
948  G4double valuePROB21 = 0;
949  G4double valuePROB22 = 0;
950  G4double valuePROB12 = 0;
951  G4double valuePROB11 = 0;
952 
953  G4double nrjTransf11 = 0;
954  G4double nrjTransf12 = 0;
955  G4double nrjTransf21 = 0;
956  G4double nrjTransf22 = 0;
957 
958  if (particleDefinition == G4Electron::ElectronDefinition())
959  {
960  // k should be in eV
961  std::vector<double>::iterator k2 = std::upper_bound(eTdummyVec.begin(),
962  eTdummyVec.end(),
963  k);
964  std::vector<double>::iterator k1 = k2-1;
965 
966  /*
967  G4cout << "----> k=" << k
968  << " " << *k1
969  << " " << *k2
970  << " " << random
971  << " " << ionizationLevelIndex
972  << " " << eProbaShellMap[ionizationLevelIndex][(*k1)].back()
973  << " " << eProbaShellMap[ionizationLevelIndex][(*k2)].back()
974  << G4endl;
975  */
976 
977  // SI : the following condition avoids situations where random >last vector element
978  if ( random <= eProbaShellMap[ionizationLevelIndex][(*k1)].back()
979  && random <= eProbaShellMap[ionizationLevelIndex][(*k2)].back() )
980  {
981  std::vector<double>::iterator prob12 = std::upper_bound(eProbaShellMap[ionizationLevelIndex][(*k1)].begin(),
982  eProbaShellMap[ionizationLevelIndex][(*k1)].end(), random);
983 
984  std::vector<double>::iterator prob11 = prob12-1;
985 
986  std::vector<double>::iterator prob22 = std::upper_bound(eProbaShellMap[ionizationLevelIndex][(*k2)].begin(),
987  eProbaShellMap[ionizationLevelIndex][(*k2)].end(), random);
988 
989  std::vector<double>::iterator prob21 = prob22-1;
990 
991  valueK1 =*k1;
992  valueK2 =*k2;
993  valuePROB21 =*prob21;
994  valuePROB22 =*prob22;
995  valuePROB12 =*prob12;
996  valuePROB11 =*prob11;
997 
998  /*
999  G4cout << " " << random << " " << valuePROB11 << " "
1000  << valuePROB12 << " " << valuePROB21 << " " << valuePROB22 << G4endl;
1001  */
1002 
1003  nrjTransf11 = eNrjTransfData[ionizationLevelIndex][valueK1][valuePROB11];
1004  nrjTransf12 = eNrjTransfData[ionizationLevelIndex][valueK1][valuePROB12];
1005  nrjTransf21 = eNrjTransfData[ionizationLevelIndex][valueK2][valuePROB21];
1006  nrjTransf22 = eNrjTransfData[ionizationLevelIndex][valueK2][valuePROB22];
1007 
1008  /*
1009  G4cout << " " << ionizationLevelIndex << " "
1010  << random << " " <<valueK1 << " " << valueK2 << G4endl;
1011 
1012  G4cout << " " << random << " " << nrjTransf11 << " "
1013  << nrjTransf12 << " " << nrjTransf21 << " " <<nrjTransf22 << G4endl;
1014  */
1015 
1016  }
1017  // Avoids cases where cum xs is zero for k1 and is not for k2 (with always k1<k2)
1018  if ( random > eProbaShellMap[ionizationLevelIndex][(*k1)].back() )
1019  {
1020  std::vector<double>::iterator prob22 = std::upper_bound(eProbaShellMap[ionizationLevelIndex][(*k2)].begin(),
1021  eProbaShellMap[ionizationLevelIndex][(*k2)].end(), random);
1022 
1023  std::vector<double>::iterator prob21 = prob22-1;
1024 
1025  valueK1 =*k1;
1026  valueK2 =*k2;
1027  valuePROB21 =*prob21;
1028  valuePROB22 =*prob22;
1029 
1030  //G4cout << " " << random << " " << valuePROB21 << " " << valuePROB22 << G4endl;
1031 
1032  nrjTransf21 = eNrjTransfData[ionizationLevelIndex][valueK2][valuePROB21];
1033  nrjTransf22 = eNrjTransfData[ionizationLevelIndex][valueK2][valuePROB22];
1034 
1035  G4double interpolatedvalue2 = Interpolate(valuePROB21, valuePROB22, random, nrjTransf21, nrjTransf22);
1036 
1037  // zeros are explicitely set
1038 
1039  G4double value = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
1040 
1041  /*
1042  G4cout << " " << ionizationLevelIndex << " "
1043  << random << " " <<valueK1 << " " << valueK2 << G4endl;
1044 
1045  G4cout << " " << random << " " << nrjTransf11 << " "
1046  << nrjTransf12 << " " << nrjTransf21 << " " <<nrjTransf22 << G4endl;
1047 
1048  G4cout << "ici" << " " << value << G4endl;
1049  */
1050 
1051  return value;
1052  }
1053  }
1054  //
1055  else if (particleDefinition == G4Proton::ProtonDefinition())
1056  {
1057  // k should be in eV
1058 
1059  std::vector<double>::iterator k2 = std::upper_bound(pTdummyVec.begin(),pTdummyVec.end(), k);
1060 
1061  std::vector<double>::iterator k1 = k2-1;
1062 
1063  /*
1064  G4cout << "----> k=" << k
1065  << " " << *k1
1066  << " " << *k2
1067  << " " << random
1068  << " " << ionizationLevelIndex
1069  << " " << pProbaShellMap[ionizationLevelIndex][(*k1)].back()
1070  << " " << pProbaShellMap[ionizationLevelIndex][(*k2)].back()
1071  << G4endl;
1072  */
1073 
1074  // SI : the following condition avoids situations where random > last vector element,
1075  // for eg. when the last element is zero
1076  if ( random <= pProbaShellMap[ionizationLevelIndex][(*k1)].back()
1077  && random <= pProbaShellMap[ionizationLevelIndex][(*k2)].back() )
1078  {
1079  std::vector<double>::iterator prob12 = std::upper_bound(pProbaShellMap[ionizationLevelIndex][(*k1)].begin(),
1080  pProbaShellMap[ionizationLevelIndex][(*k1)].end(), random);
1081 
1082  std::vector<double>::iterator prob11 = prob12-1;
1083 
1084  std::vector<double>::iterator prob22 = std::upper_bound(pProbaShellMap[ionizationLevelIndex][(*k2)].begin(),
1085  pProbaShellMap[ionizationLevelIndex][(*k2)].end(), random);
1086 
1087  std::vector<double>::iterator prob21 = prob22-1;
1088 
1089  valueK1 =*k1;
1090  valueK2 =*k2;
1091  valuePROB21 =*prob21;
1092  valuePROB22 =*prob22;
1093  valuePROB12 =*prob12;
1094  valuePROB11 =*prob11;
1095 
1096  /*
1097  G4cout << " " << random << " " << valuePROB11 << " "
1098  << valuePROB12 << " " << valuePROB21 << " " << valuePROB22 << G4endl;
1099  */
1100 
1101  nrjTransf11 = pNrjTransfData[ionizationLevelIndex][valueK1][valuePROB11];
1102  nrjTransf12 = pNrjTransfData[ionizationLevelIndex][valueK1][valuePROB12];
1103  nrjTransf21 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB21];
1104  nrjTransf22 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB22];
1105 
1106  /*
1107  G4cout << " " << ionizationLevelIndex << " "
1108  << random << " " <<valueK1 << " " << valueK2 << G4endl;
1109 
1110  G4cout << " " << random << " " << nrjTransf11 << " "
1111  << nrjTransf12 << " " << nrjTransf21 << " " <<nrjTransf22 << G4endl;
1112  */
1113  }
1114 
1115  // Avoids cases where cum xs is zero for k1 and is not for k2 (with always k1<k2)
1116 
1117  if ( random > pProbaShellMap[ionizationLevelIndex][(*k1)].back() )
1118  {
1119  std::vector<double>::iterator prob22 = std::upper_bound(pProbaShellMap[ionizationLevelIndex][(*k2)].begin(),
1120  pProbaShellMap[ionizationLevelIndex][(*k2)].end(), random);
1121 
1122  std::vector<double>::iterator prob21 = prob22-1;
1123 
1124  valueK1 =*k1;
1125  valueK2 =*k2;
1126  valuePROB21 =*prob21;
1127  valuePROB22 =*prob22;
1128 
1129  //G4cout << " " << random << " " << valuePROB21 << " " << valuePROB22 << G4endl;
1130 
1131  nrjTransf21 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB21];
1132  nrjTransf22 = pNrjTransfData[ionizationLevelIndex][valueK2][valuePROB22];
1133 
1134  G4double interpolatedvalue2 = Interpolate(valuePROB21, valuePROB22, random, nrjTransf21, nrjTransf22);
1135 
1136  // zeros are explicitely set
1137 
1138  G4double value = Interpolate(valueK1, valueK2, k, 0., interpolatedvalue2);
1139 
1140  /*
1141  G4cout << " " << ionizationLevelIndex << " "
1142  << random << " " <<valueK1 << " " << valueK2 << G4endl;
1143 
1144  G4cout << " " << random << " " << nrjTransf11 << " "
1145  << nrjTransf12 << " " << nrjTransf21 << " " <<nrjTransf22 << G4endl;
1146 
1147  G4cout << "ici" << " " << value << G4endl;
1148  */
1149 
1150  return value;
1151  }
1152  }
1153  // End electron and proton cases
1154 
1155  G4double nrjTransfProduct = nrjTransf11 * nrjTransf12 * nrjTransf21 * nrjTransf22;
1156  //G4cout << "nrjTransfProduct=" << nrjTransfProduct << G4endl;
1157 
1158  if (nrjTransfProduct != 0.)
1159  {
1160  nrj = QuadInterpolator( valuePROB11, valuePROB12,
1161  valuePROB21, valuePROB22,
1162  nrjTransf11, nrjTransf12,
1163  nrjTransf21, nrjTransf22,
1164  valueK1, valueK2,
1165  k, random);
1166  }
1167  //G4cout << nrj << endl;
1168 
1169  return nrj;
1170 }
static const double cm
Definition: G4SIunits.hh:106
static G4Electron * ElectronDefinition()
Definition: G4Electron.cc:89
G4double RandomizeEjectedElectronEnergyFromCumulatedDcs(G4ParticleDefinition *aParticleDefinition, G4double incomingParticleEnergy, G4int shell)
G4double LowEnergyLimit() const
Definition: G4VEmModel.hh:623
static const double MeV
Definition: G4SIunits.hh:193
virtual G4double FindValue(G4double x, G4int componentId=0) const =0
static const G4double d1
static G4LossTableManager * Instance()
G4double GetKineticEnergy() const
CLHEP::Hep3Vector G4ThreeVector
G4double HighEnergyLimit() const
Definition: G4VEmModel.hh:616
const std::vector< G4double > * fpMolWaterDensity
virtual const G4VEMDataSet * GetComponent(G4int componentId) const
G4double RandomizeEjectedElectronEnergy(G4ParticleDefinition *aParticleDefinition, G4double incomingParticleEnergy, G4int shell)
static G4Material * GetMaterial(const G4String &name, G4bool warning=true)
Definition: G4Material.cc:603
size_t GetIndex() const
Definition: G4Material.hh:262
virtual void SampleSecondaries(std::vector< G4DynamicParticle * > *, const G4MaterialCutsCouple *, const G4DynamicParticle *, G4double tmin, G4double maxEnergy)
static G4Proton * ProtonDefinition()
Definition: G4Proton.cc:88
G4VEmAngularDistribution * GetAngularDistribution()
Definition: G4VEmModel.hh:599
std::map< G4String, G4double, std::less< G4String > > lowEnergyLimit
static const G4double e2
virtual G4double CrossSectionPerVolume(const G4Material *material, const G4ParticleDefinition *p, G4double ekin, G4double emin, G4double emax)
virtual G4bool LoadData(const G4String &argFileName)
G4ParticleDefinition * GetDefinition() const
G4double a
Definition: TRTMaterials.hh:39
G4double QuadInterpolator(G4double e11, G4double e12, G4double e21, G4double e22, G4double x11, G4double x12, G4double x21, G4double x22, G4double t1, G4double t2, G4double t, G4double e)
G4VAtomDeexcitation * fAtomDeexcitation
int G4int
Definition: G4Types.hh:78
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
const G4String & GetParticleName() const
void ProposeLocalEnergyDeposit(G4double anEnergyPart)
void SetHighEnergyLimit(G4double)
Definition: G4VEmModel.hh:707
virtual G4ThreeVector & SampleDirectionForShell(const G4DynamicParticle *dp, G4double finalTotalEnergy, G4int Z, G4int shellID, const G4Material *)
TriDimensionMap pDiffCrossSectionData[6]
virtual const G4AtomicShell * GetAtomicShell(G4int Z, G4AtomicShellEnumerator shell)=0
#define G4UniformRand()
Definition: Randomize.hh:93
G4GLOB_DLL std::ostream G4cout
const G4ThreeVector & GetMomentumDirection() const
G4DNABornIonisationModel(const G4ParticleDefinition *p=0, const G4String &nam="DNABornIonisationModel")
const G4int n
virtual G4double FindValue(G4double e, G4int componentId=0) const
G4int RandomSelect(G4double energy, const G4String &particle)
virtual size_t NumberOfComponents(void) const
static const G4double e1
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4DNAWaterIonisationStructure waterStructure
static G4DNAChemistryManager * Instance()
static const double eV
Definition: G4SIunits.hh:194
static G4DNAMolecularMaterial * Instance()
G4double RandomTransferedEnergy(G4ParticleDefinition *aParticleDefinition, G4double incomingParticleEnergy, G4int shell)
G4double GetPDGMass() const
void CreateWaterMolecule(ElectronicModification, G4int, const G4Track *)
Method used by DNA physics model to create a water molecule.
void SetAngularDistribution(G4VEmAngularDistribution *)
Definition: G4VEmModel.hh:606
G4ParticleChangeForGamma * fParticleChangeForGamma
G4double Interpolate(G4double e1, G4double e2, G4double e, G4double xs1, G4double xs2)
double DifferentialCrossSection(G4ParticleDefinition *aParticleDefinition, G4double k, G4double energyTransfer, G4int shell)
const G4Track * GetCurrentTrack() const
static G4Electron * Electron()
Definition: G4Electron.cc:94
void SetProposedKineticEnergy(G4double proposedKinEnergy)
#define G4endl
Definition: G4ios.hh:61
TriDimensionMap eDiffCrossSectionData[6]
static const double m
Definition: G4SIunits.hh:110
G4VAtomDeexcitation * AtomDeexcitation()
static const double keV
Definition: G4SIunits.hh:195
std::map< G4String, G4double, std::less< G4String > > highEnergyLimit
double G4double
Definition: G4Types.hh:76
void SetLowEnergyLimit(G4double)
Definition: G4VEmModel.hh:714
void GenerateParticles(std::vector< G4DynamicParticle * > *secVect, const G4AtomicShell *, G4int Z, G4int coupleIndex)
void SetDeexcitationFlag(G4bool val)
Definition: G4VEmModel.hh:763
static const G4double d2
G4ThreeVector G4ParticleMomentum
G4double bindingEnergy(G4int A, G4int Z)
static const G4double pos
virtual void Initialise(const G4ParticleDefinition *, const G4DataVector &=*(new G4DataVector()))
G4AtomicShellEnumerator
G4ParticleChangeForGamma * GetParticleChangeForGamma()
Definition: G4VEmModel.cc:134
const G4Material * GetMaterial() const