Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooParamHistFunc.cxx
Go to the documentation of this file.
1/*
2 * Project: RooFit
3 *
4 * Copyright (c) 2023, CERN
5 *
6 * Redistribution and use in source and binary forms,
7 * with or without modification, are permitted according to the terms
8 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
9 */
10
11/** \class RooParamHistFunc
12 * \ingroup Roofit
13 *
14 * \deprecated RooParamHistFunc will be removed in ROOT 6.46, because its functionality is too close to the
15 * HistFactory classes. Please use the HistFactory class ParamHistFunc instead, multiplying it with a RooHistFunc,
16 * as shown in the rf709_BarlowBeeston tutorial.
17 *
18 * A histogram function that assigns scale parameters to every bin. Instead of the bare bin contents,
19 * it therefore yields:
20 * \f[
21 * \gamma_{i} * \mathrm{bin}_i
22 * \f]
23 *
24 * The \f$ \gamma_i \f$ can therefore be used to parametrise statistical uncertainties of the histogram
25 * template. In conjunction with a constraint term, this can be used to implement the Barlow-Beeston method.
26 * The constraint can be implemented using RooHistConstraint.
27 */
28
29#include <RooParamHistFunc.h>
30#include <RooRealVar.h>
31#include <RooFitImplHelpers.h>
32
33
34RooParamHistFunc::RooParamHistFunc(const char *name, const char *title, RooDataHist &dh, const RooAbsArg &x,
35 const RooParamHistFunc *paramSource, bool paramRelative)
36 : RooAbsReal(name, title), _x("x", "x", this), _p("p", "p", this), _dh(dh), _relParam(paramRelative)
37{
38 // Populate x with observables
39 _x.add(x);
40
41 if (paramSource) {
42 // Now populate p with existing parameters
43 _p.add(paramSource->_p);
44 return;
45 }
46
47 // Now populate p with parameters
48 RooArgSet allVars;
49 for (Int_t i = 0; i < _dh.numEntries(); i++) {
50 const double wi = _dh.weight(i);
51 const char *vname = Form("%s_gamma_bin_%i", GetName(), i);
52 RooRealVar *var = new RooRealVar(vname, vname, 0, 1000);
53 var->setVal(_relParam ? 1 : wi);
54 var->setError(_relParam ? 1 / sqrt(wi) : sqrt(wi));
55 var->setConstant(true);
56 allVars.add(*var);
57 _p.add(*var);
58 }
59 addOwnedComponents(allVars);
60}
61
62////////////////////////////////////////////////////////////////////////////////
63
64RooParamHistFunc::RooParamHistFunc(const RooParamHistFunc& other, const char* name) :
65 RooAbsReal(other,name),
66 _x("x",this,other._x),
67 _p("p",this,other._p),
68 _dh(other._dh),
69 _relParam(other._relParam)
70{
71}
72
73////////////////////////////////////////////////////////////////////////////////
74
75double RooParamHistFunc::evaluate() const
76{
77 Int_t idx = ((RooDataHist&)_dh).getIndex(_x,true) ;
78 double ret = (static_cast<RooAbsReal*>(_p.at(idx)))->getVal() ;
79 return _relParam ? ret * getNominal(idx) : ret;
80}
81
82////////////////////////////////////////////////////////////////////////////////
83
84double RooParamHistFunc::getActual(Int_t ibin)
85{
86 return (static_cast<RooAbsReal&>(_p[ibin])).getVal() ;
87}
88
89////////////////////////////////////////////////////////////////////////////////
90
91void RooParamHistFunc::setActual(Int_t ibin, double newVal)
92{
93 (static_cast<RooRealVar&>(_p[ibin])).setVal(newVal) ;
94}
95
96////////////////////////////////////////////////////////////////////////////////
97
98double RooParamHistFunc::getNominal(Int_t ibin) const
99{
100 return _dh.weight(ibin) ;
101}
102
103////////////////////////////////////////////////////////////////////////////////
104
105double RooParamHistFunc::getNominalError(Int_t ibin) const
106{
107 _dh.get(ibin) ;
108 return _dh.weightError() ;
109}
110
111////////////////////////////////////////////////////////////////////////////////
112/// Return sampling hint for making curves of (projections) of this function
113/// as the recursive division strategy of RooCurve cannot deal efficiently
114/// with the vertical lines that occur in a non-interpolated histogram
115
116std::list<double>* RooParamHistFunc::plotSamplingHint(RooAbsRealLValue& obs, double xlo, double xhi) const
117{
118 // Check that observable is in dataset, if not no hint is generated
119 RooAbsLValue* lvarg = dynamic_cast<RooAbsLValue*>(_dh.get()->find(obs.GetName())) ;
120 if (!lvarg) {
121 return nullptr ;
122 }
123
124 // Retrieve position of all bin boundaries
125 const RooAbsBinning* binning = lvarg->getBinningPtr(nullptr);
126 double* boundaries = binning->array() ;
127
128 std::list<double>* hint = new std::list<double> ;
129
130 // Widen range slightly
131 xlo = xlo - 0.01*(xhi-xlo) ;
132 xhi = xhi + 0.01*(xhi-xlo) ;
133
134 double delta = (xhi-xlo)*1e-8 ;
135
136 // Construct array with pairs of points positioned epsilon to the left and
137 // right of the bin boundaries
138 for (Int_t i=0 ; i<binning->numBoundaries() ; i++) {
139 if (boundaries[i]>=xlo && boundaries[i]<=xhi) {
140 hint->push_back(boundaries[i]-delta) ;
141 hint->push_back(boundaries[i]+delta) ;
142 }
143 }
144
145 return hint ;
146}
147
148////////////////////////////////////////////////////////////////////////////////
149/// Return sampling hint for making curves of (projections) of this function
150/// as the recursive division strategy of RooCurve cannot deal efficiently
151/// with the vertical lines that occur in a non-interpolated histogram
152
153std::list<double>* RooParamHistFunc::binBoundaries(RooAbsRealLValue& obs, double xlo, double xhi) const
154{
155 // Check that observable is in dataset, if not no hint is generated
156 RooAbsLValue* lvarg = dynamic_cast<RooAbsLValue*>(_dh.get()->find(obs.GetName())) ;
157 if (!lvarg) {
158 return nullptr ;
159 }
160
161 // Retrieve position of all bin boundaries
162 const RooAbsBinning* binning = lvarg->getBinningPtr(nullptr);
163 double* boundaries = binning->array() ;
164
165 std::list<double>* hint = new std::list<double> ;
166
167 // Construct array with pairs of points positioned epsilon to the left and
168 // right of the bin boundaries
169 for (Int_t i=0 ; i<binning->numBoundaries() ; i++) {
170 if (boundaries[i]>=xlo && boundaries[i]<=xhi) {
171 hint->push_back(boundaries[i]) ;
172 }
173 }
174
175 return hint ;
176}
177
178////////////////////////////////////////////////////////////////////////////////
179/// Advertise that all integrals can be handled internally.
180
181Int_t RooParamHistFunc::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars,
182 const RooArgSet* /*normSet*/, const char* /*rangeName*/) const
183{
184 // Simplest scenario, integrate over all dependents
185 std::unique_ptr<RooAbsCollection> allVarsCommon{allVars.selectCommon(_x)};
186 bool intAllObs = (allVarsCommon->size()==_x.size()) ;
187 if (intAllObs && matchArgs(allVars,analVars,_x)) {
188 return 1 ;
189 }
190
191 return 0 ;
192}
193
194////////////////////////////////////////////////////////////////////////////////
195/// Implement analytical integrations by doing appropriate weighting from component integrals
196/// functions to integrators of components
197
198double RooParamHistFunc::analyticalIntegralWN(Int_t code, const RooArgSet* /*normSet2*/,const char* rangeName) const
199{
200 // Supports only the scenario of integration over all dependents
201 R__ASSERT(code==1) ;
202
203 // The logic for summing over the histogram is borrowed from RooHistPdf with some differences:
204 //
205 // - a lambda function is used to inject the parameters for bin scaling into the RooDataHist::sum method
206 //
207 // - for simplicity, there is no check for the possibility of full-range integration with another overload of
208 // RooDataHist::sum
209 std::map<const RooAbsArg*, std::pair<double, double> > ranges;
210 for (const auto obs : _x) {
211 ranges[obs] = RooHelpers::getRangeOrBinningInterval(obs, rangeName);
212 }
213
214 auto getBinScale = [&](int iBin){ return static_cast<const RooAbsReal&>(_p[iBin]).getVal(); };
215
216 RooArgSet sliceSet{};
217 return const_cast<RooDataHist&>(_dh).sum(_x, sliceSet, true, false, ranges, getBinScale);
218}
#define e(i)
Definition RSha256.hxx:103
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:139
char name[80]
Definition TGX11.cxx:142
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2571
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:77
Abstract base class for RooRealVar binning definitions.
virtual Int_t numBoundaries() const =0
virtual double * array() const =0
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Abstract base class for objects that are lvalues, i.e.
virtual const RooAbsBinning * getBinningPtr(const char *rangeName) const =0
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
void setConstant(bool value=true)
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:63
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:107
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
RooArgSet * selectCommon(const RooAbsCollection &refColl) const
Use RooAbsCollection::selecCommon(), but return as RooArgSet.
Definition RooArgSet.h:154
Container class to hold N-dimensional binned data.
Definition RooDataHist.h:40
Variable that can be changed from the outside.
Definition RooRealVar.h:37
void setVal(double value) override
Set value of variable to 'value'.
void setError(double value)
Definition RooRealVar.h:61
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
Double_t x[n]
Definition legend1.C:17
std::pair< double, double > getRangeOrBinningInterval(RooAbsArg const *arg, const char *rangeName)
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2335