Geant4 Cross Reference

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


  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 //                                                 27 //
 28 // ===========================================     28 // ===========================================================================
 29 // GEANT4 class source file                        29 // GEANT4 class source file
 30 //                                                 30 //
 31 // Class:                G4IonDEDXHandler          31 // Class:                G4IonDEDXHandler
 32 //                                                 32 //
 33 // Author:               Anton Lechner (Anton.     33 // Author:               Anton Lechner (Anton.Lechner@cern.ch)
 34 //                                                 34 //
 35 // First implementation: 11. 03. 2009              35 // First implementation: 11. 03. 2009
 36 //                                                 36 //
 37 // Modifications: 12. 11 .2009 - Function Buil     37 // Modifications: 12. 11 .2009 - Function BuildDEDXTable: Using adapted build
 38 //                               methods of st     38 //                               methods of stopping power classes according
 39 //                               to interface      39 //                               to interface change in G4VIonDEDXTable.
 40 //                               Function Upda     40 //                               Function UpdateCacheValue: Using adapted
 41 //                               ScalingFactor     41 //                               ScalingFactorEnergy function according to
 42 //                               interface cha     42 //                               interface change in G4VIonDEDXScaling-
 43 //                               Algorithm (AL     43 //                               Algorithm (AL)
 44 //                                                 44 //
 45 // Class description:                              45 // Class description:
 46 //    Ion dE/dx table handler.                     46 //    Ion dE/dx table handler.
 47 //                                                 47 //
 48 // Comments:                                       48 // Comments:
 49 //                                                 49 //
 50 // ===========================================     50 // ===========================================================================
 51                                                    51 
 52 #include <iomanip>                                 52 #include <iomanip>
 53                                                    53 
 54 #include "G4IonDEDXHandler.hh"                     54 #include "G4IonDEDXHandler.hh"
 55 #include "G4SystemOfUnits.hh"                      55 #include "G4SystemOfUnits.hh"
 56 #include "G4VIonDEDXTable.hh"                      56 #include "G4VIonDEDXTable.hh"
 57 #include "G4VIonDEDXScalingAlgorithm.hh"           57 #include "G4VIonDEDXScalingAlgorithm.hh"
 58 #include "G4ParticleDefinition.hh"                 58 #include "G4ParticleDefinition.hh"
 59 #include "G4Material.hh"                           59 #include "G4Material.hh"
 60 #include "G4PhysicsFreeVector.hh"                  60 #include "G4PhysicsFreeVector.hh"
 61 #include "G4Exp.hh"                                61 #include "G4Exp.hh"
 62                                                    62 
 63 // ###########################################     63 // #########################################################################
 64                                                    64 
 65 G4IonDEDXHandler::G4IonDEDXHandler(                65 G4IonDEDXHandler::G4IonDEDXHandler(
 66            G4VIonDEDXTable* ionTable,              66            G4VIonDEDXTable* ionTable,
 67            G4VIonDEDXScalingAlgorithm* ionAlgo     67            G4VIonDEDXScalingAlgorithm* ionAlgorithm,
 68            const G4String& name,                   68            const G4String& name,
 69            G4int maxCacheSize,                     69            G4int maxCacheSize,
 70            G4bool splines) :                       70            G4bool splines) :
 71   table(ionTable),                                 71   table(ionTable),
 72   algorithm(ionAlgorithm),                         72   algorithm(ionAlgorithm),
 73   tableName(name),                                 73   tableName(name),
 74   useSplines(splines),                             74   useSplines(splines),
 75   maxCacheEntries(maxCacheSize) {                  75   maxCacheEntries(maxCacheSize) {
 76                                                    76 
 77   if(table == nullptr) {                           77   if(table == nullptr) {
 78      G4cerr << "G4IonDEDXHandler::G4IonDEDXHan     78      G4cerr << "G4IonDEDXHandler::G4IonDEDXHandler() "
 79             << " Pointer to G4VIonDEDXTable ob     79             << " Pointer to G4VIonDEDXTable object is null-pointer."
 80             << G4endl;                             80             << G4endl;
 81   }                                                81   }
 82                                                    82 
 83   if(algorithm == nullptr) {                       83   if(algorithm == nullptr) {
 84      G4cerr << "G4IonDEDXHandler::G4IonDEDXHan     84      G4cerr << "G4IonDEDXHandler::G4IonDEDXHandler() "
 85             << " Pointer to G4VIonDEDXScalingA     85             << " Pointer to G4VIonDEDXScalingAlgorithm object is null-pointer."
 86             << G4endl;                             86             << G4endl;
 87   }                                                87   }
 88                                                    88 
 89   if(maxCacheEntries <= 0) {                       89   if(maxCacheEntries <= 0) {
 90      G4cerr << "G4IonDEDXHandler::G4IonDEDXHan     90      G4cerr << "G4IonDEDXHandler::G4IonDEDXHandler() "
 91             << " Cache size <=0. Resetting to      91             << " Cache size <=0. Resetting to 5."
 92             << G4endl;                             92             << G4endl;
 93      maxCacheEntries = 5;                          93      maxCacheEntries = 5;
 94   }                                                94   }
 95 }                                                  95 }
 96                                                    96 
 97 // ###########################################     97 // #########################################################################
 98                                                    98 
 99 G4IonDEDXHandler::~G4IonDEDXHandler() {            99 G4IonDEDXHandler::~G4IonDEDXHandler() {
100                                                   100 
101   ClearCache();                                   101   ClearCache();
102                                                   102 
103   // All stopping power vectors built accordin    103   // All stopping power vectors built according to Bragg's addivitiy rule
104   // are deleted. All other stopping power vec    104   // are deleted. All other stopping power vectors are expected to be
105   // deleted by their creator class (sub-class    105   // deleted by their creator class (sub-class of G4VIonDEDXTable).
106   // DEDXTableBraggRule::iterator iter = stopp    106   // DEDXTableBraggRule::iterator iter = stoppingPowerTableBragg.begin();
107   // DEDXTableBraggRule::iterator iter_end = s    107   // DEDXTableBraggRule::iterator iter_end = stoppingPowerTableBragg.end();
108                                                   108 
109   //  for(;iter != iter_end; iter++) delete it    109   //  for(;iter != iter_end; iter++) delete iter -> second;
110   stoppingPowerTableBragg.clear();                110   stoppingPowerTableBragg.clear();
111                                                   111 
112   stoppingPowerTable.clear();                     112   stoppingPowerTable.clear();
113                                                   113 
114   if(table != nullptr)                            114   if(table != nullptr) 
115     delete table;                                 115     delete table;
116   if(algorithm != nullptr)                        116   if(algorithm != nullptr) 
117     delete algorithm;                             117     delete algorithm;
118 }                                                 118 }
119                                                   119 
120 // ###########################################    120 // #########################################################################
121                                                   121 
122 G4bool G4IonDEDXHandler::IsApplicable(            122 G4bool G4IonDEDXHandler::IsApplicable(
123                  const G4ParticleDefinition* p    123                  const G4ParticleDefinition* particle,  // Projectile (ion)
124                  const G4Material* material) {    124                  const G4Material* material) {          // Target material
125                                                   125 
126   G4bool isApplicable = true;                     126   G4bool isApplicable = true;
127                                                   127 
128   if(table == nullptr || algorithm == nullptr)    128   if(table == nullptr || algorithm == nullptr) {
129      isApplicable = false;                        129      isApplicable = false;
130   }                                               130   }
131   else {                                          131   else {
132                                                   132 
133      G4int atomicNumberIon = particle -> GetAt    133      G4int atomicNumberIon = particle -> GetAtomicNumber();
134      G4int atomicNumberBase =                     134      G4int atomicNumberBase =
135                 algorithm -> AtomicNumberBaseI    135                 algorithm -> AtomicNumberBaseIon(atomicNumberIon, material);
136                                                   136 
137      G4IonKey key = std::make_pair(atomicNumbe    137      G4IonKey key = std::make_pair(atomicNumberBase, material);
138                                                   138 
139      DEDXTable::iterator iter = stoppingPowerT    139      DEDXTable::iterator iter = stoppingPowerTable.find(key);
140      if(iter == stoppingPowerTable.end()) isAp    140      if(iter == stoppingPowerTable.end()) isApplicable = false;
141   }                                               141   }
142                                                   142 
143   return isApplicable;                            143   return isApplicable;
144 }                                                 144 }
145                                                   145 
146 // ###########################################    146 // #########################################################################
147                                                   147 
148 G4double G4IonDEDXHandler::GetDEDX(               148 G4double G4IonDEDXHandler::GetDEDX(
149                  const G4ParticleDefinition* p    149                  const G4ParticleDefinition* particle,  // Projectile (ion)
150                  const G4Material* material,      150                  const G4Material* material,   // Target material
151                  G4double kineticEnergy) {        151                  G4double kineticEnergy) {     // Kinetic energy of projectile
152                                                   152 
153   G4double dedx = 0.0;                            153   G4double dedx = 0.0;
154                                                   154 
155   G4CacheValue value = GetCacheValue(particle,    155   G4CacheValue value = GetCacheValue(particle, material);
156                                                   156 
157   if(kineticEnergy <= 0.0) dedx = 0.0;            157   if(kineticEnergy <= 0.0) dedx = 0.0;
158   else if(value.dedxVector != 0) {                158   else if(value.dedxVector != 0) {
159                                                   159 
160      G4bool b;                                    160      G4bool b;
161      G4double factor = value.density;             161      G4double factor = value.density;
162                                                   162 
163      factor *= algorithm -> ScalingFactorDEDX(    163      factor *= algorithm -> ScalingFactorDEDX(particle,
164                                              m    164                                              material,
165                                              k    165                                              kineticEnergy);
166      G4double scaledKineticEnergy = kineticEne    166      G4double scaledKineticEnergy = kineticEnergy * value.energyScaling;
167                                                   167 
168      if(scaledKineticEnergy < value.lowerEnerg    168      if(scaledKineticEnergy < value.lowerEnergyEdge) {
169                                                   169 
170         factor *= std::sqrt(scaledKineticEnerg    170         factor *= std::sqrt(scaledKineticEnergy / value.lowerEnergyEdge);
171         scaledKineticEnergy = value.lowerEnerg    171         scaledKineticEnergy = value.lowerEnergyEdge;
172      }                                            172      }
173                                                   173 
174      dedx = factor * value.dedxVector -> GetVa    174      dedx = factor * value.dedxVector -> GetValue(scaledKineticEnergy, b);
175                                                   175 
176      if(dedx < 0.0) dedx = 0.0;                   176      if(dedx < 0.0) dedx = 0.0;
177   }                                               177   }
178   else dedx = 0.0;                                178   else dedx = 0.0;
179                                                   179 
180 #ifdef PRINT_DEBUG                                180 #ifdef PRINT_DEBUG
181      G4cout << "G4IonDEDXHandler::GetDEDX() E     181      G4cout << "G4IonDEDXHandler::GetDEDX() E = "
182             << kineticEnergy / MeV << " MeV *     182             << kineticEnergy / MeV << " MeV * "
183             << value.energyScaling << " = "       183             << value.energyScaling << " = "
184             << kineticEnergy * value.energySca    184             << kineticEnergy * value.energyScaling / MeV
185             << " MeV, dE/dx = " << dedx / MeV     185             << " MeV, dE/dx = " << dedx / MeV * cm << " MeV/cm"
186             << ", material = " << material ->     186             << ", material = " << material -> GetName()
187             << G4endl;                            187             << G4endl;
188 #endif                                            188 #endif
189                                                   189 
190   return dedx;                                    190   return dedx;
191 }                                                 191 }
192                                                   192 
193 // ###########################################    193 // #########################################################################
194                                                   194 
195 G4bool G4IonDEDXHandler::BuildDEDXTable(          195 G4bool G4IonDEDXHandler::BuildDEDXTable(
196                  const G4ParticleDefinition* p    196                  const G4ParticleDefinition* particle,  // Projectile (ion)
197                  const G4Material* material) {    197                  const G4Material* material) {          // Target material
198                                                   198 
199   G4int atomicNumberIon = particle -> GetAtomi    199   G4int atomicNumberIon = particle -> GetAtomicNumber();
200                                                   200 
201   G4bool isApplicable = BuildDEDXTable(atomicN    201   G4bool isApplicable = BuildDEDXTable(atomicNumberIon, material);
202                                                   202 
203   return isApplicable;                            203   return isApplicable;
204 }                                                 204 }
205                                                   205 
206                                                   206 
207 // ###########################################    207 // #########################################################################
208                                                   208 
209 G4bool G4IonDEDXHandler::BuildDEDXTable(          209 G4bool G4IonDEDXHandler::BuildDEDXTable(
210                  G4int atomicNumberIon,           210                  G4int atomicNumberIon,                // Projectile (ion)
211                  const G4Material* material) {    211                  const G4Material* material) {         // Target material
212                                                   212 
213   G4bool isApplicable = true;                     213   G4bool isApplicable = true;
214                                                   214 
215   if(table == 0 || algorithm == 0) {              215   if(table == 0 || algorithm == 0) {
216      isApplicable = false;                        216      isApplicable = false;
217      return isApplicable;                         217      return isApplicable;
218   }                                               218   }
219                                                   219 
220   G4int atomicNumberBase =                        220   G4int atomicNumberBase =
221                 algorithm -> AtomicNumberBaseI    221                 algorithm -> AtomicNumberBaseIon(atomicNumberIon, material);
222                                                   222 
223   // Checking if vector is already built, and     223   // Checking if vector is already built, and returns if this is indeed
224   // the case                                     224   // the case
225   G4IonKey key = std::make_pair(atomicNumberBa    225   G4IonKey key = std::make_pair(atomicNumberBase, material);
226                                                   226 
227   auto iter = stoppingPowerTable.find(key);       227   auto iter = stoppingPowerTable.find(key);
228   if(iter != stoppingPowerTable.end()) return     228   if(iter != stoppingPowerTable.end()) return isApplicable;
229                                                   229 
230   // Checking if table contains stopping power    230   // Checking if table contains stopping power vector for given material name
231   // or chemical formula                          231   // or chemical formula
232   const G4String& chemFormula = material -> Ge    232   const G4String& chemFormula = material -> GetChemicalFormula();
233   const G4String& materialName = material -> G    233   const G4String& materialName = material -> GetName();
234                                                   234 
235   isApplicable = table -> BuildPhysicsVector(a    235   isApplicable = table -> BuildPhysicsVector(atomicNumberBase, chemFormula);
236                                                   236 
237   if(isApplicable) {                              237   if(isApplicable) {
238      stoppingPowerTable[key] =                    238      stoppingPowerTable[key] =
239               table -> GetPhysicsVector(atomic    239               table -> GetPhysicsVector(atomicNumberBase, chemFormula);
240      return isApplicable;                         240      return isApplicable;
241   }                                               241   }
242                                                   242 
243   isApplicable = table -> BuildPhysicsVector(a    243   isApplicable = table -> BuildPhysicsVector(atomicNumberBase, materialName);
244   if(isApplicable) {                              244   if(isApplicable) {
245      stoppingPowerTable[key] =                    245      stoppingPowerTable[key] =
246               table -> GetPhysicsVector(atomic    246               table -> GetPhysicsVector(atomicNumberBase, materialName);
247      return isApplicable;                         247      return isApplicable;
248   }                                               248   }
249                                                   249 
250   // Building the stopping power vector based     250   // Building the stopping power vector based on Bragg's additivity rule
251   const G4ElementVector* elementVector = mater    251   const G4ElementVector* elementVector = material -> GetElementVector() ;
252                                                   252 
253   std::vector<G4PhysicsVector*> dEdxTable;        253   std::vector<G4PhysicsVector*> dEdxTable;
254                                                   254 
255   size_t nmbElements = material -> GetNumberOf    255   size_t nmbElements = material -> GetNumberOfElements();
256                                                   256 
257   for(size_t i = 0; i < nmbElements; i++) {       257   for(size_t i = 0; i < nmbElements; i++) {
258                                                   258 
259       G4int atomicNumberMat = G4int((*elementV    259       G4int atomicNumberMat = G4int((*elementVector)[i] -> GetZ());
260                                                   260 
261       isApplicable = table -> BuildPhysicsVect    261       isApplicable = table -> BuildPhysicsVector(atomicNumberBase, atomicNumberMat);
262                                                   262 
263       if(isApplicable) {                          263       if(isApplicable) {
264                                                   264 
265          G4PhysicsVector* dEdx =                  265          G4PhysicsVector* dEdx =
266                   table -> GetPhysicsVector(at    266                   table -> GetPhysicsVector(atomicNumberBase, atomicNumberMat);
267          dEdxTable.push_back(dEdx);               267          dEdxTable.push_back(dEdx);
268       }                                           268       }
269       else {                                      269       else {
270                                                   270 
271          dEdxTable.clear();                       271          dEdxTable.clear();
272          break;                                   272          break;
273       }                                           273       }
274   }                                               274   }
275                                                   275 
276   if(isApplicable) {                              276   if(isApplicable) {
277                                                   277 
278      if(dEdxTable.size() > 0) {                   278      if(dEdxTable.size() > 0) {
279                                                   279 
280         size_t nmbdEdxBins = dEdxTable[0] -> G    280         size_t nmbdEdxBins = dEdxTable[0] -> GetVectorLength();
281         G4double lowerEdge = dEdxTable[0] -> G    281         G4double lowerEdge = dEdxTable[0] -> GetLowEdgeEnergy(0);
282         G4double upperEdge = dEdxTable[0] -> G    282         G4double upperEdge = dEdxTable[0] -> GetLowEdgeEnergy(nmbdEdxBins-1);
283                                                   283 
284         G4PhysicsFreeVector* dEdxBragg =          284         G4PhysicsFreeVector* dEdxBragg =
285     new G4PhysicsFreeVector(nmbdEdxBins,          285     new G4PhysicsFreeVector(nmbdEdxBins,
286           lowerEdge,                              286           lowerEdge,
287           upperEdge,                              287           upperEdge,
288           useSplines);                            288           useSplines);
289                                                   289 
290         const G4double* massFractionVector = m    290         const G4double* massFractionVector = material -> GetFractionVector();
291                                                   291 
292         G4bool b;                                 292         G4bool b;
293         for(size_t j = 0; j < nmbdEdxBins; j++    293         for(size_t j = 0; j < nmbdEdxBins; j++) {
294                                                   294 
295             G4double edge = dEdxTable[0] -> Ge    295             G4double edge = dEdxTable[0] -> GetLowEdgeEnergy(j);
296                                                   296 
297             G4double value = 0.0;                 297             G4double value = 0.0;
298         for(size_t i = 0; i < nmbElements; i++    298         for(size_t i = 0; i < nmbElements; i++) {
299                                                   299 
300                 value += (dEdxTable[i] -> GetV    300                 value += (dEdxTable[i] -> GetValue(edge ,b)) *
301                                                   301                                                        massFractionVector[i];
302       }                                           302       }
303                                                   303 
304             dEdxBragg -> PutValues(j, edge, va    304             dEdxBragg -> PutValues(j, edge, value);
305   }                                               305   }
306   if (useSplines)                                 306   if (useSplines)
307     dEdxBragg -> FillSecondDerivatives();         307     dEdxBragg -> FillSecondDerivatives();
308                                                   308 
309 #ifdef PRINT_DEBUG                                309 #ifdef PRINT_DEBUG
310         G4cout << "G4IonDEDXHandler::BuildPhys    310         G4cout << "G4IonDEDXHandler::BuildPhysicsVector() for ion with Z="
311                << atomicNumberBase << " in "      311                << atomicNumberBase << " in "
312                << material -> GetName()           312                << material -> GetName()
313                << G4endl;                         313                << G4endl;
314                                                   314 
315         G4cout << *dEdxBragg;                     315         G4cout << *dEdxBragg;
316 #endif                                            316 #endif
317                                                   317 
318   stoppingPowerTable[key] = dEdxBragg;            318   stoppingPowerTable[key] = dEdxBragg;
319   stoppingPowerTableBragg[key] = dEdxBragg;       319   stoppingPowerTableBragg[key] = dEdxBragg;
320      }                                            320      }
321   }                                               321   }
322                                                   322 
323   ClearCache();                                   323   ClearCache();
324                                                   324 
325   return isApplicable;                            325   return isApplicable;
326 }                                                 326 }
327                                                   327 
328 // ###########################################    328 // #########################################################################
329                                                   329 
330 G4CacheValue G4IonDEDXHandler::UpdateCacheValu    330 G4CacheValue G4IonDEDXHandler::UpdateCacheValue(
331               const G4ParticleDefinition* part    331               const G4ParticleDefinition* particle,  // Projectile (ion)
332               const G4Material* material) {       332               const G4Material* material) {          // Target material
333                                                   333 
334   G4CacheValue value;                             334   G4CacheValue value;
335                                                   335 
336   G4int atomicNumberIon = particle -> GetAtomi    336   G4int atomicNumberIon = particle -> GetAtomicNumber();
337   G4int atomicNumberBase =                        337   G4int atomicNumberBase =
338                 algorithm -> AtomicNumberBaseI    338                 algorithm -> AtomicNumberBaseIon(atomicNumberIon, material);
339                                                   339 
340   G4IonKey key = std::make_pair(atomicNumberBa    340   G4IonKey key = std::make_pair(atomicNumberBase, material);
341                                                   341 
342   DEDXTable::iterator iter = stoppingPowerTabl    342   DEDXTable::iterator iter = stoppingPowerTable.find(key);
343                                                   343 
344   if(iter != stoppingPowerTable.end()) {          344   if(iter != stoppingPowerTable.end()) {
345      value.dedxVector = iter -> second;           345      value.dedxVector = iter -> second;
346                                                   346 
347      G4double nmbNucleons = G4double(particle     347      G4double nmbNucleons = G4double(particle -> GetAtomicMass());
348      value.energyScaling =                        348      value.energyScaling =
349            algorithm -> ScalingFactorEnergy(pa    349            algorithm -> ScalingFactorEnergy(particle, material) / nmbNucleons;
350                                                   350 
351      size_t nmbdEdxBins = value.dedxVector ->     351      size_t nmbdEdxBins = value.dedxVector -> GetVectorLength();
352      value.lowerEnergyEdge = value.dedxVector     352      value.lowerEnergyEdge = value.dedxVector -> GetLowEdgeEnergy(0);
353                                                   353 
354      value.upperEnergyEdge =                      354      value.upperEnergyEdge =
355                        value.dedxVector -> Get    355                        value.dedxVector -> GetLowEdgeEnergy(nmbdEdxBins-1);
356      value.density = material -> GetDensity();    356      value.density = material -> GetDensity();
357   }                                               357   }
358   else {                                          358   else {
359      value.dedxVector = 0;                        359      value.dedxVector = 0;
360      value.energyScaling = 0.0;                   360      value.energyScaling = 0.0;
361      value.lowerEnergyEdge = 0.0;                 361      value.lowerEnergyEdge = 0.0;
362      value.upperEnergyEdge = 0.0;                 362      value.upperEnergyEdge = 0.0;
363      value.density = 0.0;                         363      value.density = 0.0;
364   }                                               364   }
365                                                   365 
366 #ifdef PRINT_DEBUG                                366 #ifdef PRINT_DEBUG
367   G4cout << "G4IonDEDXHandler::UpdateCacheValu    367   G4cout << "G4IonDEDXHandler::UpdateCacheValue() for "
368          << particle -> GetParticleName() << "    368          << particle -> GetParticleName() << " in "
369          << material -> GetName()                 369          << material -> GetName()
370          << G4endl;                               370          << G4endl;
371 #endif                                            371 #endif
372                                                   372 
373   return value;                                   373   return value;
374 }                                                 374 }
375                                                   375 
376 // ###########################################    376 // #########################################################################
377                                                   377 
378 G4CacheValue G4IonDEDXHandler::GetCacheValue(     378 G4CacheValue G4IonDEDXHandler::GetCacheValue(
379               const G4ParticleDefinition* part    379               const G4ParticleDefinition* particle,  // Projectile (ion)
380               const G4Material* material) {       380               const G4Material* material) {          // Target material
381                                                   381 
382   G4CacheKey key = std::make_pair(particle, ma    382   G4CacheKey key = std::make_pair(particle, material);
383                                                   383 
384   G4CacheEntry entry;                             384   G4CacheEntry entry;
385   CacheEntryList::iterator* pointerIter =         385   CacheEntryList::iterator* pointerIter =
386                   (CacheEntryList::iterator*)     386                   (CacheEntryList::iterator*) cacheKeyPointers[key];
387                                                   387 
388   if(!pointerIter) {                              388   if(!pointerIter) {
389       entry.value = UpdateCacheValue(particle,    389       entry.value = UpdateCacheValue(particle, material);
390                                                   390 
391       entry.key = key;                            391       entry.key = key;
392       cacheEntries.push_front(entry);             392       cacheEntries.push_front(entry);
393                                                   393 
394       CacheEntryList::iterator* pointerIter1 =    394       CacheEntryList::iterator* pointerIter1 =
395                                    new CacheEn    395                                    new CacheEntryList::iterator();
396       *pointerIter1 = cacheEntries.begin();       396       *pointerIter1 = cacheEntries.begin();
397       cacheKeyPointers[key] = pointerIter1;       397       cacheKeyPointers[key] = pointerIter1;
398                                                   398 
399       if(G4int(cacheEntries.size()) > maxCache    399       if(G4int(cacheEntries.size()) > maxCacheEntries) {
400                                                   400 
401      G4CacheEntry lastEntry = cacheEntries.bac    401      G4CacheEntry lastEntry = cacheEntries.back();
402                                                   402 
403          void* pointerIter2 = cacheKeyPointers    403          void* pointerIter2 = cacheKeyPointers[lastEntry.key];
404          CacheEntryList::iterator* listPointer    404          CacheEntryList::iterator* listPointerIter =
405                           (CacheEntryList::ite    405                           (CacheEntryList::iterator*) pointerIter2;
406                                                   406 
407          cacheEntries.erase(*listPointerIter);    407          cacheEntries.erase(*listPointerIter);
408                                                   408 
409          delete listPointerIter;                  409          delete listPointerIter;
410          cacheKeyPointers.erase(lastEntry.key)    410          cacheKeyPointers.erase(lastEntry.key);
411       }                                           411       }
412   }                                               412   }
413   else {                                          413   else {
414       entry = *(*pointerIter);                    414       entry = *(*pointerIter);
415       // Cache entries are currently not re-or    415       // Cache entries are currently not re-ordered.
416       // Uncomment for activating re-ordering:    416       // Uncomment for activating re-ordering:
417       //      cacheEntries.erase(*pointerIter)    417       //      cacheEntries.erase(*pointerIter);
418       //      cacheEntries.push_front(entry);     418       //      cacheEntries.push_front(entry);
419       //      *pointerIter = cacheEntries.begi    419       //      *pointerIter = cacheEntries.begin();
420   }                                               420   }
421   return entry.value;                             421   return entry.value;
422 }                                                 422 }
423                                                   423 
424 // ###########################################    424 // #########################################################################
425                                                   425 
426 void G4IonDEDXHandler::ClearCache() {             426 void G4IonDEDXHandler::ClearCache() {
427                                                   427 
428   CacheIterPointerMap::iterator iter = cacheKe    428   CacheIterPointerMap::iterator iter = cacheKeyPointers.begin();
429   CacheIterPointerMap::iterator iter_end = cac    429   CacheIterPointerMap::iterator iter_end = cacheKeyPointers.end();
430                                                   430 
431   for(;iter != iter_end; iter++) {                431   for(;iter != iter_end; iter++) {
432       void* pointerIter = iter -> second;         432       void* pointerIter = iter -> second;
433       CacheEntryList::iterator* listPointerIte    433       CacheEntryList::iterator* listPointerIter =
434                           (CacheEntryList::ite    434                           (CacheEntryList::iterator*) pointerIter;
435                                                   435 
436       delete listPointerIter;                     436       delete listPointerIter;
437   }                                               437   }
438                                                   438 
439   cacheEntries.clear();                           439   cacheEntries.clear();
440   cacheKeyPointers.clear();                       440   cacheKeyPointers.clear();
441 }                                                 441 }
442                                                   442 
443 // ###########################################    443 // #########################################################################
444                                                   444 
445 void G4IonDEDXHandler::PrintDEDXTable(            445 void G4IonDEDXHandler::PrintDEDXTable(
446                   const G4ParticleDefinition*     446                   const G4ParticleDefinition* particle,  // Projectile (ion)
447                   const G4Material* material,     447                   const G4Material* material,  // Target material
448                   G4double lowerBoundary,         448                   G4double lowerBoundary,      // Minimum energy per nucleon
449                   G4double upperBoundary,         449                   G4double upperBoundary,      // Maximum energy per nucleon
450                   G4int nmbBins,                  450                   G4int nmbBins,               // Number of bins
451                   G4bool logScaleEnergy) {        451                   G4bool logScaleEnergy) {     // Logarithmic scaling of energy
452                                                   452 
453   G4double atomicMassNumber = particle -> GetA    453   G4double atomicMassNumber = particle -> GetAtomicMass();
454   G4double materialDensity = material -> GetDe    454   G4double materialDensity = material -> GetDensity();
455                                                   455 
456   G4cout << "# dE/dx table for " << particle -    456   G4cout << "# dE/dx table for " << particle -> GetParticleName()
457          << " in material " << material -> Get    457          << " in material " << material -> GetName()
458          << " of density " << materialDensity     458          << " of density " << materialDensity / g * cm3
459          << " g/cm3"                              459          << " g/cm3"
460          << G4endl                                460          << G4endl
461          << "# Projectile mass number A1 = " <    461          << "# Projectile mass number A1 = " << atomicMassNumber
462          << G4endl                                462          << G4endl
463          << "# Energy range (per nucleon) of t    463          << "# Energy range (per nucleon) of tabulation: "
464          << GetLowerEnergyEdge(particle, mater    464          << GetLowerEnergyEdge(particle, material) / atomicMassNumber / MeV
465          << " - "                                 465          << " - "
466          << GetUpperEnergyEdge(particle, mater    466          << GetUpperEnergyEdge(particle, material) / atomicMassNumber / MeV
467          << " MeV"                                467          << " MeV"
468          << G4endl                                468          << G4endl
469          << "# -------------------------------    469          << "# ------------------------------------------------------"
470          << G4endl;                               470          << G4endl;
471   G4cout << "#"                                   471   G4cout << "#"
472          << std::setw(13) << std::right << "E"    472          << std::setw(13) << std::right << "E"
473          << std::setw(14) << "E/A1"               473          << std::setw(14) << "E/A1"
474          << std::setw(14) << "dE/dx"              474          << std::setw(14) << "dE/dx"
475          << std::setw(14) << "1/rho*dE/dx"        475          << std::setw(14) << "1/rho*dE/dx"
476          << G4endl;                               476          << G4endl;
477   G4cout << "#"                                   477   G4cout << "#"
478          << std::setw(13) << std::right << "(M    478          << std::setw(13) << std::right << "(MeV)"
479          << std::setw(14) << "(MeV)"              479          << std::setw(14) << "(MeV)"
480          << std::setw(14) << "(MeV/cm)"           480          << std::setw(14) << "(MeV/cm)"
481          << std::setw(14) << "(MeV*cm2/mg)"       481          << std::setw(14) << "(MeV*cm2/mg)"
482          << G4endl                                482          << G4endl
483          << "# -------------------------------    483          << "# ------------------------------------------------------"
484          << G4endl;                               484          << G4endl;
485                                                   485 
486   //G4CacheValue value = GetCacheValue(particl    486   //G4CacheValue value = GetCacheValue(particle, material);
487                                                   487 
488   G4double energyLowerBoundary = lowerBoundary    488   G4double energyLowerBoundary = lowerBoundary * atomicMassNumber;
489   G4double energyUpperBoundary = upperBoundary    489   G4double energyUpperBoundary = upperBoundary * atomicMassNumber;
490                                                   490 
491   if(logScaleEnergy) {                            491   if(logScaleEnergy) {
492                                                   492 
493      energyLowerBoundary = std::log(energyLowe    493      energyLowerBoundary = std::log(energyLowerBoundary);
494      energyUpperBoundary = std::log(energyUppe    494      energyUpperBoundary = std::log(energyUpperBoundary);
495   }                                               495   }
496                                                   496 
497   G4double deltaEnergy = (energyUpperBoundary     497   G4double deltaEnergy = (energyUpperBoundary - energyLowerBoundary) /
498                                                   498                                                            G4double(nmbBins);
499                                                   499 
500   G4cout.precision(6);                            500   G4cout.precision(6);
501   for(int i = 0; i < nmbBins + 1; i++) {          501   for(int i = 0; i < nmbBins + 1; i++) {
502                                                   502 
503       G4double energy = energyLowerBoundary +     503       G4double energy = energyLowerBoundary + i * deltaEnergy;
504       if(logScaleEnergy) energy = G4Exp(energy    504       if(logScaleEnergy) energy = G4Exp(energy);
505                                                   505 
506       G4double loss = GetDEDX(particle, materi    506       G4double loss = GetDEDX(particle, material, energy);
507                                                   507 
508       G4cout << std::setw(14) << std::right <<    508       G4cout << std::setw(14) << std::right << energy / MeV
509              << std::setw(14) << energy / atom    509              << std::setw(14) << energy / atomicMassNumber / MeV
510              << std::setw(14) << loss / MeV *     510              << std::setw(14) << loss / MeV * cm
511              << std::setw(14) << loss / materi    511              << std::setw(14) << loss / materialDensity / (MeV*cm2/(0.001*g))
512              << G4endl;                           512              << G4endl;
513   }                                               513   }
514 }                                                 514 }
515                                                   515 
516 // ###########################################    516 // #########################################################################
517                                                   517 
518 G4double G4IonDEDXHandler::GetLowerEnergyEdge(    518 G4double G4IonDEDXHandler::GetLowerEnergyEdge(
519                  const G4ParticleDefinition* p    519                  const G4ParticleDefinition* particle,  // Projectile (ion)
520                  const G4Material* material) {    520                  const G4Material* material) {          // Target material
521                                                   521 
522   G4double edge = 0.0;                            522   G4double edge = 0.0;
523                                                   523 
524   G4CacheValue value = GetCacheValue(particle,    524   G4CacheValue value = GetCacheValue(particle, material);
525                                                   525 
526   if(value.energyScaling > 0)                     526   if(value.energyScaling > 0)
527           edge = value.lowerEnergyEdge / value    527           edge = value.lowerEnergyEdge / value.energyScaling;
528                                                   528 
529   return edge;                                    529   return edge;
530 }                                                 530 }
531                                                   531 
532 // ###########################################    532 // #########################################################################
533                                                   533 
534 G4double G4IonDEDXHandler::GetUpperEnergyEdge(    534 G4double G4IonDEDXHandler::GetUpperEnergyEdge(
535                  const G4ParticleDefinition* p    535                  const G4ParticleDefinition* particle,  // Projectile (ion)
536                  const G4Material* material) {    536                  const G4Material* material) {          // Target material
537                                                   537 
538   G4double edge = 0.0;                            538   G4double edge = 0.0;
539                                                   539 
540   G4CacheValue value = GetCacheValue(particle,    540   G4CacheValue value = GetCacheValue(particle, material);
541                                                   541 
542   if(value.energyScaling > 0)                     542   if(value.energyScaling > 0)
543           edge = value.upperEnergyEdge / value    543           edge = value.upperEnergyEdge / value.energyScaling;
544                                                   544 
545   return edge;                                    545   return edge;
546 }                                                 546 }
547                                                   547 
548 // ###########################################    548 // #########################################################################
549                                                   549 
550 G4String G4IonDEDXHandler::GetName() {            550 G4String G4IonDEDXHandler::GetName() {
551                                                   551 
552   return tableName;                               552   return tableName;
553 }                                                 553 }
554                                                   554 
555 // ###########################################    555 // #########################################################################
556                                                   556