19 #include "cetlib_except/exception.h" 26 #include "CLHEP/Random/RandGaussQ.h" 37 #include "GENIE/Framework/Conventions/KineVar.h" 38 #include "GENIE/Framework/EventGen/EventRecord.h" 39 #include "GENIE/Framework/Interaction/Interaction.h" 40 #include "GENIE/Framework/Interaction/Kinematics.h" 41 #include "GENIE/Framework/Messenger/Messenger.h" 42 #include "GENIE/Framework/Utils/AppInit.h" 44 #include "GENIE/RwCalculators/GReWeightAGKY.h" 45 #include "GENIE/RwCalculators/GReWeightDISNuclMod.h" 46 #include "GENIE/RwCalculators/GReWeightFGM.h" 47 #include "GENIE/RwCalculators/GReWeightFZone.h" 48 #include "GENIE/RwCalculators/GReWeightINuke.h" 49 #include "GENIE/RwCalculators/GReWeightINukeParams.h" 50 #include "GENIE/RwCalculators/GReWeightNonResonanceBkg.h" 51 #include "GENIE/RwCalculators/GReWeightNuXSecCCQE.h" 52 #include "GENIE/RwCalculators/GReWeightNuXSecCCQEaxial.h" 53 #include "GENIE/RwCalculators/GReWeightNuXSecCCQEvec.h" 54 #include "GENIE/RwCalculators/GReWeightNuXSecCCRES.h" 55 #include "GENIE/RwCalculators/GReWeightNuXSecCOH.h" 56 #include "GENIE/RwCalculators/GReWeightNuXSecDIS.h" 57 #include "GENIE/RwCalculators/GReWeightNuXSecNC.h" 58 #include "GENIE/RwCalculators/GReWeightNuXSecNCEL.h" 59 #include "GENIE/RwCalculators/GReWeightNuXSecNCRES.h" 60 #include "GENIE/RwCalculators/GReWeightResonanceDecay.h" 61 #include "GENIE/RwCalculators/GReWeightXSecEmpiricalMEC.h" 62 #include "GENIE/RwFramework/GReWeight.h" 63 #include "GENIE/RwFramework/GSyst.h" 64 #include "GENIE/RwFramework/GSystSet.h" 71 #include "GENIE/RwCalculators/GReWeightXSecMEC.h" 74 #include "GENIE/RwCalculators/GReWeightDeltaradAngle.h" 75 #include "GENIE/RwCalculators/GReWeightNuXSecCOHuB.h" 76 #include "GENIE/RwCalculators/GReWeightRESBugFix.h" 85 std::set<genie::rew::GSyst_t> UNIMPLEMENTED_GENIE_KNOBS = {
86 kXSecTwkDial_RnubarnuCC,
87 kXSecTwkDial_NormCCQEenu,
88 kXSecTwkDial_NormDISCC,
89 kXSecTwkDial_DISNuclMod
105 std::map<std::string, std::map<int, std::set<genie::rew::GSyst_t>>> INCOMPATIBLE_GENIE_KNOBS = {
109 {genie::rew::GReWeightNuXSecCCQE::kModeNormAndMaShape,
112 kXSecTwkDial_NormCCQE,
113 kXSecTwkDial_MaCCQEshape,
114 kXSecTwkDial_E0CCQEshape
116 {genie::rew::GReWeightNuXSecCCQE::kModeMa,
122 {genie::rew::GReWeightNuXSecCCQE::kModeZExp,
125 kXSecTwkDial_ZNormCCQE,
126 kXSecTwkDial_ZExpA1CCQE,
127 kXSecTwkDial_ZExpA2CCQE,
128 kXSecTwkDial_ZExpA3CCQE,
129 kXSecTwkDial_ZExpA4CCQE
135 {{genie::rew::GReWeightNuXSecCCRES::kModeNormAndMaMvShape,
138 kXSecTwkDial_NormCCRES,
139 kXSecTwkDial_MaCCRESshape,
140 kXSecTwkDial_MvCCRESshape
142 {genie::rew::GReWeightNuXSecCCRES::kModeMaMv,
145 kXSecTwkDial_MaCCRES,
151 {{genie::rew::GReWeightNuXSecNCRES::kModeNormAndMaMvShape,
154 kXSecTwkDial_NormNCRES,
155 kXSecTwkDial_MaNCRESshape,
156 kXSecTwkDial_MvNCRESshape
158 {genie::rew::GReWeightNuXSecNCRES::kModeMaMv,
161 kXSecTwkDial_MaNCRES,
167 {{genie::rew::GReWeightNuXSecDIS::kModeABCV12u,
174 {genie::rew::GReWeightNuXSecDIS::kModeABCV12uShape,
176 kXSecTwkDial_AhtBYshape,
177 kXSecTwkDial_BhtBYshape,
178 kXSecTwkDial_CV1uBYshape,
179 kXSecTwkDial_CV2uBYshape
184 bool valid_knob_name(
const std::string& knob_name, genie::rew::GSyst_t& knob)
186 knob = genie::rew::GSyst::FromString(knob_name);
187 if (knob != kNullSystematic && knob != kNTwkDials) {
188 if (UNIMPLEMENTED_GENIE_KNOBS.count(knob)) {
189 MF_LOG_WARNING(
"GENIEWeightCalc") <<
"Ignoring unimplemented GENIE" 190 <<
" knob " << knob_name;
195 throw cet::exception(__PRETTY_FUNCTION__) <<
"Encountered unrecognized" 197 << knob_name <<
'\"';
206 std::set<std::string> CALC_NAMES_THAT_IGNORE_TUNED_CV = {
"RootinoFix"};
219 const std::vector<genie::rew::GSyst_t>& knob_vec);
222 const std::map<std::string, int>& modes_to_use);
237 genie::Messenger* messenger = genie::Messenger::Instance();
244 if (
fQuietMode) { genie::utils::app_init::MesgThresholds(
"Messenger_whisper.xml"); }
248 messenger->SetPriorityLevel(
"ReW", log4cpp::Priority::DEBUG);
250 MF_LOG_INFO(
"GENIEWeightCalc") <<
"Configuring GENIE weight" 251 <<
" calculator " << this->
GetName();
257 messenger->SetPriorityLevel(
"TransverseEnhancementFFModel", log4cpp::Priority::WARN);
258 messenger->SetPriorityLevel(
"Nieves", log4cpp::Priority::WARN);
267 std::vector<std::string> CV_knob_names = param_CVs.
get_all_keys();
270 std::map<genie::rew::GSyst_t, double> gsyst_to_cv_map;
271 genie::rew::GSyst_t temp_knob;
275 <<
"Configuring non-default GENIE knob central values from input" 276 <<
" FHiCL parameter set";
278 for (
const auto& knob_name : CV_knob_names) {
279 double CV_knob_value = param_CVs.get<
double>(knob_name);
280 if (valid_knob_name(knob_name, temp_knob)) {
281 if (gsyst_to_cv_map.count(temp_knob)) {
283 <<
"Duplicate central values" 284 <<
" were configured for the " << knob_name <<
" GENIE knob.";
286 gsyst_to_cv_map[temp_knob] = CV_knob_value;
289 <<
"Central value for the " << knob_name <<
" knob was set to " << CV_knob_value;
297 pset.
get<std::vector<std::string>>(
"parameter_list", std::vector<std::string>());
298 auto const par_sigmas = pset.
get<std::vector<double>>(
"parameter_sigma", std::vector<double>());
302 auto const par_mins = pset.
get<std::vector<double>>(
"parameter_min", std::vector<double>());
303 auto const par_maxes = pset.
get<std::vector<double>>(
"parameter_max", std::vector<double>());
305 auto const mode = pset.
get<std::string>(
"mode");
307 bool sigmas_ok =
true;
308 std::string array_name_for_exception;
309 if (mode.find(
"central_value") == std::string::npos &&
310 mode.find(
"minmax") == std::string::npos) {
313 if (pars.size() != par_sigmas.size()) {
315 array_name_for_exception =
"parameter_sigma";
318 else if (mode.find(
"minmax") != std::string::npos) {
319 if (pars.size() != par_mins.size() || pars.size() != par_maxes.size()) {
323 array_name_for_exception =
"parameter_min and parameter_max";
329 <<
GetName() <<
"::Bad fcl configuration. parameter_list and " << array_name_for_exception
330 <<
" need to have same number of parameters.";
336 <<
" GENIE systematic knobs to be varied from the input FHiCL parameter set";
340 std::vector<genie::rew::GSyst_t> knobs_to_use;
341 for (
const auto& knob_name : pars) {
342 if (valid_knob_name(knob_name, temp_knob)) knobs_to_use.push_back(temp_knob);
351 std::vector<genie::rew::GSyst_t> all_knobs_vec = knobs_to_use;
352 for (
const auto& pair : gsyst_to_cv_map) {
353 genie::rew::GSyst_t cv_knob = pair.first;
354 auto begin = all_knobs_vec.cbegin();
355 auto end = all_knobs_vec.cend();
356 if (!std::count(
begin,
end, cv_knob)) all_knobs_vec.push_back(cv_knob);
367 size_t num_universes = 0u;
368 if (mode.find(
"pm1sigma") != std::string::npos || mode.find(
"minmax") != std::string::npos) {
371 else if (mode.find(
"multisim") != std::string::npos) {
372 num_universes = pset.
get<
size_t>(
"number_of_multisims");
378 int dummy_seed = pset.
get<
int>(
"random_seed");
380 <<
"GENIE weight calculator " << this->
GetName() <<
" will generate " << num_universes
381 <<
" multisim universes with random seed " << dummy_seed;
398 size_t num_usable_knobs = knobs_to_use.size();
399 std::vector<std::vector<double>> reweightingSigmas(num_usable_knobs);
401 for (
size_t k = 0u; k < num_usable_knobs; ++k) {
402 reweightingSigmas[k].resize(num_universes);
404 genie::rew::GSyst_t current_knob = knobs_to_use.at(k);
406 for (
size_t u = 0u; u < num_universes; ++u) {
407 if (mode.find(
"multisim") != std::string::npos) {
408 reweightingSigmas[k][u] = par_sigmas[k] * CLHEP::RandGaussQ::shoot(&engine, 0., 1.);
410 else if (mode.find(
"pm1sigma") != std::string::npos) {
412 reweightingSigmas[k][u] = (u == 0 ? 1. : -1.) * par_sigmas.at(k);
414 else if (mode.find(
"minmax") != std::string::npos) {
416 reweightingSigmas[k][u] = (u == 0 ? par_maxes.at(k) : par_mins.at(k));
418 else if (mode.find(
"central_value") != std::string::npos) {
420 reweightingSigmas[k][u] = 0.;
424 reweightingSigmas[k][u] = par_sigmas[k];
429 <<
"Set sigma for the " << genie::rew::GSyst::AsString(current_knob)
430 <<
" knob in universe #" << u <<
". sigma = " << reweightingSigmas[k][u];
436 if (mode.find(
"minmax") == std::string::npos) {
437 auto iter = gsyst_to_cv_map.find(current_knob);
438 if (iter != gsyst_to_cv_map.end()) {
439 reweightingSigmas[k][u] += iter->second;
442 <<
"CV offset added to the " << genie::rew::GSyst::AsString(current_knob)
443 <<
" knob. New sigma for universe #" << u <<
" is " << reweightingSigmas[k][u];
452 if (!CALC_NAMES_THAT_IGNORE_TUNED_CV.count(this->GetName())) {
457 for (
const auto& pair : gsyst_to_cv_map) {
458 genie::rew::GSyst_t cv_knob = pair.first;
459 double cv_value = pair.second;
463 if (!std::count(knobs_to_use.cbegin(), knobs_to_use.cend(), cv_knob)) {
465 knobs_to_use.push_back(cv_knob);
468 reweightingSigmas.emplace_back(std::vector<double>(num_universes, cv_value));
471 MF_LOG_INFO(
"GENIEWeightCalc") <<
"Tuned knob " << genie::rew::GSyst::AsString(cv_knob)
472 <<
" was not configured. Setting it to " << cv_value
473 <<
" in all " << num_universes <<
" universes.";
482 for (
size_t u = 0; u < reweightVector.size(); ++u) {
484 auto& rwght = reweightVector.at(u);
485 genie::rew::GSystSet& syst = rwght.Systematics();
487 for (
unsigned int k = 0; k < knobs_to_use.size(); ++k) {
488 genie::rew::GSyst_t knob = knobs_to_use.at(k);
490 double twk_dial_value = reweightingSigmas.at(k).at(u);
491 syst.Set(knob, twk_dial_value);
494 MF_LOG_INFO(
"GENIEWeightCalc") <<
"In universe #" << u <<
", knob #" << k <<
" (" 495 << genie::rew::GSyst::AsString(knob) <<
") was set to" 496 <<
" the value " << twk_dial_value;
511 size_t num_neutrinos = mcTruth.size();
515 std::vector<std::vector<double>> weights(num_neutrinos);
516 for (
size_t v = 0u; v < num_neutrinos; ++v) {
521 std::unique_ptr<genie::EventRecord> genie_event(
evgb::RetrieveGHEP(mcTruth[v], gTruth[v]));
531 genie::Interaction*
interaction = genie_event->Summary();
532 genie::Kinematics* kine_ptr = interaction->KinePtr();
535 double ml = interaction->FSPrimLepton()->Mass();
537 const TLorentzVector& p4l = kine_ptr->FSLeptonP4();
539 double Tl = p4l.E() - ml;
541 double ctl = p4l.CosTheta();
543 kine_ptr->SetKV(kKVTl, Tl);
544 kine_ptr->SetKV(kKVctl, ctl);
548 weights[v].resize(num_knobs);
549 for (
size_t k = 0u; k < num_knobs; ++k) {
557 const std::vector<genie::rew::GSyst_t>& knob_vec)
559 std::map<std::string, int> modes_to_use;
561 for (
const auto& knob : knob_vec) {
562 for (
const auto& pair1 : INCOMPATIBLE_GENIE_KNOBS) {
563 std::string calc_name = pair1.first;
564 const auto& mode_map = pair1.second;
565 for (
const auto& pair2 : mode_map) {
566 int mode = pair2.first;
567 std::set<genie::rew::GSyst_t> knob_set = pair2.second;
569 if (knob_set.count(knob)) {
570 auto search = modes_to_use.find(calc_name);
571 if (search != modes_to_use.end()) {
572 if (search->second != mode) {
573 auto knob_str = genie::rew::GSyst::AsString(knob);
575 << this->
GetName() <<
": the GENIE knob " << knob_str <<
" is incompatible" 576 <<
" with others that are already configured";
580 modes_to_use[calc_name] = mode;
590 const std::map<std::string, int>& modes_to_use)
593 rw.AdoptWghtCalc(
"xsec_ncel",
new GReWeightNuXSecNCEL);
594 rw.AdoptWghtCalc(
"xsec_ccqe",
new GReWeightNuXSecCCQE);
595 rw.AdoptWghtCalc(
"xsec_ccqe_axial",
new GReWeightNuXSecCCQEaxial);
596 rw.AdoptWghtCalc(
"xsec_ccqe_vec",
new GReWeightNuXSecCCQEvec);
597 rw.AdoptWghtCalc(
"xsec_ccres",
new GReWeightNuXSecCCRES);
598 rw.AdoptWghtCalc(
"xsec_ncres",
new GReWeightNuXSecNCRES);
599 rw.AdoptWghtCalc(
"xsec_nonresbkg",
new GReWeightNonResonanceBkg);
600 rw.AdoptWghtCalc(
"xsec_coh",
new GReWeightNuXSecCOH);
601 rw.AdoptWghtCalc(
"xsec_dis",
new GReWeightNuXSecDIS);
602 rw.AdoptWghtCalc(
"nuclear_qe",
new GReWeightFGM);
603 rw.AdoptWghtCalc(
"hadro_res_decay",
new GReWeightResonanceDecay);
604 rw.AdoptWghtCalc(
"hadro_fzone",
new GReWeightFZone);
605 rw.AdoptWghtCalc(
"hadro_intranuke",
new GReWeightINuke);
606 rw.AdoptWghtCalc(
"hadro_agky",
new GReWeightAGKY);
607 rw.AdoptWghtCalc(
"xsec_nc",
new GReWeightNuXSecNC);
608 rw.AdoptWghtCalc(
"res_dk",
new GReWeightResonanceDecay);
609 rw.AdoptWghtCalc(
"xsec_empmec",
new GReWeightXSecEmpiricalMEC);
614 #ifdef GENIE_UB_PATCH 617 rw.AdoptWghtCalc(
"xsec_mec",
new GReWeightXSecMEC);
620 rw.AdoptWghtCalc(
"deltarad_angle",
new GReWeightDeltaradAngle);
621 rw.AdoptWghtCalc(
"xsec_coh_ub",
new GReWeightNuXSecCOHuB);
622 rw.AdoptWghtCalc(
"res_bug_fix",
new GReWeightRESBugFix);
627 for (
const auto& pair : modes_to_use) {
628 std::string calc_name = pair.first;
629 int mode = pair.second;
631 genie::rew::GReWeightI* calc = rw.WghtCalc(calc_name);
634 <<
"Failed to retrieve the GENIE weight calculator labeled \"" << calc_name <<
'\"';
641 auto* calc_ccqe =
dynamic_cast<genie::rew::GReWeightNuXSecCCQE*
>(calc);
642 auto* calc_ccres =
dynamic_cast<genie::rew::GReWeightNuXSecCCRES*
>(calc);
643 auto* calc_ncres =
dynamic_cast<genie::rew::GReWeightNuXSecNCRES*
>(calc);
644 auto* calc_dis =
dynamic_cast<genie::rew::GReWeightNuXSecDIS*
>(calc);
646 calc_ccqe->SetMode(mode);
648 calc_ccres->SetMode(mode);
650 calc_ncres->SetMode(mode);
652 calc_dis->SetMode(mode);
655 <<
"Request to set the mode of an unrecognized GENIE weight calculator \"" << calc_name
genie::EventRecord * RetrieveGHEP(const simb::MCTruth &truth, const simb::GTruth >ruth, bool useFirstTrajPosition=true)
return genie::EventRecord pointer; callee takes possession
Functions for transforming GENIE objects into ART objects (and back)
std::map< std::string, int > CheckForIncompatibleSystematics(const std::vector< genie::rew::GSyst_t > &knob_vec)
object containing MC flux information
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
#define DECLARE_WEIGHTCALC(wghcalc)
T get(std::string const &key) const
std::vector< std::vector< double > > GetWeight(art::Event &e) override
#define MF_LOG_INFO(category)
std::vector< std::string > get_all_keys() const
std::string fGenieModuleLabel
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
void SetupWeightCalculators(genie::rew::GReWeight &rw, const std::map< std::string, int > &modes_to_use)
#define MF_LOG_WARNING(category)
PROD const & getProduct(InputTag const &tag) const
std::vector< genie::rew::GReWeight > reweightVector
cet::coded_exception< error, detail::translate > exception
#define REGISTER_WEIGHTCALC(wghcalc)
void Configure(const fhicl::ParameterSet &pset, CLHEP::HepRandomEngine &engine) override