MaCh3  2.5.0
Reference Guide
Namespaces | Functions
HistogramUtils.cpp File Reference
#include "Samples/HistogramUtils.h"
#include "TList.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TRandom3.h"
Include dependency graph for HistogramUtils.cpp:

Go to the source code of this file.

Namespaces

 M3
 Main namespace for MaCh3 software.
 

Functions

_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 file with ROOT6 you will be missing 9 last bins. More...
 
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)
 WP: Poly Projectors. More...
 
TH1D * PolyProjectionY (TObject *poly, std::string TempName, const std::vector< double > &ybins, const bool computeErrors)
 WP: Poly Projectors. More...
 
TH2Poly * NormalisePoly (TH2Poly *Histogram)
 WP: Helper to Normalise histograms. More...
 
void NormaliseTH2Poly (TH2Poly *Histogram)
 Helper to Normalise histograms. More...
 
template<class HistType >
HistType * RatioHists (HistType *NumHist, HistType *DenomHist)
 Helper to make ratio histograms. More...
 
TH2Poly * RatioPolys (TH2Poly *NumHist, TH2Poly *DenomHist)
 Helper to make ratio of TH2Polys. More...
 
TH2D * ConvertTH2PolyToTH2D (TH2Poly *poly, TH2D *h2dhist)
 KS: Convert TH2D to TH2Poly. More...
 
TH2Poly * ConvertTH2DtoTH2Poly (TH2D *hist)
 KS: Convert TH2Poly to TH2D. 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...
 
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 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 MakeFluctuatedHistogramStandard (TH2Poly *FluctHist, TH2Poly *PolyHist, TRandom3 *rand)
 Make Poisson fluctuation of TH2Poly hist using default fast method. More...
 
void MakeFluctuatedHistogramStandard (TH2D *FluctHist, TH2D *Hist, TRandom3 *rand)
 Make Poisson fluctuation of TH2D 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 MakeFluctuatedHistogramAlternative (TH2D *FluctHist, TH2D *PolyHist, TRandom3 *rand)
 Make Poisson fluctuation of TH2D hist. 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...
 
void MakeFluctuatedHistogramAlternative (TH2Poly *FluctHist, TH2Poly *PolyHist, TRandom3 *rand)
 Make Poisson fluctuation of TH2Poly hist using slow method which is only for cross-check. More...
 
void FastViolinFill (TH2D *violin, TH1D *hist_1d)
 KS: Fill Violin histogram with entry from a toy. More...
 
double returnCherenkovThresholdMomentum (const int PDG)
 DB Get the Cherenkov momentum threshold in MeV. More...
 
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 energy. More...
 
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 change, and if nu/anu. More...
 
std::unique_ptr< TH1D > MakeSummaryFromSpectra (const TH2D *Spectra, const std::string &name)
 Build a 1D posterior-predictive summary from a violin spectrum. 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...
 
void M3::ScaleHistogram (TH1 *Sample_Hist, const double scale)
 Scale histogram to get divided by bin width. More...
 
void M3::CheckBinningMatch (const TH1D *Hist1, const TH1D *Hist2, const std::string &File, const int Line)
 KS: Helper function check if data and MC binning matches. More...
 
void M3::CheckBinningMatch (const TH2D *Hist1, const TH2D *Hist2, const std::string &File, const int Line)
 KS: Helper function check if data and MC binning matches. More...
 
void M3::CheckBinningMatch (TH2Poly *Hist1, TH2Poly *Hist2, const std::string &File, const int Line)
 KS: Helper function check if data and MC binning matches. More...
 
YAML::Node M3::PolyToYaml (TH2Poly *Hist, const std::string &YamlName, const std::string &File, const int Line)
 KS: Convert TH2Poly into yaml config accepted by MaCh3. More...
 

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.

Parameters
PLepShifted outgoing lepton momentum (MeV/c).
cosThetaCosine of the lepton scattering angle.
EBBinding energy shift applied to the interaction (MeV).
neutrinoTrue if the interaction is neutrino, false if antineutrino.
Todo:
WARNING this is hardcoded

