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.
 
std::string name ()
 

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

genie::GEVGDriver evg_driver_
 The GENIE event generator driver 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.
 

Detailed Description

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

Definition at line 42 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 236 of file GenieGenerator.cxx.

238 : PrimaryGenerator(name, p) {
239 fillConfig(p);
240
241 if (!validateConfig())
242 EXCEPTION_RAISE("ConfigurationException", "Configuration not valid.");
243
244 n_events_generated_ = 0;
247}
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 249 of file GenieGenerator.cxx.

249 {
250 std::cout << "--- GENIE Generation Summary BEGIN ---" << std::endl;
251 double total_xsec = 0;
252 for (size_t i_t = 0; i_t < targets_.size(); ++i_t) {
253 std::cout << "Target=" << targets_[i_t]
254 << "\tAbundance=" << abundances_[i_t]
255 << "\tXSEC=" << xsec_by_target_[i_t] / genie::units::millibarn
256 << " mb" << "\tEvents=" << n_events_by_target_[i_t] << std::endl;
257 if (n_events_by_target_[i_t] > 0)
258 total_xsec += xsec_by_target_[i_t] * abundances_[i_t];
259 }
260
261 std::cout << "Total events generated = " << n_events_generated_
262 << "\nTotal XSEC = " << total_xsec / genie::units::millibarn
263 << " mb" << std::endl;
264
265 std::cout << "--- GENIE Generation Summary *END* ---" << std::endl;
266}

Member Function Documentation

◆ calculateTotalXS()

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

GENIE initialization.

Definition at line 197 of file GenieGenerator.cxx.

197 {
198 // initializing...
199 xsec_total_ = 0;
200 ev_weighting_integral_.resize(targets_.size(), 0.0);
201
202 // calculate the total xsec per target...
203 for (size_t i_t = 0; i_t < targets_.size(); ++i_t) {
204 genie::InitialState initial_state(targets_[i_t], 11);
205 evg_driver_.Configure(initial_state);
206 evg_driver_.UseSplines();
207
208 // setup the initial election
209 TParticle initial_e;
210 initial_e.SetPdgCode(11);
211 auto elec_i_p = std::sqrt(energy_ * energy_ -
212 initial_e.GetMass() * initial_e.GetMass());
213 initial_e.SetMomentum(elec_i_p * direction_[0], elec_i_p * direction_[1],
214 elec_i_p * direction_[2], energy_);
215 TLorentzVector e_p4;
216 initial_e.Momentum(e_p4);
217
218 xsec_by_target_[i_t] = evg_driver_.XSecSum(e_p4);
219 xsec_total_ += xsec_by_target_[i_t] * abundances_[i_t];
220
221 ev_weighting_integral_[i_t] = xsec_total_; // running sum
222
223 // print...
224 ldmx_log(debug) << "Target=" << targets_[i_t]
225 << "\tAbundance=" << abundances_[i_t] << "\tXSEC="
226 << xsec_by_target_[i_t] / genie::units::millibarn << "mb";
227 }
228 ldmx_log(debug) << "Total XSEC = " << xsec_total_ / genie::units::millibarn
229 << " mb";
230
231 // renormalize our weighting integral
232 for (size_t i_t = 0; i_t < ev_weighting_integral_.size(); ++i_t)
233 ev_weighting_integral_[i_t] = ev_weighting_integral_[i_t] / xsec_total_;
234}
genie::GEVGDriver evg_driver_
The GENIE event generator driver and convertor to HepMC3GenEvent.

References evg_driver_.

Referenced by GenieGenerator().

◆ fillConfig()

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

Definition at line 62 of file GenieGenerator.cxx.

62 {
63 energy_ = p.get<double>("energy"); // * GeV;
64
65 targets_ = p.get<std::vector<int> >("targets");
66 abundances_ = p.get<std::vector<double> >("abundances");
67
68 time_ = p.get<double>("time"); // * ns;
69 position_ = p.get<std::vector<double> >("position"); // mm
70 beam_size_ = p.get<std::vector<double> >("beam_size"); // mm
71 direction_ = p.get<std::vector<double> >("direction");
72 target_thickness_ = p.get<double>("target_thickness"); // mm
73
74 tune_ = p.get<std::string>("tune");
75 spline_file_ = p.get<std::string>("spline_file");
76
77 message_threshold_file_ = p.get<std::string>("message_threshold_file");
78}
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78

◆ 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 268 of file GenieGenerator.cxx.

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

References evg_driver_, and simcore::UserPrimaryParticleInformation::setHepEvtStatus().

◆ initializeGENIE()

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

simple validation check on configuration params

Definition at line 166 of file GenieGenerator.cxx.

166 {
167 // initialize some RunOpt by hacking the command line interface
168 {
169 char* in_arr[3] = {const_cast<char*>(""),
170 const_cast<char*>("--event-generator-list"),
171 const_cast<char*>("EM")};
172 genie::RunOpt::Instance()->ReadFromCommandLine(3, in_arr);
173 }
174
175 // set message thresholds
176 genie::utils::app_init::MesgThresholds(message_threshold_file_);
177
178 // set tune info
179 genie::RunOpt::Instance()->SetTuneName(tune_);
180 if (!genie::RunOpt::Instance()->Tune()) {
181 EXCEPTION_RAISE("ConfigurationException", "No TuneId in RunOption.");
182 }
183 genie::RunOpt::Instance()->BuildTune();
184
185 // give it the splint file and require it
186 genie::utils::app_init::XSecTable(spline_file_, true);
187
188 // set GHEP print level (needed?)
189 genie::GHepRecord::SetPrintLevel(0);
190
191 // setup for event driver
192 evg_driver_.SetEventGeneratorList(
193 genie::RunOpt::Instance()->EventGeneratorList());
194 evg_driver_.SetUnphysEventMask(*genie::RunOpt::Instance()->UnphysEventMask());
195}

References evg_driver_.

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 387 of file GenieGenerator.cxx.

387 {
388 rh.setStringParameter(id + " Class", "simcore::generators::GenieGenerator");
389 rh.setStringParameter(id + "GenieTune", tune_);
390}
void setStringParameter(const std::string &name, std::string value)
Set a string parameter value.
Definition RunHeader.h:222

References ldmx::RunHeader::setStringParameter().

◆ validateConfig()

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

fill the configuration

Definition at line 80 of file GenieGenerator.cxx.

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

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_driver_

genie::GEVGDriver simcore::generators::GenieGenerator::evg_driver_
private

The GENIE event generator driver and convertor to HepMC3GenEvent.

Definition at line 78 of file GenieGenerator.h.

Referenced by calculateTotalXS(), GeneratePrimaryVertex(), and initializeGENIE().

◆ 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: