Belle II Software  release-08-01-10
EnergyLossForExtrapolator.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <simulation/kernel/EnergyLossForExtrapolator.h>
10 
11 #include <CLHEP/Units/PhysicalConstants.h>
12 #include <CLHEP/Units/SystemOfUnits.h>
13 
14 #include <G4PhysicsLogVector.hh>
15 #include <G4ParticleDefinition.hh>
16 #include <G4Material.hh>
17 #include <G4MaterialCutsCouple.hh>
18 #include <G4ParticleTable.hh>
19 #include <G4LossTableBuilder.hh>
20 #include <G4MollerBhabhaModel.hh>
21 #include <G4BetheBlochModel.hh>
22 #include <G4eBremsstrahlungRelModel.hh>
23 #include <G4MuPairProductionModel.hh>
24 #include <G4MuBremsstrahlungModel.hh>
25 #include <G4ProductionCuts.hh>
26 #include <G4LossTableManager.hh>
27 #include <G4WentzelVIModel.hh>
28 
29 #include <framework/logging/Logger.h>
30 
31 using namespace Belle2;
32 using namespace Belle2::Simulation;
33 
35  m_Particle(nullptr),
36  m_Electron(nullptr),
37  m_Positron(nullptr),
38  m_MuonPlus(nullptr),
39  m_MuonMinus(nullptr),
40  m_PionPlus(nullptr),
41  m_PionMinus(nullptr),
42  m_KaonPlus(nullptr),
43  m_KaonMinus(nullptr),
44  m_Proton(nullptr),
45  m_AntiProton(nullptr),
46  m_Deuteron(nullptr),
47  m_AntiDeuteron(nullptr),
48  m_ProductionCuts(nullptr),
49  m_DedxElectron(nullptr),
50  m_DedxPositron(nullptr),
51  m_DedxMuon(nullptr),
52  m_DedxPion(nullptr),
53  m_DedxKaon(nullptr),
54  m_DedxProton(nullptr),
55  m_DedxDeuteron(nullptr),
56  m_RangeElectron(nullptr),
57  m_RangePositron(nullptr),
58  m_RangeMuon(nullptr),
59  m_RangePion(nullptr),
60  m_RangeKaon(nullptr),
61  m_RangeProton(nullptr),
62  m_RangeDeuteron(nullptr),
63  m_InvRangeElectron(nullptr),
64  m_InvRangePositron(nullptr),
65  m_InvRangeMuon(nullptr),
66  m_InvRangePion(nullptr),
67  m_InvRangeKaon(nullptr),
68  m_InvRangeProton(nullptr),
69  m_InvRangeDeuteron(nullptr),
70  m_MscatElectron(nullptr),
71  m_Material(nullptr),
72  m_MaterialIndex(0),
73  m_ElectronDensity(0),
74  m_RadLength(0),
75  m_Mass(0),
76  m_ChargeSq(0),
77  m_KineticEnergy(0),
78  m_Gamma(1.0),
79  m_BetaGammaSq(0),
80  m_BetaSq(0),
81  m_Tmax(0),
82  m_LinLossLimit(0.01),
83  m_UserTmin(1.*CLHEP::MeV),
84  m_UserTmax(10.*CLHEP::TeV),
85  m_UserMaxEnergyTransfer(DBL_MAX),
86  m_Nbins(70),
87  m_NMaterials(0),
88  m_Initialised(false)
89 {
91 }
92 
94 {
95  m_DedxElectron->clearAndDestroy(); delete m_DedxElectron;
96  m_DedxPositron->clearAndDestroy(); delete m_DedxPositron;
97  m_DedxMuon->clearAndDestroy(); delete m_DedxMuon;
98  m_DedxPion->clearAndDestroy(); delete m_DedxPion;
99  m_DedxKaon->clearAndDestroy(); delete m_DedxKaon;
100  m_DedxProton->clearAndDestroy(); delete m_DedxProton;
101  m_DedxDeuteron->clearAndDestroy(); delete m_DedxDeuteron;
102  m_RangeElectron->clearAndDestroy(); delete m_RangeElectron;
103  m_RangePositron->clearAndDestroy(); delete m_RangePositron;
104  m_RangeMuon->clearAndDestroy(); delete m_RangeMuon;
105  m_RangePion->clearAndDestroy(); delete m_RangePion;
106  m_RangeKaon->clearAndDestroy(); delete m_RangeKaon;
107  m_RangeProton->clearAndDestroy(); delete m_RangeProton;
108  m_RangeDeuteron->clearAndDestroy(); delete m_RangeDeuteron;
109  m_InvRangeElectron->clearAndDestroy(); delete m_InvRangeElectron;
110  m_InvRangePositron->clearAndDestroy(); delete m_InvRangePositron;
111  m_InvRangeMuon->clearAndDestroy(); delete m_InvRangeMuon;
112  m_InvRangePion->clearAndDestroy(); delete m_InvRangePion;
113  m_InvRangeKaon->clearAndDestroy(); delete m_InvRangeKaon;
114  m_InvRangeProton->clearAndDestroy(); delete m_InvRangeProton;
115  m_InvRangeDeuteron->clearAndDestroy(); delete m_InvRangeDeuteron;
116  m_MscatElectron->clearAndDestroy(); delete m_MscatElectron;
117  delete m_ProductionCuts;
118  for (const G4MaterialCutsCouple* couple : m_Couples) delete couple;
119  m_Couples.clear();
120 }
121 
122 G4double EnergyLossForExtrapolator::EnergyAfterStep(G4double kinEnergy,
123  G4double stepLength,
124  const G4Material* mat,
125  const G4ParticleDefinition* part)
126 {
127  //- if (!isInitialised) Initialisation();
128  G4double kinEnergyFinal = kinEnergy;
129  if (SetupKinematics(part, mat, kinEnergy)) {
130  G4double step = TrueStepLength(kinEnergy, stepLength, mat, part);
131  G4double r = ComputeRange(kinEnergy, part);
132  if (r <= step) {
133  kinEnergyFinal = 0.0;
134  } else if (step < m_LinLossLimit * r) {
135  kinEnergyFinal -= step * ComputeDEDX(kinEnergy, part);
136  } else {
137  G4double r1 = r - step;
138  kinEnergyFinal = ComputeEnergy(r1, part);
139  }
140  }
141  return kinEnergyFinal;
142 }
143 
145  G4double stepLength,
146  const G4Material* mat,
147  const G4ParticleDefinition* part)
148 {
149  //- if (!isInitialised) Initialisation();
150  G4double kinEnergyFinal = kinEnergy;
151 
152  if (SetupKinematics(part, mat, kinEnergy)) {
153  G4double step = TrueStepLength(kinEnergy, stepLength, mat, part);
154  G4double r = ComputeRange(kinEnergy, part);
155 
156  if (step < m_LinLossLimit * r) {
157  kinEnergyFinal += step * ComputeDEDX(kinEnergy, part);
158  } else {
159  G4double r1 = r + step;
160  kinEnergyFinal = ComputeEnergy(r1, part);
161  }
162  }
163  return kinEnergyFinal;
164 }
165 
166 G4double EnergyLossForExtrapolator::TrueStepLength(G4double kinEnergy,
167  G4double stepLength,
168  const G4Material* mat,
169  const G4ParticleDefinition* part)
170 {
171  G4double res = stepLength;
172  //- if (!isInitialised) Initialisation();
173  if (SetupKinematics(part, mat, kinEnergy)) {
174  if (part == m_Electron || part == m_Positron) {
175  G4double x = stepLength * ComputeValue(kinEnergy, m_MscatElectron);
176  if (x < 0.2) res *= (1.0 + 0.5 * x + x * x / 3.0);
177  else if (x < 0.9999) res = -std::log(1.0 - x) * stepLength / x;
178  else res = ComputeRange(kinEnergy, part);
179 
180  } else {
181  res = ComputeTrueStep(mat, part, kinEnergy, stepLength);
182  }
183  }
184  return res;
185 }
186 
187 G4bool EnergyLossForExtrapolator::SetupKinematics(const G4ParticleDefinition* part,
188  const G4Material* mat,
189  G4double kinEnergy)
190 {
191  if (!part || !mat || kinEnergy < CLHEP::keV) return false;
192  //- if (!isInitialised) Initialisation();
193  G4bool flag = false;
194  if (part != m_Particle) {
195  flag = true;
196  m_Particle = part;
197  m_Mass = part->GetPDGMass();
198  G4double q = part->GetPDGCharge() / CLHEP::eplus;
199  m_ChargeSq = q * q;
200  }
201  if (mat != m_Material) {
202  G4int i = mat->GetIndex();
203  if (i >= m_NMaterials) {
204  B2WARNING("EnergyLossForExtrapolator: index i= " << i << " is out of table - NO extrapolation");
205  } else {
206  flag = true;
207  m_Material = mat;
208  m_ElectronDensity = mat->GetElectronDensity();
209  m_RadLength = mat->GetRadlen();
210  m_MaterialIndex = i;
211  }
212  }
213  if (flag || kinEnergy != m_KineticEnergy) {
214  m_KineticEnergy = kinEnergy;
215  G4double tau = kinEnergy / m_Mass;
216 
217  m_Gamma = tau + 1.0;
218  m_BetaGammaSq = tau * (tau + 2.0);
220  m_Tmax = kinEnergy;
221  if (part == m_Electron) m_Tmax *= 0.5;
222  else if (part != m_Positron) {
223  G4double r = CLHEP::electron_mass_c2 / m_Mass;
224  m_Tmax = 2.0 * m_BetaGammaSq * CLHEP::electron_mass_c2 / (1.0 + 2.0 * m_Gamma * r + r * r);
225  }
227  }
228  return true;
229 }
230 
232 {
233  m_Initialised = true;
234  B2DEBUG(20, "EnergyLossForExtrapolator::Initialisation");
235  m_Particle = 0;
236  m_Material = 0;
237  m_KineticEnergy = 0.0;
238 
239  m_Electron = G4ParticleTable::GetParticleTable()->FindParticle("g4e_e-");
240  m_Positron = G4ParticleTable::GetParticleTable()->FindParticle("g4e_e+");
241  m_MuonPlus = G4ParticleTable::GetParticleTable()->FindParticle("g4e_mu+");
242  m_MuonMinus = G4ParticleTable::GetParticleTable()->FindParticle("g4e_mu-");
243  m_PionPlus = G4ParticleTable::GetParticleTable()->FindParticle("g4e_pi+");
244  m_PionMinus = G4ParticleTable::GetParticleTable()->FindParticle("g4e_pi-");
245  m_KaonPlus = G4ParticleTable::GetParticleTable()->FindParticle("g4e_kaon+");
246  m_KaonMinus = G4ParticleTable::GetParticleTable()->FindParticle("g4e_kaon-");
247  m_Proton = G4ParticleTable::GetParticleTable()->FindParticle("g4e_proton");
248  m_AntiProton = G4ParticleTable::GetParticleTable()->FindParticle("g4e_anti_proton");
249  m_Deuteron = G4ParticleTable::GetParticleTable()->FindParticle("g4e_deuteron");
250  m_AntiDeuteron = G4ParticleTable::GetParticleTable()->FindParticle("g4e_anti_deuteron");
251 
252  m_NMaterials = G4Material::GetNumberOfMaterials();
253  const G4MaterialTable* mtable = G4Material::GetMaterialTable();
254  m_ProductionCuts = new G4ProductionCuts();
255 
256  m_Couples.resize(m_NMaterials, 0);
257  m_Cuts.resize(m_NMaterials, DBL_MAX);
258 
259  for (G4int i = 0; i < m_NMaterials; i++) {
260  m_Couples[i] = new G4MaterialCutsCouple((*mtable)[i], m_ProductionCuts);
261  }
262 
285 
286  G4LossTableBuilder& builder = *(G4LossTableManager::Instance()->GetTableBuilder());
287  builder.SetBaseMaterialActive(false);
288 
289  B2DEBUG(20, "EnergyLossForExtrapolator Builds electron tables");
291  builder.BuildRangeTable(m_DedxElectron, m_RangeElectron);
292  builder.BuildInverseRangeTable(m_RangeElectron, m_InvRangeElectron);
293 
294  B2DEBUG(20, "EnergyLossForExtrapolator Builds positron tables");
296  builder.BuildRangeTable(m_DedxPositron, m_RangePositron);
297  builder.BuildInverseRangeTable(m_RangePositron, m_InvRangePositron);
298 
299  B2DEBUG(20, "EnergyLossForExtrapolator Builds muon tables");
301  builder.BuildRangeTable(m_DedxMuon, m_RangeMuon);
302  builder.BuildInverseRangeTable(m_RangeMuon, m_InvRangeMuon);
303 
304  B2DEBUG(20, "EnergyLossForExtrapolator Builds pion tables");
306  builder.BuildRangeTable(m_DedxPion, m_RangePion);
307  builder.BuildInverseRangeTable(m_RangePion, m_InvRangePion);
308 
309  B2DEBUG(20, "EnergyLossForExtrapolator Builds kaon tables");
311  builder.BuildRangeTable(m_DedxKaon, m_RangeKaon);
312  builder.BuildInverseRangeTable(m_RangeKaon, m_InvRangeKaon);
313 
314  B2DEBUG(20, "EnergyLossForExtrapolator Builds proton tables");
316  builder.BuildRangeTable(m_DedxProton, m_RangeProton);
317  builder.BuildInverseRangeTable(m_RangeProton, m_InvRangeProton);
318 
319  B2DEBUG(20, "EnergyLossForExtrapolator Builds deuteron tables");
321  builder.BuildRangeTable(m_DedxDeuteron, m_RangeDeuteron);
322  builder.BuildInverseRangeTable(m_RangeDeuteron, m_InvRangeDeuteron);
323 
325 }
326 
328 {
329  G4PhysicsTable* table = new G4PhysicsTable();
330 
331  for (G4int i = 0; i < m_NMaterials; i++) {
332 
333  G4PhysicsVector* v = new G4PhysicsLogVector(m_UserTmin, m_UserTmax, m_Nbins, true);
334  table->push_back(v);
335  }
336  return table;
337 }
338 
339 G4double EnergyLossForExtrapolator::ComputeDEDX(G4double kinEnergy,
340  const G4ParticleDefinition* part)
341 {
342  G4double x = 0.0;
343  if (part == m_Electron) {
344  x = ComputeValue(kinEnergy, m_DedxElectron);
345  } else if (part == m_Positron) {
346  x = ComputeValue(kinEnergy, m_DedxPositron);
347  } else if (part == m_MuonPlus || part == m_MuonMinus) {
348  x = ComputeValue(kinEnergy, m_DedxMuon);
349  } else if (part == m_PionPlus || part == m_PionMinus) {
350  x = ComputeValue(kinEnergy, m_DedxPion);
351  } else if (part == m_KaonPlus || part == m_KaonMinus) {
352  x = ComputeValue(kinEnergy, m_DedxKaon);
353  } else if (part == m_Proton || part == m_AntiProton) {
354  x = ComputeValue(kinEnergy, m_DedxProton);
355  } else if (part == m_Deuteron || part == m_AntiDeuteron) {
356  x = ComputeValue(kinEnergy, m_DedxDeuteron);
357  } else {
358  B2FATAL("EnergyLossForExtrapolator::ComputeDEDX has no table for particle " << part->GetParticleName());
359  }
360  return x;
361 }
362 
363 G4double EnergyLossForExtrapolator::ComputeRange(G4double kinEnergy,
364  const G4ParticleDefinition* part)
365 {
366  G4double x = 0.0;
367  if (part == m_Electron) {
368  x = ComputeValue(kinEnergy, m_RangeElectron);
369  } else if (part == m_Positron) {
370  x = ComputeValue(kinEnergy, m_RangePositron);
371  } else if (part == m_MuonPlus || part == m_MuonMinus) {
372  x = ComputeValue(kinEnergy, m_RangeMuon);
373  } else if (part == m_PionPlus || part == m_PionMinus) {
374  x = ComputeValue(kinEnergy, m_RangePion);
375  } else if (part == m_KaonPlus || part == m_KaonMinus) {
376  x = ComputeValue(kinEnergy, m_RangeKaon);
377  } else if (part == m_Proton || part == m_AntiProton) {
378  x = ComputeValue(kinEnergy, m_RangeProton);
379  } else if (part == m_Deuteron || part == m_AntiDeuteron) {
380  x = ComputeValue(kinEnergy, m_RangeDeuteron);
381  } else {
382  B2FATAL("EnergyLossForExtrapolator::ComputeRange has no table for particle " << part->GetParticleName());
383  }
384  return x;
385 }
386 
388  const G4ParticleDefinition* part)
389 {
390  G4double x = 0.0;
391  if (part == m_Electron) {
392  x = ComputeValue(range, m_InvRangeElectron);
393  } else if (part == m_Positron) {
394  x = ComputeValue(range, m_InvRangePositron);
395  } else if (part == m_MuonPlus || part == m_MuonMinus) {
396  x = ComputeValue(range, m_InvRangeMuon);
397  } else if (part == m_PionPlus || part == m_PionMinus) {
398  x = ComputeValue(range, m_InvRangePion);
399  } else if (part == m_KaonPlus || part == m_KaonMinus) {
400  x = ComputeValue(range, m_InvRangeKaon);
401  } else if (part == m_Proton || part == m_AntiProton) {
402  x = ComputeValue(range, m_InvRangeProton);
403  } else if (part == m_Deuteron || part == m_AntiDeuteron) {
404  x = ComputeValue(range, m_InvRangeDeuteron);
405  } else {
406  B2FATAL("EnergyLossForExtrapolator::ComputeEnergy has no table for particle " << part->GetParticleName());
407  }
408  return x;
409 }
410 
411 void EnergyLossForExtrapolator::ComputeElectronDEDX(const G4ParticleDefinition* part,
412  G4PhysicsTable* table)
413 {
414  G4MollerBhabhaModel* ioni = new G4MollerBhabhaModel();
415  G4eBremsstrahlungRelModel* brem = new G4eBremsstrahlungRelModel();
416  G4ParticleChange* ioniPC = new G4ParticleChange();
417  ioni->SetParticleChange(ioniPC);
418  G4ParticleChange* bremPC = new G4ParticleChange();
419  brem->SetParticleChange(bremPC);
420  ioni->Initialise(part, m_Cuts);
421  brem->Initialise(part, m_Cuts);
422  m_Mass = CLHEP::electron_mass_c2;
423  m_ChargeSq = 1.0;
424  m_Particle = part;
425  B2DEBUG(20, "EnergyLossForExtrapolator::ComputeElectronDEDX"
426  << LogVar("particle", part->GetParticleName())
427  );
428  for (G4int i = 0; i < m_NMaterials; i++) {
429  const G4MaterialCutsCouple* couple = m_Couples[i];
430  const G4Material* material = couple->GetMaterial();
431  // Let's check this at run time (only in ComputeElectronDEDX: it's not necessary to always check this)
432  assert((*G4Material::GetMaterialTable())[i] == material);
433  B2DEBUG(20, "EnergyLossForExtrapolator::ComputeElectronDEDX()"
434  << LogVar("material index", i)
435  << LogVar("material name", material->GetName())
436  << LogVar("density [g/cm3]", material->GetDensity() * CLHEP::cm3 / CLHEP::g)
437  );
438  G4PhysicsVector* aVector = (*table)[i];
439  for (G4int j = 0; j <= m_Nbins; j++) {
440  G4double e = aVector->Energy(j);
441  G4double dedx = ioni->ComputeDEDXPerVolume(material, part, e, e)
442  + brem->ComputeDEDXPerVolume(material, part, e, e);
443  B2DEBUG(20, "EnergyLossForExtrapolator::ComputeElectronDEDX()"
444  << LogVar("bin", j)
445  << LogVar("energy [MeV]", e / CLHEP::MeV)
446  << LogVar("dE/dx [Mev/cm]", dedx * CLHEP::cm / CLHEP::MeV)
447  << LogVar("dE/dx [Mev/(g/cm2)]", dedx / ((CLHEP::MeV * material->GetDensity()) / (CLHEP::g / CLHEP::cm2)))
448  );
449  aVector->PutValue(j, dedx);
450  }
451  aVector->FillSecondDerivatives();
452  }
453  delete ioni;
454  delete ioniPC;
455  delete brem;
456  delete bremPC;
457 }
458 
459 void EnergyLossForExtrapolator::ComputeMuonDEDX(const G4ParticleDefinition* part,
460  G4PhysicsTable* table)
461 {
462  G4BetheBlochModel* ioni = new G4BetheBlochModel();
463  G4MuPairProductionModel* pair = new G4MuPairProductionModel();
464  G4MuBremsstrahlungModel* brem = new G4MuBremsstrahlungModel();
465  G4ParticleChange* ioniPC = new G4ParticleChange();
466  ioni->SetParticleChange(ioniPC);
467  G4ParticleChange* pairPC = new G4ParticleChange();
468  pair->SetParticleChange(pairPC);
469  G4ParticleChange* bremPC = new G4ParticleChange();
470  brem->SetParticleChange(bremPC);
471  ioni->Initialise(part, m_Cuts);
472  pair->Initialise(part, m_Cuts);
473  brem->Initialise(part, m_Cuts);
474  m_Mass = part->GetPDGMass();
475  m_ChargeSq = 1.0;
476  m_Particle = part;
477  B2DEBUG(20, "EnergyLossForExtrapolator::ComputeMuonDEDX"
478  << LogVar("particle", part->GetParticleName())
479  );
480  for (G4int i = 0; i < m_NMaterials; i++) {
481  const G4MaterialCutsCouple* couple = m_Couples[i];
482  const G4Material* material = couple->GetMaterial();
483  B2DEBUG(20, "EnergyLossForExtrapolator::ComputeMuonDEDX()"
484  << LogVar("material index", i)
485  << LogVar("material name", material->GetName())
486  << LogVar("density [g/cm3]", material->GetDensity() * CLHEP::cm3 / CLHEP::g)
487  );
488  G4PhysicsVector* aVector = (*table)[i];
489  for (G4int j = 0; j <= m_Nbins; j++) {
490  G4double e = aVector->Energy(j);
491  G4double dedx = ioni->ComputeDEDXPerVolume(material, part, e, e)
492  + pair->ComputeDEDXPerVolume(material, part, e, e)
493  + brem->ComputeDEDXPerVolume(material, part, e, e);
494  aVector->PutValue(j, dedx);
495  B2DEBUG(20, "EnergyLossForExtrapolator::ComputeMuonDEDX()"
496  << LogVar("bin", j)
497  << LogVar("energy [MeV]", e / CLHEP::MeV)
498  << LogVar("dE/dx [Mev/cm]", dedx * CLHEP::cm / CLHEP::MeV)
499  << LogVar("dE/dx [Mev/(g/cm2)]", dedx / ((CLHEP::MeV * material->GetDensity()) / (CLHEP::g / CLHEP::cm2)))
500  );
501  }
502  aVector->FillSecondDerivatives();
503  }
504  delete ioni;
505  delete ioniPC;
506  delete pair;
507  delete pairPC;
508  delete brem;
509  delete bremPC;
510 }
511 
512 void EnergyLossForExtrapolator::ComputeHadronDEDX(const G4ParticleDefinition* part,
513  G4PhysicsTable* table)
514 {
515  G4BetheBlochModel* ioni = new G4BetheBlochModel();
516  G4ParticleChange* ioniPC = new G4ParticleChange();
517  ioni->SetParticleChange(ioniPC);
518  ioni->Initialise(part, m_Cuts);
519  m_Mass = part->GetPDGMass();
520  double q = part->GetPDGCharge() / CLHEP::eplus;
521  m_ChargeSq = q * q;
522  m_Particle = part;
523  B2DEBUG(20, "EnergyLossForExtrapolator::ComputeHadronDEDX"
524  << LogVar("particle", part->GetParticleName())
525  );
526  for (G4int i = 0; i < m_NMaterials; i++) {
527  const G4MaterialCutsCouple* couple = m_Couples[i];
528  const G4Material* material = couple->GetMaterial();
529  B2DEBUG(20, "EnergyLossForExtrapolator::ComputeHadronDEDX()"
530  << LogVar("material index", i)
531  << LogVar("material name", material->GetName())
532  << LogVar("density [g/cm3]", material->GetDensity() * CLHEP::cm3 / CLHEP::g)
533  );
534  G4PhysicsVector* aVector = (*table)[i];
535  for (G4int j = 0; j <= m_Nbins; j++) {
536  G4double e = aVector->Energy(j);
537  G4double dedx = ioni->ComputeDEDXPerVolume(material, part, e, e);
538  aVector->PutValue(j, dedx);
539  B2DEBUG(20, "EnergyLossForExtrapolator::ComputeHadronDEDX()"
540  << LogVar("bin", j)
541  << LogVar("energy [MeV]", e / CLHEP::MeV)
542  << LogVar("dE/dx [Mev/cm]", dedx * CLHEP::cm / CLHEP::MeV)
543  << LogVar("dE/dx [Mev/(g/cm2)]", dedx / ((CLHEP::MeV * material->GetDensity()) / (CLHEP::g / CLHEP::cm2)))
544  );
545  }
546  aVector->FillSecondDerivatives();
547  }
548  delete ioni;
549  delete ioniPC;
550 }
551 
552 void EnergyLossForExtrapolator::ComputeTransportXS(const G4ParticleDefinition* part,
553  G4PhysicsTable* table)
554 {
555  G4WentzelVIModel* msc = new G4WentzelVIModel();
556  G4ParticleChange* mscPC = new G4ParticleChange();
557  msc->SetParticleChange(mscPC);
558  msc->SetPolarAngleLimit(CLHEP::pi);
559  msc->Initialise(part, m_Cuts);
560  m_Mass = part->GetPDGMass();
561  double q = part->GetPDGCharge() / CLHEP::eplus;
562  m_ChargeSq = q * q;
563  m_Particle = part;
564  const G4MaterialTable* mtable = G4Material::GetMaterialTable();
565  B2DEBUG(20, "EnergyLossForExtrapolator::ComputeTransportXS"
566  << LogVar("particle", part->GetParticleName())
567  );
568  for (G4int i = 0; i < m_NMaterials; i++) {
569  const G4Material* material = (*mtable)[i];
570  msc->SetCurrentCouple(m_Couples[i]);
571  B2DEBUG(20, "EnergyLossForExtrapolator::ComputeTransportXS()"
572  << LogVar("material index", i)
573  << LogVar("material name", material->GetName())
574  );
575  G4PhysicsVector* aVector = (*table)[i];
576  for (G4int j = 0; j <= m_Nbins; j++) {
577  G4double e = aVector->Energy(j);
578  G4double xs = msc->CrossSectionPerVolume(material, part, e);
579  aVector->PutValue(j, xs);
580  B2DEBUG(20, "EnergyLossForExtrapolator::ComputeTransportXS()"
581  << LogVar("bin", j)
582  << LogVar("energy [MeV]", e / CLHEP::MeV)
583  << LogVar("xs [1/mm]", xs * CLHEP::mm)
584  );
585  }
586  aVector->FillSecondDerivatives();
587  }
588  delete msc;
589  delete mscPC;
590 }
591 
const G4ParticleDefinition * m_Particle
Pointer to definition of the currently cached particle.
const G4ParticleDefinition * m_KaonPlus
Pointer to definition of the positive kaon.
G4PhysicsTable * m_DedxPion
Pointer to the pion's specific ionization energy loss vs KE table.
void Initialisation()
Initialize tables used to calculate energy loss, fluctuation, and scattering for electrons,...
G4PhysicsTable * m_DedxPositron
Pointer to the positron's specific ionization energy loss vs KE table.
G4double m_RadLength
Cached material radiation length.
void ComputeTransportXS(const G4ParticleDefinition *part, G4PhysicsTable *table)
Fill the table with the multiple-scattering cross section of a particle.
G4double m_KineticEnergy
Cached particle kinetic energy.
G4PhysicsTable * m_MscatElectron
Pointer to the electron's multiple-scattering cross section vs KE table.
G4PhysicsTable * PrepareTable()
Create a new table to store one type of kinematics data for a particle.
G4double m_UserMaxEnergyTransfer
User's upper limit on maximum kinetic-energy loss (default infinity)
G4PhysicsTable * m_InvRangeKaon
Pointer to the kaon's inverse-range vs KE table.
G4PhysicsTable * m_RangePositron
Pointer to the positron's range vs KE table.
G4PhysicsTable * m_DedxMuon
Pointer to the muon's specific ionization energy loss vs KE table.
G4int m_Nbins
Number of bins in each energy loss, fluctuation, and multiple-scattering table (70,...
G4PhysicsTable * m_RangeProton
Pointer to the proton's range vs KE table.
G4PhysicsTable * m_DedxKaon
Pointer to the kaon's specific ionization energy loss vs KE table.
G4PhysicsTable * m_InvRangeElectron
Pointer to the electron's inverse-range vs KE table.
const G4ParticleDefinition * m_MuonMinus
Pointer to definition of the negative muon.
G4double ComputeDEDX(G4double kinEnergy, const G4ParticleDefinition *)
Get specific ionization energy loss for the given kinetic energy and particle.
G4double m_ChargeSq
Cached charge-squared (in units of e)
G4PhysicsTable * m_RangeKaon
Pointer to the kaon's range vs KE table.
void ComputeElectronDEDX(const G4ParticleDefinition *part, G4PhysicsTable *table)
Fill the table with the specific ionization energy loss of an electron.
const G4ParticleDefinition * m_Electron
Pointer to definition of the electron.
G4double m_Tmax
Cached particle's maximum kinetic-energy loss.
G4double m_ElectronDensity
Cached material electron density.
G4double m_LinLossLimit
Step-length limit in units of range (0.01); not modifiable by user.
G4PhysicsTable * m_RangePion
Pointer to the pion's range vs KE table.
G4double EnergyAfterStep(G4double kinEnergy, G4double step, const G4Material *, const G4ParticleDefinition *)
Get kinetic energy after a step in given material by given particle.
G4double m_Gamma
Cached particle's gamma value.
const G4ParticleDefinition * m_AntiDeuteron
Pointer to definition of the antideuteron.
G4PhysicsTable * m_DedxProton
Pointer to the proton's specific ionization energy loss vs KE table.
const G4ParticleDefinition * m_Proton
Pointer to definition of the proton.
G4PhysicsTable * m_InvRangeDeuteron
Pointer to the deuteron's inverse-range vs KE table.
G4PhysicsTable * m_InvRangePositron
Pointer to the positron's inverse-range vs KE table.
G4double TrueStepLength(G4double kinEnergy, G4double step, const G4Material *, const G4ParticleDefinition *part)
Get true step length for given particle and kinetic energy.
const G4ParticleDefinition * m_AntiProton
Pointer to definition of the antiproton.
G4bool m_Initialised
UNUSED Flag to indicate that Initialisation() method has been called.
G4PhysicsTable * m_InvRangeMuon
Pointer to the muon's inverse-range vs KE table.
const G4ParticleDefinition * m_KaonMinus
Pointer to definition of the negative kaon.
const G4Material * m_Material
Pointer to internally cached material.
G4PhysicsTable * m_RangeElectron
Pointer to the electron's range vs KE table.
const G4ParticleDefinition * m_PionMinus
Pointer to definition of the negative pion.
void ComputeHadronDEDX(const G4ParticleDefinition *part, G4PhysicsTable *table)
Fill the table with the specific ionization energy loss of a hadron.
G4PhysicsTable * m_InvRangePion
Pointer to the pion's inverse-range vs KE table.
G4PhysicsTable * m_InvRangeProton
Pointer to the proton's inverse-range vs KE table.
void ComputeMuonDEDX(const G4ParticleDefinition *part, G4PhysicsTable *table)
Fill the table with the specific ionization energy loss of a muon.
G4PhysicsTable * m_DedxElectron
Pointer to the electron's specific ionization energy loss vs KE table.
G4double ComputeEnergy(G4double range, const G4ParticleDefinition *)
Get kinetic energy corresponding to the given range and particle.
EnergyLossForExtrapolator()
Constructor (WITHOUT GEANT4 verbosity flag)
const G4ParticleDefinition * m_Deuteron
Pointer to definition of the deuteron.
const G4ParticleDefinition * m_MuonPlus
Pointer to definition of the positive muon.
G4double ComputeValue(G4double x, const G4PhysicsTable *table)
Get the tabulated energy-loss, fluctuation, or scattering value for the given input.
G4bool SetupKinematics(const G4ParticleDefinition *, const G4Material *, G4double kinEnergy)
Save current particle properties, kinetic energy and material in internal cached state.
G4PhysicsTable * m_RangeMuon
Pointer to the muon's range vs KE table.
G4double m_UserTmin
User's minimum kinetic energy for particles (default 1 MeV)
G4double ComputeTrueStep(const G4Material *, const G4ParticleDefinition *part, G4double kinEnergy, G4double stepLength)
Get average scattering angle after a step in given material by given particle.
G4double EnergyBeforeStep(G4double kinEnergy, G4double step, const G4Material *, const G4ParticleDefinition *)
Get kinetic energy before a step in given material by given particle.
G4PhysicsTable * m_DedxDeuteron
Pointer to the deuteron's specific ionization energy loss vs KE table.
G4int m_NMaterials
Number of materials in current geometry.
std::vector< const G4MaterialCutsCouple * > m_Couples
List of material-cuts pairings.
G4double m_BetaSq
Cached particle's beta squared.
const G4ParticleDefinition * m_Positron
Pointer to definition of the positron.
G4double ComputeRange(G4double kinEnergy, const G4ParticleDefinition *)
Get range for the given kinetic energy and particle.
G4PhysicsTable * m_RangeDeuteron
Pointer to the deuteron's range vs KE table.
const G4ParticleDefinition * m_PionPlus
Pointer to definition of the positive pion.
G4ProductionCuts * m_ProductionCuts
Pointer to the internal cache of default G4ProductionCuts.
G4double m_UserTmax
User's maximum kinetic energy for particles (default 10 TeV)
G4double m_BetaGammaSq
Cached particle's beta*gamma squared.
Class to store variables with their name which were sent to the logging service.
Abstract base class for different kinds of events.