Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooChi2Var.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2005, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17//////////////////////////////////////////////////////////////////////////////
18/** \class RooChi2Var
19 \ingroup Roofitcore
20 \brief Simple \f$ \chi^2 \f$ calculation from a binned dataset and a PDF.
21 *
22 * It calculates:
23 *
24 \f{align*}{
25 \chi^2 &= \sum_{\mathrm{bins}} \left( \frac{N_\mathrm{PDF,bin} - N_\mathrm{Data,bin}}{\Delta_\mathrm{bin}} \right)^2 \\
26 N_\mathrm{PDF,bin} &=
27 \begin{cases}
28 \mathrm{pdf}(\text{bin centre}) \cdot V_\mathrm{bin} \cdot N_\mathrm{Data,tot} &\text{normal PDF}\\
29 \mathrm{pdf}(\text{bin centre}) \cdot V_\mathrm{bin} \cdot N_\mathrm{Data,expected} &\text{extended PDF}
30 \end{cases} \\
31 \Delta_\mathrm{bin} &=
32 \begin{cases}
33 \sqrt{N_\mathrm{PDF,bin}} &\text{if } \mathtt{DataError == RooAbsData::Expected}\\
34 \mathtt{data{\rightarrow}weightError()} &\text{otherwise} \\
35 \end{cases}
36 \f}
37 * If the dataset doesn't have user-defined errors, errors are assumed to be \f$ \sqrt{N} \f$.
38 * In extended PDF mode, N_tot (total number of data events) is substituted with N_expected, the
39 * expected number of events that the PDF predicts.
40 *
41 * \note If the dataset has errors stored, empty bins will prevent the calculation of \f$ \chi^2 \f$, because those have
42 * zero error. This leads to messages like:
43 * ```
44 * [#0] ERROR:Eval -- RooChi2Var::RooChi2Var(chi2_GenPdf_data_hist) INFINITY ERROR: bin 2 has zero error
45 * ```
46 *
47 * \note In this case, one can use the expected errors of the PDF instead of the data errors:
48 * ```{.cpp}
49 * RooChi2Var chi2(..., ..., RooFit::DataError(RooAbsData::Expected), ...);
50 * ```
51 */
52
53#include "RooChi2Var.h"
54
55#include "FitHelpers.h"
56#include "RooDataHist.h"
57#include "RooAbsPdf.h"
58#include "RooCmdConfig.h"
59#include "RooMsgService.h"
60
61#include "Riostream.h"
62#include "TClass.h"
63
64#include "RooRealVar.h"
65#include "RooAbsDataStore.h"
66
67RooChi2Var::RooChi2Var(const char *name, const char *title, RooAbsReal &func, RooDataHist &data, bool extended,
69 : RooAbsOptTestStatistic(name, title, func, data, RooArgSet{}, cfg),
70 _etype{etype == RooAbsData::Auto ? (data.isNonPoissonWeighted() ? RooAbsData::SumW2 : RooAbsData::Expected)
71 : etype},
72 _funcMode{dynamic_cast<RooAbsPdf *>(&func) ? (extended ? ExtendedPdf : Pdf) : Function}
73{
74}
75
76
77////////////////////////////////////////////////////////////////////////////////
78/// Copy constructor
79
80RooChi2Var::RooChi2Var(const RooChi2Var& other, const char* name) :
82 _etype(other._etype),
83 _funcMode(other._funcMode)
84{
85}
86
87
88////////////////////////////////////////////////////////////////////////////////
89/// Calculate chi^2 in partition from firstEvent to lastEvent using given stepSize
90/// Throughout the calculation, we use Kahan's algorithm for summing to
91/// prevent loss of precision - this is a factor four more expensive than
92/// straight addition, but since evaluating the PDF is usually much more
93/// expensive than that, we tolerate the additional cost...
94
95double RooChi2Var::evaluatePartition(std::size_t firstEvent, std::size_t lastEvent, std::size_t stepSize) const
96{
97 double result(0);
98 double carry(0);
99
100 // Determine normalization factor depending on type of input function
101 double normFactor(1) ;
102 switch (_funcMode) {
103 case Function: normFactor=1 ; break ;
104 case Pdf: normFactor = _dataClone->sumEntries() ; break ;
105 case ExtendedPdf: normFactor = (static_cast<RooAbsPdf*>(_funcClone))->expectedEvents(_dataClone->get()) ; break ;
106 }
107
108 // Loop over bins of dataset
109 RooDataHist* hdata = static_cast<RooDataHist*>(_dataClone) ;
110 for (auto i=firstEvent ; i<lastEvent ; i+=stepSize) {
111
112 // get the data values for this event
113 hdata->get(i);
114
115 const double nData = hdata->weight() ;
116
117 const double nPdf = _funcClone->getVal(_normSet) * normFactor * hdata->binVolume() ;
118
119 const double eExt = nPdf-nData ;
120
121
122 double eInt ;
124 double eIntLo;
125 double eIntHi;
126 hdata->weightError(eIntLo, eIntHi, _etype);
127 eInt = (eExt > 0) ? eIntHi : eIntLo;
128 } else {
129 eInt = sqrt(nPdf) ;
130 }
131
132 // Skip cases where pdf=0 and there is no data
133 if (0. == eInt * eInt && 0. == nData * nData && 0. == nPdf * nPdf) continue ;
134
135 // Return 0 if eInt=0, special handling in MINUIT will follow
136 if (0. == eInt * eInt) {
137 coutE(Eval) << "RooChi2Var::RooChi2Var(" << GetName() << ") INFINITY ERROR: bin " << i
138 << " has zero error" << std::endl;
139 return 0.;
140 }
141
142// cout << "Chi2Var[" << i << "] nData = " << nData << " nPdf = " << nPdf << " errorExt = " << eExt << " errorInt = " << eInt << " contrib = " << eExt*eExt/(eInt*eInt) << endl ;
143
144 double term = eExt*eExt/(eInt*eInt) ;
145 double y = term - carry;
146 double t = result + y;
147 carry = (t - result) - y;
148 result = t;
149 }
150
151 _evalCarry = carry;
152 return result ;
153}
#define coutE(a)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
char name[80]
Definition TGX11.cxx:110
Double_t(* Function)(Double_t)
Definition Functor.C:4
Abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:57
virtual double sumEntries() const =0
Return effective number of entries in dataset, i.e., sum all weights.
virtual const RooArgSet * get() const
Definition RooAbsData.h:101
Abstract base class for test statistics objects that evaluate a function or PDF at each point of a gi...
RooAbsReal * _funcClone
Pointer to internal clone of input function.
RooArgSet * _normSet
Pointer to set with observables used for normalization.
RooAbsData * _dataClone
Pointer to internal clone if input data.
Abstract interface for all probability density functions.
Definition RooAbsPdf.h:40
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:59
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:103
double _evalCarry
! carry of Kahan sum in evaluatePartition
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
Simple calculation from a binned dataset and a PDF.
Definition RooChi2Var.h:19
double evaluatePartition(std::size_t firstEvent, std::size_t lastEvent, std::size_t stepSize) const override
Calculate chi^2 in partition from firstEvent to lastEvent using given stepSize Throughout the calcula...
RooDataHist::ErrorType _etype
Error type store in associated RooDataHist.
Definition RooChi2Var.h:56
FuncMode _funcMode
Function, P.d.f. or extended p.d.f?
Definition RooChi2Var.h:57
RooChi2Var(const char *name, const char *title, RooAbsReal &func, RooDataHist &data, bool extended, RooDataHist::ErrorType etype, RooAbsTestStatistic::Configuration const &cfg=RooAbsTestStatistic::Configuration{})
Container class to hold N-dimensional binned data.
Definition RooDataHist.h:40
double weight(std::size_t i) const
Return weight of i-th bin.
void weightError(double &lo, double &hi, ErrorType etype=Poisson) const override
Return the asymmetric errors on the current weight.
double binVolume(std::size_t i) const
Return bin volume of i-th bin.
const RooArgSet * get() const override
Get bin centre of current bin.
Definition RooDataHist.h:82
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
Double_t y[n]
Definition legend1.C:17