5#include "SimCore/Reweight/GenieReweightProducer.h"
11#include "Framework/EventGen/HepMC3Converter.h"
12#include "Framework/Interaction/Interaction.h"
13#include "Framework/Messenger/Messenger.h"
14#include "Framework/Utils/AppInit.h"
15#include "Framework/Utils/RunOpt.h"
16#include "HepMC3/GenEvent.h"
17#include "HepMC3/PrintStreams.h"
18#include "RwCalculators/GReWeightFZone.h"
19#include "RwCalculators/GReWeightINuke.h"
20#include "RwCalculators/GReWeightXSecEmpiricalMEC.h"
21#include "RwFramework/GReWeight.h"
22#include "RwFramework/GSyst.h"
23#include "RwFramework/GSystSet.h"
24#include "SimCore/Event/EventWeights.h"
25#include "SimCore/Event/HepMC3GenEvent.h"
29GenieReweightProducer::GenieReweightProducer(
const std::string& name,
31 : Producer(name, process) {
32 hep_mc3_converter_ = std::make_unique<genie::HepMC3Converter>();
33 genie_rw_ = std::make_unique<genie::rew::GReWeight>();
37 hepmc3_coll_name_ = ps.
get<std::string>(
"hepmc3_coll_name");
38 hepmc3_pass_name_ = ps.
get<std::string>(
"hepmc3_pass_name");
39 event_weights_coll_name_ = ps.
get<std::string>(
"event_weights_coll_name");
40 seed_ = ps.
get<
int>(
"seed");
41 n_weights_ =
static_cast<size_t>(ps.
get<
int>(
"n_weights"));
42 auto var_types_strings = ps.
get<std::vector<std::string> >(
"var_types");
44 message_threshold_file_ = ps.
get<std::string>(
"message_threshold_file");
46 std::default_random_engine generator(seed_);
47 std::normal_distribution<double> normal_distribution;
49 for (
auto const& vt_str : var_types_strings) {
50 auto vtype = ldmx::EventWeights::stringToVariationType(vt_str);
51 for (
size_t i_w = 0; i_w < n_weights_; ++i_w)
52 variation_map_[vtype].push_back(normal_distribution(generator));
56void GenieReweightProducer::reinitializeGenieReweight() {
57 genie_rw_ = std::make_unique<genie::rew::GReWeight>();
60 genie::utils::app_init::MesgThresholds(message_threshold_file_);
62 genie::RunOpt::Instance()->SetTuneName(tune_);
63 if (!genie::RunOpt::Instance()->Tune()) {
64 EXCEPTION_RAISE(
"ConfigurationException",
"No TuneId in RunOption.");
66 genie::RunOpt::Instance()->BuildTune();
68 genie_rw_->AdoptWghtCalc(
"hadro_fzone",
new genie::rew::GReWeightFZone);
69 genie_rw_->AdoptWghtCalc(
"hadro_intranuke",
new genie::rew::GReWeightINuke);
71 auto& syst = genie_rw_->Systematics();
72 for (
auto var : variation_map_)
73 syst.Init(variationTypeToGenieDial(var.first));
77 const std::string genie_tune_par =
"GenieTune";
80 if (par.first.size() >= genie_tune_par.size() &&
81 par.first.compare(par.first.size() - genie_tune_par.size(),
82 genie_tune_par.size(), genie_tune_par) == 0) {
83 new_tune = par.second;
87 if (tune_ != new_tune) {
88 ldmx_log(debug) <<
"Found new tune " << new_tune <<
" (used to be " << tune_
91 reinitializeGenieReweight();
95void GenieReweightProducer::reconfigureGenieReweight(
size_t i_w) {
96 auto& syst = genie_rw_->Systematics();
97 for (
auto var : variation_map_) {
99 ldmx::EventWeights::VariationType::kGENIE_INukeTwkDial_MFP_pi)
100 syst.Set(genie::rew::GSyst::FromString(
"MFP_pi"), var.second[i_w]);
101 else if (var.first ==
102 ldmx::EventWeights::VariationType::kGENIE_INukeTwkDial_MFP_N)
103 syst.Set(genie::rew::GSyst::FromString(
"MFP_N"), var.second[i_w]);
104 else if (var.first ==
105 ldmx::EventWeights::VariationType::kGENIE_INukeTwkDial_FrCEx_pi)
106 syst.Set(genie::rew::GSyst::FromString(
"FrCEx_pi"), var.second[i_w]);
107 else if (var.first ==
108 ldmx::EventWeights::VariationType::kGENIE_INukeTwkDial_FrInel_pi)
109 syst.Set(genie::rew::GSyst::FromString(
"FrInel_pi"), var.second[i_w]);
110 else if (var.first ==
111 ldmx::EventWeights::VariationType::kGENIE_INukeTwkDial_FrAbs_pi)
112 syst.Set(genie::rew::GSyst::FromString(
"FrAbs_pi"), var.second[i_w]);
113 else if (var.first ==
114 ldmx::EventWeights::VariationType::kGENIE_INukeTwkDial_FrPiProd_pi)
115 syst.Set(genie::rew::GSyst::FromString(
"FrPiProd_pi"), var.second[i_w]);
116 else if (var.first ==
117 ldmx::EventWeights::VariationType::kGENIE_INukeTwkDial_FrCEx_N)
118 syst.Set(genie::rew::GSyst::FromString(
"FrCEx_N"), var.second[i_w]);
119 else if (var.first ==
120 ldmx::EventWeights::VariationType::kGENIE_INukeTwkDial_FrInel_N)
121 syst.Set(genie::rew::GSyst::FromString(
"FrInel_N"), var.second[i_w]);
122 else if (var.first ==
123 ldmx::EventWeights::VariationType::kGENIE_INukeTwkDial_FrAbs_N)
124 syst.Set(genie::rew::GSyst::FromString(
"FrAbs_N"), var.second[i_w]);
125 else if (var.first ==
126 ldmx::EventWeights::VariationType::kGENIE_INukeTwkDial_FrPiProd_N)
127 syst.Set(genie::rew::GSyst::FromString(
"FrPiProd_N"), var.second[i_w]);
128 else if (var.first ==
129 ldmx::EventWeights::VariationType::kGENIE_HadrNuclTwkDial_FormZone)
130 syst.Set(genie::rew::GSyst::FromString(
"FormZone"), var.second[i_w]);
132 genie_rw_->Reconfigure();
139 if (!event.
exists(hepmc3_coll_name_, hepmc3_pass_name_)) {
141 for (
size_t i_w = 0; i_w < n_weights_; ++i_w) {
142 ev_weights.addWeight(1.0);
144 event.add(event_weights_coll_name_, ev_weights);
148 const auto& hepmc3_col =
event.getObject<std::vector<ldmx::HepMC3GenEvent> >(
149 hepmc3_coll_name_, hepmc3_pass_name_);
151 if (hepmc3_col.empty()) {
153 for (
size_t i_w = 0; i_w < n_weights_; ++i_w) {
154 ev_weights.addWeight(1.0);
156 event.add(event_weights_coll_name_, ev_weights);
163 for (
size_t i_w = 0; i_w < n_weights_; ++i_w) {
164 double running_weight = 1;
166 reconfigureGenieReweight(i_w);
170 for (
size_t i_ev = 0; i_ev < 1; ++i_ev) {
171 auto const& hepmc3_ev = hepmc3_col.at(i_ev);
173 HepMC3::GenEvent hepmc3_genev;
174 hepmc3_genev.read_data(hepmc3_ev);
177 if (i_w == 0) ldmx_log(debug) << hepmc3_genev;
180 auto genie_ev_record_ptr = hep_mc3_converter_->RetrieveGHEP(hepmc3_genev);
183 if (i_w == 0) ldmx_log(debug) << *genie_ev_record_ptr;
186 auto this_weight = genie_rw_->CalcWeight(*genie_ev_record_ptr);
188 running_weight = running_weight * this_weight;
192 ev_weights.addWeight(running_weight);
196 ldmx_log(trace) << ev_weights;
198 event.add(event_weights_coll_name_, ev_weights);
#define DECLARE_PRODUCER(CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
Implements an event buffer system for storing event data.
bool exists(const std::string &name, const std::string &passName, bool unique=true) const
Check for the existence of an object or collection with the given name and pass name in the event.
Class which represents the process under execution.
Class encapsulating parameters for configuring a processor.
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Dynamically loadable photonuclear models either from SimCore or external libraries implementing this ...