Logo ROOT   6.10/09
Reference Guide
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 //
19 // Class RooChi2Var implements a simple chi^2 calculation from a binned dataset
20 // and a PDF. The chi^2 is calculated as
21 //
22 // / (f_PDF * N_tot/ V_bin) - N_bin \+2
23 // Sum[bins] | ------------------------------ |
24 // \ err_bin /
25 //
26 // If no user-defined errors are defined for the dataset, poisson errors
27 // are used. In extended PDF mode, N_tot is substituted with N_expected.
28 //
29 
30 #include "RooFit.h"
31 
32 #include "RooChi2Var.h"
33 #include "RooChi2Var.h"
34 #include "RooDataHist.h"
35 #include "RooAbsPdf.h"
36 #include "RooCmdConfig.h"
37 #include "RooMsgService.h"
38 
39 #include "Riostream.h"
40 
41 #include "RooRealVar.h"
42 #include "RooAbsDataStore.h"
43 
44 
45 using namespace std;
46 
48 ;
49 
51 
52 
53 ////////////////////////////////////////////////////////////////////////////////
54 
55 RooChi2Var::RooChi2Var(const char *name, const char* title, RooAbsReal& func, RooDataHist& hdata,
56  const RooCmdArg& arg1,const RooCmdArg& arg2,const RooCmdArg& arg3,
57  const RooCmdArg& arg4,const RooCmdArg& arg5,const RooCmdArg& arg6,
58  const RooCmdArg& arg7,const RooCmdArg& arg8,const RooCmdArg& arg9) :
59  RooAbsOptTestStatistic(name,title,func,hdata,_emptySet,
60  RooCmdConfig::decodeStringOnTheFly("RooChi2Var::RooChi2Var","RangeWithName",0,"",arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
61  0,
62  RooCmdConfig::decodeIntOnTheFly("RooChi2Var::RooChi2Var","NumCPU",0,1,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
64  RooCmdConfig::decodeIntOnTheFly("RooChi2Var::RooChi2Var","Verbose",0,1,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
65  0)
66  // RooChi2Var constructor. Optional arguments taken
67  //
68  // DataError() -- Choose between Poisson errors and Sum-of-weights errors
69  // NumCPU() -- Activate parallel processing feature
70  // Range() -- Fit only selected region
71  // Verbose() -- Verbose output of GOF framework
72 {
73  RooCmdConfig pc("RooChi2Var::RooChi2Var") ;
74  pc.defineInt("etype","DataError",0,(Int_t)RooDataHist::Auto) ;
75  pc.defineInt("extended","Extended",0,kFALSE) ;
76  pc.allowUndefined() ;
77 
78  pc.process(arg1) ; pc.process(arg2) ; pc.process(arg3) ;
79  pc.process(arg4) ; pc.process(arg5) ; pc.process(arg6) ;
80  pc.process(arg7) ; pc.process(arg8) ; pc.process(arg9) ;
81 
82  if (func.IsA()->InheritsFrom(RooAbsPdf::Class())) {
83  _funcMode = pc.getInt("extended") ? ExtendedPdf : Pdf ;
84  } else {
86  }
87  _etype = (RooDataHist::ErrorType) pc.getInt("etype") ;
88 
89  if (_etype==RooAbsData::Auto) {
91  }
92 
93 }
94 
95 
96 
97 ////////////////////////////////////////////////////////////////////////////////
98 
99 RooChi2Var::RooChi2Var(const char *name, const char* title, RooAbsPdf& pdf, RooDataHist& hdata,
100  const RooCmdArg& arg1,const RooCmdArg& arg2,const RooCmdArg& arg3,
101  const RooCmdArg& arg4,const RooCmdArg& arg5,const RooCmdArg& arg6,
102  const RooCmdArg& arg7,const RooCmdArg& arg8,const RooCmdArg& arg9) :
103  RooAbsOptTestStatistic(name,title,pdf,hdata,
104  *(const RooArgSet*)RooCmdConfig::decodeObjOnTheFly("RooChi2Var::RooChi2Var","ProjectedObservables",0,&_emptySet
105  ,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
106  RooCmdConfig::decodeStringOnTheFly("RooChi2Var::RooChi2Var","RangeWithName",0,"",arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
107  RooCmdConfig::decodeStringOnTheFly("RooChi2Var::RooChi2Var","AddCoefRange",0,"",arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
108  RooCmdConfig::decodeIntOnTheFly("RooChi2Var::RooChi2Var","NumCPU",0,1,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
110  RooCmdConfig::decodeIntOnTheFly("RooChi2Var::RooChi2Var","Verbose",0,1,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9),
111  RooCmdConfig::decodeIntOnTheFly("RooChi2Var::RooChi2Var","SplitRange",0,0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9))
112  // RooChi2Var constructor. Optional arguments taken
113  //
114  // Extended() -- Include extended term in calculation
115  // DataError() -- Choose between Poisson errors and Sum-of-weights errors
116  // NumCPU() -- Activate parallel processing feature
117  // Range() -- Fit only selected region
118  // SumCoefRange() -- Set the range in which to interpret the coefficients of RooAddPdf components
119  // SplitRange() -- Fit range is split by index catory of simultaneous PDF
120  // ConditionalObservables() -- Define projected observables
121  // Verbose() -- Verbose output of GOF framework
122 {
123  RooCmdConfig pc("RooChi2Var::RooChi2Var") ;
124  pc.defineInt("extended","Extended",0,kFALSE) ;
125  pc.defineInt("etype","DataError",0,(Int_t)RooDataHist::Auto) ;
126  pc.allowUndefined() ;
127 
128  pc.process(arg1) ; pc.process(arg2) ; pc.process(arg3) ;
129  pc.process(arg4) ; pc.process(arg5) ; pc.process(arg6) ;
130  pc.process(arg7) ; pc.process(arg8) ; pc.process(arg9) ;
131 
132  _funcMode = pc.getInt("extended") ? ExtendedPdf : Pdf ;
133  _etype = (RooDataHist::ErrorType) pc.getInt("etype") ;
134  if (_etype==RooAbsData::Auto) {
136  }
137 }
138 
139 
140 
141 ////////////////////////////////////////////////////////////////////////////////
142 /// Constructor of a chi2 for given p.d.f. with respect given binned
143 /// dataset. If cutRange is specified the calculation of the chi2 is
144 /// restricted to that named range. If addCoefRange is specified, the
145 /// interpretation of fractions for all component RooAddPdfs that do
146 /// not have a frozen range interpretation is set to chosen range
147 /// name. If nCPU is greater than one the chi^2 calculation is
148 /// paralellized over the specified number of processors. If
149 /// interleave is true the partitioning of event over processors
150 /// follows a (i % n == i_set) strategy rather than a bulk
151 /// partitioning strategy which may result in unequal load balancing
152 /// in binned datasets with many (adjacent) zero bins. If
153 /// splitCutRange is true the cutRange is used to construct an
154 /// individual cutRange for each RooSimultaneous index category state
155 /// name cutRange_{indexStateName}.
156 
157 RooChi2Var::RooChi2Var(const char *name, const char *title, RooAbsPdf& pdf, RooDataHist& hdata,
158  Bool_t extended, const char* cutRange, const char* addCoefRange,
159  Int_t nCPU, RooFit::MPSplit interleave, Bool_t verbose, Bool_t splitCutRange, RooDataHist::ErrorType etype) :
160  RooAbsOptTestStatistic(name,title,pdf,hdata,RooArgSet(),cutRange,addCoefRange,nCPU,interleave,verbose,splitCutRange),
161  _etype(etype), _funcMode(extended?ExtendedPdf:Pdf)
162 {
163 }
164 
165 
166 
167 ////////////////////////////////////////////////////////////////////////////////
168 /// Constructor of a chi2 for given p.d.f. with respect given binned
169 /// dataset taking the observables specified in projDeps as projected
170 /// observables. If cutRange is specified the calculation of the chi2
171 /// is restricted to that named range. If addCoefRange is specified,
172 /// the interpretation of fractions for all component RooAddPdfs that
173 /// do not have a frozen range interpretation is set to chosen range
174 /// name. If nCPU is greater than one the chi^2 calculation is
175 /// paralellized over the specified number of processors. If
176 /// interleave is true the partitioning of event over processors
177 /// follows a (i % n == i_set) strategy rather than a bulk
178 /// partitioning strategy which may result in unequal load balancing
179 /// in binned datasets with many (adjacent) zero bins. If
180 /// splitCutRange is true the cutRange is used to construct an
181 /// individual cutRange for each RooSimultaneous index category state
182 /// name cutRange_{indexStateName}.
183 
184 RooChi2Var::RooChi2Var(const char *name, const char *title, RooAbsReal& func, RooDataHist& hdata,
185  const RooArgSet& projDeps, RooChi2Var::FuncMode fmode, const char* cutRange, const char* addCoefRange,
186  Int_t nCPU, RooFit::MPSplit interleave, Bool_t verbose, Bool_t splitCutRange, RooDataHist::ErrorType etype) :
187  RooAbsOptTestStatistic(name,title,func,hdata,projDeps,cutRange,addCoefRange,nCPU,interleave,verbose,splitCutRange),
188  _etype(etype), _funcMode(fmode)
189 {
190 }
191 
192 
193 
194 ////////////////////////////////////////////////////////////////////////////////
195 /// Copy constructor
196 
197 RooChi2Var::RooChi2Var(const RooChi2Var& other, const char* name) :
198  RooAbsOptTestStatistic(other,name),
199  _etype(other._etype),
200  _funcMode(other._funcMode)
201 {
202 }
203 
204 
205 
206 ////////////////////////////////////////////////////////////////////////////////
207 /// Destructor
208 
210 {
211 }
212 
213 
214 
215 ////////////////////////////////////////////////////////////////////////////////
216 /// Calculate chi^2 in partition from firstEvent to lastEvent using given stepSize
217 
218 Double_t RooChi2Var::evaluatePartition(Int_t firstEvent, Int_t lastEvent, Int_t stepSize) const
219 {
220  // Throughout the calculation, we use Kahan's algorithm for summing to
221  // prevent loss of precision - this is a factor four more expensive than
222  // straight addition, but since evaluating the PDF is usually much more
223  // expensive than that, we tolerate the additional cost...
224  Int_t i ;
225  Double_t result(0), carry(0);
226 
227  _dataClone->store()->recalculateCache( _projDeps, firstEvent, lastEvent, stepSize, kFALSE) ;
228 
229 
230  // Determine normalization factor depending on type of input function
231  Double_t normFactor(1) ;
232  switch (_funcMode) {
233  case Function: normFactor=1 ; break ;
234  case Pdf: normFactor = _dataClone->sumEntries() ; break ;
235  case ExtendedPdf: normFactor = ((RooAbsPdf*)_funcClone)->expectedEvents(_dataClone->get()) ; break ;
236  }
237 
238  // Loop over bins of dataset
239  RooDataHist* hdata = (RooDataHist*) _dataClone ;
240  for (i=firstEvent ; i<lastEvent ; i+=stepSize) {
241 
242  // get the data values for this event
243  hdata->get(i);
244 
245  if (!hdata->valid()) continue;
246 
247  const Double_t nData = hdata->weight() ;
248 
249  const Double_t nPdf = _funcClone->getVal(_normSet) * normFactor * hdata->binVolume() ;
250 
251  const Double_t eExt = nPdf-nData ;
252 
253 
254  Double_t eInt ;
255  if (_etype != RooAbsData::Expected) {
256  Double_t eIntLo,eIntHi ;
257  hdata->weightError(eIntLo,eIntHi,_etype) ;
258  eInt = (eExt>0) ? eIntHi : eIntLo ;
259  } else {
260  eInt = sqrt(nPdf) ;
261  }
262 
263  // Skip cases where pdf=0 and there is no data
264  if (0. == eInt * eInt && 0. == nData * nData && 0. == nPdf * nPdf) continue ;
265 
266  // Return 0 if eInt=0, special handling in MINUIT will follow
267  if (0. == eInt * eInt) {
268  coutE(Eval) << "RooChi2Var::RooChi2Var(" << GetName() << ") INFINITY ERROR: bin " << i
269  << " has zero error" << endl ;
270  return 0.;
271  }
272 
273 // cout << "Chi2Var[" << i << "] nData = " << nData << " nPdf = " << nPdf << " errorExt = " << eExt << " errorInt = " << eInt << " contrib = " << eExt*eExt/(eInt*eInt) << endl ;
274 
275  Double_t term = eExt*eExt/(eInt*eInt) ;
276  Double_t y = term - carry;
277  Double_t t = result + y;
278  carry = (t - result) - y;
279  result = t;
280  }
281 
282  _evalCarry = carry;
283  return result ;
284 }
285 
286 
287 
virtual Double_t sumEntries() const =0
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
#define coutE(a)
Definition: RooMsgService.h:34
virtual const RooArgSet * get() const
Definition: RooDataHist.h:77
virtual Bool_t valid() const
Return true if currently loaded coordinate is considered valid within the current range definitions o...
virtual const RooArgSet * get() const
Definition: RooAbsData.h:77
RooDataHist::ErrorType _etype
Definition: RooChi2Var.h:71
Double_t getVal(const RooArgSet *set=0) const
Definition: RooAbsReal.h:64
virtual Double_t evaluatePartition(Int_t firstEvent, Int_t lastEvent, Int_t stepSize) const
Calculate chi^2 in partition from firstEvent to lastEvent using given stepSize.
Definition: RooChi2Var.cxx:218
virtual ~RooChi2Var()
Destructor.
Definition: RooChi2Var.cxx:209
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
void allowUndefined(Bool_t flag=kTRUE)
Definition: RooCmdConfig.h:39
STL namespace.
Bool_t process(const RooCmdArg &arg)
Process given RooCmdArg.
double sqrt(double)
RooDataSet is a container class to hold N-dimensional binned data.
Definition: RooDataHist.h:40
void Class()
Definition: Class.C:29
Double_t _evalCarry
avoids loss of precision
Double_t binVolume() const
Definition: RooDataHist.h:102
virtual Double_t weight() const
Definition: RooDataHist.h:96
FuncMode _funcMode
Definition: RooChi2Var.h:72
Bool_t defineInt(const char *name, const char *argName, Int_t intNum, Int_t defValue=0)
Define integer property name &#39;name&#39; mapped to integer in slot &#39;intNum&#39; in RooCmdArg with name argName...
virtual void weightError(Double_t &lo, Double_t &hi, ErrorType etype=Poisson) const
Return the error on current weight.
static RooArgSet _emptySet
Definition: RooChi2Var.h:69
Int_t getInt(const char *name, Int_t defaultValue=0)
Return integer property registered with name &#39;name&#39;.
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:436
RooChi2Var(const char *name, const char *title, RooAbsReal &func, RooDataHist &data, const RooCmdArg &arg1, const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none(), const RooCmdArg &arg9=RooCmdArg::none())
Definition: RooChi2Var.cxx:55
bool verbose
const UInt_t eInt[256]
Class RooCmdConfig is a configurable parser for RooCmdArg named arguments.
Definition: RooCmdConfig.h:27
RooAbsDataStore * store()
Definition: RooAbsData.h:55
const Bool_t kFALSE
Definition: RtypesCore.h:92
#define ClassImp(name)
Definition: Rtypes.h:336
double Double_t
Definition: RtypesCore.h:55
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:53
Double_t y[n]
Definition: legend1.C:17
double func(double *x, double *p)
Definition: stressTF1.cxx:213
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
virtual Bool_t isNonPoissonWeighted() const
Returns true if datasets contains entries with a non-integer weight.
double result[121]
virtual void recalculateCache(const RooArgSet *, Int_t, Int_t, Int_t, Bool_t)
RooAbsOptTestStatistic is the abstract base class for test statistics objects that evaluate a functio...
RooCmdArg is a named container for two doubles, two integers two object points and three string point...
Definition: RooCmdArg.h:27