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#include "RooRealVar.h"
27#include "RooAbsDataStore.h"
28
29#include <ROOT/StringUtils.hxx>
30
31#include <ostream>
32
33RooChi2Var::RooChi2Var(const char *name, const char *title, RooAbsReal &func, RooDataHist &data, bool extended,
34 RooDataHist::ErrorType etype, RooAbsTestStatistic::Configuration const &cfg)
35 : RooAbsOptTestStatistic(name, title, func, data, RooArgSet{}, cfg),
36 _etype{etype == RooAbsData::Auto ? (data.isNonPoissonWeighted() ? RooAbsData::SumW2 : RooAbsData::Expected)
37 : etype},
38 _funcMode{dynamic_cast<RooAbsPdf *>(&func) ? (extended ? ExtendedPdf : Pdf) : Function}
39{
40}
41
42
43////////////////////////////////////////////////////////////////////////////////
44/// Copy constructor
45
46RooChi2Var::RooChi2Var(const RooChi2Var& other, const char* name) :
47 RooAbsOptTestStatistic(other,name),
50{
51}
52
53
54////////////////////////////////////////////////////////////////////////////////
55/// Calculate chi^2 in partition from firstEvent to lastEvent using given stepSize
56/// Throughout the calculation, we use Kahan's algorithm for summing to
57/// prevent loss of precision - this is a factor four more expensive than
58/// straight addition, but since evaluating the PDF is usually much more
59/// expensive than that, we tolerate the additional cost...
60
61double RooChi2Var::evaluatePartition(std::size_t firstEvent, std::size_t lastEvent, std::size_t stepSize) const
62{
63 double result(0);
64 double carry(0);
65
66 // Also consider the composite case of multiple ranges
67 std::vector<std::string> rangeTokens;
68 if (!_rangeName.empty()) {
69 rangeTokens = ROOT::Split(_rangeName, ",");
70 }
71
72 // Determine normalization factor depending on type of input function
73 double normFactor(1) ;
74 switch (_funcMode) {
75 case Function: normFactor=1 ; break ;
76 case Pdf: normFactor = _dataClone->sumEntries() ; break ;
77 case ExtendedPdf: normFactor = (static_cast<RooAbsPdf*>(_funcClone))->expectedEvents(_dataClone->get()) ; break ;
78 }
79
80 // Loop over bins of dataset
81 RooDataHist* hdata = static_cast<RooDataHist*>(_dataClone) ;
82 for (auto i=firstEvent ; i<lastEvent ; i+=stepSize) {
83
84 // get the data values for this event
85 RooArgSet const *row = hdata->get(i);
86
87 // Skip bins that are outside of the selected range
88 bool doSelect(true) ;
89 if (!_rangeName.empty()) {
90 doSelect = false;
91 // A row is selected if it is inside at least one complete named range.
92 for (const auto &rangeName : rangeTokens) {
93 bool inThisRange = true;
94 for (const auto arg : *row) {
95 if (!arg->inRange(rangeName.c_str())) {
96 inThisRange = false;
97 break;
98 }
99 }
100 if (inThisRange) {
101 doSelect = true;
102 break;
103 }
104 }
105 }
106 if (!doSelect) continue ;
107
108 const double nData = hdata->weight(i) ;
109
110 const double nPdf = _funcClone->getVal(_normSet) * normFactor * hdata->binVolume(i) ;
111
112 const double eExt = nPdf-nData ;
113
114
115 double eInt ;
117 double eIntLo;
118 double eIntHi;
119 hdata->weightError(eIntLo, eIntHi, _etype);
120 eInt = (eExt > 0) ? eIntHi : eIntLo;
121 } else {
122 eInt = sqrt(nPdf) ;
123 }
124
125 // Skip cases where pdf=0 and there is no data
126 if (0. == eInt * eInt && 0. == nData * nData && 0. == nPdf * nPdf) continue ;
127
128 // Return 0 if eInt=0, special handling in MINUIT will follow
129 if (0. == eInt * eInt) {
130 coutE(Eval) << "RooChi2Var::RooChi2Var(" << GetName() << ") INFINITY ERROR: bin " << i
131 << " has zero error" << std::endl;
132 return 0.;
133 }
134
135// std::cout << "Chi2Var[" << i << "] nData = " << nData << " nPdf = " << nPdf << " errorExt = " << eExt << " errorInt = " << eInt << " contrib = " << eExt*eExt/(eInt*eInt) << std::endl ;
136
137 double term = eExt*eExt/(eInt*eInt) ;
138 double y = term - carry;
139 double t = result + y;
140 carry = (t - result) - y;
141 result = t;
142 }
143
144 _evalCarry = carry;
145 return result ;
146}
147
148/// \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:142
Abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:55
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]