MaCh3 2.2.1
Reference Guide
Loading...
Searching...
No Matches
Namespaces | Functions
HistogramUtils.h File Reference
#include "Samples/SampleStructs.h"
#include "Parameters/ParameterStructs.h"
#include "TGraphAsymmErrors.h"
#include "TObjString.h"
#include "TRandom3.h"
Include dependency graph for HistogramUtils.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Namespaces

namespace  M3
 

Functions

double OverflowIntegral (TH2Poly *poly)
 WP: Helper function for calculating unbinned Integral of TH2Poly i.e including overflow.
 
double NoOverflowIntegral (TH2Poly *poly)
 WP: Helper function for calculating binned Integral of TH2Poly i.e not including overflow.
 
TH1D * PolyProjectionX (TObject *poly, std::string TempName, const std::vector< double > &xbins, const bool computeErrors=false)
 WP: Poly Projectors.
 
TH1D * PolyProjectionY (TObject *poly, std::string TempName, const std::vector< double > &ybins, const bool computeErrors=false)
 WP: Poly Projectors.
 
TH2D * ConvertTH2PolyToTH2D (TH2Poly *poly, TH2D *TH2Dhist)
 KS: Convert TH2D to TH2Poly.
 
TH2Poly * ConvertTH2DtoTH2Poly (TH2D *TH2Dhist)
 KS: Convert TH2Poly to TH2D.
 
TH2Poly * NormalisePoly (TH2Poly *Histogram)
 WP: Helper to Normalise histograms.
 
void NormaliseTH2Poly (TH2Poly *Histogram)
 Helper to Normalise histograms.
 
TH2Poly * PolyScaleWidth (TH2Poly *Histogram, double scale)
 WP: Helper to scale th2poly analogous to th2d scale with option "width".
 
double PolyIntegralWidth (TH2Poly *Histogram)
 WP: Helper to calc integral of th2poly analogous to th2d integra; with option "width".
 
template<class HistType >
HistType * RatioHists (HistType *NumHist, HistType *DenomHist)
 Helper to make ratio histograms.
 
TH2Poly * RatioPolys (TH2Poly *NumPoly, TH2Poly *DenomPoly)
 Helper to make ratio of TH2Polys.
 
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.
 
void CheckTH2PolyFileVersion (TFile *file)
 KS: ROOT changes something with binning when moving from ROOT 5 to ROOT 6. If you open ROOT5 produced file with ROOT6 you will be missing 9 last bins.
 
void RemoveFitter (TH1D *hist, const std::string &name)
 KS: Remove fitted TF1 from hist to make comparison easier.
 
void MakeFluctuatedHistogramStandard (TH1D *FluctHist, TH1D *PolyHist, TRandom3 *rand)
 Make Poisson fluctuation of TH1D hist using default fast method.
 
void MakeFluctuatedHistogramAlternative (TH1D *FluctHist, TH1D *PolyHist, TRandom3 *rand)
 Make Poisson fluctuation of TH1D hist using slow method which is only for cross-check.
 
void MakeFluctuatedHistogramStandard (TH2Poly *FluctHist, TH2Poly *PolyHist, TRandom3 *rand)
 Make Poisson fluctuation of TH2Poly hist using default fast method.
 
void MakeFluctuatedHistogramAlternative (TH2Poly *FluctHist, TH2Poly *PolyHist, TRandom3 *rand)
 Make Poisson fluctuation of TH2Poly hist using slow method which is only for cross-check.
 
int GetRandomPoly2 (const TH2Poly *PolyHist, TRandom3 *rand)
 KS: ROOT developers were too lazy do develop getRanom2 for TH2Poly, this implementation is based on link
 
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.
 
void FastViolinFill (TH2D *violin, TH1D *hist_1d)
 KS: Fill Violin histogram with entry from a toy.
 
template<typename Derived , typename Base >
std::vector< Base * > CastVector (const std::vector< Derived * > &inputVec)
 Converts a vector of pointers from a derived type to a base type.
 