Definition at line 604 of file HistogramUtils.cpp.

604  {
605 // ***************************************************************************
606  double mNeff = 0.93956536 - Eb / 1000.;
607  double mNoth = 0.93827203;
608 
609  if (!neutrino) {
610  mNeff = 0.93827203 - Eb / 1000.;
611  mNoth = 0.93956536;
612  }
614  constexpr double mLep = 0.10565837;
615  constexpr double mLep2 = mLep * mLep;
616 
617  const double eLep = sqrt(PLep * PLep + mLep2);
618  double Enu = (2 * mNeff * eLep - mLep2 + mNoth * mNoth - mNeff * mNeff) /(2 * (mNeff - eLep + PLep * costh));
619 
620  return Enu;
621 }

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

Parameters
PLepShifted outgoing lepton momentum (MeV/c).
PUpdUpdated lepton angle or related kinematic quantity used in the recalculation.
EnuTrueTrue neutrino energy (MeV).
InitialQ2Optional initial Q^2 value (used as seed or fallback, default = 0).

Definition at line 584 of file HistogramUtils.cpp.

584  {
585 // ***************************************************************************
586  constexpr double MLep = 0.10565837;
587  constexpr double MLep2 = MLep * MLep;
588 
589  // Calculate muon energy
590  double ELep = sqrt((MLep2)+(PLep*PLep));
591 
592  double CosTh = (2*EnuTrue*ELep - MLep2 - InitialQ2)/(2*EnuTrue*PLep);
593 
594  ELep = sqrt((MLep2)+(PUpd*PUpd));
595 
596  // Calculate the new Q2
597  double Q2Upd = -(MLep2) + 2.0*EnuTrue*(ELep - PUpd*CosTh);
598 
599  return Q2Upd - InitialQ2;
600 }

◆ CheckTH2PolyFileVersion()

_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 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 14 of file HistogramUtils.cpp.

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

◆ ConvertTH2DtoTH2Poly()

TH2Poly* ConvertTH2DtoTH2Poly ( TH2D *  hist)

KS: Convert TH2Poly to TH2D.

Definition at line 285 of file HistogramUtils.cpp.

285  {
286 // ****************
287  // Make the x axis from the momentum of lepton
288  TAxis* xaxis = hist->GetXaxis();
289  // Make the y axis from the cos theta of lepton
290  TAxis* yaxis = hist->GetYaxis();
291 
292  TString histname = hist->GetName();
293  // Convert TH2D binning to TH2Poly
294  TH2Poly* poly = new TH2Poly();
295  poly->SetName(histname);
296  poly->SetTitle(histname);
297 
298  // Copy axis titles
299  poly->GetXaxis()->SetTitle(xaxis->GetTitle());
300  poly->GetYaxis()->SetTitle(yaxis->GetTitle());
301 
302  double xmax, xmin, ymax, ymin;
303  for (int iy = 1; iy <= yaxis->GetNbins(); iy++) {
304  ymax = yaxis->GetBinUpEdge(iy);
305  ymin = yaxis->GetBinLowEdge(iy);
306  for (int ix = 1; ix <= xaxis->GetNbins(); ix++) {
307  xmax = xaxis->GetBinUpEdge(ix);
308  xmin = xaxis->GetBinLowEdge(ix);
309  double binofx[] = {xmin, xmax, xmax, xmin};
310  double binofy[] = {ymin, ymin, ymax, ymax};
311  poly->AddBin(4, binofx, binofy);
312  }
313  }
314 
315  for (int iy = 1; iy <= yaxis->GetNbins(); iy++) {
316  ymax = yaxis->GetBinUpEdge(iy);
317  ymin = yaxis->GetBinLowEdge(iy);
318  for (int ix = 1; ix <= xaxis->GetNbins(); ix++) {
319  xmax = xaxis->GetBinUpEdge(ix);
320  xmin = xaxis->GetBinLowEdge(ix);
321 
322  // Get the content of the corresponding bin in TH2D and set it in TH2Poly
323  int bin = hist->GetBin(ix, iy);
324  double content = hist->GetBinContent(bin);
325  poly->SetBinContent(poly->FindBin((xmin + xmax) / 2, (ymin + ymax) / 2), content);
326  }
327  }
328 
329  return poly;
330 }

◆ ConvertTH2PolyToTH2D()

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

KS: Convert TH2D to TH2Poly.

Definition at line 251 of file HistogramUtils.cpp.

251  {
252 // ****************
253  double xlow, xup, ylow, yup;
254  std::string HistTempName = poly->GetName();
255 
256  HistTempName += "_";
257  //make the th2d
258  TH2D *hist = static_cast<TH2D*>(h2dhist->Clone());
259  hist->SetNameTitle(HistTempName.c_str(), HistTempName.c_str());
260 
261  for(int ix = 0; ix < hist->GetNbinsX() + 2; ix++) {
262  for(int iy = 0; iy < hist->GetNbinsY() + 2; iy++) {
263  hist->SetBinContent(ix, iy, 0);
264  }
265  }
266  //Loop over poly bins, find the corresponding th2d and setbincontent!
267  for(int i = 0; i< poly->GetNumberOfBins(); i++){
268  TH2PolyBin & polybin = static_cast<TH2PolyBin &>(*poly->GetBins()->At(i));
269  xlow = polybin.GetXMin();
270  xup = polybin.GetXMax();
271  ylow = polybin.GetYMin();
272  yup = polybin.GetYMax();
273  int xbin, ybin;
274 
275  xbin = hist->GetXaxis()->FindBin(xlow+(xup-xlow)/2);
276  ybin = hist->GetYaxis()->FindBin(ylow+(yup-ylow)/2);
277 
278  MACH3LOG_TRACE("Poly bin {}, xlow: {}, xup: {}, ylow: {}, yup: {}. Finding bin for ({}, {}). Found Bin ({}, {}) with content {}. But Poly content: {}",
279  i, xlow, xup, ylow, yup, (xlow + (xup - xlow) / 2), (ylow + (yup - ylow) / 2), xbin, ybin, polybin.GetContent(), poly->GetBinContent(i));
280  hist->SetBinContent(xbin, ybin, polybin.GetContent());
281  }
282  return hist;
283 }
#define MACH3LOG_TRACE
Definition: MaCh3Logger.h:33

◆ 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 562 of file HistogramUtils.cpp.

562  {
563 // ****************
564  for (int x = 0; x < violin->GetXaxis()->GetNbins(); ++x)
565  {
566  const int y = violin->GetYaxis()->FindBin(hist_1d->GetBinContent(x+1));
567  violin->SetBinContent(x+1, y, violin->GetBinContent(x+1, y)+1);
568  }
569 }

◆ 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 511 of file HistogramUtils.cpp.

511  {
512 // ****************
513  const int nbins = PolyHist->GetNumberOfBins();
514  const double r1 = rand->Rndm();
515 
516  double* fIntegral = new double[nbins+2];
517  fIntegral[0] = 0.0;
518 
519  //KS: This is custom version of ComputeIntegral, once again ROOT was lazy :(
520  for (int i = 1; i < nbins+1; ++i)
521  {
522  fIntegral[i] = 0.0;
523  const double content = PolyHist->GetBinContent(i);
524  fIntegral[i] += fIntegral[i - 1] + content;
525  }
526  for (Int_t bin = 1; bin < nbins+1; ++bin) fIntegral[bin] /= fIntegral[nbins];
527  fIntegral[nbins+1] = PolyHist->GetEntries();
528 
529  //KS: We just return one rather then X and Y, this way we can use SetBinContent rather than Fill, which is faster
530  int iBin = int(TMath::BinarySearch(nbins, fIntegral, r1));
531  //KS: Have to increment because TH2Poly has stupid offset arghh
532  iBin += 1;
533 
534  delete[] fIntegral;
535  return iBin;
536 }

