All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | List of all members
ana::PredictionInterp Class Reference

Implements systematic errors by interpolation between shifted templates. More...

#include <PredictionInterp.h>

Inheritance diagram for ana::PredictionInterp:
ana::IPrediction

Classes

struct  Coeffs
 
struct  Key_t
 
struct  ShiftedPreds
 
struct  Val_t
 

Public Types

enum  EMode_t { kCombineSigns, kSplitBySign }
 
enum  CoeffsType {
  kNueApp, kNueSurv, kNumuSurv, kNC,
  kOther, kNCoeffTypes
}
 

Public Member Functions

 PredictionInterp (std::vector< const ISyst * > systs, osc::IOscCalc *osc, const IPredictionGenerator &predGen, Loaders &loaders, const SystShifts &shiftMC=kNoShift, EMode_t mode=kCombineSigns)
 
virtual ~PredictionInterp ()
 
virtual Spectrum Predict (osc::IOscCalc *calc) const override
 
virtual Spectrum PredictSyst (osc::IOscCalc *calc, const SystShifts &shift) const override
 
virtual Spectrum PredictComponent (osc::IOscCalc *calc, Flavors::Flavors_t flav, Current::Current_t curr, Sign::Sign_t sign) const override
 
virtual Spectrum PredictComponentSyst (osc::IOscCalc *calc, const SystShifts &shift, Flavors::Flavors_t flav, Current::Current_t curr, Sign::Sign_t sign) const override
 
virtual void SaveTo (TDirectory *dir) const override
 
void MinimizeMemory ()
 
void DebugPlot (const ISyst *syst, osc::IOscCalc *calc, Flavors::Flavors_t flav=Flavors::kAll, Current::Current_t curr=Current::kBoth, Sign::Sign_t sign=Sign::kBoth) const
 
void DebugPlots (osc::IOscCalc *calc, const std::string &savePattern="", Flavors::Flavors_t flav=Flavors::kAll, Current::Current_t curr=Current::kBoth, Sign::Sign_t sign=Sign::kBoth) const
 
void SetOscSeed (osc::IOscCalc *oscSeed)
 
void DebugPlotColz (const ISyst *syst, osc::IOscCalc *calc, Flavors::Flavors_t flav=Flavors::kAll, Current::Current_t curr=Current::kBoth, Sign::Sign_t sign=Sign::kBoth) const
 
void DebugPlotsColz (osc::IOscCalc *calc, const std::string &savePattern="", Flavors::Flavors_t flav=Flavors::kAll, Current::Current_t curr=Current::kBoth, Sign::Sign_t sign=Sign::kBoth) const
 
bool SplitBySign () const
 
 PredictionInterp ()
 
std::vector< std::vector
< Coeffs > > 
FitRatios (const std::vector< double > &shifts, const std::vector< std::unique_ptr< TH1 >> &ratios) const
 Find coefficients describing this set of shifts. More...
 
std::vector< std::vector
< Coeffs > > 
FitComponent (const std::vector< double > &shifts, const std::vector< IPrediction * > &preds, Flavors::Flavors_t flav, Current::Current_t curr, Sign::Sign_t sign, const std::string &shortName) const
 Find coefficients describing the ratios from this component. More...
 
Spectrum ShiftSpectrum (const Spectrum &s, CoeffsType type, bool nubar, const SystShifts &shift) const
 
Spectrum ShiftedComponent (osc::IOscCalc *calc, const TMD5 *hash, const SystShifts &shift, Flavors::Flavors_t flav, Current::Current_t curr, Sign::Sign_t sign, CoeffsType type) const
 Helper for PredictComponentSyst. More...
 
- Public Member Functions inherited from ana::IPrediction
virtual ~IPrediction ()
 
virtual Spectrum PredictUnoscillated () const
 
virtual OscillatableSpectrum ComponentCC (int from, int to) const
 

Static Public Member Functions

static std::unique_ptr
< PredictionInterp
LoadFrom (TDirectory *dir)
 

Public Attributes

std::unique_ptr< IPredictionfPredNom
 The nominal prediction. More...
 

Protected Member Functions

void InitFits () const
 
void InitFitsHelper (ShiftedPreds &sp, std::vector< std::vector< std::vector< Coeffs >>> &fits, Sign::Sign_t sign) const
 

Protected Attributes

std::unordered_map< const
ISyst *, ShiftedPreds
fPreds
 
osc::IOscCalcfOscOrigin
 The oscillation values we assume when evaluating the coefficients. More...
 
Spectrum fBinning
 Dummy spectrum to provide binning. More...
 
std::map< Key_t, Val_tfNomCache
 
bool fSplitBySign
 

Detailed Description

Implements systematic errors by interpolation between shifted templates.

Definition at line 22 of file PredictionInterp.h.

Member Enumeration Documentation

Enumerator
kNueApp 
kNueSurv 
kNumuSurv 
kNC 
kOther 

Taus, numu appearance.

kNCoeffTypes 

Definition at line 101 of file PredictionInterp.h.

Enumerator
kCombineSigns 
kSplitBySign 

Definition at line 25 of file PredictionInterp.h.

Constructor & Destructor Documentation

ana::PredictionInterp::PredictionInterp ( std::vector< const ISyst * >  systs,
osc::IOscCalc osc,
const IPredictionGenerator predGen,
Loaders loaders,
const SystShifts shiftMC = kNoShift,
EMode_t  mode = kCombineSigns 
)
Parameters
systsWhat systematics we should be capable of interpolating
oscThe oscillation point to expand around
predGenConstruct an IPrediction from the following information.
loadersThe loaders to be passed on to the underlying prediction
shiftMCUnderlying shift. Use with care. Mostly for PredictionNumuFAHadE. Should not contain any of of systs
modeIn FHC the wrong-sign has bad stats and probably the fits can't be split out reasonably. For RHC it's important not to conflate them.

