LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
evgen::MARLEYHelper Class Reference

#include "MARLEYHelper.h"

Public Member Functions

 MARLEYHelper (const fhicl::ParameterSet &pset, rndm::NuRandomService &rand_service, const std::string &generator_name)
 
void reconfigure (const fhicl::ParameterSet &pset)
 
simb::MCTruth create_MCTruth (const TLorentzVector &vtx_pos, marley::Event *marley_event=nullptr)
 
marley::Generator & get_generator ()
 
const marley::Generator & get_generator () const
 
std::string find_file (const std::string &fileName, const std::string &fileType)
 

Protected Member Functions

void add_marley_particles (simb::MCTruth &truth, const std::vector< marley::Particle * > &particles, const TLorentzVector &vtx_pos, bool track)
 
void load_full_paths_into_json (marley::JSON &json, const std::string &array_name, bool missing_ok=false)
 
void load_marley_dictionaries ()
 

Protected Attributes

std::unique_ptr< marley::Generator > fMarleyGenerator
 
std::string fHelperName
 
std::stringstream fMarleyLogStream
 

Detailed Description

Definition at line 45 of file MARLEYHelper.h.

Constructor & Destructor Documentation

evgen::MARLEYHelper::MARLEYHelper ( const fhicl::ParameterSet pset,
rndm::NuRandomService rand_service,
const std::string &  generator_name 
)

Definition at line 35 of file MARLEYHelper.cxx.

References fHelperName, fMarleyGenerator, fMarleyLogStream, load_marley_dictionaries(), MF_LOG_INFO, reconfigure(), rndm::NuRandomService::registerEngine(), and seed.

38  : fHelperName(helper_name)
39 {
40  // Configure MARLEY using the FHiCL parameters
41  this->reconfigure(pset);
42 
43  // Register this MARLEY generator with the NuRandomService. For simplicity,
44  // we use a lambda as the seeder function (see NuRandomService.h for
45  // details). This allows the SeedService to automatically re-seed MARLEY
46  // whenever necessary. The user can set an explicit seed for MARLEY in the
47  // FHiCL configuration using the "seed" parameter. If you need to get the
48  // seed for MARLEY from the SeedService, note that we're using use the value
49  // of the input variable helper_name as its generator instance name.
50  rndm::NuRandomService::seed_t marley_seed = rand_service.registerEngine(
51  [this](rndm::NuRandomService::EngineId const& /* unused */,
52  rndm::NuRandomService::seed_t lar_seed) -> void {
53  if (fMarleyGenerator && fMarleyGenerator.get()) {
54  auto seed = static_cast<uint_fast64_t>(lar_seed);
55  fMarleyGenerator->reseed(seed);
56  }
57  },
59  pset,
60  {"seed"});
61 
62  // Unless I'm mistaken, the call to registerEngine should seed the generator
63  // with the seed from the FHiCL configuration file if one is included, but it
64  // doesn't appear to do so (as of 16 Aug 2016, larsoft v06_03_00). As a
65  // workaround, I manually reseed the generator (if needed) here using the
66  // result of the call to registerEngine, which will be the seed from the
67  // FHiCL file if one was given.
68  // TODO: figure out what's going on here, and remove this workaround as
69  // needed
70  uint_fast64_t marley_cast_seed = static_cast<uint_fast64_t>(marley_seed);
71  if (marley_cast_seed != fMarleyGenerator->get_seed()) {
72  fMarleyGenerator->reseed(marley_cast_seed);
73  }
74 
75  // Log initialization information from the MARLEY generator
77  fMarleyLogStream = std::stringstream();
78 
79  // Do any needed setup of the MARLEY class dictionaries
81 }
seed_t registerEngine(SeedMaster_t::Seeder_t seeder, std::string const instance="", std::optional< seed_t > const seed=std::nullopt)
Registers an existing engine with rndm::NuRandomService.
std::stringstream fMarleyLogStream
Definition: MARLEYHelper.h:82
std::unique_ptr< marley::Generator > fMarleyGenerator
Definition: MARLEYHelper.h:75
std::string fHelperName
Definition: MARLEYHelper.h:78
long seed
Definition: chem4.cc:67
void reconfigure(const fhicl::ParameterSet &pset)
Identifier for a engine, made of module name and optional instance name.
Definition: EngineId.h:22
#define MF_LOG_INFO(category)
art::detail::EngineCreator::seed_t seed_t

