10 #include "cetlib_except/exception.h"
11 #include "messagefacility/MessageLogger/MessageLogger.h"
16 #include "nusimdata/SimulationBase/MCParticle.h"
17 #include "nurandom/RandomUtils/NuRandomService.h"
20 #include "TInterpreter.h"
24 #include "marley/Event.hh"
25 #include "marley/Particle.hh"
26 #include "marley/RootJSONConfig.hh"
31 constexpr
double MeV_to_GeV = 1
e-3;
36 rndm::NuRandomService& rand_service,
const std::string& helper_name )
37 : fHelperName( helper_name )
49 rndm::NuRandomService::seed_t marley_seed = rand_service.registerEngine(
50 [
this](rndm::NuRandomService::EngineId
const& ,
51 rndm::NuRandomService::seed_t lar_seed) ->
void
54 auto seed =
static_cast<uint_fast64_t
>( lar_seed );
69 uint_fast64_t marley_cast_seed =
static_cast<uint_fast64_t
>( marley_seed );
84 const std::vector<marley::Particle*>& particles,
85 const TLorentzVector& vtx_pos,
bool track )
89 for (
const marley::Particle*
p : particles ) {
92 int trackID = -1 * ( truth.NParticles() + 1 );
94 int pdg =
p->pdg_code();
95 double mass =
p->mass() * MeV_to_GeV;
96 double px =
p->px() * MeV_to_GeV;
97 double py =
p->py() * MeV_to_GeV;
98 double pz =
p->pz() * MeV_to_GeV;
99 double E =
p->total_energy() * MeV_to_GeV;
100 TLorentzVector mom( px, py, pz, E );
103 if ( track ) status = 1;
105 simb::MCParticle part( trackID , pdg,
106 "MARLEY", -1 , mass, status );
108 part.AddTrajectoryPoint( vtx_pos, mom );
115 const TLorentzVector& vtx_pos, marley::Event* marley_event )
119 truth.SetOrigin( simb::kSuperNovaNeutrino );
121 marley::Event
event = fMarleyGenerator->create_event();
124 add_marley_particles( truth, event.get_initial_particles(), vtx_pos,
false );
125 add_marley_particles( truth, event.get_final_particles(), vtx_pos,
true );
128 const marley::Particle&
nu =
event.projectile();
129 const marley::Particle& lep =
event.ejectile();
130 double qx = nu.px() - lep.px();
131 double qy = nu.py() - lep.py();
132 double qz = nu.pz() - lep.pz();
133 double Enu = nu.total_energy();
134 double Elep = lep.total_energy();
135 double Q2 = qx*qx + qy*qy + qz*qz - std::pow(Enu - Elep, 2);
139 double bjorken_x = Q2 / (2 *
event.target().mass() * (Enu - Elep));
140 double inelasticity_y = 1. - Elep / Enu;
146 const marley::Particle& res =
event.residue();
147 double hadronic_mass_W = res.mass() +
event.Ex();
152 simb::kUnknownInteraction,
153 simb::kUnknownInteraction,
154 marley_utils::get_nucleus_pid(18, 40),
155 marley_utils::NEUTRON,
157 hadronic_mass_W * MeV_to_GeV,
160 Q2 * std::pow(MeV_to_GeV, 2)
163 if ( marley_event ) *marley_event = event;
168 while( std::getline(fMarleyLogStream, line) ) {
169 MF_LOG_INFO( fHelperName ) << line;
173 fMarleyLogStream = std::stringstream();
180 const std::string& fileType )
182 cet::search_path searchPath(
"FW_SEARCH_PATH" );
184 std::string fullName;
185 searchPath.find_file( fileName, fullName );
187 if ( fullName.empty() )
188 throw cet::exception(
"MARLEYHelper" )
189 <<
"Cannot find MARLEY " << fileType <<
" data file '"
197 marley::JSON& json,
const std::string& key,
bool missing_ok )
199 if ( json.has_key(key) ) {
201 marley::JSON&
value = json.at(key);
203 if ( value.is_array() ) {
206 for (
auto&
element : value.array_range() ) {
211 else value = find_file(value.to_string(), key);
213 else if ( !missing_ok )
throw cet::exception(
"MARLEYHelper")
214 <<
"Missing \"" << key <<
"\" key in the MARLEY parameters.";
224 marley::JSON& json = mpsw.
get_json();
228 load_full_paths_into_json( json,
"reactions",
false );
229 load_full_paths_into_json( json,
"structure",
true );
233 if ( json.has_key(
"source") ) {
234 marley::JSON& source_object = json.at(
"source" );
236 if ( source_object.has_key(
"tfile") ) {
237 load_full_paths_into_json( source_object,
"tfile" );
242 MF_LOG_INFO(
"MARLEYHelper " + fHelperName ) <<
"MARLEY will now use"
243 " the JSON configuration\n" << json.dump_string() <<
'\n';
244 marley::RootJSONConfig config( json );
247 fMarleyGenerator = std::make_unique<marley::Generator>(
248 config.create_generator() );
254 static bool already_loaded_marley_dict =
false;
256 if ( already_loaded_marley_dict )
return;
267 if ( gROOT->GetVersionInt() >= 60000 ) {
268 MF_LOG_INFO(
"MARLEYHelper " + fHelperName ) <<
"ROOT 6 or greater"
269 <<
" detected. Loading class information\nfrom headers"
270 <<
" \"marley/Particle.hh\" and \"marley/Event.hh\"";
271 TInterpreter::EErrorCode* ec =
new TInterpreter::EErrorCode();
272 gInterpreter->ProcessLine(
"#include \"marley/Particle.hh\"", ec );
273 if ( *ec != 0 )
throw cet::exception(
"MARLEYHelper " + fHelperName )
274 <<
"Error loading MARLEY header Particle.hh. For MARLEY headers stored"
275 <<
" in /path/to/include/marley/, please add /path/to/include"
276 <<
" to your ROOT_INCLUDE_PATH environment variable and"
278 gInterpreter->ProcessLine(
"#include \"marley/Event.hh\"" );
279 if ( *ec != 0 )
throw cet::exception(
"MARLEYHelper" ) <<
"Error loading"
280 <<
" MARLEY header Event.hh. For MARLEY headers stored in"
281 <<
" /path/to/include/marley/, please add /path/to/include"
282 <<
" to your ROOT_INCLUDE_PATH environment variable and"
289 already_loaded_marley_dict =
true;
LArSoft interface to the MARLEY (Model of Argon Reaction Low Energy Yields) supernova neutrino event ...
void load_marley_dictionaries()
std::unique_ptr< marley::Generator > fMarleyGenerator
void add_marley_particles(simb::MCTruth &truth, const std::vector< marley::Particle * > &particles, const TLorentzVector &vtx_pos, bool track)
MARLEYHelper(const fhicl::ParameterSet &pset, rndm::NuRandomService &rand_service, const std::string &generator_name)
simb::MCTruth create_MCTruth(const TLorentzVector &vtx_pos, marley::Event *marley_event=nullptr)
Concrete fhicl::ParameterSetWalker that converts a fhicl::ParameterSet into a marley::JSON object...
process_name use argoneut_mc_hitfinder track
const marley::JSON & get_json() const
std::stringstream fMarleyLogStream
std::string find_file(const std::string &fileName, const std::string &fileType)
Charged-current interactions.
void reconfigure(const fhicl::ParameterSet &pset)
void load_full_paths_into_json(marley::JSON &json, const std::string &array_name, bool missing_ok=false)
process_name physics producers generator physics producers generator physics producers generator py
services TFileService fileName
BEGIN_PROLOG don t mess with this pandoraTrackGausCryoW true