Definition at line 29 of file PredictionInterp.cxx.

35  : fOscOrigin(osc ? osc->Copy() : 0),
36  fBinning(0, {}, {}, 0, 0),
Spectrum fBinning
Dummy spectrum to provide binning.
osc::IOscCalc * fOscOrigin
The oscillation values we assume when evaluating the coefficients.
ana::PredictionInterp::~PredictionInterp ( )
virtual

Definition at line 60 of file PredictionInterp.cxx.

61  {
62  // for(auto it: fPreds) for(IPrediction* p: it.second.preds) delete p;
63  // delete fOscOrigin;
64 
65  // It isn't really a unique ptr when we use PredictionInterpTemplates
66  fPredNom.release();
67  }
std::unique_ptr< IPrediction > fPredNom
The nominal prediction.
ana::PredictionInterp::PredictionInterp ( )
inline

Definition at line 107 of file PredictionInterp.h.

107 : fBinning(0, {}, {}, 0, 0) {}
Spectrum fBinning
Dummy spectrum to provide binning.

Member Function Documentation

void ana::PredictionInterp::DebugPlot ( const ISyst syst,
osc::IOscCalc calc,
Flavors::Flavors_t  flav = Flavors::kAll,
Current::Current_t  curr = Current::kBoth,
Sign::Sign_t  sign = Sign::kBoth 
) const

Definition at line 556 of file PredictionInterp.cxx.

561  {
562  DontAddDirectory guard;
563 
564  InitFits();
565 
566  auto it = fPreds.find(syst);
567  if(it == fPreds.end()){
568  std::cout << "PredictionInterp::DebugPlots(): "
569  << syst->ShortName() << " not found" << std::endl;
570  return;
571  }
572 
573  std::unique_ptr<TH1> nom(fPredNom->PredictComponent(calc, flav, curr, sign).ToTH1(18e20));
574  const int nbins = nom->GetNbinsX();
575 
576  std::vector<TGraph*> curves(nbins);
577  std::vector<TGraph*> points(nbins);
578 
579  for(int i = 0; i <= 80; ++i){
580  const double x = .1*i-4;
581  const SystShifts ss(it->first, x);
582  std::unique_ptr<TH1> h(PredictComponentSyst(calc, ss, flav, curr, sign).ToTH1(18e20));
583 
584  for(int bin = 0; bin < nbins; ++bin){
585  if(i == 0){
586  curves[bin] = new TGraph;
587  points[bin] = new TGraph;
588  }
589 
590  const double ratio = h->GetBinContent(bin+1)/nom->GetBinContent(bin+1);
591 
592  if(!std::isnan(ratio)) curves[bin]->SetPoint(curves[bin]->GetN(), x, ratio);
593  else curves[bin]->SetPoint(curves[bin]->GetN(), x, 1);
594  } // end for bin
595  } // end for i (x)
596 
597  // As elswhere, to allow BirksC etc that need a different nominal to plot
598  // right.
599  IPrediction* pNom = 0;
600  for(unsigned int shiftIdx = 0; shiftIdx < it->second.shifts.size(); ++shiftIdx){
601  if(it->second.shifts[shiftIdx] == 0) pNom = it->second.preds[shiftIdx];
602  }
603  assert(pNom);
604  std::unique_ptr<TH1> hnom(pNom->PredictComponent(calc, flav, curr, sign).ToTH1(18e20));
605 
606  for(unsigned int shiftIdx = 0; shiftIdx < it->second.shifts.size(); ++shiftIdx){
607  if(!it->second.preds[shiftIdx]) continue; // Probably MinimizeMemory()
608  std::unique_ptr<TH1> h(it->second.preds[shiftIdx]->PredictComponent(calc, flav, curr, sign).ToTH1(18e20));
609 
610  for(int bin = 0; bin < nbins; ++bin){
611  const double ratio = h->GetBinContent(bin+1)/hnom->GetBinContent(bin+1);
612  if(!std::isnan(ratio)) points[bin]->SetPoint(points[bin]->GetN(), it->second.shifts[shiftIdx], ratio);
613  else points[bin]->SetPoint(points[bin]->GetN(), it->second.shifts[shiftIdx], 1);
614  }
615  } // end for shiftIdx
616 
617 
618  int nx = int(sqrt(nbins));
619  int ny = int(sqrt(nbins));
620  if(nx*ny < nbins) ++nx;
621  if(nx*ny < nbins) ++ny;
622 
623  TCanvas* c = new TCanvas;
624  c->Divide(nx, ny);
625 
626  for(int bin = 0; bin < nbins; ++bin){
627  c->cd(bin+1);
628  (new TH2F(UniqueName().c_str(),
629  TString::Format("%s %g < %s < %g;Shift;Ratio",
630  it->second.systName.c_str(),
631  nom->GetXaxis()->GetBinLowEdge(bin+1),
632  nom->GetXaxis()->GetTitle(),
633  nom->GetXaxis()->GetBinUpEdge(bin+1)),
634  100, -4, +4, 100, .5, 1.5))->Draw();
635  curves[bin]->Draw("l same");
636  points[bin]->SetMarkerStyle(kFullDotMedium);
637  points[bin]->Draw("p same");
638  } // end for bin
639 
640  c->cd(0);
641  }
process_name opflash particleana ie x
constexpr details::BinObj< T > bin(T value)
Returns a wrapper to print the specified data in binary format.
std::unique_ptr< IPrediction > fPredNom
The nominal prediction.
while getopts h
int sign(double val)
Definition: UtilFunc.cxx:104
std::unordered_map< const ISyst *, ShiftedPreds > fPreds
virtual Spectrum PredictComponentSyst(osc::IOscCalc *calc, const SystShifts &shift, Flavors::Flavors_t flav, Current::Current_t curr, Sign::Sign_t sign) const override
std::string UniqueName()
Return a different string each time, for creating histograms.
BEGIN_PROLOG could also be cout
void ana::PredictionInterp::DebugPlotColz ( const ISyst syst,
osc::IOscCalc calc,
Flavors::Flavors_t  flav = Flavors::kAll,
Current::Current_t  curr = Current::kBoth,
Sign::Sign_t  sign = Sign::kBoth 
) const