Member Function Documentation

void evgen::MARLEYHelper::add_marley_particles ( simb::MCTruth truth,
const std::vector< marley::Particle * > &  particles,
const TLorentzVector &  vtx_pos,
bool  track 
)
protected

Definition at line 84 of file MARLEYHelper.cxx.

References simb::MCTruth::Add(), simb::MCParticle::AddTrajectoryPoint(), E, simb::MCTruth::NParticles(), and part.

Referenced by create_MCTruth().

88 {
89  // Loop over the vector of MARLEY particles and add simb::MCParticle
90  // versions of each of them to the MCTruth object.
91  for (const marley::Particle* p : particles) {
92  // Treat all of these particles as primaries, which have negative
93  // track IDs by convention
94  int trackID = -1 * (truth.NParticles() + 1);
95 
96  int pdg = p->pdg_code();
97  double mass = p->mass() * MeV_to_GeV;
98  double px = p->px() * MeV_to_GeV;
99  double py = p->py() * MeV_to_GeV;
100  double pz = p->pz() * MeV_to_GeV;
101  double E = p->total_energy() * MeV_to_GeV;
102  TLorentzVector mom(px, py, pz, E);
103 
104  int status = 0; // don't track the particles in LArG4 by default
105  if (track) status = 1;
106 
107  simb::MCParticle part(trackID /* trackID to use in Geant4 */,
108  pdg,
109  "MARLEY",
110  -1 /* primary particle */,
111  mass,
112  status);
113 
114  part.AddTrajectoryPoint(vtx_pos, mom);
115  truth.Add(part);
116  }
117 }
int NParticles() const
Definition: MCTruth.h:75
TString part[npart]
Definition: Style.C:32
Float_t E
Definition: plot.C:20
void Add(simb::MCParticle const &part)
Definition: MCTruth.h:80
Float_t track
Definition: plot.C:35
simb::MCTruth evgen::MARLEYHelper::create_MCTruth ( const TLorentzVector &  vtx_pos,
marley::Event *  marley_event = nullptr 
)

Definition at line 120 of file MARLEYHelper.cxx.

References add_marley_particles(), fHelperName, fMarleyGenerator, fMarleyLogStream, simb::kCC, simb::kSuperNovaNeutrino, simb::kUnknownInteraction, MF_LOG_INFO, simb::MCTruth::SetNeutrino(), and simb::MCTruth::SetOrigin().

122 {
123  simb::MCTruth truth;
124 
126 
127  marley::Event event = fMarleyGenerator->create_event();
128 
129  // Add the initial and final state particles to the MCTruth object.
130  add_marley_particles(truth, event.get_initial_particles(), vtx_pos, false);
131  add_marley_particles(truth, event.get_final_particles(), vtx_pos, true);
132 
133  // calculate a few parameters for the call to SetNeutrino
134  const marley::Particle& nu = event.projectile();
135  const marley::Particle& lep = event.ejectile();
136  double qx = nu.px() - lep.px();
137  double qy = nu.py() - lep.py();
138  double qz = nu.pz() - lep.pz();
139  double Enu = nu.total_energy();
140  double Elep = lep.total_energy();
141  double Q2 = qx * qx + qy * qy + qz * qz - std::pow(Enu - Elep, 2);
142 
143  // For definitions of Bjorken x, etc., a good reference is Mark Thomson's
144  // set of slides on deep inelastic scattering (http://tinyurl.com/hcn5n6l)
145  double bjorken_x = Q2 / (2 * event.target().mass() * (Enu - Elep));
146  double inelasticity_y = 1. - Elep / Enu;
147 
148  // Include the initial excitation energy of the final-state nucleus when
149  // calculating W (the final-state invariant mass of the hadronic system)
150  // since the other parameters (X, Y) also take into account the 2-2
151  // scattering reaction only.
152  const marley::Particle& res = event.residue();
153  double hadronic_mass_W = res.mass() + event.Ex();
154 
155  // TODO: do a more careful job of setting the parameters here
156  truth.SetNeutrino(simb::kCC, // change when MARLEY can handle NC
157  simb::kUnknownInteraction, // not sure what the mode should be
158  simb::kUnknownInteraction, // not sure what the interaction type should be
159  marley_utils::get_nucleus_pid(18, 40), // Ar-40 PDG code
160  marley_utils::NEUTRON, // nucleon PDG
161  0, // MARLEY handles low enough energies that we shouldn't need HitQuark
162  hadronic_mass_W * MeV_to_GeV,
163  bjorken_x, // dimensionless
164  inelasticity_y, // dimensionless
165  Q2 * std::pow(MeV_to_GeV, 2));
166 
167  if (marley_event) *marley_event = event;
168 
169  // Process the MARLEY logging messages (if any) captured by our
170  // stringstream and forward them to the messagefacility logger
171  std::string line;
172  while (std::getline(fMarleyLogStream, line)) {
173  MF_LOG_INFO(fHelperName) << line;
174  }
175 
176  // Reset the MARLEY log stream
177  fMarleyLogStream = std::stringstream();
178 
179  return truth;
180 }
void add_marley_particles(simb::MCTruth &truth, const std::vector< marley::Particle * > &particles, const TLorentzVector &vtx_pos, bool track)
void SetOrigin(simb::Origin_t origin)
Definition: MCTruth.h:82
void SetNeutrino(int CCNC, int mode, int interactionType, int target, int nucleon, int quark, double w, double x, double y, double qsqr)
Definition: MCTruth.cxx:30
std::stringstream fMarleyLogStream
Definition: MARLEYHelper.h:82
std::unique_ptr< marley::Generator > fMarleyGenerator
Definition: MARLEYHelper.h:75
std::string fHelperName
Definition: MARLEYHelper.h:78
#define MF_LOG_INFO(category)
n.b.: this group is similar but not quite, entirely unlike GENIE ScatteringType convention ...
Definition: MCNeutrino.h:80
Supernova neutrinos.
Definition: MCTruth.h:25
Event generator information.
Definition: MCTruth.h:32
Event finding and building.
std::string evgen::MARLEYHelper::find_file ( const std::string &  fileName,
const std::string &  fileType 
)

