35 #include <TLorentzVector.h> 50 using namespace genie;
99 <<
"Reconfiguring weight calculator for pion intranuke fate systematics";
103 <<
"Reconfiguring weight calculator for nucleon intranuke fate systematics";
150 <<
"Mean-free path reweighting code handles only pions or nucleons";
166 fSystValuesUser.clear();
167 fSystValuesActual.clear();
173 this->AddCushionTerms();
179 if(!this->IsHandled(syst))
return;
182 if(this->IsIncluded(syst)) {
183 if(this->IsCushionTerm(syst)) {
185 <<
"You may not set the value of cushion term " <<
GSyst::AsString(syst)
186 <<
". It is set automatically to maintain unitarity";
192 fSystValuesUser[syst] =
val;
193 fIsCushion[syst] =
false;
197 GSyst_t syst,
const TLorentzVector & p4)
const 199 double KE = p4.Energy() - p4.M();
200 return this->ScaleFactor(syst, KE);
208 double fractional_error = uncert->
OneSigmaErr(syst);
209 double twk_dial = this->ActualTwkDial(syst, KE);
211 double fate_fraction_scale = 1. + twk_dial * fractional_error;
215 <<
" (1 sigma frac. err = " << 100*fractional_error
216 <<
"%, tweak dial = " << twk_dial
217 <<
"): Weight = " << fate_fraction_scale;
219 return fate_fraction_scale;
224 if(! this->IsIncluded(syst)) {
230 LOG(
"ReW",
pERROR) <<
"Negative kinetic energy! (KE = " << KE <<
")";
240 fSystValuesActual.clear();
241 fSystValuesActual.insert(fSystValuesUser.begin(), fSystValuesUser.end());
250 for(iter = fSystValuesActual.begin(); iter != fSystValuesActual.end(); ++iter)
252 GSyst_t curr_syst = iter->first;
253 double curr_twk_dial = iter->second;
255 bool curr_is_cushion = this->IsCushionTerm(curr_syst);
256 if(curr_is_cushion)
continue;
258 double fractional_frac_err = uncert->
OneSigmaErr(curr_syst);
259 double frac_scale = 1. + curr_twk_dial * fractional_frac_err;
262 double curr_twk_dial_min = -1/fractional_frac_err;
263 fSystValuesActual[curr_syst] = curr_twk_dial_min;
265 <<
"Too large systematic variation for non-cushion systematic " <<
GSyst::AsString(curr_syst)
266 <<
" makes the corresponding fate scaling factor negative! Taking corrective action...";
268 <<
"Tweak dial automatically re-adjusted from " << curr_twk_dial
269 <<
" to " << curr_twk_dial_min;
277 double sum_nocushion_fate_fraction_nom = 0.;
278 double sum_nocushion_fate_fraction_twk = 0.;
280 for(iter = fSystValuesActual.begin(); iter != fSystValuesActual.end(); ++iter)
282 GSyst_t curr_syst = iter->first;
283 double curr_twk_dial = iter->second;
285 bool curr_is_cushion = this->IsCushionTerm(curr_syst);
286 if(curr_is_cushion)
continue;
288 double fractional_frac_err = uncert->
OneSigmaErr(curr_syst);
290 double frac_scale = 1. + curr_twk_dial * fractional_frac_err;
294 sum_nocushion_fate_fraction_nom += nom_frac;
295 sum_nocushion_fate_fraction_twk += curr_frac;
299 <<
" (1 sigma frac. err = " << 100*fractional_frac_err
300 <<
"%, tweak dial = " << curr_twk_dial
301 <<
"): fate fraction (KE = " << KE <<
" GeV) = " 302 << nom_frac <<
" (nominal), " 303 << curr_frac <<
" (tweaked)";
307 <<
"Sum of non-cushion fate fractions = " 308 << sum_nocushion_fate_fraction_nom <<
" (nominal), " 309 << sum_nocushion_fate_fraction_twk <<
" (tweaked)";
318 if(sum_nocushion_fate_fraction_twk > 1.) {
321 <<
"Current sum of non-cushion fate fractions = " 322 << sum_nocushion_fate_fraction_twk <<
" ( > 1 ). " 323 <<
"Can not maintain unitarity with current set of systematic parameter values. " 324 <<
"Taking corrective action...";
326 for(iter = fSystValuesActual.begin(); iter != fSystValuesActual.end(); ++iter)
328 GSyst_t curr_syst = iter->first;
329 double curr_twk_dial = iter->second;
331 bool curr_is_cushion = this->IsCushionTerm(curr_syst);
333 double fractional_frac_err = uncert->
OneSigmaErr(curr_syst);
335 double frac_scale = 1. + curr_twk_dial * fractional_frac_err;
338 double curr_frac_new = (curr_is_cushion) ? 0 : curr_frac * (1./sum_nocushion_fate_fraction_twk);
340 double curr_twk_dial_new = (frac_scale_new != 0) ? (frac_scale_new - 1.)/fractional_frac_err : 0;
342 fSystValuesActual[curr_syst] = curr_twk_dial_new;
345 << ((curr_is_cushion) ?
" Cushion " :
" Non-cushion ")
347 <<
": fate fraction re-adjusted from " << curr_frac <<
" to " << curr_frac_new
348 <<
" (tweak dial re-adjusted from " << curr_twk_dial
349 <<
" to " << curr_twk_dial_new <<
")";
353 sum_nocushion_fate_fraction_twk = 1.;
365 double delta_fate_fraction =
366 sum_nocushion_fate_fraction_twk - sum_nocushion_fate_fraction_nom;
369 <<
"Sum of non-cushion fate fractions changed by " << delta_fate_fraction
370 <<
" - Change to be absorbed by the selected cushion terms...";
373 for(iter = fSystValuesActual.begin(); iter != fSystValuesActual.end(); ++iter)
375 GSyst_t curr_syst = iter->first;
377 bool curr_is_cushion = this->IsCushionTerm(curr_syst);
378 if(!curr_is_cushion)
continue;
380 double fractional_frac_err = uncert->
OneSigmaErr(curr_syst);
382 sum += (nom_frac * fractional_frac_err);
385 double twk_dial = -1.*delta_fate_fraction / sum;
387 for(iter = fSystValuesActual.begin(); iter != fSystValuesActual.end(); ++iter)
389 GSyst_t curr_syst = iter->first;
390 bool curr_is_cushion = this->IsCushionTerm(curr_syst);
391 if(!curr_is_cushion)
continue;
393 fSystValuesActual[curr_syst] = twk_dial;
397 <<
"To absorb change in the sum of non-cushion fate fractions, " 398 <<
"the tweaking dial for all cushion terms needs to be set to " 407 LOG(
"ReW",
pINFO) <<
"Confirming unitarity for current fate fractions";
409 double sum_fate_fraction_all = 0;
410 for(iter = fSystValuesActual.begin(); iter != fSystValuesActual.end(); ++iter)
412 GSyst_t curr_syst = iter->first;
413 double curr_twk_dial = iter->second;
415 bool curr_is_cushion = this->IsCushionTerm(curr_syst);
417 double fractional_frac_err = uncert->
OneSigmaErr(curr_syst);
419 double frac_scale = 1. + curr_twk_dial * fractional_frac_err;
424 <<
" (1 sigma frac. err = " << 100*fractional_frac_err
425 <<
"%, tweak dial = " << curr_twk_dial
426 <<
"): Current fate fraction (KE = " << KE <<
" GeV) = " << curr_frac
427 << ((curr_is_cushion) ?
" ** cushion term ** " :
"");
429 sum_fate_fraction_all += curr_frac;
432 LOG(
"ReW",
pINFO) <<
"Current sum of all fate fractions = " << sum_fate_fraction_all;
434 if(TMath::Abs(sum_fate_fraction_all-1) > 0.01) {
435 LOG(
"ReW",
pWARN) <<
"Unitarity violation level exceeded 1 part in 100.";
436 LOG(
"ReW",
pWARN) <<
"Current sum of all fate fractions = " << sum_fate_fraction_all;
440 return dial_iter->second;
450 const double kKEmin = 0;
451 const double kKEmax = 10;
452 const double kKEstep = (kKEmax-kKEmin)/(kN-1);
462 for(
int j=0; j < kN; j++) {
463 double KE = kKEmin + j * kKEstep;
464 double twkdial = this->ActualTwkDial(syst,KE);
465 chisq += (TMath::Power(twkdial, 2.));
477 if(iter != fSystValuesUser.end())
return true;
484 if(iter != fIsCushion.end())
return iter->second;
487 <<
"Cannot query 'is cushion' flag for systematic " 495 if(!this->IsHandled (syst))
return false;
496 if(!this->IsIncluded(syst))
return false;
499 double dial = dial_iter->second;
505 << ((tweaked) ?
" was " :
" was not ")
506 <<
"tweaked (tweaking dial = " << dial <<
")";
521 bool tweaked = this->IsTweaked(syst);
522 if(tweaked)
return true;
551 LOG(
"ReW",
pINFO) <<
"Adding cushion terms...";
563 if(this->IsIncluded(syst)) {
564 bool is_cushion = this->IsCushionTerm(syst);
567 <<
" was already specified as a" 568 << ((is_cushion) ?
" cuhsion " :
" non-cushion ")
571 fSystValuesUser[syst] = 0.;
578 <<
" as a cushion term.";
580 fSystValuesUser[syst] = 0.;
581 fIsCushion[syst] =
true;
586 LOG(
"ReW",
pINFO) <<
"Number of cushion terms = " << ncushions;
590 <<
"There must be at least one cushion term (" 591 << ncushions <<
" were set)";
611 <<
"Mean-free path reweighting code handles only pions or nucleons";
625 if(! this->IsTweaked())
return 1.;
630 double mfp_twkdial = this->TwkDial();
631 double scale_factor = 1.0 + mfp_sigma * mfp_twkdial;
653 return TMath::Power(fTwkDial, 2.0);
bool IsTweaked(void) const
is any param tweaked
double ChisqPenalty(void) const
double WhichFateFractionScaleFactor(genie::rew::GSyst_t syst, double kinE, double fate_frac)
#include "Numerical/GSFunc.h"
MFP * MeanFreePathParams(int pdgc) const
bool IsHandled(GSyst_t s) const
void AddCushionTerms(void)
bool IsCushionTerm(GSyst_t s) const
is it a cushion term?
void SetTwkDial(double val)
double OneSigmaErr(GSyst_t syst, int sign=0) const
static bool IsINukeNuclMeanFreePathSystematic(GSyst_t syst)
void SetTwkDial(GSyst_t s, double val)
MFP(HadronType_t hadtype=kRwINukeUndefined)
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
void SetTwkDial(GSyst_t s, double val)
bool IsIncluded(GSyst_t s) const
is included?
static const double kASmallNum
An enumeration of systematic parameters.
double ChisqPenalty(void) const
bool IsIncluded(void) const
tweak mean free path for nucleons
tweak mean free path for pions
static GSyst_t NextPionFateSystematic(int i)
double ChisqPenalty(void) const
double ScaleFactor(void) const
mean free path scale factor = 1 + twk_dial * fractional_err
double TwkDial(void) const
current value of mfp tweak dial
static string AsString(GSyst_t syst)
static bool IsINukePionFateSystematic(GSyst_t syst)
static bool IsINukePionMeanFreePathSystematic(GSyst_t syst)
Fates(HadronType_t hadtype=kRwINukeUndefined)
double ScaleFactor(GSyst_t s, const TLorentzVector &p4) const
see next
double FateFraction(genie::rew::GSyst_t syst, double kinE, double frac_scale_factor=1.)
static GSystUncertainty * Instance(void)
bool IsTweaked(void) const
enum genie::rew::GReWeightINukeParams::EHadronType HadronType_t
static bool IsINukeNuclFateSystematic(GSyst_t syst)
double ActualTwkDial(GSyst_t s, double KE=-1.) const
actual tweaking dial for input systematic at input kinetic energy
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
static GSyst_t NextNuclFateSystematic(int i)
Fates * FateParams(int pdgc) const