MaCh3  2.6.0
Reference Guide
Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
SampleHandlerInterface Class Referenceabstract

Class responsible for handling implementation of samples used in analysis, reweighting and returning LLH. More...

#include <Samples/SampleHandlerInterface.h>

Inheritance diagram for SampleHandlerInterface:
[legend]
Collaboration diagram for SampleHandlerInterface:
[legend]

Public Member Functions

 SampleHandlerInterface ()
 The main constructor. More...
 
virtual ~SampleHandlerInterface ()
 destructor More...
 
virtual M3::int_t GetNSamples ()
 returns total number of samples More...
 
virtual std::string GetSampleTitle (const int iSample) const =0
 Get fancy title for specified samples. More...
 
virtual std::string GetName () const =0
 Get name for Sample Handler. More...
 
virtual double GetSampleLikelihood (const int iSample) const =0
 Get likelihood (-logL) for a single sample. More...
 
virtual void CleanMemoryBeforeFit ()=0
 Allow to clean not used memory before fit starts. More...
 
virtual void SaveAdditionalInfo ([[maybe_unused]] TDirectory *Dir)
 Store additional info in a chain. More...
 
MaCh3ModesGetMaCh3Modes () const
 Return pointer to MaCh3 modes. More...
 
virtual void Reweight ()=0
 main routine modifying MC prediction based on proposed parameter values More...
 
virtual double GetLikelihood () const =0
 Return likelihood (-LogL) for all samples. More...
 
virtual void PrintRates (const bool DataOnly=false)=0
 Helper function to print rates for the samples with LLH. More...
 
virtual int GetNOscChannels (const int iSample) const =0
 Get number of oscillation channels for a single sample. More...
 
virtual std::string GetKinVarName (const int iSample, const int Dimension) const =0
 Return Kinematic Variable name for specified sample and dimension for example "Reconstructed_Neutrino_Energy". More...
 
virtual const TH1 * GetDataHist (const int Sample)=0
 Get Data histogram. More...
 
virtual const TH1 * GetMCHist (const int Sample)=0
 Get MC histogram. More...
 
virtual const TH1 * GetW2Hist (const int Sample)=0
 Get W2 histogram. More...
 
virtual int GetNDim (const int Sample) const =0
 DB Get what dimensionality binning for given sample has. More...
 
virtual std::string GetFlavourName (const int iSample, const int iChannel) const =0
 Get the flavour name for a given sample and oscillation channel. More...
 
virtual std::vector< double > ReturnKinematicParameterBinning (const int Sample, const std::string &KinematicParameter) const =0
 Return the binning used to draw a kinematic parameter. More...
 
virtual std::unique_ptr< TH1 > Get1DVarHistByModeAndChannel (const int iSample, const std::string &ProjectionVar_Str, const int kModeToFill=-1, const int kChannelToFill=-1, const int WeightStyle=0)=0
 Build a 1D histogram for a given variable, optionally filtered by mode and channel. More...
 
virtual std::unique_ptr< TH2 > Get2DVarHistByModeAndChannel (const int iSample, const std::string &ProjectionVar_StrX, const std::string &ProjectionVar_StrY, int kModeToFill=-1, const int kChannelToFill=-1, const int WeightStyle=0)=0
 Build a 2D histogram for given variables, optionally filtered by mode and channel. More...
 
