LDMX Software
APrimePhysics.cxx
Go to the documentation of this file.
1
9
10#include "G4DarkBreM/G4APrime.h"
11#include "G4DarkBreM/G4DarkBreMModel.h"
12#include "G4DarkBreM/G4FractionallyCharged.h"
13#include "G4EventManager.hh"
14#include "G4ProcessManager.hh"
15#include "SimCore/G4User/UserEventInformation.h"
16
17namespace simcore {
18
19const std::string APrimePhysics::NAME = "APrime";
20
31static void storeElementZ(const G4Element& element) {
32 static_cast<UserEventInformation*>(
33 G4EventManager::GetEventManager()->GetUserInformation())
34 ->setDarkBremMaterialZ(element.GetZ());
35}
36
38 : G4VPhysicsConstructor(APrimePhysics::NAME),
39 parameters_{params},
40 process_{nullptr} {
41 ap_mass_ = parameters_.get<double>("ap_mass", 0.) * MeV;
42 enable_ = parameters_.get<bool>("enable", false);
43 fcp_enable_ = parameters_.get<bool>("fcp_enable", false);
44 fcp_mass_ = parameters_.get<double>("fcp_mass", 0.) * MeV;
45 fcp_charge_ = parameters_.get<double>("fcp_charge", 0.1);
46 fcp_xsec_factor_ = parameters_.get<double>("fcp_xsec_factor", 1.0);
47
48 ldmx_log(info) << "Configuration:" << " A' mass: " << ap_mass_ / MeV << " MeV"
49 << ", Dark brem enabled: " << (enable_ ? "YES" : "NO")
50 << ", FCP enabled: " << (fcp_enable_ ? "YES" : "NO")
51 << ", FCP mass: " << fcp_mass_ / MeV << " MeV"
52 << ", FCP charge: " << fcp_charge_ << " e"
53 << ", FCP xsec factor: " << fcp_xsec_factor_;
54}
55
57 auto model{parameters_.get<framework::config::Parameters>("model")};
58 static const std::map<std::string, G4APrime::DecayMode> decay_lut = {
59 {"no_decay", G4APrime::DecayMode::NoDecay},
60 {"flat_decay", G4APrime::DecayMode::FlatDecay},
61 {"geant_decay", G4APrime::DecayMode::GeantDecay}};
62 auto decay_it{
63 decay_lut.find(model.get<std::string>("decay_mode", "no_decay"))};
64 if (decay_it == decay_lut.end()) {
65 EXCEPTION_RAISE(
66 "BadConf",
67 "Unrecognized decay mode '" + model.get<std::string>("decay_mode") +
68 "',"
69 " options are 'no_decay', 'flat_decay', or 'geant_decay'.");
70 }
71
72 double ap_tau = model.get<double>("ap_tau", -1.0);
73
84 int decay_id = fcp_enable_ ? 17 : 11;
85 ldmx_log(info) << "Initializing A' with:" << ", Mass: " << ap_mass_ / MeV
86 << " MeV" << ", PDG ID: 622" << ", Lifetime (tau): " << ap_tau
87 << ", Decay mode: "
88 << model.get<std::string>("decay_mode", "no_decay")
89 << ", Decay product ID: " << decay_id
90 << (fcp_enable_ ? " (fcp+fcp-)" : " (e+e-)");
91
92 // Initialize the A' with the specified parameters
93 G4APrime::Initialize(ap_mass_, 622, ap_tau, decay_it->second, decay_id);
94
99 if (fcp_enable_) {
100 G4FractionallyCharged::Initialize(fcp_mass_, 17, fcp_charge_);
101 }
102}
103
105 ldmx_log(trace) << "=== APrimePhysics::ConstructProcess ===";
106 // add process to electron if we are enabled
107 if (enable_) {
108 ldmx_log(debug)
109 << "Dark brem is enabled, setting up G4DarkBremsstrahlung...";
110 auto model{parameters_.get<framework::config::Parameters>("model")};
111 auto model_name{model.get<std::string>("name")};
112 if (model_name == "vertex_library" or model_name == "g4db") {
113 static const std::map<std::string, g4db::G4DarkBreMModel::ScalingMethod>
114 method_lut = {
115 {"forward_only",
116 g4db::G4DarkBreMModel::ScalingMethod::ForwardOnly},
117 {"cm_scaling", g4db::G4DarkBreMModel::ScalingMethod::CMScaling},
118 {"undefined", g4db::G4DarkBreMModel::ScalingMethod::Undefined}};
119 auto scaling_method_it{method_lut.find(model.get<std::string>("method"))};
120 if (scaling_method_it == method_lut.end()) {
121 EXCEPTION_RAISE(
122 "BadConf",
123 "Unrecognized scaling method '" + model.get<std::string>("method") +
124 "',"
125 " options are 'forward_only', 'cm_scaling', or 'undefined'.");
126 }
127 // Note: The process variable isn't used here, but creating the
128 // G4DarkBremsstahlung object has side-effects
129 process_ = std::make_unique<G4DarkBremsstrahlung>(
130 std::make_shared<g4db::G4DarkBreMModel>(
131 model.get<std::string>("library_path"),
132 false /* dark brem off muons instead of electrons - we
133 always DB off electrons here */
134 ,
135 model.get<double>("threshold"), model.get<double>("epsilon"),
136 scaling_method_it->second,
137 g4db::G4DarkBreMModel::XsecMethod::Auto,
138 model.get<double>("max_R_for_full", 50.0),
139 model.get<int>("aprime_lhe_id", 1023),
140 true, // always load the library
141 model.get<bool>("scale_APrime", false),
142 model.get<bool>("correct_forward", false),
143 model.get<double>("dist_decay_min", 0.0),
144 model.get<double>("dist_decay_max", 1.0)),
145 parameters_.get<bool>("only_one_per_event"),
146 1., /* global bias - should use bias operator instead */
147 parameters_.get<bool>("cache_xsec"));
148 process_->RegisterStorageMechanism(storeElementZ);
149 } else {
150 EXCEPTION_RAISE("BadConf",
151 "Unrecognized model name '" + model_name + "'.");
152 }
153 ldmx_log(trace) << "Initialization of dark brem complete";
154 }
155
156 // Add A' -> fcp+ fcp- conversion process if enabled
157 if (fcp_enable_) {
158 ldmx_log(debug)
159 << "FCP is enabled, setting up A' -> fcp+ fcp- conversion process...";
160 G4ProcessManager* aprime_proc_man = G4APrime::APrime()->GetProcessManager();
161 if (aprime_proc_man == nullptr) {
162 ldmx_log(error) << "FATAL: Unable to access process manager for A'!";
163 EXCEPTION_RAISE("APrimePhysics",
164 "Was unable to access the process manager for A', "
165 "something is very wrong!");
166 }
167 ldmx_log(debug) << "Creating APrimeConversionToFCPs process...";
169
170 // Apply cross section biasing factor
171 if (fcp_xsec_factor_ != 1.0) {
173 ldmx_log(debug) << "Applied cross section biasing factor: "
175 }
176
177 aprime_proc_man->AddDiscreteProcess(fcp_conversion_process_);
178 aprime_proc_man->SetProcessOrderingToFirst(
179 fcp_conversion_process_, G4ProcessVectorDoItIndex::idxAll);
180 ldmx_log(info)
181 << "A' -> fcp+ fcp- conversion process registered successfully!";
182 } else {
183 ldmx_log(info) << "FCP not enabled, A' conversion process not registered";
184 }
185}
186
187} // namespace simcore
Class which defines basic APrime physics.
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
Discrete process for A' -> fcp+ fcp- conversion in a nuclear field.
void setCrossSecFactor(G4double fac)
Set a factor to artificially scale the cross section.
Defines basic APrime physics.
bool fcp_enable_
is A' -> fcp conversion enabled for this run?
APrimeConversionToFCPs * fcp_conversion_process_
A' -> fcp conversion process (owned by G4 process manager after registration)
G4double fcp_xsec_factor_
cross section biasing factor for A' -> fcp conversion
framework::config::Parameters parameters_
Dark brem parameters to pass to the process (if enabled)
void ConstructParticle()
Construct particle.
G4double ap_mass_
the mass of the A' for this run
static const std::string NAME
The name of this physics constructor.
APrimePhysics(const framework::config::Parameters &params)
Class constructor.
G4double fcp_mass_
mass of the fcp in MeV
bool enable_
is dark brem enabled for this run?
G4double fcp_charge_
charge of the fcp in units of e
void ConstructProcess()
Construct the process.
Encapsulates user defined information associated with a Geant4 event.
Dynamically loadable photonuclear models either from SimCore or external libraries implementing this ...
static void storeElementZ(const G4Element &element)
Store the atomic Z for the element in which the dark brem occurred.