Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooHistConstraint.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 RooHistConstraint
12 * \ingroup Roofit
13 *
14 * \deprecated RooHistConstraint will be removed in ROOT 6.46, because its functionality is too close to the
15 * HistFactory classes. Please constrain the parameters of the HistFactory class ParamHistFunc with one RooPoisson
16 * per bin instead, as shown in the rf709_BarlowBeeston tutorial.
17 *
18 * The RooHistConstraint implements constraint terms for a binned PDF with statistical uncertainties.
19 * Following the Barlow-Beeston method, it adds Poisson constraints for each bin that
20 * constrain the statistical uncertainty of the template histogram.
21 *
22 * It can therefore be used to estimate the Monte Carlo uncertainty of a fit.
23 *
24 */
25
26#include <RooHistConstraint.h>
27
28#include <RooParamHistFunc.h>
29#include <RooRealVar.h>
30
32
33// RooHistConstraint is deprecated together with RooParamHistFunc, which it is
34// built on, so its implementation necessarily refers to the deprecated class.
35#ifdef _MSC_VER
36#pragma warning(push)
37#pragma warning(disable : 4996)
38#else
39#pragma GCC diagnostic push
40#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
41#endif
42
43////////////////////////////////////////////////////////////////////////////////
44/// Create a new RooHistConstraint.
45/// \param[in] name Name of the PDF. This is used to identify it in a likelihood model.
46/// \param[in] title Title for plotting etc.
47/// \param[in] phfSet Set of parametrised histogram functions (RooParamHistFunc).
48/// \param[in] threshold Threshold (bin content) up to which statistical uncertainties are taken into account.
49RooHistConstraint::RooHistConstraint(const char *name, const char *title,
50 const RooArgSet& phfSet, int threshold) :
51 RooAbsPdf(name,title),
52 _gamma("gamma","gamma",this),
53 _nominal("nominal","nominal",this),
54 _relParam(true)
55{
56 // Implementing constraint on sum of RooParamHists
57 //
58 // Step 1 - Create new gamma parameters for sum
59 // Step 2 - Replace entries in gamma listproxy of components with new sum components
60 // Step 3 - Implement constraints in terms of gamma sum parameters
61
62
63 if (phfSet.size()==1) {
64
65 auto phf = dynamic_cast<RooParamHistFunc*>(phfSet.first()) ;
66
67 if (!phf) {
68 coutE(InputArguments) << "RooHistConstraint::ctor(" << GetName()
69 << ") ERROR: input object must be a RooParamHistFunc" << std::endl ;
70 throw std::string("RooHistConstraint::ctor ERROR incongruent input arguments") ;
71 }
72
73 // Now populate nominal with parameters
74 for (int i=0 ; i<phf->_dh.numEntries() ; i++) {
75 const double wi = phf->_dh.weight(i) ;
76 if (wi<threshold && wi != 0.) {
77 const char* vname = Form("%s_nominal_bin_%i",GetName(),i) ;
78 auto var = std::make_unique<RooRealVar>(vname,vname,0,1.E30);
79 var->setVal(wi) ;
80 var->setConstant(true);
81
82 auto gamma = static_cast<RooRealVar*>(phf->_p.at(i));
83 if (var->getVal() > 0.0) {
84 gamma->setConstant(false);
85 }
86
87 _nominal.addOwned(std::move(var)) ;
88 _gamma.add(*gamma) ;
89 }
90 }
91
92 return ;
93 }
94
95
96
97 int nbins(-1) ;
98 std::vector<RooParamHistFunc*> phvec ;
99 RooArgSet gammaSet ;
100 std::string bin0_name ;
101 for (const auto arg : phfSet) {
102
103 auto phfComp = dynamic_cast<RooParamHistFunc*>(arg) ;
104 if (phfComp) {
105 phvec.push_back(phfComp) ;
106 if (nbins==-1) {
107 nbins = phfComp->_p.size() ;
108 bin0_name = phfComp->_p.at(0)->GetName() ;
109 gammaSet.add(phfComp->_p) ;
110 } else {
111 if (int(phfComp->_p.size())!=nbins) {
112 coutE(InputArguments) << "RooHistConstraint::ctor(" << GetName()
113 << ") ERROR: incongruent input arguments: all input RooParamHistFuncs should have same #bins" << std::endl ;
114 throw std::string("RooHistConstraint::ctor ERROR incongruent input arguments") ;
115 }
116 if (bin0_name != phfComp->_p.at(0)->GetName()) {
117 coutE(InputArguments) << "RooHistConstraint::ctor(" << GetName()
118 << ") ERROR: incongruent input arguments: all input RooParamHistFuncs should have the same bin parameters.\n"
119 << "Previously found " << bin0_name << ", now found " << phfComp->_p.at(0)->GetName() << ".\n"
120 << "Check that the right RooParamHistFuncs have been passed to this RooHistConstraint." << std::endl;
121 throw std::string("RooHistConstraint::ctor ERROR incongruent input arguments") ;
122 }
123
124 }
125 } else {
126 coutW(InputArguments) << "RooHistConstraint::ctor(" << GetName()
127 << ") WARNING: ignoring input argument " << arg->GetName() << " which is not of type RooParamHistFunc" << std::endl;
128 }
129 }
130
131 _gamma.add(gammaSet) ;
132
133 // Now populate nominal and nominalErr with parameters
134 for (int i=0 ; i<nbins ; i++) {
135
136 double sumVal(0) ;
137 for (const auto phfunc : phvec) {
138 sumVal += phfunc->getNominal(i);
139 }
140
141 if (sumVal<threshold && sumVal != 0.) {
142
143 const char* vname = Form("%s_nominal_bin_%i",GetName(),i) ;
144 auto var = std::make_unique<RooRealVar>(vname,vname,0,1000);
145
146 double sumVal2(0) ;
147 for(auto const& elem : phvec) {
148 sumVal2 += elem->getNominal(i) ;
149 }
150 var->setVal(sumVal2) ;
151 var->setConstant(true) ;
152
153 vname = Form("%s_nominal_error_bin_%i",GetName(),i) ;
154 //RooRealVar* vare = new RooRealVar(vname,vname,0,1000) ;
155
156 //double sumErr2(0) ;
157 //for(auto const& elem : phvec) {
158 //sumErr2 += std::pow(elem->getNominalError(i),2) ;
159 //}
160 //vare->setVal(sqrt(sumErr2)) ;
161 //vare->setConstant(true) ;
162
163 _nominal.addOwned(std::move(var));
164 // _nominalErr.add(*vare) ;
165
166 (static_cast<RooRealVar*>(_gamma.at(i)))->setConstant(false) ;
167
168 }
169 }
170}
171
172////////////////////////////////////////////////////////////////////////////////
173
174 RooHistConstraint::RooHistConstraint(const RooHistConstraint& other, const char* name) :
175 RooAbsPdf(other,name),
176 _gamma("gamma",this,other._gamma),
177 _nominal("nominal",this,other._nominal),
178 _relParam(other._relParam)
179 {
180 }
181
182////////////////////////////////////////////////////////////////////////////////
183
184 double RooHistConstraint::evaluate() const
185 {
186 double prod(1.0);
187
188 for (unsigned int i=0; i < _nominal.size(); ++i) {
189 const auto& gamma = static_cast<const RooAbsReal&>(_gamma[i]);
190 const auto& nominal = static_cast<const RooAbsReal&>(_nominal[i]);
191 double gammaVal = gamma.getVal();
192 const int nomVal = static_cast<int>(nominal.getVal());
193
194 if (_relParam) {
195 gammaVal *= nomVal;
196 }
197
198 if (gammaVal>0) {
199 const double pois = ROOT::Math::poisson_pdf(nomVal, gammaVal);
200 prod *= pois;
201 } else if (nomVal > 0) {
202 coutE(Eval) << "ERROR in RooHistConstraint: gamma=0 and nom>0" << std::endl;
203 }
204 }
205
206 return prod;
207 }
208
209////////////////////////////////////////////////////////////////////////////////
210
211double RooHistConstraint::getLogVal(const RooArgSet* /*set*/) const
212{
213 double sum = 0.;
214 for (unsigned int i=0; i < _nominal.size(); ++i) {
215 const auto& gamma = static_cast<const RooAbsReal&>(_gamma[i]);
216 const auto& nominal = static_cast<const RooAbsReal&>(_nominal[i]);
217 double gammaVal = gamma.getVal();
218 const int nomVal = static_cast<int>(nominal.getVal());
219
220 if (_relParam) {
221 gammaVal *= nomVal;
222 }
223
224 if (gammaVal>0) {
225 const double logPoisson = nomVal * log(gammaVal) - gammaVal - std::lgamma(nomVal + 1);
226 sum += logPoisson ;
227 } else if (nomVal > 0) {
228 coutE(Eval) << "ERROR in RooHistConstraint: gamma=0 and nom>0" << std::endl;
229 }
230 }
231
232 return sum ;
233}
234
235#ifdef _MSC_VER
236#pragma warning(pop)
237#else
238#pragma GCC diagnostic pop
239#endif
#define coutW(a)
#define coutE(a)
char name[80]
Definition TGX11.cxx:142
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2571
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Storage_t::size_type size() const
RooAbsArg * first() const
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
Variable that can be changed from the outside.
Definition RooRealVar.h:37
double poisson_pdf(unsigned int n, double mu)
Probability density function of the Poisson distribution.
RVec< PromoteType< T > > log(const RVec< T > &v)
Definition RVec.hxx:1821
double gamma(double x)
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2335