Definition at line 677 of file PredictionInterp.cxx.

682  {
683  InitFits();
684 
685  std::unique_ptr<TH1> nom(fPredNom->PredictComponent(calc, flav, curr, sign).ToTH1(18e20));
686  const int nbins = nom->GetNbinsX();
687 
688  TH2* h2 = new TH2F("", (syst->LatexName()+";;#sigma").c_str(),
689  nbins, nom->GetXaxis()->GetXmin(), nom->GetXaxis()->GetXmax(),
690  80, -4, +4);
691  h2->GetXaxis()->SetTitle(nom->GetXaxis()->GetTitle());
692 
693  for(int i = 1; i <= 80; ++i){
694  const double y = h2->GetYaxis()->GetBinCenter(i);
695  const SystShifts ss(syst, y);
696  std::unique_ptr<TH1> h(PredictComponentSyst(calc, ss, flav, curr, sign).ToTH1(18e20));
697 
698  for(int bin = 0; bin < nbins; ++bin){
699  const double ratio = h->GetBinContent(bin+1)/nom->GetBinContent(bin+1);
700 
701  if(!isnan(ratio) && !isinf(ratio))
702  h2->Fill(h2->GetXaxis()->GetBinCenter(bin), y, ratio);
703  } // end for bin
704  } // end for i (x)
705 
706  h2->Draw("colz");
707  h2->SetMinimum(0.5);
708  h2->SetMaximum(1.5);
709  }
constexpr details::BinObj< T > bin(T value)
Returns a wrapper to print the specified data in binary format.
std::unique_ptr< IPrediction > fPredNom
The nominal prediction.
while getopts h
process_name opflash particleana ie ie y
int sign(double val)
Definition: UtilFunc.cxx:104
virtual Spectrum PredictComponentSyst(osc::IOscCalc *calc, const SystShifts &shift, Flavors::Flavors_t flav, Current::Current_t curr, Sign::Sign_t sign) const override
void ana::PredictionInterp::DebugPlots ( osc::IOscCalc calc,
const std::string &  savePattern = "",
Flavors::Flavors_t  flav = Flavors::kAll,
Current::Current_t  curr = Current::kBoth,
Sign::Sign_t  sign = Sign::kBoth 
) const

Definition at line 644 of file PredictionInterp.cxx.

649  {
650  const bool save = !savePattern.empty();
651  const bool multiFile = savePattern.find("%s") != std::string::npos;
652 
653  if(save && !multiFile){
654  new TCanvas;
655  gPad->Print((savePattern+"[").c_str());
656  }
657 
658  for(auto& it: fPreds){
659  DebugPlot(it.first, calc, flav, curr, sign);
660 
661  if(save){
662  if(multiFile){
663  gPad->Print(TString::Format(savePattern.c_str(), it.second.systName.c_str()).Data());
664  }
665  else{
666  gPad->Print(savePattern.c_str());
667  }
668  }
669  } // end for it
670 
671  if(save && !multiFile){
672  gPad->Print((savePattern+"]").c_str());
673  }
674  }
int sign(double val)
Definition: UtilFunc.cxx:104
void DebugPlot(const ISyst *syst, osc::IOscCalc *calc, Flavors::Flavors_t flav=Flavors::kAll, Current::Current_t curr=Current::kBoth, Sign::Sign_t sign=Sign::kBoth) const
std::unordered_map< const ISyst *, ShiftedPreds > fPreds
void ana::PredictionInterp::DebugPlotsColz ( osc::IOscCalc calc,
const std::string &  savePattern = "",
Flavors::Flavors_t  flav = Flavors::kAll,
Current::Current_t  curr = Current::kBoth,
Sign::Sign_t  sign = Sign::kBoth 
) const

Definition at line 712 of file PredictionInterp.cxx.

717  {
718  const bool save = !savePattern.empty();
719  const bool multiFile = savePattern.find("%s") != std::string::npos;
720 
721  if(save && !multiFile){
722  new TCanvas;
723  gPad->Print((savePattern+"[").c_str());
724  }
725 
726  for(auto it: fPreds){
727  new TCanvas;
728  DebugPlotColz(it.first, calc, flav, curr, sign);
729 
730  if(save){
731  if(multiFile){
732  gPad->Print(TString::Format(savePattern.c_str(), it.second.systName.c_str()).Data());
733  }
734  else{
735  gPad->Print(savePattern.c_str());
736  }
737  }
738  } // end for it
739 
740  if(save && !multiFile){
741  gPad->Print((savePattern+"]").c_str());
742  }
743  }
int sign(double val)
Definition: UtilFunc.cxx:104
void DebugPlotColz(const ISyst *syst, osc::IOscCalc *calc, Flavors::Flavors_t flav=Flavors::kAll, Current::Current_t curr=Current::kBoth, Sign::Sign_t sign=Sign::kBoth) const
std::unordered_map< const ISyst *, ShiftedPreds > fPreds
std::vector< std::vector< PredictionInterp::Coeffs > > ana::PredictionInterp::FitComponent ( const std::vector< double > &  shifts,
const std::vector< IPrediction * > &  preds,
Flavors::Flavors_t  flav,
Current::Current_t  curr,
Sign::Sign_t  sign,
const std::string &  shortName 
) const

