Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/lowenergy/src/G4PenelopePhotoElectricModel.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/lowenergy/src/G4PenelopePhotoElectricModel.cc (Version 11.3.0) and /processes/electromagnetic/lowenergy/src/G4PenelopePhotoElectricModel.cc (Version 9.2.p1)


  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 // $Id: G4PenelopePhotoElectricModel.cc,v 1.2.2.1 2009/03/05 08:50:19 gcosmo Exp $
                                                   >>  27 // GEANT4 tag $Name: geant4-09-02-patch-01 $
 26 //                                                 28 //
 27 // Author: Luciano Pandola                         29 // Author: Luciano Pandola
 28 //                                                 30 //
 29 // History:                                        31 // History:
 30 // --------                                        32 // --------
 31 // 08 Jan 2010   L Pandola  First implementati <<  33 // 08 Oct 2008   L Pandola  Migration from process to model 
 32 // 01 Feb 2011   L Pandola  Suppress fake ener <<  34 // 08 Jan 2009  L. Pandola  Check shell index to avoid mismatch between 
 33 //                          is active.         <<  35 //                          the Penelope cross section database and the 
 34 //                          Make sure that flu <<  36 //                          G4AtomicTransitionManager database. It suppresses 
 35 //                          only if above thre <<  37 //                          a warning from G4AtomicTransitionManager only. 
 36 // 25 May 2011   L Pandola  Renamed (make v200 <<  38 //                          Results are unchanged.
 37 // 10 Jun 2011   L Pandola  Migrate atomic dee << 
 38 // 07 Oct 2011   L Pandola  Bug fix (potential << 
 39 // 27 Sep 2013   L Pandola  Migrate to MT para << 
 40 //                          tables.            << 
 41 // 02 Oct 2013   L Pandola  Rewrite sampling a << 
 42 //                          to improve CPU per << 
 43 //                                                 39 //
 44                                                    40 
 45 #include "G4PenelopePhotoElectricModel.hh"         41 #include "G4PenelopePhotoElectricModel.hh"
 46 #include "G4PhysicalConstants.hh"              << 
 47 #include "G4SystemOfUnits.hh"                  << 
 48 #include "G4ParticleDefinition.hh"                 42 #include "G4ParticleDefinition.hh"
 49 #include "G4MaterialCutsCouple.hh"                 43 #include "G4MaterialCutsCouple.hh"
                                                   >>  44 #include "G4ProductionCutsTable.hh"
 50 #include "G4DynamicParticle.hh"                    45 #include "G4DynamicParticle.hh"
 51 #include "G4PhysicsTable.hh"                       46 #include "G4PhysicsTable.hh"
 52 #include "G4PhysicsFreeVector.hh"              << 
 53 #include "G4ElementTable.hh"                       47 #include "G4ElementTable.hh"
 54 #include "G4Element.hh"                            48 #include "G4Element.hh"
                                                   >>  49 #include "G4CrossSectionHandler.hh"
 55 #include "G4AtomicTransitionManager.hh"            50 #include "G4AtomicTransitionManager.hh"
 56 #include "G4AtomicShell.hh"                        51 #include "G4AtomicShell.hh"
 57 #include "G4Gamma.hh"                              52 #include "G4Gamma.hh"
 58 #include "G4Electron.hh"                           53 #include "G4Electron.hh"
 59 #include "G4AutoLock.hh"                       << 
 60 #include "G4LossTableManager.hh"               << 
 61 #include "G4Exp.hh"                            << 
 62                                                    54 
 63 //....oooOO0OOooo........oooOO0OOooo........oo     55 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 64                                                    56 
 65 const G4int G4PenelopePhotoElectricModel::fMax << 
 66 G4PhysicsTable* G4PenelopePhotoElectricModel:: << 
 67                                                    57 
 68 //....oooOO0OOooo........oooOO0OOooo........oo <<  58 G4PenelopePhotoElectricModel::G4PenelopePhotoElectricModel(const G4ParticleDefinition*,
 69                                                <<  59                                              const G4String& nam)
 70 G4PenelopePhotoElectricModel::G4PenelopePhotoE <<  60   :G4VEmModel(nam),isInitialised(false),crossSectionHandler(0),
 71                  const G4String& nam)          <<  61    shellCrossSectionHandler(0)
 72   :G4VEmModel(nam),fParticleChange(nullptr),fP << 
 73    fAtomDeexcitation(nullptr),fIsInitialised(f << 
 74 {                                                  62 {
 75   fIntrinsicLowEnergyLimit = 100.0*eV;             63   fIntrinsicLowEnergyLimit = 100.0*eV;
 76   fIntrinsicHighEnergyLimit = 100.0*GeV;           64   fIntrinsicHighEnergyLimit = 100.0*GeV;
 77   //  SetLowEnergyLimit(fIntrinsicLowEnergyLim <<  65   SetLowEnergyLimit(fIntrinsicLowEnergyLimit);
 78   SetHighEnergyLimit(fIntrinsicHighEnergyLimit     66   SetHighEnergyLimit(fIntrinsicHighEnergyLimit);
 79   //                                               67   //
 80                                                <<  68   fUseAtomicDeexcitation = true;
 81   if (part)                                    <<  69   verboseLevel= 0;
 82     SetParticle(part);                         << 
 83                                                << 
 84   fVerboseLevel= 0;                            << 
 85   // Verbosity scale:                              70   // Verbosity scale:
 86   // 0 = nothing                               <<  71   // 0 = nothing 
 87   // 1 = warning for energy non-conservation   <<  72   // 1 = warning for energy non-conservation 
 88   // 2 = details of energy budget                  73   // 2 = details of energy budget
 89   // 3 = calculation of cross sections, file o     74   // 3 = calculation of cross sections, file openings, sampling of atoms
 90   // 4 = entering in methods                       75   // 4 = entering in methods
 91                                                << 
 92   //Mark this model as "applicable" for atomic << 
 93   SetDeexcitationFlag(true);                   << 
 94                                                << 
 95   fTransitionManager = G4AtomicTransitionManag << 
 96 }                                                  76 }
 97                                                    77 
 98 //....oooOO0OOooo........oooOO0OOooo........oo     78 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
 99                                                    79 
100 G4PenelopePhotoElectricModel::~G4PenelopePhoto     80 G4PenelopePhotoElectricModel::~G4PenelopePhotoElectricModel()
101 {                                              <<  81 {  
102   if (IsMaster() || fLocalTable)               <<  82   if (crossSectionHandler) delete crossSectionHandler;
103     {                                          <<  83   if (shellCrossSectionHandler) delete shellCrossSectionHandler;
104       for(G4int i=0; i<=fMaxZ; ++i)            << 
105   {                                            << 
106     if(fLogAtomicShellXS[i]) {                 << 
107       fLogAtomicShellXS[i]->clearAndDestroy(); << 
108       delete fLogAtomicShellXS[i];             << 
109       fLogAtomicShellXS[i] = nullptr;          << 
110     }                                          << 
111   }                                            << 
112     }                                          << 
113 }                                                  84 }
114                                                    85 
115 //....oooOO0OOooo........oooOO0OOooo........oo     86 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
116                                                    87 
117 void G4PenelopePhotoElectricModel::Initialise( <<  88 void G4PenelopePhotoElectricModel::Initialise(const G4ParticleDefinition*,
118                 const G4DataVector& cuts)      <<  89                                        const G4DataVector& )
119 {                                                  90 {
120   if (fVerboseLevel > 3)                       <<  91   if (verboseLevel > 3)
121     G4cout << "Calling  G4PenelopePhotoElectri     92     G4cout << "Calling  G4PenelopePhotoElectricModel::Initialise()" << G4endl;
122                                                <<  93   if (crossSectionHandler)
123   fAtomDeexcitation = G4LossTableManager::Inst << 
124   //Issue warning if the AtomicDeexcitation ha << 
125   if (!fAtomDeexcitation)                      << 
126     {                                              94     {
127       G4cout << G4endl;                        <<  95       crossSectionHandler->Clear();
128       G4cout << "WARNING from G4PenelopePhotoE <<  96       delete crossSectionHandler;
129       G4cout << "Atomic de-excitation module i << 
130       G4cout << "any fluorescence/Auger emissi << 
131       G4cout << "Please make sure this is inte << 
132     }                                              97     }
133                                                <<  98   if (shellCrossSectionHandler)
134   SetParticle(particle);                       << 
135                                                << 
136   //Only the master model creates/fills/destro << 
137   if (IsMaster() && particle == fParticle)     << 
138     {                                              99     {
139       G4ProductionCutsTable* theCoupleTable =  << 100       shellCrossSectionHandler->Clear();
140   G4ProductionCutsTable::GetProductionCutsTabl << 101       delete shellCrossSectionHandler;
141                                                << 102     }
142       for (G4int i=0;i<(G4int)theCoupleTable-> << 
143   {                                            << 
144     const G4Material* material =               << 
145       theCoupleTable->GetMaterialCutsCouple(i) << 
146     const G4ElementVector* theElementVector =  << 
147                                                << 
148     for (std::size_t j=0;j<material->GetNumber << 
149       {                                        << 
150         G4int iZ = theElementVector->at(j)->Ge << 
151         //read data files only in the master   << 
152         if (!fLogAtomicShellXS[iZ])            << 
153     ReadDataFile(iZ);                          << 
154       }                                        << 
155   }                                            << 
156                                                << 
157       InitialiseElementSelectors(particle,cuts << 
158                                                   103 
159       if (fVerboseLevel > 0) {                 << 104   //Check energy limits
160   G4cout << "Penelope Photo-Electric model v20 << 105   if (LowEnergyLimit() < fIntrinsicLowEnergyLimit)
161          << "Energy range: "                   << 106     {
162          << LowEnergyLimit() / MeV << " MeV -  << 107       G4cout << "G4PenelopePhotoElectricModel: low energy limit increased from " <<
163          << HighEnergyLimit() / GeV << " GeV"; << 108         LowEnergyLimit()/eV << " eV to " << fIntrinsicLowEnergyLimit/eV << " eV" << 
164       }                                        << 109   G4endl;
                                                   >> 110       SetLowEnergyLimit(fIntrinsicLowEnergyLimit);
                                                   >> 111     }
                                                   >> 112   if (HighEnergyLimit() > fIntrinsicHighEnergyLimit)
                                                   >> 113     {
                                                   >> 114       G4cout << "G4PenelopePhotoElectricModel: high energy limit decreased from " <<
                                                   >> 115         HighEnergyLimit()/GeV << " GeV to " << fIntrinsicHighEnergyLimit/GeV << " GeV" 
                                                   >> 116        << G4endl;
                                                   >> 117       SetHighEnergyLimit(fIntrinsicHighEnergyLimit);
165     }                                             118     }
166                                                   119 
167   if(fIsInitialised) return;                   << 
168   fParticleChange = GetParticleChangeForGamma( << 
169   fIsInitialised = true;                       << 
170                                                   120 
171 }                                              << 121   //Re-initialize cross section handlers
                                                   >> 122   crossSectionHandler = new G4CrossSectionHandler();
                                                   >> 123   crossSectionHandler->Clear();
                                                   >> 124   G4String crossSectionFile = "penelope/ph-cs-pen-";
                                                   >> 125   crossSectionHandler->LoadData(crossSectionFile);
                                                   >> 126   shellCrossSectionHandler = new G4CrossSectionHandler();
                                                   >> 127   shellCrossSectionHandler->Clear();
                                                   >> 128   crossSectionFile = "penelope/ph-ss-cs-pen-";
                                                   >> 129   shellCrossSectionHandler->LoadShellData(crossSectionFile);
                                                   >> 130   //This is used to retrieve cross section values later on
                                                   >> 131   crossSectionHandler->BuildMeanFreePathForMaterials();
172                                                   132 
173 void G4PenelopePhotoElectricModel::InitialiseL << 133   if (verboseLevel > 2) 
174                  G4VEmModel *masterModel)      << 134     G4cout << "Loaded cross section files for PenelopePhotoElectric" << G4endl;
175 {                                              << 
176   if (fVerboseLevel > 3)                       << 
177     G4cout << "Calling  G4PenelopePhotoElectri << 
178   //                                           << 
179   //Check that particle matches: one might hav << 
180   //for e+ and e-).                            << 
181   //                                           << 
182   if (part == fParticle)                       << 
183     {                                          << 
184       SetElementSelectors(masterModel->GetElem << 
185                                                   135 
186       //Get the const table pointers from the  << 136   G4cout << "Penelope Photo-Electric model is initialized " << G4endl
187       const G4PenelopePhotoElectricModel* theM << 137          << "Energy range: "
188   static_cast<G4PenelopePhotoElectricModel*> ( << 138          << LowEnergyLimit() / MeV << " MeV - "
189       for(G4int i=0; i<=fMaxZ; ++i)            << 139          << HighEnergyLimit() / GeV << " GeV"
190   fLogAtomicShellXS[i] = theModel->fLogAtomicS << 140          << G4endl;
191       //Same verbosity for all workers, as the << 141 
192       fVerboseLevel = theModel->fVerboseLevel; << 142   if(isInitialised) return;
193     }                                          << 
194                                                   143 
195  return;                                       << 144   if(pParticleChange)
                                                   >> 145     fParticleChange = reinterpret_cast<G4ParticleChangeForGamma*>(pParticleChange);
                                                   >> 146   else
                                                   >> 147     fParticleChange = new G4ParticleChangeForGamma();
                                                   >> 148   isInitialised = true;
196 }                                                 149 }
197                                                   150 
198 //....oooOO0OOooo........oooOO0OOooo........oo    151 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
199 namespace { G4Mutex  PenelopePhotoElectricMode << 152 
200 G4double G4PenelopePhotoElectricModel::Compute    153 G4double G4PenelopePhotoElectricModel::ComputeCrossSectionPerAtom(
201                   const G4ParticleDefinition*, << 154                                        const G4ParticleDefinition*,
202                   G4double energy,             << 155                                              G4double energy,
203                   G4double Z, G4double,        << 156                                              G4double Z, G4double,
204                   G4double, G4double)          << 157                                              G4double, G4double)
205 {                                                 158 {
206   //                                              159   //
207   // Penelope model v2008                      << 160   // Penelope model. Use data-driven approach for cross section estimate (and 
                                                   >> 161   // also shell sampling from a given atom). Data are from the Livermore database
                                                   >> 162   //  D.E. Cullen et al., Report UCRL-50400 (1989)
208   //                                              163   //
209   if (fVerboseLevel > 3)                       << 
210     G4cout << "Calling ComputeCrossSectionPerA << 
211                                                   164 
212   G4int iZ = G4int(Z);                         << 165   if (verboseLevel > 3)
                                                   >> 166     G4cout << "Calling ComputeCrossSectionPerAtom() of G4PenelopePhotoElectricModel" << G4endl;
213                                                   167 
214   if (!fLogAtomicShellXS[iZ])                  << 168   G4int iZ = (G4int) Z;
                                                   >> 169   if (!crossSectionHandler)
215     {                                             170     {
216       //If we are here, it means that Initiali << 171       G4cout << "G4PenelopePhotoElectricModel::ComputeCrossSectionPerAtom" << G4endl;
217       //not filled up. This can happen in a Un << 172       G4cout << "The cross section handler is not correctly initialized" << G4endl;
218       if (fVerboseLevel > 0)                   << 173       G4Exception();
219   {                                            << 174     }
220     //Issue a G4Exception (warning) only in ve << 175   G4double cs = crossSectionHandler->FindValue(iZ,energy);
221     G4ExceptionDescription ed;                 << 176  
222     ed << "Unable to retrieve the shell cross  << 177   if (verboseLevel > 2)
223     ed << "This can happen only in Unit Tests  << 
224     G4Exception("G4PenelopePhotoElectricModel: << 
225           "em2038",JustWarning,ed);            << 
226   }                                            << 
227       //protect file reading via autolock      << 
228       G4AutoLock lock(&PenelopePhotoElectricMo << 
229       ReadDataFile(iZ);                        << 
230       lock.unlock();                           << 
231     }                                          << 
232                                                << 
233   G4double cross = 0;                          << 
234   G4PhysicsTable* theTable =  fLogAtomicShellX << 
235   G4PhysicsFreeVector* totalXSLog = (G4Physics << 
236                                                << 
237    if (!totalXSLog)                            << 
238      {                                         << 
239        G4Exception("G4PenelopePhotoElectricMod << 
240        "em2039",FatalException,                << 
241        "Unable to retrieve the total cross sec << 
242        return 0;                               << 
243      }                                         << 
244    G4double logene = G4Log(energy);            << 
245    G4double logXS = totalXSLog->Value(logene); << 
246    cross = G4Exp(logXS);                       << 
247                                                << 
248   if (fVerboseLevel > 2)                       << 
249     G4cout << "Photoelectric cross section at     178     G4cout << "Photoelectric cross section at " << energy/MeV << " MeV for Z=" << Z <<
250       " = " << cross/barn << " barn" << G4endl << 179       " = " << cs/barn << " barn" << G4endl;
251   return cross;                                << 180   return cs;
252 }                                                 181 }
253                                                   182 
254 //....oooOO0OOooo........oooOO0OOooo........oo    183 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
255                                                   184 
256 void G4PenelopePhotoElectricModel::SampleSecon    185 void G4PenelopePhotoElectricModel::SampleSecondaries(std::vector<G4DynamicParticle*>* fvect,
257                  const G4MaterialCutsCouple* c << 186                 const G4MaterialCutsCouple* couple,
258                  const G4DynamicParticle* aDyn << 187                 const G4DynamicParticle* aDynamicGamma,
259                  G4double,                     << 188                 G4double,
260                  G4double)                     << 189                 G4double)
261 {                                                 190 {
262   //                                              191   //
263   // Photoelectric effect, Penelope model v200 << 192   // Photoelectric effect, Penelope model
264   //                                              193   //
265   // The target atom and the target shell are  << 194   // The target atom and the target shell are sampled according to the Livermore 
266   // database                                  << 195   // database 
267   //  D.E. Cullen et al., Report UCRL-50400 (1    196   //  D.E. Cullen et al., Report UCRL-50400 (1989)
268   // The angular distribution of the electron  << 197   // The angular distribution of the electron in the final state is sampled 
269   // according to the Sauter distribution from << 198   // according to the Sauter distribution from 
270   //  F. Sauter, Ann. Phys. 11 (1931) 454         199   //  F. Sauter, Ann. Phys. 11 (1931) 454
271   // The energy of the final electron is given << 200   // The energy of the final electron is given by the initial photon energy minus 
272   // the binding energy. Fluorescence de-excit << 201   // the binding energy. Fluorescence de-excitation is subsequently produced 
273   // (to fill the vacancy) according to the ge    202   // (to fill the vacancy) according to the general Geant4 G4DeexcitationManager:
274   //  J. Stepanek, Comp. Phys. Comm. 1206 pp 1    203   //  J. Stepanek, Comp. Phys. Comm. 1206 pp 1-1-9 (1997)
275                                                   204 
276   if (fVerboseLevel > 3)                       << 205   if (verboseLevel > 3)
277     G4cout << "Calling SamplingSecondaries() o    206     G4cout << "Calling SamplingSecondaries() of G4PenelopePhotoElectricModel" << G4endl;
278                                                   207 
279   G4double photonEnergy = aDynamicGamma->GetKi    208   G4double photonEnergy = aDynamicGamma->GetKineticEnergy();
280                                                   209 
281   // always kill primary                       << 210   if (photonEnergy <= LowEnergyLimit())
282   fParticleChange->ProposeTrackStatus(fStopAnd << 211   {
283   fParticleChange->SetProposedKineticEnergy(0. << 212       fParticleChange->ProposeTrackStatus(fStopAndKill);
284                                                << 213       fParticleChange->SetProposedKineticEnergy(0.);
285   if (photonEnergy <= fIntrinsicLowEnergyLimit << 
286     {                                          << 
287       fParticleChange->ProposeLocalEnergyDepos    214       fParticleChange->ProposeLocalEnergyDeposit(photonEnergy);
288       return ;                                    215       return ;
289     }                                          << 216   }
290                                                   217 
291   G4ParticleMomentum photonDirection = aDynami    218   G4ParticleMomentum photonDirection = aDynamicGamma->GetMomentumDirection();
292                                                   219 
293   // Select randomly one element in the curren    220   // Select randomly one element in the current material
294   if (fVerboseLevel > 2)                       << 221   if (verboseLevel > 2)
295     G4cout << "Going to select element in " <<    222     G4cout << "Going to select element in " << couple->GetMaterial()->GetName() << G4endl;
296                                                << 223   //use crossSectionHandler instead of G4EmElementSelector because in this case 
297   // atom can be selected efficiently if eleme << 224   //the dimension of the table is equal to the dimension of the database (less interpolation errors)
298   const G4Element* anElement =                 << 225   G4int Z = crossSectionHandler->SelectRandomAtom(couple,photonEnergy);
299     SelectRandomAtom(couple,G4Gamma::GammaDefi << 226   if (verboseLevel > 2)
300   G4int Z = anElement->GetZasInt();            << 227     G4cout << "Selected Z = " << Z << G4endl;
301   if (fVerboseLevel > 2)                       << 
302     G4cout << "Selected " << anElement->GetNam << 
303                                                   228 
304   // Select the ionised shell in the current a    229   // Select the ionised shell in the current atom according to shell cross sections
305   //shellIndex = 0 --> K shell                 << 230   size_t shellIndex = shellCrossSectionHandler->SelectRandomShell(Z,photonEnergy);
306   //             1-3 --> L shells              << 
307   //             4-8 --> M shells              << 
308   //             9 --> outer shells cumulative << 
309   //                                           << 
310   std::size_t shellIndex = SelectRandomShell(Z << 
311                                                << 
312   if (fVerboseLevel > 2)                       << 
313     G4cout << "Selected shell " << shellIndex  << 
314                                                   231 
315   // Retrieve the corresponding identifier and    232   // Retrieve the corresponding identifier and binding energy of the selected shell
316   const G4AtomicTransitionManager* transitionM    233   const G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
317                                                   234 
318   //The number of shell cross section possibly << 235   //The number of shell cross section possibly reported in the Penelope database 
319   //might be different from the number of shel    236   //might be different from the number of shells in the G4AtomicTransitionManager
320   //(namely, Penelope may contain more shell,     237   //(namely, Penelope may contain more shell, especially for very light elements).
321   //In order to avoid a warning message from t << 238   //In order to avoid a warning message from the G4AtomicTransitionManager, I 
322   //add this protection. Results are anyway ch    239   //add this protection. Results are anyway changed, because when G4AtomicTransitionManager
323   //has a shellID>maxID, it sets the shellID t << 240   //has a shellID>maxID, it sets the shellID to the last valid shell. 
324   std::size_t numberOfShells = (std::size_t) t << 241   size_t numberOfShells = (size_t) transitionManager->NumberOfShells(Z);
325   if (shellIndex >= numberOfShells)               242   if (shellIndex >= numberOfShells)
326     shellIndex = numberOfShells-1;                243     shellIndex = numberOfShells-1;
327                                                   244 
328   const G4AtomicShell* shell = fTransitionMana << 245   const G4AtomicShell* shell = transitionManager->Shell(Z,shellIndex);
329   G4double bindingEnergy = shell->BindingEnerg    246   G4double bindingEnergy = shell->BindingEnergy();
330                                                << 247   G4int shellId = shell->ShellId();
331   //Penelope considers only K, L and M shells. << 
332   //not included in the Penelope database. If  << 
333   //shellIndex = 9, it means that an outer she << 
334   //Penelope recipe is to set bindingEnergy =  << 
335   //to the electron) and to disregard fluoresc << 
336   if (shellIndex == 9)                         << 
337     bindingEnergy = 0.*eV;                     << 
338                                                   248 
339   G4double localEnergyDeposit = 0.0;              249   G4double localEnergyDeposit = 0.0;
340   G4double cosTheta = 1.0;                     << 
341                                                   250 
342   // Primary outcoming electron                   251   // Primary outcoming electron
343   G4double eKineticEnergy = photonEnergy - bin    252   G4double eKineticEnergy = photonEnergy - bindingEnergy;
                                                   >> 253   
                                                   >> 254   G4double cutForLowEnergySecondaryParticles = 250.0*eV;
                                                   >> 255   const G4ProductionCutsTable* theCoupleTable=
                                                   >> 256     G4ProductionCutsTable::GetProductionCutsTable();
                                                   >> 257   size_t indx = couple->GetIndex();
                                                   >> 258   G4double cutE = (*(theCoupleTable->GetEnergyCutsVector(1)))[indx];
                                                   >> 259   cutE = std::max(cutForLowEnergySecondaryParticles,cutE);
344                                                   260 
345   // There may be cases where the binding ener    261   // There may be cases where the binding energy of the selected shell is > photon energy
346   // In such cases do not generate secondaries    262   // In such cases do not generate secondaries
347   if (eKineticEnergy > 0.)                        263   if (eKineticEnergy > 0.)
348     {                                             264     {
349       // The electron is created               << 265       //Now check if the electron is above cuts: if so, it is created explicitely
350       // Direction sampled from the Sauter dis << 266       if (eKineticEnergy > cutE)
351       cosTheta = SampleElectronDirection(eKine << 267   {
352       G4double sinTheta = std::sqrt(1-cosTheta << 268     // The electron is created
353       G4double phi = twopi * G4UniformRand() ; << 269     // Direction sampled from the Sauter distribution
354       G4double dirx = sinTheta * std::cos(phi) << 270     G4double cosTheta = SampleElectronDirection(eKineticEnergy);
355       G4double diry = sinTheta * std::sin(phi) << 271     G4double sinTheta = std::sqrt(1-cosTheta*cosTheta);
356       G4double dirz = cosTheta ;               << 272     G4double phi = twopi * G4UniformRand() ;
357       G4ThreeVector electronDirection(dirx,dir << 273     G4double dirx = sinTheta * std::cos(phi);
358       electronDirection.rotateUz(photonDirecti << 274     G4double diry = sinTheta * std::sin(phi);
359       G4DynamicParticle* electron = new G4Dyna << 275     G4double dirz = cosTheta ;
360                  electronDirection,            << 276     G4ThreeVector electronDirection(dirx,diry,dirz); //electron direction
361                  eKineticEnergy);              << 277     electronDirection.rotateUz(photonDirection);
362       fvect->push_back(electron);              << 278     G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(), 
                                                   >> 279                      electronDirection, 
                                                   >> 280                      eKineticEnergy);
                                                   >> 281     fvect->push_back(electron);
                                                   >> 282   } 
                                                   >> 283       else 
                                                   >> 284   localEnergyDeposit += eKineticEnergy;    
363     }                                             285     }
364   else                                            286   else
365     bindingEnergy = photonEnergy;              << 287       bindingEnergy = photonEnergy;
366                                                << 288     
                                                   >> 289   
367   G4double energyInFluorescence = 0; //testing    290   G4double energyInFluorescence = 0; //testing purposes
368   G4double energyInAuger = 0; //testing purpos << 
369                                                   291 
370   //Now, take care of fluorescence, if require << 292   //Now, take care of fluorescence, if required
371   //recipe, I have to skip fluoresence complet << 293   if (fUseAtomicDeexcitation)
372   //(= sampling of a shell outer than K,L,M)   << 
373   if (fAtomDeexcitation && shellIndex<9)       << 
374     {                                             294     {
375       G4int index = couple->GetIndex();        << 295       G4double cutG = (*(theCoupleTable->GetEnergyCutsVector(0)))[indx];
376       if (fAtomDeexcitation->CheckDeexcitation << 296       cutG = std::min(cutForLowEnergySecondaryParticles,cutG);
                                                   >> 297       
                                                   >> 298       std::vector<G4DynamicParticle*>* photonVector = 0;
                                                   >> 299 
                                                   >> 300       // Protection to avoid generating photons in the unphysical case of 
                                                   >> 301       // shell binding energy > photon energy
                                                   >> 302       if (Z > 5  && (bindingEnergy > cutG || bindingEnergy > cutE))
377   {                                               303   {
378     std::size_t nBefore = fvect->size();       << 304     photonVector = deexcitationManager.GenerateParticles(Z,shellId); 
379     fAtomDeexcitation->GenerateParticles(fvect << 305     //Check for single photons (if they are above threshold)
380     std::size_t nAfter = fvect->size();        << 306     for (size_t k=0; k< photonVector->size(); k++)
381                                                << 
382     if (nAfter > nBefore) //actual production  << 
383       {                                           307       {
384         for (std::size_t j=nBefore;j<nAfter;++ << 308         G4DynamicParticle* aPhoton = (*photonVector)[k];
                                                   >> 309         if (aPhoton)
385     {                                             310     {
386       G4double itsEnergy = ((*fvect)[j])->GetK << 311       G4double itsCut = cutG;
387       if (itsEnergy < bindingEnergy) // valid  << 312       if(aPhoton->GetDefinition() == G4Electron::Electron()) itsCut = cutE;
                                                   >> 313       G4double itsEnergy = aPhoton->GetKineticEnergy();
                                                   >> 314       
                                                   >> 315       if (itsEnergy > itsCut && itsEnergy <= bindingEnergy)
388         {                                         316         {
                                                   >> 317           // Local energy deposit is given as the sum of the 
                                                   >> 318           // energies of incident photons minus the energies
                                                   >> 319           // of the outcoming fluorescence photons
389           bindingEnergy -= itsEnergy;             320           bindingEnergy -= itsEnergy;
390           if (((*fvect)[j])->GetParticleDefini << 321           
391       energyInFluorescence += itsEnergy;       << 322         }
392           else if (((*fvect)[j])->GetParticleD << 323       else
393       energyInAuger += itsEnergy;              << 324         { 
                                                   >> 325           (*photonVector)[k] = 0;
394         }                                         326         }
395       else //invalid secondary: takes more tha << 
396         {                                      << 
397           delete (*fvect)[j];                  << 
398           (*fvect)[j] = nullptr;               << 
399         }                                      << 
400     }                                             327     }
401       }                                           328       }
402   }                                               329   }
                                                   >> 330       //Register valid secondaries
                                                   >> 331       if (photonVector)
                                                   >> 332   {
                                                   >> 333     for ( size_t ll = 0; ll <photonVector->size(); ll++) 
                                                   >> 334       {
                                                   >> 335         G4DynamicParticle* aPhoton = (*photonVector)[ll];
                                                   >> 336         if (aPhoton) 
                                                   >> 337     {
                                                   >> 338       energyInFluorescence += aPhoton->GetKineticEnergy();
                                                   >> 339       fvect->push_back(aPhoton);
                                                   >> 340     }
                                                   >> 341       }
                                                   >> 342     delete photonVector;
                                                   >> 343   }
403     }                                             344     }
404                                                << 
405   //Residual energy is deposited locally          345   //Residual energy is deposited locally
406   localEnergyDeposit += bindingEnergy;            346   localEnergyDeposit += bindingEnergy;
                                                   >> 347       
407                                                   348 
408   if (localEnergyDeposit < 0) //Should not be: << 349   if (localEnergyDeposit < 0)
409     {                                             350     {
410       G4Exception("G4PenelopePhotoElectricMode << 351       G4cout << "WARNING - "
411       "em2099",JustWarning,"WARNING: Negative  << 352        << "G4PenelopePhotoElectric::PostStepDoIt - Negative energy deposit"
                                                   >> 353        << G4endl;
412       localEnergyDeposit = 0;                     354       localEnergyDeposit = 0;
413     }                                             355     }
414                                                   356 
                                                   >> 357  //Update the status of the primary gamma (kill it)
                                                   >> 358   fParticleChange->SetProposedKineticEnergy(0.);
415   fParticleChange->ProposeLocalEnergyDeposit(l    359   fParticleChange->ProposeLocalEnergyDeposit(localEnergyDeposit);
                                                   >> 360   fParticleChange->ProposeTrackStatus(fStopAndKill);
416                                                   361 
417   if (fVerboseLevel > 1)                       << 362   if (verboseLevel > 1)
418     {                                             363     {
419       G4cout << "-----------------------------    364       G4cout << "-----------------------------------------------------------" << G4endl;
420       G4cout << "Energy balance from G4Penelop    365       G4cout << "Energy balance from G4PenelopePhotoElectric" << G4endl;
421       G4cout << "Selected shell: " << WriteTar << 
422   anElement->GetName() << G4endl;              << 
423       G4cout << "Incoming photon energy: " <<     366       G4cout << "Incoming photon energy: " << photonEnergy/keV << " keV" << G4endl;
424       G4cout << "-----------------------------    367       G4cout << "-----------------------------------------------------------" << G4endl;
425       if (eKineticEnergy)                         368       if (eKineticEnergy)
426   G4cout << "Outgoing electron " << eKineticEn    369   G4cout << "Outgoing electron " << eKineticEnergy/keV << " keV" << G4endl;
427       if (energyInFluorescence)                << 370       G4cout << "Fluorescence: " << energyInFluorescence/keV << " keV" << G4endl;
428   G4cout << "Fluorescence x-rays: " << energyI << 
429       if (energyInAuger)                       << 
430   G4cout << "Auger electrons: " << energyInAug << 
431       G4cout << "Local energy deposit " << loc    371       G4cout << "Local energy deposit " << localEnergyDeposit/keV << " keV" << G4endl;
432       G4cout << "Total final state: " <<       << 372       G4cout << "Total final state: " << (eKineticEnergy+energyInFluorescence+localEnergyDeposit)/keV << 
433   (eKineticEnergy+energyInFluorescence+localEn << 
434   " keV" << G4endl;                               373   " keV" << G4endl;
435       G4cout << "-----------------------------    374       G4cout << "-----------------------------------------------------------" << G4endl;
436     }                                             375     }
437   if (fVerboseLevel > 0)                       << 376   if (verboseLevel > 0)
438     {                                             377     {
439       G4double energyDiff =                    << 378       G4double energyDiff = std::fabs(eKineticEnergy+energyInFluorescence+localEnergyDeposit-photonEnergy);
440   std::fabs(eKineticEnergy+energyInFluorescenc << 
441       if (energyDiff > 0.05*keV)                  379       if (energyDiff > 0.05*keV)
442   {                                            << 380   G4cout << "Warning from G4PenelopePhotoElectric: problem with energy conservation: " << 
443     G4cout << "Warning from G4PenelopePhotoEle << 381     (eKineticEnergy+energyInFluorescence+localEnergyDeposit)/keV << " keV (final) vs. " << 
444       (eKineticEnergy+energyInFluorescence+loc << 382     photonEnergy/keV << " keV (initial)" << G4endl;
445      << " keV (final) vs. " <<                 << 
446       photonEnergy/keV << " keV (initial)" <<  << 
447     G4cout << "------------------------------- << 
448     G4cout << "Energy balance from G4PenelopeP << 
449     G4cout << "Selected shell: " << WriteTarge << 
450       anElement->GetName() << G4endl;          << 
451     G4cout << "Incoming photon energy: " << ph << 
452     G4cout << "------------------------------- << 
453     if (eKineticEnergy)                        << 
454       G4cout << "Outgoing electron " << eKinet << 
455     if (energyInFluorescence)                  << 
456       G4cout << "Fluorescence x-rays: " << ene << 
457     if (energyInAuger)                         << 
458       G4cout << "Auger electrons: " << energyI << 
459     G4cout << "Local energy deposit " << local << 
460     G4cout << "Total final state: " <<         << 
461       (eKineticEnergy+energyInFluorescence+loc << 
462       " keV" << G4endl;                        << 
463     G4cout << "------------------------------- << 
464   }                                            << 
465     }                                             383     }
466 }                                                 384 }
467                                                   385 
468 //....oooOO0OOooo........oooOO0OOooo........oo    386 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
469                                                   387 
                                                   >> 388 void G4PenelopePhotoElectricModel::ActivateAuger(G4bool augerbool)
                                                   >> 389 {
                                                   >> 390   if (!fUseAtomicDeexcitation)
                                                   >> 391     {
                                                   >> 392       G4cout << "WARNING - G4PenelopePhotoElectricModel" << G4endl;
                                                   >> 393       G4cout << "The use of the Atomic Deexcitation Manager is set to false " << G4endl;
                                                   >> 394       G4cout << "Therefore, Auger electrons will be not generated anyway" << G4endl;
                                                   >> 395     }
                                                   >> 396   deexcitationManager.ActivateAugerElectronProduction(augerbool);
                                                   >> 397   if (verboseLevel > 1)
                                                   >> 398     G4cout << "Auger production set to " << augerbool << G4endl;
                                                   >> 399 }
                                                   >> 400 
                                                   >> 401 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
                                                   >> 402 
470 G4double G4PenelopePhotoElectricModel::SampleE    403 G4double G4PenelopePhotoElectricModel::SampleElectronDirection(G4double energy)
471 {                                                 404 {
472   G4double costheta = 1.0;                        405   G4double costheta = 1.0;
473   if (energy>1*GeV) return costheta;              406   if (energy>1*GeV) return costheta;
474                                                << 407  
475   //1) initialize energy-dependent variables      408   //1) initialize energy-dependent variables
476   // Variable naming according to Eq. (2.24) o    409   // Variable naming according to Eq. (2.24) of Penelope Manual
477   // (pag. 44)                                    410   // (pag. 44)
478   G4double gamma = 1.0 + energy/electron_mass_    411   G4double gamma = 1.0 + energy/electron_mass_c2;
479   G4double gamma2 = gamma*gamma;                  412   G4double gamma2 = gamma*gamma;
480   G4double beta = std::sqrt((gamma2-1.0)/gamma    413   G4double beta = std::sqrt((gamma2-1.0)/gamma2);
481                                                << 414    
482   // ac corresponds to "A" of Eq. (2.31)          415   // ac corresponds to "A" of Eq. (2.31)
483   //                                              416   //
484   G4double ac = (1.0/beta) - 1.0;                 417   G4double ac = (1.0/beta) - 1.0;
485   G4double a1 = 0.5*beta*gamma*(gamma-1.0)*(ga    418   G4double a1 = 0.5*beta*gamma*(gamma-1.0)*(gamma-2.0);
486   G4double a2 = ac + 2.0;                         419   G4double a2 = ac + 2.0;
487   G4double gtmax = 2.0*(a1 + 1.0/ac);             420   G4double gtmax = 2.0*(a1 + 1.0/ac);
488                                                << 421  
489   G4double tsam = 0;                              422   G4double tsam = 0;
490   G4double gtr = 0;                               423   G4double gtr = 0;
491                                                   424 
492   //2) sampling. Eq. (2.31) of Penelope Manual    425   //2) sampling. Eq. (2.31) of Penelope Manual
493   // tsam = 1-std::cos(theta)                     426   // tsam = 1-std::cos(theta)
494   // gtr = rejection function according to Eq.    427   // gtr = rejection function according to Eq. (2.28)
495   do{                                             428   do{
496     G4double rand = G4UniformRand();              429     G4double rand = G4UniformRand();
497     tsam = 2.0*ac * (2.0*rand + a2*std::sqrt(r    430     tsam = 2.0*ac * (2.0*rand + a2*std::sqrt(rand)) / (a2*a2 - 4.0*rand);
498     gtr = (2.0 - tsam) * (a1 + 1.0/(ac+tsam));    431     gtr = (2.0 - tsam) * (a1 + 1.0/(ac+tsam));
499   }while(G4UniformRand()*gtmax > gtr);            432   }while(G4UniformRand()*gtmax > gtr);
500   costheta = 1.0-tsam;                            433   costheta = 1.0-tsam;
501                                                << 
502   return costheta;                                434   return costheta;
503 }                                                 435 }
504                                                   436 
505 //....oooOO0OOooo........oooOO0OOooo........oo << 
506                                                << 
507 void G4PenelopePhotoElectricModel::ReadDataFil << 
508 {                                              << 
509   if (!IsMaster())                             << 
510       //Should not be here!                    << 
511     G4Exception("G4PenelopePhotoElectricModel: << 
512     "em0100",FatalException,"Worker thread in  << 
513                                                << 
514   if (fVerboseLevel > 2)                       << 
515     {                                          << 
516       G4cout << "G4PenelopePhotoElectricModel: << 
517       G4cout << "Going to read PhotoElectric d << 
518     }                                          << 
519                                                << 
520     const char* path = G4FindDataDir("G4LEDATA << 
521     if(!path)                                  << 
522     {                                          << 
523       G4String excep = "G4PenelopePhotoElectri << 
524       G4Exception("G4PenelopePhotoElectricMode << 
525       "em0006",FatalException,excep);          << 
526       return;                                  << 
527     }                                          << 
528                                                << 
529   /*                                           << 
530     Read the cross section file                << 
531   */                                           << 
532   std::ostringstream ost;                      << 
533   if (Z>9)                                     << 
534     ost << path << "/penelope/photoelectric/pd << 
535   else                                         << 
536     ost << path << "/penelope/photoelectric/pd << 
537   std::ifstream file(ost.str().c_str());       << 
538   if (!file.is_open())                         << 
539     {                                          << 
540       G4String excep = "G4PenelopePhotoElectri << 
541       G4Exception("G4PenelopePhotoElectricMode << 
542       "em0003",FatalException,excep);          << 
543     }                                          << 
544   //I have to know in advance how many points  << 
545   //to initialize the G4PhysicsFreeVector()    << 
546   std::size_t ndata=0;                         << 
547   G4String line;                               << 
548   while( getline(file, line) )                 << 
549     ndata++;                                   << 
550   ndata -= 1;                                  << 
551   //G4cout << "Found: " << ndata << " lines" < << 
552                                                << 
553   file.clear();                                << 
554   file.close();                                << 
555   file.open(ost.str().c_str());                << 
556                                                << 
557   G4int readZ =0;                              << 
558   std::size_t nShells= 0;                      << 
559   file >> readZ >> nShells;                    << 
560                                                << 
561   if (fVerboseLevel > 3)                       << 
562     G4cout << "Element Z=" << Z << " , nShells << 
563                                                << 
564   //check the right file is opened.            << 
565   if (readZ != Z || nShells <= 0 || nShells >  << 
566     {                                          << 
567       G4ExceptionDescription ed;               << 
568       ed << "Corrupted data file for Z=" << Z  << 
569       G4Exception("G4PenelopePhotoElectricMode << 
570       "em0005",FatalException,ed);             << 
571       return;                                  << 
572     }                                          << 
573   G4PhysicsTable* thePhysicsTable = new G4Phys << 
574                                                << 
575   //the table has to contain nShell+1 G4Physic << 
576   //(theTable)[0] --> total cross section      << 
577   //(theTable)[ishell] --> cross section for s << 
578                                                << 
579   //reserve space for the vectors              << 
580   //everything is log-log                      << 
581   for (std::size_t i=0;i<nShells+1;++i)        << 
582     thePhysicsTable->push_back(new G4PhysicsFr << 
583                                                << 
584   std::size_t k =0;                            << 
585   for (k=0;k<ndata && !file.eof();++k)         << 
586     {                                          << 
587       G4double energy = 0;                     << 
588       G4double aValue = 0;                     << 
589       file >> energy ;                         << 
590       energy *= eV;                            << 
591       G4double logene = G4Log(energy);         << 
592       //loop on the columns                    << 
593       for (std::size_t i=0;i<nShells+1;++i)    << 
594   {                                            << 
595     file >> aValue;                            << 
596     aValue *= barn;                            << 
597     G4PhysicsFreeVector* theVec = (G4PhysicsFr << 
598     if (aValue < 1e-40*cm2) //protection again << 
599       aValue = 1e-40*cm2;                      << 
600     theVec->PutValue(k,logene,G4Log(aValue));  << 
601   }                                            << 
602     }                                          << 
603                                                << 
604   if (fVerboseLevel > 2)                       << 
605     {                                          << 
606       G4cout << "G4PenelopePhotoElectricModel: << 
607        << Z << G4endl;                         << 
608     }                                          << 
609                                                << 
610   fLogAtomicShellXS[Z] = thePhysicsTable;      << 
611                                                << 
612   file.close();                                << 
613   return;                                      << 
614 }                                              << 
615                                                << 
616 //....oooOO0OOooo........oooOO0OOooo........oo << 
617                                                << 
618 std::size_t G4PenelopePhotoElectricModel::GetN << 
619 {                                              << 
620   if (!IsMaster())                             << 
621     //Should not be here!                      << 
622     G4Exception("G4PenelopePhotoElectricModel: << 
623     "em0100",FatalException,"Worker thread in  << 
624                                                << 
625   //read data files                            << 
626   if (!fLogAtomicShellXS[Z])                   << 
627     ReadDataFile(Z);                           << 
628   //now it should be ok                        << 
629   if (!fLogAtomicShellXS[Z])                   << 
630      {                                         << 
631        G4ExceptionDescription ed;              << 
632        ed << "Cannot find shell cross section  << 
633        G4Exception("G4PenelopePhotoElectricMod << 
634        "em2038",FatalException,ed);            << 
635      }                                         << 
636   //one vector is allocated for the _total_ cr << 
637   std::size_t nEntries = fLogAtomicShellXS[Z]- << 
638   return  (nEntries-1);                        << 
639 }                                              << 
640                                                << 
641 //....oooOO0OOooo........oooOO0OOooo........oo << 
642                                                << 
643 G4double G4PenelopePhotoElectricModel::GetShel << 
644 {                                              << 
645   //this forces also the loading of the data   << 
646   std::size_t entries = GetNumberOfShellXS(Z); << 
647                                                << 
648   if (shellID >= entries)                      << 
649     {                                          << 
650       G4cout << "Element Z=" << Z << " has dat << 
651       G4cout << "so shellID should be from 0 t << 
652       return 0;                                << 
653     }                                          << 
654                                                << 
655   G4PhysicsTable* theTable =  fLogAtomicShellX << 
656   //[0] is the total XS, shellID is in the ele << 
657   G4PhysicsFreeVector* totalXSLog = (G4Physics << 
658                                                << 
659   if (!totalXSLog)                             << 
660      {                                         << 
661        G4Exception("G4PenelopePhotoElectricMod << 
662        "em2039",FatalException,                << 
663        "Unable to retrieve the total cross sec << 
664        return 0;                               << 
665      }                                         << 
666    G4double logene = G4Log(energy);            << 
667    G4double logXS = totalXSLog->Value(logene); << 
668    G4double cross = G4Exp(logXS);              << 
669    if (cross < 2e-40*cm2) cross = 0;           << 
670    return cross;                               << 
671 }                                              << 
672                                                << 
673 //....oooOO0OOooo........oooOO0OOooo........oo << 
674                                                << 
675 G4String G4PenelopePhotoElectricModel::WriteTa << 
676 {                                              << 
677   G4String theShell = "outer shell";           << 
678   if (shellID == 0)                            << 
679     theShell = "K";                            << 
680   else if (shellID == 1)                       << 
681     theShell = "L1";                           << 
682   else if (shellID == 2)                       << 
683     theShell = "L2";                           << 
684   else if (shellID == 3)                       << 
685     theShell = "L3";                           << 
686   else if (shellID == 4)                       << 
687     theShell = "M1";                           << 
688   else if (shellID == 5)                       << 
689     theShell = "M2";                           << 
690   else if (shellID == 6)                       << 
691     theShell = "M3";                           << 
692   else if (shellID == 7)                       << 
693     theShell = "M4";                           << 
694   else if (shellID == 8)                       << 
695     theShell = "M5";                           << 
696                                                << 
697   return theShell;                             << 
698 }                                              << 
699                                                << 
700 //....oooOO0OOooo........oooOO0OOooo........oo << 
701                                                << 
702 void G4PenelopePhotoElectricModel::SetParticle << 
703 {                                              << 
704   if(!fParticle) {                             << 
705     fParticle = p;                             << 
706   }                                            << 
707 }                                              << 
708                                                << 
709 //....oooOO0OOooo........oooOO0OOooo........oo << 
710                                                << 
711 std::size_t G4PenelopePhotoElectricModel::Sele << 
712 {                                              << 
713   G4double logEnergy = G4Log(energy);          << 
714                                                << 
715   //Check if data have been read (it should be << 
716   if (!fLogAtomicShellXS[Z])                   << 
717      {                                         << 
718        G4ExceptionDescription ed;              << 
719        ed << "Cannot find shell cross section  << 
720        G4Exception("G4PenelopePhotoElectricMod << 
721        "em2038",FatalException,ed);            << 
722      }                                         << 
723                                                << 
724   G4PhysicsTable* theTable =  fLogAtomicShellX << 
725                                                << 
726   G4double sum = 0;                            << 
727   G4PhysicsFreeVector* totalXSLog = (G4Physics << 
728   G4double logXS = totalXSLog->Value(logEnergy << 
729   G4double totalXS = G4Exp(logXS);             << 
730                                                << 
731   //Notice: totalXS is the total cross section << 
732   //the sum of partialXS's, since these includ << 
733   //                                           << 
734   // Therefore, here one have to consider the  << 
735   // an outer shell. Conventionally, it is ind << 
736   //                                           << 
737   G4double random = G4UniformRand()*totalXS;   << 
738                                                << 
739   for (std::size_t k=1;k<theTable->entries();+ << 
740     {                                          << 
741       //Add one shell                          << 
742       G4PhysicsFreeVector* partialXSLog = (G4P << 
743       G4double logXSLocal = partialXSLog->Valu << 
744       G4double partialXS = G4Exp(logXSLocal);  << 
745       sum += partialXS;                        << 
746       if (random <= sum)                       << 
747   return k-1;                                  << 
748     }                                          << 
749   //none of the shells K, L, M: return outer s << 
750   return 9;                                    << 
751 }                                              << 
752                                                   437