Definition at line 183 of file MARLEYHelper.cxx.

Referenced by load_full_paths_into_json().

184 {
185  cet::search_path searchPath("FW_SEARCH_PATH");
186 
187  std::string fullName;
188  searchPath.find_file(fileName, fullName);
189 
190  if (fullName.empty())
191  throw cet::exception("MARLEYHelper")
192  << "Cannot find MARLEY " << fileType << " data file '" << fileName << '\'';
193 
194  return fullName;
195 }
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
marley::Generator& evgen::MARLEYHelper::get_generator ( )
inline

Definition at line 60 of file MARLEYHelper.h.

60 { return *fMarleyGenerator; }
std::unique_ptr< marley::Generator > fMarleyGenerator
Definition: MARLEYHelper.h:75
const marley::Generator& evgen::MARLEYHelper::get_generator ( ) const
inline

Definition at line 61 of file MARLEYHelper.h.

References track.

61 { return *fMarleyGenerator; }
std::unique_ptr< marley::Generator > fMarleyGenerator
Definition: MARLEYHelper.h:75
void evgen::MARLEYHelper::load_full_paths_into_json ( marley::JSON &  json,
const std::string &  array_name,
bool  missing_ok = false 
)
protected

Definition at line 198 of file MARLEYHelper.cxx.

References find_file(), and value.

Referenced by reconfigure().

201 {
202  if (json.has_key(key)) {
203 
204  marley::JSON& value = json.at(key);
205 
206  if (value.is_array()) {
207  // Replace each file name (which may appear in the FHiCL configuration
208  // without a full path) with the full path found using cetlib
209  for (auto& element : value.array_range()) {
210  element = find_file(element.to_string(), key);
211  }
212  }
213 
214  else
215  value = find_file(value.to_string(), key);
216  }
217  else if (!missing_ok)
218  throw cet::exception("MARLEYHelper")
219  << "Missing \"" << key << "\" key in the MARLEY parameters.";
220 }
std::string find_file(const std::string &fileName, const std::string &fileType)
double value
Definition: spectrum.C:18
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void evgen::MARLEYHelper::load_marley_dictionaries ( )
protected

Definition at line 255 of file MARLEYHelper.cxx.

References fHelperName, and MF_LOG_INFO.

Referenced by MARLEYHelper().

