Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
BayesianCalculator.cxx
Go to the documentation of this file.
1// @(#)root/roostats:$Id$
2// Author: Kyle Cranmer, Lorenzo Moneta, Gregory Schott, Wouter Verkerke
3/*************************************************************************
4 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11
12/** \class RooStats::BayesianCalculator
13 \ingroup Roostats
14
15BayesianCalculator is a concrete implementation of IntervalCalculator, providing the computation
16of a credible interval using a Bayesian method.
17The class works only for one single parameter of interest and it integrates the likelihood function with the given prior
18probability density function to compute the posterior probability. The result of the class is a one dimensional interval
19(class SimpleInterval ), which is obtained from inverting the cumulative posterior distribution.
20This calculator works then only for model with a single parameter of interest.
21The model can instead have several nuisance parameters which are integrated (marginalized) in the computation of the posterior function.
22The integration and normalization of the posterior is computed using numerical integration methods provided by ROOT.
23See the MCMCCalculator for model with multiple parameters of interest.
24
25The interface allows one to construct the class by passing the data set, probability density function for the model, the prior
26functions and then the parameter of interest to scan. The nuisance parameters can also be passed to be marginalized when
27computing the posterior. Alternatively, the class can be constructed by passing the data and the ModelConfig containing
28all the needed information (model pdf, prior pdf, parameter of interest, nuisance parameters, etc..)
29
30After configuring the calculator, one only needs to ask GetInterval(), which
31will return an SimpleInterval object. By default the extreme of the integral are obtained by inverting directly the
32cumulative posterior distribution. By using the method SetScanOfPosterior(nbins) the interval is then obtained by
33scanning the posterior function in the given number of points. The first method is in general faster but it requires an
34integration one extra dimension ( in the poi in addition to the nuisance parameters), therefore in some case it can be
35less robust.
36
37The class can also return the posterior function (method GetPosteriorFunction) or if needed the normalized
38posterior function (the posterior pdf) (method GetPosteriorPdf). A posterior plot is also obtained using
39the GetPosteriorPlot method.
40
41The class allows to use different integration methods for integrating in (marginalizing) the nuisances and in the poi. All the numerical
42integration methods of ROOT can be used via the method SetIntegrationType (see more in the documentation of
43this method).
44
45Calculator estimating a credible interval using the Bayesian procedure.
46The calculator computes given the model the posterior distribution and estimates the
47credible interval from the given function.
48*/
49
50
51// include other header files
52
53#include "RooAbsFunc.h"
54#include "RooAbsReal.h"
55#include "RooRealVar.h"
56#include "RooArgSet.h"
57#include "RooBrentRootFinder.h"
58#include "RooFormulaVar.h"
59#include "RooGenericPdf.h"
60#include "RooPlot.h"
61#include "RooProdPdf.h"
62#include "RooDataSet.h"
63
64// include header file of this class
68
69#include "Math/IFunction.h"
71#include "Math/Integrator.h"
72#include "Math/RootFinder.h"
74#include "RooFunctor.h"
75#include "RooFunctor1DBinding.h"
76#include "RooTFnBinding.h"
77#include "RooMsgService.h"
78
79#include "TAxis.h"
80#include "TF1.h"
81#include "TH1.h"
82#include "TMath.h"
83
84#include <map>
85#include <cmath>
86#include <memory>
87
88#include "RConfigure.h"
89
91
92using namespace std;
93
94namespace RooStats {
95
96
97// first some utility classes and functions
98
99#ifdef R__HAS_MATHMORE
101#else
103#endif
104
105
106
107
109 LikelihoodFunction(RooFunctor & f, RooFunctor * prior = nullptr, double offset = 0) :
110 fFunc(f), fPrior(prior),
112 {
114 }
115
116 void SetPrior(RooFunctor * prior) { fPrior = prior; }
117
118 double operator() (const double *x ) const {
119 double nll = fFunc(x) - fOffset;
120 double likelihood = std::exp(-nll);
121
122 if (fPrior) likelihood *= (*fPrior)(x);
123
124 int nCalls = fFunc.binding().numCall();
125 if (nCalls > 0 && nCalls % 1000 == 0) {
126 ooccoutD(nullptr,Eval) << "Likelihood evaluation ncalls = " << nCalls
127 << " x0 " << x[0] << " nll = " << nll+fOffset;
128 if (fPrior) ooccoutD(nullptr,Eval) << " prior(x) = " << (*fPrior)(x);
129 ooccoutD(nullptr,Eval) << " likelihood " << likelihood
130 << " max Likelihood " << fMaxL << std::endl;
131 }
132
133 if (likelihood > fMaxL ) {
134 fMaxL = likelihood;
135 if ( likelihood > 1.E10) {
136 ooccoutW(nullptr,Eval) << "LikelihoodFunction::() WARNING - Huge likelihood value found for parameters ";
137 for (int i = 0; i < fFunc.nObs(); ++i)
138 ooccoutW(nullptr,Eval) << " x[" << i << " ] = " << x[i];
139 ooccoutW(nullptr,Eval) << " nll = " << nll << " L = " << likelihood << std::endl;
140 }
141 }
142
143 return likelihood;
144 }
145
146 // for the 1D case
147 double operator() (double x) const {
148 // just call the previous method
149 assert(fFunc.nObs() == 1); // check nobs = 1
150 double tmp = x;
151 return (*this)(&tmp);
152 }
153
154 RooFunctor & fFunc; // functor representing the nll function
155 RooFunctor * fPrior; // functor representing the prior function
156 double fOffset; // offset used to bring the nll in a reasonable range for computing the exponent
157 mutable double fMaxL = 0;
158};
159
160
161// Posterior CDF Function class
162// for integral of posterior function in nuisance and POI
163// 1-Dim function as function of the poi
164
166
167public:
168
169 PosteriorCdfFunction(RooAbsReal & nll, RooArgList & bindParams, RooAbsReal * prior = nullptr, const char * integType = nullptr, double nllMinimum = 0) :
170 fFunctor(nll, bindParams, RooArgList() ), // functor
171 fPriorFunc(nullptr),
172 fLikelihood(fFunctor, nullptr, nllMinimum), // integral of exp(-nll) function
173 fIntegrator(ROOT::Math::IntegratorMultiDim::GetType(integType) ), // integrator
174 fXmin(bindParams.size()), // vector of parameters (min values)
175 fXmax(bindParams.size())
176 {
177 if (prior) {
178 fPriorFunc = std::make_shared<RooFunctor>(*prior, bindParams, RooArgList());
180 }
181
182 fIntegrator.SetFunction(fLikelihood, bindParams.size() );
183
184 ooccoutD(nullptr,NumIntegration) << "PosteriorCdfFunction::Compute integral of posterior in nuisance and poi. "
185 << " nllMinimum is " << nllMinimum << std::endl;
186
187 std::vector<double> par(bindParams.size());
188 for (unsigned int i = 0; i < fXmin.size(); ++i) {
189 RooRealVar & var = static_cast<RooRealVar &>( bindParams[i]);
190 fXmin[i] = var.getMin();
191 fXmax[i] = var.getMax();
192 par[i] = var.getVal();
193 ooccoutD(nullptr,NumIntegration) << "PosteriorFunction::Integrate" << var.GetName()
194 << " in interval [ " << fXmin[i] << " , " << fXmax[i] << " ] " << std::endl;
195 }
196
197 fIntegrator.Options().Print(ooccoutD(nullptr,NumIntegration));
198
199 // store max POI value because it will be changed when evaluating the function
200 fMaxPOI = fXmax[0];
201
202 // compute first the normalization with the poi
203 fNorm = (*this)( fMaxPOI );
204 if (fError) ooccoutE(nullptr,NumIntegration) << "PosteriorFunction::Error computing normalization - norm = " << fNorm << std::endl;
205 fHasNorm = true;
206 fNormCdfValues.insert(std::make_pair(fXmin[0], 0) );
207 fNormCdfValues.insert(std::make_pair(fXmax[0], 1.0) );
208
209 }
210
211 // copy constructor (needed for Cloning the object)
212 // need special treatment because integrator
213 // has no copy constructor
215 ROOT::Math::IGenFunction(),
216 fFunctor(rhs.fFunctor),
217 //fPriorFunc(std::shared_ptr<RooFunctor>((RooFunctor*)0)),
220 fIntegrator(ROOT::Math::IntegratorMultiDim::GetType( rhs.fIntegrator.Name().c_str() ) ), // integrator
221 fXmin( rhs.fXmin),
222 fXmax( rhs.fXmax),
223 fNorm( rhs.fNorm),
224 fNormErr( rhs.fNormErr),
225 fOffset(rhs.fOffset),
226 fMaxPOI(rhs.fMaxPOI),
227 fHasNorm(rhs.fHasNorm),
229 fError(rhs.fError),
231 {
233 // need special treatment for the smart pointer
234 // if (rhs.fPriorFunc.get() ) {
235 // fPriorFunc = std::shared_ptr<RooFunctor>(new RooFunctor(*(rhs.fPriorFunc) ) );
236 // fLikelihood.SetPrior( fPriorFunc.get() );
237 // }
238 }
239
240
241 bool HasError() const { return fError; }
242
243
244 ROOT::Math::IGenFunction * Clone() const override {
245 ooccoutD(nullptr,NumIntegration) << " cloning function .........." << std::endl;
246 return new PosteriorCdfFunction(*this);
247 }
248
249 // offset value for computing the root
250 void SetOffset(double offset) { fOffset = offset; }
251
252private:
253
254 // make assignment operator private
256 return *this;
257 }
258
259 double DoEval (double x) const override {
260
261 // evaluate cdf at poi value x by integrating poi from [xmin,x] and all the nuisances
262 fXmax[0] = x;
263 if (x <= fXmin[0] ) return -fOffset;
264 // could also avoid a function evaluation at maximum
265 if (x >= fMaxPOI && fHasNorm) return 1. - fOffset; // cdf is bound to these values
266
267 // computes the integral using a previous cdf estimate
268 double normcdf0 = 0;
269 if (fHasNorm && fUseOldValues) {
270 // look in the map of the stored cdf values the closes one
271 std::map<double,double>::iterator itr = fNormCdfValues.upper_bound(x);
272 --itr; // upper bound returns a position 1 up of the value we want
273 if (itr != fNormCdfValues.end() ) {
274 fXmin[0] = itr->first;
275 normcdf0 = itr->second;
276 // ooccoutD(nullptr,NumIntegration) << "PosteriorCdfFunction: computing integral between in poi interval : "
277 // << fXmin[0] << " - " << fXmax[0] << std::endl;
278 }
279 }
280
281 fFunctor.binding().resetNumCall(); // reset number of calls for debug
282
283 double cdf = fIntegrator.Integral(&fXmin[0],&fXmax[0]);
284 double error = fIntegrator.Error();
285 double normcdf = cdf/fNorm; // normalize the cdf
286
287 ooccoutD(nullptr,NumIntegration) << "PosteriorCdfFunction: poi = [" << fXmin[0] << " , "
288 << fXmax[0] << "] integral = " << cdf << " +/- " << error
289 << " norm-integ = " << normcdf << " cdf(x) = " << normcdf+normcdf0
290 << " ncalls = " << fFunctor.binding().numCall() << std::endl;
291
292 if (TMath::IsNaN(cdf) || cdf > std::numeric_limits<double>::max()) {
293 ooccoutE(nullptr,NumIntegration) << "PosteriorFunction::Error computing integral - cdf = "
294 << cdf << std::endl;
295 fError = true;
296 }
297
298 if (cdf != 0 && error / cdf > 0.2) {
299 oocoutW(nullptr, NumIntegration)
300 << "PosteriorCdfFunction: integration error is larger than 20 % x0 = " << fXmin[0] << " x = " << x
301 << " cdf(x) = " << cdf << " +/- " << error << std::endl;
302 }
303
304 if (!fHasNorm) {
305 oocoutI(nullptr,NumIntegration) << "PosteriorCdfFunction - integral of posterior = "
306 << cdf << " +/- " << error << std::endl;
307 fNormErr = error;
308 return cdf;
309 }
310
311 normcdf += normcdf0;
312
313 // store values in the map
314 if (fUseOldValues) {
315 fNormCdfValues.insert(std::make_pair(x, normcdf) );
316 }
317
318 double errnorm = sqrt( error*error + normcdf*normcdf * fNormErr * fNormErr )/fNorm;
319 if (normcdf > 1. + 3 * errnorm) {
320 oocoutW(nullptr,NumIntegration) << "PosteriorCdfFunction: normalized cdf values is larger than 1"
321 << " x = " << x << " normcdf(x) = " << normcdf << " +/- " << error/fNorm << std::endl;
322 }
323
324 return normcdf - fOffset; // apply an offset (for finding the roots)
325 }
326
327 mutable RooFunctor fFunctor; // functor binding nll
328 mutable std::shared_ptr<RooFunctor> fPriorFunc; // functor binding the prior
329 LikelihoodFunction fLikelihood; // likelihood function
330 mutable ROOT::Math::IntegratorMultiDim fIntegrator; // integrator (mutable because Integral() is not const
331 mutable std::vector<double> fXmin; // min value of parameters (poi+nuis) -
332 mutable std::vector<double> fXmax; // max value of parameters (poi+nuis) - max poi changes so it is mutable
333 double fNorm = 1.0; // normalization value (computed in ctor)
334 mutable double fNormErr = 0.0; // normalization error value (computed in ctor)
335 double fOffset = 0; // offset for computing the root
336 double fMaxPOI = 0; // maximum value of POI
337 bool fHasNorm = false; // flag to control first call to the function
338 bool fUseOldValues = true; // use old cdf values
339 mutable bool fError = false; // flag to indicate if a numerical evaluation error occurred
340 mutable std::map<double,double> fNormCdfValues;
341};
342
343//__________________________________________________________________
344// Posterior Function class
345// 1-Dim function as function of the poi
346// and it integrated all the nuisance parameters
347
349
350public:
351
352
353 PosteriorFunction(RooAbsReal & nll, RooRealVar & poi, RooArgList & nuisParams, RooAbsReal * prior = nullptr, const char * integType = nullptr, double
354 norm = 1.0, double nllOffset = 0, int niter = 0) :
355 fFunctor(nll, nuisParams, RooArgList() ),
356 fPriorFunc(nullptr),
357 fLikelihood(fFunctor, nullptr, nllOffset),
358 fPoi(&poi),
359 fXmin(nuisParams.size()),
360 fXmax(nuisParams.size()),
361 fNorm(norm)
362 {
363
364 if (prior) {
365 fPriorFunc = std::make_shared<RooFunctor>(*prior, nuisParams, RooArgList());
367 }
368
369 ooccoutD(nullptr,NumIntegration) << "PosteriorFunction::Evaluate the posterior function by integrating the nuisances: " << std::endl;
370 for (unsigned int i = 0; i < fXmin.size(); ++i) {
371 RooRealVar & var = static_cast<RooRealVar &>( nuisParams[i]);
372 fXmin[i] = var.getMin();
373 fXmax[i] = var.getMax();
374 ooccoutD(nullptr,NumIntegration) << "PosteriorFunction::Integrate " << var.GetName()
375 << " in interval [" << fXmin[i] << " , " << fXmax[i] << " ] " << std::endl;
376 }
377 if (fXmin.size() == 1) { // 1D case
378 fIntegratorOneDim = std::make_unique<ROOT::Math::Integrator>( ROOT::Math::IntegratorOneDim::GetType(integType) );
379
380 fIntegratorOneDim->SetFunction(fLikelihood);
381 // interested only in relative tolerance
382 //fIntegratorOneDim->SetAbsTolerance(1.E-300);
383 fIntegratorOneDim->Options().Print(ooccoutD(nullptr,NumIntegration) );
384 }
385 else if (fXmin.size() > 1) { // multiDim case
386 fIntegratorMultiDim = std::make_unique<ROOT::Math::IntegratorMultiDim>(ROOT::Math::IntegratorMultiDim::GetType(integType));
387 fIntegratorMultiDim->SetFunction(fLikelihood, fXmin.size());
389 if (niter > 0) {
390 opt.SetNCalls(niter);
391 fIntegratorMultiDim->SetOptions(opt);
392 }
393 //fIntegratorMultiDim->SetAbsTolerance(1.E-300);
394 // print the options
395 opt.Print(ooccoutD(nullptr,NumIntegration) );
396 }
397 }
398
399
400 ROOT::Math::IGenFunction * Clone() const override {
401 assert(1);
402 return nullptr; // cannot clone this function for integrator
403 }
404
405 double Error() const { return fError;}
406
407
408private:
409 double DoEval (double x) const override {
410
411 // evaluate posterior function at a poi value x by integrating all nuisance parameters
412
413 fPoi->setVal(x);
414 fFunctor.binding().resetNumCall(); // reset number of calls for debug
415
416 double f = 0;
417 double error = 0;
418 if (fXmin.size() == 1) { // 1D case
419 f = fIntegratorOneDim->Integral(fXmin[0],fXmax[0]);
420 error = fIntegratorOneDim->Error();
421 }
422 else if (fXmin.size() > 1) { // multi-dim case
423 f = fIntegratorMultiDim->Integral(&fXmin[0],&fXmax[0]);
424 error = fIntegratorMultiDim->Error();
425 } else {
426 // no integration to be done
427 f = fLikelihood(x);
428 }
429
430 // debug
431 ooccoutD(nullptr,NumIntegration) << "PosteriorFunction: POI value = "
432 << x << "\tf(x) = " << f << " +/- " << error
433 << " norm-f(x) = " << f/fNorm
434 << " ncalls = " << fFunctor.binding().numCall() << std::endl;
435
436 if (f != 0 && error / f > 0.2) {
437 ooccoutW(nullptr, NumIntegration)
438 << "PosteriorFunction::DoEval - Error from integration in " << fXmin.size() << " Dim is larger than 20 % "
439 << "x = " << x << " p(x) = " << f << " +/- " << error << std::endl;
440 }
441
442 fError = error / fNorm;
443 return f / fNorm;
444 }
445
447 mutable std::shared_ptr<RooFunctor> fPriorFunc; // functor binding the prior
450 std::unique_ptr<ROOT::Math::Integrator> fIntegratorOneDim;
451 std::unique_ptr<ROOT::Math::IntegratorMultiDim> fIntegratorMultiDim;
452 std::vector<double> fXmin;
453 std::vector<double> fXmax;
454 double fNorm;
455 mutable double fError = 0;
456};
457
458////////////////////////////////////////////////////////////////////////////////
459/// Posterior function obtaining sampling toy MC for the nuisance according to their pdf
460
462
463public:
465 RooAbsReal *prior = nullptr, double nllOffset = 0, int niter = 0, bool redoToys = true)
466 : fFunctor(nll, nuisParams, RooArgList()),
467 fPriorFunc(nullptr),
468 fLikelihood(fFunctor, nullptr, nllOffset),
469 fPdf(&pdf),
470 fPoi(&poi),
471 fNuisParams(nuisParams),
472 fNumIterations(niter),
473
474 fRedoToys(redoToys)
475 {
476 if (niter == 0) fNumIterations = 100; // default value
477
478 if (prior) {
479 fPriorFunc = std::make_shared<RooFunctor>(*prior, nuisParams, RooArgList());
481 }
482
483 ooccoutI(nullptr,InputArguments) << "PosteriorFunctionFromToyMC::Evaluate the posterior function by randomizing the nuisances: niter " << fNumIterations << std::endl;
484
485 ooccoutI(nullptr,InputArguments) << "PosteriorFunctionFromToyMC::Pdf used for randomizing the nuisance is " << fPdf->GetName() << std::endl;
486 // check that pdf contains the nuisance
487 std::unique_ptr<RooArgSet> vars{fPdf->getVariables()};
488 for (std::size_t i = 0; i < fNuisParams.size(); ++i) {
489 if (!vars->find( fNuisParams[i].GetName() ) ) {
490 ooccoutW(nullptr,InputArguments) << "Nuisance parameter " << fNuisParams[i].GetName()
491 << " is not part of sampling pdf. "
492 << "they will be treated as constant " << std::endl;
493 }
494 }
495
496 if (!fRedoToys) {
497 ooccoutI(nullptr,InputArguments) << "PosteriorFunctionFromToyMC::Generate nuisance toys only one time (for all POI points)" << std::endl;
498 GenerateToys();
499 }
500 }
501
502 // generate first n-samples of the nuisance parameters
503 void GenerateToys() const {
504 fGenParams = std::unique_ptr<RooDataSet>{fPdf->generate(fNuisParams, fNumIterations)};
505 if(fGenParams==nullptr) {
506 ooccoutE(nullptr,InputArguments) << "PosteriorFunctionFromToyMC - failed to generate nuisance parameters" << std::endl;
507 }
508 }
509
510 double Error() const { return fError;}
511
512 ROOT::Math::IGenFunction * Clone() const override {
513 // use default copy constructor
514 //return new PosteriorFunctionFromToyMC(*this);
515 // clone not implemented
516 assert(1);
517 return nullptr;
518 }
519
520private:
521 // evaluate the posterior at the poi value x
522 double DoEval( double x) const override {
523
524 int npar = fNuisParams.size();
525 assert (npar > 0);
526
527
528 // generate the toys
529 if (fRedoToys) GenerateToys();
530 if (!fGenParams) return 0;
531
532 // evaluate posterior function at a poi value x by integrating all nuisance parameters
533
534 fPoi->setVal(x);
535
536 // loop over all of the generate data
537 double sum = 0;
538 double sum2 = 0;
539
540 for(int iter=0; iter<fNumIterations; ++iter) {
541
542 // get the set of generated parameters and set the nuisance parameters to the generated values
543 std::vector<double> p(npar);
544 for (int i = 0; i < npar; ++i) {
545 const RooArgSet* genset=fGenParams->get(iter);
546 RooAbsArg * arg = genset->find( fNuisParams[i].GetName() );
547 RooRealVar * var = dynamic_cast<RooRealVar*>(arg);
548 assert(var != nullptr);
549 p[i] = var->getVal();
550 (static_cast<RooRealVar &>( fNuisParams[i])).setVal(p[i]);
551 }
552
553 // evaluate now the likelihood function
554 double fval = fLikelihood( &p.front() );
555
556 // likelihood already must contained the pdf we have sampled
557 // so we must divided by it. The value must be normalized on all
558 // other parameters
560 double nuisPdfVal = fPdf->getVal(&arg);
561 fval /= nuisPdfVal;
562
563
564 if( fval > std::numeric_limits<double>::max() ) {
565 ooccoutE(nullptr,Eval) << "BayesianCalculator::EvalPosteriorFunctionFromToy : "
566 << "Likelihood evaluates to infinity " << std::endl;
567 ooccoutE(nullptr,Eval) << "poi value = " << x << std::endl;
568 ooccoutE(nullptr,Eval) << "Nuisance parameter values : ";
569 for (int i = 0; i < npar; ++i)
570 ooccoutE(nullptr,Eval) << fNuisParams[i].GetName() << " = " << p[i] << " ";
571 ooccoutE(nullptr,Eval) << " - return 0 " << std::endl;
572
573 fError = 1.E30;
574 return 0;
575 }
576 if( TMath::IsNaN(fval) ) {
577 ooccoutE(nullptr,Eval) << "BayesianCalculator::EvalPosteriorFunctionFromToy : "
578 << "Likelihood is a NaN " << std::endl;
579 ooccoutE(nullptr,Eval) << "poi value = " << x << std::endl;
580 ooccoutE(nullptr,Eval) << "Nuisance parameter values : ";
581 for (int i = 0; i < npar; ++i)
582 ooccoutE(nullptr,Eval) << fNuisParams[i].GetName() << " = " << p[i] << " ";
583 ooccoutE(nullptr,Eval) << " - return 0 " << std::endl;
584 fError = 1.E30;
585 return 0;
586 }
587
588
589
590 sum += fval;
591 sum2 += fval*fval;
592 }
593
594 // compute the average and variance
595 double val = sum/double(fNumIterations);
596 double dval2 = std::max( sum2/double(fNumIterations) - val*val, 0.0);
597 fError = std::sqrt( dval2 / fNumIterations);
598
599 // debug
600 ooccoutD(nullptr,NumIntegration) << "PosteriorFunctionFromToyMC: POI value = "
601 << x << "\tp(x) = " << val << " +/- " << fError << std::endl;
602
603
604 if (val != 0 && fError/val > 0.2 ) {
605 ooccoutW(nullptr,NumIntegration) << "PosteriorFunctionFromToyMC::DoEval"
606 << " - Error in estimating posterior is larger than 20% ! "
607 << "x = " << x << " p(x) = " << val << " +/- " << fError << std::endl;
608 }
609
610
611 return val;
612 }
613
615 mutable std::shared_ptr<RooFunctor> fPriorFunc; // functor binding the prior
617 mutable RooAbsPdf * fPdf;
620 mutable std::unique_ptr<RooDataSet> fGenParams;
622 mutable double fError = -1;
623 bool fRedoToys; // do toys every iteration
624
625};
626
627////////////////////////////////////////////////////////////////////////////////
628// Implementation of BayesianCalculator
629////////////////////////////////////////////////////////////////////////////////
630
631////////////////////////////////////////////////////////////////////////////////
632/// default constructor
633
635 fData(nullptr),
636 fPdf(nullptr),
637 fPriorPdf(nullptr),
638 fNuisancePdf(nullptr),
639 fProductPdf (nullptr), fLikelihood (nullptr), fIntegratedLikelihood (nullptr), fPosteriorPdf(nullptr),
640 fPosteriorFunction(nullptr), fApproxPosterior(nullptr),
641 fLower(0), fUpper(0),
642 fNLLMin(0),
643 fSize(0.05), fLeftSideFraction(0.5),
644 fBrfPrecision(0.00005),
645 fNScanBins(-1),
646 fNumIterations(0),
647 fValidInterval(false)
648{
649}
650
651////////////////////////////////////////////////////////////////////////////////
652/// Constructor from data set, model pdf, parameter of interests and prior pdf
653/// If nuisance parameters are given they will be integrated according either to the prior or
654/// their constraint term included in the model
655
656BayesianCalculator::BayesianCalculator( /* const char* name, const char* title, */
658 RooAbsPdf& pdf,
659 const RooArgSet& POI,
660 RooAbsPdf& priorPdf,
661 const RooArgSet* nuisanceParameters ) :
662 fData(&data),
663 fPdf(&pdf),
664 fPOI(POI),
665 fPriorPdf(&priorPdf),
666 fNuisancePdf(nullptr),
667 fProductPdf (nullptr), fLikelihood (nullptr), fIntegratedLikelihood (nullptr), fPosteriorPdf(nullptr),
668 fPosteriorFunction(nullptr), fApproxPosterior(nullptr),
669 fLower(0), fUpper(0),
670 fNLLMin(0),
671 fSize(0.05), fLeftSideFraction(0.5),
672 fBrfPrecision(0.00005),
673 fNScanBins(-1),
674 fNumIterations(0),
675 fValidInterval(false)
676{
677
678 if (nuisanceParameters) fNuisanceParameters.add(*nuisanceParameters);
679 // remove constant nuisance parameters
681}
682
683////////////////////////////////////////////////////////////////////////////////
684/// Constructor from a data set and a ModelConfig
685/// model pdf, poi and nuisances will be taken from the ModelConfig
686
688 ModelConfig & model) :
689 fData(&data),
690 fPdf(model.GetPdf()),
691 fPriorPdf( model.GetPriorPdf()),
692 fNuisancePdf(nullptr),
693 fProductPdf (nullptr), fLikelihood (nullptr), fIntegratedLikelihood (nullptr), fPosteriorPdf(nullptr),
694 fPosteriorFunction(nullptr), fApproxPosterior(nullptr),
695 fLower(0), fUpper(0),
696 fNLLMin(0),
697 fSize(0.05), fLeftSideFraction(0.5),
698 fBrfPrecision(0.00005),
699 fNScanBins(-1),
700 fNumIterations(0),
701 fValidInterval(false)
702{
703 SetModel(model);
704}
705
706
708{
709 // destructor
710 ClearAll();
711}
712
713////////////////////////////////////////////////////////////////////////////////
714/// clear all cached pdf objects
715
717 if (fProductPdf) delete fProductPdf;
718 fLogLike.reset();
719 if (fLikelihood) delete fLikelihood;
721 if (fPosteriorPdf) delete fPosteriorPdf;
724 fPosteriorPdf = nullptr;
725 fPosteriorFunction = nullptr;
726 fProductPdf = nullptr;
727 fLikelihood = nullptr;
728 fIntegratedLikelihood = nullptr;
729 fLower = 0;
730 fUpper = 0;
731 fNLLMin = 0;
732 fValidInterval = false;
733}
734
735////////////////////////////////////////////////////////////////////////////////
736/// set the model to use
737/// The model pdf, prior pdf, parameter of interest and nuisances
738/// will be taken according to the model
739
741
742 fPdf = model.GetPdf();
743 fPriorPdf = model.GetPriorPdf();
744 // assignment operator = does not do a real copy the sets (must use add method)
745 fPOI.removeAll();
749 if (model.GetParametersOfInterest()) fPOI.add( *(model.GetParametersOfInterest()) );
752 if (model.GetGlobalObservables()) fGlobalObs.add( *(model.GetGlobalObservables() ) );
753 // remove constant nuisance parameters
755
756 // invalidate the cached pointers
757 ClearAll();
758}
759
760////////////////////////////////////////////////////////////////////////////////
761/// Build and return the posterior function (not normalized) as a RooAbsReal
762/// the posterior is obtained from the product of the likelihood function and the
763/// prior pdf which is then integrated in the nuisance parameters (if existing).
764/// A prior function for the nuisance can be specified either in the prior pdf object
765/// or in the model itself. If no prior nuisance is specified, but prior parameters are then
766/// the integration is performed assuming a flat prior for the nuisance parameters.
767///
768/// NOTE: the return object is managed by the BayesianCalculator class, users do not need to delete it,
769/// but the object will be deleted when the BayesiabCalculator object is deleted
770
772{
773
775 if (fLikelihood) return fLikelihood;
776
777 // run some sanity checks
778 if (!fPdf ) {
779 coutE(InputArguments) << "BayesianCalculator::GetPosteriorPdf - missing pdf model" << std::endl;
780 return nullptr;
781 }
782 if (fPOI.empty()) {
783 coutE(InputArguments) << "BayesianCalculator::GetPosteriorPdf - missing parameter of interest" << std::endl;
784 return nullptr;
785 }
786 if (fPOI.size() > 1) {
787 coutE(InputArguments) << "BayesianCalculator::GetPosteriorPdf - current implementation works only on 1D intervals" << std::endl;
788 return nullptr;
789 }
790
791
792 std::unique_ptr<RooArgSet> constrainedParams{fPdf->getParameters(*fData)};
793 // remove the constant parameters
794 RemoveConstantParameters(&*constrainedParams);
795
796 //constrainedParams->Print("V");
797
798 // use RooFit::Constrain() to be sure constraints terms are taken into account
800
801
802
803 ccoutD(Eval) << "BayesianCalculator::GetPosteriorFunction : "
804 << " pdf value " << fPdf->getVal()
805 << " neglogLikelihood = " << fLogLike->getVal() << std::endl;
806
807 if (fPriorPdf)
808 ccoutD(Eval) << "\t\t\t priorPOI value " << fPriorPdf->getVal() << std::endl;
809
810 // check that likelihood evaluation is not infinity
811 double nllVal = fLogLike->getVal();
812 if ( nllVal > std::numeric_limits<double>::max() ) {
813 coutE(Eval) << "BayesianCalculator::GetPosteriorFunction : "
814 << " Negative log likelihood evaluates to infinity " << std::endl
815 << " Non-const Parameter values : ";
816 RooArgList p(*constrainedParams);
817 for (std::size_t i = 0; i < p.size(); ++i) {
818 RooRealVar * v = dynamic_cast<RooRealVar *>(&p[i] );
819 if (v!=nullptr) ccoutE(Eval) << v->GetName() << " = " << v->getVal() << " ";
820 }
821 ccoutE(Eval) << std::endl;
822 ccoutE(Eval) << "-- Perform a full likelihood fit of the model before or set more reasonable parameter values"
823 << std::endl;
824 coutE(Eval) << "BayesianCalculator::GetPosteriorFunction : " << " cannot compute posterior function " << std::endl;
825 return nullptr;
826 }
827
828
829
830 // need do find minimum of log-likelihood in the range to shift function
831 // to avoid numerical errors when we compute the likelihood (overflows in the exponent)
832 // N.B.: this works for only 1 parameter of interest otherwise Minuit should be used for finding the minimum
833 RooFunctor * nllFunc = fLogLike->functor(fPOI);
834 assert(nllFunc);
835 ROOT::Math::Functor1D wnllFunc(*nllFunc);
836 RooRealVar* poi = dynamic_cast<RooRealVar*>(fPOI.first() );
837 assert(poi);
838
839 // try to reduce some error messages
840 //bool silentMode = (RooMsgService::instance().globalKillBelow() >= RooFit::ERROR || RooMsgService::instance().silentMode()) ;
842
843
844 coutI(Eval) << "BayesianCalculator::GetPosteriorFunction : "
845 << " nll value " << nllVal << " poi value = " << poi->getVal() << std::endl;
846
847
849 minim.SetFunction(wnllFunc,poi->getMin(),poi->getMax() );
850 bool ret = minim.Minimize(100,1.E-3,1.E-3);
851 fNLLMin = 0;
852 if (ret) fNLLMin = minim.FValMinimum();
853
854 coutI(Eval) << "BayesianCalculator::GetPosteriorFunction : minimum of NLL vs POI for POI = "
855 << poi->getVal() << " min NLL = " << fNLLMin << std::endl;
856
857 delete nllFunc;
858
859
860 if ( fNuisanceParameters.empty() || fIntegrationType.Contains("ROOFIT") ) {
861
862 ccoutD(Eval) << "BayesianCalculator::GetPosteriorFunction : use ROOFIT integration "
863 << std::endl;
864
865#ifdef DOLATER // (not clear why this does not work)
866 // need to make in this case a likelihood from the nll and make the product with the prior
867 TString likeName = TString("likelihood_times_prior_") + TString(fPriorPdf->GetName());
868 TString formula;
869 formula.Form("exp(-@0+%f+log(@1))",fNLLMin);
870 fLikelihood = new RooFormulaVar(likeName,formula,RooArgList(*fLogLike,*fPriorPdf));
871#else
872 // here use RooProdPdf (not very nice) but working
873
874 if (fLogLike) fLogLike.reset();
875 if (fProductPdf) {
876 delete fProductPdf;
877 fProductPdf = nullptr;
878 }
879
880 // // create a unique name for the product pdf
881 RooAbsPdf * pdfAndPrior = fPdf;
882 if (fPriorPdf) {
883 TString prodName = TString("product_") + TString(fPdf->GetName()) + TString("_") + TString(fPriorPdf->GetName() );
884 // save this as data member since it needs to be deleted afterwards
885 fProductPdf = new RooProdPdf(prodName,"",RooArgList(*fPdf,*fPriorPdf));
886 pdfAndPrior = fProductPdf;
887 }
888
889 std::unique_ptr<RooArgSet> constrParams{fPdf->getParameters(*fData)};
890 // remove the constant parameters
891 RemoveConstantParameters(&*constrParams);
893
894 TString likeName = TString("likelihood_times_prior_") + TString(pdfAndPrior->GetName());
895 TString formula;
896 formula.Form("exp(-@0+%f)",fNLLMin);
897 fLikelihood = new RooFormulaVar(likeName,formula,RooArgList(*fLogLike));
898#endif
899
900
901 // if no nuisance parameter we can just return the likelihood function
904 fLikelihood = nullptr;
905 } else {
906 // case of using RooFit for the integration
908 std::unique_ptr<RooAbsReal>{fLikelihood->createIntegral(fNuisanceParameters)}.release();
909 }
910
911 }
912
913 else if ( fIntegrationType.Contains("TOYMC") ) {
914 // compute the posterior as expectation values of the likelihood function
915 // sampling on the nuisance parameters
916
918
919 bool doToysEveryIteration = true;
920 // if type is 1-TOYMC or TOYMC-1
921 if ( fIntegrationType.Contains("1") || fIntegrationType.Contains("ONE") ) doToysEveryIteration = false;
922
923 RooAbsPdf * samplingPdf = (fNuisancePdf) ? fNuisancePdf : fPdf;
924 if (!fNuisancePdf) {
925 ccoutI(Eval) << "BayesianCalculator::GetPosteriorFunction : no nuisance pdf is provided, try using global pdf (this will be slower)"
926 << std::endl;
927 }
928 fPosteriorFunction = new PosteriorFunctionFromToyMC(*fLogLike, *samplingPdf, *poi, nuisParams, fPriorPdf, fNLLMin,
929 fNumIterations, doToysEveryIteration );
930
931 TString name = "toyposteriorfunction_from_";
932 name += fLogLike->GetName();
934
935 // need to scan likelihood in this case
936 if (fNScanBins <= 0) fNScanBins = 100;
937
938 }
939
940 else {
941
942 // use ROOT integration method if there are nuisance parameters
943
946
947 TString name = "posteriorfunction_from_";
948 name += fLogLike->GetName();
950
951 }
952
953 if (RooAbsReal::numEvalErrors() > 0) {
954 coutW(Eval) << "BayesianCalculator::GetPosteriorFunction : " << RooAbsReal::numEvalErrors()
955 << " errors reported in evaluating log-likelihood function " << std::endl;
956 }
959
961
962}
963
964////////////////////////////////////////////////////////////////////////////////
965/// Build and return the posterior pdf (i.e posterior function normalized to all range of poi)
966/// Note that an extra integration in the POI is required for the normalization
967/// NOTE: user must delete the returned object
968
970{
971
973 if (!plike) return nullptr;
974
975
976 // create a unique name on the posterior from the names of the components
977 TString posteriorName = this->GetName() + TString("_posteriorPdf_") + plike->GetName();
978
979 RooAbsPdf * posteriorPdf = new RooGenericPdf(posteriorName,"@0",*plike);
980
981 return posteriorPdf;
982}
983
984////////////////////////////////////////////////////////////////////////////////
985/// When am approximate posterior is computed binninig the parameter of interest (poi) range
986/// (see SetScanOfPosteriors) an histogram is created and can be returned to the user
987/// A nullptr is instead returned when the posterior is computed without binning the poi.
988///
989/// NOTE: the returned object is managed by the BayesianCalculator class,
990/// if the user wants to take ownership of the returned histogram, he needs to clone
991/// or copy the return object.
992
994{
995 return (fApproxPosterior) ? fApproxPosterior->GetHistogram() : nullptr;
996}
997
998
999////////////////////////////////////////////////////////////////////////////////
1000/// return a RooPlot with the posterior and the credibility region
1001/// NOTE: User takes ownership of the returned object
1002
1003RooPlot* BayesianCalculator::GetPosteriorPlot(bool norm, double precision ) const
1004{
1005
1007
1008 // if a scan is requested approximate the posterior
1009 if (fNScanBins > 0)
1011
1012 RooAbsReal * posterior = fIntegratedLikelihood;
1013 if (norm) {
1014 // delete and re-do always posterior pdf (could be invalid after approximating it)
1015 if (fPosteriorPdf) delete fPosteriorPdf;
1017 posterior = fPosteriorPdf;
1018 }
1019 if (!posterior) return nullptr;
1020
1022
1023 RooAbsRealLValue* poi = dynamic_cast<RooAbsRealLValue*>(fPOI.first() );
1024 assert(poi);
1025
1026
1027 RooPlot* plot = poi->frame();
1028 if (!plot) return nullptr;
1029
1030 // try to reduce some error messages
1032
1033 plot->SetTitle(TString("Posterior probability of parameter \"")+TString(poi->GetName())+TString("\""));
1035 posterior->plotOn(plot);
1036 plot->GetYaxis()->SetTitle("posterior function");
1037
1038 // reset the counts and default mode
1041
1042 return plot;
1043}
1044
1045////////////////////////////////////////////////////////////////////////////////
1046/// set the integration type (possible type are) :
1047///
1048/// - 1D integration ( used when only one nuisance and when the posterior is scanned):
1049/// adaptive , gauss, nonadaptive
1050/// - multidim:
1051/// - ADAPTIVE, adaptive numerical integration
1052/// The parameter numIters (settable with SetNumIters) is the max number of function calls.
1053/// It can be reduced to make the integration faster but it will be difficult to reach the required tolerance
1054/// - VEGAS MC integration method based on importance sampling - numIters is number of function calls
1055/// Extra Vegas parameter can be set using IntegratorMultiDimOptions class
1056/// - MISER MC integration method based on stratified sampling
1057/// See also http://en.wikipedia.org/wiki/Monte_Carlo_integration for VEGAS and MISER description
1058/// - PLAIN simple MC integration method, where the max number of calls can be specified using SetNumIters(numIters)
1059///
1060/// Extra integration types are:
1061///
1062/// - TOYMC:
1063/// evaluate posterior by generating toy MC for the nuisance parameters. It is a MC
1064/// integration, where the function is sampled according to the nuisance. It is convenient to use when all
1065/// the nuisance are uncorrelated and it is efficient to generate them
1066/// The toy are generated by default for each poi values
1067/// (this method has been proposed and provided by J.P Chou)
1068/// - 1-TOYMC : same method as before but in this case the toys are generated only one time and then used for
1069/// each poi value. It can be convenient when the generation time is much larger than the evaluation time,
1070/// otherwise it is recommended to re-generate the toy for each poi scanned point of the posterior function
1071/// - ROOFIT:
1072/// use roofit default integration methods which will produce a nested integral (not recommended for more
1073/// than 1 nuisance parameters)
1074
1076 // if type = 0 use default specified via class IntegratorMultiDimOptions::SetDefaultIntegrator
1079}
1080
1081////////////////////////////////////////////////////////////////////////////////
1082/// Compute the interval. By Default a central interval is computed
1083/// and the result is a SimpleInterval object.
1084///
1085/// Using the method (to be called before SetInterval) SetLeftSideTailFraction the user can choose the type of interval.
1086/// By default the returned interval is a central interval with the confidence level specified
1087/// previously in the constructor ( LeftSideTailFraction = 0.5).
1088/// - For lower limit use SetLeftSideTailFraction = 1
1089/// - For upper limit use SetLeftSideTailFraction = 0
1090/// - for shortest intervals use SetLeftSideTailFraction = -1 or call the method SetShortestInterval()
1091///
1092/// NOTE: The BayesianCalculator covers only the case with one
1093/// single parameter of interest
1094///
1095/// NOTE: User takes ownership of the returned object
1096
1098{
1099
1100 if (fValidInterval)
1101 coutW(Eval) << "BayesianCalculator::GetInterval - recomputing interval for the same CL and same model" << std::endl;
1102
1103 RooRealVar* poi = dynamic_cast<RooRealVar*>(fPOI.first() );
1104 if (!poi) {
1105 coutE(Eval) << "BayesianCalculator::GetInterval - no parameter of interest is set " << std::endl;
1106 return nullptr;
1107 }
1108
1109
1110
1111 // get integrated likelihood (posterior function)
1113
1114 //bool silentMode = (RooMsgService::instance().globalKillBelow() >= RooFit::ERROR || RooMsgService::instance().silentMode()) ;
1116
1117 if (fLeftSideFraction < 0 ) {
1118 // compute short intervals
1120 }
1121 else {
1122 // compute the other intervals
1123
1124 double lowerCutOff = fLeftSideFraction * fSize;
1125 double upperCutOff = 1. - (1.- fLeftSideFraction) * fSize;
1126
1127
1128 if (fNScanBins > 0) {
1129 ComputeIntervalFromApproxPosterior(lowerCutOff, upperCutOff);
1130 }
1131
1132 else {
1133 // use integration method if there are nuisance parameters
1134 if (!fNuisanceParameters.empty()) {
1135 ComputeIntervalFromCdf(lowerCutOff, upperCutOff);
1136 }
1137 else {
1138 // case of no nuisance - just use createCdf from roofit
1139 ComputeIntervalUsingRooFit(lowerCutOff, upperCutOff);
1140 }
1141 // case cdf failed (scan then the posterior)
1142 if (!fValidInterval) {
1143 fNScanBins = 100;
1144 coutW(Eval) << "BayesianCalculator::GetInterval - computing integral from cdf failed - do a scan in "
1145 << fNScanBins << " nbins " << std::endl;
1146 ComputeIntervalFromApproxPosterior(lowerCutOff, upperCutOff);
1147 }
1148 }
1149 }
1150
1151
1152 // reset the counts and default mode
1153 if (RooAbsReal::numEvalErrors() > 0) {
1154 coutW(Eval) << "BayesianCalculator::GetInterval : " << RooAbsReal::numEvalErrors()
1155 << " errors reported in evaluating log-likelihood function " << std::endl;
1156 }
1157
1160
1161 if (!fValidInterval) {
1162 fLower = 1; fUpper = 0;
1163 coutE(Eval) << "BayesianCalculator::GetInterval - cannot compute a valid interval - return a dummy [1,0] interval"
1164 << std::endl;
1165 }
1166 else {
1167 coutI(Eval) << "BayesianCalculator::GetInterval - found a valid interval : [" << fLower << " , "
1168 << fUpper << " ]" << std::endl;
1169 }
1170
1171 TString interval_name = TString("BayesianInterval_a") + TString(this->GetName());
1172 SimpleInterval * interval = new SimpleInterval(interval_name,*poi,fLower,fUpper,ConfidenceLevel());
1173 interval->SetTitle("SimpleInterval from BayesianCalculator");
1174
1175 return interval;
1176}
1177
1178////////////////////////////////////////////////////////////////////////////////
1179/// Returns the value of the parameter for the point in
1180/// parameter-space that is the most likely.
1181/// How do we do if there are points that are equi-probable?
1182/// use approximate posterior
1183/// t.b.d use real function to find the mode
1184
1186
1189 return h->GetBinCenter(h->GetMaximumBin() );
1190 //return fApproxPosterior->GetMaximumX();
1191}
1192
1193////////////////////////////////////////////////////////////////////////////////
1194/// internal function compute the interval using RooFit
1195
1196void BayesianCalculator::ComputeIntervalUsingRooFit(double lowerCutOff, double upperCutOff ) const {
1197
1198 coutI(Eval) << "BayesianCalculator: Compute interval using RooFit: posteriorPdf + createCdf + RooBrentRootFinder " << std::endl;
1199
1200 RooRealVar* poi = dynamic_cast<RooRealVar*>(fPOI.first() );
1201 assert(poi);
1202
1203 fValidInterval = false;
1205 if (!fPosteriorPdf) return;
1206
1207 std::unique_ptr<RooAbsReal> cdf{fPosteriorPdf->createCdf(fPOI,RooFit::ScanNoCdf())};
1208 if (!cdf) return;
1209
1210 std::unique_ptr<RooAbsFunc> cdf_bind{cdf->bindVars(fPOI,&fPOI)};
1211 if (!cdf_bind) return;
1212
1213 RooBrentRootFinder brf(*cdf_bind);
1214 brf.setTol(fBrfPrecision); // set the brf precision
1215
1216 double tmpVal = poi->getVal(); // patch used because findRoot changes the value of poi
1217
1218 bool ret = true;
1219 if (lowerCutOff > 0) {
1220 double y = lowerCutOff;
1221 ret &= brf.findRoot(fLower,poi->getMin(),poi->getMax(),y);
1222 }
1223 else
1224 fLower = poi->getMin();
1225
1226 if (upperCutOff < 1.0) {
1227 double y=upperCutOff;
1228 ret &= brf.findRoot(fUpper,poi->getMin(),poi->getMax(),y);
1229 }
1230 else
1231 fUpper = poi->getMax();
1232 if (!ret) {
1233 coutE(Eval) << "BayesianCalculator::GetInterval "
1234 << "Error returned from Root finder, estimated interval is not fully correct" << std::endl;
1235 } else {
1236 fValidInterval = true;
1237 }
1238
1239 poi->setVal(tmpVal); // patch: restore the original value of poi
1240}
1241
1242////////////////////////////////////////////////////////////////////////////////
1243/// internal function compute the interval using Cdf integration
1244
1245void BayesianCalculator::ComputeIntervalFromCdf(double lowerCutOff, double upperCutOff ) const {
1246
1247 fValidInterval = false;
1248
1249 coutI(InputArguments) << "BayesianCalculator:GetInterval Compute the interval from the posterior cdf " << std::endl;
1250
1251 RooRealVar* poi = dynamic_cast<RooRealVar*>(fPOI.first() );
1252 assert(poi);
1253 if (GetPosteriorFunction() == nullptr) {
1254 coutE(InputArguments) << "BayesianCalculator::GetInterval() cannot make posterior Function " << std::endl;
1255 return;
1256 }
1257
1258 // need to remove the constant parameters
1259 RooArgList bindParams;
1260 bindParams.add(fPOI);
1261 bindParams.add(fNuisanceParameters);
1262
1263 // this code could be put inside the PosteriorCdfFunction
1264
1265 //bindParams.Print("V");
1266
1268 if( cdf.HasError() ) {
1269 coutE(Eval) << "BayesianCalculator: Numerical error computing CDF integral - try a different method " << std::endl;
1270 return;
1271 }
1272
1273 //find the roots
1274
1276
1277 ccoutD(Eval) << "BayesianCalculator::GetInterval - finding roots of posterior using RF " << rf.Name()
1278 << " with precision = " << fBrfPrecision;
1279
1280 if (lowerCutOff > 0) {
1281 cdf.SetOffset(lowerCutOff);
1282 ccoutD(NumIntegration) << "Integrating posterior to get cdf and search lower limit at p =" << lowerCutOff << std::endl;
1283 bool ok = rf.Solve(cdf, poi->getMin(),poi->getMax() , 200,fBrfPrecision, fBrfPrecision);
1284 if( cdf.HasError() )
1285 coutW(Eval) << "BayesianCalculator: Numerical error integrating the CDF " << std::endl;
1286 if (!ok) {
1287 coutE(NumIntegration) << "BayesianCalculator::GetInterval - Error from root finder when searching lower limit !" << std::endl;
1288 return;
1289 }
1290 fLower = rf.Root();
1291 }
1292 else {
1293 fLower = poi->getMin();
1294 }
1295 if (upperCutOff < 1.0) {
1296 cdf.SetOffset(upperCutOff);
1297 ccoutD(NumIntegration) << "Integrating posterior to get cdf and search upper interval limit at p =" << upperCutOff << std::endl;
1298 bool ok = rf.Solve(cdf, fLower,poi->getMax() , 200, fBrfPrecision, fBrfPrecision);
1299 if( cdf.HasError() )
1300 coutW(Eval) << "BayesianCalculator: Numerical error integrating the CDF " << std::endl;
1301 if (!ok) {
1302 coutE(NumIntegration) << "BayesianCalculator::GetInterval - Error from root finder when searching upper limit !" << std::endl;
1303 return;
1304 }
1305 fUpper = rf.Root();
1306 }
1307 else {
1308 fUpper = poi->getMax();
1309 }
1310
1311 fValidInterval = true;
1312}
1313
1314////////////////////////////////////////////////////////////////////////////////
1315/// approximate posterior in nbins using a TF1
1316/// scan the poi values and evaluate the posterior at each point
1317/// and save the result in a cloned TF1
1318/// For each point the posterior is evaluated by integrating the nuisance
1319/// parameters
1320
1322
1323 if (fApproxPosterior) {
1324 // if number of bins of existing function is >= requested one - no need to redo the scan
1325 if (fApproxPosterior->GetNpx() >= fNScanBins) return;
1326 // otherwise redo the scan
1327 delete fApproxPosterior;
1328 fApproxPosterior = nullptr;
1329 }
1330
1331
1332 RooAbsReal * posterior = GetPosteriorFunction();
1333 if (!posterior) return;
1334
1335
1336 TF1 * tmp = posterior->asTF(fPOI);
1337 assert(tmp != nullptr);
1338 // binned the function in nbins and evaluate at those points
1339 if (fNScanBins > 0) tmp->SetNpx(fNScanBins); // if not use default of TF1 (which is 100)
1340
1341 coutI(Eval) << "BayesianCalculator - scan posterior function in nbins = " << tmp->GetNpx() << std::endl;
1342
1343 fApproxPosterior = static_cast<TF1*>(tmp->Clone());
1344 // save this function for future reuse
1345 // I can delete now original posterior and use this approximated copy
1346 delete tmp;
1347 TString name = posterior->GetName() + TString("_approx");
1348 TString title = posterior->GetTitle() + TString("_approx");
1349 RooAbsReal * posterior2 = new RooTFnBinding(name,title,fApproxPosterior,fPOI);
1350 if (posterior == fIntegratedLikelihood) {
1351 delete fIntegratedLikelihood;
1352 fIntegratedLikelihood = posterior2;
1353 }
1354 else if (posterior == fLikelihood) {
1355 delete fLikelihood;
1356 fLikelihood = posterior2;
1357 }
1358 else {
1359 assert(1); // should never happen this case
1360 }
1361}
1362
1363////////////////////////////////////////////////////////////////////////////////
1364/// compute the interval using the approximate posterior function
1365
1366void BayesianCalculator::ComputeIntervalFromApproxPosterior(double lowerCutOff, double upperCutOff ) const {
1367
1368 ccoutD(Eval) << "BayesianCalculator: Compute interval from the approximate posterior " << std::endl;
1369
1371 if (!fApproxPosterior) return;
1372
1373 double prob[2];
1374 double limits[2] = {0,0};
1375 prob[0] = lowerCutOff;
1376 prob[1] = upperCutOff;
1377 fApproxPosterior->GetQuantiles(2,limits,prob);
1378 fLower = limits[0];
1379 fUpper = limits[1];
1380 fValidInterval = true;
1381}
1382
1383////////////////////////////////////////////////////////////////////////////////
1384/// compute the shortest interval from the histogram representing the posterior
1385
1386
1388 coutI(Eval) << "BayesianCalculator - computing shortest interval with CL = " << 1.-fSize << std::endl;
1389
1390 // compute via the approx posterior function
1392 if (!fApproxPosterior) return;
1393
1394 TH1D * h1 = dynamic_cast<TH1D*>(fApproxPosterior->GetHistogram() );
1395 assert(h1 != nullptr);
1397 // get bins and sort them
1398 double * bins = h1->GetArray();
1399 // exclude under/overflow bins
1400 int n = h1->GetSize()-2;
1401 std::vector<int> index(n);
1402 // exclude bins[0] (the underflow bin content)
1403 TMath::Sort(n, bins+1, &index[0]);
1404 // find cut off as test size
1405 double sum = 0;
1406 double actualCL = 0;
1407 double upper = h1->GetXaxis()->GetXmin();
1408 double lower = h1->GetXaxis()->GetXmax();
1409 double norm = h1->GetSumOfWeights();
1410
1411 for (int i = 0; i < n; ++i) {
1412 int idx = index[i];
1413 double p = bins[ idx] / norm;
1414 sum += p;
1415 if (sum > 1.-fSize ) {
1416 actualCL = sum - p;
1417 break;
1418 }
1419
1420 // histogram bin content starts from 1
1421 if ( h1->GetBinLowEdge(idx+1) < lower)
1422 lower = h1->GetBinLowEdge(idx+1);
1423 if ( h1->GetXaxis()->GetBinUpEdge(idx+1) > upper)
1424 upper = h1->GetXaxis()->GetBinUpEdge(idx+1);
1425 }
1426
1427 ccoutD(Eval) << "BayesianCalculator::ComputeShortestInterval - actual interval CL = "
1428 << actualCL << " difference from requested is " << (actualCL-(1.-fSize))/fSize*100. << "% "
1429 << " limits are [ " << lower << " , " << " upper ] " << std::endl;
1430
1431
1432 if (lower < upper) {
1433 fLower = lower;
1434 fUpper = upper;
1435
1436 if (std::abs(actualCL - (1. - fSize)) > 0.1 * (1. - fSize)) {
1437 coutW(Eval) << "BayesianCalculator::ComputeShortestInterval - actual interval CL = " << actualCL
1438 << " differs more than 10% from desired CL value - must increase nbins " << n
1439 << " to an higher value " << std::endl;
1440 }
1441 }
1442 else
1443 coutE(Eval) << "BayesianCalculator::ComputeShortestInterval " << n << " bins are not sufficient " << std::endl;
1444
1445 fValidInterval = true;
1446
1447}
1448
1449
1450
1451
1452} // end namespace RooStats
size_t fSize
#define f(i)
Definition RSha256.hxx:104
#define h(i)
Definition RSha256.hxx:106
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define coutI(a)
#define ccoutE(a)
#define oocoutW(o, a)
#define coutW(a)
#define oocoutI(o, a)
#define coutE(a)
#define ooccoutW(o, a)
#define ooccoutI(o, a)
#define ooccoutD(o, a)
#define ccoutI(a)
#define ccoutD(a)
#define ooccoutE(o, a)
#define ClassImp(name)
Definition Rtypes.h:377
@ kGray
Definition Rtypes.h:65
winID h TVirtualViewer3D TVirtualGLPainter p
winID h TVirtualViewer3D TVirtualGLPainter char TVirtualGLPainter plot
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 Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
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 Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:110
User class for performing function minimization.
void SetFunction(const ROOT::Math::IGenFunction &f, double xlow, double xup)
Sets function to be minimized.
bool Minimize(int maxIter, double absTol=1.E-8, double relTol=1.E-10) override
Find minimum position iterating until convergence specified by the absolute and relative tolerance or...
double FValMinimum() const override
Return function value at current estimate of the minimum.
Functor1D class for one-dimensional functions.
Definition Functor.h:95
Interface (abstract class) for generic functions objects of one-dimension Provides a method to evalua...
Definition IFunction.h:112
Numerical multi dimensional integration options.
void Print(std::ostream &os=std::cout) const
print all the options
void SetNCalls(unsigned int calls)
set maximum number of function calls
User class for performing multidimensional integration.
double Integral(const double *xmin, const double *xmax)
evaluate the integral with the previously given function between xmin[] and xmax[]
void SetFunction(Function &f, unsigned int dim)
set integration function using a generic function implementing the operator()(double *x) The dimensio...
static IntegrationMultiDim::Type GetType(const char *name)
static function to get the enumeration from a string
ROOT::Math::IntegratorMultiDimOptions Options() const
retrieve the options
double Error() const
return integration error
static IntegrationOneDim::Type GetType(const char *name)
static function to get the enumeration from a string
User Class to find the Root of one dimensional functions.
Definition RootFinder.h:73
const char * Name() const
Return the current and latest estimate of the lower value of the Root-finding interval (for bracketin...
Definition RootFinder.h:190
bool Solve(Function &f, Derivative &d, double start, int maxIter=100, double absTol=1E-8, double relTol=1E-10)
Solve f(x) = 0, given a derivative d.
Definition RootFinder.h:224
double Root() const
Return the current and latest estimate of the Root.
Definition RootFinder.h:160
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:79
RooFit::OwningPtr< RooArgSet > getParameters(const RooAbsData *data, bool stripDisconnected=true) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
RooFit::OwningPtr< RooArgSet > getVariables(bool stripDisconnected=true) const
Return RooArgSet with all variables (tree leaf nodes of expression tree)
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
Storage_t const & get() const
Const access to the underlying stl container.
const char * GetName() const override
Returns name of object.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Storage_t::size_type size() const
RooAbsArg * first() const
RooAbsArg * find(const char *name) const
Find object with given name in list.
Abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:57
void resetNumCall() const
Reset function call counter.
Definition RooAbsFunc.h:52
Int_t numCall() const
Return number of function calls since last reset.
Definition RooAbsFunc.h:47
Abstract interface for all probability density functions.
Definition RooAbsPdf.h:40
RooFit::OwningPtr< RooAbsReal > createNLL(RooAbsData &data, CmdArgs_t const &... cmdArgs)
Construct representation of -log(L) of PDF with given dataset.
Definition RooAbsPdf.h:162
RooFit::OwningPtr< RooAbsReal > createCdf(const RooArgSet &iset, const RooArgSet &nset=RooArgSet())
Create a cumulative distribution function of this p.d.f in terms of the observables listed in iset.
RooFit::OwningPtr< RooDataSet > generate(const RooArgSet &whatVars, Int_t nEvents, const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={})
See RooAbsPdf::generate(const RooArgSet&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,...
Definition RooAbsPdf.h:57
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
virtual double getMax(const char *name=nullptr) const
Get maximum of currently defined range.
virtual double getMin(const char *name=nullptr) const
Get minimum of currently defined range.
RooPlot * frame(const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
Create a new RooPlot on the heap with a drawing frame initialized for this object,...
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:59
RooFit::OwningPtr< RooAbsReal > createIntegral(const RooArgSet &iset, const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
Create an object that represents the integral of the function over one or more observables listed in ...
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:103
TF1 * asTF(const RooArgList &obs, const RooArgList &pars=RooArgList(), const RooArgSet &nset=RooArgSet()) const
Return a ROOT TF1,2,3 object bound to this RooAbsReal with given definition of observables and parame...
static Int_t numEvalErrors()
Return the number of logged evaluation errors since the last clearing.
static void setEvalErrorLoggingMode(ErrorLoggingMode m)
Set evaluation error logging mode.
static void clearEvalErrorLog()
Clear the stack of evaluation error messages.
virtual RooPlot * plotOn(RooPlot *frame, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}, const RooCmdArg &arg9={}, const RooCmdArg &arg10={}) const
Plot (project) PDF on specified frame.
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:22
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
Implement the abstract 1-dimensional root finding interface using the Brent-Decker method.
bool findRoot(double &result, double xlo, double xhi, double value=0) const
Do the root finding using the Brent-Decker method.
void setTol(double tol)
Set convergence tolerance parameter.
A RooFormulaVar is a generic implementation of a real-valued object, which takes a RooArgList of serv...
RooCFunction1Binding is a templated implementation of class RooAbsReal that binds generic C(++) funct...
Lightweight interface adaptor that exports a RooAbsPdf as a functor.
Definition RooFunctor.h:25
Int_t nObs() const
Definition RooFunctor.h:34
RooAbsFunc & binding()
Definition RooFunctor.h:51
Implementation of a probability density function that takes a RooArgList of servers and a C++ express...
Plot frame and a container for graphics objects within that frame.
Definition RooPlot.h:43
Efficient implementation of a product of PDFs of the form.
Definition RooProdPdf.h:33
Variable that can be changed from the outside.
Definition RooRealVar.h:37
void setVal(double value) override
Set value of variable to 'value'.
BayesianCalculator is a concrete implementation of IntervalCalculator, providing the computation of a...
ROOT::Math::IGenFunction * fPosteriorFunction
function representing the posterior
RooAbsReal * fLikelihood
internal pointer to likelihood function
double fNLLMin
minimum value of Nll
int fNumIterations
number of iterations (when using ToyMC)
RooAbsPdf * GetPosteriorPdf() const
return posterior pdf (object is managed by the user)
RooPlot * GetPosteriorPlot(bool norm=false, double precision=0.01) const
get the plot with option to get it normalized
int fNScanBins
number of bins to scan, if = -1 no scan is done (default)
void ClearAll() const
clear all cached pdf objects
void ComputeShortestInterval() const
compute the shortest interval from the histogram representing the posterior
RooAbsPdf * fNuisancePdf
nuisance pdf (needed when using nuisance sampling technique)
RooArgSet fConditionalObs
conditional observables
double fBrfPrecision
root finder precision
RooAbsReal * fIntegratedLikelihood
integrated likelihood function, i.e - unnormalized posterior function
void ApproximatePosterior() const
approximate posterior in nbins using a TF1 scan the poi values and evaluate the posterior at each poi...
double fSize
size used for getting the interval
RooArgSet fNuisanceParameters
nuisance parameters
double fLeftSideFraction
fraction of probability content on left side of interval
RooArgSet fGlobalObs
global observables
double GetMode() const
return the mode (most probable value of the posterior function)
RooAbsPdf * fPdf
model pdf (could contain the nuisance pdf as constraint term)
SimpleInterval * GetInterval() const override
compute the interval.
RooAbsPdf * fProductPdf
internal pointer to model * prior
TF1 * fApproxPosterior
TF1 representing the scanned posterior function.
RooAbsReal * GetPosteriorFunction() const
return posterior function (object is managed by the BayesianCalculator class)
void SetIntegrationType(const char *type)
set the integration type (possible type are) :
RooAbsPdf * fPosteriorPdf
normalized (on the poi) posterior pdf
double fUpper
upper interval bound
double fLower
computer lower interval bound
TH1 * GetPosteriorHistogram() const
return the approximate posterior as histogram (TH1 object). Note the object is managed by the Bayesia...
void ComputeIntervalFromApproxPosterior(double c1, double c2) const
compute the interval using the approximate posterior function
void SetModel(const ModelConfig &model) override
set the model via the ModelConfig
RooAbsPdf * fPriorPdf
prior pdf (typically for the POI)
std::unique_ptr< RooAbsReal > fLogLike
internal pointer to log likelihood function
double ConfidenceLevel() const override
Get the Confidence level for the test.
~BayesianCalculator() override
destructor
void ComputeIntervalUsingRooFit(double c1, double c2) const
internal function compute the interval using RooFit
void ComputeIntervalFromCdf(double c1, double c2) const
internal function compute the interval using Cdf integration
ModelConfig is a simple class that holds configuration information specifying how a model should be u...
Definition ModelConfig.h:35
const RooArgSet * GetConditionalObservables() const
get RooArgSet for conditional observables (return nullptr if not existing)
const RooArgSet * GetGlobalObservables() const
get RooArgSet for global observables (return nullptr if not existing)
const RooArgSet * GetParametersOfInterest() const
get RooArgSet containing the parameter of interest (return nullptr if not existing)
const RooArgSet * GetNuisanceParameters() const
get RooArgSet containing the nuisance parameters (return nullptr if not existing)
RooAbsPdf * GetPdf() const
get model PDF (return nullptr if pdf has not been specified or does not exist)
RooAbsPdf * GetPriorPdf() const
get parameters prior pdf (return nullptr if not existing)
std::shared_ptr< RooFunctor > fPriorFunc
PosteriorCdfFunction & operator=(const PosteriorCdfFunction &)
PosteriorCdfFunction(const PosteriorCdfFunction &rhs)
ROOT::Math::IntegratorMultiDim fIntegrator
PosteriorCdfFunction(RooAbsReal &nll, RooArgList &bindParams, RooAbsReal *prior=nullptr, const char *integType=nullptr, double nllMinimum=0)
double DoEval(double x) const override
implementation of the evaluation function. Must be implemented by derived classes
std::map< double, double > fNormCdfValues
ROOT::Math::IGenFunction * Clone() const override
Clone a function.
Posterior function obtaining sampling toy MC for the nuisance according to their pdf.
std::shared_ptr< RooFunctor > fPriorFunc
std::unique_ptr< RooDataSet > fGenParams
double DoEval(double x) const override
implementation of the evaluation function. Must be implemented by derived classes
PosteriorFunctionFromToyMC(RooAbsReal &nll, RooAbsPdf &pdf, RooRealVar &poi, RooArgList &nuisParams, RooAbsReal *prior=nullptr, double nllOffset=0, int niter=0, bool redoToys=true)
ROOT::Math::IGenFunction * Clone() const override
Clone a function.
PosteriorFunction(RooAbsReal &nll, RooRealVar &poi, RooArgList &nuisParams, RooAbsReal *prior=nullptr, const char *integType=nullptr, double norm=1.0, double nllOffset=0, int niter=0)
std::shared_ptr< RooFunctor > fPriorFunc
std::unique_ptr< ROOT::Math::IntegratorMultiDim > fIntegratorMultiDim
ROOT::Math::IGenFunction * Clone() const override
Clone a function.
double DoEval(double x) const override
implementation of the evaluation function. Must be implemented by derived classes
std::unique_ptr< ROOT::Math::Integrator > fIntegratorOneDim
SimpleInterval is a concrete implementation of the ConfInterval interface.
Use TF1, TF2, TF3 functions as RooFit objects.
const Float_t * GetArray() const
Definition TArrayF.h:43
Int_t GetSize() const
Definition TArray.h:47
Double_t GetXmax() const
Definition TAxis.h:140
Double_t GetXmin() const
Definition TAxis.h:139
virtual Double_t GetBinUpEdge(Int_t bin) const
Return up edge of bin.
Definition TAxis.cxx:528
1-Dim function class
Definition TF1.h:233
virtual TH1 * GetHistogram() const
Return a pointer to the histogram used to visualise the function Note that this histogram is managed ...
Definition TF1.cxx:1586
virtual void SetNpx(Int_t npx=100)
Set the number of points used to draw the function.
Definition TF1.cxx:3433
virtual Int_t GetQuantiles(Int_t nprobSum, Double_t *q, const Double_t *probSum)
Compute Quantiles for density distribution of this function.
Definition TF1.cxx:1994
TObject * Clone(const char *newname=nullptr) const override
Make a complete copy of the underlying object.
Definition TF1.cxx:1066
virtual Int_t GetNpx() const
Definition TF1.h:515
1-D histogram with a double per channel (see TH1 documentation)}
Definition TH1.h:621
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:58
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:8968
TAxis * GetXaxis()
Definition TH1.h:323
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:8979
void SetName(const char *name) override
Change the name of this histogram.
Definition TH1.cxx:8787
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition TH1.cxx:7788
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:164
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
Basic string class.
Definition TString.h:139
void ToUpper()
Change string to upper case.
Definition TString.cxx:1184
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2335
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:633
RooCmdArg ScanNoCdf()
RooCmdArg Constrain(const RooArgSet &params)
RooCmdArg GlobalObservables(Args_t &&... argsOrArgSet)
RooCmdArg ConditionalObservables(Args_t &&... argsOrArgSet)
Create a RooCmdArg to declare conditional observables.
RooCmdArg FillColor(Color_t color)
RooCmdArg Precision(double prec)
RooCmdArg DrawOption(const char *opt)
RooCmdArg Range(const char *rangeName, bool adjustNorm=true)
RooCmdArg MoveToBack()
RooCmdArg VLines()
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
TH1F * h1
Definition legend1.C:5
Namespace for new Math classes and functions.
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
Namespace for the RooStats classes.
Definition Asimov.h:19
void RemoveConstantParameters(RooArgSet *set)
const ROOT::Math::RootFinder::EType kRootFinderType
Bool_t IsNaN(Double_t x)
Definition TMath.h:892
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Sort the n elements of the array a of generic templated type Element.
Definition TMathBase.h:431
void SetPrior(RooFunctor *prior)
LikelihoodFunction(RooFunctor &f, RooFunctor *prior=nullptr, double offset=0)
double operator()(const double *x) const
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345