LDMX Software
simcore::generators::GenieGenerator Class Reference

Class that uses GENIE's GEVGDriver to generator eN interactions. More...

#include <GenieGenerator.h>

Public Member Functions

 GenieGenerator (const std::string &name, const framework::config::Parameters &parameters)
 Constructor.
 
 ~GenieGenerator ()
 Destructor.
 
void GeneratePrimaryVertex (G4Event *event) final override
 Generate the primary vertices in the Geant4 event.
 
void RecordConfig (const std::string &id, ldmx::RunHeader &rh) final override
 Record the configuration of the primary generator into the run header.
 
- Public Member Functions inherited from simcore::PrimaryGenerator
 PrimaryGenerator (const std::string &name, const framework::config::Parameters &parameters)
 Constructor.
 
 DECLARE_FACTORY_WITH_WAREHOUSE (PrimaryGenerator, std::shared_ptr< PrimaryGenerator >, const std::string &, const framework::config::Parameters &)
 
virtual ~PrimaryGenerator ()=default
 Destructor.
 
virtual void prepEvent (const framework::Event &event)
 Prepare to generate a new primary vertex given the input event context.
 
std::string name ()
 
void smearBeamspot (G4PrimaryVertex *primary_vertex)
 Apply beam spot smearing to a primary vertex.
 
bool useBeamspot () const
 Check if beam spot smearing is enabled for this generator.
 

Private Member Functions

void fillConfig (const framework::config::Parameters &)
 
bool validateConfig ()
 fill the configuration
 
void initializeGENIE ()
 simple validation check on configuration params
 
void calculateTotalXS ()
 GENIE initialization.
 

Private Attributes

std::vector< genie::GEVGDriver > evg_drivers_
 One GENIE event generator driver per target and convertor to HepMC3GenEvent.
 
genie::HepMC3Converter hep_mc3_converter_
 
double energy_
 
std::vector< int > targets_
 
std::vector< double > abundances_
 
std::vector< double > position_
 
std::vector< double > beam_size_
 
float target_thickness_
 
float time_
 
std::vector< double > direction_
 
std::string tune_
 
std::string spline_file_
 
std::string message_threshold_file_
 
std::vector< float > ev_weighting_integral_
 
size_t n_events_generated_
 
std::vector< size_t > n_events_by_target_
 
std::vector< float > xsec_by_target_
 
float xsec_total_
 

Additional Inherited Members

- Protected Attributes inherited from simcore::PrimaryGenerator
std::string name_ {""}
 Name of the PrimaryGenerator.
 
bool use_beamspot_ {false}
 Flag denoting whether beam spot smearing is enabled for this generator.
 
double beamspot_x_size_ {0}
 Extent of the beamspot in x [mm].
 
double beamspot_y_size_ {0}
 Extent of the beamspot in y [mm].
 
double beamspot_z_size_ {0}
 Extent of the beamspot in z [mm].
 

Detailed Description

Class that uses GENIE's GEVGDriver to generator eN interactions.

Definition at line 40 of file GenieGenerator.h.

Constructor & Destructor Documentation

◆ GenieGenerator()

simcore::generators::GenieGenerator::GenieGenerator ( const std::string & name,
const framework::config::Parameters & parameters )

Constructor.

Parameters
parametersParameters used to configure GENIE generator.

Parameters: energy : energy of initial electron (GeV) targets : list of ten-digit 10LZZZAAAI target codes abundances: list of relative abundances for the given targets position : position of interaction from (mm three-vector) time : time to shoot at (ns) direction : direction to shoot in (unitless three-vector) tune : name of GENIE tune seed : seed for random generator

Definition at line 224 of file GenieGenerator.cxx.

226 : PrimaryGenerator(name, p) {
227 fillConfig(p);
228
229 if (!validateConfig())
230 EXCEPTION_RAISE("ConfigurationException", "Configuration not valid.");
231
232 n_events_generated_ = 0;
235}
PrimaryGenerator(const std::string &name, const framework::config::Parameters &parameters)
Constructor.
void calculateTotalXS()
GENIE initialization.
void initializeGENIE()
simple validation check on configuration params
bool validateConfig()
fill the configuration

References calculateTotalXS(), initializeGENIE(), and validateConfig().

◆ ~GenieGenerator()

simcore::generators::GenieGenerator::~GenieGenerator ( )

Destructor.

Definition at line 237 of file GenieGenerator.cxx.

