Belle II Software development
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
31using namespace Belle2;
32using 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
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
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
187G4bool 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
339G4double 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
363G4double 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) {
393 } else if (part == m_Positron) {
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) {
405 } else {
406 B2FATAL("EnergyLossForExtrapolator::ComputeEnergy has no table for particle " << part->GetParticleName());
407 }
408 return x;
409}
410
411void 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
459void 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
512void 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
552void 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.