std::string file_exists (std::string filename)
 Helper to check if files exist or not.
 
double returnCherenkovThresholdMomentum (int PDG)
 DB Get the Cherenkov momentum threshold in MeV.
 
double CalculateQ2 (double PLep, double PUpd, double EnuTrue, double InitialQ2=0.0)
 Recalculate Q^2 after Eb shift. Takes in shifted lepton momentum, lepton angle, and true neutrino energy.
 
double CalculateEnu (double PLep, double cosTheta, double EB, bool neutrino)
 Recalculate Enu after Eb shift. Takes in shifted lepton momentum, lepton angle, and binding energy change, and if nu/anu.
 
template<typename ObjectType >
std::unique_ptr< ObjectType > M3::Clone (const ObjectType *obj, const std::string &name="")
 KS: Creates a copy of a ROOT-like object and wraps it in a smart pointer.
 
TFile * M3::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.
 

Detailed Description

Author
Will Parker
Kamil Skwarczynski

Definition in file HistogramUtils.h.

Function Documentation

◆ CalculateEnu()

double CalculateEnu ( double  PLep,
double  cosTheta,
double  EB,
bool  neutrino 
)

Recalculate Enu after Eb shift. Takes in shifted lepton momentum, lepton angle, and binding energy change, and if nu/anu.

Todo:
WARNING this is hardcoded

Definition at line 589 of file HistogramUtils.cpp.

589 {
590// ***************************************************************************
591 double mNeff = 0.93956536 - Eb / 1000.;
592 double mNoth = 0.93827203;
593
594 if (!neutrino) {
595 mNeff = 0.93827203 - Eb / 1000.;
596 mNoth = 0.93956536;
597 }
599 constexpr double mLep = 0.10565837;
600 double eLep = sqrt(PLep * PLep + mLep * mLep);
601
602 double Enu = (2 * mNeff * eLep - mLep * mLep + mNoth * mNoth - mNeff * mNeff) /(2 * (mNeff - eLep + PLep * costh));
603
604 return Enu;
605}

◆ CalculateQ2()

double CalculateQ2 ( double  PLep,
double  PUpd,
double  EnuTrue,
double  InitialQ2 = 0.0 
)

Recalculate Q^2 after Eb shift. Takes in shifted lepton momentum, lepton angle, and true neutrino energy.

Definition at line 570 of file HistogramUtils.cpp.

570 {
571// ***************************************************************************
572 constexpr double MLep = 0.10565837;
573
574 // Caluclate muon energy
575 double ELep = sqrt((MLep*MLep)+(PLep*PLep));
576
577 double CosTh = (2*EnuTrue*ELep - MLep*MLep - InitialQ2)/(2*EnuTrue*PLep);
578
579 ELep = sqrt((MLep*MLep)+(PUpd*PUpd));
580
581 // Calculate the new Q2
582 double Q2Upd = -(MLep*MLep) + 2.0*EnuTrue*(ELep - PUpd*CosTh);
583
584 return Q2Upd - InitialQ2;
585}

◆ CastVector()

template<typename Derived , typename Base >
std::vector< Base * > CastVector ( const std::vector< Derived * > &  inputVec)

Converts a vector of pointers from a derived type to a base type.

Template Parameters
DerivedThe derived class type.
BaseThe base class type.
Parameters
inputVecA std::vector of pointers to Derived objects.
Returns
A std::vector of pointers to Base objects.

Definition at line 99 of file HistogramUtils.h.

99 {
100 std::vector<Base*> outputVec;
101 // Reserve space for efficiency
102 outputVec.reserve(inputVec.size());
103 for (auto* ptr : inputVec) {
104 outputVec.push_back(static_cast<Base*>(ptr));
105 }
106 return outputVec;
107}

◆ CheckTH2PolyFileVersion()

void CheckTH2PolyFileVersion ( TFile *  file)

KS: ROOT changes something with binning when moving from ROOT 5 to ROOT 6. If you open ROOT5 produced file with ROOT6 you will be missing 9 last bins.

However if you use ROOT6 and have ROOT6 file exactly the same code will work. Something have changed with how TH2Poly bins are stored in TFile

Parameters
fileROOT file that we will make version checks

Definition at line 11 of file HistogramUtils.cpp.

11 {
12// **************************************************
13 int FileROOTVersion = file->GetVersion();
14 int MainFileROOTVersion = FileROOTVersion;
15
16 // Remove last digit from number
17 // till only one digit is left
18 while (MainFileROOTVersion >= 10)
19 MainFileROOTVersion /= 10;
20
21 std::string SystemROOTVersion = std::string(ROOT_RELEASE);
22 int MainSystemROOTVersion = SystemROOTVersion.at(0) - '0';
23
24 if(MainFileROOTVersion != MainSystemROOTVersion)
25 {
26 MACH3LOG_ERROR("File was produced with: {} ROOT version", FileROOTVersion);
27 MACH3LOG_ERROR("Found: {} ROOT version in the system", SystemROOTVersion);
28 MACH3LOG_ERROR("For some documentation please visit me");
29 throw MaCh3Exception(__FILE__, __LINE__);
30 }
31}
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:25
Custom exception class for MaCh3 errors.

◆ ConvertTH2DtoTH2Poly()

TH2Poly * ConvertTH2DtoTH2Poly ( TH2D *  TH2Dhist)

KS: Convert TH2Poly to TH2D.

Definition at line 282 of file HistogramUtils.cpp.

282 {
283// ****************
284 // Make the x axis from the momentum of lepton
285 TAxis* xaxis = hist->GetXaxis();
286 // Make the y axis from the cos theta of lepton
287 TAxis* yaxis = hist->GetYaxis();
288
289 TString histname = hist->GetName();
290 // Convert TH2D binning to TH2Poly
291 TH2Poly* poly = new TH2Poly();
292 poly->SetName(histname);
293 poly->SetTitle(histname);
294
295 // Copy axis titles
296 poly->GetXaxis()->SetTitle(xaxis->GetTitle());
297 poly->GetYaxis()->SetTitle(yaxis->GetTitle());
298
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);
309 }
310 }
311
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);
318
319 // Get the content of the corresponding bin in TH2D and set it in TH2Poly
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);
323 }
324 }
325
326 return poly;
327}

◆ ConvertTH2PolyToTH2D()

TH2D * ConvertTH2PolyToTH2D ( TH2Poly *  poly,
TH2D *  TH2Dhist 
)

KS: Convert TH2D to TH2Poly.

Definition at line 248 of file HistogramUtils.cpp.

248 {
249// ****************
250 double xlow, xup, ylow, yup;
251 std::string HistTempName = poly->GetName();
252
253 HistTempName += "_";
254 //make the th2d
255 TH2D *hist = static_cast<TH2D*>(h2dhist->Clone());
256 hist->SetNameTitle(HistTempName.c_str(), HistTempName.c_str());
257
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);
261 }
262 }
263 //Loop over poly bins, find the corresponding th2d and setbincontent!
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();
270 int xbin, ybin;
271
272 xbin = hist->GetXaxis()->FindBin(xlow+(xup-xlow)/2);
273 ybin = hist->GetYaxis()->FindBin(ylow+(yup-ylow)/2);
274
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());
278 }
279 return hist;
280}
#define MACH3LOG_TRACE
Definition: MaCh3Logger.h:21

◆ FastViolinFill()

void FastViolinFill ( TH2D *  violin,
TH1D *  hist_1d 
)

KS: Fill Violin histogram with entry from a toy.

Parameters
violinhist that will be filled
hist_1drefence hist from which we take entries to be filled

Definition at line 548 of file HistogramUtils.cpp.

548 {
549// ****************
550 for (int x = 0; x < violin->GetXaxis()->GetNbins(); ++x)
551 {
552 const int y = violin->GetYaxis()->FindBin(hist_1d->GetBinContent(x+1));
553 violin->SetBinContent(x+1, y, violin->GetBinContent(x+1, y)+1);
554 }
555}

◆ file_exists()

std::string file_exists ( std::string  filename)
inline

Helper to check if files exist or not.

Definition at line 110 of file HistogramUtils.h.

110 {
111 std::ifstream infile(filename.c_str());
112 if (!infile.good()) {
113 MACH3LOG_ERROR("*** ERROR ***");
114 MACH3LOG_ERROR("File {} does not exist", filename);
115 MACH3LOG_ERROR("Please try again");
116 MACH3LOG_ERROR("*************");
117 throw MaCh3Exception(__FILE__ , __LINE__ );
118 }
119 return filename;
120}

◆ GetRandomPoly2()

int GetRandomPoly2 ( const TH2Poly *  PolyHist,
TRandom3 *  rand 
)

KS: ROOT developers were too lazy do develop getRanom2 for TH2Poly, this implementation is based on link

Definition at line 466 of file HistogramUtils.cpp.

466 {
467// ****************
468 const int nbins = PolyHist->GetNumberOfBins();
469 const double r1 = rand->Rndm();
470
471 double* fIntegral = new double[nbins+2];
472 fIntegral[0] = 0.0;
473
474 //KS: This is custom version of ComputeIntegral, once again ROOT was lazy :(
475 for (int i = 1; i < nbins+1; ++i)
476 {
477 fIntegral[i] = 0.0;
478 const double content = PolyHist->GetBinContent(i);
479 fIntegral[i] += fIntegral[i - 1] + content;
480 }
481 for (Int_t bin = 1; bin < nbins+1; ++bin) fIntegral[bin] /= fIntegral[nbins];
482 fIntegral[nbins+1] = PolyHist->GetEntries();
483
484 //KS: We just return one rather then X and Y, this way we can use SetBinContent rather than Fill, which is faster
485 int iBin = int(TMath::BinarySearch(nbins, fIntegral, r1));
486 //KS: Have to increment because TH2Poly has stupid offset arghh
487 iBin += 1;
488
489 delete[] fIntegral;
490 return iBin;
491}

◆ MakeAsymGraph()

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.

Parameters
sigmaArrayLeftsigma var hist at -1 or -3 sigma shift
sigmaArrayCentrsigma var hist at prior values
sigmaArrayRightsigma var hist at +1 or +3 sigma shift
titleA tittle for returned object
Returns
A TGraphAsymmErrors object that visualizes the sigma variation of spectra, showing confidence intervals between different sigma shifts.

Definition at line 516 of file HistogramUtils.cpp.

516 {
517// *************************
518 auto var = std::make_unique<TGraphAsymmErrors>(sigmaArrayCentr);
519 var->SetNameTitle((title).c_str(), (title).c_str());
520
521 // Need to draw TGraphs to set axes labels
522 var->Draw("AP");
523 var->GetXaxis()->SetTitle(sigmaArrayCentr->GetXaxis()->GetTitle());
524 var->GetYaxis()->SetTitle("Number of events/bin");
525
526 for (int m = 0; m < var->GetN(); ++m)
527 {
528 double xlow = sigmaArrayLeft->GetBinContent(m+1);
529 double xhigh = sigmaArrayRight->GetBinContent(m+1);
530 double xtemp;
531
532 // Figure out which variation is larger so we set the error correctly
533 if (xlow > xhigh)
534 {
535 xtemp = xlow;
536 xlow = xhigh;
537 xhigh = xtemp;
538 }
539
540 var->SetPointEYhigh(m, xhigh - var->GetY()[m]);
541 var->SetPointEYlow(m, var->GetY()[m] - xlow);
542 }
543 return var;
544}

◆ MakeFluctuatedHistogramAlternative() [1/2]

void MakeFluctuatedHistogramAlternative ( TH1D *  FluctHist,
TH1D *  PolyHist,
TRandom3 *  rand 
)

Make Poisson fluctuation of TH1D hist using slow method which is only for cross-check.

Definition at line 443 of file HistogramUtils.cpp.

443 {
444// ****************
445 // Make the Poisson fluctuated hist
446 FluctHist->Reset("");
447 FluctHist->Fill(0.0, 0.0);
448
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
454 int count = 0;
455 while(count < num)
456 {
457 const double candidate = PolyHist->GetRandom();
458 FluctHist->Fill(candidate);
459 count++;
460 }
461}

◆ MakeFluctuatedHistogramAlternative() [2/2]

void MakeFluctuatedHistogramAlternative ( TH2Poly *  FluctHist,
TH2Poly *  PolyHist,
TRandom3 *  rand 
)

Make Poisson fluctuation of TH2Poly hist using slow method which is only for cross-check.

Definition at line 495 of file HistogramUtils.cpp.

495 {
496// ****************
497 // Make the Poisson fluctuated hist
498 FluctHist->Reset("");
499 FluctHist->Fill(0.0, 0.0, 0.0);
500
501 const double evrate = NoOverflowIntegral(PolyHist);
502 #pragma GCC diagnostic push
503 #pragma GCC diagnostic ignored "-Wconversion"
504 const int num = rand->Poisson(evrate);
505 #pragma GCC diagnostic pop
506 int count = 0;
507 while(count < num)
508 {
509 const int iBin = GetRandomPoly2(PolyHist, rand);
510 FluctHist->SetBinContent(iBin, FluctHist->GetBinContent(iBin) + 1);
511 count++;
512 }
513}
int GetRandomPoly2(const TH2Poly *PolyHist, TRandom3 *rand)
KS: ROOT developers were too lazy do develop getRanom2 for TH2Poly, this implementation is based on l...
double NoOverflowIntegral(TH2Poly *poly)
WP: Helper function for calculating binned Integral of TH2Poly i.e not including overflow.

◆ MakeFluctuatedHistogramStandard() [1/2]

void MakeFluctuatedHistogramStandard ( TH1D *  FluctHist,
TH1D *  PolyHist,
TRandom3 *  rand 
)

Make Poisson fluctuation of TH1D hist using default fast method.

Definition at line 405 of file HistogramUtils.cpp.

405 {
406// ****************
407 // Make the Poisson fluctuated hist
408 FluctHist->Reset("");
409 FluctHist->Fill(0.0, 0.0);
410
411 for (int i = 1; i <= PolyHist->GetXaxis()->GetNbins(); ++i)
412 {
413 // Get the posterior predictive bin content
414 const double MeanContent = PolyHist->GetBinContent(i);
415 // Get a Poisson fluctuation of the content
416 const double Random = rand->PoissonD(MeanContent);
417 // Set the fluctuated histogram content to the Poisson variation of the posterior predictive histogram
418 FluctHist->SetBinContent(i,Random);
419 }
420}

◆ MakeFluctuatedHistogramStandard() [2/2]

void MakeFluctuatedHistogramStandard ( TH2Poly *  FluctHist,
TH2Poly *  PolyHist,
TRandom3 *  rand 
)

Make Poisson fluctuation of TH2Poly hist using default fast method.

Definition at line 424 of file HistogramUtils.cpp.

424 {
425// ****************
426 // Make the Poisson fluctuated hist
427 FluctHist->Reset("");
428 FluctHist->Fill(0.0, 0.0, 0.0);
429
430 for (int i = 1; i < FluctHist->GetNumberOfBins()+1; ++i)
431 {
432 // Get the posterior predictive bin content
433 const double MeanContent = PolyHist->GetBinContent(i);
434 // Get a Poisson fluctuation of the content
435 const double Random = rand->PoissonD(MeanContent);
436 // Set the fluctuated histogram content to the Poisson variation of the posterior predictive histogram
437 FluctHist->SetBinContent(i,Random);
438 }
439}

◆ MakePolyHist()

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.

Parameters
nameThis will be tittle of output histogram
BinArray_xBin edges for X axis
BinArray_yBin edges for Y axis

Definition at line 370 of file HistogramUtils.cpp.

370 {
371// *********************
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++)
377 {
378 ymax = BinArray_y[iy+1];
379 ymin = BinArray_y[iy];
380 for(unsigned int ix = 0; ix < BinArray_x.size()-1; ix++)
381 {
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);
387 }
388 }
389 return poly;
390}

◆ NoOverflowIntegral()

double NoOverflowIntegral ( TH2Poly *  poly)

WP: Helper function for calculating binned Integral of TH2Poly i.e not including overflow.

Definition at line 50 of file HistogramUtils.cpp.

50 {
51// **************************************************
52 double integral = 0.;
53 for(int i = 1; i < poly->GetNumberOfBins()+1; i++)
54 {
55 integral += poly->GetBinContent(i);
56 }
57
58 return integral;
59} // end function

◆ NormalisePoly()

TH2Poly * NormalisePoly ( TH2Poly *  Histogram)

WP: Helper to Normalise histograms.

Definition at line 198 of file HistogramUtils.cpp.

198 {
199// ****************
200 TH2Poly* HistCopy = static_cast<TH2Poly*>(Histogram->Clone());
201 double IntegralWidth = PolyIntegralWidth(HistCopy);
202 HistCopy = PolyScaleWidth(HistCopy, IntegralWidth);
203 std::string title = std::string(HistCopy->GetName())+"_norm";
204 HistCopy->SetNameTitle(title.c_str(), title.c_str());
205
206 return HistCopy;
207}
TH2Poly * PolyScaleWidth(TH2Poly *Histogram, double scale)
WP: Helper to scale th2poly analogous to th2d scale with option "width".
double PolyIntegralWidth(TH2Poly *Histogram)
WP: Helper to calc integral of th2poly analogous to th2d integra; with option "width".

◆ NormaliseTH2Poly()

void NormaliseTH2Poly ( TH2Poly *  Histogram)

Helper to Normalise histograms.

Parameters
Histogramhist which we normalise

Definition at line 211 of file HistogramUtils.cpp.

211 {
212// ****************
213 const double Integral = NoOverflowIntegral(Histogram);
214 for(int j = 1; j < Histogram->GetNumberOfBins()+1; j++)
215 {
216 Histogram->SetBinContent(j, Histogram->GetBinContent(j)/Integral);
217 }
218}

◆ OverflowIntegral()

double OverflowIntegral ( TH2Poly *  poly)

WP: Helper function for calculating unbinned Integral of TH2Poly i.e including overflow.

Definition at line 35 of file HistogramUtils.cpp.

35 {
36// **************************************************
37 double overflow = 0.;
38 //TH2Polys have 9 overflow bins
39 for(int iOverflow = -1; iOverflow > -10; iOverflow--)
40 {
41 overflow += poly->GetBinContent(iOverflow);
42 }
43 double IntegralUn = NoOverflowIntegral(poly) + overflow;
44
45 return IntegralUn;
46} // end function

◆ PolyIntegralWidth()

double PolyIntegralWidth ( TH2Poly *  Histogram)

WP: Helper to calc integral of th2poly analogous to th2d integra; with option "width".

Definition at line 351 of file HistogramUtils.cpp.

351 {
352// ****************
353 double integral = 0;
354 double xlow, xup, ylow, yup, area;
355
356 for(int i = 1; i < Histogram->GetNumberOfBins()+1; i++)
357 {
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;
365 }
366 return integral;
367}

◆ PolyProjectionX()

TH1D * PolyProjectionX ( TObject *  poly,
std::string  TempName,
const std::vector< double > &  xbins,
const bool  computeErrors = false 
)

WP: Poly Projectors.

Definition at line 63 of file HistogramUtils.cpp.

63 {
64// **************************************************
65 TH1D* hProjX = new TH1D((TempName+"_x").c_str(),(TempName+"_x").c_str(), int(xbins.size()-1), &xbins[0]);
66
67 //KS: Temp Histogram to store error, use double as this is thread safe
68 std::vector<double> hProjX_Error(hProjX->GetXaxis()->GetNbins() + 1, 0.0);
69 double xlow, xup, frac = 0.;
70
71 //loop over bins in the poly
72 for (int i = 0; i < static_cast<TH2Poly*>(poly)->GetNumberOfBins(); i++)
73 {
74 //get bin and its edges
75 TH2PolyBin* bin = static_cast<TH2PolyBin*>(static_cast<TH2Poly*>(poly)->GetBins()->At(i));
76 xlow = bin->GetXMin();
77 xup = bin->GetXMax();
78
79 //Loop over projected bins, find fraction of poly bin in each
80 for(int dx = 0; dx < int(xbins.size()); dx++)
81 {
82 if(xbins[dx+1] <= xlow || xbins[dx] >= xup)
83 {
84 frac = 0;
85 }
86 else if(xbins[dx] <= xlow && xbins[dx+1] >= xup)
87 {
88 frac = 1;
89 }
90 else if(xbins[dx] <= xlow && xbins[dx+1] <= xup)
91 {
92 frac = (xbins[dx+1]-xlow)/(xup-xlow);
93 }
94 else if(xbins[dx] >= xlow && xbins[dx+1] >= xup)
95 {
96 frac = (xup-xbins[dx])/(xup-xlow);
97 }
98 else if(xbins[dx] >= xlow && xbins[dx+1] <= xup)
99 {
100 frac = (xbins[dx+1]-xbins[dx])/(xup-xlow);
101 }
102 else
103 {
104 frac = 0;
105 }
106 hProjX->SetBinContent(dx+1,hProjX->GetBinContent(dx+1)+frac*bin->GetContent());
107 //KS: Follow ROOT implementation and sum up the variance
108 if(computeErrors)
109 {
110 //KS: TH2PolyBin doesn't have GetError so we have to use TH2Poly,
111 //but numbering of GetBinError is different than GetBins...
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;
114 }
115 }
116 }
117 //KS: The error is sqrt(summed variance)) https://root.cern.ch/doc/master/TH2_8cxx_source.html#l02266
118 if(computeErrors)
119 {
120 for (int i = 1; i <= hProjX->GetXaxis()->GetNbins(); ++i)
121 {
122 const double Error = std::sqrt(hProjX_Error[i]);
123 hProjX->SetBinError(i, Error);
124 }
125 }
126 return hProjX;
127} // end project poly X function

◆ PolyProjectionY()

TH1D * PolyProjectionY ( TObject *  poly,
std::string  TempName,
const std::vector< double > &  ybins,
const bool  computeErrors = false 
)

WP: Poly Projectors.

Definition at line 131 of file HistogramUtils.cpp.

131 {
132// **************************************************
133 TH1D* hProjY = new TH1D((TempName+"_y").c_str(),(TempName+"_y").c_str(),int(ybins.size()-1),&ybins[0]);
134 //KS: Temp Histogram to store error, use double as this is thread safe
135 std::vector<double> hProjY_Error(hProjY->GetXaxis()->GetNbins() + 1, 0.0);
136 double ylow, yup, frac = 0.;
137
138 //loop over bins in the poly
139 for (int i = 0; i < static_cast<TH2Poly*>(poly)->GetNumberOfBins(); i++)
140 {
141 //get bin and its edges
142 TH2PolyBin* bin = static_cast<TH2PolyBin*>(static_cast<TH2Poly*>(poly)->GetBins()->At(i));
143 ylow = bin->GetYMin();
144 yup = bin->GetYMax();
145
146 //Loop over projected bins, find fraction of poly bin in each
147 for(int dy = 0; dy < int(ybins.size()); dy++)
148 {
149 if(ybins[dy+1]<=ylow || ybins[dy] >= yup)
150 {
151 frac = 0;
152 }
153 else if(ybins[dy] <= ylow && ybins[dy+1] >= yup)
154 {
155 frac = 1;
156 }
157 else if(ybins[dy] <= ylow && ybins[dy+1] <= yup)
158 {
159 frac = (ybins[dy+1]-ylow)/(yup-ylow);
160 }
161 else if(ybins[dy] >= ylow && ybins[dy+1] >= yup)
162 {
163 frac = (yup-ybins[dy])/(yup-ylow);
164 }
165 else if(ybins[dy] >= ylow && ybins[dy+1] <= yup)
166 {
167 frac = (ybins[dy+1]-ybins[dy])/(yup-ylow);
168 }
169 else
170 {
171 frac = 0;
172 }
173 hProjY->SetBinContent(dy+1,hProjY->GetBinContent(dy+1)+frac*bin->GetContent());
174 //KS: Follow ROOT implementation and sum up the variance
175 if(computeErrors)
176 {
177 //KS: TH2PolyBin doesn't have GetError so we have to use TH2Poly,
178 //but numbering of GetBinError is different than GetBins...
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;
181 }
182 }
183 }
184 //KS: The error is sqrt(summed variance)) https://root.cern.ch/doc/master/TH2_8cxx_source.html#l02266
185 if(computeErrors)
186 {
187 for (int i = 1; i <= hProjY->GetXaxis()->GetNbins(); ++i)
188 {
189 const double Error = std::sqrt(hProjY_Error[i]);
190 hProjY->SetBinError(i, Error);
191 }
192 }
193 return hProjY;
194} // end project poly Y function

◆ PolyScaleWidth()

TH2Poly * PolyScaleWidth ( TH2Poly *  Histogram,
double  scale 
)

WP: Helper to scale th2poly analogous to th2d scale with option "width".

Definition at line 331 of file HistogramUtils.cpp.

331 {
332// ****************
333 TH2Poly* HistCopy = static_cast<TH2Poly*>(Histogram->Clone());
334 double xlow, xup, ylow, yup, area;
335
336 for(int i = 1; i < HistCopy->GetNumberOfBins()+1; i++)
337 {
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));
345 }
346 return HistCopy;
347}

◆ RatioHists()

template<class HistType >
HistType * RatioHists ( HistType *  NumHist,
HistType *  DenomHist 
)

Helper to make ratio histograms.

Definition at line 223 of file HistogramUtils.cpp.

223 {
224// ****************
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);
229
230 return NumCopy;
231}

◆ RatioPolys()

TH2Poly * RatioPolys ( TH2Poly *  NumPoly,
TH2Poly *  DenomPoly 
)

Helper to make ratio of TH2Polys.

Definition at line 235 of file HistogramUtils.cpp.

235 {
236// ****************
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());
240
241 for(int i = 1; i < NumCopy->GetNumberOfBins()+1; ++i) {
242 NumCopy->SetBinContent(i,NumHist->GetBinContent(i)/DenomHist->GetBinContent(i));
243 }
244 return NumCopy;
245}

◆ RemoveFitter()

void RemoveFitter ( TH1D *  hist,
const std::string &  name 
)

KS: Remove fitted TF1 from hist to make comparison easier.

Definition at line 394 of file HistogramUtils.cpp.

394 {
395// *********************
396 TList *listOfFunctions = hist->GetListOfFunctions();
397 TF1 *fitter = dynamic_cast<TF1*>(listOfFunctions->FindObject(name.c_str()));
398
399 listOfFunctions->Remove(fitter);
400 delete fitter;
401}

◆ returnCherenkovThresholdMomentum()

double returnCherenkovThresholdMomentum ( int  PDG)

DB Get the Cherenkov momentum threshold in MeV.

Definition at line 560 of file HistogramUtils.cpp.

560 {
561// ****************
562 constexpr double refractiveIndex = 1.334; //DB From https://github.com/fiTQun/fiTQun/blob/646cf9c8ba3d4f7400bcbbde029d5ca15513a3bf/fiTQun_shared.cc#L757
563 double mass = MaCh3Utils::GetMassFromPDG(PDG)*1e3;
564 double momentumThreshold = mass/sqrt(refractiveIndex*refractiveIndex-1.);
565 return momentumThreshold;
566}
double GetMassFromPDG(const int PDG)
Return mass for given PDG.