Find coefficients describing the ratios from this component.

Definition at line 167 of file PredictionInterp.cxx.

173  {
174  IPrediction* pNom = 0;
175  for(unsigned int i = 0; i < shifts.size(); ++i){
176  if(shifts[i] == 0) pNom = preds[i];
177  }
178  assert(pNom);
179 
180  // Do it this way rather than via fPredNom so that systematics evaluated
181  // relative to some alternate nominal (eg Birks C where the appropriate
182  // nominal is no-rock) can work.
183  const Spectrum nom = pNom->PredictComponent(fOscOrigin,
184  flav, curr, sign);
185 
186  std::vector<std::unique_ptr<TH1>> ratios;
187  for(auto& p: preds){
188  ratios.emplace_back(Ratio(p->PredictComponent(fOscOrigin,
189  flav, curr, sign),
190  nom).ToTH1());
191 
192  // Check none of the ratio values is utterly crazy
193  std::unique_ptr<TH1>& r = ratios.back();
194  for(int i = 0; i < r->GetNbinsX()+2; ++i){
195  const double y = r->GetBinContent(i);
196  if(y > 500){
197  std::cout << "PredictionInterp: WARNING, ratio in bin "
198  << i << " is " << y
199  << " for '" << shortName << "'. Ignoring." << std::endl;
200  r->SetBinContent(i, 1);
201  }
202  }
203  }
204 
205  return FitRatios(shifts, ratios);
206  }
pdgs p
Definition: selectors.fcl:22
std::vector< std::vector< Coeffs > > FitRatios(const std::vector< double > &shifts, const std::vector< std::unique_ptr< TH1 >> &ratios) const
Find coefficients describing this set of shifts.
process_name opflash particleana ie ie y
int sign(double val)
Definition: UtilFunc.cxx:104
osc::IOscCalc * fOscOrigin
The oscillation values we assume when evaluating the coefficients.
esac echo uname r
BEGIN_PROLOG could also be cout
std::vector< std::vector< PredictionInterp::Coeffs > > ana::PredictionInterp::FitRatios ( const std::vector< double > &  shifts,
const std::vector< std::unique_ptr< TH1 >> &  ratios 
) const

Find coefficients describing this set of shifts.

Definition at line 71 of file PredictionInterp.cxx.

73  {
74  assert(shifts.size() == ratios.size());
75 
76  std::vector<std::vector<Coeffs>> ret;
77 
78  const int binMax = ratios[0]->GetNbinsX();
79 
80  // Linear interpolation
81  if(ratios.size() == 2){
82  for(int binIdx = 0; binIdx < binMax+2; ++binIdx){
83  ret.push_back({});
84  const double y1 = ratios[0]->GetBinContent(binIdx);
85  const double y2 = ratios[1]->GetBinContent(binIdx);
86  ret.back().emplace_back(0, 0, y2-y1, y1);
87  }
88  return ret;
89  }
90 
91  for(int binIdx = 0; binIdx < binMax+2; ++binIdx){
92  ret.push_back({});
93 
94  // This is cubic interpolation. For each adjacent set of four points we
95  // determine coefficients for a cubic which will be the curve between the
96  // center two. We constrain the function to match the two center points
97  // and to have the right mean gradient at them. This causes this patch to
98  // match smoothly with the next one along. The resulting function is
99  // continuous and first and second differentiable. At the ends of the
100  // range we fit a quadratic instead with only one constraint on the
101  // slope. The coordinate conventions are that point y1 sits at x=0 and y2
102  // at x=1. The matrices are simply the inverses of writing out the
103  // constraints expressed above.
104 
105  {
106  const double y1 = ratios[0]->GetBinContent(binIdx);
107  const double y2 = ratios[1]->GetBinContent(binIdx);
108  const double y3 = ratios[2]->GetBinContent(binIdx);
109  const double v[3] = {y1, y2, (y3-y1)/2};
110  const double m[9] = { 1, -1, 1,
111  -2, 2, -1,
112  1, 0, 0};
113  const TVectorD res = TMatrixD(3, 3, m) * TVectorD(3, v);
114  ret.back().emplace_back(0, res(0), res(1), res(2));
115  }
116 
117  // We're assuming here that the shifts are separated by exactly 1 sigma.
118  for(unsigned int shiftIdx = 1; shiftIdx < ratios.size()-2; ++shiftIdx){
119  const double y0 = ratios[shiftIdx-1]->GetBinContent(binIdx);
120  const double y1 = ratios[shiftIdx ]->GetBinContent(binIdx);
121  const double y2 = ratios[shiftIdx+1]->GetBinContent(binIdx);
122  const double y3 = ratios[shiftIdx+2]->GetBinContent(binIdx);
123 
124  const double v[4] = {y1, y2, (y2-y0)/2, (y3-y1)/2};
125  const double m[16] = { 2, -2, 1, 1,
126  -3, 3, -2, -1,
127  0, 0, 1, 0,
128  1, 0, 0, 0};
129  const TVectorD res = TMatrixD(4, 4, m) * TVectorD(4, v);
130  ret.back().emplace_back(res(0), res(1), res(2), res(3));
131  } // end for shiftIdx
132 
133  {
134  const int N = ratios.size()-3;
135  const double y0 = ratios[N ]->GetBinContent(binIdx);
136  const double y1 = ratios[N+1]->GetBinContent(binIdx);
137  const double y2 = ratios[N+2]->GetBinContent(binIdx);
138  const double v[3] = {y1, y2, (y2-y0)/2};
139  const double m[9] = {-1, 1, -1,
140  0, 0, 1,
141  1, 0, 0};
142  const TVectorD res = TMatrixD(3, 3, m) * TVectorD(3, v);
143  ret.back().emplace_back(0, res(0), res(1), res(2));
144  }
145  } // end for binIdx
146 
147  double stride = -1;
148  for(unsigned int i = 0; i < shifts.size()-1; ++i){
149  const double newStride = shifts[i+1]-shifts[i];
150  assert((stride < 0 || fabs(stride-newStride) < 1e-3) &&
151  "Variably-spaced syst templates are unsupported");
152  stride = newStride;
153  }
154 
155  // If the stride is actually not 1, need to rescale all the coefficients
156  for(std::vector<Coeffs>& cs: ret)
157  for(Coeffs& c: cs){
158  c = Coeffs(c.a/util::cube(stride),
159  c.b/util::sqr(stride),
160  c.c/stride,
161  c.d);}
162  return ret;
163  }
T cube(T x)
More efficient cube function than pow(x,3)
Definition: MathUtil.h:26
T sqr(T x)
More efficient square function than pow(x,2)
Definition: MathUtil.h:23
tuple m
now if test mode generate materials, CRT shell, world, gdml header else just generate CRT shell for u...
process_name largeant stream1 can override from command line with o or output physics producers generator N
do i e
void ana::PredictionInterp::InitFits ( ) const
protected