237 {
238 ldmx_log(info) << "--- GENIE Generation Summary BEGIN ---";
239 double total_xsec = 0;
240 for (size_t i_t = 0; i_t < targets_.size(); ++i_t) {
241 ldmx_log(info) << "Target=" << targets_[i_t]
242 << "\tAbundance=" << abundances_[i_t] << "\tXSEC="
243 << xsec_by_target_[i_t] / genie::units::millibarn << " mb"
244 << "\tEvents=" << n_events_by_target_[i_t];
245 if (n_events_by_target_[i_t] > 0)
246 total_xsec += xsec_by_target_[i_t] * abundances_[i_t];
247 }
248
249 ldmx_log(info) << "Total events generated = " << n_events_generated_
250 << "\nTotal XSEC = " << total_xsec / genie::units::millibarn
251 << " mb";
252
253 ldmx_log(info) << "--- GENIE Generation Summary *END* ---";
254}

Member Function Documentation

◆ calculateTotalXS()

void simcore::generators::GenieGenerator::calculateTotalXS ( )
private

GENIE initialization.

Definition at line 180 of file GenieGenerator.cxx.

180 {
181 // initializing...
182 xsec_total_ = 0;
183 ev_weighting_integral_.resize(targets_.size(), 0.0);
184 evg_drivers_.resize(targets_.size());
185
186 // calculate the total xsec per target...
187 for (size_t i_t = 0; i_t < targets_.size(); ++i_t) {
188 genie::InitialState initial_state(targets_[i_t], 11);
189 evg_drivers_[i_t].SetEventGeneratorList(
190 genie::RunOpt::Instance()->EventGeneratorList());
191 evg_drivers_[i_t].SetUnphysEventMask(
192 *genie::RunOpt::Instance()->UnphysEventMask());
193 evg_drivers_[i_t].Configure(initial_state);
194 evg_drivers_[i_t].UseSplines();
195
196 // setup the initial election
197 TParticle initial_e;
198 initial_e.SetPdgCode(11);
199 auto elec_i_p = std::sqrt(energy_ * energy_ -
200 initial_e.GetMass() * initial_e.GetMass());
201 initial_e.SetMomentum(elec_i_p * direction_[0], elec_i_p * direction_[1],
202 elec_i_p * direction_[2], energy_);
203 TLorentzVector e_p4;
204 initial_e.Momentum(e_p4);
205
206 xsec_by_target_[i_t] = evg_drivers_[i_t].XSecSum(e_p4);
207 xsec_total_ += xsec_by_target_[i_t] * abundances_[i_t];
208
209 ev_weighting_integral_[i_t] = xsec_total_; // running sum
210
211 // print...
212 ldmx_log(debug) << "Target=" << targets_[i_t]
213 << "\tAbundance=" << abundances_[i_t] << "\tXSEC="
214 << xsec_by_target_[i_t] / genie::units::millibarn << "mb";
215 }
216 ldmx_log(debug) << "Total XSEC = " << xsec_total_ / genie::units::millibarn
217 << " mb";
218
219 // renormalize our weighting integral
220 for (size_t i_t = 0; i_t < ev_weighting_integral_.size(); ++i_t)
221 ev_weighting_integral_[i_t] = ev_weighting_integral_[i_t] / xsec_total_;
222}
std::vector< genie::GEVGDriver > evg_drivers_
One GENIE event generator driver per target and convertor to HepMC3GenEvent.

References evg_drivers_.

Referenced by GenieGenerator().

◆ fillConfig()

void simcore::generators::GenieGenerator::fillConfig ( const framework::config::Parameters & p)
private

Definition at line 50 of file GenieGenerator.cxx.

50 {
51 energy_ = p.get<double>("energy"); // * GeV;
52
53 targets_ = p.get<std::vector<int> >("targets");
54 abundances_ = p.get<std::vector<double> >("abundances");
55
56 time_ = p.get<double>("time"); // * ns;
57 position_ = p.get<std::vector<double> >("position"); // mm
58 beam_size_ = p.get<std::vector<double> >("beam_size"); // mm
59 direction_ = p.get<std::vector<double> >("direction");
60 target_thickness_ = p.get<double>("target_thickness"); // mm
61
62 tune_ = p.get<std::string>("tune");
63 spline_file_ = p.get<std::string>("spline_file");
64
65 message_threshold_file_ = p.get<std::string>("message_threshold_file");
66}
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:75

◆ GeneratePrimaryVertex()

void simcore::generators::GenieGenerator::GeneratePrimaryVertex ( G4Event * event)
finaloverridevirtual

Generate the primary vertices in the Geant4 event.

Parameters
eventThe Geant4 event.

Implements simcore::PrimaryGenerator.

Definition at line 256 of file GenieGenerator.cxx.

