Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooChi2Var.cxx
Go to the documentation of this file.
1/// \cond ROOFIT_INTERNAL
2
3/*****************************************************************************
4 * Project: RooFit *
5 * Package: RooFitCore *
6 * @(#)root/roofitcore:$Id$
7 * Authors: *
8 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
9 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
10 * *
11 * Copyright (c) 2000-2005, Regents of the University of California *
12 * and Stanford University. All rights reserved. *
13 * *
14 * Redistribution and use in source and binary forms, *
15 * with or without modification, are permitted according to the terms *
16 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
17 *****************************************************************************/
18
19#include "RooChi2Var.h"
20
21#include "FitHelpers.h"
22#include "RooDataHist.h"
23#include "RooAbsPdf.h"
24#include "RooCmdConfig.h"
25#include "RooMsgService.h"
26
27#include "Riostream.h"
28#include "TClass.h"
29
30#include "RooRealVar.h"
31#include "RooAbsDataStore.h"
32
33#include <ROOT/StringUtils.hxx>
34
35RooChi2Var::RooChi2Var(const char *name, const char *title, RooAbsReal &func, RooDataHist &data, bool extended,
36 RooDataHist::ErrorType etype, RooAbsTestStatistic::Configuration const &cfg)
37 : RooAbsOptTestStatistic(name, title, func, data, RooArgSet{}, cfg),
38 _etype{etype == RooAbsData::Auto ? (data.isNonPoissonWeighted() ? RooAbsData::SumW2 : RooAbsData::Expected)
39 : etype},
41{
42}
43
44
45////////////////////////////////////////////////////////////////////////////////
46/// Copy constructor
47
48RooChi2Var::RooChi2Var(const RooChi2Var& other, const char* name) :
49 RooAbsOptTestStatistic(other,name),
52{
53}
54
55
56////////////////////////////////////////////////////////////////////////////////
57/// Calculate chi^2 in partition from firstEvent to lastEvent using given stepSize
58/// Throughout the calculation, we use Kahan's algorithm for summing to
59/// prevent loss of precision - this is a factor four more expensive than
60/// straight addition, but since evaluating the PDF is usually much more
61/// expensive than that, we tolerate the additional cost...
62
63double RooChi2Var::evaluatePartition(std::size_t firstEvent, std::size_t lastEvent, std::size_t stepSize) const
64{
65 double result(0);
66 double carry(0);
67
68 // Also consider the composite case of multiple ranges
69 std::vector<std::string> rangeTokens;
70 if (!_rangeName.empty()) {
71 rangeTokens = ROOT::Split(_rangeName, ",");
72 }
73
74 // Determine normalization factor depending on type of input function
75 double normFactor(1) ;
76 switch (_funcMode) {
77 case Function: normFactor=1 ; break ;
78 case Pdf: normFactor = _dataClone->sumEntries() ; break ;
79 case ExtendedPdf: normFactor = (static_cast<RooAbsPdf*>(_funcClone))->expectedEvents(_dataClone->get()) ; break ;
80 }
81
82 // Loop over bins of dataset
83 RooDataHist* hdata = static_cast<RooDataHist*>(_dataClone) ;
84 for (auto i=firstEvent ; i<lastEvent ; i+=stepSize) {
85
86 // get the data values for this event
87 RooArgSet const *row = hdata->get(i);
88
89 // Skip bins that are outside of the selected range
90 bool doSelect(true) ;
91 if (!_rangeName.empty()) {
92 doSelect = false;
93 // A row is selected if it is inside at least one complete named range.
94 for (const auto &rangeName : rangeTokens) {
95 bool inThisRange = true;
96 for (const auto arg : *row) {
97 if (!arg->inRange(rangeName.c_str())) {
98 inThisRange = false;
99 break;
100 }
101 }
102 if (inThisRange) {
103 doSelect = true;
104 break;
105 }
106 }
107 }
108 if (!doSelect) continue ;
109
110 const double nData = hdata->weight() ;
111
112 const double nPdf = _funcClone->getVal(_normSet) * normFactor * hdata->binVolume() ;
113
114 const double eExt = nPdf-nData ;
115
116
117 double eInt ;
119 double eIntLo;
120 double eIntHi;
121 hdata->weightError(eIntLo, eIntHi, _etype);
122 eInt = (eExt > 0) ? eIntHi : eIntLo;
123 } else {
124 eInt = sqrt(nPdf) ;
125 }
126
127 // Skip cases where pdf=0 and there is no data
128 if (0. == eInt * eInt && 0. == nData * nData && 0. == nPdf * nPdf) continue ;
129
130 // Return 0 if eInt=0, special handling in MINUIT will follow
131 if (0. == eInt * eInt) {
132 coutE(Eval) << "RooChi2Var::RooChi2Var(" << GetName() << ") INFINITY ERROR: bin " << i
133 << " has zero error" << std::endl;
134 return 0.;
135 }
136
137// std::cout << "Chi2Var[" << i << "] nData = " << nData << " nPdf = " << nPdf << " errorExt = " << eExt << " errorInt = " << eInt << " contrib = " << eExt*eExt/(eInt*eInt) << std::endl ;
138
139 double term = eExt*eExt/(eInt*eInt) ;
140 double y = term - carry;
141 double t = result + y;
142 carry = (t - result) - y;
143 result = t;
144 }
145
146 _evalCarry = carry;
147 return result ;
148}
149
150/// \endcond
#define coutE(a)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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:146
Double_t(* Function)(Double_t)
Definition Functor.C:4
Abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:56
Abstract interface for all probability density functions.
Definition RooAbsPdf.h:32
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:63
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
Container class to hold N-dimensional binned data.
Definition RooDataHist.h:40
Double_t y[n]
Definition legend1.C:17
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
const UInt_t eInt[256]