◆ MakeFluctuatedHistogramAlternative() [1/3]

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 469 of file HistogramUtils.cpp.

469  {
470 // ****************
471  // Make the Poisson fluctuated hist
472  FluctHist->Reset("");
473  FluctHist->Fill(0.0, 0.0);
474 
475  const double evrate = PolyHist->Integral();
476  #pragma GCC diagnostic push
477  #pragma GCC diagnostic ignored "-Wconversion"
478  const int num = rand->Poisson(evrate);
479  #pragma GCC diagnostic pop
480  int count = 0;
481  while(count < num)
482  {
483  const double candidate = PolyHist->GetRandom();
484  FluctHist->Fill(candidate);
485  count++;
486  }
487 }

◆ MakeFluctuatedHistogramAlternative() [2/3]

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

Make Poisson fluctuation of TH2D hist.

Definition at line 491 of file HistogramUtils.cpp.

491  {
492 // ****************
493  FluctHist->Reset();
494  FluctHist->Fill(0.0, 0.0, 0.0);
495 
496  const double evrate = PolyHist->Integral();
497  #pragma GCC diagnostic push
498  #pragma GCC diagnostic ignored "-Wconversion"
499  const int num = rand->Poisson(evrate);
500  #pragma GCC diagnostic pop
501 
502  double x, y;
503  for (int count = 0; count < num; ++count) {
504  PolyHist->GetRandom2(x, y);
505  FluctHist->Fill(x, y);
506  }
507 }

◆ MakeFluctuatedHistogramAlternative() [3/3]

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 540 of file HistogramUtils.cpp.

540  {
541 // ****************
542  // Make the Poisson fluctuated hist
543  FluctHist->Reset("");
544  FluctHist->Fill(0.0, 0.0, 0.0);
545 
546  const double evrate = NoOverflowIntegral(PolyHist);
547  #pragma GCC diagnostic push
548  #pragma GCC diagnostic ignored "-Wconversion"
549  const int num = rand->Poisson(evrate);
550  #pragma GCC diagnostic pop
551  int count = 0;
552  while(count < num)
553  {
554  const int iBin = GetRandomPoly2(PolyHist, rand);
555  FluctHist->SetBinContent(iBin, FluctHist->GetBinContent(iBin) + 1);
556  count++;
557  }
558 }
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/3]

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

Make Poisson fluctuation of TH1D hist using default fast method.

Definition at line 408 of file HistogramUtils.cpp.

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

◆ MakeFluctuatedHistogramStandard() [2/3]

void MakeFluctuatedHistogramStandard ( TH2D *  FluctHist,
TH2D *  Hist,
TRandom3 *  rand 
)

Make Poisson fluctuation of TH2D hist using default fast method.

Definition at line 446 of file HistogramUtils.cpp.

446  {
447 // ****************
448  // Reset the histogram
449  FluctHist->Reset("");
450  FluctHist->Fill(0.0, 0.0, 0.0);
451 
452  // Loop over all bins
453  const int nBinsX = Hist->GetXaxis()->GetNbins();
454  const int nBinsY = Hist->GetYaxis()->GetNbins();
455  for (int ix = 1; ix <= nBinsX; ++ix) {
456  for (int iy = 1; iy <= nBinsY; ++iy) {
457  // Get the original bin content
458  const double MeanContent = Hist->GetBinContent(ix, iy);
459  // Generate Poisson fluctuation
460  const double Random = rand->PoissonD(MeanContent);
461  // Set the Random content
462  FluctHist->SetBinContent(ix, iy, Random);
463  }
464  }
465 }

◆ MakeFluctuatedHistogramStandard() [3/3]

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

Make Poisson fluctuation of TH2Poly hist using default fast method.

Definition at line 427 of file HistogramUtils.cpp.

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

◆ 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 373 of file HistogramUtils.cpp.

373  {
374 // *********************
375  TH2Poly* poly = new TH2Poly();
376  poly->SetName(name.c_str());
377  poly->SetTitle(name.c_str());
378  double xmax, xmin, ymax, ymin;
379  for(unsigned int iy = 0; iy < BinArray_y.size()-1; iy++)
380  {
381  ymax = BinArray_y[iy+1];
382  ymin = BinArray_y[iy];
383  for(unsigned int ix = 0; ix < BinArray_x.size()-1; ix++)
384  {
385  xmax = BinArray_x[ix+1];
386  xmin = BinArray_x[ix];
387  double binofx[] = {xmin, xmax, xmax, xmin};
388  double binofy[] = {ymin, ymin, ymax, ymax};
389  poly->AddBin(4,binofx,binofy);
390  }
391  }
392  return poly;
393 }

◆ MakeSummaryFromSpectra()

std::unique_ptr<TH1D> MakeSummaryFromSpectra ( const TH2D *  Spectra,
const std::string &  name 
)

Build a 1D posterior-predictive summary from a violin spectrum.

Parameters
SpectraInput TH2D violin/density histogram.
nameName of the output TH1D.

Definition at line 624 of file HistogramUtils.cpp.

625  {
626 // ***********************************************
627  const int nBinsX = Spectra->GetNbinsX();
628  // Reuse the exact x binning
629  std::vector<double> edges(nBinsX + 1);
630  for (int i = 0; i < nBinsX; ++i) {
631  edges[i] = Spectra->GetXaxis()->GetBinLowEdge(i+1);
632  }
633  edges[nBinsX] = Spectra->GetXaxis()->GetBinUpEdge(nBinsX);
634 
635  auto h1 = std::make_unique<TH1D>(name.c_str(), name.c_str(), nBinsX, edges.data());
636  h1->SetDirectory(nullptr);
637  h1->Sumw2(true);
638 
639  // ---- Loop X bins and extract Y distribution
640  for (int ix = 1; ix <= nBinsX; ++ix) {
641  // Project THIS x-bin onto Y
642  std::unique_ptr<TH1D> slice(Spectra->ProjectionY(Form("_py_%d", ix), ix, ix));
643  slice->SetDirectory(nullptr);
644  if (slice->GetEntries() == 0) {
645  h1->SetBinContent(ix, 0.0);
646  h1->SetBinError(ix, 0.0);
647  continue;
648  }
649 
650  const double mean = slice->GetMean();
651  const double rms = slice->GetRMS();
652 
653  h1->SetBinContent(ix, mean);
654  h1->SetBinError(ix, rms);
655  }
656 
657  h1->GetXaxis()->SetTitle(Spectra->GetXaxis()->GetTitle());
658  h1->GetYaxis()->SetTitle("Events");
659 
660  return h1;
661 }

◆ NoOverflowIntegral()

double NoOverflowIntegral ( TH2Poly *  poly)

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

Definition at line 53 of file HistogramUtils.cpp.

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

◆ NormalisePoly()

TH2Poly* NormalisePoly ( TH2Poly *  Histogram)

WP: Helper to Normalise histograms.

Definition at line 201 of file HistogramUtils.cpp.

201  {
202 // ****************
203  TH2Poly* HistCopy = static_cast<TH2Poly*>(Histogram->Clone());
204  double IntegralWidth = PolyIntegralWidth(HistCopy);
205  HistCopy = PolyScaleWidth(HistCopy, IntegralWidth);
206  std::string title = std::string(HistCopy->GetName())+"_norm";
207  HistCopy->SetNameTitle(title.c_str(), title.c_str());
208 
209  return HistCopy;
210 }
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 214 of file HistogramUtils.cpp.

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

◆ OverflowIntegral()

double OverflowIntegral ( TH2Poly *  poly)

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

Definition at line 38 of file HistogramUtils.cpp.

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

◆ PolyIntegralWidth()

double PolyIntegralWidth ( TH2Poly *  Histogram)

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