256 {
257 if (n_events_generated_ == 0) {
258 // set random seed
259 // have to do this here since seeds aren't properly set until we know the
260 // run number
261 auto seed = G4Random::getTheEngine()->getSeed();
262 ldmx_log(debug) << "Initializing GENIE with seed " << seed;
263 genie::utils::app_init::RandGen(seed);
264 }
265
266 auto nucl_target_i = 0;
267
268 if (targets_.size() > 0) {
269 double rand_uniform = G4Random::getTheGenerator()->flat();
270
271 nucl_target_i = std::distance(
272 ev_weighting_integral_.begin(),
273 std::lower_bound(ev_weighting_integral_.begin(),
274 ev_weighting_integral_.end(), rand_uniform));
275
276 ldmx_log(debug) << "Random number = " << rand_uniform << ", target picked "
277 << targets_.at(nucl_target_i);
278 }
279
280 auto x_pos = position_[0] +
281 (G4Random::getTheGenerator()->flat() - 0.5) * beam_size_[0];
282 auto y_pos = position_[1] +
283 (G4Random::getTheGenerator()->flat() - 0.5) * beam_size_[1];
284 auto z_pos = position_[2] +
285 (G4Random::getTheGenerator()->flat() - 0.5) * target_thickness_;
286
287 ldmx_log(debug) << "Generating interaction at (x_,y_,z_)=" << "(" << x_pos
288 << "," << y_pos << "," << z_pos << ")";
289
290 // setup the initial election
291 TParticle initial_e;
292 initial_e.SetPdgCode(11);
293 float elec_i_p =
294 std::sqrt(energy_ * energy_ - initial_e.GetMass() * initial_e.GetMass());
295 initial_e.SetMomentum(elec_i_p * direction_[0], elec_i_p * direction_[1],
296 elec_i_p * direction_[2], energy_);
297 TLorentzVector e_p4;
298 initial_e.Momentum(e_p4);
299
300 ldmx_log(debug) << "Generating interation with (px,py,pz,e)=" << "("
301 << e_p4.Px() << "," << e_p4.Py() << "," << e_p4.Pz() << ","
302 << e_p4.E() << ")";
303
304 n_events_by_target_[nucl_target_i] += 1;
305
306 // GENIE magic — use the pre-configured driver for this target
307 genie::EventRecord* genie_event = NULL;
308 while (!genie_event)
309 genie_event = evg_drivers_[nucl_target_i].GenerateEvent(e_p4);
310
311 auto ev_info = new UserEventInformation;
312 auto hepmc3_genie = hep_mc3_converter_.ConvertToHepMC3(*genie_event);
313 ldmx::HepMC3GenEvent hepmc3_ldmx_genie;
314 hepmc3_genie->write_data(hepmc3_ldmx_genie);
315 ev_info->addHepMC3GenEvent(hepmc3_ldmx_genie);
316 event->SetUserInformation(ev_info);
317
318 // setup the primary vertex now
319
320 G4PrimaryVertex* vertex = new G4PrimaryVertex();
321 vertex->SetPosition(x_pos, y_pos, z_pos);
322 vertex->SetWeight(genie_event->Weight());
323
324 // loop over the entries and add to the G4Event
325 int n_entries = genie_event->GetEntries();
326
327 ldmx_log(debug) << "---------- " << "Generated Event "
328 << n_events_generated_ + 1 << " ----------";
329
330 for (int i_p = 0; i_p < n_entries; ++i_p) {
331 genie::GHepParticle* p = (genie::GHepParticle*)(*genie_event)[i_p];
332
333 // make sure it's a final state particle
334 if (p->Status() != 1) continue;
335
336 ldmx_log(debug) << "\tAdding particle " << p->Pdg() << " with status "
337 << p->Status() << " energy " << p->E() << " ...";
338
339 G4PrimaryParticle* primary = new G4PrimaryParticle();
340 primary->SetPDGcode(p->Pdg());
341
342 // this sets the 4momentum. But may not respect masses in G4...
343 // primary->Set4Momentum(p->Px() * CLHEP::GeV, p->Py() * CLHEP::GeV,
344 // p->Pz() * CLHEP::GeV, p->E() * CLHEP::GeV);
345
346 // for now, do this to set the masses to be the G4 ones, through the PDG
347 // code
348 primary->SetMomentum(p->Px() * CLHEP::GeV, p->Py() * CLHEP::GeV,
349 p->Pz() * CLHEP::GeV);
350
351 primary->SetProperTime(time_ * CLHEP::ns);
352
353 UserPrimaryParticleInformation* primary_info =
354 new UserPrimaryParticleInformation();
355 primary_info->setHepEvtStatus(1);
356 primary->SetUserInformation(primary_info);
357
358 vertex->SetPrimary(primary);
359 }
360
361 // add the vertex to the event
362 event->AddPrimaryVertex(vertex);
363
364 // Apply beam spot smearing if configured for this generator
365 if (useBeamspot()) {
366 smearBeamspot(vertex);
367 }
368
369 ++n_events_generated_;
370 delete genie_event;
371}
bool useBeamspot() const
Check if beam spot smearing is enabled for this generator.
void smearBeamspot(G4PrimaryVertex *primary_vertex)
Apply beam spot smearing to a primary vertex.