virtual std::unique_ptr< TH1 > Get1DVarHist (const int iSample, const std::string &ProjectionVar, const std::vector< KinematicCut > &EventSelectionVec={}, int WeightStyle=0, const std::vector< KinematicCut > &SubEventSelectionVec={})=0
 Return 1D projection of MC into given 1D variable (doesn't have to be variable used in the fit) More...
 
virtual std::unique_ptr< TH2 > Get2DVarHist (const int iSample, const std::string &ProjectionVarX, const std::string &ProjectionVarY, const std::vector< KinematicCut > &EventSelectionVec={}, const int WeightStyle=0, const std::vector< KinematicCut > &SubEventSelectionVec={})=0
 Build a 2D projection of MC events into specified variables. More...
 
double GetPoissonLLH (const double data, const double mc) const
 Calculate test statistic for a single bin using Poisson. More...
 
double GetTestStatLLH (const double data, const double mc, const double w2) const
 Calculate test statistic for a single bin. Calculation depends on setting of fTestStatistic. Data and mc -> 0 cut-offs are defined in M3::LOW_MC_BOUND. More...
 
void SetTestStatistic (TestStatistic testStat)
 Set the test statistic to be used when calculating the binned likelihoods. More...
 
TestStatistic GetTestStatistic () const
 Get the test statistic used when calculating the binned likelihoods. More...
 

Protected Member Functions

void QuietPlease ()
 CW: Redirect std::cout to silence some experiment specific libraries. More...
 
void NowTalk ()
 CW: Redirect std::cout to silence some experiment specific libraries. More...
 
template<typename T >
bool MatchCondition (const std::vector< T > &allowedValues, const T &value)
 check if event is affected by following conditions, for example pdg, or modes etc More...
 

Protected Attributes

TestStatistic fTestStatistic
 Test statistic tells what kind of likelihood sample is using. More...
 
std::streambuf * buf
 Keep the cout buffer. More...
 
std::streambuf * errbuf
 Keep the cerr buffer. More...
 
M3::int_t nSamples
 Contains how many samples we've got. More...
 
std::unique_ptr< MaCh3ModesModes
 Holds information about used Generator and MaCh3 modes. More...
 

Detailed Description

Class responsible for handling implementation of samples used in analysis, reweighting and returning LLH.

It serves as basic interface for fit running, as well as other functionalities like llh scan, sigma var or even posterior predictive distribution. Concrete implementations of this interface are responsible for defining the specific structure of samples, event selections, and histogram filling.

The interface operates in terms of samples and sample histograms, without direct knowledge of individual events. This abstraction supports event-by-event reweighting and may allow fully binned reweighting in future implementations.

Author
Asher Kaboth
Richard Calland

Definition at line 38 of file SampleHandlerInterface.h.

Constructor & Destructor Documentation

◆ SampleHandlerInterface()

SampleHandlerInterface::SampleHandlerInterface ( )

The main constructor.

Definition at line 4 of file SampleHandlerInterface.cpp.

4  {
5 // ***************************************************************************
6  nSamples = 0;
7 }
M3::int_t nSamples
Contains how many samples we've got.

◆ ~SampleHandlerInterface()

SampleHandlerInterface::~SampleHandlerInterface ( )
virtual

destructor

Definition at line 10 of file SampleHandlerInterface.cpp.

10  {
11 // ***************************************************************************
12 }

Member Function Documentation

◆ CleanMemoryBeforeFit()

virtual void SampleHandlerInterface::CleanMemoryBeforeFit ( )
pure virtual

Allow to clean not used memory before fit starts.

Implemented in PySampleHandlerBase, PySampleHandlerInterface, and SampleHandlerNuDockBase.

◆ Get1DVarHist()

virtual std::unique_ptr<TH1> SampleHandlerInterface::Get1DVarHist ( const int  iSample,
const std::string &  ProjectionVar,
const std::vector< KinematicCut > &  EventSelectionVec = {},
int  WeightStyle = 0,
const std::vector< KinematicCut > &  SubEventSelectionVec = {} 
)
pure virtual

Return 1D projection of MC into given 1D variable (doesn't have to be variable used in the fit)

Parameters
iSampleIndex of the sample.
ProjectionVarname of variable
EventSelectionVecVector of additional cuts like cut on interaction mode
WeightStyleAlow to modify weight for example if equal to 1 all weights are set to 1
SubEventSelectionVecVector of additional cuts for sub event (particle, ring etc.)

Implemented in SampleHandlerBase, and PySampleHandlerInterface.

◆ Get1DVarHistByModeAndChannel()

virtual std::unique_ptr<TH1> SampleHandlerInterface::Get1DVarHistByModeAndChannel ( const int  iSample,
const std::string &  ProjectionVar_Str,
const int  kModeToFill = -1,
const int  kChannelToFill = -1,
const int  WeightStyle = 0 
)
pure virtual

Build a 1D histogram for a given variable, optionally filtered by mode and channel.

Parameters
iSampleIndex of the sample.
ProjectionVar_StrName of the variable to project onto.
kModeToFillInteraction mode to select (-1 means all modes).
kChannelToFillOscillation channel to select (-1 means all channels).
WeightStyleWeighting scheme (e.g. 0 = nominal weights, 1 = unit weights).

Implemented in PySampleHandlerInterface, and SampleHandlerBase.

◆ Get2DVarHist()

virtual std::unique_ptr<TH2> SampleHandlerInterface::Get2DVarHist ( const int  iSample,
const std::string &  ProjectionVarX,
const std::string &  ProjectionVarY,
const std::vector< KinematicCut > &  EventSelectionVec = {},
const int  WeightStyle = 0,
const std::vector< KinematicCut > &  SubEventSelectionVec = {} 
)
pure virtual

Build a 2D projection of MC events into specified variables.

Parameters
iSampleIndex of the sample.
ProjectionVarXName of the variable for the X axis.
ProjectionVarYName of the variable for the Y axis.
EventSelectionVecVector of event-level selection cuts.
WeightStyleWeighting scheme (e.g. 0 = nominal weights, 1 = unit weights).
SubEventSelectionVecVector of sub-event selection cuts.

Implemented in SampleHandlerBase, and PySampleHandlerInterface.

◆ Get2DVarHistByModeAndChannel()

virtual std::unique_ptr<TH2> SampleHandlerInterface::Get2DVarHistByModeAndChannel ( const int  iSample,
const std::string &  ProjectionVar_StrX,
const std::string &  ProjectionVar_StrY,
int  kModeToFill = -1,
const int  kChannelToFill = -1,
const int  WeightStyle = 0 
)
pure virtual

Build a 2D histogram for given variables, optionally filtered by mode and channel.

Parameters
iSampleIndex of the sample.
ProjectionVar_StrXName of the variable for the X axis.
ProjectionVar_StrYName of the variable for the Y axis.
kModeToFillInteraction mode to select (-1 means all modes).
kChannelToFillOscillation channel to select (-1 means all channels).
WeightStyleWeighting scheme (e.g. 0 = nominal weights, 1 = unit weights).

Implemented in PySampleHandlerInterface, and SampleHandlerBase.

◆ GetDataHist()

virtual const TH1* SampleHandlerInterface::GetDataHist ( const int  Sample)
pure virtual

Get Data histogram.

Parameters
SampleSample enumerator

Implemented in PySampleHandlerInterface, and SampleHandlerBase.

◆ GetFlavourName()

virtual std::string SampleHandlerInterface::GetFlavourName ( const int  iSample,
const int  iChannel 
) const
pure virtual

Get the flavour name for a given sample and oscillation channel.

Parameters
iSampleIndex of the sample.
iChannelIndex of the oscillation channel within the sample.

Implemented in PySampleHandlerInterface, and SampleHandlerBase.

◆ GetKinVarName()

virtual std::string SampleHandlerInterface::GetKinVarName ( const int  iSample,
const int  Dimension 
) const
pure virtual

Return Kinematic Variable name for specified sample and dimension for example "Reconstructed_Neutrino_Energy".

Parameters
iSampleSample index
DimensionDimension index

Implemented in PySampleHandlerInterface, and SampleHandlerBase.

◆ GetLikelihood()

virtual double SampleHandlerInterface::GetLikelihood ( ) const
pure virtual

Return likelihood (-LogL) for all samples.

Implemented in SampleHandlerBase, PySampleHandlerInterface, and SampleHandlerNuDockBase.

◆ GetMaCh3Modes()

MaCh3Modes* SampleHandlerInterface::GetMaCh3Modes ( ) const
inline

Return pointer to MaCh3 modes.

Definition at line 62 of file SampleHandlerInterface.h.

62 { return Modes.get(); }
std::unique_ptr< MaCh3Modes > Modes
Holds information about used Generator and MaCh3 modes.

◆ GetMCHist()

virtual const TH1* SampleHandlerInterface::GetMCHist ( const int  Sample)
pure virtual

Get MC histogram.

Parameters
SampleSample enumerator

Implemented in PySampleHandlerInterface, and SampleHandlerBase.

◆ GetName()

virtual std::string SampleHandlerInterface::GetName ( ) const
pure virtual

Get name for Sample Handler.

Implemented in PySampleHandlerInterface, SampleHandlerNuDockBase, and SampleHandlerBase.

◆ GetNDim()

virtual int SampleHandlerInterface::GetNDim ( const int  Sample) const
pure virtual

DB Get what dimensionality binning for given sample has.

Parameters
SampleNumber of sample

Implemented in PySampleHandlerInterface, and SampleHandlerBase.

◆ GetNOscChannels()

virtual int SampleHandlerInterface::GetNOscChannels ( const int  iSample) const
pure virtual

Get number of oscillation channels for a single sample.

Parameters
iSampleSample enumerator

Implemented in PySampleHandlerInterface, and SampleHandlerBase.

◆ GetNSamples()

virtual M3::int_t SampleHandlerInterface::GetNSamples ( )
inlinevirtual

returns total number of samples

Definition at line 47 of file SampleHandlerInterface.h.

47 { return nSamples; };

◆ GetPoissonLLH()

double SampleHandlerInterface::GetPoissonLLH ( const double  data,
const double  mc 
) const

Calculate test statistic for a single bin using Poisson.

Parameters
datais data
mcis mc

Definition at line 16 of file SampleHandlerInterface.cpp.

16  {
17 // ***************************************************************************
18  // Return MC if there are no data, returns 0 for data == 0 && mc == 0
19  if ( data == 0 ) return mc;
20 
21  // If there are some data, but the prediction falls below the MC bound => return Poisson LogL for the low MC bound
22  if ( mc < M3::_LOW_MC_BOUND_ ) {
23  if ( data > M3::_LOW_MC_BOUND_ ) return ( M3::_LOW_MC_BOUND_ - data + data * std::log( data/M3::_LOW_MC_BOUND_ ) );
24  else if ( data >= mc ) return 0.;
25  }
26 
27  // Otherwise, just return usual Poisson LogL using Stirling's approximation
28  // http://hyperphysics.phy-astr.gsu.edu/hbase/math/stirling.html
29  return ( mc - data + data * std::log( data / mc ) );
30 }
constexpr static const double _LOW_MC_BOUND_
MC prediction lower bound in bin to identify problematic binning definitions and handle LogL calculat...
Definition: Core.h:83

◆ GetSampleLikelihood()

virtual double SampleHandlerInterface::GetSampleLikelihood ( const int  iSample) const
pure virtual

Get likelihood (-logL) for a single sample.

Parameters
iSampleSample enumerator

Implemented in SampleHandlerBase, and PySampleHandlerInterface.

◆ GetSampleTitle()

virtual std::string SampleHandlerInterface::GetSampleTitle ( const int  iSample) const
pure virtual

Get fancy title for specified samples.

Parameters
iSampleSample enumerator

Implemented in SampleHandlerBase, and PySampleHandlerInterface.

◆ GetTestStatistic()

TestStatistic SampleHandlerInterface::GetTestStatistic ( ) const
inline

Get the test statistic used when calculating the binned likelihoods.

Definition at line 239 of file SampleHandlerInterface.h.

239 { return fTestStatistic; }
TestStatistic fTestStatistic
Test statistic tells what kind of likelihood sample is using.

◆ GetTestStatLLH()

double SampleHandlerInterface::GetTestStatLLH ( const double  data,
const double  mc,
const double  w2 
) const

Calculate test statistic for a single bin. Calculation depends on setting of fTestStatistic. Data and mc -> 0 cut-offs are defined in M3::LOW_MC_BOUND.

Poisson

Standard Poisson log-likelihood (Stirling approximation) [2]

\[ - \log \mathcal{L}_\mathrm{Poisson} = \sum_i N_i^\mathrm{MC} - N_i^\mathrm{data} + N_i^\mathrm{data} \ln \frac{N_i^\mathrm{data}}{N_i^\mathrm{MC}}, \]

Pearson

Standard Pearson likelihood [28] (assumes Gaussian approximation of bin counts):

\[ - \log \mathcal{L}_\mathrm{Pearson} = \sum_i \frac{(N_i^\mathrm{data} - N_i^\mathrm{MC})^2}{2 \, N_i^\mathrm{MC}} \]

Barlow-Beeston

Based on [3] and following Conway approximation ([5]) The generation of MC is a stochastic process, so even identical settings can lead to different outputs (assuming that the seeds of the random number generator are different). This introduces uncertainty in MC distributions, especially in bins with low statistics.

\[ - \log \mathcal{L}_\mathrm{BB} = - \log \mathcal{L}_\mathrm{Poisson} - \log \mathcal{L}_\mathrm{MC_{stat}} = \sum_i \Biggl[ N_i^\mathrm{MC}(\vec{\theta}) - N_i^\mathrm{data} + N_i^\mathrm{data} \ln \frac{N_i^\mathrm{data}}{N_i^\mathrm{MC}(\vec{\theta})} + \frac{(\beta_i - 1)^2}{2 \sigma_{\beta_i}^2} \Biggr], \]

where \(\beta_i\) is a scaling parameter between ideal ("true") and generated MC in a bin ( \(N^\mathrm{true}_{\mathrm{MC},i} = \beta_i N_i^\mathrm{MC}\)), and \(\sigma^2_{\beta_i} = \frac{\sum_i w_i^2}{N_i^\mathrm{MC}}\), with \(\sum_i w_i^2\) being the sum of the squares of weights in bin \(i\). Assuming \(\beta_i\) follows a Gaussian, its mean can be found by solving the quadratic equation derived by Conway:

\[ \beta_i^2 + (N_i^\mathrm{MC} \sigma_{\beta_i}^2 - 1)\beta_i - N_i^\mathrm{data} \sigma_{\beta_i}^2 = 0 \]

Dembinski-Abdelmotteleb

Alternative treatment of MC statistical uncertainty following Hans Dembinski and Ahmed Abdelmotteleb [6]

This approach extends the Barlow-Beeston method. For each bin:

\[ - \log \mathcal{L}_\mathrm{DA} = (N_i^{\mathrm{MC},\prime} - N_i^\mathrm{data} + N_i^\mathrm{data} \ln \frac{N_i^\mathrm{data}}{N_i^{\mathrm{MC},\prime}}) + k \beta - k + k \ln \frac{k}{k \beta} \]

where

\[ k = \frac{(N_i^\mathrm{MC})^2}{\sum_i w_i^2} \]

and

\[ \beta = \frac{N_i^\mathrm{data} + k}{N_i^\mathrm{MC} + k}, \quad N_i^{\mathrm{MC},\prime} = N_i^\mathrm{MC} \cdot \beta \]

IceCube

Alternative likelihood definition described by the IceCube collaboration [1]

\[ - \log \mathcal{L} = - \sum_i \Biggl( a_i \log(b_i) + \log[\Gamma(N_i^{\mathrm{data}}+a_i)] - (N_i^{\mathrm{data}}+a_i)\log(b_i+1) - \log[\Gamma(a_i)] \Biggr), \]

where the auxiliary variables are

\[ a_i = N^{\mathrm{gen}}_{\mathrm{MC},i} \, b_i + 1, \quad b_i = \frac{N^{\mathrm{gen}}_{\mathrm{MC},i}}{\sum_i w_i^2}. \]

Treatment of low data/mc

Implemented fTestStatistic are kPoisson (with Stirling's approx.), kBarlowBeeston (arXiv:1103.0354), kDembinskiAbdelmotteleb (arXiv:2206.12346), kIceCube (arxiv:1901.04645), and kPearson. Test statistics require mc > 0, therefore low mc and data values are treated with cut-offs based on M3::LOW_MC_BOUND = .00001 by default. For kPoisson, kBarlowBeeston, kDembinskiAbdelmotteleb, kPearson: data > LOW_MC_BOUND & mc <= LOW_MC_BOUND: returns GetTestStatLLH(data, LOW_MC_BOUND, w2), with Poisson(data,LOW_MC_BOUND) limit for mc->0, w2->0. mc < data <= LOW_MC_BOUND: returns 0 (as if any data <= LOW_MC_BOUND were effectively consistent with 0 data count), with a limit of 0 for mc->0. data = 0: returns mc (or mc/2. for kPearson), with a limit of 0 for mc->0. For kIceCube: mc < data returns the lower of IceCube(data,mc,w2) and Poisson(data,mc) penalties, with a Poisson(data,LOW_MC_BOUND) limit for mc->0, w2->0.

Parameters
datais data
mcis mc
w2is \(\sum_{i} w_{i}^2\) (sum of weights squared), which is \(\sigma^2_{\text{MC stats}}\)

Definition at line 34 of file SampleHandlerInterface.cpp.

34  {
35 // *************************
36  switch (fTestStatistic)
37  {
38  //CW: Not full Barlow-Beeston or what is referred to as "light": we're not introducing any more parameters
39  // Assume the MC has a Gaussian distribution around generated
40  // As in https://arxiv.org/abs/1103.0354 eq 10, 11
41  //CW: Calculate the Barlow-Beeston likelihood contribution from MC statistics
42  // Assumes the beta scaling parameters are Gaussian distributed
43  // Follows arXiv:1103.0354 section 5 and equation 8, 9, 10, 11 on page 4/5
44  // Essentially solves equation 11
45  case (kBarlowBeeston):
46  {
47  // The MC used in the likelihood calculation is allowed to be changed by Barlow Beeston beta parameters
48  double newmc = mc;
49 
50  // If MC falls below the low MC bound, use low MC bound for newmc
51  if ( mc < M3::_LOW_MC_BOUND_ ) {
52  if ( data > M3::_LOW_MC_BOUND_ ) newmc = M3::_LOW_MC_BOUND_;
53  else if ( data >= mc ) return 0.;
54  }
55 
56  // Barlow-Beeston uses fractional uncertainty on MC, so sqrt(sum[w^2])/mc
57  const double fractional = std::sqrt( w2 ) / newmc;
58  // fractional^2 to avoid doing same operation several times
59  const double fractional2 = fractional * fractional;
60  // b in quadratic equation
61  const double temp = newmc * fractional2 - 1;
62  // b^2 - 4ac in quadratic equation
63  const double temp2 = temp * temp + 4 * data * fractional2;
64  if ( temp2 < 0 ) {
65  MACH3LOG_ERROR("Negative square root in Barlow Beeston coefficient calculation!");
66  throw MaCh3Exception(__FILE__ , __LINE__ );
67  }
68  // Solve for the positive beta
69  const double beta = ( -1 * temp + sqrt( temp2 ) ) / 2.;
70 
71  // If there is no data, test-stat shall return only MC*beta
72  double stat = mc * beta;
73  // With data, test-stat shall return LogL for newMC*beta which includes the low MC bound
74  if ( data > 0 ) {
75  newmc *= beta;
76  stat = newmc - data + data * std::log( data / newmc );
77  }
78 
79  // Now, MC stat penalty
80  // The penalty from MC statistics using Conways approach (https://cds.cern.ch/record/1333496?)
81  double penalty = 0;
82  if ( fractional > 0 ) penalty = ( beta - 1 ) * ( beta - 1 ) / ( 2 * fractional2 );
83 
84  // Returns test-stat plus the MC stat penalty
85  return stat+penalty;
86  }
87  break;
88  //KS: Alternative calculation of Barlow-Beeston following Hans Dembinski and Ahmed Abdelmottele arXiv:2206.12346v2
90  {
91  //KS: code follows authors implementation from:
92  //https://github.com/scikit-hep/iminuit/blob/059d06b00cae097ebf340b218b4eb57357111df8/src/iminuit/cost.py#L274-L300
93 
94  // If there is no MC stat error for any reason, return Poisson LogL
95  if ( w2 == 0 ) return GetPoissonLLH(data,mc);
96 
97  // The MC can be changed
98  double newmc = mc;
99 
100  // If MC falls below the low MC bound, use low MC bound for newmc
101  if ( mc < M3::_LOW_MC_BOUND_ ) {
102  if ( data > M3::_LOW_MC_BOUND_ ) newmc = M3::_LOW_MC_BOUND_;
103  else if ( data >= mc ) return 0.;
104  }
105 
106  //the so-called effective count
107  const double k = newmc * newmc / w2;
108  //Calculate beta which is scaling factor between true and generated MC
109  const double beta = ( data + k ) / ( newmc + k );
110 
111  newmc *= beta;
112 
113  // And penalise the movement in beta relative the mc uncertainty
114  const double penalty = k * beta - k + k * std::log( k / ( k * beta ) );
115 
116  // If there are no data, this shall return newmc
117  double stat = newmc;
118  // All likelihood calculations may use the bare Poisson likelihood, so calculate here
119  // Only if there are some data
120  if ( data > 0 ) stat = newmc - data + data * std::log( data / newmc );
121 
122  // Return the statistical contribution and penalty
123  return stat+penalty;
124  }
125  break;
126  //CW: Also try the IceCube likelihood
127  // It does not modify the MC content
128  // https://arxiv.org/abs/1901.04645
129  // Argüelles, C.A., Schneider, A. & Yuan, T. J. High Energ. Phys. (2019) 2019: 30. https://doi.org/10.1007/JHEP06(2019)030
130  // We essentially construct eq 3.16 and take the logarithm
131  // in eq 3.16, mu is MC, sigma2 is w2, k is data
132  case (kIceCube):
133  {
134  // IceCube low MC bound is implemented to return Poisson(data, _LOW_MC_BOUND_)
135  // up until the IceCube(data, mc) test-statistic is less than Poisson(data, _LOW_MC_BOUND_)
136  // The 0 MC limit is set to Poisson(data, 0.) as there is no way to get a non-diverging and reasonable guess on w2
137 
138  // If there is 0 MC uncertainty (technically also when MC is 0) => Return Poisson(data, mc)
139  if ( w2 == 0 ) return GetPoissonLLH(data,mc);
140 
141  // Auxiliary variables
142  const long double b = mc / w2;
143  const long double a = mc * b + 1;
144 
145  // Use C99's implementation of log of gamma function to not be C++11 dependent
146  const double stat = double( -1 * ( a * logl( b ) + lgammal( data + a ) - lgammal( data + 1 ) - ( ( data + a ) * log1pl( b ) ) - lgammal( a ) ) );
147 
148  // Check whether the stat is more than Poisson-like bound for low mc (mc < data)
149  // TN: I believe this might get some extra optimization
150  if ( mc <= data ) {
151  if ( data <= M3::_LOW_MC_BOUND_ ) return 0.;
152  const double poisson = GetPoissonLLH(data, M3::_LOW_MC_BOUND_);
153  if ( stat > poisson ) return poisson;
154  }
155 
156  // Otherwise, return IceCube test-stat
157  return stat;
158  }
159  break;
160  //KS: Pearson works on assumption that event distribution in each bin is described by a Gaussian which in our case is not fulfilled for all bins, hence use it at your own risk
161  case (kPearson):
162  {
163  //KS: 2 is because this function returns -LLH not -2LLH
164  // With no data return the MC/2.
165  if ( data == 0 ) return mc/2.;
166 
167  // If MC is lower than the low MC bound, return the test-stat at the bound
168  if ( mc < M3::_LOW_MC_BOUND_ ) {
169  if ( data > M3::_LOW_MC_BOUND_ ) return ( data - M3::_LOW_MC_BOUND_ ) * ( data - M3::_LOW_MC_BOUND_ ) / ( 2. * M3::_LOW_MC_BOUND_ );
170  else if ( data >= mc ) return 0.;
171  }
172 
173  // Return the Pearson metric
174  return ( data - mc ) * ( data - mc ) / ( 2 * mc );
175  }
176  break;
177  case (kPoisson):
178  {
179  //Just call GetPoissonLLH which doesn't take in weights
180  //and is a Poisson likelihood comparison.
181  return GetPoissonLLH(data, mc);
182  }
183  break;
185  MACH3LOG_ERROR("kNTestStatistics is not a valid TestStatistic!");
186  throw MaCh3Exception(__FILE__, __LINE__);
187  default:
188  MACH3LOG_ERROR("Couldn't find TestStatistic {} exiting!", static_cast<int>(fTestStatistic));
189  throw MaCh3Exception(__FILE__ , __LINE__ );
190  } // end switch
191 }
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
@ kNTestStatistics
Number of test statistics.
@ kPearson
Standard Pearson likelihood .
@ kBarlowBeeston
Barlow-Beeston () following Conway approximation ()
@ kIceCube
Based on .
@ kDembinskiAbdelmotteleb
Based on .
@ kPoisson
Standard Poisson likelihood .
Custom exception class used throughout MaCh3.
double GetPoissonLLH(const double data, const double mc) const
Calculate test statistic for a single bin using Poisson.

◆ GetW2Hist()

virtual const TH1* SampleHandlerInterface::GetW2Hist ( const int  Sample)
pure virtual

Get W2 histogram.

Parameters
SampleSample enumerator

Implemented in PySampleHandlerInterface, and SampleHandlerBase.

◆ MatchCondition()

template<typename T >
bool SampleHandlerInterface::MatchCondition ( const std::vector< T > &  allowedValues,
const T &  value 
)
inlineprotected

check if event is affected by following conditions, for example pdg, or modes etc

Definition at line 249 of file SampleHandlerInterface.h.

249  {
250  if (allowedValues.empty()) {
251  return true; // Apply to all if no specific values are specified
252  }
253  return std::find(allowedValues.begin(), allowedValues.end(), value) != allowedValues.end();
254  }

◆ NowTalk()

void SampleHandlerInterface::NowTalk ( )
protected

CW: Redirect std::cout to silence some experiment specific libraries.

Definition at line 209 of file SampleHandlerInterface.cpp.

209  {
210 // ***************************************************************************
211  #if MACH3_DEBUG > 0
212  return;
213  #else
214  std::cout.rdbuf(buf);
215  std::cerr.rdbuf(errbuf);
216  #endif
217 }
std::streambuf * errbuf
Keep the cerr buffer.
std::streambuf * buf
Keep the cout buffer.

◆ PrintRates()

virtual void SampleHandlerInterface::PrintRates ( const bool  DataOnly = false)
pure virtual

Helper function to print rates for the samples with LLH.

Parameters
DataOnlywhether to print data only rates

Implemented in PySampleHandlerInterface, and SampleHandlerBase.

◆ QuietPlease()

void SampleHandlerInterface::QuietPlease ( )
protected

CW: Redirect std::cout to silence some experiment specific libraries.

Definition at line 195 of file SampleHandlerInterface.cpp.

195  {
196 // ***************************************************************************
197  #if MACH3_DEBUG > 0
198  return;
199  #else
200  buf = std::cout.rdbuf();
201  errbuf = std::cerr.rdbuf();
202  std::cout.rdbuf( nullptr );
203  std::cerr.rdbuf( nullptr );
204  #endif
205 }

◆ ReturnKinematicParameterBinning()

virtual std::vector<double> SampleHandlerInterface::ReturnKinematicParameterBinning ( const int  Sample,
const std::string &  KinematicParameter 
) const
pure virtual

Return the binning used to draw a kinematic parameter.

Parameters
iSampleIndex of the sample.
KinematicParametername of variable

Implemented in PySampleHandlerInterface, and SampleHandlerBase.

◆ Reweight()

virtual void SampleHandlerInterface::Reweight ( )
pure virtual

main routine modifying MC prediction based on proposed parameter values

Implemented in SampleHandlerBase, PySampleHandlerInterface, and SampleHandlerNuDockBase.

◆ SaveAdditionalInfo()

virtual void SampleHandlerInterface::SaveAdditionalInfo ( [[maybe_unused] ] TDirectory *  Dir)
inlinevirtual

Store additional info in a chain.

Parameters
Dirdirectory to which we save additional info

Definition at line 60 of file SampleHandlerInterface.h.

60 {};

◆ SetTestStatistic()

void SampleHandlerInterface::SetTestStatistic ( TestStatistic  testStat)
inline

Set the test statistic to be used when calculating the binned likelihoods.

Parameters
testStatThe test statistic to use.

Definition at line 237 of file SampleHandlerInterface.h.

237 { fTestStatistic = testStat; }

Member Data Documentation

◆ buf

std::streambuf* SampleHandlerInterface::buf
protected

Keep the cout buffer.

Definition at line 260 of file SampleHandlerInterface.h.

◆ errbuf

std::streambuf* SampleHandlerInterface::errbuf
protected

Keep the cerr buffer.

Definition at line 262 of file SampleHandlerInterface.h.

◆ fTestStatistic

TestStatistic SampleHandlerInterface::fTestStatistic
protected

Test statistic tells what kind of likelihood sample is using.

Definition at line 257 of file SampleHandlerInterface.h.

◆ Modes

std::unique_ptr<MaCh3Modes> SampleHandlerInterface::Modes
protected

Holds information about used Generator and MaCh3 modes.

Definition at line 268 of file SampleHandlerInterface.h.

◆ nSamples

M3::int_t SampleHandlerInterface::nSamples
protected

Contains how many samples we've got.

Definition at line 265 of file SampleHandlerInterface.h.


The documentation for this class was generated from the following files: