Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/cross_sections/src/G4CrossSectionDataStore.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/hadronic/cross_sections/src/G4CrossSectionDataStore.cc (Version 11.3.0) and /processes/hadronic/cross_sections/src/G4CrossSectionDataStore.cc (Version 9.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 // ------------------------------------------- << 
 28 //                                             << 
 29 // GEANT4 Class file                           << 
 30 //                                             << 
 31 //                                             << 
 32 // File name:     G4CrossSectionDataStore      << 
 33 //                                             << 
 34 // Modifications:                              << 
 35 // 23.01.2009 V.Ivanchenko add destruction of  << 
 36 // 29.04.2010 G.Folger     modifictaions for i << 
 37 // 14.03.2011 V.Ivanchenko fixed DumpPhysicsTa << 
 38 // 15.08.2011 G.Folger, V.Ivanchenko, T.Koi, D << 
 39 // 07.03.2013 M.Maire cosmetic in DumpPhysicsT << 
 40 //                                             << 
 41 //....oooOO0OOooo........oooOO0OOooo........oo << 
 42 //....oooOO0OOooo........oooOO0OOooo........oo << 
 43                                                    27 
 44 #include "G4CrossSectionDataStore.hh"              28 #include "G4CrossSectionDataStore.hh"
 45 #include "G4SystemOfUnits.hh"                  <<  29 #include "G4HadronicException.hh"
 46 #include "G4UnitsTable.hh"                     <<  30 #include "G4StableIsotopes.hh"
                                                   >>  31 #include "G4HadTmpUtil.hh"
 47 #include "Randomize.hh"                            32 #include "Randomize.hh"
 48 #include "G4Nucleus.hh"                        <<  33 #include "G4Nucleus.hh" 
 49                                                    34 
 50 #include "G4DynamicParticle.hh"                << 
 51 #include "G4Isotope.hh"                        << 
 52 #include "G4Element.hh"                        << 
 53 #include "G4Material.hh"                       << 
 54 #include "G4MaterialTable.hh"                  << 
 55 #include "G4NistManager.hh"                    << 
 56 #include "G4HadronicParameters.hh"             << 
 57 #include <algorithm>                           << 
 58 #include <typeinfo>                            << 
 59                                                    35 
 60 //....oooOO0OOooo........oooOO0OOooo........oo <<  36 G4double
 61                                                <<  37 G4CrossSectionDataStore::GetCrossSection(const G4DynamicParticle* aParticle,
 62 G4CrossSectionDataStore::G4CrossSectionDataSto <<  38                                          const G4Element* anElement,
 63   : nist(G4NistManager::Instance())            <<  39            G4double aTemperature)
 64 {}                                             << 
 65                                                << 
 66 //....oooOO0OOooo........oooOO0OOooo........oo << 
 67                                                << 
 68 G4double                                       << 
 69 G4CrossSectionDataStore::ComputeCrossSection(c << 
 70                const G4Material* mat)          << 
 71 {                                                  40 {
 72   currentMaterial = mat;                       <<  41   if (NDataSetList == 0) 
 73   matParticle = dp->GetDefinition();           <<  42   {
 74   matKinEnergy = dp->GetKineticEnergy();       <<  43     throw G4HadronicException(__FILE__, __LINE__, 
 75   matCrossSection = 0.0;                       <<  44      "G4CrossSectionDataStore: no data sets registered");
 76                                                <<  45     return DBL_MIN;
 77   std::size_t nElements = mat->GetNumberOfElem << 
 78   const G4double* nAtomsPerVolume = mat->GetVe << 
 79                                                << 
 80   if(xsecelm.size() < nElements) { xsecelm.res << 
 81                                                << 
 82   for(G4int i=0; i<(G4int)nElements; ++i) {    << 
 83     G4double xs =                              << 
 84       nAtomsPerVolume[i]*GetCrossSection(dp, m << 
 85     matCrossSection += std::max(xs, 0.0);      << 
 86     xsecelm[i] = matCrossSection;              << 
 87   }                                                46   }
 88   return matCrossSection;                      <<  47   for (G4int i = NDataSetList-1; i >= 0; i--) {
                                                   >>  48     if (DataSetList[i]->IsApplicable(aParticle, anElement))
                                                   >>  49       return DataSetList[i]->GetCrossSection(aParticle,anElement,aTemperature);
                                                   >>  50   }
                                                   >>  51   throw G4HadronicException(__FILE__, __LINE__, 
                                                   >>  52                       "G4CrossSectionDataStore: no applicable data set found "
                                                   >>  53                       "for particle/element");
                                                   >>  54   return DBL_MIN;
 89 }                                                  55 }
 90                                                    56 
 91 //....oooOO0OOooo........oooOO0OOooo........oo <<  57 G4VCrossSectionDataSet*
 92                                                <<  58 G4CrossSectionDataStore::whichDataSetInCharge(const G4DynamicParticle* aParticle,
 93 G4double G4CrossSectionDataStore::GetCrossSect <<  59                                               const G4Element* anElement)
 94                                                << 
 95                                                << 
 96 {                                                  60 {
 97   // first check the most last cross section   <<  61   if (NDataSetList == 0) 
 98   G4int i = nDataSetList-1;                    << 
 99   G4int Z = elm->GetZasInt();                  << 
100                                                << 
101   if(elm->GetNaturalAbundanceFlag() &&         << 
102      dataSetList[i]->IsElementApplicable(dp, Z << 
103   {                                                62   {
104     // element wise cross section              <<  63     throw G4HadronicException(__FILE__, __LINE__, 
105     return dataSetList[i]->GetElementCrossSect <<  64      "G4CrossSectionDataStore: no data sets registered");
                                                   >>  65     return 0;
                                                   >>  66   }
                                                   >>  67   for (G4int i = NDataSetList-1; i >= 0; i--) {
                                                   >>  68     if (DataSetList[i]->IsApplicable(aParticle, anElement) )
                                                   >>  69     {
                                                   >>  70       return DataSetList[i];
                                                   >>  71     }
106   }                                                72   }
                                                   >>  73   throw G4HadronicException(__FILE__, __LINE__, 
                                                   >>  74                       "G4CrossSectionDataStore: no applicable data set found "
                                                   >>  75                       "for particle/element");
                                                   >>  76   return 0;
                                                   >>  77 }
107                                                    78 
108   // isotope wise cross section                << 
109   G4int nIso = (G4int)elm->GetNumberOfIsotopes << 
110                                                    79 
111   // user-defined isotope abundances           <<  80 G4double
112   const G4double* abundVector = elm->GetRelati <<  81 G4CrossSectionDataStore::GetCrossSection(const G4DynamicParticle* aParticle,
                                                   >>  82                                          const G4Isotope* anIsotope,
                                                   >>  83            G4double aTemperature)
                                                   >>  84 {
                                                   >>  85   if (NDataSetList == 0) 
                                                   >>  86   {
                                                   >>  87     throw G4HadronicException(__FILE__, __LINE__, 
                                                   >>  88      "G4CrossSectionDataStore: no data sets registered");
                                                   >>  89     return DBL_MIN;
                                                   >>  90   }
                                                   >>  91   for (G4int i = NDataSetList-1; i >= 0; i--) {
                                                   >>  92     if (DataSetList[i]->IsZAApplicable(aParticle, anIsotope->GetZ(), anIsotope->GetN()))
                                                   >>  93       return DataSetList[i]->GetIsoCrossSection(aParticle,anIsotope,aTemperature);
                                                   >>  94   }
                                                   >>  95   throw G4HadronicException(__FILE__, __LINE__, 
                                                   >>  96                       "G4CrossSectionDataStore: no applicable data set found "
                                                   >>  97                       "for particle/element");
                                                   >>  98   return DBL_MIN;
                                                   >>  99 }
113                                                   100 
114   G4double sigma = 0.0;                        << 
115                                                   101 
116   // isotope and element wise cross sections   << 102 G4double
117   for(G4int j = 0; j < nIso; ++j)              << 103 G4CrossSectionDataStore::GetCrossSection(const G4DynamicParticle* aParticle,
                                                   >> 104                                          G4double Z, G4double A,
                                                   >> 105            G4double aTemperature)
                                                   >> 106 {
                                                   >> 107   if (NDataSetList == 0) 
118   {                                               108   {
119     const G4Isotope* iso = elm->GetIsotope(j); << 109     throw G4HadronicException(__FILE__, __LINE__, 
120     sigma += abundVector[j] *                  << 110      "G4CrossSectionDataStore: no data sets registered");
121       GetIsoCrossSection(dp, Z, iso->GetN(), i << 111     return DBL_MIN;
122   }                                            << 112   }
123   return sigma;                                << 113   for (G4int i = NDataSetList-1; i >= 0; i--) {
                                                   >> 114       if (DataSetList[i]->IsZAApplicable(aParticle, Z, A))
                                                   >> 115       return DataSetList[i]->GetIsoZACrossSection(aParticle,Z,A,aTemperature);
                                                   >> 116   }
                                                   >> 117   throw G4HadronicException(__FILE__, __LINE__, 
                                                   >> 118                       "G4CrossSectionDataStore: no applicable data set found "
                                                   >> 119                       "for particle/element");
                                                   >> 120   return DBL_MIN;
124 }                                                 121 }
125                                                   122 
126 //....oooOO0OOooo........oooOO0OOooo........oo << 
127                                                   123 
128 G4double                                          124 G4double
129 G4CrossSectionDataStore::GetIsoCrossSection(co << 125 G4CrossSectionDataStore::GetCrossSection(const G4DynamicParticle* aParticle,
130               G4int Z, G4int A,                << 126                                          const G4Material* aMaterial)
131               const G4Isotope* iso,            << 127 {
132               const G4Element* elm,            << 128   G4double sigma(0);
133               const G4Material* mat,           << 129   G4double aTemp = aMaterial->GetTemperature();
134               G4int idx)                       << 130   G4int nElements = aMaterial->GetNumberOfElements();
135 {                                              << 131   const G4double* theAtomsPerVolumeVector = aMaterial->GetVecNbOfAtomsPerVolume();
136   // this methods is called after the check th << 132   G4double xSection(0);
137   // depend on isotopes, so first isotopes are << 133 
138   if(dataSetList[idx]->IsIsoApplicable(dp, Z,  << 134   for(G4int i=0; i<nElements; i++) {
139     return dataSetList[idx]->GetIsoCrossSectio << 135     xSection = GetCrossSection( aParticle, (*aMaterial->GetElementVector())[i], aTemp);
140   }                                            << 136     sigma += theAtomsPerVolumeVector[i] * xSection;
141                                                << 
142   // no isotope wise cross section - check oth << 
143   for (G4int j = nDataSetList-1; j >= 0; --j)  << 
144     if(dataSetList[j]->IsElementApplicable(dp, << 
145       return dataSetList[j]->GetElementCrossSe << 
146     } else if (dataSetList[j]->IsIsoApplicable << 
147       return dataSetList[j]->GetIsoCrossSectio << 
148     }                                          << 
149   }                                               137   }
150   G4ExceptionDescription ed;                   << 138 
151   ed << "No isotope cross section found for "  << 139   return sigma;
152      << dp->GetDefinition()->GetParticleName() << 
153      << " off target Element " << elm->GetName << 
154      << " Z= " << Z << " A= " << A;            << 
155   if(nullptr != mat) ed << " from " << mat->Ge << 
156   ed << " E(MeV)=" << dp->GetKineticEnergy()/M << 
157   G4Exception("G4CrossSectionDataStore::GetIso << 
158               FatalException, ed);             << 
159   return 0.0;                                  << 
160 }                                                 140 }
161                                                   141 
162 //....oooOO0OOooo........oooOO0OOooo........oo << 
163                                                   142 
164 G4double                                       << 143 G4Element* G4CrossSectionDataStore::SampleZandA(const G4DynamicParticle* particle, 
165 G4CrossSectionDataStore::GetCrossSection(const << 144             const G4Material* aMaterial,
166                                          G4int << 145             G4Nucleus& target)
167            const G4Isotope* iso,               << 146 {
168                                          const << 147   G4double aTemp = aMaterial->GetTemperature();
169            const G4Material* mat)              << 148   const G4int nElements = aMaterial->GetNumberOfElements();
170 {                                              << 149   const G4ElementVector* theElementVector = aMaterial->GetElementVector();
171   for (G4int i = nDataSetList-1; i >= 0; --i)  << 150   G4Element* anElement = (*theElementVector)[0];
172     if (dataSetList[i]->IsIsoApplicable(dp, Z, << 151   G4VCrossSectionDataSet* inCharge;
173       return dataSetList[i]->GetIsoCrossSectio << 152   G4int i;
174     } else if(dataSetList[i]->IsElementApplica << 
175       return dataSetList[i]->GetElementCrossSe << 
176     }                                          << 
177   }                                            << 
178   G4ExceptionDescription ed;                   << 
179   ed << "No isotope cross section found for "  << 
180      << dp->GetDefinition()->GetParticleName() << 
181      << " off target Element " << elm->GetName << 
182      << " Z= " << Z << " A= " << A;            << 
183   if(nullptr != mat) ed << " from " << mat->Ge << 
184   ed << " E(MeV)=" << dp->GetKineticEnergy()/M << 
185   G4Exception("G4CrossSectionDataStore::GetCro << 
186               FatalException, ed);             << 
187   return 0.0;                                  << 
188 }                                              << 
189                                                << 
190 //....oooOO0OOooo........oooOO0OOooo........oo << 
191                                                << 
192 const G4Element*                               << 
193 G4CrossSectionDataStore::SampleZandA(const G4D << 
194                                      const G4M << 
195              G4Nucleus& target)                << 
196 {                                              << 
197   if(nullptr != forcedElement) { return forced << 
198   std::size_t nElements = mat->GetNumberOfElem << 
199   const G4Element* anElement = mat->GetElement << 
200                                                   153 
201   // select element from a compound            << 154   // compounds
202   if(1 < nElements) {                             155   if(1 < nElements) {
203     G4double cross = matCrossSection*G4Uniform << 156     G4double* xsec = new G4double [nElements];
204     for(G4int i=0; i<(G4int)nElements; ++i) {  << 157     const G4double* theAtomsPerVolumeVector = aMaterial->GetVecNbOfAtomsPerVolume();
205       if(cross <= xsecelm[i]) {                << 158     G4double cross = 0.0;
206         anElement = mat->GetElement(i);        << 159     for(i=0; i<nElements; i++) {
207         break;                                 << 160       anElement= (*theElementVector)[i];
                                                   >> 161       inCharge = whichDataSetInCharge(particle, anElement);
                                                   >> 162       cross   += theAtomsPerVolumeVector[i]*
                                                   >> 163   inCharge->GetCrossSection(particle, anElement, aTemp);
                                                   >> 164       xsec[i]  = cross;
                                                   >> 165     }
                                                   >> 166     cross *= G4UniformRand();
                                                   >> 167 
                                                   >> 168     for(i=0; i<nElements; i++) {
                                                   >> 169       if( cross <=  xsec[i] ) {
                                                   >> 170   anElement = (*theElementVector)[i];
                                                   >> 171   break;
208       }                                           172       }
209     }                                             173     }
                                                   >> 174     delete [] xsec;
210   }                                               175   }
211                                                   176 
212   G4int Z = anElement->GetZasInt();            << 177   // element have been selected
213   const G4Isotope* iso = nullptr;              << 178   inCharge = whichDataSetInCharge(particle, anElement);
                                                   >> 179   G4double ZZ = anElement->GetZ();
                                                   >> 180   G4double AA;
                                                   >> 181 
                                                   >> 182   // Collect abundance weighted cross sections and A values for each isotope 
                                                   >> 183   // in each element
                                                   >> 184  
                                                   >> 185   const G4int nIsoPerElement = anElement->GetNumberOfIsotopes();
214                                                   186 
215   G4int i = nDataSetList-1;                    << 187   // user-defined isotope abundances
216   if (dataSetList[i]->IsElementApplicable(dp,  << 188   if (0 < nIsoPerElement) { 
                                                   >> 189     G4IsotopeVector* isoVector = anElement->GetIsotopeVector();
                                                   >> 190     AA = G4double((*isoVector)[0]->GetN());
                                                   >> 191     if(1 < nIsoPerElement) {
                                                   >> 192 
                                                   >> 193       G4double* xsec  = new G4double [nIsoPerElement];
                                                   >> 194       G4double iso_xs = 0.0;
                                                   >> 195       G4double cross  = 0.0;
                                                   >> 196 
                                                   >> 197       G4double* abundVector = anElement->GetRelativeAbundanceVector();
                                                   >> 198       G4bool elementXS = false;
                                                   >> 199       for (i = 0; i<nIsoPerElement; i++) {
                                                   >> 200   if (inCharge->IsZAApplicable(particle, ZZ, G4double((*isoVector)[i]->GetN()))) {
                                                   >> 201     iso_xs = inCharge->GetIsoCrossSection(particle, (*isoVector)[i], aTemp);
                                                   >> 202   } else if (elementXS == false) {
                                                   >> 203     iso_xs = inCharge->GetCrossSection(particle, anElement, aTemp);
                                                   >> 204     elementXS = true;
                                                   >> 205   }
217                                                   206 
218     //---------------------------------------- << 207   cross  += abundVector[i]*iso_xs;
219     // element-wise cross section              << 208   xsec[i] = cross;
220     // isotope cross section is not computed   << 209       }
221     //---------------------------------------- << 210       cross *= G4UniformRand();
222     std::size_t nIso = anElement->GetNumberOfI << 211       for (i = 0; i<nIsoPerElement; i++) {
223     iso = anElement->GetIsotope(0);            << 212   if(cross <= xsec[i]) {
224                                                << 213     AA = G4double((*isoVector)[i]->GetN());
225     // more than 1 isotope                     << 214     break;
226     if(1 < nIso) {                             << 215   }
227       iso = dataSetList[i]->SelectIsotope(anEl << 216       }
228                                           dp-> << 217       delete [] xsec;
229             dp->GetLogKineticEnergy());        << 
230     }                                             218     }
231   } else {                                     << 219     // natural abundances
232                                                << 220   } else { 
233     //---------------------------------------- << 
234     // isotope-wise cross section              << 
235     // isotope cross section is computed       << 
236     //---------------------------------------- << 
237     std::size_t nIso = anElement->GetNumberOfI << 
238     iso = anElement->GetIsotope(0);            << 
239                                                   221 
240     // more than 1 isotope                     << 222     G4StableIsotopes theDefaultIsotopes;  
                                                   >> 223     G4int Z = G4int(ZZ + 0.5);
                                                   >> 224     const G4int nIso = theDefaultIsotopes.GetNumberOfIsotopes(Z);
                                                   >> 225     G4int index = theDefaultIsotopes.GetFirstIsotope(Z);
                                                   >> 226     AA = G4double(theDefaultIsotopes.GetIsotopeNucleonCount(index));
                                                   >> 227     
241     if(1 < nIso) {                                228     if(1 < nIso) {
242       const G4double* abundVector = anElement- << 
243       if(xseciso.size() < nIso) { xseciso.resi << 
244                                                   229 
245       G4double cross = 0.0;                    << 230       G4double* xsec  = new G4double [nIso];
246       G4int j;                                 << 231       G4double iso_xs = 0.0;
247       for (j = 0; j<(G4int)nIso; ++j) {        << 232       G4double cross  = 0.0;
248   G4double xsec = 0.0;                         << 233       G4bool elementXS= false;
249   if(abundVector[j] > 0.0) {                   << 234 
250     iso = anElement->GetIsotope(j);            << 235       for (i = 0; i<nIso; i++) {
251     xsec = abundVector[j]*                     << 236         AA = G4double(theDefaultIsotopes.GetIsotopeNucleonCount(index+i));
252       GetIsoCrossSection(dp, Z, iso->GetN(), i << 237   if (inCharge->IsZAApplicable(particle, ZZ, AA )) {
                                                   >> 238     iso_xs = inCharge->GetIsoZACrossSection(particle, ZZ, AA, aTemp);
                                                   >> 239   } else if (elementXS == false) {
                                                   >> 240     iso_xs = inCharge->GetCrossSection(particle, anElement, aTemp);
                                                   >> 241     elementXS = true;
253   }                                               242   }
254   cross += xsec;                               << 243   cross  += theDefaultIsotopes.GetAbundance(index+i)*iso_xs;
255   xseciso[j] = cross;                          << 244   xsec[i] = cross;
256       }                                           245       }
257       cross *= G4UniformRand();                   246       cross *= G4UniformRand();
258       for (j = 0; j<(G4int)nIso; ++j) {        << 247       for (i = 0; i<nIso; i++) {
259   if(cross <= xseciso[j]) {                    << 248   if(cross <= xsec[i]) {
260     iso = anElement->GetIsotope(j);            << 249     AA = G4double(theDefaultIsotopes.GetIsotopeNucleonCount(index+i));
261     break;                                        250     break;
262   }                                               251   }
263       }                                           252       }
                                                   >> 253       delete [] xsec;
264     }                                             254     }
265   }                                               255   }
266   target.SetIsotope(iso);                      << 256   //G4cout << "XS: " << particle->GetDefinition()->GetParticleName()
                                                   >> 257   //   << " e(GeV)= " << particle->GetKineticEnergy()/GeV
                                                   >> 258   //   << " in " << aMaterial->GetName()
                                                   >> 259   //   << " ZZ= " << ZZ << " AA= " << AA << "  " << anElement->GetName() << G4endl;
                                                   >> 260 
                                                   >> 261   target.SetParameters(AA, ZZ);
267   return anElement;                               262   return anElement;
268 }                                                 263 }
269                                                   264 
270 //....oooOO0OOooo........oooOO0OOooo........oo << 265 /*
                                                   >> 266 G4Element* G4CrossSectionDataStore::SampleZandA(const G4DynamicParticle* particle, 
                                                   >> 267             const G4Material* aMaterial,
                                                   >> 268             G4Nucleus& target)
                                                   >> 269 {
                                                   >> 270   static G4StableIsotopes theDefaultIsotopes;  // natural abundances and 
                                                   >> 271                                                // stable isotopes
                                                   >> 272   G4double aTemp = aMaterial->GetTemperature();
                                                   >> 273   G4int nElements = aMaterial->GetNumberOfElements();
                                                   >> 274   const G4ElementVector* theElementVector = aMaterial->GetElementVector();
                                                   >> 275   const G4double* theAtomsPerVolumeVector = aMaterial->GetVecNbOfAtomsPerVolume();
                                                   >> 276   std::vector<std::vector<G4double> > awicsPerElement;
                                                   >> 277   std::vector<std::vector<G4double> > AvaluesPerElement;
                                                   >> 278   G4Element* anElement;
                                                   >> 279 
                                                   >> 280   // Collect abundance weighted cross sections and A values for each isotope 
                                                   >> 281   // in each element
                                                   >> 282  
                                                   >> 283   for (G4int i = 0; i < nElements; i++) {
                                                   >> 284     anElement = (*theElementVector)[i];
                                                   >> 285     G4int nIsoPerElement = anElement->GetNumberOfIsotopes();
                                                   >> 286     std::vector<G4double> isoholder;
                                                   >> 287     std::vector<G4double> aholder;
                                                   >> 288     G4double iso_xs = DBL_MIN;
                                                   >> 289 
                                                   >> 290     if (nIsoPerElement) { // user-defined isotope abundances
                                                   >> 291       G4IsotopeVector* isoVector = anElement->GetIsotopeVector();
                                                   >> 292       G4double* abundVector = anElement->GetRelativeAbundanceVector();
                                                   >> 293       G4VCrossSectionDataSet* inCharge = whichDataSetInCharge(particle, anElement);
                                                   >> 294       G4bool elementXS = false;
                                                   >> 295       for (G4int j = 0; j < nIsoPerElement; j++) {
                                                   >> 296         if (inCharge->IsZAApplicable(particle, (*isoVector)[j]->GetZ(), 
                                                   >> 297                                                (*isoVector)[j]->GetN() ) ) {
                                                   >> 298           iso_xs = inCharge->GetIsoCrossSection(particle, (*isoVector)[j], aTemp);
                                                   >> 299         } else if (elementXS == false) {
                                                   >> 300           iso_xs = inCharge->GetCrossSection(particle, anElement, aTemp);
                                                   >> 301           elementXS = true;
                                                   >> 302         }
271                                                   303 
272 void                                           << 304         isoholder.push_back(abundVector[j]*iso_xs);
273 G4CrossSectionDataStore::BuildPhysicsTable(con << 305         aholder.push_back(G4double((*isoVector)[j]->GetN()));
274 {                                              << 306       }
275   if (nDataSetList == 0) {                     << 307 
276     G4ExceptionDescription ed;                 << 308     } else { // natural abundances
277     ed << "No cross section is registered for  << 309       G4int ZZ = G4lrint(anElement->GetZ());
278        << part.GetParticleName() << G4endl;    << 310       nIsoPerElement = theDefaultIsotopes.GetNumberOfIsotopes(ZZ);
279     G4Exception("G4CrossSectionDataStore::Buil << 311       G4int index = theDefaultIsotopes.GetFirstIsotope(ZZ);
280                 FatalException, ed);           << 312       G4double AA;
281     return;                                    << 313       G4double abundance;
282   }                                            << 314 
283   matParticle = &part;                         << 315       G4VCrossSectionDataSet* inCharge = whichDataSetInCharge(particle, anElement);
284   for (G4int i=0; i<nDataSetList; ++i) {       << 316       G4bool elementXS = false;
285     dataSetList[i]->BuildPhysicsTable(part);   << 317 
286   }                                            << 318       for (G4int j = 0; j < nIsoPerElement; j++) {
287   const G4MaterialTable* theMatTable = G4Mater << 319         AA = G4double(theDefaultIsotopes.GetIsotopeNucleonCount(index+j));
288   std::size_t nelm = 0;                        << 320         aholder.push_back(AA);
289   std::size_t niso = 0;                        << 321         if (inCharge->IsZAApplicable(particle, G4double(ZZ), AA) ) {
290   for(auto mat : *theMatTable) {               << 322           iso_xs = inCharge->GetIsoZACrossSection(particle, G4double(ZZ), AA, aTemp);
291     std::size_t nElements = mat->GetNumberOfEl << 323         } else if (elementXS == false) {
292     nelm = std::max(nelm, nElements);          << 324           iso_xs = inCharge->GetCrossSection(particle, anElement, aTemp);
293     for(G4int j=0; j<(G4int)nElements; ++j) {  << 325           elementXS = true;
294       niso = std::max(niso, mat->GetElement(j) << 326         }
                                                   >> 327         abundance = theDefaultIsotopes.GetAbundance(index+j)/100.0;
                                                   >> 328         isoholder.push_back(abundance*iso_xs);
                                                   >> 329       }
295     }                                             330     }
                                                   >> 331 
                                                   >> 332     awicsPerElement.push_back(isoholder);
                                                   >> 333     AvaluesPerElement.push_back(aholder);
296   }                                               334   }
297   // define vectors for a run                  << 335 
298   xsecelm.resize(nelm, 0.0);                   << 336   // Calculate running sums for isotope selection
299   xseciso.resize(niso, 0.0);                   << 337 
300 }                                              << 338   G4double crossSectionTotal = 0;
301                                                << 339   G4double xSectionPerElement;
302 //....oooOO0OOooo........oooOO0OOooo........oo << 340   std::vector<G4double> runningSum;
303                                                << 341 
304 void                                           << 342   for (G4int i=0; i < nElements; i++) {
305 G4CrossSectionDataStore::DumpPhysicsTable(cons << 343     xSectionPerElement = 0;
306 {                                              << 344     for (G4int j=0; j < G4int(awicsPerElement[i].size()); j++)
307   // Print out all cross section data sets use << 345                      xSectionPerElement += awicsPerElement[i][j];
308   // which they apply                          << 346     runningSum.push_back(theAtomsPerVolumeVector[i]*xSectionPerElement);
309                                                << 347     crossSectionTotal += runningSum[i];
310   if (nDataSetList == 0) {                     << 348   }
311     G4cout << "WARNING - G4CrossSectionDataSto << 349 
312      << " no data sets registered" << G4endl;  << 350   // Compare random number to running sum over element xc to choose Z
313     return;                                    << 351 
314   }                                            << 352   // Initialize Z and A to first element and first isotope in case 
315                                                << 353   // cross section is zero
316   for (G4int i = nDataSetList-1; i >= 0; --i)  << 354    
317     G4double e1 = dataSetList[i]->GetMinKinEne << 355   anElement = (*theElementVector)[0];
318     G4double e2 = dataSetList[i]->GetMaxKinEne << 356   G4double ZZ = anElement->GetZ();
319     G4cout                                     << 357   G4double AA = AvaluesPerElement[0][0];
320       << "     Cr_sctns: " << std::setw(25) << << 358   if (crossSectionTotal != 0.) {
321       << G4BestUnit(e1, "Energy") << " ---> "  << 359     G4double random = G4UniformRand();
322       << G4BestUnit(e2, "Energy") << "\n";     << 360     for(G4int i=0; i < nElements; i++) {
323     if (dataSetList[i]->GetName() == "G4CrossS << 361       if(i!=0) runningSum[i] += runningSum[i-1];
324       dataSetList[i]->DumpPhysicsTable(part);  << 362       if(random <= runningSum[i]/crossSectionTotal) {
325       G4cout << G4endl;                        << 363   anElement = (*theElementVector)[i];
                                                   >> 364         ZZ = anElement->GetZ();
                                                   >> 365 
                                                   >> 366         // Compare random number to running sum over isotope xc to choose A
                                                   >> 367 
                                                   >> 368         G4int nIso = awicsPerElement[i].size();
                                                   >> 369         G4double* running = new G4double[nIso];
                                                   >> 370         for (G4int j=0; j < nIso; j++) {
                                                   >> 371           running[j] = awicsPerElement[i][j];
                                                   >> 372           if(j!=0) running[j] += running[j-1];
                                                   >> 373         }
                                                   >> 374 
                                                   >> 375         G4double trial = G4UniformRand(); 
                                                   >> 376         for (G4int j=0; j < nIso; j++) {
                                                   >> 377           AA = AvaluesPerElement[i][j];
                                                   >> 378           if (trial <= running[j]/running[nIso-1]) break;
                                                   >> 379         }
                                                   >> 380         delete [] running;
                                                   >> 381         break;
                                                   >> 382       }
326     }                                             383     }
327   }                                               384   }
328 }                                              << 
329                                                   385 
330 //....oooOO0OOooo........oooOO0OOooo........oo << 386   //G4cout << "XS: " << particle->GetDefinition()->GetParticleName()
                                                   >> 387   //   << " e(GeV)= " << particle->GetKineticEnergy()/GeV
                                                   >> 388   //   << " in " << aMaterial->GetName()
                                                   >> 389   //   << " ZZ= " << ZZ << " AA= " << AA << "  " << anElement->GetName() << G4endl;
331                                                   390 
332 void G4CrossSectionDataStore::DumpHtml(const G << 391   target.SetParameters(AA, ZZ);
333                                        std::of << 392   return anElement;
334 {                                              << 393 }
335   // Write cross section data set info to html << 394 */
336   // documentation page                        << 
337                                                   395 
338   G4double ehi = 0;                            << 396 std::pair<G4double, G4double> 
339   G4double elo = 0;                            << 397 G4CrossSectionDataStore::SelectRandomIsotope(const G4DynamicParticle* particle,
340   auto param = G4HadronicParameters::Instance( << 398                                              const G4Material* aMaterial)
341   G4String physListName = param->GetPhysListNa << 399 {
342   G4String dirName = param->GetPhysListDocDir( << 400   static G4StableIsotopes theDefaultIsotopes;  // natural abundances and 
                                                   >> 401                                                // stable isotopes
                                                   >> 402   G4double aTemp = aMaterial->GetTemperature();
                                                   >> 403   G4int nElements = aMaterial->GetNumberOfElements();
                                                   >> 404   const G4ElementVector* theElementVector = aMaterial->GetElementVector();
                                                   >> 405   const G4double* theAtomsPerVolumeVector = aMaterial->GetVecNbOfAtomsPerVolume();
                                                   >> 406   std::vector<std::vector<G4double> > awicsPerElement;
                                                   >> 407   std::vector<std::vector<G4double> > AvaluesPerElement;
                                                   >> 408   G4Element* anElement;
                                                   >> 409 
                                                   >> 410   // Collect abundance weighted cross sections and A values for each isotope 
                                                   >> 411   // in each element
                                                   >> 412  
                                                   >> 413   for (G4int i = 0; i < nElements; i++) {
                                                   >> 414     anElement = (*theElementVector)[i];
                                                   >> 415     G4int nIsoPerElement = anElement->GetNumberOfIsotopes();
                                                   >> 416     std::vector<G4double> isoholder;
                                                   >> 417     std::vector<G4double> aholder;
                                                   >> 418     G4double iso_xs = DBL_MIN;
                                                   >> 419 
                                                   >> 420     if (nIsoPerElement) { // user-defined isotope abundances
                                                   >> 421       G4IsotopeVector* isoVector = anElement->GetIsotopeVector();
                                                   >> 422       G4double* abundVector = anElement->GetRelativeAbundanceVector();
                                                   >> 423       G4VCrossSectionDataSet* inCharge = whichDataSetInCharge(particle, anElement);
                                                   >> 424       G4bool elementXS = false;
                                                   >> 425       for (G4int j = 0; j < nIsoPerElement; j++) {
                                                   >> 426         if (inCharge->IsZAApplicable(particle, (*isoVector)[j]->GetZ(), 
                                                   >> 427                                                (*isoVector)[j]->GetN() ) ) {
                                                   >> 428           iso_xs = inCharge->GetIsoCrossSection(particle, (*isoVector)[j], aTemp);
                                                   >> 429         } else if (elementXS == false) {
                                                   >> 430           iso_xs = inCharge->GetCrossSection(particle, anElement, aTemp);
                                                   >> 431           elementXS = true;
                                                   >> 432         }
343                                                   433 
344   for (G4int i = nDataSetList-1; i > 0; i--) { << 434         isoholder.push_back(abundVector[j]*iso_xs);
345     elo = dataSetList[i]->GetMinKinEnergy()/Ge << 435         aholder.push_back(G4double((*isoVector)[j]->GetN()));
346     ehi = dataSetList[i]->GetMaxKinEnergy()/Ge << 436       }
347     outFile << "      <li><b><a href=\"" << ph << 
348       << dataSetList[i]->GetName() << ".html\" << 
349             << dataSetList[i]->GetName() << "< << 
350             << elo << " GeV to " << ehi << " G << 
351     PrintCrossSectionHtml(dataSetList[i], phys << 
352   }                                            << 
353                                                   437 
354   G4double defaultHi = dataSetList[0]->GetMaxK << 438     } else { // natural abundances
355   if (ehi < defaultHi) {                       << 439       G4int ZZ = G4lrint(anElement->GetZ());
356     outFile << "      <li><b><a href=\"" << da << 440       nIsoPerElement = theDefaultIsotopes.GetNumberOfIsotopes(ZZ);
357       << ".html\"> "                           << 441       G4int index = theDefaultIsotopes.GetFirstIsotope(ZZ);
358             << dataSetList[0]->GetName() << "< << 442       G4double AA;
359             << ehi << " GeV to " << defaultHi  << 443       G4double abundance;
360     PrintCrossSectionHtml(dataSetList[0], phys << 444 
361   }                                            << 445       G4VCrossSectionDataSet* inCharge = whichDataSetInCharge(particle, anElement);
362 }                                              << 446       G4bool elementXS = false;
                                                   >> 447 
                                                   >> 448       for (G4int j = 0; j < nIsoPerElement; j++) {
                                                   >> 449         AA = G4double(theDefaultIsotopes.GetIsotopeNucleonCount(index+j));
                                                   >> 450         aholder.push_back(AA);
                                                   >> 451         if (inCharge->IsZAApplicable(particle, G4double(ZZ), AA) ) {
                                                   >> 452           iso_xs = inCharge->GetIsoZACrossSection(particle, G4double(ZZ), AA, aTemp);
                                                   >> 453         } else if (elementXS == false) {
                                                   >> 454           iso_xs = inCharge->GetCrossSection(particle, anElement, aTemp);
                                                   >> 455           elementXS = true;
                                                   >> 456         }
                                                   >> 457         abundance = theDefaultIsotopes.GetAbundance(index+j)/100.0;
                                                   >> 458         isoholder.push_back(abundance*iso_xs);
                                                   >> 459       }
                                                   >> 460     }
363                                                   461 
364 //....oooOO0OOooo........oooOO0OOooo........oo << 462     awicsPerElement.push_back(isoholder);
                                                   >> 463     AvaluesPerElement.push_back(aholder);
                                                   >> 464   }
365                                                   465 
366 void G4CrossSectionDataStore::PrintCrossSectio << 466   // Calculate running sums for isotope selection
367                                                << 
368                                                << 
369 {                                              << 
370                                                   467 
371   G4String pathName = dirName + "/" + physList << 468   G4double crossSectionTotal = 0;
372   std::ofstream outCS;                         << 469   G4double xSectionPerElement;
373   outCS.open(pathName);                        << 470   std::vector<G4double> runningSum;
374   outCS << "<html>\n";                         << 471 
375   outCS << "<head>\n";                         << 472   for (G4int i=0; i < nElements; i++) {
376   outCS << "<title>Description of " << cs->Get << 473     xSectionPerElement = 0;
377   << "</title>\n";                             << 474     for (G4int j=0; j < G4int(awicsPerElement[i].size()); j++)
378   outCS << "</head>\n";                        << 475                      xSectionPerElement += awicsPerElement[i][j];
379   outCS << "<body>\n";                         << 476     runningSum.push_back(theAtomsPerVolumeVector[i]*xSectionPerElement);
380                                                << 477     crossSectionTotal += runningSum[i];
381   cs->CrossSectionDescription(outCS);          << 478   }
382                                                << 479 
383   outCS << "</body>\n";                        << 480   // Compare random number to running sum over element xc to choose Z
384   outCS << "</html>\n";                        << 481 
                                                   >> 482   // Initialize Z and A to first element and first isotope in case 
                                                   >> 483   // cross section is zero
                                                   >> 484    
                                                   >> 485   G4double ZZ = (*theElementVector)[0]->GetZ();
                                                   >> 486   G4double AA = AvaluesPerElement[0][0];
                                                   >> 487   if (crossSectionTotal != 0.) {
                                                   >> 488     G4double random = G4UniformRand();
                                                   >> 489     for(G4int i=0; i < nElements; i++) {
                                                   >> 490       if(i!=0) runningSum[i] += runningSum[i-1];
                                                   >> 491       if(random <= runningSum[i]/crossSectionTotal) {
                                                   >> 492         ZZ = ((*theElementVector)[i])->GetZ();
                                                   >> 493 
                                                   >> 494         // Compare random number to running sum over isotope xc to choose A
                                                   >> 495 
                                                   >> 496         G4int nIso = awicsPerElement[i].size();
                                                   >> 497         G4double* running = new G4double[nIso];
                                                   >> 498         for (G4int j=0; j < nIso; j++) {
                                                   >> 499           running[j] = awicsPerElement[i][j];
                                                   >> 500           if(j!=0) running[j] += running[j-1];
                                                   >> 501         }
                                                   >> 502 
                                                   >> 503         G4double trial = G4UniformRand(); 
                                                   >> 504         for (G4int j=0; j < nIso; j++) {
                                                   >> 505           AA = AvaluesPerElement[i][j];
                                                   >> 506           if (trial <= running[j]/running[nIso-1]) break;
                                                   >> 507         }
                                                   >> 508         delete [] running;
                                                   >> 509         break;
                                                   >> 510       }
                                                   >> 511     }
                                                   >> 512   }
                                                   >> 513   return std::pair<G4double, G4double>(ZZ, AA);
385 }                                                 514 }
386                                                   515 
387 //....oooOO0OOooo........oooOO0OOooo........oo << 
388                                                   516 
389 G4String G4CrossSectionDataStore::HtmlFileName << 517 void
                                                   >> 518 G4CrossSectionDataStore::AddDataSet(G4VCrossSectionDataSet* aDataSet)
390 {                                                 519 {
391    G4String str(in);                           << 520    if (NDataSetList == NDataSetMax) {
392    // replace blanks by _  C++11 version:      << 521       G4cout << "WARNING: G4CrossSectionDataStore::AddDataSet: "<<G4endl;
393    std::transform(str.begin(), str.end(), str. << 522       G4cout << "         reached maximum number of data sets";
394        return ch == ' ' ? '_' : ch;            << 523       G4cout << "         data set not added !!!!!!!!!!!!!!!!";
395    });                                         << 524       return;
396    str=str + ".html";                          << 525    }
397    return str;                                 << 526    DataSetList[NDataSetList] = aDataSet;
                                                   >> 527    NDataSetList++;
398 }                                                 528 }
399                                                   529 
400 //....oooOO0OOooo........oooOO0OOooo........oo << 
401                                                   530 
402 void G4CrossSectionDataStore::AddDataSet(G4VCr << 531 void
                                                   >> 532 G4CrossSectionDataStore::
                                                   >> 533 BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
403 {                                                 534 {
404   if(p->ForAllAtomsAndEnergies()) {            << 535    if (NDataSetList == 0) 
405     dataSetList.clear();                       << 536    {
406     nDataSetList = 0;                          << 537      G4Exception("G4CrossSectionDataStore", "007", FatalException,
407   }                                            << 538                  "BuildPhysicsTable: no data sets registered");
408   dataSetList.push_back(p);                    << 539      return;
409   ++nDataSetList;                              << 540    }
                                                   >> 541    for (G4int i = NDataSetList-1; i >= 0; i--) {
                                                   >> 542       DataSetList[i]->BuildPhysicsTable(aParticleType);
                                                   >> 543    }
410 }                                                 544 }
411                                                   545 
412 //....oooOO0OOooo........oooOO0OOooo........oo << 
413                                                   546 
414 void G4CrossSectionDataStore::AddDataSet(G4VCr << 547 void
                                                   >> 548 G4CrossSectionDataStore::
                                                   >> 549 DumpPhysicsTable(const G4ParticleDefinition& aParticleType)
415 {                                                 550 {
416   if(p->ForAllAtomsAndEnergies()) {            << 551    if (NDataSetList == 0) {
417     dataSetList.clear();                       << 552       G4cout << "WARNING - G4CrossSectionDataStore::DumpPhysicsTable: no data sets registered"<<G4endl;
418     dataSetList.push_back(p);                  << 553       return;
419     nDataSetList = 1;                          << 554    }
420   } else if ( i >= dataSetList.size() ) {      << 555    for (G4int i = NDataSetList-1; i >= 0; i--) {
421     dataSetList.push_back(p);                  << 556       DataSetList[i]->DumpPhysicsTable(aParticleType);
422     ++nDataSetList;                            << 557    }
423   } else {                                     << 
424     std::vector< G4VCrossSectionDataSet* >::it << 
425     dataSetList.insert(it , p);                << 
426     ++nDataSetList;                            << 
427   }                                            << 
428 }                                                 558 }
429                                                << 
430 //....oooOO0OOooo........oooOO0OOooo........oo << 
431                                                   559