12 #include "TFeldmanCousins.h"
14 #include "TGraphAsymmErrors.h"
41 hData->SetMarkerStyle(kFullCircle);
44 if(hMC->GetMaximum() > hData->GetMaximum()+sqrt(hData->GetMaximum())){
47 hData->Draw(
"ep same");
52 hMC->Draw(
"hist same");
53 hData->Draw(
"ep same");
71 hData->SetMarkerStyle(kFullCircle);
73 hMC->Scale(hData->Integral()/hMC->Integral());
76 if(hMC->GetMaximum() > hData->GetMaximum()+sqrt(hData->GetMaximum())){
79 hData->Draw(
"ep same");
84 hMC->Draw(
"hist same");
85 hData->Draw(
"ep same");
121 TH1* hData = data.
ToTH1(data.
POT());
122 hData->SetMarkerStyle(kFullCircle);
125 if(hMC->GetMaximum() > hData->GetMaximum()+sqrt(hData->GetMaximum())){
128 hData->Draw(
"ep same");
133 hMC->Draw(
"hist same");
134 hData->Draw(
"ep same");
137 hNC->Draw(
"hist same");
138 hCC->Draw(
"hist same");
139 hBeam->Draw(
"hist same");
149 std::string hist_name,
154 hTotal->SetNameTitle((hist_name+
"_total").c_str(), (hist_name+
"_total").c_str());
160 std::string hist_name,
169 std::string hist_name,
179 std::string hist_name,
183 std::vector<TH1*> ret;
186 hTotal->SetNameTitle((hist_name+
"_total").c_str(), (hist_name+
"_total").c_str());
187 ret .push_back(hTotal);
193 hNC->SetNameTitle((hist_name+
"_NC").c_str(), (hist_name+
"_NC").c_str());
200 hAllNumu->SetNameTitle((hist_name+
"_AllNumu").c_str(), (hist_name+
"_AllNumu").c_str());
201 ret .push_back(hAllNumu);
207 hNumu->SetNameTitle((hist_name+
"_Numu").c_str(), (hist_name+
"_Numu").c_str());
208 ret .push_back(hNumu);
214 hNumubar->SetNameTitle((hist_name+
"_Numubar").c_str(), (hist_name+
"_Numubar").c_str());
215 ret .push_back(hNumubar);
221 hAllNutau->SetNameTitle((hist_name+
"_AllNutau").c_str(), (hist_name+
"_AllNutau").c_str());
222 ret .push_back(hAllNutau);
229 hAllNue->SetNameTitle((hist_name+
"_AllNue").c_str(), (hist_name+
"_AllNue").c_str());
230 ret .push_back(hAllNue);
236 hAllBeamNue->SetNameTitle((hist_name+
"_AllBeamNue").c_str(), (hist_name+
"_AllBeamNue").c_str());
237 ret .push_back(hAllBeamNue);
243 hBeamNue->SetNameTitle((hist_name+
"_BeamNue").c_str(), (hist_name+
"_BeamNue").c_str());
244 ret .push_back(hBeamNue);
250 hBeamNuebar->SetNameTitle((hist_name+
"_BeamNuebar").c_str(), (hist_name+
"_BeamNuebar").c_str());
251 ret .push_back(hBeamNuebar);
257 hAllSignalNue->SetNameTitle((hist_name+
"_AllSignalNue").c_str(), (hist_name+
"_AllSignalNue").c_str());
258 ret .push_back(hAllSignalNue);
264 hSignalNue->SetNameTitle((hist_name+
"_SignalNue").c_str(), (hist_name+
"_SignalNue").c_str());
265 ret .push_back(hSignalNue);
271 hSignalNuebar->SetNameTitle((hist_name+
"_SignalNuebar").c_str(), (hist_name+
"_SignalNuebar").c_str());
272 ret .push_back(hSignalNuebar);
281 std::string hist_base_name,
285 std::vector<TH1*> ret;
286 std::string syst_name = syst->
ShortName();
287 for (
int i = -3; i < 4; ++i){
290 hTotal->SetNameTitle((hist_base_name+
"_total_"+syst_name+
"_"+
std::to_string(i)).c_str(),
291 (hist_base_name+
"_total_"+syst_name+
"_"+
std::to_string(i)).c_str());
292 ret .push_back(hTotal);
302 double miny,
double maxy)
310 double miny,
double maxy)
312 Ratio ratio(data, mc);
314 h->GetYaxis()->SetTitle(
"Data / MC");
315 h->GetYaxis()->SetRangeUser(miny, maxy);
318 TLine*
one =
new TLine(h->GetXaxis()->GetXmin(), 1,
319 h->GetXaxis()->GetXmax(), 1);
320 one->SetLineWidth(2);
321 one->SetLineStyle(7);
331 double miny,
double maxy)
339 double miny,
double maxy)
351 double miny,
double maxy)
353 Ratio fitRatio(fit, expected);
354 Ratio dataRatio(data, expected);
356 TH1*
h = fitRatio.
ToTH1();
357 h->GetYaxis()->SetTitle(
"Ratio to expectation");
358 h->GetYaxis()->SetRangeUser(miny, maxy);
362 h = dataRatio.
ToTH1();
363 h->SetMarkerStyle(kFullCircle);
366 TLine*
one =
new TLine(h->GetXaxis()->GetXmin(), 1,
367 h->GetXaxis()->GetXmax(), 1);
368 one->SetLineWidth(2);
369 one->SetLineStyle(7);
378 const std::vector<const ISyst*>& systs,
381 int col,
int errCol,
float headroom,
387 std::vector<Spectrum> ups, dns;
389 for(
const ISyst* syst: systs){
405 const std::vector<Spectrum>& upShifts,
406 const std::vector<Spectrum>& downShifts,
407 double pot,
int col,
int errCol,
408 float headroom,
bool newaxis)
414 else if(errCol == -1) errCol = col-7;
416 TH1* nom = nominal.
ToTH1(pot);
418 std::vector<TH1*> ups, dns;
420 for(
const auto& upShift:upShifts) ups.push_back(upShift.ToTH1(pot));
421 for(
const auto& downShift:downShifts) dns.push_back(downShift.ToTH1(pot));
423 nom->SetLineColor(col);
424 nom->GetXaxis()->CenterTitle();
425 nom->GetYaxis()->CenterTitle();
426 if(newaxis) nom->Draw(
"hist ][");
428 double yMax = nom->GetBinContent(nom->GetMaximumBin());
430 TGraphAsymmErrors*
g =
new TGraphAsymmErrors;
432 for(
int binIdx = 0; binIdx < nom->GetNbinsX()+2; ++binIdx){
433 const double y = nom->GetBinContent(binIdx);
434 g->SetPoint(binIdx, nom->GetXaxis()->GetBinCenter(binIdx),
y);
436 const double w = nom->GetXaxis()->GetBinWidth(binIdx);
441 for(
unsigned int systIdx = 0; systIdx < ups.size(); ++systIdx){
442 double hi = ups[systIdx]->GetBinContent(binIdx)-
y;
443 double lo = y-dns[systIdx]->GetBinContent(binIdx);
445 if(lo <= 0 && hi <= 0) std::swap(lo, hi);
454 g->SetPointError(binIdx, w/2, w/2, sqrt(errDn), sqrt(errUp));
457 g->SetFillColor(errCol);
459 g->GetYaxis()->SetRangeUser(0, headroom*yMax);
460 nom->GetYaxis()->SetRangeUser(0, headroom*yMax);
462 nom->Draw(
"hist ][ same");
464 for(TH1* up: ups)
delete up;
465 for(TH1* dn: dns)
delete dn;
472 THStack* ret =
new THStack;
474 TH1*
h = it.first.ToTH1(pot);
475 h->SetFillColor(it.second);
484 double x0,
double y0,
double x1,
double y1)
487 if(x > x0 && x < x1 && y > y0 && y < y1)
return 0;
496 if(x > x0 && x < x1){
501 if(y > y0 && y < y1){
515 dx *= (gPad->GetX2()-gPad->GetX1());
516 dy *= (gPad->GetY2()-gPad->GetY1());
519 const double x0 = gPad->GetUxmin();
520 const double x1 = gPad->GetUxmax();
521 const double y0 = gPad->GetUymin();
522 const double y1 = gPad->GetUymax();
524 const double X = x1-x0;
525 const double Y = y1-y0;
531 if(yPin >= 0) besty = yPin * (gPad->GetY2()-gPad->GetY1());
533 for(
bool fallback: {
false,
true}){
534 for(
double x = x0+dx/2;
x < x1-dx/2;
x += X/50){
535 for(
double y = y0+dy/2;
y < y1-dy/2;
y += Y/50){
543 if(d < bestd)
continue;
545 TIter next(gPad->GetListOfPrimitives());
546 while(TObject* obj = next()){
548 if(!obj->InheritsFrom(TH1::Class()))
continue;
549 if( obj->InheritsFrom(TH2::Class()))
continue;
553 for(
int n = 1;
n <= h->GetNbinsX(); ++
n){
554 const double px = h->GetBinCenter(
n);
555 const double py = h->GetBinContent(
n);
562 (
x-dx/2)/X, (
y-dy/2)/Y,
563 (
x+dx/2)/X, (
y+dy/2)/Y));
574 if (yPin < 0) besty =
y;
579 if(bestd != 0)
break;
583 const double nx = (bestx-gPad->GetX1())/(gPad->GetX2()-gPad->GetX1());
584 const double ny = (besty-gPad->GetY1())/(gPad->GetY2()-gPad->GetY1());
586 const double ndx = dx/(gPad->GetX2()-gPad->GetX1());
587 const double ndy = dy/(gPad->GetY2()-gPad->GetY1());
589 return new TLegend(nx-ndx/2, ny-ndy/2, nx+ndx/2, ny+ndy/2);
680 TGraphAsymmErrors* gr =
new TGraphAsymmErrors(h);
682 TFeldmanCousins fc(0.6827);
684 for(
int i = 0; i < h->GetNbinsX(); ++i){
686 gr->GetPoint(i, x, y);
688 if ( drawEmptyBins || y!=0 ){
689 if ( y < 50 ) gr->SetPointEYlow(i, y-fc.CalculateLowerLimit(y,0));
690 else gr->SetPointEYlow(i,sqrt(y));
691 if ( y < 30 ) gr->SetPointEYhigh(i,fc.CalculateUpperLimit(y,0)-
y);
692 else gr->SetPointEYhigh(i,sqrt(y));
696 gr->SetPointEXlow(i, 0);
697 gr->SetPointEXhigh(i, 0);
706 int n = hmin->GetNbinsX();
707 TGraph* gr =
new TGraph(4*n);
709 for(
int i=1; i<=
n; i++)
711 double xdown = hmax->GetBinLowEdge(i);
712 double xup = hmax->GetBinLowEdge(i+1);
713 double ydown = hmin->GetBinContent(i);
714 double yup = hmax->GetBinContent(i);
716 gr->SetPoint(2*(i-1), xdown, ydown);
717 gr->SetPoint(2*(i-1)+1, xup, ydown);
718 gr->SetPoint(4*n-2*i, xup, yup);
719 gr->SetPoint(4*n-2*i+1, xdown, yup);
722 gr->SetFillColor(hmin->GetLineColor() - 9);
723 gr->SetLineColor(hmin->GetLineColor() - 9);
729 const std::string & axisName,
730 const std::string & graphName,
731 const std::pair<double, double> & quantileDivisions)
733 if (hist->GetDimension() != 2)
734 throw std::runtime_error(Form(
"Can't profile a histogram with other than 2 dimensions. Yours is a %d-D histogram...", hist->GetDimension()));
736 const TAxis * axis =
nullptr;
737 std::function<TH1D*(const char *, Int_t, Int_t, Option_t*)> projectionMethod;
738 if (axisName ==
"x" || axisName ==
"X")
740 axis = hist->GetXaxis();
741 projectionMethod = std::bind(&
TH2::ProjectionY, hist, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
743 else if (axisName ==
"y" || axisName ==
"Y")
745 axis = hist->GetYaxis();
746 projectionMethod = std::bind(&
TH2::ProjectionX, hist, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4);
749 throw std::runtime_error( Form(
"Can't profile onto unknown axis: '%s'", axisName.c_str()) );
752 std::vector<double> points_x, points_y, errors_x_low, errors_x_high, errors_y_low, errors_y_high;
754 double quantiles[2] = {0, 0};
755 double _quantileDivisions[2] = {quantileDivisions.first, quantileDivisions.second};
756 for (
int binNum = 1; binNum <= axis->GetNbins(); binNum++)
758 std::unique_ptr<TH1D> proj ( projectionMethod(Form(
"%s_tmp_%d", hist->GetName(), int(std::time(
nullptr))), binNum, binNum,
"") );
760 double y = proj->GetMean();
761 points_x.push_back(axis->GetBinCenter(binNum));
762 points_y.push_back(y);
765 unsigned int n_qs = 0;
766 if (proj->Integral() == 0)
769 quantiles[0] = quantiles[1] = 0;
772 n_qs = proj->GetQuantiles(2, quantiles, _quantileDivisions);
774 throw std::runtime_error( Form(
"GetQuantiles() didn't compute all the quantiles in HistoTools.ProfileQuantile(). I requested 2 quantiles, but got %d of them...", n_qs) );
776 double binWidth = axis->GetBinWidth(binNum);
777 errors_x_low.push_back(binWidth/2.);
778 errors_x_high.push_back(binWidth/2.);
779 errors_y_low.push_back(y-quantiles[0]);
780 errors_y_high.push_back(quantiles[1]-y);
783 TGraphAsymmErrors * outGraph =
new TGraphAsymmErrors(
792 std::string
name = (graphName.size()) ? graphName : Form(
"%s_quantile_errors", hist->GetName());
793 outGraph->SetName(name.c_str());
THStack * ToTHStack(const std::vector< std::pair< Spectrum, Color_t >> &s, double pot)
Can call like ToTHStack({{h1, kRed}, {h2, kBlue}}, pot)
void DataMCRatio(const Spectrum &data, const IPrediction *mc, osc::IOscCalc *calc, double miny, double maxy)
Plot data/MC ratio for the given spectrum. Normalize MC to Data by POT.
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 SetShift(const ISyst *syst, double shift)
Shifts are 0=nominal, -1,+1 = 1 sigma shifts.
TH1D * ToTH1(Color_t col=kBlack, Style_t style=kSolid) const
process_name opflash particleana ie x
TH1 * DataMCComparison(const Spectrum &data, const Spectrum &mc)
void PlotWithSystErrorBand(IPrediction *pred, const std::vector< const ISyst * > &systs, osc::IOscCalc *calc, double pot, int col, int errCol, float headroom, bool newaxis)
Plot prediction with +/-1sigma error band.
Simple record of shifts applied to systematic parameters.
void OverridePOT(double newpot)
DO NOT USE UNLESS YOU ARE 110% CERTAIN THERE ISN'T A BETTER WAY!
virtual Spectrum PredictComponentSyst(osc::IOscCalc *calc, const SystShifts &syst, Flavors::Flavors_t flav, Current::Current_t curr, Sign::Sign_t sign) const
TGraphAsymmErrors * GraphWithPoissonErrors(const TH1 *h, bool noErrorsXaxis, bool drawEmptyBins)
Calculate statistical errors appropriate for small Poisson numbers.
process_name opflashCryoW ana
double Integral(double exposure, double *err=0, EExposureType expotype=kPOT) const
Return total number of events scaled to pot.
then echo echo For and will not be changed by echo further linking echo echo B echo The symbol is in the uninitialized data multiple common symbols may appear with the echo same name If the symbol is defined the common echo symbols are treated as undefined references For more echo details on common see the discussion of warn common echo in *Note Linker see the discussion of warn common echo in *Note Linker such as a global int variable echo as opposed to a large global array echo echo I echo The symbol is an indirect reference to another symbol This echo is a GNU extension to the a out object file format which is echo rarely used echo echo N echo The symbol is a debugging symbol echo echo R echo The symbol is in a read only data section echo echo S echo The symbol is in an uninitialized data section for small echo objects echo echo T echo The symbol is in the the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo W echo The symbol is a weak symbol that has not been specifically echo tagged as a weak object symbol When a weak defined symbol echo is linked with a normal defined the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo echo The symbol is a stabs symbol in an a out object file In echo this the next values printed are the stabs other echo the stabs desc and the stab type Stabs symbols are echo used to hold debugging information For more echo see *Note or object file format specific echo echo For Mac OS X
const Color_t kTotalMCErrorBandColor
T sqr(T x)
More efficient square function than pow(x,2)
Encapsulate code to systematically shift a caf::StandardRecord.
const Color_t kNumuBackgroundColor
virtual std::string ShortName() const final
The name printed out to the screen.
void ProjectionY(TH2D *from, TH1D *to)
Helper for WeightingVariable.
TGraphAsymmErrors * ProfileQuantile(const TH2 *hist, const std::string &axisName, const std::string &graphName, const std::pair< double, double > &quantileDivisions)
Calculate profile with error bars corresponding to specified quantiles of a 2D distribution (by defau...
Representation of a spectrum in any variable, with associated POT.
std::vector< TH1 * > GetMCTotalForSystShifts(const IPrediction *mc, osc::IOscCalc *calc, const ISyst *syst, std::string hist_base_name, double pot, bool force1D)
virtual Spectrum Predict(osc::IOscCalc *calc) const =0
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Charged-current interactions.
process_name opflash particleana ie ie y
void RatioPlot(const Spectrum &data, const Spectrum &expected, const Spectrum &fit, double miny, double maxy)
Plot data/expected, compared with fit/expected.
TH1 * DataMCComparisonAreaNormalized(const Spectrum &data, const Spectrum &mc)
const Color_t kBeamNueBackgroundColor
TGraph * ShadeBetweenHistograms(TH1 *hmin, TH1 *hmax)
TH1 * ToTHX(double exposure, bool force1D=false, EExposureType expotype=kPOT) const
Function decides what is the appropriate projection based on fBins, and does that.
TH1 * GetMCTotal(const IPrediction *mc, osc::IOscCalc *calc, std::string hist_name, double pot, bool force1D)
virtual Spectrum PredictSyst(osc::IOscCalc *calc, const SystShifts &syst) const
void ProjectionX(TH2D *from, TH1D *to)
Helper for Unweighted.
std::vector< TH1 * > GetMCSystComponents(const IPrediction *mc, osc::IOscCalc *calc, const SystShifts &shift, std::string hist_name, double pot, bool force1D)
Represent the ratio between two spectra.
const SystShifts kNoShift
double PointDistanceToBox(double x, double y, double x0, double y0, double x1, double y1)
Helper for AutoPlaceLegend.
then echo Cowardly refusing to create a new FHiCL file with the same name as the original one('${SourceName}')." >&2 exit 1 fi echo "'$
void DataMCAreaNormalizedRatio(const Spectrum &data, const IPrediction *mc, osc::IOscCalc *calc, double miny, double maxy)
Plot data/MC ratio for the given spectrum. Normalize MC to Data by area.
TH1 * DataMCComparisonComponents(const Spectrum &data, const IPrediction *mc, osc::IOscCalc *calc)
Plot MC broken down into flavour components, overlayed with data.
process_name physics producers generator physics producers generator physics producers generator py
std::string to_string(WindowPattern const &pattern)
then echo File list $list not found else cat $list while read file do echo $file sed s
std::vector< TH1 * > GetMCComponents(const IPrediction *mc, osc::IOscCalc *calc, std::string hist_name, double pot, bool force1D)
TH1 * GetMCSystTotal(const IPrediction *mc, osc::IOscCalc *calc, const SystShifts &shift, std::string hist_name, double pot, bool force1D)
Neutral-current interactions.
virtual Spectrum PredictComponent(osc::IOscCalc *calc, Flavors::Flavors_t flav, Current::Current_t curr, Sign::Sign_t sign) const =0
Both neutrinos and antineutrinos.
Standard interface to all prediction techniques.
TLegend * AutoPlaceLegend(double dx, double dy, double yPin)
Create a legend, maximizing distance from all histograms.
const Color_t kTotalMCColor
All neutrinos, any flavor.
const Color_t kNCBackgroundColor