Definition at line 354 of file HistogramUtils.cpp.

354  {
355 // ****************
356  double integral = 0;
357  double xlow, xup, ylow, yup, area;
358 
359  for(int i = 1; i < Histogram->GetNumberOfBins()+1; i++)
360  {
361  TH2PolyBin* bin = static_cast<TH2PolyBin*>(Histogram->GetBins()->At(i - 1));
362  xlow = bin->GetXMin();
363  xup = bin->GetXMax();
364  ylow = bin->GetYMin();
365  yup = bin->GetYMax();
366  area = (xup-xlow)*(yup-ylow);
367  integral += Histogram->GetBinContent(i)*area;
368  }
369  return integral;
370 }

◆ PolyProjectionX()

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

WP: Poly Projectors.

Definition at line 66 of file HistogramUtils.cpp.

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

◆ PolyProjectionY()

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

WP: Poly Projectors.

Definition at line 134 of file HistogramUtils.cpp.

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

334  {
335 // ****************
336  TH2Poly* HistCopy = static_cast<TH2Poly*>(Histogram->Clone());
337  double xlow, xup, ylow, yup, area;
338 
339  for(int i = 1; i < HistCopy->GetNumberOfBins()+1; i++)
340  {
341  TH2PolyBin* bin = static_cast<TH2PolyBin*>(Histogram->GetBins()->At(i - 1));
342  xlow = bin->GetXMin();
343  xup = bin->GetXMax();
344  ylow = bin->GetYMin();
345  yup = bin->GetYMax();
346  area = (xup-xlow)*(yup-ylow);
347  HistCopy->SetBinContent(i, Histogram->GetBinContent(i)/(area*scale));
348  }
349  return HistCopy;
350 }

◆ RatioHists()

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

Helper to make ratio histograms.

Definition at line 226 of file HistogramUtils.cpp.

226  {
227 // ****************
228  HistType *NumCopy = static_cast<HistType*>(NumHist->Clone());
229  std::string title = std::string(DenomHist->GetName()) + "_ratio";
230  NumCopy->SetNameTitle(title.c_str(), title.c_str());
231  NumCopy->Divide(DenomHist);
232 
233  return NumCopy;
234 }

◆ RatioPolys()

TH2Poly* RatioPolys ( TH2Poly *  NumHist,
TH2Poly *  DenomHist 
)

Helper to make ratio of TH2Polys.

Definition at line 238 of file HistogramUtils.cpp.

238  {
239 // ****************
240  TH2Poly *NumCopy = static_cast<TH2Poly*>(NumHist->Clone());
241  std::string title = std::string(DenomHist->GetName()) + "_ratio";
242  NumCopy->SetNameTitle(title.c_str(), title.c_str());
243 
244  for(int i = 1; i < NumCopy->GetNumberOfBins()+1; ++i) {
245  NumCopy->SetBinContent(i,NumHist->GetBinContent(i)/DenomHist->GetBinContent(i));
246  }
247  return NumCopy;
248 }

◆ RemoveFitter()

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

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

Definition at line 397 of file HistogramUtils.cpp.

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

◆ returnCherenkovThresholdMomentum()

double returnCherenkovThresholdMomentum ( const int  PDG)

DB Get the Cherenkov momentum threshold in MeV.

Parameters
PDGPDG code of the particle for which the Cherenkov threshold is requested.

Definition at line 574 of file HistogramUtils.cpp.

574  {
575 // ****************
576  constexpr double refractiveIndex = 1.334; //DB From https://github.com/fiTQun/fiTQun/blob/646cf9c8ba3d4f7400bcbbde029d5ca15513a3bf/fiTQun_shared.cc#L757
577  double mass = M3::Utils::GetMassFromPDG(PDG)*1e3;
578  double momentumThreshold = mass/sqrt(refractiveIndex*refractiveIndex-1.);
579  return momentumThreshold;
580 }
double GetMassFromPDG(const int PDG)
Return mass for given PDG.