256 {
257  static bool already_loaded_marley_dict = false;
258 
259  if (already_loaded_marley_dict) return;
260 
261  // Current (24 July 2016) versions of ROOT 6 require runtime
262  // loading of headers for custom classes in order to use
263  // dictionaries correctly. If we're running ROOT 6+, do the
264  // loading here, and give the user guidance if there are any
265  // problems.
266  //
267  // This is the same technique used in the MARLEY source code
268  // for the executable (src/marley.cc). If you change how this
269  // code works, please sync changes with the executable as well.
270  if (gROOT->GetVersionInt() >= 60000) {
271  MF_LOG_INFO("MARLEYHelper " + fHelperName)
272  << "ROOT 6 or greater"
273  << " detected. Loading class information\nfrom headers"
274  << " \"marley/Particle.hh\" and \"marley/Event.hh\"";
275  TInterpreter::EErrorCode* ec = new TInterpreter::EErrorCode();
276  gInterpreter->ProcessLine("#include \"marley/Particle.hh\"", ec);
277  if (*ec != 0)
278  throw cet::exception("MARLEYHelper " + fHelperName)
279  << "Error loading MARLEY header Particle.hh. For MARLEY headers stored"
280  << " in /path/to/include/marley/, please add /path/to/include"
281  << " to your ROOT_INCLUDE_PATH environment variable and"
282  << " try again.";
283  gInterpreter->ProcessLine("#include \"marley/Event.hh\"");
284  if (*ec != 0)
285  throw cet::exception("MARLEYHelper")
286  << "Error loading"
287  << " MARLEY header Event.hh. For MARLEY headers stored in"
288  << " /path/to/include/marley/, please add /path/to/include"
289  << " to your ROOT_INCLUDE_PATH environment variable and"
290  << " try again.";
291  }
292 
293  // No further action is required for ROOT 5 because the compiled
294  // dictionaries (which are linked to this algorithm) contain all of
295  // the needed information
296  already_loaded_marley_dict = true;
297 }
std::string fHelperName
Definition: MARLEYHelper.h:78
#define MF_LOG_INFO(category)
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void evgen::MARLEYHelper::reconfigure ( const fhicl::ParameterSet pset)

Definition at line 223 of file MARLEYHelper.cxx.

References fHelperName, fMarleyGenerator, evgen::MarleyParameterSetWalker::get_json(), load_full_paths_into_json(), MF_LOG_INFO, and fhicl::ParameterSet::walk().

Referenced by MARLEYHelper().

224 {
225  // Convert the FHiCL parameters into a JSON object that MARLEY can understand
227  pset.walk(mpsw);
228 
229  marley::JSON& json = mpsw.get_json();
230 
231  // Update the reaction and structure data file names to the full paths
232  // using cetlib to search for them
233  load_full_paths_into_json(json, "reactions", false);
234  load_full_paths_into_json(json, "structure", true);
235 
236  // Also update the path for a neutrino source spectrum given in a ROOT
237  // TFile
238  if (json.has_key("source")) {
239  marley::JSON& source_object = json.at("source");
240 
241  if (source_object.has_key("tfile")) { load_full_paths_into_json(source_object, "tfile"); }
242  }
243 
244  // Create a new MARLEY configuration based on the JSON parameters
245  MF_LOG_INFO("MARLEYHelper " + fHelperName) << "MARLEY will now use"
246  " the JSON configuration\n"
247  << json.dump_string() << '\n';
248  marley::RootJSONConfig config(json);
249 
250  // Create a new marley::Generator object based on the current configuration
251  fMarleyGenerator = std::make_unique<marley::Generator>(config.create_generator());
252 }
const marley::JSON & get_json() const
std::unique_ptr< marley::Generator > fMarleyGenerator
Definition: MARLEYHelper.h:75
std::string fHelperName
Definition: MARLEYHelper.h:78
void walk(ParameterSetWalker &psw) const
#define MF_LOG_INFO(category)
void load_full_paths_into_json(marley::JSON &json, const std::string &array_name, bool missing_ok=false)

Member Data Documentation

std::string evgen::MARLEYHelper::fHelperName
protected

Definition at line 78 of file MARLEYHelper.h.

Referenced by create_MCTruth(), load_marley_dictionaries(), MARLEYHelper(), and reconfigure().

std::unique_ptr<marley::Generator> evgen::MARLEYHelper::fMarleyGenerator
protected

Definition at line 75 of file MARLEYHelper.h.

Referenced by create_MCTruth(), MARLEYHelper(), and reconfigure().

std::stringstream evgen::MARLEYHelper::fMarleyLogStream
protected

Definition at line 82 of file MARLEYHelper.h.

Referenced by create_MCTruth(), and MARLEYHelper().


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