Definition at line 225 of file PredictionInterp.cxx.

226  {
227  // No systs
228  if(fPreds.empty()){
229  if(fBinning.POT() > 0 || fBinning.Livetime() > 0) return;
230  }
231  // Already initialized
232  else if(!fPreds.empty() && !fPreds.begin()->second.fits.empty()) return;
233 
234  for(auto& it: fPreds){
235  ShiftedPreds& sp = it.second;
236 
237  if(fSplitBySign){
238  InitFitsHelper(sp, sp.fits, Sign::kNu);
239  InitFitsHelper(sp, sp.fitsNubar, Sign::kAntiNu);
240  }
241  else{
242  InitFitsHelper(sp, sp.fits, Sign::kBoth);
243  }
244  sp.nCoeffs = sp.fits[0][0].size();
245  }
246 
247  // Predict something, anything, so that we can know what binning to use
248  fBinning = fPredNom->Predict(fOscOrigin);
249  fBinning.Clear();
250  }
Antineutrinos-only.
Definition: IPrediction.h:49
std::unique_ptr< IPrediction > fPredNom
The nominal prediction.
Spectrum fBinning
Dummy spectrum to provide binning.
double POT() const
Definition: Spectrum.h:289
Neutrinos-only.
Definition: IPrediction.h:48
Both neutrinos and antineutrinos.
Definition: IPrediction.h:51
void InitFitsHelper(ShiftedPreds &sp, std::vector< std::vector< std::vector< Coeffs >>> &fits, Sign::Sign_t sign) const
std::unordered_map< const ISyst *, ShiftedPreds > fPreds
osc::IOscCalc * fOscOrigin
The oscillation values we assume when evaluating the coefficients.
double Livetime() const
Seconds. For informational purposes only. No calculations use this.
Definition: Spectrum.h:292
void ana::PredictionInterp::InitFitsHelper ( ShiftedPreds sp,
std::vector< std::vector< std::vector< Coeffs >>> &  fits,
Sign::Sign_t  sign 
) const
protected

Definition at line 209 of file PredictionInterp.cxx.

