All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sbncode/sbncode/SBNEventWeight/Calculators/CrossSections/GenieWeightCalc.cxx
Go to the documentation of this file.
1 // GenieWeightCalc.cxx
2 //
3 // Handles event weights for GENIE systematics studies
4 //
5 // Updated by Marco Del Tutto on Feb 18 2017
6 //
7 // Ported from uboonecode to larsim on Feb 14 2017
8 // by Marco Del Tutto <marco.deltutto@physics.ox.ac.uk>
9 //
10 // Heavily rewritten on Dec 9 2019
11 // by Steven Gardiner <gardiner@fnal.gov>
12 // Updated for merge into larsim develop branch on Feb 22 2021 by Steven Gardiner
13 //
14 // Ported from larsim in Oct. 2021,
15 // Assign strange-CCQE events weight as 1 to avoid crashing
16 // ub specific packages are not ready to be used unless GENIE v3.2 is used
17 // by Keng Lin
18 //-----------------------------------------------------------
19 
20 // Standard library includes
21 #include <map>
22 #include <memory>
23 #include <set>
24 
25 // Framework includes
26 #include "art/Framework/Principal/Event.h"
27 #include "cetlib_except/exception.h"
28 #include "messagefacility/MessageLogger/MessageLogger.h"
29 
32 
33 #include "nugen/EventGeneratorBase/GENIE/GENIE2ART.h"
34 
35 #include "nusimdata/SimulationBase/MCFlux.h"
36 #include "nusimdata/SimulationBase/MCTruth.h"
37 #include "nusimdata/SimulationBase/GTruth.h"
38 
39 #include "fhiclcpp/ParameterSet.h"
40 
41 //GENIE includes
42 #include "GENIE/Framework/Conventions/KineVar.h"
43 #include "GENIE/Framework/EventGen/EventRecord.h"
44 #include "GENIE/Framework/Interaction/Interaction.h"
45 #include "GENIE/Framework/Interaction/Kinematics.h"
46 #include "GENIE/Framework/Messenger/Messenger.h"
47 #include "GENIE/Framework/Utils/AppInit.h"
48 
49 #include "GENIE/RwFramework/GSystSet.h"
50 #include "GENIE/RwFramework/GSyst.h"
51 #include "GENIE/RwFramework/GReWeight.h"
52 #include "GENIE/RwCalculators/GReWeightNuXSecNCEL.h"
53 #include "GENIE/RwCalculators/GReWeightNuXSecCCQE.h"
54 #include "GENIE/RwCalculators/GReWeightNuXSecCCRES.h"
55 #include "GENIE/RwCalculators/GReWeightNuXSecCOH.h"
56 #include "GENIE/RwCalculators/GReWeightNonResonanceBkg.h"
57 #include "GENIE/RwCalculators/GReWeightFGM.h"
58 #include "GENIE/RwCalculators/GReWeightDISNuclMod.h"
59 #include "GENIE/RwCalculators/GReWeightResonanceDecay.h"
60 #include "GENIE/RwCalculators/GReWeightFZone.h"
61 #include "GENIE/RwCalculators/GReWeightINuke.h"
62 #include "GENIE/RwCalculators/GReWeightAGKY.h"
63 #include "GENIE/RwCalculators/GReWeightNuXSecCCQEaxial.h"
64 #include "GENIE/RwCalculators/GReWeightNuXSecCCQEvec.h"
65 #include "GENIE/RwCalculators/GReWeightNuXSecNCRES.h"
66 #include "GENIE/RwCalculators/GReWeightNuXSecDIS.h"
67 #include "GENIE/RwCalculators/GReWeightINukeParams.h"
68 #include "GENIE/RwCalculators/GReWeightNuXSecNC.h"
69 #include "GENIE/RwCalculators/GReWeightXSecEmpiricalMEC.h"
70 
71 
72 #ifdef GENIE_UB_PATCH
73 // New weight calculator in GENIE v3.0.4 MicroBooNE patch 01
74 #include "GENIE/RwCalculators/GReWeightXSecMEC.h"
75 
76 // New weight calculators in GENIE v3.0.4 MicroBooNE patch 02
77 #include "GENIE/RwCalculators/GReWeightDeltaradAngle.h"
78 #include "GENIE/RwCalculators/GReWeightNuXSecCOHuB.h"
79 #include "GENIE/RwCalculators/GReWeightRESBugFix.h"
80 
81 #endif
82 namespace sbn {
83 namespace {//Helper functions are defined in this block
84 
85  // These GENIE knobs are listed in the GSyst_t enum type but are not actually implemented.
86  // They will be skipped and a warning message will be printed.
87  // Last updated 9 Dec 2019 by S. Gardiner
88  std::set< genie::rew::GSyst_t > UNIMPLEMENTED_GENIE_KNOBS = {
89  kXSecTwkDial_RnubarnuCC, // tweak the ratio of \sigma(\bar\nu CC) / \sigma(\nu CC)
90  kXSecTwkDial_NormCCQEenu, // tweak CCQE normalization (maintains dependence on neutrino energy)
91  kXSecTwkDial_NormDISCC, // tweak the inclusive DIS CC normalization
92  kXSecTwkDial_DISNuclMod // unclear intent, does anyone else know? - S. Gardiner
93  };
94 
95  // Some GENIE weight calculators can work with sets of knobs that should not be used simultaneously.
96  // For instance, the CCQE weight calculator can vary parameters for the dipole axial form factor model
97  // (the axial mass Ma) or for the z-expansion model, but using both together is invalid. The map below
98  // is used to check that all of the requested knobs from the FHiCL input are compatible with each
99  // other. Assuming they pass this check, the code will then configure the weight calculators to use
100  // the correct "basis" of reweighting knobs as appropriate.
101 
102  // Outer keys are names of GENIE weight calculators that use sets of incompatible knobs. The names
103  // need to match those used in GenieWeightCalc::SetupWeightCalculators(), specifically in the
104  // calls to genie::rew::GReWeight::AdoptWeightCalc().
105  // Inner keys are integer codes used to represent (and configure) each of the mutually exclusive
106  // modes (i.e., to select one of the sets of incompatible knobs to use for the weight calculation).
107  // Values are GSyst_t knob labels that belong to the given mode.
108  std::map< std::string, std::map<int, std::set<genie::rew::GSyst_t> > > INCOMPATIBLE_GENIE_KNOBS = {
109  // CCQE (genie::rew::GReWeightNuXSecCCQE)
110  { "xsec_ccqe", {
111  { genie::rew::GReWeightNuXSecCCQE::kModeNormAndMaShape,
112  {
113  // Norm + shape
114  kXSecTwkDial_NormCCQE, // tweak CCQE normalization (energy independent)
115  kXSecTwkDial_MaCCQEshape, // tweak Ma CCQE, affects dsigma(CCQE)/dQ2 in shape only (normalized to constant integral)
116  kXSecTwkDial_E0CCQEshape // tweak E0 CCQE RunningMA, affects dsigma(CCQE)/dQ2 in shape only (normalized to constant integral)
117  }
118  },
119  { genie::rew::GReWeightNuXSecCCQE::kModeMa,
120  {
121  // Ma
122  kXSecTwkDial_MaCCQE, // tweak Ma CCQE, affects dsigma(CCQE)/dQ2 both in shape and normalization
123  kXSecTwkDial_E0CCQE, // tweak E0 CCQE RunningMA, affects dsigma(CCQE)/dQ2 both in shape and normalization
124  }
125  },
126  { genie::rew::GReWeightNuXSecCCQE::kModeZExp,
127  {
128  // Z-expansion
129  kXSecTwkDial_ZNormCCQE, // tweak Z-expansion CCQE normalization (energy independent)
130  kXSecTwkDial_ZExpA1CCQE, // tweak Z-expansion coefficient 1, affects dsigma(CCQE)/dQ2 both in shape and normalization
131  kXSecTwkDial_ZExpA2CCQE, // tweak Z-expansion coefficient 2, affects dsigma(CCQE)/dQ2 both in shape and normalization
132  kXSecTwkDial_ZExpA3CCQE, // tweak Z-expansion coefficient 3, affects dsigma(CCQE)/dQ2 both in shape and normalization
133  kXSecTwkDial_ZExpA4CCQE // tweak Z-expansion coefficient 4, affects dsigma(CCQE)/dQ2 both in shape and normalization
134  }
135  },
136  } },
137 
138  // CCRES (genie::rew::GReWeightNuXSecCCRES)
139  { "xsec_ccres", {
140  { genie::rew::GReWeightNuXSecCCRES::kModeNormAndMaMvShape,
141  {
142  // Norm + shape
143  kXSecTwkDial_NormCCRES, /// tweak CCRES normalization
144  kXSecTwkDial_MaCCRESshape, /// tweak Ma CCRES, affects d2sigma(CCRES)/dWdQ2 in shape only (normalized to constant integral)
145  kXSecTwkDial_MvCCRESshape /// tweak Mv CCRES, affects d2sigma(CCRES)/dWdQ2 in shape only (normalized to constant integral)
146  }
147  },
148  { genie::rew::GReWeightNuXSecCCRES::kModeMaMv,
149  {
150  // Ma + Mv
151  kXSecTwkDial_MaCCRES, // tweak Ma CCRES, affects d2sigma(CCRES)/dWdQ2 both in shape and normalization
152  kXSecTwkDial_MvCCRES // tweak Mv CCRES, affects d2sigma(CCRES)/dWdQ2 both in shape and normalization
153  }
154  }
155  } },
156 
157  // NCRES (genie::rew::GReWeightNuXSecNCRES)
158  { "xsec_ncres", {
159  { genie::rew::GReWeightNuXSecNCRES::kModeNormAndMaMvShape,
160  {
161  // Norm + shape
162  kXSecTwkDial_NormNCRES, /// tweak NCRES normalization
163  kXSecTwkDial_MaNCRESshape, /// tweak Ma NCRES, affects d2sigma(NCRES)/dWdQ2 in shape only (normalized to constant integral)
164  kXSecTwkDial_MvNCRESshape /// tweak Mv NCRES, affects d2sigma(NCRES)/dWdQ2 in shape only (normalized to constant integral)
165  }
166  },
167  { genie::rew::GReWeightNuXSecNCRES::kModeMaMv,
168  {
169  // Ma + Mv
170  kXSecTwkDial_MaNCRES, // tweak Ma NCRES, affects d2sigma(NCRES)/dWdQ2 both in shape and normalization
171  kXSecTwkDial_MvNCRES // tweak Mv NCRES, affects d2sigma(NCRES)/dWdQ2 both in shape and normalization
172  }
173  }
174  } },
175 
176  // DIS (genie::rew::GReWeightNuXSecDIS)
177  { "xsec_dis", {
178  { genie::rew::GReWeightNuXSecDIS::kModeABCV12u,
179  {
180  kXSecTwkDial_AhtBY, // tweak the Bodek-Yang model parameter A_{ht} - incl. both shape and normalization effect
181  kXSecTwkDial_BhtBY, // tweak the Bodek-Yang model parameter B_{ht} - incl. both shape and normalization effect
182  kXSecTwkDial_CV1uBY, // tweak the Bodek-Yang model parameter CV1u - incl. both shape and normalization effect
183  kXSecTwkDial_CV2uBY // tweak the Bodek-Yang model parameter CV2u - incl. both shape and normalization effect
184  }
185  },
186  { genie::rew::GReWeightNuXSecDIS::kModeABCV12uShape,
187  {
188  kXSecTwkDial_AhtBYshape, // tweak the Bodek-Yang model parameter A_{ht} - shape only effect to d2sigma(DIS)/dxdy
189  kXSecTwkDial_BhtBYshape, // tweak the Bodek-Yang model parameter B_{ht} - shape only effect to d2sigma(DIS)/dxdy
190  kXSecTwkDial_CV1uBYshape, // tweak the Bodek-Yang model parameter CV1u - shape only effect to d2sigma(DIS)/dxdy
191  kXSecTwkDial_CV2uBYshape // tweak the Bodek-Yang model parameter CV2u - shape only effect to d2sigma(DIS)/dxdy
192  }
193  }
194  } }
195  };
196 
197 
198  // Helper function that checks whether a string storing a GENIE knob name is
199  // valid. Also stores the corresponding GSyst_t enum value for the knob.
200  // This grab the knob by <string> name;
201  bool valid_knob_name( const std::string& knob_name, genie::rew::GSyst_t& knob ) {
202  knob = genie::rew::GSyst::FromString( knob_name );
203  if ( knob != kNullSystematic && knob != kNTwkDials ) {
204  if ( UNIMPLEMENTED_GENIE_KNOBS.count(knob) ) {
205  MF_LOG_WARNING("GENIEWeightCalc") << "Ignoring unimplemented GENIE"
206  << " knob " << knob_name;
207  return false;
208  }
209  }
210  else {
211  throw cet::exception(__PRETTY_FUNCTION__) << "Encountered unrecognized"
212  "GENIE knob \"" << knob_name << '\"';
213  return false;
214  }
215  return true;
216  }
217 
218 
219  // Set of FHiCL weight calculator labels for which the tuned CV will be
220  // ignored. If the name of the weight calculator doesn't appear in this set,
221  // then variation weights will be thrown around the tuned CV.
222  std::set< std::string > CALC_NAMES_THAT_IGNORE_TUNED_CV = { "RootinoFix" };
223 
224 } // anonymous namespace
225 
226 
227  namespace evwgh {
228 
229 class GenieWeightCalc : public WeightCalc {
230 public:
232 
233  void Configure(fhicl::ParameterSet const& pset,
234  CLHEP::HepRandomEngine& engine) override;
235 
236  std::vector<float> GetWeight(art::Event& e, size_t inu) override;
237 
238 private:
239  std::vector< genie::rew::GReWeight > reweightVector;
240 
241  std::string fGenieModuleLabel;
242  std::string fTuneName;
243 
244  std::map< std::string, int > CheckForIncompatibleSystematics(
245  const std::vector<genie::rew::GSyst_t>& knob_vec);
246 
247  void SetupWeightCalculators(genie::rew::GReWeight& rw,
248  const std::map<std::string, int>& modes_to_use);
249 
250  bool fQuietMode;//quiet mode
251 
253 };
254 
255 
256 void GenieWeightCalc::Configure(fhicl::ParameterSet const& p,
257  CLHEP::HepRandomEngine& engine) {
258 
259  genie::Messenger* messenger = genie::Messenger::Instance();
260  // By default, run GENIE reweighting in "quiet mode"
261  // (use the logging settings in the "whisper" configuration
262  // of the genie::Messenger class). The user can disable
263  // quiet mode using the boolean FHiCL parameter "quiet_mode"
264  fQuietMode = p.get<bool>( "quiet_mode", true );
265  if ( fQuietMode ) {
266  genie::utils::app_init::MesgThresholds( "Messenger_whisper.xml" );
267  }
268  else {
269  // If quiet mode isn't enabled, then print detailed debugging
270  // messages for GENIE reweighting
271  messenger->SetPriorityLevel( "ReW", log4cpp::Priority::DEBUG );
272 
273  MF_LOG_INFO("GENIEWeightCalc") << "Configuring GENIE weight"
274  << " calculator " << this->GetName();
275  }
276 
277  // Manually silence a couple of annoying GENIE logging messages
278  // that appear a lot when running reweighting. This is done
279  // whether or not "quiet mode" is enabled.
280  messenger->SetPriorityLevel( "TransverseEnhancementFFModel",
282  messenger->SetPriorityLevel( "Nieves", log4cpp::Priority::WARN );
283 
284 
285  // Global config
286  //----Initialize the tune
287  // Configure the appropriate GENIE tune if needed (important for v3+ only)
288  // NOTE: In all normal use cases, relying on the ${GENIE_XSEC_TUNE} environment
289  // variable set by the genie_xsec package should be sufficient. Only include
290  // the "TuneName" FHiCL parameter for EventWeight if you really know what you're
291  // doing! The same goes for the "EventGeneratorList" parameter.
292  std::string genie_tune_name = p.get<std::string>("TuneName", "${GENIE_XSEC_TUNE}");
293 
294  // The default empty string used here will cause the subsequent call to
295  // evgb::SetEventGeneratorListAndTune() to leave GENIE's current event generator
296  // list name (probably "Default") alone
297  std::string evgen_list_name = p.get<std::string>("EventGeneratorList", "");
298 
299  // Tell GENIE about the event generator list and tune
300  evgb::SetEventGeneratorListAndTune( evgen_list_name, genie_tune_name );
301 
302 
303  fGenieModuleLabel = p.get<std::string>("genie_module_label");
304 
305  const fhicl::ParameterSet& param_CVs = p.get<fhicl::ParameterSet>(
306  "genie_central_values", fhicl::ParameterSet() );
307  std::vector< std::string > CV_knob_names = param_CVs.get_all_keys();
308 
309  std::map< genie::rew::GSyst_t, double > gsyst_to_cv_map;
310  genie::rew::GSyst_t temp_knob;
311 
312  if ( !CV_knob_names.empty() && !fQuietMode ) MF_LOG_INFO("GENIEWeightCalc")
313  << "Configuring non-default GENIE knob central values from input"
314  << " FHiCL parameter set";
315 
316  for ( const auto& knob_name : CV_knob_names ) {
317  double CV_knob_value = param_CVs.get<double>( knob_name );
318  if ( valid_knob_name(knob_name, temp_knob) ) {
319  if ( gsyst_to_cv_map.count( temp_knob ) ) {
320  throw cet::exception(__PRETTY_FUNCTION__) << "Duplicate central values"
321  << " were configured for the " << knob_name << " GENIE knob.";
322  }
323  gsyst_to_cv_map[ temp_knob ] = CV_knob_value;
324  if ( !fQuietMode ) {
325  MF_LOG_INFO("GENIEWeightCalc") << "Central value for the " << knob_name
326  << " knob was set to " << CV_knob_value;
327  }
328  }
329  }
330 
331  // Calculator config
332  const fhicl::ParameterSet& pset = p.get<fhicl::ParameterSet>(GetName());
333 
334  auto const& pars = pset.get<std::vector<std::string> >("parameter_list");
335 
336  std::vector<float> parsigmas = pset.get<std::vector<float> >("parameter_sigma", std::vector<float>() );
337 
338 
339  // Convert the list of GENIE knob names from the input FHiCL configuration
340  // into a vector of genie::rew::GSyst_t labels
341  std::vector< genie::rew::GSyst_t > knobs_to_use;
342  for ( const auto& knob_name : pars ) {
343  if ( valid_knob_name(knob_name, temp_knob) ) knobs_to_use.push_back( temp_knob );
344  }
345 
346  //check if all_knobs_vec are good
347  std::vector< genie::rew::GSyst_t > all_knobs_vec = knobs_to_use;
348  for ( const auto& pair : gsyst_to_cv_map ) {
349  genie::rew::GSyst_t cv_knob = pair.first;
350  auto begin = all_knobs_vec.cbegin();
351  auto end = all_knobs_vec.cend();
352  if ( !std::count(begin, end, cv_knob) ) all_knobs_vec.push_back( cv_knob );
353  }
354  std::map< std::string, int >
355  modes_to_use = this->CheckForIncompatibleSystematics( all_knobs_vec );
356 
357 
358  std::string mode = pset.get<std::string>("mode");
359 
360  int num_universes = 1; //for "central_value" or "default" mode
361 
362  std::string array_name_for_exception;
363 
364  if (pars.size() != parsigmas.size()) {
365  array_name_for_exception = "parameter_sigma";
366  }
367  //One fParameterSet gives one set of weights;
368  //Different fParameterSet's are independent.
369  if(mode.find("pmNsigma") != std::string::npos){
370  //This mode will be updated and replaced with a more useful one.
371 
372  num_universes = 2;
373 
374  for (size_t i=0; i<pars.size(); i++){
375  fParameterSet.AddParameter(pars[i], parsigmas[i]);
376  }
377 
378  }else if(mode.find("multisigma") != std::string::npos){
379 
380  //==== pars.size()==1 is supported
381  array_name_for_exception = "";
382  if(pars.size()!=1){
383  array_name_for_exception = "multisigma";
384  throw cet::exception(__PRETTY_FUNCTION__) << GetName()
385  << "::Bad fcl configuration. multisigma only supports one parameter_list";
386  }
387 
388  for (size_t i=0; i<pars.size(); i++){
389  num_universes = pars.size() * parsigmas.size();
390  std::vector<float> withds;
391  for (size_t j=0; j<parsigmas.size(); j++){
392  withds.push_back(parsigmas[j]);
393  }
394  fParameterSet.AddParameter(pars[i], withds);
395  }
396 
397  }else if(mode.find("multisim") != std::string::npos){
398 
399  num_universes = pset.get<int>( "number_of_multisims", 1 );
400 
401  MF_LOG_INFO("GENIEWeightCalc") << "GENIE weight calculator "
402  << this->GetName() << " will generate " << num_universes
403  << " multisim universes";
404 
405  for (size_t i=0; i<pars.size(); i++) {
406  fParameterSet.AddParameter(pars[i], parsigmas[i]);
407  }
408 
409  }else if(mode.find("fixed") != std::string::npos){
410 
411  num_universes = 1;
412 
413  for (size_t i=0; i<pars.size(); i++) {
414  fParameterSet.AddParameter(pars[i], parsigmas[i]);
415  }
416 
417  }else { //need to identify a mode
418 
419  throw cet::exception(__PRETTY_FUNCTION__) << GetName()
420  <<":: Mode is not recognized: "<<mode;
421 
422  }
423 
424  if( array_name_for_exception.size() > 1){
425 
426  throw cet::exception(__PRETTY_FUNCTION__) << GetName()
427  << "::Bad fcl configuration. parameter_list and "
428  << array_name_for_exception
429  << " need to have same number of parameters.";
430  }
431 
432  // Set up parameters
433  fParameterSet.Configure(GetFullName(), mode, num_universes);
434  fParameterSet.Sample(engine);
435 
436  //Initialize genie::rew::GReWeight's
437  reweightVector.resize( num_universes );// Reconfigure this later in this function.
438  std::cout << GetFullName() << ": Initialize WeightCalculators with "<<num_universes<<" univeres."<<std::endl;
439 
440  // Initialize weight calculators for all universes;
441  for ( auto& rwght : reweightVector ){ this->SetupWeightCalculators( rwght, modes_to_use );}
442 
443  // Set up parameters
444  for ( size_t univ = 0; univ < reweightVector.size(); ++univ ) {//loop over universes
445 
446  auto& rwght = reweightVector.at( univ );
447  genie::rew::GSystSet& syst = rwght.Systematics();
448 
449  rwght.Reconfigure();//Redundant, but it avoids "cushion error":
450  //1638551728 FATAL ReW : [n] <GReWeightINukeParams.cxx::AddCushionTerms (583)> : There must be at least one cushion term (0 were set)
451  //loop over parameters;
452  for (auto const& it : fParameterSet.fParameterMap) {//loop over knobs
453  //member of std::map<EventWeightParameter, std::vector<float> >
454  //(see line 41 of sbnobj/Common/SBNEventWeight/EventWeightParameterSet.h)
455  std::string name = it.first.fName;
456  genie::rew::GSyst_t knob = genie::rew::GSyst::FromString( name );
457 
458  double cv_shift = 0;
459  auto iter = gsyst_to_cv_map.find( knob ); //Apply CV shift, if required
460  if ( iter != gsyst_to_cv_map.end() ) {
461  cv_shift = iter->second;
462  if ( !fQuietMode ) MF_LOG_INFO("GENIEWeightCalc")
463  << "CV offset added to the "
464  << genie::rew::GSyst::AsString( knob )
465  << " knob. New sigma for universe #" << univ << " is "
466  << cv_shift;
467  }
468 
469  double twk_dial_value = it.second[univ]+cv_shift;
470  syst.Set( knob, twk_dial_value ); //Assign knob with new values based on variation
471 
472  std::cout << GetFullName() << ": univ "<<univ<<" "<<genie::rew::GSyst::AsString( knob )<<" Knob value: "<<twk_dial_value<<std::endl;
473 
474  if ( !fQuietMode ) {
475  MF_LOG_INFO("GENIEWeightCalc") << "In universe #" << univ << ", knob name" << name // << k
476  << " (" << genie::rew::GSyst::AsString( knob ) << ") was set to"
477  << " the value " << twk_dial_value << " with shift "<<cv_shift;
478  }
479 
480  }//next knob
481  rwght.Reconfigure();//Apply all set knobs, i.e. use the updated syst.
482  rwght.Print();
483  }//next universe
484 }
485 
486 //Keng:
487 //copied from larsim's GetWeight()
488 //2d weights --> 1d weights; no major modifications.
489 std::vector<float> GenieWeightCalc::GetWeight(art::Event& e, size_t inu) {
490  // Get the MC generator information out of the event
491  // These are both handles to MC information.
492  art::Handle< std::vector<simb::MCTruth> > mcTruthHandle;
493  art::Handle< std::vector<simb::GTruth> > gTruthHandle;
494 
495  // Actually go and get the stuff
496  e.getByLabel( fGenieModuleLabel, mcTruthHandle );
497  e.getByLabel( fGenieModuleLabel, gTruthHandle );
498 
499  std::vector< art::Ptr<simb::MCTruth> > mclist;
500  art::fill_ptr_vector( mclist, mcTruthHandle );
501 
502  std::vector< art::Ptr<simb::GTruth > > glist;
503  art::fill_ptr_vector( glist, gTruthHandle );
504 
505  size_t num_knobs = reweightVector.size();
506 
507  // Calculate weight(s) here
508  std::vector< float > weights( num_knobs );
509 // std::vector< std::vector<double> > weights( num_neutrinos );
510 
511  // Convert the MCTruth and GTruth objects from the event
512  // back into the original genie::EventRecord needed to
513  // compute the weights
514  std::unique_ptr< genie::EventRecord >
515  genie_event( evgb::RetrieveGHEP(*mclist[inu], *glist[inu]) );
516 
517  // Set the final lepton kinetic energy and scattering cosine
518  // in the owned GENIE kinematics object. This is done during
519  // event generation but is not reproduced by evgb::RetrieveGHEP().
520  // Several new CCMEC weight calculators developed for MicroBooNE
521  // expect the variables to be set in this way (so that differential
522  // cross sections can be recomputed). Failing to set them results
523  // in inf and NaN weights.
524  // TODO: maybe update evgb::RetrieveGHEP to handle this instead.
525  genie::Interaction* interaction = genie_event->Summary();
526  genie::Kinematics* kine_ptr = interaction->KinePtr();
527 
528  // Final lepton mass
529  double ml = interaction->FSPrimLepton()->Mass();
530  // Final lepton 4-momentum
531  const TLorentzVector& p4l = kine_ptr->FSLeptonP4();
532  // Final lepton kinetic energy
533  double Tl = p4l.E() - ml;
534  // Final lepton scattering cosine
535  double ctl = p4l.CosTheta();
536 
537  kine_ptr->SetKV( kKVTl, Tl );
538  kine_ptr->SetKV( kKVctl, ctl );
539 
540  // All right, the event record is fully ready. Now ask the GReWeight
541  // objects to compute the weights.
542 
543  for (size_t k = 0u; k < num_knobs; ++k ) {//one "knob" for one universe;
544  //Add exception to avoid "FATAL KineLimits",
545  // see https://github.com/GENIE-MC/Reweight/issues/12
546  std::vector< genie::rew::GSyst_t > ak = reweightVector.at( k ).Systematics().AllIncluded();//all konbs used
547 
548  //NOTE: this line is to skip reweighting stange-CCQE events
549  //Among 7500 events, 207 of them are strange events; ~3%
550  if(glist[inu]->fIsStrange && std::find(ak.begin(), ak.end(), kXSecTwkDial_MaCCQE) != ak.end()){
551  weights[k] = 1;
552  } else{
553  weights[k] = reweightVector.at( k ).CalcWeight( *genie_event );
554  reweightVector.at(k).Print();
555  }
556 // std::cout<<"CHECK "<<k<<" universe weight "<<weights[k]<<std::endl;
557  }
558 // std::cout<<"Finish Event # "<<e.event()<<std::endl;
559 
560  return weights;
561 }
562 
563 
565  const std::vector<genie::rew::GSyst_t>& knob_vec){
566  std::map< std::string, int > modes_to_use;
567 
568  for ( const auto& knob : knob_vec ) {
569  for ( const auto& pair1 : INCOMPATIBLE_GENIE_KNOBS ) {
570  std::string calc_name = pair1.first;
571  const auto& mode_map = pair1.second;
572  for ( const auto& pair2 : mode_map ) {
573  int mode = pair2.first;//<int> code of the variable
574  std::set<genie::rew::GSyst_t> knob_set = pair2.second;//incomp. knobs
575 
576  if ( knob_set.count(knob) ) {//<string> leads to incomp. knobs
577  auto search = modes_to_use.find( calc_name );
578  if ( search != modes_to_use.end() ) {//found a incomp. knob's name
579  if ( search->second != mode ) {//if the knob is not connected to the variable?
580  auto knob_str = genie::rew::GSyst::AsString( knob );
581  throw cet::exception(__PRETTY_FUNCTION__) << this->GetName()
582  << ": the GENIE knob " << knob_str << " is incompatible"
583  << " with others that are already configured";
584  }
585  }
586  else modes_to_use[ calc_name ] = mode;
587  }
588  }
589  }
590  }
591 
592  return modes_to_use;
593  }
594 
595 
596 void GenieWeightCalc::SetupWeightCalculators(genie::rew::GReWeight& rw,
597  const std::map<std::string, int>& modes_to_use){
598  // Based on the list from the GENIE command-line tool grwght1p
599  rw.AdoptWghtCalc( "xsec_ncel", new GReWeightNuXSecNCEL );
600  rw.AdoptWghtCalc( "xsec_ccqe", new GReWeightNuXSecCCQE );
601  rw.AdoptWghtCalc( "xsec_ccqe_axial", new GReWeightNuXSecCCQEaxial );
602  rw.AdoptWghtCalc( "xsec_ccqe_vec", new GReWeightNuXSecCCQEvec );
603  rw.AdoptWghtCalc( "xsec_ccres", new GReWeightNuXSecCCRES );
604  rw.AdoptWghtCalc( "xsec_ncres", new GReWeightNuXSecNCRES );
605  rw.AdoptWghtCalc( "xsec_nonresbkg", new GReWeightNonResonanceBkg );
606  rw.AdoptWghtCalc( "xsec_coh", new GReWeightNuXSecCOH );
607  rw.AdoptWghtCalc( "xsec_dis", new GReWeightNuXSecDIS );
608  rw.AdoptWghtCalc( "nuclear_qe", new GReWeightFGM );
609  rw.AdoptWghtCalc( "hadro_res_decay", new GReWeightResonanceDecay );
610  rw.AdoptWghtCalc( "hadro_fzone", new GReWeightFZone );
611  rw.AdoptWghtCalc( "hadro_intranuke", new GReWeightINuke );
612  rw.AdoptWghtCalc( "hadro_agky", new GReWeightAGKY );
613  rw.AdoptWghtCalc( "xsec_nc", new GReWeightNuXSecNC );
614  rw.AdoptWghtCalc( "res_dk", new GReWeightResonanceDecay );
615  rw.AdoptWghtCalc( "xsec_empmec", new GReWeightXSecEmpiricalMEC);
616  // GReWeightDISNuclMod::CalcWeight() is not implemented, so we won't
617  // bother to use it here. - S. Gardiner, 9 Dec 2019
618  //rw.AdoptWghtCalc( "nuclear_dis", new GReWeightDISNuclMod );
619 
620 #ifdef GENIE_UB_PATCH
621 
622  // New weight calculator in GENIE v3.0.4 MicroBooNE patch 01
623  rw.AdoptWghtCalc( "xsec_mec", new GReWeightXSecMEC );
624 
625  // New weight calculators in GENIE v3.0.4 MicroBooNE patch 02
626  rw.AdoptWghtCalc( "deltarad_angle", new GReWeightDeltaradAngle );
627  rw.AdoptWghtCalc( "xsec_coh_ub", new GReWeightNuXSecCOHuB );
628  rw.AdoptWghtCalc( "res_bug_fix", new GReWeightRESBugFix );
629 
630 #endif
631 
632  // Set the modes for the weight calculators that need them to be specified
633  for ( const auto& pair : modes_to_use ) {
634  std::string calc_name = pair.first;
635  int mode = pair.second;
636 
637  genie::rew::GReWeightI* calc = rw.WghtCalc( calc_name );
638  if ( !calc ) throw cet::exception(__PRETTY_FUNCTION__)
639  << "Failed to retrieve the GENIE weight calculator labeled \""
640  << calc_name << '\"';
641 
642  // The GReWeightI base class doesn't have a SetMode(int) function,
643  // so we'll just try dynamic casting until we get the right one.
644  // If none work, then throw an exception.
645  // TODO: Add a virtual function GReWeightI::SetMode( int ) in GENIE's
646  // Reweight framework. Then we can avoid the hacky dynamic casts here.
647  auto* calc_ccqe = dynamic_cast< genie::rew::GReWeightNuXSecCCQE* >( calc );
648  auto* calc_ccres = dynamic_cast< genie::rew::GReWeightNuXSecCCRES* >( calc );
649  auto* calc_ncres = dynamic_cast< genie::rew::GReWeightNuXSecNCRES* >( calc );
650  auto* calc_dis = dynamic_cast< genie::rew::GReWeightNuXSecDIS* >( calc );
651  if ( calc_ccqe ) calc_ccqe->SetMode( mode );
652  else if ( calc_ccres ) calc_ccres->SetMode( mode );
653  else if ( calc_ncres ) calc_ncres->SetMode( mode );
654  else if ( calc_dis ) calc_dis->SetMode( mode );
655  else throw cet::exception(__PRETTY_FUNCTION__)
656  << "Request to set the mode of an unrecognized GENIE weight calculator \""
657  << calc_name << '\"';
658  }
659 
660 }
661 
663 
664  } // namespace evwgh
665 } // namespace sbn
666 
667 
668 
void AddParameter(std::string name, float width, float mean=0, size_t covIndex=0)
pdgs p
Definition: selectors.fcl:22
void Configure(fhicl::ParameterSet const &pset, CLHEP::HepRandomEngine &engine) override
void Configure(std::string name, ReweightType rwtype, size_t nuni=1)
const char mode
Definition: noise_ana.cxx:20
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)
Definition: Parser.cxx:8
void Sample(CLHEP::HepRandomEngine &engine)
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
std::map< EventWeightParameter, std::vector< float > > fParameterMap
Mapping of definitions to the set of values.
auto begin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:573
#define REGISTER_WEIGHTCALC(wghcalc)
do i e
void SetupWeightCalculators(genie::rew::GReWeight &rw, const std::map< std::string, int > &modes_to_use)
then echo fcl name
pdgs k
Definition: selectors.fcl:22
std::size_t count(Cont const &cont)
std::map< std::string, int > CheckForIncompatibleSystematics(const std::vector< genie::rew::GSyst_t > &knob_vec)
BEGIN_PROLOG don t mess with this pandoraTrackGausCryoW true
BEGIN_PROLOG could also be cout