17 #include "OscLib/IOscCalc.h"
20 #include "TDirectory.h"
23 #include "TObjString.h"
30 const std::vector<std::pair<SystShifts, const IPrediction*>>& univs)
31 : fSysts(systs), fNom(pnom), fUnivs(univs)
87 std::vector<std::vector<double>> coords;
89 for(
const auto& it:
fUnivs){
90 const std::vector<double> c =
GetCoords(it.first);
91 if(coords.empty()) coords.resize(c.size());
92 for(
unsigned int varIdx = 0; varIdx < c.size(); ++varIdx){
93 coords[varIdx].push_back(c[varIdx]);
97 const unsigned int N = coords.size();
99 std::vector<std::vector<double>> M(N, std::vector<double>(N));
101 for(
unsigned int i = 0; i <
N; ++i){
102 const std::vector<double>& ci = coords[i];
103 for(
unsigned int j = 0; j <
N; ++j){
104 const std::vector<double>& cj = coords[j];
105 for(
unsigned int univIdx = 0; univIdx < fUnivs.size(); ++univIdx){
106 M[i][j] += ci[univIdx] * cj[univIdx];
111 osc::NoOscillations calc;
115 TH1D* hnom = snom.
ToTH1(1);
116 const int Nbins = hnom->GetNbinsX();
120 std::vector<std::vector<double>>
ds(Nbins+2, std::vector<double>(fUnivs.size()));
122 for(
unsigned int univIdx = 0; univIdx < fUnivs.size(); ++univIdx){
123 const Ratio r(fUnivs[univIdx].
second->Predict(&calc), snom);
124 TH1D* hr =
r.ToTH1();
126 for(
int binIdx = 0; binIdx < Nbins+2; ++binIdx){
127 ds[binIdx][univIdx] = log(hr->GetBinContent(binIdx));
134 for(
int binIdx = 0; binIdx < Nbins+2; ++binIdx){
143 const std::vector<double>&
ds,
144 const std::vector<std::vector<double>>& coords)
const
146 const unsigned int N = M.size();
147 const unsigned int Nuniv =
fUnivs.size();
149 std::vector<double> v(N);
151 for(
unsigned int i = 0; i <
N; ++i){
152 const std::vector<double>& c = coords[i];
153 for(
unsigned int univIdx = 0; univIdx < Nuniv; ++univIdx){
154 v[i] += c[univIdx]* ds[univIdx];
161 std::vector<bool> already(N);
165 std::vector<double> vsub;
167 std::vector<int> vars;
169 std::vector<double> residual =
ds;
171 std::vector<std::vector<double>> coords_sub(Nuniv);
173 for(
unsigned int matSize = 1; matSize <= 500; ++matSize){
178 double bestSqErr = std::numeric_limits<double>::infinity();
180 for(
unsigned int varIdx = 0; varIdx <
N; ++varIdx){
181 if(already[varIdx])
continue;
183 const std::vector<double>& c = coords[varIdx];
185 double num = 0, denom = 0;
187 for(
unsigned int univIdx = 0; univIdx < Nuniv; ++univIdx){
188 num += residual[univIdx]*c[univIdx];
193 const double x = num/denom;
197 for(
unsigned int univIdx = 0; univIdx < Nuniv; ++univIdx){
198 sqErr +=
util::sqr(residual[univIdx] - c[univIdx] * x);
201 if(sqErr < bestSqErr){
210 const int varIdx = bestVarIdx;
211 const std::vector<double>& c = coords[varIdx];
214 already[varIdx] =
true;
217 vsub.push_back(v[varIdx]);
218 vars.push_back(varIdx);
219 icd.
AddRow(M[varIdx], vars);
222 const std::vector<double>
a = icd.
Solve(vsub);
225 for(
unsigned int univIdx = 0; univIdx < Nuniv; ++univIdx){
226 std::vector<double>& cs = coords_sub[univIdx];
227 cs.push_back(c[univIdx]);
230 residual[univIdx] = ds[univIdx];
231 for(
unsigned int i = 0; i < matSize; ++i){
232 residual[univIdx] -= a[i] * cs[i];
244 vsub = icd.
Solve(vsub);
247 std::vector<double> ret(N);
248 for(
unsigned int i = 0; i < vars.size(); ++i) ret[vars[i]] = vsub[i];
287 const unsigned int N =
fSysts.size();
289 std::vector<double> coords;
290 coords.reserve(N + (N*(N+1))/2);
296 for(
unsigned int i = 0; i <
N; ++i){
297 for(
unsigned int j = i; j <
N; ++j){
298 coords.push_back(coords[i] * coords[j]);
314 const std::vector<double> coords =
GetCoords(shift);
315 const unsigned int N = coords.size();
317 for(
unsigned int binIdx = 0; binIdx <
fCoeffs.size(); ++binIdx){
319 for(
unsigned int i = 0; i <
N; ++i) factor +=
fCoeffs[binIdx][i] * coords[i];
321 hret->SetBinContent(binIdx,
exp(factor));
324 const Ratio ret(hret);
332 TDirectory* tmp = gDirectory;
335 TObjString(
"PredictionLinFit").Write(
"type");
339 for(
unsigned int univIdx = 0; univIdx <
fUnivs.size(); ++univIdx){
340 TDirectory* ud = dir->mkdir(TString::Format(
"univ_%d", univIdx).
Data());
341 fUnivs[univIdx].first.SaveTo(ud->mkdir(
"shift"));
342 fUnivs[univIdx].second->SaveTo(ud->mkdir(
"pred"));
346 TH1F hSystNames(
"syst_names",
";Syst names",
fSysts.size(), 0,
fSysts.size());
349 hSystNames.GetXaxis()->SetBinLabel(binIdx++, it->ShortName().c_str());
351 hSystNames.Write(
"syst_names");
369 const int nbins = nom->GetNbinsX();
371 std::vector<TGraph*> curves(nbins);
372 for(
int bin = 0;
bin < nbins; ++
bin) curves[
bin] =
new TGraph;
374 for(
int i = 0; i <= 80; ++i){
375 const double x = .1*i-4;
380 const double ratio = h->GetBinContent(
bin+1)/nom->GetBinContent(
bin+1);
382 if(!std::isnan(ratio)) curves[
bin]->SetPoint(curves[
bin]->GetN(), x, ratio);
383 else curves[
bin]->SetPoint(curves[
bin]->GetN(), x, 1);
387 int nx = int(sqrt(nbins));
388 int ny = int(sqrt(nbins));
389 if(nx*ny < nbins) ++nx;
390 if(nx*ny < nbins) ++ny;
392 TCanvas* c =
new TCanvas;
398 TString::Format(
"%s %g < %s < %g;Shift;Ratio",
400 nom->GetXaxis()->GetBinLowEdge(
bin+1),
401 nom->GetXaxis()->GetTitle(),
402 nom->GetXaxis()->GetBinUpEdge(
bin+1)),
403 100, -4, +4, 100, .5, 1.5))->Draw();
404 curves[
bin]->Draw(
"l same");
412 const std::string& savePattern,
417 const bool save = !savePattern.empty();
418 const bool multiFile = savePattern.find(
"%s") != std::string::npos;
420 if(save && !multiFile){
422 gPad->Print((savePattern+
"[").c_str());
430 gPad->Print(TString::Format(savePattern.c_str(),
s->ShortName().c_str()).
Data());
433 gPad->Print(savePattern.c_str());
438 if(save && !multiFile){
439 gPad->Print((savePattern+
"]").c_str());
453 const int nbins = nom->GetNbinsX();
455 TH2* h2 =
new TH2F(
"", (syst->
LatexName()+
";;#sigma").c_str(),
456 nbins, nom->GetXaxis()->GetXmin(), nom->GetXaxis()->GetXmax(),
458 h2->GetXaxis()->SetTitle(nom->GetXaxis()->GetTitle());
460 for(
int i = 1; i <= 80; ++i){
461 const double y = h2->GetYaxis()->GetBinCenter(i);
466 const double ratio = h->GetBinContent(
bin+1)/nom->GetBinContent(
bin+1);
468 if(!isnan(ratio) && !isinf(ratio))
469 h2->Fill(h2->GetXaxis()->GetBinCenter(
bin),
y, ratio);
480 const std::string& savePattern,
485 const bool save = !savePattern.empty();
486 const bool multiFile = savePattern.find(
"%s") != std::string::npos;
488 if(save && !multiFile){
490 gPad->Print((savePattern+
"[").c_str());
499 gPad->Print(TString::Format(savePattern.c_str(),
s->ShortName().c_str()).
Data());
502 gPad->Print(savePattern.c_str());
507 if(save && !multiFile){
508 gPad->Print((savePattern+
"]").c_str());
515 TObjString* tag = (TObjString*)dir->Get(
"type");
517 assert(tag->GetString() ==
"PredictionLinFit");
521 std::vector<const ISyst*> systs;
522 TH1* hSystNames = (TH1*)dir->Get(
"syst_names");
524 for(
int systIdx = 0; systIdx < hSystNames->GetNbinsX(); ++systIdx){
529 std::vector<std::pair<SystShifts, const IPrediction*>> univs;
531 for(
int univIdx = 0; ; ++univIdx){
532 TDirectory* ud = dir->GetDirectory(TString::Format(
"univ_%d", univIdx).
Data());
535 univs.emplace_back(*ana::LoadFrom<SystShifts>(ud->GetDirectory(
"shift")),
540 return std::make_unique<PredictionLinFit>(systs, nom.release(), univs);
Spectrum PredictComponentSyst(osc::IOscCalc *calc, const SystShifts &syst, Flavors::Flavors_t flav, Current::Current_t curr, Sign::Sign_t sign) const override
TH1D * ToTH1(double exposure, Color_t col=kBlack, Style_t style=kSolid, EExposureType expotype=kPOT, EBinType bintype=kBinContent) const
Histogram made from this Spectrum, scaled to some exposure.
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
process_name opflash particleana ie x
virtual void SaveTo(TDirectory *dir) 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
const std::vector< const ISyst * > fSysts
Simple record of shifts applied to systematic parameters.
Collection of SpectrumLoaders for many configurations.
void AddRow(const std::vector< double > &row)
std::vector< double > GetCoords(const SystShifts &shift) const
std::vector< std::vector< double > > fCoeffs
virtual Spectrum PredictUnoscillated() const
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
process_name opflashCryoW ana
static SystShifts Nominal()
Spectrum PredictSyst(osc::IOscCalc *calc, const SystShifts &syst) const override
T sqr(T x)
More efficient square function than pow(x,2)
Encapsulate code to systematically shift a caf::StandardRecord.
virtual std::string ShortName() const final
The name printed out to the screen.
Spectrum Predict(osc::IOscCalc *calc) const override
Representation of a spectrum in any variable, with associated POT.
constexpr details::BinObj< T > bin(T value)
Returns a wrapper to print the specified data in binary format.
virtual Spectrum Predict(osc::IOscCalc *calc) const =0
std::vector< std::pair< SystShifts, const IPrediction * > > fUnivs
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
process_name opflash particleana ie ie y
PredictionLinFit(const std::vector< const ISyst * > &systs, const IPrediction *pnom, const std::vector< std::pair< SystShifts, const IPrediction * >> &univs)
Direct creation from an ensemble of universes.
Spectrum PredictComponent(osc::IOscCalc *calc, Flavors::Flavors_t flav, Current::Current_t curr, Sign::Sign_t sign) const override
static void Delete(TH1D *&h)
double GetShift(const ISyst *syst) const
Represent the ratio between two spectra.
std::vector< double > InitFitsBin(const std::vector< std::vector< double >> &M, const std::vector< double > &ds, const std::vector< std::vector< double >> &coords) const
Helper for InitFits()
static std::unique_ptr< PredictionLinFit > LoadFrom(TDirectory *dir)
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::vector< double > Solve(const std::vector< double > &b) const
static const ISyst * ShortNameToSyst(const std::string &s, bool allowFail=false)
std::unique_ptr< IPrediction > LoadFrom< IPrediction >(TDirectory *dir)
void SetProgress(double frac)
Update the progress fraction between zero and one.
virtual std::unique_ptr< IPrediction > Generate(Loaders &loaders, const SystShifts &shiftMC=kNoShift) const =0
then echo File list $list not found else cat $list while read file do echo $file sed s
process_name largeant stream1 can override from command line with o or output physics producers generator N
virtual Spectrum PredictComponent(osc::IOscCalc *calc, Flavors::Flavors_t flav, Current::Current_t curr, Sign::Sign_t sign) const =0
A simple ascii-art progress bar.
Standard interface to all prediction techniques.
virtual std::string LatexName() const final
The name used on plots (ROOT's TLatex syntax)
Given loaders and an MC shift, Generate() generates an IPrediction.
Prevent histograms being added to the current directory.
void SaveTo(TDirectory *dir) const override
Ratio GetRatio(const SystShifts &shift) const
std::string UniqueName()
Return a different string each time, for creating histograms.