212  {
213  fits.resize(kNCoeffTypes);
214 
215  fits[kNueApp] = FitComponent(sp.shifts, sp.preds, Flavors::kNuMuToNuE, Current::kCC, sign, sp.systName);
216  fits[kNueSurv] = FitComponent(sp.shifts, sp.preds, Flavors::kNuEToNuE, Current::kCC, sign, sp.systName);
217  fits[kNumuSurv] = FitComponent(sp.shifts, sp.preds, Flavors::kNuMuToNuMu, Current::kCC, sign, sp.systName);
218 
219  fits[kNC] = FitComponent(sp.shifts, sp.preds, Flavors::kAll, Current::kNC, sign, sp.systName);
220 
221  fits[kOther] = FitComponent(sp.shifts, sp.preds, Flavors::kNuEToNuMu | Flavors::kAllNuTau, Current::kCC, sign, sp.systName);
222  }
(&#39; appearance&#39;)
Definition: IPrediction.h:17
(&#39;beam &#39;)
Definition: IPrediction.h:14
Charged-current interactions.
Definition: IPrediction.h:38
(&#39; survival&#39;)
Definition: IPrediction.h:18
Taus, numu appearance.
int sign(double val)
Definition: UtilFunc.cxx:104
Neutral-current interactions.
Definition: IPrediction.h:39
All neutrinos, any flavor.
Definition: IPrediction.h:25
(&#39; appearance&#39;)
Definition: IPrediction.h:15
std::vector< std::vector< Coeffs > > FitComponent(const std::vector< double > &shifts, const std::vector< IPrediction * > &preds, Flavors::Flavors_t flav, Current::Current_t curr, Sign::Sign_t sign, const std::string &shortName) const
Find coefficients describing the ratios from this component.
std::unique_ptr< PredictionInterp > ana::PredictionInterp::LoadFrom ( TDirectory *  dir)
static

Definition at line 479 of file PredictionInterp.cxx.

480  {
481  TObjString* tag = (TObjString*)dir->Get("type");
482  assert(tag);
483  assert(tag->GetString() == "PredictionInterp" ||
484  tag->GetString() == "PredictionInterp2"); // backwards compatibility
485 
486  std::unique_ptr<PredictionInterp> ret(new PredictionInterp);
487 
488  LoadFromBody(dir, ret.get());
489 
490  TObjString* split_sign = (TObjString*)dir->Get("split_sign");
491  // Can be missing from old files
492  ret->fSplitBySign = (split_sign && split_sign->String() == "yes");
493 
494  return ret;
495  }
tuple dir
Definition: dropbox.py:28
void ana::PredictionInterp::MinimizeMemory ( )

After calling this DebugPlots won't work fully and SaveTo won't work at all.

Definition at line 531 of file PredictionInterp.cxx.

532  {
533  InitFits();
534 
535  std::set<IPrediction*> todel;
536  for(auto& it: fPreds){
537  std::vector<IPrediction*>& preds = it.second.preds;
538  for(unsigned int i = 0; i < preds.size(); ++i){
539  if(preds[i] != fPredNom.get()){
540  todel.insert(preds[i]);
541  preds[i] = 0;
542  }
543  }
544  }
545 
546  for(IPrediction* p: todel) delete p;
547 
548  // We probably just freed up a lot of memory, but malloc by default hangs
549  // on to all of it as cache.
550  #ifndef DARWINBUILD
551  malloc_trim(0);
552  #endif
553  }
pdgs p
Definition: selectors.fcl:22
std::unique_ptr< IPrediction > fPredNom
The nominal prediction.
std::unordered_map< const ISyst *, ShiftedPreds > fPreds
Spectrum ana::PredictionInterp::Predict ( osc::IOscCalc calc) const
overridevirtual

Implements ana::IPrediction.

Definition at line 259 of file PredictionInterp.cxx.

260  {
261  return fPredNom->Predict(calc);
262  }
std::unique_ptr< IPrediction > fPredNom
The nominal prediction.
Spectrum ana::PredictionInterp::PredictComponent ( osc::IOscCalc calc,
Flavors::Flavors_t  flav,
Current::Current_t  curr,
Sign::Sign_t  sign 
) const
overridevirtual

Implements ana::IPrediction.

Definition at line 265 of file PredictionInterp.cxx.

269  {
270  return fPredNom->PredictComponent(calc, flav, curr, sign);
271  }
std::unique_ptr< IPrediction > fPredNom
The nominal prediction.
int sign(double val)
Definition: UtilFunc.cxx:104
Spectrum ana::PredictionInterp::PredictComponentSyst ( osc::IOscCalc calc,
const SystShifts shift,
Flavors::Flavors_t  flav,
Current::Current_t  curr,
Sign::Sign_t  sign 
) const
overridevirtual

Reimplemented from ana::IPrediction.

Definition at line 391 of file PredictionInterp.cxx.

396  {
397  InitFits();
398 
399  Spectrum& ret = fBinning;
400  ret.Clear();
401 
402  if(ret.POT()==0) ret.OverridePOT(1e24);
403 
404  // Check that we're able to handle all the systs we were passed
405  for(const ISyst* syst: shift.ActiveSysts()){
406  if(fPreds.find(syst) == fPreds.end()){
407  std::cerr << "This PredictionInterp is not set up to handle the requested systematic: " << syst->ShortName() << std::endl;
408  abort();
409  }
410  } // end for syst
411 
412 
413  const TMD5* hash = calc ? calc->GetParamsHash() : 0;
414 
415  if(curr & Current::kCC){
416  if(flav & Flavors::kNuEToNuE) ret += ShiftedComponent(calc, hash, shift, Flavors::kNuEToNuE, Current::kCC, sign, kNueSurv);
417  if(flav & Flavors::kNuEToNuMu) ret += ShiftedComponent(calc, hash, shift, Flavors::kNuEToNuMu, Current::kCC, sign, kOther );
418  if(flav & Flavors::kNuEToNuTau) ret += ShiftedComponent(calc, hash, shift, Flavors::kNuEToNuTau, Current::kCC, sign, kOther );
419 
420  if(flav & Flavors::kNuMuToNuE) ret += ShiftedComponent(calc, hash, shift, Flavors::kNuMuToNuE, Current::kCC, sign, kNueApp );
421  if(flav & Flavors::kNuMuToNuMu) ret += ShiftedComponent(calc, hash, shift, Flavors::kNuMuToNuMu, Current::kCC, sign, kNumuSurv);
422  if(flav & Flavors::kNuMuToNuTau) ret += ShiftedComponent(calc, hash, shift, Flavors::kNuMuToNuTau, Current::kCC, sign, kOther );
423  }
424  if(curr & Current::kNC){
425  assert(flav == Flavors::kAll); // Don't know how to calculate anything else
426 
427  ret += ShiftedComponent(calc, hash, shift, Flavors::kAll, Current::kNC, sign, kNC);
428  }
429 
430  delete hash;
431 
432  return ret;
433  }
(&#39; appearance&#39;)
Definition: IPrediction.h:17
BEGIN_PROLOG could also be cerr
(&#39;beam &#39;)
Definition: IPrediction.h:14
shift
Definition: fcl_checks.sh:26
Charged-current interactions.
Definition: IPrediction.h:38
Spectrum fBinning
Dummy spectrum to provide binning.
(&#39; survival&#39;)
Definition: IPrediction.h:18
Taus, numu appearance.
int sign(double val)
Definition: UtilFunc.cxx:104
Neutral-current interactions.
Definition: IPrediction.h:39
std::unordered_map< const ISyst *, ShiftedPreds > fPreds
All neutrinos, any flavor.
Definition: IPrediction.h:25
(&#39; appearance&#39;)
Definition: IPrediction.h:15
Spectrum ShiftedComponent(osc::IOscCalc *calc, const TMD5 *hash, const SystShifts &shift, Flavors::Flavors_t flav, Current::Current_t curr, Sign::Sign_t sign, CoeffsType type) const
Helper for PredictComponentSyst.
Spectrum ana::PredictionInterp::PredictSyst ( osc::IOscCalc calc,
const SystShifts shift 
) const
overridevirtual

Reimplemented from ana::IPrediction.

Definition at line 274 of file PredictionInterp.cxx.

276  {
277  InitFits();
278 
279  return PredictComponentSyst(calc, shift,
282  Sign::kBoth);
283  }
shift
Definition: fcl_checks.sh:26
Interactions of both types.
Definition: IPrediction.h:41
Both neutrinos and antineutrinos.
Definition: IPrediction.h:51
All neutrinos, any flavor.
Definition: IPrediction.h:25
virtual Spectrum PredictComponentSyst(osc::IOscCalc *calc, const SystShifts &shift, Flavors::Flavors_t flav, Current::Current_t curr, Sign::Sign_t sign) const override
void ana::PredictionInterp::SaveTo ( TDirectory *  dir) const
overridevirtual

Reimplemented from ana::IPrediction.

Definition at line 436 of file PredictionInterp.cxx.

437  {
438  TDirectory* tmp = gDirectory;
439 
440  dir->cd();
441  TObjString("PredictionInterp").Write("type");
442 
443 
444  fPredNom->SaveTo(dir->mkdir("pred_nom"));
445 
446 
447  for(auto it: fPreds){
448  const ShiftedPreds& sp = it.second;
449 
450  for(unsigned int i = 0; i < sp.shifts.size(); ++i){
451  if(!sp.preds[i]){
452  std::cout << "Can't save a PredictionInterp after MinimizeMemory()" << std::endl;
453  abort();
454  }
455  sp.preds[i]->SaveTo(dir->mkdir(TString::Format("pred_%s_%+d",
456  sp.systName.c_str(),
457  int(sp.shifts[i])).Data()));
458  } // end for i
459  } // end for it
460 
461  ana::SaveTo(*fOscOrigin, dir->mkdir("osc_origin"));
462 
463  if(!fPreds.empty()){
464  TH1F hSystNames("syst_names", ";Syst names", fPreds.size(), 0, fPreds.size());
465  int binIdx = 1;
466  for(auto it: fPreds){
467  hSystNames.GetXaxis()->SetBinLabel(binIdx++, it.second.systName.c_str());
468  }
469  hSystNames.Write("syst_names");
470  }
471 
472  TObjString split_sign = fSplitBySign ? "yes" : "no";
473  split_sign.Write("split_sign");
474 
475  tmp->cd();
476  }
std::unique_ptr< IPrediction > fPredNom
The nominal prediction.
tuple dir
Definition: dropbox.py:28
std::unordered_map< const ISyst *, ShiftedPreds > fPreds
osc::IOscCalc * fOscOrigin
The oscillation values we assume when evaluating the coefficients.
void SaveTo(const osc::IOscCalc &x, TDirectory *dir)
BEGIN_PROLOG could also be cout
void ana::PredictionInterp::SetOscSeed ( osc::IOscCalc oscSeed)

Definition at line 253 of file PredictionInterp.cxx.

253  {
254  fOscOrigin = oscSeed->Copy();
255  for(auto& it: fPreds) it.second.fits.clear();
256  }
std::unordered_map< const ISyst *, ShiftedPreds > fPreds
osc::IOscCalc * fOscOrigin
The oscillation values we assume when evaluating the coefficients.
Spectrum ana::PredictionInterp::ShiftedComponent ( osc::IOscCalc calc,
const TMD5 *  hash,
const SystShifts shift,
Flavors::Flavors_t  flav,
Current::Current_t  curr,
Sign::Sign_t  sign,
CoeffsType  type 
) const

Helper for PredictComponentSyst.

Definition at line 345 of file PredictionInterp.cxx.

352  {
353  if(fSplitBySign && sign == Sign::kBoth){
354  return (ShiftedComponent(calc, hash, shift, flav, curr, Sign::kAntiNu, type)+
355  ShiftedComponent(calc, hash, shift, flav, curr, Sign::kNu, type));
356  }
357 
358  // Must be the base case of the recursion to use the cache. Otherwise we
359  // can cache systematically shifted versions of our children, which is
360  // wrong. Also, some calcs won't hash themselves.
361  const bool canCache = (hash != 0);
362 
363  const Key_t key = {flav, curr, sign};
364  auto it = fNomCache.find(key);
365 
366  // Should the interpolation use the nubar fits?
367  const bool nubar = (fSplitBySign && sign == Sign::kAntiNu);
368 
369  // We have the nominal for this exact combination of flav, curr, sign, calc
370  // stored. Shift it and return.
371  if(canCache && it != fNomCache.end() && it->second.hash == *hash){
372  return ShiftSpectrum(it->second.nom, type, nubar, shift);
373  }
374 
375  // We need to compute the nominal again for whatever reason
376  const Spectrum nom = fPredNom->PredictComponent(calc, flav, curr, sign);
377 
378  if(canCache){
379  // Insert into the cache if not already there, or update if there but
380  // with old oscillation parameters.
381  if(it == fNomCache.end())
382  fNomCache.emplace(key, Val_t({*hash, nom}));
383  else
384  it->second = {*hash, nom};
385  }
386 
387  return ShiftSpectrum(nom, type, nubar, shift);
388  }
Antineutrinos-only.
Definition: IPrediction.h:49
shift
Definition: fcl_checks.sh:26
std::unique_ptr< IPrediction > fPredNom
The nominal prediction.
std::map< Key_t, Val_t > fNomCache
Neutrinos-only.
Definition: IPrediction.h:48
int sign(double val)
Definition: UtilFunc.cxx:104
Both neutrinos and antineutrinos.
Definition: IPrediction.h:51
Spectrum ShiftedComponent(osc::IOscCalc *calc, const TMD5 *hash, const SystShifts &shift, Flavors::Flavors_t flav, Current::Current_t curr, Sign::Sign_t sign, CoeffsType type) const
Helper for PredictComponentSyst.
Spectrum ShiftSpectrum(const Spectrum &s, CoeffsType type, bool nubar, const SystShifts &shift) const
Spectrum ana::PredictionInterp::ShiftSpectrum ( const Spectrum s,
CoeffsType  type,
bool  nubar,
const SystShifts shift 
) const

Definition at line 287 of file PredictionInterp.cxx.

291  {
292  // Save time by not shifting a spectrum that is all zeros anyway
293  if(s.POT() == 0 && s.Livetime() == 0) return s;
294 
295  if(nubar) assert(fSplitBySign);
296 
297  InitFits();
298 
299  // TODO histogram operations could be too slow
300  TH1D* h = s.ToTH1(s.POT());
301 
302  const unsigned int N = h->GetNbinsX()+2;
303  std::vector<double> corr(N,1.0);
304 
305  for(auto& it: fPreds){
306  const ISyst* syst = it.first;
307  const ShiftedPreds& sp = it.second;
308 
309  auto& fits = nubar ? sp.fitsNubar : sp.fits;
310 
311  double x = shift.GetShift(syst);
312 
313  if(x == 0) continue;
314 
315  int shiftBin = (x - sp.shifts[0])/sp.Stride();
316  shiftBin = std::max(0, shiftBin);
317  shiftBin = std::min(shiftBin, sp.nCoeffs-1);
318 
319  x -= sp.shifts[shiftBin];
320 
321  const double x_cube = util::cube(x);
322  const double x_sqr = util::sqr(x);
323 
324  for(unsigned int n = 0; n < N; ++n){
325  // Uncomment to debug crashes in this function
326  // assert(type < fits.size());
327  // assert(n < sp.fits[type].size());
328  // assert(shiftBin < int(sp.fits[type][n].size()));
329  const Coeffs& f = fits[type][n][shiftBin];
330 
331  corr[n] *= f.a*x_cube + f.b*x_sqr + f.c*x + f.d;
332  } // end for n
333  } // end for syst
334 
335  double* arr = h->GetArray();
336  for(unsigned int n = 0; n < N; ++n){
337  arr[n] *= std::max(corr[n], 0.);
338  }
339 
340  return Spectrum(std::unique_ptr<TH1D>(h), s.GetLabels(), s.GetBinnings(), s.POT(), s.Livetime());
341  }
process_name opflash particleana ie x
T cube(T x)
More efficient cube function than pow(x,3)
Definition: MathUtil.h:26
shift
Definition: fcl_checks.sh:26
T sqr(T x)
More efficient square function than pow(x,2)
Definition: MathUtil.h:23
while getopts h
then echo File list $list not found else cat $list while read file do echo $file sed s
Definition: file_to_url.sh:60
process_name largeant stream1 can override from command line with o or output physics producers generator N
std::unordered_map< const ISyst *, ShiftedPreds > fPreds
bool ana::PredictionInterp::SplitBySign ( ) const
inline

Definition at line 100 of file PredictionInterp.h.

100 {return fSplitBySign;}

Member Data Documentation

Spectrum ana::PredictionInterp::fBinning
mutableprotected

Dummy spectrum to provide binning.

Definition at line 170 of file PredictionInterp.h.

std::map<Key_t, Val_t> ana::PredictionInterp::fNomCache
mutableprotected

Definition at line 188 of file PredictionInterp.h.

osc::IOscCalc* ana::PredictionInterp::fOscOrigin
protected

The oscillation values we assume when evaluating the coefficients.

Definition at line 168 of file PredictionInterp.h.

std::unique_ptr<IPrediction> ana::PredictionInterp::fPredNom

The nominal prediction.

Definition at line 146 of file PredictionInterp.h.

std::unordered_map<const ISyst*, ShiftedPreds> ana::PredictionInterp::fPreds
mutableprotected

Definition at line 165 of file PredictionInterp.h.

bool ana::PredictionInterp::fSplitBySign
protected

Definition at line 190 of file PredictionInterp.h.


The documentation for this class was generated from the following files: