MaCh3  2.2.3
Reference Guide
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

 M3
 

Functions

double OverflowIntegral (TH2Poly *poly)
 WP: Helper function for calculating unbinned Integral of TH2Poly i.e including overflow. More...
 
double NoOverflowIntegral (TH2Poly *poly)
 WP: Helper function for calculating binned Integral of TH2Poly i.e not including overflow. More...
 
TH1D * PolyProjectionX (TObject *poly, std::string TempName, const std::vector< double > &xbins, const bool computeErrors=false)
 WP: Poly Projectors. More...
 
TH1D * PolyProjectionY (TObject *poly, std::string TempName, const std::vector< double > &ybins, const bool computeErrors=false)
 WP: Poly Projectors. More...
 
TH2D * ConvertTH2PolyToTH2D (TH2Poly *poly, TH2D *TH2Dhist)
 KS: Convert TH2D to TH2Poly. More...
 
TH2Poly * ConvertTH2DtoTH2Poly (TH2D *TH2Dhist)
 KS: Convert TH2Poly to TH2D. More...
 
TH2Poly * NormalisePoly (TH2Poly *Histogram)
 WP: Helper to Normalise histograms. More...
 
void NormaliseTH2Poly (TH2Poly *Histogram)
 Helper to Normalise histograms. More...
 
TH2Poly * PolyScaleWidth (TH2Poly *Histogram, double scale)
 WP: Helper to scale th2poly analogous to th2d scale with option "width". More...
 
double PolyIntegralWidth (TH2Poly *Histogram)
 WP: Helper to calc integral of th2poly analogous to th2d integra; with option "width". More...
 
template<class HistType >
HistType * RatioHists (HistType *NumHist, HistType *DenomHist)
 Helper to make ratio histograms. More...
 
TH2Poly * RatioPolys (TH2Poly *NumPoly, TH2Poly *DenomPoly)
 Helper to make ratio of TH2Polys. More...
 
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. More...
 
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. More...
 
void RemoveFitter (TH1D *hist, const std::string &name)
 KS: Remove fitted TF1 from hist to make comparison easier. More...
 
void MakeFluctuatedHistogramStandard (TH1D *FluctHist, TH1D *PolyHist, TRandom3 *rand)
 Make Poisson fluctuation of TH1D hist using default fast method. More...
 
void MakeFluctuatedHistogramAlternative (TH1D *FluctHist, TH1D *PolyHist, TRandom3 *rand)
 Make Poisson fluctuation of TH1D hist using slow method which is only for cross-check. More...
 
void MakeFluctuatedHistogramStandard (TH2Poly *FluctHist, TH2Poly *PolyHist, TRandom3 *rand)
 Make Poisson fluctuation of TH2Poly hist using default fast method. More...
 
void MakeFluctuatedHistogramAlternative (TH2Poly *FluctHist, TH2Poly *PolyHist, TRandom3 *rand)
 Make Poisson fluctuation of TH2Poly hist using slow method which is only for cross-check. More...
 
int GetRandomPoly2 (const TH2Poly *PolyHist, TRandom3 *rand)
 KS: ROOT developers were too lazy do develop getRanom2 for TH2Poly, this implementation is based on link More...
 
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. More...
 
void FastViolinFill (TH2D *violin, TH1D *hist_1d)
 KS: Fill Violin histogram with entry from a toy. More...
 
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. More...
 
std::string file_exists (std::string filename)
 Helper to check if files exist or not. More...
 
double returnCherenkovThresholdMomentum (int PDG)
 DB Get the Cherenkov momentum threshold in MeV. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 

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:27
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:23

◆ 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 title 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 title 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.