References evg_drivers_, simcore::UserPrimaryParticleInformation::setHepEvtStatus(), simcore::PrimaryGenerator::smearBeamspot(), and simcore::PrimaryGenerator::useBeamspot().

◆ initializeGENIE()

void simcore::generators::GenieGenerator::initializeGENIE ( )
private

simple validation check on configuration params

Definition at line 154 of file GenieGenerator.cxx.

154 {
155 // initialize some RunOpt by hacking the command line interface
156 {
157 char* in_arr[3] = {const_cast<char*>(""),
158 const_cast<char*>("--event-generator-list"),
159 const_cast<char*>("EM")};
160 genie::RunOpt::Instance()->ReadFromCommandLine(3, in_arr);
161 }
162
163 // set message thresholds
164 genie::utils::app_init::MesgThresholds(message_threshold_file_);
165
166 // set tune info
167 genie::RunOpt::Instance()->SetTuneName(tune_);
168 if (!genie::RunOpt::Instance()->Tune()) {
169 EXCEPTION_RAISE("ConfigurationException", "No TuneId in RunOption.");
170 }
171 genie::RunOpt::Instance()->BuildTune();
172
173 // give it the splint file and require it
174 genie::utils::app_init::XSecTable(spline_file_, true);
175
176 // set GHEP print level (needed?)
177 genie::GHepRecord::SetPrintLevel(0);
178}

Referenced by GenieGenerator().

◆ RecordConfig()

void simcore::generators::GenieGenerator::RecordConfig ( const std::string & id,
ldmx::RunHeader & rh )
finaloverridevirtual

Record the configuration of the primary generator into the run header.

Note
you must include the id number in each entry into the run header just in case there are other generators

Implements simcore::PrimaryGenerator.

Definition at line 373 of file GenieGenerator.cxx.

373 {
374 rh.setStringParameter(id + " Class", "simcore::generators::GenieGenerator");
375 rh.setStringParameter(id + "GenieTune", tune_);
376}
void setStringParameter(const std::string &name, std::string value)
Set a string parameter value.
Definition RunHeader.h:261

References ldmx::RunHeader::setStringParameter().

◆ validateConfig()

bool simcore::generators::GenieGenerator::validateConfig ( )
private

fill the configuration

Definition at line 68 of file GenieGenerator.cxx.

68 {
69 bool ret = true;
70
71 if (targets_.size() == 0 || abundances_.size() == 0) {
72 ldmx_log(error) << "targets and/or abundances sizes are zero." << " "
73 << targets_.size() << ", " << abundances_.size();
74 ret = false;
75 }
76 if (targets_.size() != abundances_.size()) {
77 ldmx_log(error) << "targets and abundances sizes unequal." << " "
78 << targets_.size() << " != " << abundances_.size();
79 ret = false;
80 }
81
82 if (position_.size() != 3 || direction_.size() != 3) {
83 ldmx_log(error) << "position and/or direction sizes are not 3." << " "
84 << position_.size() << ", " << direction_.size();
85 ret = false;
86 }
87
88 if (target_thickness_ < 0) {
89 ldmx_log(warn) << "target thickness cannot be less than 0! (thickness="
90 << target_thickness_ << "). Taking absolute value.";
91 target_thickness_ = std::abs(target_thickness_);
92 }
93
94 if (beam_size_.size() != 2) {
95 if (beam_size_.size() == 0) {
96 ldmx_log(info) << "beam size not set. Using zero.";
97 beam_size_.resize(2);
98 beam_size_[0] = 0.0;
99 beam_size_[1] = 0.0;
100 } else {
101 ldmx_log(error) << "beam size is set, but does not have size 2." << " "
102 << beam_size_.size();
103 ret = false;
104 }
105 } else if (beam_size_[0] < 0 || beam_size_[1] < 0) {
106 ldmx_log(warn) << "Beam size set as negative value? " << "("
107 << beam_size_[0] << "," << beam_size_[1] << ")"
108 << ". Changing to positive.";
109 beam_size_[0] = std::abs(beam_size_[0]);
110 beam_size_[1] = std::abs(beam_size_[1]);
111 }
112
113 // normalize abundances
114 float abundance_sum = 0;
115 for (auto a : abundances_) {
116 abundance_sum += a;
117 }
118
119 if (std::abs(abundance_sum) < 1e-6) {
120 ldmx_log(error) << "abundances list sums to zero? " << abundance_sum;
121 ret = false;
122 }
123
124 if (std::abs(abundance_sum - 1.0) > 2e-2) {
125 ldmx_log(info) << "abundances list sums is not unity (" << abundance_sum
126 << " instead.) Will renormalize abundances to unity!";
127 }
128
129 for (size_t i_a = 0; i_a < abundances_.size(); ++i_a) {
130 abundances_[i_a] = abundances_[i_a] / abundance_sum;
131
132 ldmx_log(debug) << "Target=" << targets_[i_a]
133 << ", Abundance=" << abundances_[i_a];
134 }
135
136 float dir_total_sq = 0;
137 for (auto d : direction_) dir_total_sq += d * d;
138
139 if (dir_total_sq < 1e-6) {
140 ldmx_log(error) << "direction vector is zero or negative? " << "("
141 << direction_[0] << "," << direction_[1] << ","
142 << direction_[2] << ")";
143 ret = false;
144 }
145 for (size_t i_d = 0; i_d < direction_.size(); ++i_d)
146 direction_[i_d] = direction_[i_d] / std::sqrt(dir_total_sq);
147
148 xsec_by_target_.resize(targets_.size(), -999.);
149 n_events_by_target_.resize(targets_.size(), 0);
150
151 return ret;
152}

