13 int FileROOTVersion = file->GetVersion();
14 int MainFileROOTVersion = FileROOTVersion;
18 while (MainFileROOTVersion >= 10)
19 MainFileROOTVersion /= 10;
21 std::string SystemROOTVersion = std::string(ROOT_RELEASE);
22 int MainSystemROOTVersion = SystemROOTVersion.at(0) -
'0';
24 if(MainFileROOTVersion != MainSystemROOTVersion)
26 MACH3LOG_ERROR(
"File was produced with: {} ROOT version", FileROOTVersion);
27 MACH3LOG_ERROR(
"Found: {} ROOT version in the system", SystemROOTVersion);
39 for(
int iOverflow = -1; iOverflow > -10; iOverflow--)
41 overflow += poly->GetBinContent(iOverflow);
53 for(
int i = 1; i < poly->GetNumberOfBins()+1; i++)
55 integral += poly->GetBinContent(i);
63TH1D*
PolyProjectionX(TObject* poly, std::string TempName,
const std::vector<double>& xbins,
const bool computeErrors) {
65 TH1D* hProjX =
new TH1D((TempName+
"_x").c_str(),(TempName+
"_x").c_str(),
int(xbins.size()-1), &xbins[0]);
68 std::vector<double> hProjX_Error(hProjX->GetXaxis()->GetNbins() + 1, 0.0);
69 double xlow, xup, frac = 0.;
72 for (
int i = 0; i < static_cast<TH2Poly*>(poly)->GetNumberOfBins(); i++)
75 TH2PolyBin* bin =
static_cast<TH2PolyBin*
>(
static_cast<TH2Poly*
>(poly)->GetBins()->At(i));
76 xlow = bin->GetXMin();
80 for(
int dx = 0; dx < int(xbins.size()); dx++)
82 if(xbins[dx+1] <= xlow || xbins[dx] >= xup)
86 else if(xbins[dx] <= xlow && xbins[dx+1] >= xup)
90 else if(xbins[dx] <= xlow && xbins[dx+1] <= xup)
92 frac = (xbins[dx+1]-xlow)/(xup-xlow);
94 else if(xbins[dx] >= xlow && xbins[dx+1] >= xup)
96 frac = (xup-xbins[dx])/(xup-xlow);
98 else if(xbins[dx] >= xlow && xbins[dx+1] <= xup)
100 frac = (xbins[dx+1]-xbins[dx])/(xup-xlow);
106 hProjX->SetBinContent(dx+1,hProjX->GetBinContent(dx+1)+frac*bin->GetContent());
112 const double Temp_Err = frac*
static_cast<TH2Poly*
>(poly)->GetBinError(i+1)*frac*
static_cast<TH2Poly*
>(poly)->GetBinError(i+1);
113 hProjX_Error[dx+1] += Temp_Err;
120 for (
int i = 1; i <= hProjX->GetXaxis()->GetNbins(); ++i)
122 const double Error = std::sqrt(hProjX_Error[i]);
123 hProjX->SetBinError(i, Error);
131TH1D*
PolyProjectionY(TObject* poly, std::string TempName,
const std::vector<double>& ybins,
const bool computeErrors) {
133 TH1D* hProjY =
new TH1D((TempName+
"_y").c_str(),(TempName+
"_y").c_str(),
int(ybins.size()-1),&ybins[0]);
135 std::vector<double> hProjY_Error(hProjY->GetXaxis()->GetNbins() + 1, 0.0);
136 double ylow, yup, frac = 0.;
139 for (
int i = 0; i < static_cast<TH2Poly*>(poly)->GetNumberOfBins(); i++)
142 TH2PolyBin* bin =
static_cast<TH2PolyBin*
>(
static_cast<TH2Poly*
>(poly)->GetBins()->At(i));
143 ylow = bin->GetYMin();
144 yup = bin->GetYMax();
147 for(
int dy = 0; dy < int(ybins.size()); dy++)
149 if(ybins[dy+1]<=ylow || ybins[dy] >= yup)
153 else if(ybins[dy] <= ylow && ybins[dy+1] >= yup)
157 else if(ybins[dy] <= ylow && ybins[dy+1] <= yup)
159 frac = (ybins[dy+1]-ylow)/(yup-ylow);
161 else if(ybins[dy] >= ylow && ybins[dy+1] >= yup)
163 frac = (yup-ybins[dy])/(yup-ylow);
165 else if(ybins[dy] >= ylow && ybins[dy+1] <= yup)
167 frac = (ybins[dy+1]-ybins[dy])/(yup-ylow);
173 hProjY->SetBinContent(dy+1,hProjY->GetBinContent(dy+1)+frac*bin->GetContent());
179 const double Temp_Err = frac*
static_cast<TH2Poly*
>(poly)->GetBinError(i+1)*frac*
static_cast<TH2Poly*
>(poly)->GetBinError(i+1);
180 hProjY_Error[dy+1] += Temp_Err;
187 for (
int i = 1; i <= hProjY->GetXaxis()->GetNbins(); ++i)
189 const double Error = std::sqrt(hProjY_Error[i]);
190 hProjY->SetBinError(i, Error);
200 TH2Poly* HistCopy =
static_cast<TH2Poly*
>(Histogram->Clone());
203 std::string title = std::string(HistCopy->GetName())+
"_norm";
204 HistCopy->SetNameTitle(title.c_str(), title.c_str());
214 for(
int j = 1; j < Histogram->GetNumberOfBins()+1; j++)
216 Histogram->SetBinContent(j, Histogram->GetBinContent(j)/Integral);
222template<
class HistType>
223HistType*
RatioHists(HistType *NumHist, HistType *DenomHist) {
225 HistType *NumCopy =
static_cast<HistType*
>(NumHist->Clone());
226 std::string title = std::string(DenomHist->GetName()) +
"_ratio";
227 NumCopy->SetNameTitle(title.c_str(), title.c_str());
228 NumCopy->Divide(DenomHist);
237 TH2Poly *NumCopy =
static_cast<TH2Poly*
>(NumHist->Clone());
238 std::string title = std::string(DenomHist->GetName()) +
"_ratio";
239 NumCopy->SetNameTitle(title.c_str(), title.c_str());
241 for(
int i = 1; i < NumCopy->GetNumberOfBins()+1; ++i) {
242 NumCopy->SetBinContent(i,NumHist->GetBinContent(i)/DenomHist->GetBinContent(i));
250 double xlow, xup, ylow, yup;
251 std::string HistTempName = poly->GetName();
255 TH2D *hist =
static_cast<TH2D*
>(h2dhist->Clone());
256 hist->SetNameTitle(HistTempName.c_str(), HistTempName.c_str());
258 for(
int ix = 0; ix < hist->GetNbinsX() + 2; ix++) {
259 for(
int iy = 0; iy < hist->GetNbinsY() + 2; iy++) {
260 hist->SetBinContent(ix, iy, 0);
264 for(
int i = 0; i< poly->GetNumberOfBins(); i++){
265 TH2PolyBin & polybin =
static_cast<TH2PolyBin &
>(*poly->GetBins()->At(i));
266 xlow = polybin.GetXMin();
267 xup = polybin.GetXMax();
268 ylow = polybin.GetYMin();
269 yup = polybin.GetYMax();
272 xbin = hist->GetXaxis()->FindBin(xlow+(xup-xlow)/2);
273 ybin = hist->GetYaxis()->FindBin(ylow+(yup-ylow)/2);
275 MACH3LOG_TRACE(
"Poly bin {}, xlow: {}, xup: {}, ylow: {}, yup: {}. Finding bin for ({}, {}). Found Bin ({}, {}) with content {}. But Poly content: {}",
276 i, xlow, xup, ylow, yup, (xlow + (xup - xlow) / 2), (ylow + (yup - ylow) / 2), xbin, ybin, polybin.GetContent(), poly->GetBinContent(i));
277 hist->SetBinContent(xbin, ybin, polybin.GetContent());
285 TAxis* xaxis = hist->GetXaxis();
287 TAxis* yaxis = hist->GetYaxis();
289 TString histname = hist->GetName();
291 TH2Poly* poly =
new TH2Poly();
292 poly->SetName(histname);
293 poly->SetTitle(histname);
296 poly->GetXaxis()->SetTitle(xaxis->GetTitle());
297 poly->GetYaxis()->SetTitle(yaxis->GetTitle());
299 double xmax, xmin, ymax, ymin;
300 for (
int iy = 1; iy <= yaxis->GetNbins(); iy++) {
301 ymax = yaxis->GetBinUpEdge(iy);
302 ymin = yaxis->GetBinLowEdge(iy);
303 for (
int ix = 1; ix <= xaxis->GetNbins(); ix++) {
304 xmax = xaxis->GetBinUpEdge(ix);
305 xmin = xaxis->GetBinLowEdge(ix);
306 double binofx[] = {xmin, xmax, xmax, xmin};
307 double binofy[] = {ymin, ymin, ymax, ymax};
308 poly->AddBin(4, binofx, binofy);
312 for (
int iy = 1; iy <= yaxis->GetNbins(); iy++) {
313 ymax = yaxis->GetBinUpEdge(iy);
314 ymin = yaxis->GetBinLowEdge(iy);
315 for (
int ix = 1; ix <= xaxis->GetNbins(); ix++) {
316 xmax = xaxis->GetBinUpEdge(ix);
317 xmin = xaxis->GetBinLowEdge(ix);
320 int bin = hist->GetBin(ix, iy);
321 double content = hist->GetBinContent(bin);
322 poly->SetBinContent(poly->FindBin((xmin + xmax) / 2, (ymin + ymax) / 2), content);
333 TH2Poly* HistCopy =
static_cast<TH2Poly*
>(Histogram->Clone());
334 double xlow, xup, ylow, yup, area;
336 for(
int i = 1; i < HistCopy->GetNumberOfBins()+1; i++)
338 TH2PolyBin* bin =
static_cast<TH2PolyBin*
>(Histogram->GetBins()->At(i - 1));
339 xlow = bin->GetXMin();
340 xup = bin->GetXMax();
341 ylow = bin->GetYMin();
342 yup = bin->GetYMax();
343 area = (xup-xlow)*(yup-ylow);
344 HistCopy->SetBinContent(i, Histogram->GetBinContent(i)/(area*scale));
354 double xlow, xup, ylow, yup, area;
356 for(
int i = 1; i < Histogram->GetNumberOfBins()+1; i++)
358 TH2PolyBin* bin =
static_cast<TH2PolyBin*
>(Histogram->GetBins()->At(i - 1));
359 xlow = bin->GetXMin();
360 xup = bin->GetXMax();
361 ylow = bin->GetYMin();
362 yup = bin->GetYMax();
363 area = (xup-xlow)*(yup-ylow);
364 integral += Histogram->GetBinContent(i)*area;
370TH2Poly*
MakePolyHist(
const std::string& name,
const std::vector<double>& BinArray_x,
const std::vector<double>& BinArray_y) {
372 TH2Poly* poly =
new TH2Poly();
373 poly->SetName(name.c_str());
374 poly->SetTitle(name.c_str());
375 double xmax, xmin, ymax, ymin;
376 for(
unsigned int iy = 0; iy < BinArray_y.size()-1; iy++)
378 ymax = BinArray_y[iy+1];
379 ymin = BinArray_y[iy];
380 for(
unsigned int ix = 0; ix < BinArray_x.size()-1; ix++)
382 xmax = BinArray_x[ix+1];
383 xmin = BinArray_x[ix];
384 double binofx[] = {xmin, xmax, xmax, xmin};
385 double binofy[] = {ymin, ymin, ymax, ymax};
386 poly->AddBin(4,binofx,binofy);
396 TList *listOfFunctions = hist->GetListOfFunctions();
397 TF1 *fitter =
dynamic_cast<TF1*
>(listOfFunctions->FindObject(name.c_str()));
399 listOfFunctions->Remove(fitter);
408 FluctHist->Reset(
"");
409 FluctHist->Fill(0.0, 0.0);
411 for (
int i = 1; i <= PolyHist->GetXaxis()->GetNbins(); ++i)
414 const double MeanContent = PolyHist->GetBinContent(i);
416 const double Random = rand->PoissonD(MeanContent);
418 FluctHist->SetBinContent(i,Random);
427 FluctHist->Reset(
"");
428 FluctHist->Fill(0.0, 0.0, 0.0);
430 for (
int i = 1; i < FluctHist->GetNumberOfBins()+1; ++i)
433 const double MeanContent = PolyHist->GetBinContent(i);
435 const double Random = rand->PoissonD(MeanContent);
437 FluctHist->SetBinContent(i,Random);
446 FluctHist->Reset(
"");
447 FluctHist->Fill(0.0, 0.0);
449 const double evrate = PolyHist->Integral();
450 #pragma GCC diagnostic push
451 #pragma GCC diagnostic ignored "-Wconversion"
452 const int num = rand->Poisson(evrate);
453 #pragma GCC diagnostic pop
457 const double candidate = PolyHist->GetRandom();
458 FluctHist->Fill(candidate);
468 const int nbins = PolyHist->GetNumberOfBins();
469 const double r1 = rand->Rndm();
471 double* fIntegral =
new double[nbins+2];
475 for (
int i = 1; i < nbins+1; ++i)
478 const double content = PolyHist->GetBinContent(i);
479 fIntegral[i] += fIntegral[i - 1] + content;
481 for (Int_t bin = 1; bin < nbins+1; ++bin) fIntegral[bin] /= fIntegral[nbins];
482 fIntegral[nbins+1] = PolyHist->GetEntries();
485 int iBin = int(TMath::BinarySearch(nbins, fIntegral, r1));
498 FluctHist->Reset(
"");
499 FluctHist->Fill(0.0, 0.0, 0.0);
502 #pragma GCC diagnostic push
503 #pragma GCC diagnostic ignored "-Wconversion"
504 const int num = rand->Poisson(evrate);
505 #pragma GCC diagnostic pop
510 FluctHist->SetBinContent(iBin, FluctHist->GetBinContent(iBin) + 1);
516std::unique_ptr<TGraphAsymmErrors>
MakeAsymGraph(TH1* sigmaArrayLeft, TH1* sigmaArrayCentr, TH1* sigmaArrayRight,
const std::string& title) {
518 auto var = std::make_unique<TGraphAsymmErrors>(sigmaArrayCentr);
519 var->SetNameTitle((title).c_str(), (title).c_str());
523 var->GetXaxis()->SetTitle(sigmaArrayCentr->GetXaxis()->GetTitle());
524 var->GetYaxis()->SetTitle(
"Number of events/bin");
526 for (
int m = 0; m < var->GetN(); ++m)
528 double xlow = sigmaArrayLeft->GetBinContent(m+1);
529 double xhigh = sigmaArrayRight->GetBinContent(m+1);
540 var->SetPointEYhigh(m, xhigh - var->GetY()[m]);
541 var->SetPointEYlow(m, var->GetY()[m] - xlow);
550 for (
int x = 0; x < violin->GetXaxis()->GetNbins(); ++x)
552 const int y = violin->GetYaxis()->FindBin(hist_1d->GetBinContent(x+1));
553 violin->SetBinContent(x+1, y, violin->GetBinContent(x+1, y)+1);
562 constexpr double refractiveIndex = 1.334;
564 double momentumThreshold = mass/sqrt(refractiveIndex*refractiveIndex-1.);
565 return momentumThreshold;
570double CalculateQ2(
double PLep,
double PUpd,
double EnuTrue,
double InitialQ2){
572 constexpr double MLep = 0.10565837;
575 double ELep = sqrt((MLep*MLep)+(PLep*PLep));
577 double CosTh = (2*EnuTrue*ELep - MLep*MLep - InitialQ2)/(2*EnuTrue*PLep);
579 ELep = sqrt((MLep*MLep)+(PUpd*PUpd));
582 double Q2Upd = -(MLep*MLep) + 2.0*EnuTrue*(ELep - PUpd*CosTh);
584 return Q2Upd - InitialQ2;
589double CalculateEnu(
double PLep,
double costh,
double Eb,
bool neutrino){
591 double mNeff = 0.93956536 - Eb / 1000.;
592 double mNoth = 0.93827203;
595 mNeff = 0.93827203 - Eb / 1000.;
599 constexpr double mLep = 0.10565837;
600 double eLep = sqrt(PLep * PLep + mLep * mLep);
602 double Enu = (2 * mNeff * eLep - mLep * mLep + mNoth * mNoth - mNeff * mNeff) /(2 * (mNeff - eLep + PLep * costh));
610TFile*
Open(
const std::string& Name,
const std::string& Type,
const std::string& File,
const int Line) {
612 TFile* OutFile =
new TFile(Name.c_str(), Type.c_str());
615 if (OutFile->IsZombie()) {
617 if (Type ==
"RECREATE") {
#define _MaCh3_Safe_Include_Start_
KS: Avoiding warning checking for headers.
#define _MaCh3_Safe_Include_End_
KS: Restore warning checking after including external headers.
TH2D * ConvertTH2PolyToTH2D(TH2Poly *poly, TH2D *h2dhist)
KS: Convert TH2D to TH2Poly.
TH1D * PolyProjectionX(TObject *poly, std::string TempName, const std::vector< double > &xbins, const bool computeErrors)
WP: Poly Projectors.
void MakeFluctuatedHistogramAlternative(TH1D *FluctHist, TH1D *PolyHist, TRandom3 *rand)
Make Poisson fluctuation of TH1D hist using slow method which is only for cross-check.
TH2Poly * ConvertTH2DtoTH2Poly(TH2D *hist)
KS: Convert TH2Poly to TH2D.
void NormaliseTH2Poly(TH2Poly *Histogram)
Helper to Normalise histograms.
double OverflowIntegral(TH2Poly *poly)
WP: Helper function for calculating unbinned Integral of TH2Poly i.e including overflow.
void MakeFluctuatedHistogramStandard(TH1D *FluctHist, TH1D *PolyHist, TRandom3 *rand)
Make Poisson fluctuation of TH1D hist using default fast method.
int GetRandomPoly2(const TH2Poly *PolyHist, TRandom3 *rand)
KS: ROOT developers were too lazy do develop getRanom2 for TH2Poly, this implementation is based on l...
void FastViolinFill(TH2D *violin, TH1D *hist_1d)
KS: Fill Violin histogram with entry from a toy.
TH2Poly * PolyScaleWidth(TH2Poly *Histogram, double scale)
WP: Helper to scale th2poly analogous to th2d scale with option "width".
double returnCherenkovThresholdMomentum(int PDG)
DB Get the Cherenkov momentum threshold in MeV.
std::unique_ptr< TGraphAsymmErrors > MakeAsymGraph(TH1 *sigmaArrayLeft, TH1 *sigmaArrayCentr, TH1 *sigmaArrayRight, const std::string &title)
Used by sigma variation, check how 1 sigma changes spectra.
HistType * RatioHists(HistType *NumHist, HistType *DenomHist)
Helper to make ratio histograms.
void RemoveFitter(TH1D *hist, const std::string &name)
KS: Remove fitted TF1 from hist to make comparison easier.
double CalculateEnu(double PLep, double costh, double Eb, bool neutrino)
Recalculate Enu after Eb shift. Takes in shifted lepton momentum, lepton angle, and binding energy ch...
double PolyIntegralWidth(TH2Poly *Histogram)
WP: Helper to calc integral of th2poly analogous to th2d integra; with option "width".
TH2Poly * MakePolyHist(const std::string &name, const std::vector< double > &BinArray_x, const std::vector< double > &BinArray_y)
WP: Helper function to create TH2Poly histogram with uniform binning.
TH1D * PolyProjectionY(TObject *poly, std::string TempName, const std::vector< double > &ybins, const bool computeErrors)
WP: Poly Projectors.
_MaCh3_Safe_Include_Start_ _MaCh3_Safe_Include_End_ void CheckTH2PolyFileVersion(TFile *file)
KS: ROOT changes something with binning when moving from ROOT 5 to ROOT 6. If you open ROOT5 produced...
double NoOverflowIntegral(TH2Poly *poly)
WP: Helper function for calculating binned Integral of TH2Poly i.e not including overflow.
TH2Poly * RatioPolys(TH2Poly *NumHist, TH2Poly *DenomHist)
Helper to make ratio of TH2Polys.
TH2Poly * NormalisePoly(TH2Poly *Histogram)
WP: Helper to Normalise histograms.
double CalculateQ2(double PLep, double PUpd, double EnuTrue, double InitialQ2)
Recalculate Q^2 after Eb shift. Takes in shifted lepton momentum, lepton angle, and true neutrino ene...
Custom exception class for MaCh3 errors.
TFile * Open(const std::string &Name, const std::string &Type, const std::string &File, const int Line)
Opens a ROOT file with the given name and mode.
double GetMassFromPDG(const int PDG)
Return mass for given PDG.