18 #include "art/Framework/Principal/Event.h"
19 #include "cetlib_except/exception.h"
20 #include "messagefacility/MessageLogger/MessageLogger.h"
21 #include "fhiclcpp/ParameterSet.h"
26 #include "CLHEP/Random/RandGaussQ.h"
28 #include "nugen/EventGeneratorBase/GENIE/GENIE2ART.h"
30 #include "nusimdata/SimulationBase/MCFlux.h"
31 #include "nusimdata/SimulationBase/MCTruth.h"
32 #include "nusimdata/SimulationBase/GTruth.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/RwFramework/GSystSet.h"
45 #include "GENIE/RwFramework/GSyst.h"
46 #include "GENIE/RwFramework/GReWeight.h"
47 #include "GENIE/RwCalculators/GReWeightNuXSecNCEL.h"
48 #include "GENIE/RwCalculators/GReWeightNuXSecCCQE.h"
49 #include "GENIE/RwCalculators/GReWeightNuXSecCCRES.h"
50 #include "GENIE/RwCalculators/GReWeightNuXSecCOH.h"
51 #include "GENIE/RwCalculators/GReWeightNonResonanceBkg.h"
52 #include "GENIE/RwCalculators/GReWeightFGM.h"
53 #include "GENIE/RwCalculators/GReWeightDISNuclMod.h"
54 #include "GENIE/RwCalculators/GReWeightResonanceDecay.h"
55 #include "GENIE/RwCalculators/GReWeightFZone.h"
56 #include "GENIE/RwCalculators/GReWeightINuke.h"
57 #include "GENIE/RwCalculators/GReWeightAGKY.h"
58 #include "GENIE/RwCalculators/GReWeightNuXSecCCQEaxial.h"
59 #include "GENIE/RwCalculators/GReWeightNuXSecCCQEvec.h"
60 #include "GENIE/RwCalculators/GReWeightNuXSecNCRES.h"
61 #include "GENIE/RwCalculators/GReWeightNuXSecDIS.h"
62 #include "GENIE/RwCalculators/GReWeightINukeParams.h"
63 #include "GENIE/RwCalculators/GReWeightNuXSecNC.h"
64 #include "GENIE/RwCalculators/GReWeightXSecEmpiricalMEC.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 = {
108 { genie::rew::GReWeightNuXSecCCQE::kModeNormAndMaShape,
111 kXSecTwkDial_NormCCQE,
112 kXSecTwkDial_MaCCQEshape,
113 kXSecTwkDial_E0CCQEshape
116 { genie::rew::GReWeightNuXSecCCQE::kModeMa,
123 { genie::rew::GReWeightNuXSecCCQE::kModeZExp,
126 kXSecTwkDial_ZNormCCQE,
127 kXSecTwkDial_ZExpA1CCQE,
128 kXSecTwkDial_ZExpA2CCQE,
129 kXSecTwkDial_ZExpA3CCQE,
130 kXSecTwkDial_ZExpA4CCQE
137 { genie::rew::GReWeightNuXSecCCRES::kModeNormAndMaMvShape,
140 kXSecTwkDial_NormCCRES,
141 kXSecTwkDial_MaCCRESshape,
142 kXSecTwkDial_MvCCRESshape
145 { genie::rew::GReWeightNuXSecCCRES::kModeMaMv,
148 kXSecTwkDial_MaCCRES,
156 { genie::rew::GReWeightNuXSecNCRES::kModeNormAndMaMvShape,
159 kXSecTwkDial_NormNCRES,
160 kXSecTwkDial_MaNCRESshape,
161 kXSecTwkDial_MvNCRESshape
164 { genie::rew::GReWeightNuXSecNCRES::kModeMaMv,
167 kXSecTwkDial_MaNCRES,
175 { genie::rew::GReWeightNuXSecDIS::kModeABCV12u,
183 { genie::rew::GReWeightNuXSecDIS::kModeABCV12uShape,
185 kXSecTwkDial_AhtBYshape,
186 kXSecTwkDial_BhtBYshape,
187 kXSecTwkDial_CV1uBYshape,
188 kXSecTwkDial_CV2uBYshape
197 bool valid_knob_name(
const std::string& knob_name, genie::rew::GSyst_t& knob ) {
199 if ( knob != kNullSystematic && knob != kNTwkDials ) {
200 if ( UNIMPLEMENTED_GENIE_KNOBS.count(knob) ) {
201 MF_LOG_WARNING(
"GENIEWeightCalc") <<
"Ignoring unimplemented GENIE"
202 <<
" knob " << knob_name;
207 throw cet::exception(__PRETTY_FUNCTION__) <<
"Encountered unrecognized"
208 "GENIE knob \"" << knob_name <<
'\"';
218 std::set< std::string > CALC_NAMES_THAT_IGNORE_TUNED_CV = {
"RootinoFix" };
227 void Configure(
const fhicl::ParameterSet& pset,
228 CLHEP::HepRandomEngine& engine)
override;
229 std::vector< std::vector<double> >
GetWeight(art::Event&
e)
override;
234 const std::vector<genie::rew::GSyst_t>& knob_vec);
237 const std::map<std::string, int>& modes_to_use);
252 CLHEP::HepRandomEngine& engine)
254 genie::Messenger* messenger = genie::Messenger::Instance();
262 genie::utils::app_init::MesgThresholds(
"Messenger_whisper.xml" );
269 MF_LOG_INFO(
"GENIEWeightCalc") <<
"Configuring GENIE weight"
270 <<
" calculator " << this->
GetName();
276 messenger->SetPriorityLevel(
"TransverseEnhancementFFModel",
285 const fhicl::ParameterSet& param_CVs = p.get<fhicl::ParameterSet>(
286 "genie_central_values", fhicl::ParameterSet() );
287 std::vector< std::string > CV_knob_names = param_CVs.get_all_keys();
290 std::map< genie::rew::GSyst_t, double > gsyst_to_cv_map;
291 genie::rew::GSyst_t temp_knob;
293 if ( !CV_knob_names.empty() && !
fQuietMode ) MF_LOG_INFO(
"GENIEWeightCalc")
294 <<
"Configuring non-default GENIE knob central values from input"
295 <<
" FHiCL parameter set";
297 for (
const auto& knob_name : CV_knob_names ) {
298 double CV_knob_value = param_CVs.get<
double>( knob_name );
299 if ( valid_knob_name(knob_name, temp_knob) ) {
300 if ( gsyst_to_cv_map.count( temp_knob ) ) {
301 throw cet::exception(__PRETTY_FUNCTION__) <<
"Duplicate central values"
302 <<
" were configured for the " << knob_name <<
" GENIE knob.";
304 gsyst_to_cv_map[ temp_knob ] = CV_knob_value;
306 MF_LOG_INFO(
"GENIEWeightCalc") <<
"Central value for the " << knob_name
307 <<
" knob was set to " << CV_knob_value;
313 const fhicl::ParameterSet& pset = p.get<fhicl::ParameterSet>(
GetName() );
314 auto const pars = pset.get< std::vector<std::string> >(
"parameter_list",
315 std::vector<std::string>() );
316 auto const par_sigmas = pset.get< std::vector<double> >(
"parameter_sigma",
317 std::vector<double>() );
321 auto const par_mins = pset.get< std::vector<double> >(
"parameter_min",
322 std::vector<double>() );
323 auto const par_maxes = pset.get< std::vector<double> >(
"parameter_max",
324 std::vector<double>() );
326 auto const mode = pset.get<std::string>(
"mode" );
328 bool sigmas_ok =
true;
329 std::string array_name_for_exception;
330 if (
mode.find(
"central_value") == std::string::npos
331 &&
mode.find(
"minmax") == std::string::npos )
335 if ( pars.size() != par_sigmas.size() ) {
337 array_name_for_exception =
"parameter_sigma";
340 else if (
mode.find(
"minmax") != std::string::npos ) {
341 if ( pars.size() != par_mins.size()
342 || pars.size() != par_maxes.size() )
347 array_name_for_exception =
"parameter_min and parameter_max";
352 throw cet::exception(__PRETTY_FUNCTION__) <<
GetName()
353 <<
"::Bad fcl configuration. parameter_list and "
354 << array_name_for_exception
355 <<
" need to have same number of parameters.";
358 if ( !pars.empty() && !
fQuietMode ) MF_LOG_INFO(
"GENIEWeightCalc") <<
"Configuring"
359 <<
" GENIE systematic knobs to be varied from the input FHiCL parameter set";
363 std::vector< genie::rew::GSyst_t > knobs_to_use;
364 for (
const auto& knob_name : pars ) {
365 if ( valid_knob_name(knob_name, temp_knob) ) knobs_to_use.push_back( temp_knob );
374 std::vector< genie::rew::GSyst_t > all_knobs_vec = knobs_to_use;
375 for (
const auto& pair : gsyst_to_cv_map ) {
376 genie::rew::GSyst_t cv_knob = pair.first;
377 auto begin = all_knobs_vec.cbegin();
378 auto end = all_knobs_vec.cend();
386 std::map< std::string, int >
391 size_t num_universes = 0u;
392 if (
mode.find(
"pm1sigma") != std::string::npos
393 ||
mode.find(
"minmax") != std::string::npos )
397 else if (
mode.find(
"multisim") != std::string::npos ) {
398 num_universes = pset.get<
size_t>(
"number_of_multisims" );
404 int dummy_seed = pset.get<
int>(
"random_seed" );
405 MF_LOG_INFO(
"GENIEWeightCalc") <<
"GENIE weight calculator "
406 << this->
GetName() <<
" will generate " << num_universes
407 <<
" multisim universes with random seed " << dummy_seed;
424 size_t num_usable_knobs = knobs_to_use.size();
425 std::vector< std::vector<double> > reweightingSigmas( num_usable_knobs );
427 for (
size_t k = 0u;
k < num_usable_knobs; ++
k ) {
428 reweightingSigmas[
k].resize( num_universes );
430 genie::rew::GSyst_t current_knob = knobs_to_use.at(
k );
432 for (
size_t u = 0u; u < num_universes; ++u ) {
433 if (
mode.find(
"multisim") != std::string::npos ) {
434 reweightingSigmas[
k][u] = par_sigmas[
k] * CLHEP::RandGaussQ::shoot(&engine, 0., 1.);
436 else if (
mode.find(
"pm1sigma") != std::string::npos ) {
438 reweightingSigmas[
k][u] = ( u == 0 ? 1. : -1. ) * par_sigmas.at(
k);
440 else if (
mode.find(
"minmax") != std::string::npos ) {
442 reweightingSigmas[
k][u] = ( u == 0 ? par_maxes.at(
k) : par_mins.at(
k) );
444 else if (
mode.find(
"central_value") != std::string::npos ) {
446 reweightingSigmas[
k][u] = 0.;
450 reweightingSigmas[
k][u] = par_sigmas[
k];
453 if ( !
fQuietMode ) MF_LOG_INFO(
"GENIEWeightCalc")
454 <<
"Set sigma for the " << genie::rew::GSyst::AsString( current_knob )
455 <<
" knob in universe #" << u <<
". sigma = "
456 << reweightingSigmas[
k][u];
462 if (
mode.find(
"minmax") == std::string::npos ) {
463 auto iter = gsyst_to_cv_map.find( current_knob );
464 if ( iter != gsyst_to_cv_map.end() ) {
465 reweightingSigmas[
k][u] += iter->second;
466 if ( !
fQuietMode ) MF_LOG_INFO(
"GENIEWeightCalc")
467 <<
"CV offset added to the "
468 << genie::rew::GSyst::AsString( current_knob )
469 <<
" knob. New sigma for universe #" << u <<
" is "
470 << reweightingSigmas[
k][u];
479 if ( !CALC_NAMES_THAT_IGNORE_TUNED_CV.count(
this->GetName()) ) {
484 for (
const auto& pair : gsyst_to_cv_map ) {
485 genie::rew::GSyst_t cv_knob = pair.first;
486 double cv_value = pair.second;
490 if ( !
std::count(knobs_to_use.cbegin(), knobs_to_use.cend(), cv_knob) ) {
492 knobs_to_use.push_back( cv_knob );
495 reweightingSigmas.emplace_back(
496 std::vector<double>(num_universes, cv_value) );
498 if ( !
fQuietMode ) MF_LOG_INFO(
"GENIEWeightCalc")
499 <<
"Tuned knob " << genie::rew::GSyst::AsString( cv_knob )
500 <<
" was not configured. Setting it to " << cv_value
501 <<
" in all " << num_universes <<
" universes.";
510 for (
size_t u = 0; u < reweightVector.size(); ++u ) {
512 auto& rwght = reweightVector.at( u );
513 genie::rew::GSystSet& syst = rwght.Systematics();
515 for (
unsigned int k = 0;
k < knobs_to_use.size(); ++
k ) {
516 genie::rew::GSyst_t knob = knobs_to_use.at(
k );
518 double twk_dial_value = reweightingSigmas.at(
k ).at( u );
519 syst.Set( knob, twk_dial_value );
522 MF_LOG_INFO(
"GENIEWeightCalc") <<
"In universe #" << u <<
", knob #" <<
k
523 <<
" (" << genie::rew::GSyst::AsString( knob ) <<
") was set to"
524 <<
" the value " << twk_dial_value;
539 art::Handle< std::vector<simb::MCTruth> > mcTruthHandle;
540 art::Handle< std::vector<simb::GTruth> > gTruthHandle;
546 std::vector< art::Ptr<simb::MCTruth> > mclist;
547 art::fill_ptr_vector( mclist, mcTruthHandle );
549 std::vector< art::Ptr<simb::GTruth > > glist;
550 art::fill_ptr_vector( glist, gTruthHandle );
552 size_t num_neutrinos = mclist.size();
556 std::vector< std::vector<double> > weights( num_neutrinos );
557 for (
size_t v = 0u; v < num_neutrinos; ++v ) {
562 std::unique_ptr< genie::EventRecord >
563 genie_event( evgb::RetrieveGHEP(*mclist[v], *glist[v]) );
573 genie::Interaction* interaction = genie_event->Summary();
574 genie::Kinematics* kine_ptr = interaction->KinePtr();
577 double ml = interaction->FSPrimLepton()->Mass();
579 const TLorentzVector& p4l = kine_ptr->FSLeptonP4();
581 double Tl = p4l.E() - ml;
583 double ctl = p4l.CosTheta();
585 kine_ptr->SetKV( kKVTl, Tl );
586 kine_ptr->SetKV( kKVctl, ctl );
590 weights[v].resize( num_knobs );
591 for (
size_t k = 0u;
k < num_knobs; ++
k ) {
600 const std::vector<genie::rew::GSyst_t>& knob_vec)
602 std::map< std::string, int > modes_to_use;
604 for (
const auto& knob : knob_vec ) {
605 for (
const auto& pair1 : INCOMPATIBLE_GENIE_KNOBS ) {
606 std::string calc_name = pair1.first;
607 const auto& mode_map = pair1.second;
608 for (
const auto& pair2 : mode_map ) {
609 int mode = pair2.first;
610 std::set<genie::rew::GSyst_t> knob_set = pair2.second;
612 if ( knob_set.count(knob) ) {
613 auto search = modes_to_use.find( calc_name );
614 if ( search != modes_to_use.end() ) {
615 if ( search->second != mode ) {
616 auto knob_str = genie::rew::GSyst::AsString( knob );
617 throw cet::exception(__PRETTY_FUNCTION__) << this->
GetName()
618 <<
": the GENIE knob " << knob_str <<
" is incompatible"
619 <<
" with others that are already configured";
622 else modes_to_use[ calc_name ] =
mode;
632 const std::map<std::string, int>& modes_to_use)
635 rw.AdoptWghtCalc(
"xsec_ncel",
new GReWeightNuXSecNCEL );
636 rw.AdoptWghtCalc(
"xsec_ccqe",
new GReWeightNuXSecCCQE );
637 rw.AdoptWghtCalc(
"xsec_ccqe_axial",
new GReWeightNuXSecCCQEaxial );
638 rw.AdoptWghtCalc(
"xsec_ccqe_vec",
new GReWeightNuXSecCCQEvec );
639 rw.AdoptWghtCalc(
"xsec_ccres",
new GReWeightNuXSecCCRES );
640 rw.AdoptWghtCalc(
"xsec_ncres",
new GReWeightNuXSecNCRES );
641 rw.AdoptWghtCalc(
"xsec_nonresbkg",
new GReWeightNonResonanceBkg );
642 rw.AdoptWghtCalc(
"xsec_coh",
new GReWeightNuXSecCOH );
643 rw.AdoptWghtCalc(
"xsec_dis",
new GReWeightNuXSecDIS );
644 rw.AdoptWghtCalc(
"nuclear_qe",
new GReWeightFGM );
645 rw.AdoptWghtCalc(
"hadro_res_decay",
new GReWeightResonanceDecay );
646 rw.AdoptWghtCalc(
"hadro_fzone",
new GReWeightFZone );
647 rw.AdoptWghtCalc(
"hadro_intranuke",
new GReWeightINuke );
648 rw.AdoptWghtCalc(
"hadro_agky",
new GReWeightAGKY );
649 rw.AdoptWghtCalc(
"xsec_nc",
new GReWeightNuXSecNC );
650 rw.AdoptWghtCalc(
"res_dk",
new GReWeightResonanceDecay );
651 rw.AdoptWghtCalc(
"xsec_empmec",
new GReWeightXSecEmpiricalMEC);
656 #ifdef GENIE_UB_PATCH
659 rw.AdoptWghtCalc(
"xsec_mec",
new GReWeightXSecMEC );
662 rw.AdoptWghtCalc(
"deltarad_angle",
new GReWeightDeltaradAngle );
663 rw.AdoptWghtCalc(
"xsec_coh_ub",
new GReWeightNuXSecCOHuB );
664 rw.AdoptWghtCalc(
"res_bug_fix",
new GReWeightRESBugFix );
669 for (
const auto& pair : modes_to_use ) {
670 std::string calc_name = pair.first;
671 int mode = pair.second;
673 genie::rew::GReWeightI* calc = rw.WghtCalc( calc_name );
674 if ( !calc )
throw cet::exception(__PRETTY_FUNCTION__)
675 <<
"Failed to retrieve the GENIE weight calculator labeled \""
676 << calc_name <<
'\"';
683 auto* calc_ccqe =
dynamic_cast< genie::rew::GReWeightNuXSecCCQE*
>( calc );
684 auto* calc_ccres =
dynamic_cast< genie::rew::GReWeightNuXSecCCRES*
>( calc );
685 auto* calc_ncres =
dynamic_cast< genie::rew::GReWeightNuXSecNCRES*
>( calc );
686 auto* calc_dis =
dynamic_cast< genie::rew::GReWeightNuXSecDIS*
>( calc );
687 if ( calc_ccqe ) calc_ccqe->SetMode( mode );
688 else if ( calc_ccres ) calc_ccres->SetMode( mode );
689 else if ( calc_ncres ) calc_ncres->SetMode( mode );
690 else if ( calc_dis ) calc_dis->SetMode( mode );
691 else throw cet::exception(__PRETTY_FUNCTION__)
692 <<
"Request to set the mode of an unrecognized GENIE weight calculator \""
693 << calc_name <<
'\"';
#define DECLARE_WEIGHTCALC(wghcalc)
std::vector< genie::rew::GReWeight > reweightVector
std::map< std::string, int > CheckForIncompatibleSystematics(const std::vector< genie::rew::GSyst_t > &knob_vec)
MF_LOG_WARNING("SimWire")<< "SimWire is an example module that works for the "<< "MicroBooNE detector. Each experiment should implement "<< "its own version of this module to simulate electronics "<< "response."
std::string FromString(const std::string &value)
auto end(FixedBins< T, C > const &) noexcept
std::vector< std::vector< double > > GetWeight(art::Event &e) override
auto begin(FixedBins< T, C > const &) noexcept
std::string fGenieModuleLabel
#define REGISTER_WEIGHTCALC(wghcalc)
void SetupWeightCalculators(genie::rew::GReWeight &rw, const std::map< std::string, int > &modes_to_use)
std::size_t count(Cont const &cont)
BEGIN_PROLOG don t mess with this pandoraTrackGausCryoW true
void Configure(const fhicl::ParameterSet &pset, CLHEP::HepRandomEngine &engine) override