Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/models/src/G4DNARuddIonisationExtendedModel.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 ]

Diff markup

Differences between /processes/electromagnetic/dna/models/src/G4DNARuddIonisationExtendedModel.cc (Version 11.3.0) and /processes/electromagnetic/dna/models/src/G4DNARuddIonisationExtendedModel.cc (Version 11.2)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 //                                                 26 //
 27 // Modified by Z. Francis, S. Incerti to handl     27 // Modified by Z. Francis, S. Incerti to handle HZE 
 28 // && inverse rudd function sampling 26-10-201     28 // && inverse rudd function sampling 26-10-2010
 29 //                                                 29 //
 30 // Rewitten by V.Ivanchenko 21.05.2023             30 // Rewitten by V.Ivanchenko 21.05.2023
 31 //                                                 31 //
 32                                                    32 
 33 #include "G4EmCorrections.hh"                      33 #include "G4EmCorrections.hh"
 34 #include "G4DNARuddIonisationExtendedModel.hh"     34 #include "G4DNARuddIonisationExtendedModel.hh"
 35 #include "G4PhysicalConstants.hh"                  35 #include "G4PhysicalConstants.hh"
 36 #include "G4SystemOfUnits.hh"                      36 #include "G4SystemOfUnits.hh"
 37 #include "G4UAtomicDeexcitation.hh"                37 #include "G4UAtomicDeexcitation.hh"
 38 #include "G4LossTableManager.hh"                   38 #include "G4LossTableManager.hh"
 39 #include "G4NistManager.hh"                        39 #include "G4NistManager.hh"
 40 #include "G4DNAChemistryManager.hh"                40 #include "G4DNAChemistryManager.hh"
 41 #include "G4DNAMolecularMaterial.hh"               41 #include "G4DNAMolecularMaterial.hh"
 42                                                    42 
 43 #include "G4IonTable.hh"                           43 #include "G4IonTable.hh"
 44 #include "G4DNARuddAngle.hh"                       44 #include "G4DNARuddAngle.hh"
 45 #include "G4DeltaAngle.hh"                         45 #include "G4DeltaAngle.hh"
 46 #include "G4Exp.hh"                                46 #include "G4Exp.hh"
 47 #include "G4Log.hh"                                47 #include "G4Log.hh"
 48 #include "G4Pow.hh"                                48 #include "G4Pow.hh"
 49 #include "G4Alpha.hh"                              49 #include "G4Alpha.hh"
 50 #include "G4Proton.hh"                             50 #include "G4Proton.hh"
                                                   >>  51 #include "G4AutoLock.hh"
 51                                                    52 
 52 //....oooOO0OOooo........oooOO0OOooo........oo     53 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 53                                                    54 
 54 G4DNACrossSectionDataSet* G4DNARuddIonisationE     55 G4DNACrossSectionDataSet* G4DNARuddIonisationExtendedModel::xsdata[] = {nullptr};
 55 G4DNACrossSectionDataSet* G4DNARuddIonisationE     56 G4DNACrossSectionDataSet* G4DNARuddIonisationExtendedModel::xshelium = nullptr;
 56 G4DNACrossSectionDataSet* G4DNARuddIonisationE     57 G4DNACrossSectionDataSet* G4DNARuddIonisationExtendedModel::xsalphaplus = nullptr;
 57 const std::vector<G4double>* G4DNARuddIonisati     58 const std::vector<G4double>* G4DNARuddIonisationExtendedModel::fpWaterDensity = nullptr;
 58                                                    59 
 59 namespace                                          60 namespace
 60 {                                                  61 {
                                                   >>  62   G4Mutex ionDNAMutex = G4MUTEX_INITIALIZER;
 61   const G4double scaleFactor = CLHEP::m*CLHEP:     63   const G4double scaleFactor = CLHEP::m*CLHEP::m;
 62   const G4double tolerance = 1*CLHEP::eV;          64   const G4double tolerance = 1*CLHEP::eV;
 63   const G4double Ry = 13.6*CLHEP::eV;              65   const G4double Ry = 13.6*CLHEP::eV;
                                                   >>  66   const G4double Gj[5] = {0.99, 1.11, 1.11, 0.52, 1.};
 64                                                    67 
 65   // Following values provided by M. Dingfelde     68   // Following values provided by M. Dingfelder (priv. comm)
 66   const G4double Bj[5] = {12.60*CLHEP::eV, 14.     69   const G4double Bj[5] = {12.60*CLHEP::eV, 14.70*CLHEP::eV, 18.40*CLHEP::eV,
 67                           32.20*CLHEP::eV, 539     70                           32.20*CLHEP::eV, 539*CLHEP::eV};
 68 }                                                  71 }
 69                                                    72 
 70 //....oooOO0OOooo........oooOO0OOooo........oo     73 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 71                                                    74 
 72 G4DNARuddIonisationExtendedModel::G4DNARuddIon     75 G4DNARuddIonisationExtendedModel::G4DNARuddIonisationExtendedModel(const G4ParticleDefinition*,
 73                                                    76                                                                    const G4String& nam)
 74   : G4VEmModel(nam)                                77   : G4VEmModel(nam)
 75 {                                                  78 {
 76   fEmCorrections = G4LossTableManager::Instanc     79   fEmCorrections = G4LossTableManager::Instance()->EmCorrections();
 77   fGpow = G4Pow::GetInstance();                    80   fGpow = G4Pow::GetInstance();
 78   fLowestEnergy = 100*CLHEP::eV;                   81   fLowestEnergy = 100*CLHEP::eV;
 79   fLimitEnergy = 1*CLHEP::keV;                     82   fLimitEnergy = 1*CLHEP::keV;
 80                                                    83 
 81   // Mark this model as "applicable" for atomi     84   // Mark this model as "applicable" for atomic deexcitation
 82   SetDeexcitationFlag(true);                       85   SetDeexcitationFlag(true);
 83                                                    86 
 84   // Define default angular generator              87   // Define default angular generator
 85   SetAngularDistribution(new G4DNARuddAngle())     88   SetAngularDistribution(new G4DNARuddAngle());
 86                                                << 
 87   if (nullptr == xshelium) { LoadData(); }     << 
 88 }                                                  89 }
 89                                                    90 
 90 //....oooOO0OOooo........oooOO0OOooo........oo     91 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 91                                                    92 
 92 G4DNARuddIonisationExtendedModel::~G4DNARuddIo     93 G4DNARuddIonisationExtendedModel::~G4DNARuddIonisationExtendedModel()
 93 {                                                  94 {  
 94   if(isFirst) {                                    95   if(isFirst) {
 95     for(auto & i : xsdata) { delete i; }           96     for(auto & i : xsdata) { delete i; }
 96   }                                                97   }
 97 }                                                  98 }
 98                                                    99 
 99 //....oooOO0OOooo........oooOO0OOooo........oo    100 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
100                                                   101 
101 void G4DNARuddIonisationExtendedModel::LoadDat << 
102 {                                              << 
103   // initialisation of static data once        << 
104   isFirst = true;                              << 
105   G4String filename("dna/sigma_ionisation_h_ru << 
106   xsdata[0] = new G4DNACrossSectionDataSet(new << 
107   xsdata[0]->LoadData(filename);               << 
108                                                << 
109   filename = "dna/sigma_ionisation_p_rudd";    << 
110   xsdata[1] = new G4DNACrossSectionDataSet(new << 
111   xsdata[1]->LoadData(filename);               << 
112                                                << 
113   filename = "dna/sigma_ionisation_alphapluspl << 
114   xsdata[2] = new G4DNACrossSectionDataSet(new << 
115   xsdata[2]->LoadData(filename);               << 
116                                                << 
117   filename = "dna/sigma_ionisation_li_rudd";   << 
118   xsdata[3] = new G4DNACrossSectionDataSet(new << 
119   xsdata[3]->LoadData(filename);               << 
120                                                << 
121   filename = "dna/sigma_ionisation_be_rudd";   << 
122   xsdata[4] = new G4DNACrossSectionDataSet(new << 
123   xsdata[4]->LoadData(filename);               << 
124                                                << 
125   filename = "dna/sigma_ionisation_b_rudd";    << 
126   xsdata[5] = new G4DNACrossSectionDataSet(new << 
127   xsdata[5]->LoadData(filename);               << 
128                                                << 
129   filename = "dna/sigma_ionisation_c_rudd";    << 
130   xsdata[6] = new G4DNACrossSectionDataSet(new << 
131   xsdata[6]->LoadData(filename);               << 
132                                                << 
133   filename = "dna/sigma_ionisation_n_rudd";    << 
134   xsdata[7] = new G4DNACrossSectionDataSet(new << 
135   xsdata[7]->LoadData(filename);               << 
136                                                << 
137   filename = "dna/sigma_ionisation_o_rudd";    << 
138   xsdata[8] = new G4DNACrossSectionDataSet(new << 
139   xsdata[8]->LoadData(filename);               << 
140                                                << 
141   filename = "dna/sigma_ionisation_si_rudd";   << 
142   xsdata[14] = new G4DNACrossSectionDataSet(ne << 
143   xsdata[14]->LoadData(filename);              << 
144                                                << 
145   filename = "dna/sigma_ionisation_fe_rudd";   << 
146   xsdata[26] = new G4DNACrossSectionDataSet(ne << 
147   xsdata[26]->LoadData(filename);              << 
148                                                << 
149   filename = "dna/sigma_ionisation_alphaplus_r << 
150   xsalphaplus = new G4DNACrossSectionDataSet(n << 
151   xsalphaplus->LoadData(filename);             << 
152                                                << 
153   filename = "dna/sigma_ionisation_he_rudd";   << 
154   xshelium = new G4DNACrossSectionDataSet(new  << 
155   xshelium->LoadData(filename);                << 
156                                                << 
157   // to avoid possible threading problem fill  << 
158   auto water = G4NistManager::Instance()->Find << 
159   fpWaterDensity =                             << 
160     G4DNAMolecularMaterial::Instance()->GetNum << 
161 }                                              << 
162                                                << 
163 //....oooOO0OOooo........oooOO0OOooo........oo << 
164                                                << 
165 void G4DNARuddIonisationExtendedModel::Initial    102 void G4DNARuddIonisationExtendedModel::Initialise(const G4ParticleDefinition* p,
166                                                   103                                                   const G4DataVector&)
167 {                                                 104 {
168   if (p != fParticle) { SetParticle(p); }      << 105   if(p != fParticle) { SetParticle(p); }
169                                                   106 
170   // particle change object may be externally  << 107   // initialisation of static data once
171   if (nullptr == fParticleChangeForGamma) {    << 108   if(nullptr == xsdata[0]) {
172     fParticleChangeForGamma = GetParticleChang << 109     G4AutoLock l(&ionDNAMutex);
                                                   >> 110     if(nullptr == xsdata[0]) {
                                                   >> 111       isFirst = true;
                                                   >> 112       G4String filename("dna/sigma_ionisation_h_rudd");
                                                   >> 113       xsdata[0] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
                                                   >> 114       xsdata[0]->LoadData(filename);
                                                   >> 115 
                                                   >> 116       filename = "dna/sigma_ionisation_p_rudd";
                                                   >> 117       xsdata[1] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
                                                   >> 118       xsdata[1]->LoadData(filename);
                                                   >> 119 
                                                   >> 120       filename = "dna/sigma_ionisation_alphaplusplus_rudd";
                                                   >> 121       xsdata[2] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
                                                   >> 122       xsdata[2]->LoadData(filename);
                                                   >> 123 
                                                   >> 124       filename = "dna/sigma_ionisation_li_rudd";
                                                   >> 125       xsdata[3] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
                                                   >> 126       xsdata[3]->LoadData(filename);
                                                   >> 127 
                                                   >> 128       filename = "dna/sigma_ionisation_be_rudd";
                                                   >> 129       xsdata[4] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
                                                   >> 130       xsdata[4]->LoadData(filename);
                                                   >> 131 
                                                   >> 132       filename = "dna/sigma_ionisation_b_rudd";
                                                   >> 133       xsdata[5] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
                                                   >> 134       xsdata[5]->LoadData(filename);
                                                   >> 135 
                                                   >> 136       filename = "dna/sigma_ionisation_c_rudd";
                                                   >> 137       xsdata[6] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
                                                   >> 138       xsdata[6]->LoadData(filename);
                                                   >> 139 
                                                   >> 140       filename = "dna/sigma_ionisation_n_rudd";
                                                   >> 141       xsdata[7] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
                                                   >> 142       xsdata[7]->LoadData(filename);
                                                   >> 143 
                                                   >> 144       filename = "dna/sigma_ionisation_o_rudd";
                                                   >> 145       xsdata[8] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
                                                   >> 146       xsdata[8]->LoadData(filename);
                                                   >> 147 
                                                   >> 148       filename = "dna/sigma_ionisation_si_rudd";
                                                   >> 149       xsdata[14] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
                                                   >> 150       xsdata[14]->LoadData(filename);
                                                   >> 151 
                                                   >> 152       filename = "dna/sigma_ionisation_fe_rudd";
                                                   >> 153       xsdata[26] = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
                                                   >> 154       xsdata[26]->LoadData(filename);
                                                   >> 155       filename = "dna/sigma_ionisation_alphaplus_rudd";
                                                   >> 156       xsalphaplus = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
                                                   >> 157       xsalphaplus->LoadData(filename);
                                                   >> 158 
                                                   >> 159       filename = "dna/sigma_ionisation_he_rudd";
                                                   >> 160       xshelium = new G4DNACrossSectionDataSet(new G4LogLogInterpolation, CLHEP::eV, scaleFactor);
                                                   >> 161       xshelium->LoadData(filename);
                                                   >> 162     }
                                                   >> 163     // to avoid possible threading problem fill this vector only once
                                                   >> 164     auto water = G4NistManager::Instance()->FindMaterial("G4_WATER");
                                                   >> 165     fpWaterDensity =
                                                   >> 166       G4DNAMolecularMaterial::Instance()->GetNumMolPerVolTableFor(water);
                                                   >> 167 
                                                   >> 168     l.unlock();
173   }                                               169   }
174                                                   170 
175   // initialisation once in each thread           171   // initialisation once in each thread
176   if (!isInitialised) {                        << 172   if(nullptr == fParticleChangeForGamma) {
177     isInitialised = true;                      << 173     fParticleChangeForGamma = GetParticleChangeForGamma();
178     const G4String& pname = fParticle->GetPart    174     const G4String& pname = fParticle->GetParticleName();
179     if (pname == "proton") {                   << 175     if(pname == "proton") {
180       idx = 1;                                    176       idx = 1;
181       xscurrent = xsdata[1];                      177       xscurrent = xsdata[1];
182       fElow = fLowestEnergy;                      178       fElow = fLowestEnergy;
183     } else if (pname == "hydrogen") {          << 179     } else if(pname == "hydrogen") {
184       idx = 0;                                    180       idx = 0; 
185       xscurrent = xsdata[0];                      181       xscurrent = xsdata[0];
186       fElow = fLowestEnergy;                      182       fElow = fLowestEnergy;
187     } else if (pname == "alpha") {             << 183     } else if(pname == "alpha") {
188       idx = 1;                                    184       idx = 1;
189       xscurrent = xsdata[2];                      185       xscurrent = xsdata[2];
190       isHelium = true;                            186       isHelium = true;
191       fElow = fLimitEnergy;                       187       fElow = fLimitEnergy;
192     } else if (pname == "alpha+") {            << 188     } else if(pname == "alpha+") {
193       idx = 1;                                    189       idx = 1;
194       isHelium = true;                            190       isHelium = true;
195       xscurrent = xsalphaplus;                    191       xscurrent = xsalphaplus;
196       fElow = fLimitEnergy;                       192       fElow = fLimitEnergy;
197       // The following values are provided by     193       // The following values are provided by M. Dingfelder (priv. comm)
198       slaterEffectiveCharge[0]=2.0;               194       slaterEffectiveCharge[0]=2.0;
199       slaterEffectiveCharge[1]=2.0;               195       slaterEffectiveCharge[1]=2.0;
200       slaterEffectiveCharge[2]=2.0;               196       slaterEffectiveCharge[2]=2.0;
201       sCoefficient[0]=0.7;                        197       sCoefficient[0]=0.7;
202       sCoefficient[1]=0.15;                       198       sCoefficient[1]=0.15;
203       sCoefficient[2]=0.15;                       199       sCoefficient[2]=0.15;
204     } else if (pname == "helium") {            << 200     } else if(pname == "helium") {
205       idx = 0;                                    201       idx = 0; 
206       isHelium = true;                            202       isHelium = true;
207       fElow = fLimitEnergy;                       203       fElow = fLimitEnergy;
208       xscurrent = xshelium;                       204       xscurrent = xshelium;
209       slaterEffectiveCharge[0]=1.7;               205       slaterEffectiveCharge[0]=1.7;
210       slaterEffectiveCharge[1]=1.15;              206       slaterEffectiveCharge[1]=1.15;
211       slaterEffectiveCharge[2]=1.15;              207       slaterEffectiveCharge[2]=1.15;
212       sCoefficient[0]=0.5;                        208       sCoefficient[0]=0.5;
213       sCoefficient[1]=0.25;                       209       sCoefficient[1]=0.25;
214       sCoefficient[2]=0.25;                       210       sCoefficient[2]=0.25;
215     } else {                                      211     } else {
216       isIon = true;                               212       isIon = true;
217       idx = -1;                                << 
218       xscurrent = xsdata[1];                   << 
219       fElow = fLowestEnergy;                   << 
220     }                                             213     }
221     // defined stationary mode                    214     // defined stationary mode
222     statCode = G4EmParameters::Instance()->DNA    215     statCode = G4EmParameters::Instance()->DNAStationary();
223                                                   216 
224     // initialise atomic de-excitation            217     // initialise atomic de-excitation
225     fAtomDeexcitation = G4LossTableManager::In    218     fAtomDeexcitation = G4LossTableManager::Instance()->AtomDeexcitation();
226                                                   219 
227     if (verbose > 0) {                            220     if (verbose > 0) {
228       G4cout << "### G4DNARuddIonisationExtend    221       G4cout << "### G4DNARuddIonisationExtendedModel::Initialise(..) " << pname 
229        << "/n    idx=" << idx << " isIon=" <<  << 222        << "/n    idx=" << idx << " Amass=" << fAmass 
230        << " isHelium=" << isHelium << G4endl;  << 223        << " isIon=" << isIon << " isHelium=" << isHelium << G4endl;
231     }                                             224     }
232   }                                               225   }
233 }                                                 226 }
234                                                   227 
235 //....oooOO0OOooo........oooOO0OOooo........oo    228 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
236                                                   229 
237 void G4DNARuddIonisationExtendedModel::SetPart    230 void G4DNARuddIonisationExtendedModel::SetParticle(const G4ParticleDefinition* p)
238 {                                                 231 {
239   fParticle = p;                                  232   fParticle = p;
240   fMass = p->GetPDGMass();                        233   fMass = p->GetPDGMass();
241   fMassRate = (isIon) ? CLHEP::proton_mass_c2/ << 234   fAmass = p->GetAtomicMass();
                                                   >> 235 
                                                   >> 236   // for generic ions idx is dynamic, -1 means that data for the ion does not exist
                                                   >> 237   if(isIon) { 
                                                   >> 238     G4int i = p->GetAtomicNumber();
                                                   >> 239     idx = -1;
                                                   >> 240     if (i < RUDDZMAX && nullptr != xsdata[i]) {
                                                   >> 241       idx = i;
                                                   >> 242       fElow = fAmass*fLowestEnergy;
                                                   >> 243     }
                                                   >> 244   }
242 }                                                 245 }
243                                                   246 
244 //....oooOO0OOooo........oooOO0OOooo........oo    247 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
245                                                   248 
246 G4double                                          249 G4double 
247 G4DNARuddIonisationExtendedModel::CrossSection    250 G4DNARuddIonisationExtendedModel::CrossSectionPerVolume(const G4Material* material,
248                                                   251                                                         const G4ParticleDefinition* part,
249                                                   252                                                         G4double kinE,
250                                                   253                                                         G4double, G4double)
251 {                                                 254 {
252   // check if model is applicable for given ma    255   // check if model is applicable for given material
253   G4double density = (material->GetIndex() < f    256   G4double density = (material->GetIndex() < fpWaterDensity->size())
254     ? (*fpWaterDensity)[material->GetIndex()]     257     ? (*fpWaterDensity)[material->GetIndex()] : 0.0;
255   if (0.0 == density) { return 0.0; }             258   if (0.0 == density) { return 0.0; }
256                                                   259 
257   // ion may be different                         260   // ion may be different
258   if (fParticle != part) { SetParticle(part);     261   if (fParticle != part) { SetParticle(part); }
259                                                   262 
                                                   >> 263   // initilise mass rate
                                                   >> 264   fMassRate = 1.0;
                                                   >> 265 
260   // ion shoud be stopped - check on kinetic e    266   // ion shoud be stopped - check on kinetic energy and not scaled energy
261   if (kinE < fLowestEnergy) { return DBL_MAX;     267   if (kinE < fLowestEnergy) { return DBL_MAX; }
262                                                   268 
263   G4double e = kinE*fMassRate;                 << 269   G4double sigma = 0.;
264                                                << 270   
265   G4double sigma = (e > fElow) ? xscurrent->Fi << 271   // use ion table if available for given energy
266     : xscurrent->FindValue(fElow) * e / fElow; << 272   // for proton, hydrogen, alpha, alpha+, and helium no scaling to proton x-section
                                                   >> 273   if (idx == 0 || idx == 1) {
                                                   >> 274     sigma = (kinE > fElow) ? xscurrent->FindValue(kinE)
                                                   >> 275       : xscurrent->FindValue(fElow)*kinE/fElow;
                                                   >> 276 
                                                   >> 277     // for ions with data above limit energy
                                                   >> 278   } else if (idx > 1) {
                                                   >> 279     sigma = (kinE > fElow) ? xsdata[idx]->FindValue(kinE)
                                                   >> 280       : xsdata[idx]->FindValue(fElow)*kinE/fElow;
267                                                   281 
268   if (idx == -1) {                             << 282     // scaling from proton
                                                   >> 283   } else {
                                                   >> 284     fMassRate = CLHEP::proton_mass_c2/fMass;
                                                   >> 285     G4double e = kinE*fMassRate;
                                                   >> 286     sigma = (e > fLowestEnergy) ? xsdata[1]->FindValue(e)
                                                   >> 287       : xsdata[1]->FindValue(fLowestEnergy)*e/fLowestEnergy;
269     sigma *= fEmCorrections->EffectiveChargeSq    288     sigma *= fEmCorrections->EffectiveChargeSquareRatio(part, material, kinE);
270   }                                               289   }
271                                                << 
272   sigma *= density;                               290   sigma *= density;
273                                                   291 
274   if (verbose > 1) {                              292   if (verbose > 1) {
275     G4cout << "G4DNARuddIonisationExtendedMode    293     G4cout << "G4DNARuddIonisationExtendedModel for " << part->GetParticleName() 
276            << " Ekin(keV)=" << kinE/CLHEP::keV    294            << " Ekin(keV)=" << kinE/CLHEP::keV 
277            << " sigma(cm^2)=" << sigma/CLHEP::    295            << " sigma(cm^2)=" << sigma/CLHEP::cm2 << G4endl;
278   }                                               296   }
279   return sigma;                                   297   return sigma;
280 }                                                 298 }
281                                                   299 
282 //....oooOO0OOooo........oooOO0OOooo........oo    300 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
283                                                   301 
284 void                                              302 void
285 G4DNARuddIonisationExtendedModel::SampleSecond    303 G4DNARuddIonisationExtendedModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
286                                                   304                                                     const G4MaterialCutsCouple* couple,
287                                                   305                                                     const G4DynamicParticle* dpart,
288                                                   306                                                     G4double, G4double)
289 {                                                 307 {
290   const G4ParticleDefinition* pd = dpart->GetD    308   const G4ParticleDefinition* pd = dpart->GetDefinition();
291   if (fParticle != pd) { SetParticle(pd); }       309   if (fParticle != pd) { SetParticle(pd); }
292                                                   310 
293   // stop ion with energy below low energy lim    311   // stop ion with energy below low energy limit
294   G4double kinE = dpart->GetKineticEnergy();      312   G4double kinE = dpart->GetKineticEnergy();
295   // ion shoud be stopped - check on kinetic e    313   // ion shoud be stopped - check on kinetic energy and not scaled energy
296   if (kinE <= fLowestEnergy) {                    314   if (kinE <= fLowestEnergy) {
297     fParticleChangeForGamma->SetProposedKineti    315     fParticleChangeForGamma->SetProposedKineticEnergy(0.);
298     fParticleChangeForGamma->ProposeTrackStatu    316     fParticleChangeForGamma->ProposeTrackStatus(fStopButAlive);
299     fParticleChangeForGamma->ProposeLocalEnerg    317     fParticleChangeForGamma->ProposeLocalEnergyDeposit(kinE);
300     return;                                       318     return;
301   }                                               319   }
302                                                   320 
303   G4int shell = SelectShell(kinE*fMassRate);   << 321   G4int shell = SelectShell(kinE);
304   G4double bindingEnergy = (useDNAWaterStructu    322   G4double bindingEnergy = (useDNAWaterStructure)
305     ? waterStructure.IonisationEnergy(shell) :    323     ? waterStructure.IonisationEnergy(shell) : Bj[shell];
306                                                   324 
307   //Si: additional protection if tcs interpola    325   //Si: additional protection if tcs interpolation method is modified
308   if (kinE < bindingEnergy) { return; }        << 326   if (kinE < bindingEnergy) return;
309                                                << 327 
310   G4double esec = SampleElectronEnergy(kinE, s << 328   G4double esec = SampleElectronEnergy(kinE, bindingEnergy, shell);
311   G4double esum = 0.0;                            329   G4double esum = 0.0;
312                                                   330 
313   // sample deexcitation                          331   // sample deexcitation
314   // here we assume that H2O electronic levels    332   // here we assume that H2O electronic levels are the same as Oxygen.
315   // this can be considered true with a rough     333   // this can be considered true with a rough 10% error in energy on K-shell,
316   G4int Z = 8;                                    334   G4int Z = 8;  
317   G4ThreeVector deltaDir =                        335   G4ThreeVector deltaDir = 
318     GetAngularDistribution()->SampleDirectionF    336     GetAngularDistribution()->SampleDirectionForShell(dpart, esec, Z, shell, couple->GetMaterial());
319                                                   337 
320   // SI: only atomic deexcitation from K shell    338   // SI: only atomic deexcitation from K shell is considered
321   if(fAtomDeexcitation != nullptr && shell ==     339   if(fAtomDeexcitation != nullptr && shell == 4) {
322     auto as = G4AtomicShellEnumerator(0);         340     auto as = G4AtomicShellEnumerator(0);
323     auto ashell = fAtomDeexcitation->GetAtomic    341     auto ashell = fAtomDeexcitation->GetAtomicShell(Z, as);
324     fAtomDeexcitation->GenerateParticles(fvect    342     fAtomDeexcitation->GenerateParticles(fvect, ashell, Z, 0, 0);
325                                                   343 
326     // compute energy sum from de-excitation      344     // compute energy sum from de-excitation
327     for (auto const & ptr : *fvect) {          << 345     std::size_t nn = fvect->size();
328       esum += ptr->GetKineticEnergy();         << 346     for (std::size_t i=0; i<nn; ++i) {
                                                   >> 347       esum += (*fvect)[i]->GetKineticEnergy();
329     }                                             348     }
330   }                                               349   }
331   // check energy balance                         350   // check energy balance
332   // remaining excitation energy of water mole    351   // remaining excitation energy of water molecule
333   G4double exc = bindingEnergy - esum;            352   G4double exc = bindingEnergy - esum;
334                                                   353 
335   // remaining projectile energy                  354   // remaining projectile energy
336   G4double scatteredEnergy = kinE - bindingEne    355   G4double scatteredEnergy = kinE - bindingEnergy - esec;
337   if(scatteredEnergy < -tolerance || exc < -to    356   if(scatteredEnergy < -tolerance || exc < -tolerance) {
338     G4cout << "G4DNARuddIonisationExtendedMode    357     G4cout << "G4DNARuddIonisationExtendedModel::SampleSecondaries: "
339            << "negative final E(keV)=" << scat    358            << "negative final E(keV)=" << scatteredEnergy/CLHEP::keV << " Ein(keV)="
340            << kinE/CLHEP::keV << "  " << pd->G    359            << kinE/CLHEP::keV << "  " << pd->GetParticleName()
341            << " Edelta(keV)=" << esec/CLHEP::k    360            << " Edelta(keV)=" << esec/CLHEP::keV << " MeV, Exc(keV)=" << exc/CLHEP::keV
342      << G4endl;                                   361      << G4endl;
343   }                                               362   }
344                                                   363 
345   // projectile                                   364   // projectile
346   if (!statCode) {                                365   if (!statCode) {
347     fParticleChangeForGamma->SetProposedKineti    366     fParticleChangeForGamma->SetProposedKineticEnergy(scatteredEnergy);
348     fParticleChangeForGamma->ProposeLocalEnerg    367     fParticleChangeForGamma->ProposeLocalEnergyDeposit(exc);
349   } else {                                        368   } else {
350     fParticleChangeForGamma->SetProposedKineti    369     fParticleChangeForGamma->SetProposedKineticEnergy(kinE);
351     fParticleChangeForGamma->ProposeLocalEnerg    370     fParticleChangeForGamma->ProposeLocalEnergyDeposit(kinE - scatteredEnergy);
352   }                                               371   }
353                                                   372 
354   // delta-electron                               373   // delta-electron
355   auto  dp = new G4DynamicParticle(G4Electron:    374   auto  dp = new G4DynamicParticle(G4Electron::Electron(), deltaDir, esec);
356   fvect->push_back(dp);                           375   fvect->push_back(dp);
357                                                   376 
358   // create radical                               377   // create radical
359   const G4Track* theIncomingTrack = fParticleC    378   const G4Track* theIncomingTrack = fParticleChangeForGamma->GetCurrentTrack();
360   G4DNAChemistryManager::Instance()->CreateWat    379   G4DNAChemistryManager::Instance()->CreateWaterMolecule(eIonizedMolecule, shell,
361                theIncomingTrack);                 380                theIncomingTrack);
362 }                                                 381 }
363                                                   382 
364 //....oooOO0OOooo........oooOO0OOooo........oo    383 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
365                                                   384 
366 G4int G4DNARuddIonisationExtendedModel::Select    385 G4int G4DNARuddIonisationExtendedModel::SelectShell(G4double e)
367 {                                                 386 {
368   G4double sum = 0.0;                             387   G4double sum = 0.0;
369   G4double xs;                                    388   G4double xs;
370   for (G4int i=0; i<5; ++i) {                  << 389   for(G4int i=0; i<5; ++i) {
371     auto ptr = xscurrent->GetComponent(i);     << 390     if (idx == 0 || idx == 1) {
372     xs = (e > fElow) ? ptr->FindValue(e) : ptr << 391       auto ptr = xscurrent->GetComponent(i);
                                                   >> 392       xs = (e > fElow) ? ptr->FindValue(e) : ptr->FindValue(fElow)*e/fElow;
                                                   >> 393 
                                                   >> 394     } else if (idx > 1) {
                                                   >> 395       auto ptr = xsdata[idx]->GetComponent(i);
                                                   >> 396       xs = (e > fElow) ? ptr->FindValue(e) : ptr->FindValue(fElow)*e/fElow;
                                                   >> 397 
                                                   >> 398     } else {
                                                   >> 399       // use scaling from proton
                                                   >> 400       auto ptr = xsdata[1]->GetComponent(i);
                                                   >> 401       G4double x = e*fMassRate;
                                                   >> 402       xs = (x >= fLowestEnergy) ? ptr->FindValue(x) 
                                                   >> 403   : ptr->FindValue(fLowestEnergy)*x/fLowestEnergy;
                                                   >> 404     }
373     sum += xs;                                    405     sum += xs;
374     fTemp[i] = sum;                               406     fTemp[i] = sum;
375   }                                               407   }
376   sum *= G4UniformRand();                         408   sum *= G4UniformRand();
377   for (G4int i=0; i<5; ++i) {                  << 409   for(G4int i=0; i<5; ++i) {
378     if (sum <= fTemp[i]) { return i; }         << 410     if(sum <= fTemp[i]) { return i; }
379   }                                               411   }
380   return 0;                                       412   return 0;
381 }                                                 413 }
382                                                   414 
383 //....oooOO0OOooo........oooOO0OOooo........oo    415 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
384                                                   416 
385 G4double G4DNARuddIonisationExtendedModel::Max << 417 G4double G4DNARuddIonisationExtendedModel::SampleElectronEnergy(G4double kine,
                                                   >> 418                                                                 G4double eexc,
                                                   >> 419                                                                 G4int shell)
386 {                                                 420 {
387   // kinematic limit                              421   // kinematic limit
388   G4double tau = kine/fMass;                      422   G4double tau = kine/fMass;
389   G4double gam = 1.0 + tau;                    << 
390   G4double emax = 2.0*CLHEP::electron_mass_c2*    423   G4double emax = 2.0*CLHEP::electron_mass_c2*tau*(tau + 2.0);
391                                                << 
392   // Initialisation of sampling                << 
393   G4double A1, B1, C1, D1, E1, A2, B2, C2, D2; << 
394   if (shell == 4) {                            << 
395     //Data For Liquid Water K SHELL from Dingf << 
396     A1 = 1.25;                                 << 
397     B1 = 0.5;                                  << 
398     C1 = 1.00;                                 << 
399     D1 = 1.00;                                 << 
400     E1 = 3.00;                                 << 
401     A2 = 1.10;                                 << 
402     B2 = 1.30;                                 << 
403     C2 = 1.00;                                 << 
404     D2 = 0.00;                                 << 
405     alphaConst = 0.66;                         << 
406   } else {                                     << 
407     //Data For Liquid Water from Dingfelder (P << 
408     A1 = 1.02;                                 << 
409     B1 = 82.0;                                 << 
410     C1 = 0.45;                                 << 
411     D1 = -0.80;                                << 
412     E1 = 0.38;                                 << 
413     A2 = 1.07;                                 << 
414     // Value provided by M. Dingfelder (priv.  << 
415     B2 = 11.6;                                 << 
416     C2 = 0.60;                                 << 
417     D2 = 0.04;                                 << 
418     alphaConst = 0.64;                         << 
419   }                                            << 
420   bEnergy = Bj[shell];                         << 
421   G4double v2 = 0.25*emax/(bEnergy*gam*gam);   << 
422   v = std::sqrt(v2);                           << 
423   u = Ry/bEnergy;                              << 
424   wc = 4.*v2 - 2.*v - 0.25*u;                  << 
425                                                << 
426   G4double L1 = (C1 * fGpow->powA(v, D1)) / (1 << 
427   G4double L2 = C2 * fGpow->powA(v, D2);       << 
428   G4double H1 = (A1 * G4Log(1. + v2)) / (v2 +  << 
429   G4double H2 = (A2 / v2) + (B2 / (v2 * v2));  << 
430                                                << 
431   F1 = L1 + H1;                                << 
432   F2 = (L2 * H2) / (L2 + H2);                  << 
433   return emax;                                 << 
434 }                                              << 
435                                                << 
436 //....oooOO0OOooo........oooOO0OOooo........oo << 
437                                                << 
438 G4double G4DNARuddIonisationExtendedModel::Sam << 
439                                                << 
440 {                                              << 
441   G4double emax = MaxEnergy(kine, shell);      << 
442   // compute cumulative probability function      424   // compute cumulative probability function
443   G4double step = 1*CLHEP::eV;                    425   G4double step = 1*CLHEP::eV;
444   auto nn = (G4int)(emax/step);                << 426   auto  nn = (G4int)(emax/step);
445   nn = std::min(std::max(nn, 10), 100);        << 427   nn = std::max(nn, 10);
446   step = emax/(G4double)nn;                       428   step = emax/(G4double)nn;
447                                                   429 
448   // find max probability                         430   // find max probability
449   G4double pmax = ProbabilityFunction(kine, 0. << 431   G4double pmax = ProbabilityFunction(kine, 0.0, eexc, shell);
450   //G4cout << "## E(keV)=" << kine/keV << " em << 432   //G4cout << "E(keV)=" << kine/keV << " emax=" << emax/keV
451   //       << " pmax(0)=" << pmax << " shell="    433   //       << " pmax(0)=" << pmax << " shell=" << shell << " nn=" << nn << G4endl;
452                                                   434 
                                                   >> 435   G4double e2 = 0.0; // backup energy
453   G4double e0 = 0.0; // energy with max probab    436   G4double e0 = 0.0; // energy with max probability
454   // 2 areas after point with max probability  << 
455   G4double e1 = emax;                          << 
456   G4double e2 = emax;                          << 
457   G4double p1 = 0.0;                           << 
458   G4double p2 = 0.0;                           << 
459   const G4double f = 0.25;                     << 
460                                                << 
461   // find max probability                      << 
462   G4double e = 0.0;                               437   G4double e = 0.0;
463   G4double p = 0.0;                            << 
464   for (G4int i=0; i<nn; ++i) {                    438   for (G4int i=0; i<nn; ++i) {
465     e += step;                                    439     e += step;
466     p = ProbabilityFunction(kine, e, shell);   << 440     G4double prob = ProbabilityFunction(kine, e, eexc, shell);
467     if (p > pmax) {                            << 441     if (prob < pmax) {
468       pmax = p;                                << 442       e2 = 2*e;
469       e0 = e;                                  << 
470     } else {                                   << 
471       break;                                      443       break;
472     }                                             444     }
                                                   >> 445     pmax = prob;
                                                   >> 446     e0 = e;
473   }                                               447   }
474   // increase step to be more effective        << 448   //G4cout << "         E0(keV)=" << e0/keV << " pmax=" << pmax << G4endl;
475   step *= 2.0;                                 << 
476   // 2-nd area                                 << 
477   for (G4int i=0; i<nn; ++i) {                 << 
478     e += step;                                 << 
479     if (std::abs(e - emax) < step) {           << 
480       e1 = emax;                               << 
481       break;                                   << 
482     }                                          << 
483     p = ProbabilityFunction(kine, e, shell);   << 
484     if (p < f*pmax) {                          << 
485       p1 = p;                                  << 
486       e1 = e;                                  << 
487       break;                                   << 
488     }                                          << 
489   }                                            << 
490   // 3-d area                                  << 
491   if (e < emax) {                              << 
492     for (G4int i=0; i<nn; ++i) {               << 
493       e += step;                               << 
494       if (std::abs(e - emax) < step) {         << 
495         e2 = emax;                             << 
496   break;                                       << 
497       }                                        << 
498       p = ProbabilityFunction(kine, e, shell); << 
499       if (p < f*p1) {                          << 
500   p2 = p;                                      << 
501   e2 = e;                                      << 
502         break;                                 << 
503       }                                        << 
504     }                                          << 
505   }                                            << 
506   pmax *= 1.05;                                   449   pmax *= 1.05;
507   // regression method with 3 regions          << 450   // regression method with two regions
508   G4double s0 = pmax*e1;                       << 451   G4double e1 = emax;
509   G4double s1 = s0 + p1 * (e2 - e1);           << 452   G4double p1 = 0.0;
510   G4double s2 = s1 + p2 * (emax - e2);         << 453   if (2*e0 < emax) {
511   s0 = (s0 == s1) ? 1.0 : s0 / s2;             << 454     e1 = e0 + 0.25*(emax - e0);
512   s1 = (s1 == s2) ? 1.0 : s1 / s2;             << 455     p1 = ProbabilityFunction(kine, e1, eexc, shell);
513                                                << 456   }
514   //G4cout << "pmax=" << pmax << " e1(keV)=" < << 457   G4double s2 = p1*(emax - e1);
515   //   << " p2=" << p2 << " s0=" << s0 << " s1 << 458   s2 /= (s2 + e1*pmax);
                                                   >> 459   G4double s1 = 1.0 - s2;
516                                                   460 
517   // sampling                                     461   // sampling
518   G4int count = 0;                                462   G4int count = 0;
519   G4double ymax, y, deltae;                       463   G4double ymax, y, deltae;
520   for (G4int i = 0; i<100000; ++i) {              464   for (G4int i = 0; i<100000; ++i) {
521     G4double q = G4UniformRand();                 465     G4double q = G4UniformRand();
522     if (q <= s0) {                             << 466     if (q <= s1) {
523       ymax = pmax;                                467       ymax = pmax;
524       deltae = e1 * q / s0;                    << 468       deltae = e1 * q / s1;
525     } else if (q <= s1) {                      << 
526       ymax = p1;                               << 
527       deltae = e1 + (e2 - e1) * (q - s0) / (s1 << 
528     } else {                                      469     } else {
529       ymax = p2;                               << 470       ymax = p1;
530       deltae = e2 + (emax - e2) * (q - s1) / ( << 471       deltae = e1 + (emax - e1)* (q - s1) / s2;
531     }                                             472     }
532     y = ProbabilityFunction(kine, deltae, shel << 473     y = ProbabilityFunction(kine, deltae, eexc, shell);
533     //G4cout << "    " << i << ".  deltae=" <<    474     //G4cout << "    " << i << ".  deltae=" << deltae/CLHEP::keV 
534     //       << " y=" << y << " ymax=" << ymax << 475     // << " y=" << y << " ymax=" << ymax << G4endl; 
535     if (y > ymax && count < 10) {                 476     if (y > ymax && count < 10) {
536       ++count;                                    477       ++count;
537       G4cout << "G4DNARuddIonisationExtendedMo    478       G4cout << "G4DNARuddIonisationExtendedModel::SampleElectronEnergy warning: "
538        << fParticle->GetParticleName() << " E(    479        << fParticle->GetParticleName() << " E(keV)=" << kine/CLHEP::keV
539        << " Edelta(keV)=" << deltae/CLHEP::keV    480        << " Edelta(keV)=" << deltae/CLHEP::keV 
540        << " y=" << y << " ymax=" << ymax << "     481        << " y=" << y << " ymax=" << ymax << " n=" << i << G4endl; 
541     }                                             482     }
542     if (ymax * G4UniformRand() <= y) {         << 483     if (ymax * G4UniformRand() < y) {
543       return deltae;                              484       return deltae;
544     }                                             485     }
545   }                                               486   }
546   deltae = std::min(e0 + step, 0.5*emax);      << 487   deltae = e2;
547   return deltae;                                  488   return deltae;
548 }                                                 489 }
549                                                   490 
550 //....oooOO0OOooo........oooOO0OOooo........oo    491 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
551                                                   492 
552 G4double G4DNARuddIonisationExtendedModel::Pro    493 G4double G4DNARuddIonisationExtendedModel::ProbabilityFunction(G4double kine,
553                                                   494                                                                G4double deltae,
                                                   >> 495                                                                G4double bindingEnergy,
554                                                   496                                                                G4int shell)
555 {                                                 497 {
556   // Shells ids are 0 1 2 3 4 (4 is k shell)      498   // Shells ids are 0 1 2 3 4 (4 is k shell)
557   // !!Attention, "energyTransfer" here is the    499   // !!Attention, "energyTransfer" here is the energy transfered to the electron which means
558   //             that the secondary kinetic en    500   //             that the secondary kinetic energy is w = energyTransfer - bindingEnergy
559   //                                              501   //
560   //   ds            S                F1(nu) +    502   //   ds            S                F1(nu) + w * F2(nu)
561   //  ---- = G(k) * ----     -----------------    503   //  ---- = G(k) * ----     -------------------------------------------
562   //   dw            Bj       (1+w)^3 * [1 + e    504   //   dw            Bj       (1+w)^3 * [1 + exp{alpha * (w - wc) / nu}]
563   //                                              505   //
564   // w is the secondary electron kinetic Energ    506   // w is the secondary electron kinetic Energy in eV
565   //                                              507   //
566   // All the other parameters can be found in     508   // All the other parameters can be found in Rudd's Papers
567   //                                              509   //
568   // M.Eugene Rudd, 1988, User-Friendly model     510   // M.Eugene Rudd, 1988, User-Friendly model for the energy distribution of
569   // electrons from protons or electron collis    511   // electrons from protons or electron collisions. Nucl. Tracks Rad. Meas.Vol 16 N0 2/3 pp 219-218
570   //                                              512   //
                                                   >> 513   G4double A1, B1, C1, D1, E1, A2, B2, C2, D2, alphaConst;
                                                   >> 514   if (shell == 4) {
                                                   >> 515     //Data For Liquid Water K SHELL from Dingfelder (Protons in Water)
                                                   >> 516     A1 = 1.25;
                                                   >> 517     B1 = 0.5;
                                                   >> 518     C1 = 1.00;
                                                   >> 519     D1 = 1.00;
                                                   >> 520     E1 = 3.00;
                                                   >> 521     A2 = 1.10;
                                                   >> 522     B2 = 1.30;
                                                   >> 523     C2 = 1.00;
                                                   >> 524     D2 = 0.00;
                                                   >> 525     alphaConst = 0.66;
                                                   >> 526   } else {
                                                   >> 527     //Data For Liquid Water from Dingfelder (Protons in Water)
                                                   >> 528     A1 = 1.02;
                                                   >> 529     B1 = 82.0;
                                                   >> 530     C1 = 0.45;
                                                   >> 531     D1 = -0.80;
                                                   >> 532     E1 = 0.38;
                                                   >> 533     A2 = 1.07;
                                                   >> 534     // Value provided by M. Dingfelder (priv. comm)
                                                   >> 535     B2 = 11.6;
                                                   >> 536     C2 = 0.60;
                                                   >> 537     D2 = 0.04;
                                                   >> 538     alphaConst = 0.64;
                                                   >> 539   }
                                                   >> 540   G4double bEnergy = Bj[shell];
571   G4double w = deltae/bEnergy;                    541   G4double w = deltae/bEnergy;
                                                   >> 542   G4double u = Ry/bEnergy;
                                                   >> 543   G4double tau = kine/fMass;
                                                   >> 544   G4double gam = 1.0 + tau;;
                                                   >> 545 
                                                   >> 546   G4double v2 = 0.5*CLHEP::electron_mass_c2*tau*(tau + 2.0)/(bEnergy*gam*gam);
                                                   >> 547   G4double v = std::sqrt(v2);
                                                   >> 548   G4double wc = 4.*v2 - 2.*v - 0.25*u;
                                                   >> 549 
572   G4double x = alphaConst*(w - wc)/v;             550   G4double x = alphaConst*(w - wc)/v;
573   G4double y = (x > -15.) ? 1.0 + G4Exp(x) : 1    551   G4double y = (x > -15.) ? 1.0 + G4Exp(x) : 1.0;
574                                                   552 
575   G4double res = CorrectionFactor(kine, shell) << 553   G4double L1 = (C1 * fGpow->powA(v, D1)) / (1. + E1 * fGpow->powA(v, (D1 + 4.)));
                                                   >> 554   G4double L2 = C2 * fGpow->powA(v, D2);
                                                   >> 555   G4double H1 = (A1 * G4Log(1. + v2)) / (v2 + (B1 / v2));
                                                   >> 556   G4double H2 = (A2 / v2) + (B2 / (v2 * v2));
                                                   >> 557 
                                                   >> 558   G4double F1 = L1 + H1;
                                                   >> 559   G4double F2 = (L2 * H2) / (L2 + H2);
                                                   >> 560 
                                                   >> 561   G4double res = CorrectionFactor(kine, shell) * (F1 + w*F2) * Gj[shell] /
576     (fGpow->powN((1. + w)/u, 3) * y);             562     (fGpow->powN((1. + w)/u, 3) * y);
577                                                   563 
578   if (isHelium) {                              << 564   if(isHelium) {
579     G4double energyTransfer = deltae + bEnergy << 565     G4double energyTransfer = deltae + bindingEnergy;
580     G4double Zeff = 2.0 -                         566     G4double Zeff = 2.0 -
581       (sCoefficient[0] * S_1s(kine, energyTran    567       (sCoefficient[0] * S_1s(kine, energyTransfer, slaterEffectiveCharge[0], 1.) +
582        sCoefficient[1] * S_2s(kine, energyTran    568        sCoefficient[1] * S_2s(kine, energyTransfer, slaterEffectiveCharge[1], 2.) +
583        sCoefficient[2] * S_2p(kine, energyTran    569        sCoefficient[2] * S_2p(kine, energyTransfer, slaterEffectiveCharge[2], 2.) );
584                                                   570 
585     res *= Zeff * Zeff;                           571     res *= Zeff * Zeff;
586   }                                               572   }
587   return std::max(res, 0.0);                      573   return std::max(res, 0.0);
588 }                                                 574 }
589                                                   575 
590 //....oooOO0OOooo........oooOO0OOooo........oo    576 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
591                                                   577 
592 G4double G4DNARuddIonisationExtendedModel::Com    578 G4double G4DNARuddIonisationExtendedModel::ComputeProbabilityFunction(
593          const G4ParticleDefinition* p, G4doub    579          const G4ParticleDefinition* p, G4double e, G4double deltae, G4int shell)
594 {                                                 580 {
595   if (fParticle != p) { SetParticle(p); }         581   if (fParticle != p) { SetParticle(p); }
596   MaxEnergy(e, shell);                         << 582   G4double bEnergy = (useDNAWaterStructure)
597   return ProbabilityFunction(e, deltae, shell) << 583     ? waterStructure.IonisationEnergy(shell) : Bj[shell];
                                                   >> 584   return ProbabilityFunction(e, deltae, bEnergy, shell);
598 }                                                 585 }
599                                                   586 
600 //....oooOO0OOooo........oooOO0OOooo........oo    587 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
601                                                   588 
602 G4double G4DNARuddIonisationExtendedModel::S_1    589 G4double G4DNARuddIonisationExtendedModel::S_1s(G4double kine,
603                                                   590                                                 G4double energyTransfer,
604                                                   591                                                 G4double slaterEffCharge,
605                                                   592                                                 G4double shellNumber)
606 {                                                 593 {
607   // 1 - e^(-2r) * ( 1 + 2 r + 2 r^2)             594   // 1 - e^(-2r) * ( 1 + 2 r + 2 r^2)
608   // Dingfelder, in Chattanooga 2005 proceedin    595   // Dingfelder, in Chattanooga 2005 proceedings, formula (7)
609                                                   596 
610   G4double r = Rh(kine, energyTransfer, slater    597   G4double r = Rh(kine, energyTransfer, slaterEffCharge, shellNumber);
611   G4double value = 1. - G4Exp(-2 * r) * ( ( 2.    598   G4double value = 1. - G4Exp(-2 * r) * ( ( 2. * r + 2. ) * r + 1. );
612   return value;                                   599   return value;
613 }                                                 600 }
614                                                   601 
615 //....oooOO0OOooo........oooOO0OOooo........oo    602 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
616                                                   603 
617 G4double G4DNARuddIonisationExtendedModel::S_2    604 G4double G4DNARuddIonisationExtendedModel::S_2s(G4double kine,
618                                                   605                                                 G4double energyTransfer,
619                                                   606                                                 G4double slaterEffCharge,
620                                                   607                                                 G4double shellNumber)
621 {                                                 608 {
622   // 1 - e^(-2 r) * ( 1 + 2 r + 2 r^2 + 2 r^4)    609   // 1 - e^(-2 r) * ( 1 + 2 r + 2 r^2 + 2 r^4)
623   // Dingfelder, in Chattanooga 2005 proceedin    610   // Dingfelder, in Chattanooga 2005 proceedings, formula (8)
624                                                   611 
625   G4double r = Rh(kine, energyTransfer, slater    612   G4double r = Rh(kine, energyTransfer, slaterEffCharge, shellNumber);
626   G4double value =                                613   G4double value =
627     1. - G4Exp(-2 * r) * (((2. * r * r + 2.) *    614     1. - G4Exp(-2 * r) * (((2. * r * r + 2.) * r + 2.) * r + 1.);
628                                                   615 
629   return value;                                   616   return value;
630 }                                                 617 }
631                                                   618 
632 //....oooOO0OOooo........oooOO0OOooo........oo    619 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
633                                                   620 
634 G4double G4DNARuddIonisationExtendedModel::S_2    621 G4double G4DNARuddIonisationExtendedModel::S_2p(G4double kine, 
635                                                   622                                                 G4double energyTransfer,
636                                                   623                                                 G4double slaterEffCharge,
637                                                   624                                                 G4double shellNumber)
638 {                                                 625 {
639   // 1 - e^(-2 r) * ( 1 + 2 r + 2 r^2 + 4/3 r^    626   // 1 - e^(-2 r) * ( 1 + 2 r + 2 r^2 + 4/3 r^3 + 2/3 r^4)
640   // Dingfelder, in Chattanooga 2005 proceedin    627   // Dingfelder, in Chattanooga 2005 proceedings, formula (9)
641                                                   628 
642   G4double r = Rh(kine, energyTransfer, slater    629   G4double r = Rh(kine, energyTransfer, slaterEffCharge, shellNumber);
643   G4double value =                                630   G4double value =
644     1. - G4Exp(-2 * r) * (((( 2./3. * r + 4./3    631     1. - G4Exp(-2 * r) * (((( 2./3. * r + 4./3.) * r + 2.) * r + 2.) * r  + 1.);
645                                                   632 
646   return value;                                   633   return value;
647 }                                                 634 }
648                                                   635 
649 //....oooOO0OOooo........oooOO0OOooo........oo    636 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
650                                                   637 
651 G4double G4DNARuddIonisationExtendedModel::Rh(    638 G4double G4DNARuddIonisationExtendedModel::Rh(G4double ekin, G4double etrans,
652                                                   639                                               G4double q, G4double shell)
653 {                                                 640 {
654   // The following values are provided by M. D    641   // The following values are provided by M. Dingfelder (priv. comm)
655   // Dingfelder, in Chattanooga 2005 proceedin    642   // Dingfelder, in Chattanooga 2005 proceedings, p 4
656                                                   643 
657   G4double escaled = CLHEP::electron_mass_c2/f    644   G4double escaled = CLHEP::electron_mass_c2/fMass * ekin;
658   const G4double H = 13.60569172 * CLHEP::eV;     645   const G4double H = 13.60569172 * CLHEP::eV;
659   G4double value = 2.0*std::sqrt(escaled / H)*    646   G4double value = 2.0*std::sqrt(escaled / H)*q*H /(etrans*shell);
660                                                   647 
661   return value;                                   648   return value;
662 }                                                 649 }
663                                                   650 
664 //....oooOO0OOooo........oooOO0OOooo........oo    651 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
665                                                   652 
666 G4double                                          653 G4double 
667 G4DNARuddIonisationExtendedModel::CorrectionFa    654 G4DNARuddIonisationExtendedModel::CorrectionFactor(G4double kine, G4int shell) 
668 {                                                 655 {
669   // ZF Shortened                                 656   // ZF Shortened
670   G4double res = 1.0;                             657   G4double res = 1.0;
671   if (shell < 4 && 0 != idx) {                    658   if (shell < 4 && 0 != idx) {
672     const G4double ln10 = fGpow->logZ(10);        659     const G4double ln10 = fGpow->logZ(10);
673     G4double x = 2.0*((G4Log(kine/CLHEP::eV)/l    660     G4double x = 2.0*((G4Log(kine/CLHEP::eV)/ln10) - 4.2);
674     // The following values are provided by M.    661     // The following values are provided by M. Dingfelder (priv. comm)
675     res = 0.6/(1.0 + G4Exp(x)) + 0.9;             662     res = 0.6/(1.0 + G4Exp(x)) + 0.9;
676   }                                               663   }
677   return res;                                     664   return res;
678 }                                                 665 }
679                                                   666 
680 //....oooOO0OOooo........oooOO0OOooo........oo    667 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
681                                                   668