Referenced by GenieGenerator().

Member Data Documentation

◆ abundances_

std::vector<double> simcore::generators::GenieGenerator::abundances_
private

Definition at line 83 of file GenieGenerator.h.

◆ beam_size_

std::vector<double> simcore::generators::GenieGenerator::beam_size_
private

Definition at line 85 of file GenieGenerator.h.

◆ direction_

std::vector<double> simcore::generators::GenieGenerator::direction_
private

Definition at line 88 of file GenieGenerator.h.

◆ energy_

double simcore::generators::GenieGenerator::energy_
private

Definition at line 81 of file GenieGenerator.h.

◆ ev_weighting_integral_

std::vector<float> simcore::generators::GenieGenerator::ev_weighting_integral_
private

Definition at line 95 of file GenieGenerator.h.

◆ evg_drivers_

std::vector<genie::GEVGDriver> simcore::generators::GenieGenerator::evg_drivers_
private

One GENIE event generator driver per target and convertor to HepMC3GenEvent.

Each driver is configured once for its target during initialization.

Definition at line 78 of file GenieGenerator.h.

Referenced by calculateTotalXS(), and GeneratePrimaryVertex().

◆ hep_mc3_converter_

genie::HepMC3Converter simcore::generators::GenieGenerator::hep_mc3_converter_
private

Definition at line 79 of file GenieGenerator.h.

◆ message_threshold_file_

std::string simcore::generators::GenieGenerator::message_threshold_file_
private

Definition at line 93 of file GenieGenerator.h.

◆ n_events_by_target_

std::vector<size_t> simcore::generators::GenieGenerator::n_events_by_target_
private

Definition at line 97 of file GenieGenerator.h.

◆ n_events_generated_

size_t simcore::generators::GenieGenerator::n_events_generated_
private

Definition at line 96 of file GenieGenerator.h.

◆ position_

std::vector<double> simcore::generators::GenieGenerator::position_
private

Definition at line 84 of file GenieGenerator.h.

◆ spline_file_

std::string simcore::generators::GenieGenerator::spline_file_
private

Definition at line 91 of file GenieGenerator.h.

◆ target_thickness_

float simcore::generators::GenieGenerator::target_thickness_
private

Definition at line 86 of file GenieGenerator.h.

◆ targets_

std::vector<int> simcore::generators::GenieGenerator::targets_
private

Definition at line 82 of file GenieGenerator.h.

◆ time_

float simcore::generators::GenieGenerator::time_
private

Definition at line 87 of file GenieGenerator.h.

◆ tune_

std::string simcore::generators::GenieGenerator::tune_
private

Definition at line 90 of file GenieGenerator.h.

◆ xsec_by_target_

std::vector<float> simcore::generators::GenieGenerator::xsec_by_target_
private

Definition at line 98 of file GenieGenerator.h.

◆ xsec_total_

float simcore::generators::GenieGenerator::xsec_total_
private

Definition at line 100 of file GenieGenerator.h.


The documentation for this class was generated from the following files: