LDMX Software
KaonPhysics.cxx
1#include "SimCore/KaonPhysics.h"
2
3#include <G4DecayTable.hh>
4#include <G4KaonMinus.hh>
5#include <G4KaonPlus.hh>
6#include <G4KaonZeroLong.hh>
7#include <G4KaonZeroShort.hh>
8#include <iomanip>
9#include <iostream>
10
11#include "Framework/Exception/Exception.h"
12
13namespace simcore {
14KaonPhysics::KaonPhysics(const G4String& name,
15 const framework::config::Parameters& parameters)
16 : G4VPhysicsConstructor(name) {
17 kplus_branching_ratios_ =
18 parameters.get<std::vector<double>>("kplus_branching_ratios");
19 kminus_branching_ratios_ =
20 parameters.get<std::vector<double>>("kminus_branching_ratios");
21 k0l_branching_ratios_ =
22 parameters.get<std::vector<double>>("k0l_branching_ratios");
23 k0s_branching_ratios_ =
24 parameters.get<std::vector<double>>("k0s_branching_ratios");
25 kplus_lifetime_factor_ = parameters.get<double>("kplus_lifetime_factor");
26 kminus_lifetime_factor_ = parameters.get<double>("kminus_lifetime_factor");
27 k0l_lifetime_factor_ = parameters.get<double>("k0l_lifetime_factor");
28 k0s_lifetime_factor_ = parameters.get<double>("k0s_lifetime_factor");
29}
30void KaonPhysics::setDecayProperties(
31 G4ParticleDefinition* kaon, const std::vector<double>& branching_ratios,
32 double lifetime_factor) const {
33 auto table{kaon->GetDecayTable()};
34 if (!table) {
35 EXCEPTION_RAISE("KaonPhysics", "Unable to get the decay table from " +
36 kaon->GetParticleName());
37 }
38 ldmx_log(trace) << "Decay details (" << kaon->GetParticleName()
39 << ") before setting branching ratios and lifetimes";
40 dumpDecayDetails(kaon);
41 kaon->SetPDGLifeTime(kaon->GetPDGLifeTime() * lifetime_factor);
42 if (kaon == G4KaonZeroLong::Definition()) {
43 (*table)[KaonZeroLongDecayChannel::pi0_pi0_pi0]->SetBR(
44 branching_ratios[KaonZeroLongDecayChannel::pi0_pi0_pi0]);
45 (*table)[KaonZeroLongDecayChannel::pi0_pip_pim]->SetBR(
46 branching_ratios[KaonZeroLongDecayChannel::pi0_pip_pim]);
47 (*table)[KaonZeroLongDecayChannel::pip_e_nu]->SetBR(
48 branching_ratios[KaonZeroLongDecayChannel::pip_e_nu]);
49 (*table)[KaonZeroLongDecayChannel::pim_e_nu]->SetBR(
50 branching_ratios[KaonZeroLongDecayChannel::pim_e_nu]);
51 (*table)[KaonZeroLongDecayChannel::pim_mu_nu]->SetBR(
52 branching_ratios[KaonZeroLongDecayChannel::pim_mu_nu]);
53 (*table)[KaonZeroLongDecayChannel::pip_mu_nu]->SetBR(
54 branching_ratios[KaonZeroLongDecayChannel::pip_mu_nu]);
55 } else if (kaon == G4KaonZeroShort::Definition()) {
56 (*table)[KaonZeroShortDecayChannel::pip_pim]->SetBR(
57 branching_ratios[KaonZeroShortDecayChannel::pip_pim]);
58 (*table)[KaonZeroShortDecayChannel::pi0_pi0]->SetBR(
59 branching_ratios[KaonZeroShortDecayChannel::pi0_pi0]);
60 } else {
61 (*table)[ChargedKaonDecayChannel::mu_nu]->SetBR(
62 branching_ratios[ChargedKaonDecayChannel::mu_nu]);
63 (*table)[ChargedKaonDecayChannel::pi_pi0]->SetBR(
64 branching_ratios[ChargedKaonDecayChannel::pi_pi0]);
65 (*table)[ChargedKaonDecayChannel::pi_pi_pi]->SetBR(
66 branching_ratios[ChargedKaonDecayChannel::pi_pi_pi]);
67 (*table)[ChargedKaonDecayChannel::pi_pi0_pi0]->SetBR(
68 branching_ratios[ChargedKaonDecayChannel::pi_pi0_pi0]);
69 (*table)[ChargedKaonDecayChannel::pi0_e_nu]->SetBR(
70 branching_ratios[ChargedKaonDecayChannel::pi0_e_nu]);
71 (*table)[ChargedKaonDecayChannel::pi0_mu_nu]->SetBR(
72 branching_ratios[ChargedKaonDecayChannel::pi0_mu_nu]);
73 }
74 ldmx_log(trace) << "Decay details (" << kaon->GetParticleName()
75 << ") after setting branching ratios and lifetimes"
76 << std::endl;
77 dumpDecayDetails(kaon);
78}
79void KaonPhysics::ConstructParticle() {
80 auto kaon_plus{G4KaonPlus::Definition()};
81 auto kaon_minus{G4KaonMinus::Definition()};
82 auto kaon_long{G4KaonZeroLong::Definition()};
83 auto kaon_short{G4KaonZeroShort::Definition()};
84
85 if (!kaon_plus || !kaon_minus || !kaon_long || !kaon_short) {
86 EXCEPTION_RAISE("KaonPhysics",
87 "Unable to get the charged kaon particle definitions, "
88 "something is very wrong with the configuration.");
89 }
90 setDecayProperties(kaon_plus, kplus_branching_ratios_,
91 kplus_lifetime_factor_);
92 setDecayProperties(kaon_minus, kminus_branching_ratios_,
93 kminus_lifetime_factor_);
94 setDecayProperties(kaon_long, k0l_branching_ratios_, k0l_lifetime_factor_);
95 setDecayProperties(kaon_short, k0s_branching_ratios_, k0s_lifetime_factor_);
96}
97
98void KaonPhysics::dumpDecayDetails(const G4ParticleDefinition* kaon) const {
99 ldmx_log(trace) << "Decay table details for " << kaon->GetParticleName()
100 << std::scientific << std::setprecision(15)
101 << " (PDG Lifetime " << kaon->GetPDGLifeTime() << ")"
102 << std::endl;
103 auto* table{kaon->GetDecayTable()};
104 if (not table) {
105 ldmx_log(error) << "No Kaon decay table.";
106 return;
107 }
108 const int entries{table->entries()};
109 for (auto i{0}; i < entries; ++i) {
110 const auto channel{(*table)[i]};
111 const auto daughters{channel->GetNumberOfDaughters()};
112 std::string products{};
113 // N-1 to avoid extra " + "
114 for (auto j{0}; j < daughters; ++j) {
115 auto* d{channel->GetDaughter(j)};
116 if (d) {
117 products += d->GetParticleName();
118 } else {
119 products += "NULL";
120 }
121 if (j < daughters - 1) {
122 // only add '+' when there are more to come
123 products += " + ";
124 }
125 }
126 ldmx_log(trace) << "Channel " << i << " (" << kaon->GetParticleName()
127 << " -> " << products << ") Kinematics type "
128 << channel->GetKinematicsName() << " with BR "
129 << channel->GetBR() << std::endl;
130 }
131}
132
133} // namespace simcore
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:26
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:75
Dynamically loadable photonuclear models either from SimCore or external libraries implementing this ...