9 #include <simulation/kernel/EnergyLossForExtrapolator.h>
11 #include <CLHEP/Units/PhysicalConstants.h>
12 #include <CLHEP/Units/SystemOfUnits.h>
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 <G4Version.hh>
23 #if G4VERSION_NUMBER < 1001
24 #include <G4eBremsstrahlungModel.hh>
26 #include <G4eBremsstrahlungRelModel.hh>
28 #include <G4MuPairProductionModel.hh>
29 #include <G4MuBremsstrahlungModel.hh>
30 #include <G4ProductionCuts.hh>
31 #include <G4LossTableManager.hh>
32 #include <G4WentzelVIModel.hh>
34 #include <framework/logging/Logger.h>
37 using namespace Belle2::Simulation;
52 m_AntiProton(nullptr),
54 m_AntiDeuteron(nullptr),
55 m_ProductionCuts(nullptr),
56 m_DedxElectron(nullptr),
57 m_DedxPositron(nullptr),
61 m_DedxProton(nullptr),
62 m_DedxDeuteron(nullptr),
63 m_RangeElectron(nullptr),
64 m_RangePositron(nullptr),
68 m_RangeProton(nullptr),
69 m_RangeDeuteron(nullptr),
70 m_InvRangeElectron(nullptr),
71 m_InvRangePositron(nullptr),
72 m_InvRangeMuon(nullptr),
73 m_InvRangePion(nullptr),
74 m_InvRangeKaon(nullptr),
75 m_InvRangeProton(nullptr),
76 m_InvRangeDeuteron(nullptr),
77 m_MscatElectron(nullptr),
90 m_UserTmin(1.*CLHEP::MeV),
91 m_UserTmax(10.*CLHEP::TeV),
92 m_UserMaxEnergyTransfer(DBL_MAX),
127 for (
const G4MaterialCutsCouple* couple :
m_Couples)
delete couple;
135 const G4Material* mat,
136 const G4ParticleDefinition* part)
139 G4double kinEnergyFinal = kinEnergy;
144 kinEnergyFinal = 0.0;
146 kinEnergyFinal -= step *
ComputeDEDX(kinEnergy, part);
148 G4double r1 = r - step;
152 return kinEnergyFinal;
159 const G4Material* mat,
160 const G4ParticleDefinition* part)
163 G4double kinEnergyFinal = kinEnergy;
170 kinEnergyFinal += step *
ComputeDEDX(kinEnergy, part);
172 G4double r1 = r + step;
176 return kinEnergyFinal;
183 const G4Material* mat,
184 const G4ParticleDefinition* part)
186 G4double res = stepLength;
191 if (x < 0.2) res *= (1.0 + 0.5 * x + x * x / 3.0);
192 else if (x < 0.9999) res = -std::log(1.0 - x) * stepLength / x;
205 const G4Material* mat,
208 if (!part || !mat || kinEnergy < CLHEP::keV)
return false;
214 m_Mass = part->GetPDGMass();
215 G4double q = part->GetPDGCharge() / CLHEP::eplus;
219 G4int i = mat->GetIndex();
221 B2WARNING(
"EnergyLossForExtrapolator: index i= " << i <<
" is out of table - NO extrapolation");
232 G4double tau = kinEnergy /
m_Mass;
240 G4double r = CLHEP::electron_mass_c2 /
m_Mass;
253 B2DEBUG(10,
"EnergyLossForExtrapolator::Initialisation");
258 m_Electron = G4ParticleTable::GetParticleTable()->FindParticle(
"g4e_e-");
259 m_Positron = G4ParticleTable::GetParticleTable()->FindParticle(
"g4e_e+");
260 m_MuonPlus = G4ParticleTable::GetParticleTable()->FindParticle(
"g4e_mu+");
261 m_MuonMinus = G4ParticleTable::GetParticleTable()->FindParticle(
"g4e_mu-");
262 m_PionPlus = G4ParticleTable::GetParticleTable()->FindParticle(
"g4e_pi+");
263 m_PionMinus = G4ParticleTable::GetParticleTable()->FindParticle(
"g4e_pi-");
264 m_KaonPlus = G4ParticleTable::GetParticleTable()->FindParticle(
"g4e_kaon+");
265 m_KaonMinus = G4ParticleTable::GetParticleTable()->FindParticle(
"g4e_kaon-");
266 m_Proton = G4ParticleTable::GetParticleTable()->FindParticle(
"g4e_proton");
267 m_AntiProton = G4ParticleTable::GetParticleTable()->FindParticle(
"g4e_anti_proton");
268 m_Deuteron = G4ParticleTable::GetParticleTable()->FindParticle(
"g4e_deuteron");
269 m_AntiDeuteron = G4ParticleTable::GetParticleTable()->FindParticle(
"g4e_anti_deuteron");
272 const G4MaterialTable* mtable = G4Material::GetMaterialTable();
305 G4LossTableBuilder& builder = *(G4LossTableManager::Instance()->GetTableBuilder());
307 B2DEBUG(10,
"EnergyLossForExtrapolator Builds electron tables");
312 B2DEBUG(10,
"EnergyLossForExtrapolator Builds positron tables");
317 B2DEBUG(10,
"EnergyLossForExtrapolator Builds muon tables");
322 B2DEBUG(10,
"EnergyLossForExtrapolator Builds pion tables");
327 B2DEBUG(10,
"EnergyLossForExtrapolator Builds kaon tables");
332 B2DEBUG(10,
"EnergyLossForExtrapolator Builds proton tables");
337 B2DEBUG(10,
"EnergyLossForExtrapolator Builds deuteron tables");
349 G4PhysicsTable* table =
new G4PhysicsTable();
363 const G4ParticleDefinition* part)
381 B2FATAL(
"EnergyLossForExtrapolator::ComputeDEDX has no table for particle " << part->GetParticleName());
389 const G4ParticleDefinition* part)
407 B2FATAL(
"EnergyLossForExtrapolator::ComputeRange has no table for particle " << part->GetParticleName());
415 const G4ParticleDefinition* part)
433 B2FATAL(
"EnergyLossForExtrapolator::ComputeEnergy has no table for particle " << part->GetParticleName());
441 G4PhysicsTable* table)
443 G4MollerBhabhaModel* ioni =
new G4MollerBhabhaModel();
444 #if G4VERSION_NUMBER < 1001
445 G4eBremsstrahlungModel* brem =
new G4eBremsstrahlungModel();
447 G4eBremsstrahlungRelModel* brem =
new G4eBremsstrahlungRelModel();
449 G4ParticleChange* ioniPC =
new G4ParticleChange();
450 ioni->SetParticleChange(ioniPC);
451 G4ParticleChange* bremPC =
new G4ParticleChange();
452 brem->SetParticleChange(bremPC);
454 ioni->Initialise(part,
m_Cuts);
455 brem->Initialise(part,
m_Cuts);
457 m_Mass = CLHEP::electron_mass_c2;
461 B2DEBUG(1,
"EnergyLossForExtrapolator::ComputeElectronDEDX for " << part->GetParticleName());
465 B2DEBUG(10,
"EnergyLossForExtrapolator::ComputeElectronDEDX(): i= " << i <<
" mat= " <<
466 (*G4Material::GetMaterialTable())[i]->GetName());
467 const G4MaterialCutsCouple* couple =
m_Couples[i];
468 G4PhysicsVector* aVector = (*table)[i];
470 for (G4int j = 0; j <=
m_Nbins; j++) {
472 G4double e = aVector->Energy(j);
473 G4double dedx = ioni->ComputeDEDX(couple, part, e, e) +
474 brem->ComputeDEDX(couple, part, e, e);
475 B2DEBUG(10,
"EnergyLossForExtrapolator::ComputeElectronDEDX(): j= " << j
476 <<
" e(MeV)= " << e / CLHEP::MeV
477 <<
" dedx(Mev/cm)= " << dedx * CLHEP::cm / CLHEP::MeV
478 <<
" dedx(Mev.cm2/g)= "
479 << dedx / ((CLHEP::MeV * (*G4Material::GetMaterialTable())[i]->GetDensity()) / (CLHEP::g / CLHEP::cm2)));
480 aVector->PutValue(j, dedx);
482 aVector->FillSecondDerivatives();
484 delete ioni;
delete ioniPC;
485 delete brem;
delete bremPC;
491 G4PhysicsTable* table)
493 G4BetheBlochModel* ioni =
new G4BetheBlochModel();
494 G4MuPairProductionModel* pair =
new G4MuPairProductionModel();
495 G4MuBremsstrahlungModel* brem =
new G4MuBremsstrahlungModel();
497 G4ParticleChange* ioniPC =
new G4ParticleChange();
498 ioni->SetParticleChange(ioniPC);
499 G4ParticleChange* pairPC =
new G4ParticleChange();
500 pair->SetParticleChange(pairPC);
501 G4ParticleChange* bremPC =
new G4ParticleChange();
502 brem->SetParticleChange(bremPC);
504 ioni->Initialise(part,
m_Cuts);
505 pair->Initialise(part,
m_Cuts);
506 brem->Initialise(part,
m_Cuts);
508 m_Mass = part->GetPDGMass();
512 B2DEBUG(1,
"EnergyLossForExtrapolator::ComputeMuonDEDX for " << part->GetParticleName());
516 B2DEBUG(10,
"EnergyLossForExtrapolator::ComputeMuonDEDX(): i= " << i <<
" mat= " <<
517 (*G4Material::GetMaterialTable())[i]->GetName());
518 const G4MaterialCutsCouple* couple =
m_Couples[i];
519 G4PhysicsVector* aVector = (*table)[i];
520 for (G4int j = 0; j <=
m_Nbins; j++) {
522 G4double e = aVector->Energy(j);
523 G4double dedx = ioni->ComputeDEDX(couple, part, e, e) +
524 pair->ComputeDEDX(couple, part, e, e) +
525 brem->ComputeDEDX(couple, part, e, e);
526 aVector->PutValue(j, dedx);
527 B2DEBUG(10,
"EnergyLossForExtrapolator::ComputeMuonDEDX(): j= " << j
528 <<
" e(MeV)= " << e / CLHEP::MeV
529 <<
" dedx(Mev/cm)= " << dedx * CLHEP::cm / CLHEP::MeV
530 <<
" dedx(Mev/(g/cm2)= "
531 << dedx / ((CLHEP::MeV * (*G4Material::GetMaterialTable())[i]->GetDensity()) / (CLHEP::g / CLHEP::cm2)));
533 aVector->FillSecondDerivatives();
535 delete ioni;
delete ioniPC;
536 delete pair;
delete pairPC;
537 delete brem;
delete bremPC;
543 G4PhysicsTable* table)
545 G4BetheBlochModel* ioni =
new G4BetheBlochModel();
546 G4ParticleChange* ioniPC =
new G4ParticleChange();
547 ioni->SetParticleChange(ioniPC);
548 ioni->Initialise(part,
m_Cuts);
550 m_Mass = part->GetPDGMass();
551 double q = part->GetPDGCharge() / CLHEP::eplus;
555 B2DEBUG(1,
"EnergyLossForExtrapolator::ComputeHadronDEDX for " << part->GetParticleName());
559 B2DEBUG(10,
"EnergyLossForExtrapolator::ComputeHadronDEDX(): i= " << i <<
" mat= " <<
560 (*G4Material::GetMaterialTable())[i]->GetName());
561 const G4MaterialCutsCouple* couple =
m_Couples[i];
562 G4PhysicsVector* aVector = (*table)[i];
563 for (G4int j = 0; j <=
m_Nbins; j++) {
565 G4double e = aVector->Energy(j);
566 G4double dedx = ioni->ComputeDEDX(couple, part, e, e);
567 aVector->PutValue(j, dedx);
568 B2DEBUG(10,
"EnergyLossForExtrapolator::ComputeHadronDEDX(): j= " << j
569 <<
" e(MeV)= " << e / CLHEP::MeV
570 <<
" dedx(Mev/cm)= " << dedx * CLHEP::cm / CLHEP::MeV
571 <<
" dedx(Mev.cm2/g)= "
572 << dedx / (((*G4Material::GetMaterialTable())[i]->GetDensity()) / (CLHEP::g / CLHEP::cm2)));
574 aVector->FillSecondDerivatives();
576 delete ioni;
delete ioniPC;
582 G4PhysicsTable* table)
584 G4WentzelVIModel* msc =
new G4WentzelVIModel();
585 G4ParticleChange* mscPC =
new G4ParticleChange();
586 msc->SetParticleChange(mscPC);
587 msc->SetPolarAngleLimit(CLHEP::pi);
588 msc->Initialise(part,
m_Cuts);
590 m_Mass = part->GetPDGMass();
591 double q = part->GetPDGCharge() / CLHEP::eplus;
595 const G4MaterialTable* mtable = G4Material::GetMaterialTable();
596 B2DEBUG(1,
"EnergyLossForExtrapolator::ComputeTransportXS for " << part->GetParticleName());
600 const G4Material* mat = (*mtable)[i];
602 B2DEBUG(10,
"EnergyLossForExtrapolator::ComputeTransportXS(): i= " << i <<
" mat= " << mat->GetName());
603 G4PhysicsVector* aVector = (*table)[i];
604 for (G4int j = 0; j <=
m_Nbins; j++) {
606 G4double e = aVector->Energy(j);
607 G4double xs = msc->CrossSectionPerVolume(mat, part, e);
608 aVector->PutValue(j, xs);
609 B2DEBUG(10,
"EnergyLossForExtrapolator::ComputeTransportXS(): j= " << j <<
" e(MeV)= " << e / CLHEP::MeV
610 <<
" xs(1/mm)= " << xs * CLHEP::mm);
612 aVector->FillSecondDerivatives();
614 delete msc;
delete mscPC;
Abstract base class for different kinds of events.