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),
111 fOffset(offset), fMaxL(0) {
113 }
114
115 void SetPrior(RooFunctor * prior) { fPrior = prior; }
116
117 double operator() (const double *x ) const {
118 double nll = fFunc(x) - fOffset;
119 double likelihood = std::exp(-nll);
120
121 if (fPrior) likelihood *= (*fPrior)(x);
122
123 int nCalls = fFunc.binding().numCall();
124 if (nCalls > 0 && nCalls % 1000 == 0) {
125 ooccoutD(nullptr,Eval) << "Likelihood evaluation ncalls = " << nCalls
126 << " x0 " << x[0] << " nll = " << nll+fOffset;
127 if (fPrior) ooccoutD(nullptr,Eval) << " prior(x) = " << (*fPrior)(x);
128 ooccoutD(nullptr,Eval) << " likelihood " << likelihood
129 << " max Likelihood " << fMaxL << std::endl;
130 }
131
132 if (likelihood > fMaxL ) {
133 fMaxL = likelihood;
134 if ( likelihood > 1.E10) {
135 ooccoutW(nullptr,Eval) << "LikelihoodFunction::() WARNING - Huge likelihood value found for parameters ";
136 for (int i = 0; i < fFunc.nObs(); ++i)
137 ooccoutW(nullptr,Eval) << " x[" << i << " ] = " << x[i];
138 ooccoutW(nullptr,Eval) << " nll = " << nll << " L = " << likelihood << std::endl;
139 }
140 }
141
142 return likelihood;
143 }
144
145 // for the 1D case
146 double operator() (double x) const {
147 // just call the previous method
148 assert(fFunc.nObs() == 1); // check nobs = 1
149 double tmp = x;
150 return (*this)(&tmp);
151 }
152
153 RooFunctor & fFunc; // functor representing the nll function
154 RooFunctor * fPrior; // functor representing the prior function
155 double fOffset; // offset used to bring the nll in a reasonable range for computing the exponent
156 mutable double fMaxL;
157};
158
159
160// Posterior CDF Function class
161// for integral of posterior function in nuisance and POI
162// 1-Dim function as function of the poi
163
165
166public:
167
168 PosteriorCdfFunction(RooAbsReal & nll, RooArgList & bindParams, RooAbsReal * prior = nullptr, const char * integType = nullptr, double nllMinimum = 0) :
169 fFunctor(nll, bindParams, RooArgList() ), // functor
170 fPriorFunc(nullptr),
171 fLikelihood(fFunctor, nullptr, nllMinimum), // integral of exp(-nll) function
172 fIntegrator(ROOT::Math::IntegratorMultiDim::GetType(integType) ), // integrator
173 fXmin(bindParams.getSize() ), // vector of parameters (min values)
174 fXmax(bindParams.getSize() ), // vector of parameter (max values)
175 fNorm(1.0), fNormErr(0.0), fOffset(0), fMaxPOI(0),
176 fHasNorm(false), fUseOldValues(true), fError(false)
177 {
178
179 if (prior) {
180 fPriorFunc = std::make_shared<RooFunctor>(*prior, bindParams, RooArgList());
182 }
183
185
186 ooccoutD(nullptr,NumIntegration) << "PosteriorCdfFunction::Compute integral of posterior in nuisance and poi. "
187 << " nllMinimum is " << nllMinimum << std::endl;
188
189 std::vector<double> par(bindParams.getSize());
190 for (unsigned int i = 0; i < fXmin.size(); ++i) {
191 RooRealVar & var = (RooRealVar &) bindParams[i];
192 fXmin[i] = var.getMin();
193 fXmax[i] = var.getMax();
194 par[i] = var.getVal();
195 ooccoutD(nullptr,NumIntegration) << "PosteriorFunction::Integrate" << var.GetName()
196 << " in interval [ " << fXmin[i] << " , " << fXmax[i] << " ] " << std::endl;
197 }
198
199 fIntegrator.Options().Print(ooccoutD(nullptr,NumIntegration));
200
201 // store max POI value because it will be changed when evaluating the function
202 fMaxPOI = fXmax[0];
203
204 // compute first the normalization with the poi
205 fNorm = (*this)( fMaxPOI );
206 if (fError) ooccoutE(nullptr,NumIntegration) << "PosteriorFunction::Error computing normalization - norm = " << fNorm << std::endl;
207 fHasNorm = true;
208 fNormCdfValues.insert(std::make_pair(fXmin[0], 0) );
209 fNormCdfValues.insert(std::make_pair(fXmax[0], 1.0) );
210
211 }
212
213 // copy constructor (needed for Cloning the object)
214 // need special treatment because integrator
215 // has no copy constructor
217 ROOT::Math::IGenFunction(),
218 fFunctor(rhs.fFunctor),
219 //fPriorFunc(std::shared_ptr<RooFunctor>((RooFunctor*)0)),
222 fIntegrator(ROOT::Math::IntegratorMultiDim::GetType( rhs.fIntegrator.Name().c_str() ) ), // integrator
223 fXmin( rhs.fXmin),
224 fXmax( rhs.fXmax),
225 fNorm( rhs.fNorm),
226 fNormErr( rhs.fNormErr),
227 fOffset(rhs.fOffset),
228 fMaxPOI(rhs.fMaxPOI),
229 fHasNorm(rhs.fHasNorm),
231 fError(rhs.fError),
233 {
235 // need special treatment for the smart pointer
236 // if (rhs.fPriorFunc.get() ) {
237 // fPriorFunc = std::shared_ptr<RooFunctor>(new RooFunctor(*(rhs.fPriorFunc) ) );
238 // fLikelihood.SetPrior( fPriorFunc.get() );
239 // }
240 }
241
242
243 bool HasError() const { return fError; }
244
245
246 ROOT::Math::IGenFunction * Clone() const override {
247 ooccoutD(nullptr,NumIntegration) << " cloning function .........." << std::endl;
248 return new PosteriorCdfFunction(*this);
249 }
250
251 // offset value for computing the root
252 void SetOffset(double offset) { fOffset = offset; }
253
254private:
255
256 // make assignment operator private
258 return *this;
259 }
260
261 double DoEval (double x) const override {
262
263 // evaluate cdf at poi value x by integrating poi from [xmin,x] and all the nuisances
264 fXmax[0] = x;
265 if (x <= fXmin[0] ) return -fOffset;
266 // could also avoid a function evaluation at maximum
267 if (x >= fMaxPOI && fHasNorm) return 1. - fOffset; // cdf is bound to these values
268
269 // computes the integral using a previous cdf estimate
270 double normcdf0 = 0;
271 if (fHasNorm && fUseOldValues) {
272 // look in the map of the stored cdf values the closes one
273 std::map<double,double>::iterator itr = fNormCdfValues.upper_bound(x);
274 --itr; // upper bound returns a position 1 up of the value we want
275 if (itr != fNormCdfValues.end() ) {
276 fXmin[0] = itr->first;
277 normcdf0 = itr->second;
278 // ooccoutD(nullptr,NumIntegration) << "PosteriorCdfFunction: computing integral between in poi interval : "
279 // << fXmin[0] << " - " << fXmax[0] << std::endl;
280 }
281 }
282
283 fFunctor.binding().resetNumCall(); // reset number of calls for debug
284
285 double cdf = fIntegrator.Integral(&fXmin[0],&fXmax[0]);
286 double error = fIntegrator.Error();
287 double normcdf = cdf/fNorm; // normalize the cdf
288
289 ooccoutD(nullptr,NumIntegration) << "PosteriorCdfFunction: poi = [" << fXmin[0] << " , "
290 << fXmax[0] << "] integral = " << cdf << " +/- " << error
291 << " norm-integ = " << normcdf << " cdf(x) = " << normcdf+normcdf0
292 << " ncalls = " << fFunctor.binding().numCall() << std::endl;
293
294 if (TMath::IsNaN(cdf) || cdf > std::numeric_limits<double>::max()) {
295 ooccoutE(nullptr,NumIntegration) << "PosteriorFunction::Error computing integral - cdf = "
296 << cdf << std::endl;
297 fError = true;
298 }
299
300 if (cdf != 0 && error/cdf > 0.2 )
301 oocoutW(nullptr,NumIntegration) << "PosteriorCdfFunction: integration error is larger than 20 % x0 = " << fXmin[0]
302 << " x = " << x << " cdf(x) = " << cdf << " +/- " << error << std::endl;
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; // normalization value (computed in ctor)
334 mutable double fNormErr; // normalization error value (computed in ctor)
335 double fOffset; // offset for computing the root
336 double fMaxPOI; // maximum value of POI
337 bool fHasNorm; // flag to control first call to the function
338 bool fUseOldValues; // use old cdf values
339 mutable bool fError; // 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.getSize() ),
360 fXmax(nuisParams.getSize() ),
361 fNorm(norm),
362 fError(0)
363 {
364
365 if (prior) {
366 fPriorFunc = std::make_shared<RooFunctor>(*prior, nuisParams, RooArgList());
368 }
369
370 ooccoutD(nullptr,NumIntegration) << "PosteriorFunction::Evaluate the posterior function by integrating the nuisances: " << std::endl;
371 for (unsigned int i = 0; i < fXmin.size(); ++i) {
372 RooRealVar & var = (RooRealVar &) nuisParams[i];
373 fXmin[i] = var.getMin();
374 fXmax[i] = var.getMax();
375 ooccoutD(nullptr,NumIntegration) << "PosteriorFunction::Integrate " << var.GetName()
376 << " in interval [" << fXmin[i] << " , " << fXmax[i] << " ] " << std::endl;
377 }
378 if (fXmin.size() == 1) { // 1D case
379 fIntegratorOneDim = std::make_unique<ROOT::Math::Integrator>( ROOT::Math::IntegratorOneDim::GetType(integType) );
380
381 fIntegratorOneDim->SetFunction(fLikelihood);
382 // interested only in relative tolerance
383 //fIntegratorOneDim->SetAbsTolerance(1.E-300);
384 fIntegratorOneDim->Options().Print(ooccoutD(nullptr,NumIntegration) );
385 }
386 else if (fXmin.size() > 1) { // multiDim case
387 fIntegratorMultiDim = std::make_unique<ROOT::Math::IntegratorMultiDim>(ROOT::Math::IntegratorMultiDim::GetType(integType));
388 fIntegratorMultiDim->SetFunction(fLikelihood, fXmin.size());
390 if (niter > 0) {
391 opt.SetNCalls(niter);
392 fIntegratorMultiDim->SetOptions(opt);
393 }
394 //fIntegratorMultiDim->SetAbsTolerance(1.E-300);
395 // print the options
396 opt.Print(ooccoutD(nullptr,NumIntegration) );
397 }
398 }
399
400
401 ROOT::Math::IGenFunction * Clone() const override {
402 assert(1);
403 return nullptr; // cannot clone this function for integrator
404 }
405
406 double Error() const { return fError;}
407
408
409private:
410 double DoEval (double x) const override {
411
412 // evaluate posterior function at a poi value x by integrating all nuisance parameters
413
414 fPoi->setVal(x);
415 fFunctor.binding().resetNumCall(); // reset number of calls for debug
416
417 double f = 0;
418 double error = 0;
419 if (fXmin.size() == 1) { // 1D case
420 f = fIntegratorOneDim->Integral(fXmin[0],fXmax[0]);
421 error = fIntegratorOneDim->Error();
422 }
423 else if (fXmin.size() > 1) { // multi-dim case
424 f = fIntegratorMultiDim->Integral(&fXmin[0],&fXmax[0]);
425 error = fIntegratorMultiDim->Error();
426 } else {
427 // no integration to be done
428 f = fLikelihood(x);
429 }
430
431 // debug
432 ooccoutD(nullptr,NumIntegration) << "PosteriorFunction: POI value = "
433 << x << "\tf(x) = " << f << " +/- " << error
434 << " norm-f(x) = " << f/fNorm
435 << " ncalls = " << fFunctor.binding().numCall() << std::endl;
436
437
438
439
440 if (f != 0 && error/f > 0.2 )
441 ooccoutW(nullptr,NumIntegration) << "PosteriorFunction::DoEval - Error from integration in "
442 << fXmin.size() << " Dim is larger than 20 % "
443 << "x = " << x << " p(x) = " << f << " +/- " << error << std::endl;
444
445 fError = error / fNorm;
446 return f / fNorm;
447 }
448
450 mutable std::shared_ptr<RooFunctor> fPriorFunc; // functor binding the prior
453 std::unique_ptr<ROOT::Math::Integrator> fIntegratorOneDim;
454 std::unique_ptr<ROOT::Math::IntegratorMultiDim> fIntegratorMultiDim;
455 std::vector<double> fXmin;
456 std::vector<double> fXmax;
457 double fNorm;
458 mutable double fError;
459};
460
461////////////////////////////////////////////////////////////////////////////////
462/// Posterior function obtaining sampling toy MC for the nuisance according to their pdf
463
465
466public:
467
468
469 PosteriorFunctionFromToyMC(RooAbsReal & nll, RooAbsPdf & pdf, RooRealVar & poi, RooArgList & nuisParams, RooAbsReal * prior = nullptr, double
470 nllOffset = 0, int niter = 0, bool redoToys = true ) :
471 fFunctor(nll, nuisParams, RooArgList() ),
472 fPriorFunc(nullptr),
473 fLikelihood(fFunctor, nullptr, nllOffset),
474 fPdf(&pdf),
475 fPoi(&poi),
476 fNuisParams(nuisParams),
477 fNumIterations(niter),
478 fError(-1),
479 fRedoToys(redoToys)
480 {
481 if (niter == 0) fNumIterations = 100; // default value
482
483 if (prior) {
484 fPriorFunc = std::make_shared<RooFunctor>(*prior, nuisParams, RooArgList());
486 }
487
488 ooccoutI(nullptr,InputArguments) << "PosteriorFunctionFromToyMC::Evaluate the posterior function by randomizing the nuisances: niter " << fNumIterations << std::endl;
489
490 ooccoutI(nullptr,InputArguments) << "PosteriorFunctionFromToyMC::Pdf used for randomizing the nuisance is " << fPdf->GetName() << std::endl;
491 // check that pdf contains the nuisance
492 std::unique_ptr<RooArgSet> vars{fPdf->getVariables()};
493 for (int i = 0; i < fNuisParams.getSize(); ++i) {
494 if (!vars->find( fNuisParams[i].GetName() ) ) {
495 ooccoutW(nullptr,InputArguments) << "Nuisance parameter " << fNuisParams[i].GetName()
496 << " is not part of sampling pdf. "
497 << "they will be treated as constant " << std::endl;
498 }
499 }
500
501 if (!fRedoToys) {
502 ooccoutI(nullptr,InputArguments) << "PosteriorFunctionFromToyMC::Generate nuisance toys only one time (for all POI points)" << std::endl;
503 GenerateToys();
504 }
505 }
506
507 // generate first n-samples of the nuisance parameters
508 void GenerateToys() const {
509 fGenParams = std::unique_ptr<RooDataSet>{fPdf->generate(fNuisParams, fNumIterations)};
510 if(fGenParams==nullptr) {
511 ooccoutE(nullptr,InputArguments) << "PosteriorFunctionFromToyMC - failed to generate nuisance parameters" << std::endl;
512 }
513 }
514
515 double Error() const { return fError;}
516
517 ROOT::Math::IGenFunction * Clone() const override {
518 // use default copy constructor
519 //return new PosteriorFunctionFromToyMC(*this);
520 // clone not implemented
521 assert(1);
522 return nullptr;
523 }
524
525private:
526 // evaluate the posterior at the poi value x
527 double DoEval( double x) const override {
528
529 int npar = fNuisParams.getSize();
530 assert (npar > 0);
531
532
533 // generate the toys
534 if (fRedoToys) GenerateToys();
535 if (!fGenParams) return 0;
536
537 // evaluate posterior function at a poi value x by integrating all nuisance parameters
538
539 fPoi->setVal(x);
540
541 // loop over all of the generate data
542 double sum = 0;
543 double sum2 = 0;
544
545 for(int iter=0; iter<fNumIterations; ++iter) {
546
547 // get the set of generated parameters and set the nuisance parameters to the generated values
548 std::vector<double> p(npar);
549 for (int i = 0; i < npar; ++i) {
550 const RooArgSet* genset=fGenParams->get(iter);
551 RooAbsArg * arg = genset->find( fNuisParams[i].GetName() );
552 RooRealVar * var = dynamic_cast<RooRealVar*>(arg);
553 assert(var != nullptr);
554 p[i] = var->getVal();
555 ((RooRealVar &) fNuisParams[i]).setVal(p[i]);
556 }
557
558 // evaluate now the likelihood function
559 double fval = fLikelihood( &p.front() );
560
561 // likelihood already must contained the pdf we have sampled
562 // so we must divided by it. The value must be normalized on all
563 // other parameters
565 double nuisPdfVal = fPdf->getVal(&arg);
566 fval /= nuisPdfVal;
567
568
569 if( fval > std::numeric_limits<double>::max() ) {
570 ooccoutE(nullptr,Eval) << "BayesianCalculator::EvalPosteriorFunctionFromToy : "
571 << "Likelihood evaluates to infinity " << std::endl;
572 ooccoutE(nullptr,Eval) << "poi value = " << x << std::endl;
573 ooccoutE(nullptr,Eval) << "Nuisance parameter values : ";
574 for (int i = 0; i < npar; ++i)
575 ooccoutE(nullptr,Eval) << fNuisParams[i].GetName() << " = " << p[i] << " ";
576 ooccoutE(nullptr,Eval) << " - return 0 " << std::endl;
577
578 fError = 1.E30;
579 return 0;
580 }
581 if( TMath::IsNaN(fval) ) {
582 ooccoutE(nullptr,Eval) << "BayesianCalculator::EvalPosteriorFunctionFromToy : "
583 << "Likelihood is a NaN " << std::endl;
584 ooccoutE(nullptr,Eval) << "poi value = " << x << std::endl;
585 ooccoutE(nullptr,Eval) << "Nuisance parameter values : ";
586 for (int i = 0; i < npar; ++i)
587 ooccoutE(nullptr,Eval) << fNuisParams[i].GetName() << " = " << p[i] << " ";
588 ooccoutE(nullptr,Eval) << " - return 0 " << std::endl;
589 fError = 1.E30;
590 return 0;
591 }
592
593
594
595 sum += fval;
596 sum2 += fval*fval;
597 }
598
599 // compute the average and variance
600 double val = sum/double(fNumIterations);
601 double dval2 = std::max( sum2/double(fNumIterations) - val*val, 0.0);
602 fError = std::sqrt( dval2 / fNumIterations);
603
604 // debug
605 ooccoutD(nullptr,NumIntegration) << "PosteriorFunctionFromToyMC: POI value = "
606 << x << "\tp(x) = " << val << " +/- " << fError << std::endl;
607
608
609 if (val != 0 && fError/val > 0.2 ) {
610 ooccoutW(nullptr,NumIntegration) << "PosteriorFunctionFromToyMC::DoEval"
611 << " - Error in estimating posterior is larger than 20% ! "
612 << "x = " << x << " p(x) = " << val << " +/- " << fError << std::endl;
613 }
614
615
616 return val;
617 }
618
620 mutable std::shared_ptr<RooFunctor> fPriorFunc; // functor binding the prior
622 mutable RooAbsPdf * fPdf;
625 mutable std::unique_ptr<RooDataSet> fGenParams;
627 mutable double fError;
628 bool fRedoToys; // do toys every iteration
629
630};
631
632////////////////////////////////////////////////////////////////////////////////
633// Implementation of BayesianCalculator
634////////////////////////////////////////////////////////////////////////////////
635
636////////////////////////////////////////////////////////////////////////////////
637/// default constructor
638
640 fData(nullptr),
641 fPdf(nullptr),
642 fPriorPdf(nullptr),
643 fNuisancePdf(nullptr),
644 fProductPdf (nullptr), fLikelihood (nullptr), fIntegratedLikelihood (nullptr), fPosteriorPdf(nullptr),
645 fPosteriorFunction(nullptr), fApproxPosterior(nullptr),
646 fLower(0), fUpper(0),
647 fNLLMin(0),
648 fSize(0.05), fLeftSideFraction(0.5),
649 fBrfPrecision(0.00005),
650 fNScanBins(-1),
651 fNumIterations(0),
652 fValidInterval(false)
653{
654}
655
656////////////////////////////////////////////////////////////////////////////////
657/// Constructor from data set, model pdf, parameter of interests and prior pdf
658/// If nuisance parameters are given they will be integrated according either to the prior or
659/// their constraint term included in the model
660
661BayesianCalculator::BayesianCalculator( /* const char* name, const char* title, */
663 RooAbsPdf& pdf,
664 const RooArgSet& POI,
665 RooAbsPdf& priorPdf,
666 const RooArgSet* nuisanceParameters ) :
667 fData(&data),
668 fPdf(&pdf),
669 fPOI(POI),
670 fPriorPdf(&priorPdf),
671 fNuisancePdf(nullptr),
672 fProductPdf (nullptr), fLikelihood (nullptr), fIntegratedLikelihood (nullptr), fPosteriorPdf(nullptr),
673 fPosteriorFunction(nullptr), fApproxPosterior(nullptr),
674 fLower(0), fUpper(0),
675 fNLLMin(0),
676 fSize(0.05), fLeftSideFraction(0.5),
677 fBrfPrecision(0.00005),
678 fNScanBins(-1),
679 fNumIterations(0),
680 fValidInterval(false)
681{
682
683 if (nuisanceParameters) fNuisanceParameters.add(*nuisanceParameters);
684 // remove constant nuisance parameters
686}
687
688////////////////////////////////////////////////////////////////////////////////
689/// Constructor from a data set and a ModelConfig
690/// model pdf, poi and nuisances will be taken from the ModelConfig
691
693 ModelConfig & model) :
694 fData(&data),
695 fPdf(model.GetPdf()),
696 fPriorPdf( model.GetPriorPdf()),
697 fNuisancePdf(nullptr),
698 fProductPdf (nullptr), fLikelihood (nullptr), fIntegratedLikelihood (nullptr), fPosteriorPdf(nullptr),
699 fPosteriorFunction(nullptr), fApproxPosterior(nullptr),
700 fLower(0), fUpper(0),
701 fNLLMin(0),
702 fSize(0.05), fLeftSideFraction(0.5),
703 fBrfPrecision(0.00005),
704 fNScanBins(-1),
705 fNumIterations(0),
706 fValidInterval(false)
707{
708 SetModel(model);
709}
710
711
713{
714 // destructor
715 ClearAll();
716}
717
718////////////////////////////////////////////////////////////////////////////////
719/// clear all cached pdf objects
720
722 if (fProductPdf) delete fProductPdf;
723 fLogLike.reset();
724 if (fLikelihood) delete fLikelihood;
726 if (fPosteriorPdf) delete fPosteriorPdf;
729 fPosteriorPdf = nullptr;
730 fPosteriorFunction = nullptr;
731 fProductPdf = nullptr;
732 fLikelihood = nullptr;
733 fIntegratedLikelihood = nullptr;
734 fLower = 0;
735 fUpper = 0;
736 fNLLMin = 0;
737 fValidInterval = false;
738}
739
740////////////////////////////////////////////////////////////////////////////////
741/// set the model to use
742/// The model pdf, prior pdf, parameter of interest and nuisances
743/// will be taken according to the model
744
746
747 fPdf = model.GetPdf();
748 fPriorPdf = model.GetPriorPdf();
749 // assignment operator = does not do a real copy the sets (must use add method)
750 fPOI.removeAll();
754 if (model.GetParametersOfInterest()) fPOI.add( *(model.GetParametersOfInterest()) );
757 if (model.GetGlobalObservables()) fGlobalObs.add( *(model.GetGlobalObservables() ) );
758 // remove constant nuisance parameters
760
761 // invalidate the cached pointers
762 ClearAll();
763}
764
765////////////////////////////////////////////////////////////////////////////////
766/// Build and return the posterior function (not normalized) as a RooAbsReal
767/// the posterior is obtained from the product of the likelihood function and the
768/// prior pdf which is then integrated in the nuisance parameters (if existing).
769/// A prior function for the nuisance can be specified either in the prior pdf object
770/// or in the model itself. If no prior nuisance is specified, but prior parameters are then
771/// the integration is performed assuming a flat prior for the nuisance parameters.
772///
773/// NOTE: the return object is managed by the BayesianCalculator class, users do not need to delete it,
774/// but the object will be deleted when the BayesiabCalculator object is deleted
775
777{
778
780 if (fLikelihood) return fLikelihood;
781
782 // run some sanity checks
783 if (!fPdf ) {
784 coutE(InputArguments) << "BayesianCalculator::GetPosteriorPdf - missing pdf model" << std::endl;
785 return nullptr;
786 }
787 if (fPOI.empty()) {
788 coutE(InputArguments) << "BayesianCalculator::GetPosteriorPdf - missing parameter of interest" << std::endl;
789 return nullptr;
790 }
791 if (fPOI.getSize() > 1) {
792 coutE(InputArguments) << "BayesianCalculator::GetPosteriorPdf - current implementation works only on 1D intervals" << std::endl;
793 return nullptr;
794 }
795
796
797 std::unique_ptr<RooArgSet> constrainedParams{fPdf->getParameters(*fData)};
798 // remove the constant parameters
799 RemoveConstantParameters(&*constrainedParams);
800
801 //constrainedParams->Print("V");
802
803 // use RooFit::Constrain() to be sure constraints terms are taken into account
805
806
807
808 ccoutD(Eval) << "BayesianCalculator::GetPosteriorFunction : "
809 << " pdf value " << fPdf->getVal()
810 << " neglogLikelihood = " << fLogLike->getVal() << std::endl;
811
812 if (fPriorPdf)
813 ccoutD(Eval) << "\t\t\t priorPOI value " << fPriorPdf->getVal() << std::endl;
814
815 // check that likelihood evaluation is not infinity
816 double nllVal = fLogLike->getVal();
817 if ( nllVal > std::numeric_limits<double>::max() ) {
818 coutE(Eval) << "BayesianCalculator::GetPosteriorFunction : "
819 << " Negative log likelihood evaluates to infinity " << std::endl
820 << " Non-const Parameter values : ";
821 RooArgList p(*constrainedParams);
822 for (int i = 0; i < p.getSize(); ++i) {
823 RooRealVar * v = dynamic_cast<RooRealVar *>(&p[i] );
824 if (v!=nullptr) ccoutE(Eval) << v->GetName() << " = " << v->getVal() << " ";
825 }
826 ccoutE(Eval) << std::endl;
827 ccoutE(Eval) << "-- Perform a full likelihood fit of the model before or set more reasonable parameter values"
828 << std::endl;
829 coutE(Eval) << "BayesianCalculator::GetPosteriorFunction : " << " cannot compute posterior function " << std::endl;
830 return nullptr;
831 }
832
833
834
835 // need do find minimum of log-likelihood in the range to shift function
836 // to avoid numerical errors when we compute the likelihood (overflows in the exponent)
837 // N.B.: this works for only 1 parameter of interest otherwise Minuit should be used for finding the minimum
838 RooFunctor * nllFunc = fLogLike->functor(fPOI);
839 assert(nllFunc);
840 ROOT::Math::Functor1D wnllFunc(*nllFunc);
841 RooRealVar* poi = dynamic_cast<RooRealVar*>( fPOI.first() );
842 assert(poi);
843
844 // try to reduce some error messages
845 //bool silentMode = (RooMsgService::instance().globalKillBelow() >= RooFit::ERROR || RooMsgService::instance().silentMode()) ;
847
848
849 coutI(Eval) << "BayesianCalculator::GetPosteriorFunction : "
850 << " nll value " << nllVal << " poi value = " << poi->getVal() << std::endl;
851
852
854 minim.SetFunction(wnllFunc,poi->getMin(),poi->getMax() );
855 bool ret = minim.Minimize(100,1.E-3,1.E-3);
856 fNLLMin = 0;
857 if (ret) fNLLMin = minim.FValMinimum();
858
859 coutI(Eval) << "BayesianCalculator::GetPosteriorFunction : minimum of NLL vs POI for POI = "
860 << poi->getVal() << " min NLL = " << fNLLMin << std::endl;
861
862 delete nllFunc;
863
864
865 if ( fNuisanceParameters.empty() || fIntegrationType.Contains("ROOFIT") ) {
866
867 ccoutD(Eval) << "BayesianCalculator::GetPosteriorFunction : use ROOFIT integration "
868 << std::endl;
869
870#ifdef DOLATER // (not clear why this does not work)
871 // need to make in this case a likelihood from the nll and make the product with the prior
872 TString likeName = TString("likelihood_times_prior_") + TString(fPriorPdf->GetName());
873 TString formula;
874 formula.Form("exp(-@0+%f+log(@1))",fNLLMin);
875 fLikelihood = new RooFormulaVar(likeName,formula,RooArgList(*fLogLike,*fPriorPdf));
876#else
877 // here use RooProdPdf (not very nice) but working
878
879 if (fLogLike) fLogLike.reset();
880 if (fProductPdf) {
881 delete fProductPdf;
882 fProductPdf = nullptr;
883 }
884
885 // // create a unique name for the product pdf
886 RooAbsPdf * pdfAndPrior = fPdf;
887 if (fPriorPdf) {
888 TString prodName = TString("product_") + TString(fPdf->GetName()) + TString("_") + TString(fPriorPdf->GetName() );
889 // save this as data member since it needs to be deleted afterwards
890 fProductPdf = new RooProdPdf(prodName,"",RooArgList(*fPdf,*fPriorPdf));
891 pdfAndPrior = fProductPdf;
892 }
893
894 std::unique_ptr<RooArgSet> constrParams{fPdf->getParameters(*fData)};
895 // remove the constant parameters
896 RemoveConstantParameters(&*constrParams);
898
899 TString likeName = TString("likelihood_times_prior_") + TString(pdfAndPrior->GetName());
900 TString formula;
901 formula.Form("exp(-@0+%f)",fNLLMin);
902 fLikelihood = new RooFormulaVar(likeName,formula,RooArgList(*fLogLike));
903#endif
904
905
906 // if no nuisance parameter we can just return the likelihood function
909 fLikelihood = nullptr;
910 }
911 else
912 // case of using RooFit for the integration
913 fIntegratedLikelihood = std::unique_ptr<RooAbsReal>{fLikelihood->createIntegral(fNuisanceParameters)}.release();
914
915
916 }
917
918 else if ( fIntegrationType.Contains("TOYMC") ) {
919 // compute the posterior as expectation values of the likelihood function
920 // sampling on the nuisance parameters
921
923
924 bool doToysEveryIteration = true;
925 // if type is 1-TOYMC or TOYMC-1
926 if ( fIntegrationType.Contains("1") || fIntegrationType.Contains("ONE") ) doToysEveryIteration = false;
927
928 RooAbsPdf * samplingPdf = (fNuisancePdf) ? fNuisancePdf : fPdf;
929 if (!fNuisancePdf) {
930 ccoutI(Eval) << "BayesianCalculator::GetPosteriorFunction : no nuisance pdf is provided, try using global pdf (this will be slower)"
931 << std::endl;
932 }
933 fPosteriorFunction = new PosteriorFunctionFromToyMC(*fLogLike, *samplingPdf, *poi, nuisParams, fPriorPdf, fNLLMin,
934 fNumIterations, doToysEveryIteration );
935
936 TString name = "toyposteriorfunction_from_";
937 name += fLogLike->GetName();
939
940 // need to scan likelihood in this case
941 if (fNScanBins <= 0) fNScanBins = 100;
942
943 }
944
945 else {
946
947 // use ROOT integration method if there are nuisance parameters
948
951
952 TString name = "posteriorfunction_from_";
953 name += fLogLike->GetName();
955
956 }
957
958
960 coutW(Eval) << "BayesianCalculator::GetPosteriorFunction : " << RooAbsReal::numEvalErrors() << " errors reported in evaluating log-likelihood function "
961 << std::endl;
964
966
967}
968
969////////////////////////////////////////////////////////////////////////////////
970/// Build and return the posterior pdf (i.e posterior function normalized to all range of poi)
971/// Note that an extra integration in the POI is required for the normalization
972/// NOTE: user must delete the returned object
973
975{
976
978 if (!plike) return nullptr;
979
980
981 // create a unique name on the posterior from the names of the components
982 TString posteriorName = this->GetName() + TString("_posteriorPdf_") + plike->GetName();
983
984 RooAbsPdf * posteriorPdf = new RooGenericPdf(posteriorName,"@0",*plike);
985
986 return posteriorPdf;
987}
988
989////////////////////////////////////////////////////////////////////////////////
990/// When am approximate posterior is computed binninig the parameter of interest (poi) range
991/// (see SetScanOfPosteriors) an histogram is created and can be returned to the user
992/// A nullptr is instead returned when the posterior is computed without binning the poi.
993///
994/// NOTE: the returned object is managed by the BayesianCalculator class,
995/// if the user wants to take ownership of the returned histogram, he needs to clone
996/// or copy the return object.
997
999{
1000 return (fApproxPosterior) ? fApproxPosterior->GetHistogram() : nullptr;
1001}
1002
1003
1004////////////////////////////////////////////////////////////////////////////////
1005/// return a RooPlot with the posterior and the credibility region
1006/// NOTE: User takes ownership of the returned object
1007
1008RooPlot* BayesianCalculator::GetPosteriorPlot(bool norm, double precision ) const
1009{
1010
1012
1013 // if a scan is requested approximate the posterior
1014 if (fNScanBins > 0)
1016
1017 RooAbsReal * posterior = fIntegratedLikelihood;
1018 if (norm) {
1019 // delete and re-do always posterior pdf (could be invalid after approximating it)
1020 if (fPosteriorPdf) delete fPosteriorPdf;
1022 posterior = fPosteriorPdf;
1023 }
1024 if (!posterior) return nullptr;
1025
1027
1028 RooAbsRealLValue* poi = dynamic_cast<RooAbsRealLValue*>( fPOI.first() );
1029 assert(poi);
1030
1031
1032 RooPlot* plot = poi->frame();
1033 if (!plot) return nullptr;
1034
1035 // try to reduce some error messages
1037
1038 plot->SetTitle(TString("Posterior probability of parameter \"")+TString(poi->GetName())+TString("\""));
1040 posterior->plotOn(plot);
1041 plot->GetYaxis()->SetTitle("posterior function");
1042
1043 // reset the counts and default mode
1046
1047 return plot;
1048}
1049
1050////////////////////////////////////////////////////////////////////////////////
1051/// set the integration type (possible type are) :
1052///
1053/// - 1D integration ( used when only one nuisance and when the posterior is scanned):
1054/// adaptive , gauss, nonadaptive
1055/// - multidim:
1056/// - ADAPTIVE, adaptive numerical integration
1057/// The parameter numIters (settable with SetNumIters) is the max number of function calls.
1058/// It can be reduced to make the integration faster but it will be difficult to reach the required tolerance
1059/// - VEGAS MC integration method based on importance sampling - numIters is number of function calls
1060/// Extra Vegas parameter can be set using IntegratorMultiDimOptions class
1061/// - MISER MC integration method based on stratified sampling
1062/// See also http://en.wikipedia.org/wiki/Monte_Carlo_integration for VEGAS and MISER description
1063/// - PLAIN simple MC integration method, where the max number of calls can be specified using SetNumIters(numIters)
1064///
1065/// Extra integration types are:
1066///
1067/// - TOYMC:
1068/// evaluate posterior by generating toy MC for the nuisance parameters. It is a MC
1069/// integration, where the function is sampled according to the nuisance. It is convenient to use when all
1070/// the nuisance are uncorrelated and it is efficient to generate them
1071/// The toy are generated by default for each poi values
1072/// (this method has been proposed and provided by J.P Chou)
1073/// - 1-TOYMC : same method as before but in this case the toys are generated only one time and then used for
1074/// each poi value. It can be convenient when the generation time is much larger than the evaluation time,
1075/// otherwise it is recommended to re-generate the toy for each poi scanned point of the posterior function
1076/// - ROOFIT:
1077/// use roofit default integration methods which will produce a nested integral (not recommended for more
1078/// than 1 nuisance parameters)
1079
1081 // if type = 0 use default specified via class IntegratorMultiDimOptions::SetDefaultIntegrator
1084}
1085
1086////////////////////////////////////////////////////////////////////////////////
1087/// Compute the interval. By Default a central interval is computed
1088/// and the result is a SimpleInterval object.
1089///
1090/// Using the method (to be called before SetInterval) SetLeftSideTailFraction the user can choose the type of interval.
1091/// By default the returned interval is a central interval with the confidence level specified
1092/// previously in the constructor ( LeftSideTailFraction = 0.5).
1093/// - For lower limit use SetLeftSideTailFraction = 1
1094/// - For upper limit use SetLeftSideTailFraction = 0
1095/// - for shortest intervals use SetLeftSideTailFraction = -1 or call the method SetShortestInterval()
1096///
1097/// NOTE: The BayesianCalculator covers only the case with one
1098/// single parameter of interest
1099///
1100/// NOTE: User takes ownership of the returned object
1101
1103{
1104
1105 if (fValidInterval)
1106 coutW(Eval) << "BayesianCalculator::GetInterval - recomputing interval for the same CL and same model" << std::endl;
1107
1108 RooRealVar* poi = dynamic_cast<RooRealVar*>( fPOI.first() );
1109 if (!poi) {
1110 coutE(Eval) << "BayesianCalculator::GetInterval - no parameter of interest is set " << std::endl;
1111 return nullptr;
1112 }
1113
1114
1115
1116 // get integrated likelihood (posterior function)
1118
1119 //bool silentMode = (RooMsgService::instance().globalKillBelow() >= RooFit::ERROR || RooMsgService::instance().silentMode()) ;
1121
1122 if (fLeftSideFraction < 0 ) {
1123 // compute short intervals
1125 }
1126 else {
1127 // compute the other intervals
1128
1129 double lowerCutOff = fLeftSideFraction * fSize;
1130 double upperCutOff = 1. - (1.- fLeftSideFraction) * fSize;
1131
1132
1133 if (fNScanBins > 0) {
1134 ComputeIntervalFromApproxPosterior(lowerCutOff, upperCutOff);
1135 }
1136
1137 else {
1138 // use integration method if there are nuisance parameters
1139 if (fNuisanceParameters.getSize() > 0) {
1140 ComputeIntervalFromCdf(lowerCutOff, upperCutOff);
1141 }
1142 else {
1143 // case of no nuisance - just use createCdf from roofit
1144 ComputeIntervalUsingRooFit(lowerCutOff, upperCutOff);
1145 }
1146 // case cdf failed (scan then the posterior)
1147 if (!fValidInterval) {
1148 fNScanBins = 100;
1149 coutW(Eval) << "BayesianCalculator::GetInterval - computing integral from cdf failed - do a scan in "
1150 << fNScanBins << " nbins " << std::endl;
1151 ComputeIntervalFromApproxPosterior(lowerCutOff, upperCutOff);
1152 }
1153 }
1154 }
1155
1156
1157 // reset the counts and default mode
1158 if (RooAbsReal::numEvalErrors() > 0)
1159 coutW(Eval) << "BayesianCalculator::GetInterval : " << RooAbsReal::numEvalErrors() << " errors reported in evaluating log-likelihood function "
1160 << std::endl;
1161
1164
1165 if (!fValidInterval) {
1166 fLower = 1; fUpper = 0;
1167 coutE(Eval) << "BayesianCalculator::GetInterval - cannot compute a valid interval - return a dummy [1,0] interval"
1168 << std::endl;
1169 }
1170 else {
1171 coutI(Eval) << "BayesianCalculator::GetInterval - found a valid interval : [" << fLower << " , "
1172 << fUpper << " ]" << std::endl;
1173 }
1174
1175 TString interval_name = TString("BayesianInterval_a") + TString(this->GetName());
1176 SimpleInterval * interval = new SimpleInterval(interval_name,*poi,fLower,fUpper,ConfidenceLevel());
1177 interval->SetTitle("SimpleInterval from BayesianCalculator");
1178
1179 return interval;
1180}
1181
1182////////////////////////////////////////////////////////////////////////////////
1183/// Returns the value of the parameter for the point in
1184/// parameter-space that is the most likely.
1185/// How do we do if there are points that are equi-probable?
1186/// use approximate posterior
1187/// t.b.d use real function to find the mode
1188
1190
1193 return h->GetBinCenter(h->GetMaximumBin() );
1194 //return fApproxPosterior->GetMaximumX();
1195}
1196
1197////////////////////////////////////////////////////////////////////////////////
1198/// internal function compute the interval using RooFit
1199
1200void BayesianCalculator::ComputeIntervalUsingRooFit(double lowerCutOff, double upperCutOff ) const {
1201
1202 coutI(Eval) << "BayesianCalculator: Compute interval using RooFit: posteriorPdf + createCdf + RooBrentRootFinder " << std::endl;
1203
1204 RooRealVar* poi = dynamic_cast<RooRealVar*>( fPOI.first() );
1205 assert(poi);
1206
1207 fValidInterval = false;
1209 if (!fPosteriorPdf) return;
1210
1211 std::unique_ptr<RooAbsReal> cdf{fPosteriorPdf->createCdf(fPOI,RooFit::ScanNoCdf())};
1212 if (!cdf) return;
1213
1214 std::unique_ptr<RooAbsFunc> cdf_bind{cdf->bindVars(fPOI,&fPOI)};
1215 if (!cdf_bind) return;
1216
1217 RooBrentRootFinder brf(*cdf_bind);
1218 brf.setTol(fBrfPrecision); // set the brf precision
1219
1220 double tmpVal = poi->getVal(); // patch used because findRoot changes the value of poi
1221
1222 bool ret = true;
1223 if (lowerCutOff > 0) {
1224 double y = lowerCutOff;
1225 ret &= brf.findRoot(fLower,poi->getMin(),poi->getMax(),y);
1226 }
1227 else
1228 fLower = poi->getMin();
1229
1230 if (upperCutOff < 1.0) {
1231 double y=upperCutOff;
1232 ret &= brf.findRoot(fUpper,poi->getMin(),poi->getMax(),y);
1233 }
1234 else
1235 fUpper = poi->getMax();
1236 if (!ret) coutE(Eval) << "BayesianCalculator::GetInterval "
1237 << "Error returned from Root finder, estimated interval is not fully correct"
1238 << std::endl;
1239 else
1240 fValidInterval = true;
1241
1242
1243 poi->setVal(tmpVal); // patch: restore the original value of poi
1244}
1245
1246////////////////////////////////////////////////////////////////////////////////
1247/// internal function compute the interval using Cdf integration
1248
1249void BayesianCalculator::ComputeIntervalFromCdf(double lowerCutOff, double upperCutOff ) const {
1250
1251 fValidInterval = false;
1252
1253 coutI(InputArguments) << "BayesianCalculator:GetInterval Compute the interval from the posterior cdf " << std::endl;
1254
1255 RooRealVar* poi = dynamic_cast<RooRealVar*>( fPOI.first() );
1256 assert(poi);
1257 if (GetPosteriorFunction() == nullptr) {
1258 coutE(InputArguments) << "BayesianCalculator::GetInterval() cannot make posterior Function " << std::endl;
1259 return;
1260 }
1261
1262 // need to remove the constant parameters
1263 RooArgList bindParams;
1264 bindParams.add(fPOI);
1265 bindParams.add(fNuisanceParameters);
1266
1267 // this code could be put inside the PosteriorCdfFunction
1268
1269 //bindParams.Print("V");
1270
1272 if( cdf.HasError() ) {
1273 coutE(Eval) << "BayesianCalculator: Numerical error computing CDF integral - try a different method " << std::endl;
1274 return;
1275 }
1276
1277 //find the roots
1278
1280
1281 ccoutD(Eval) << "BayesianCalculator::GetInterval - finding roots of posterior using RF " << rf.Name()
1282 << " with precision = " << fBrfPrecision;
1283
1284 if (lowerCutOff > 0) {
1285 cdf.SetOffset(lowerCutOff);
1286 ccoutD(NumIntegration) << "Integrating posterior to get cdf and search lower limit at p =" << lowerCutOff << std::endl;
1287 bool ok = rf.Solve(cdf, poi->getMin(),poi->getMax() , 200,fBrfPrecision, fBrfPrecision);
1288 if( cdf.HasError() )
1289 coutW(Eval) << "BayesianCalculator: Numerical error integrating the CDF " << std::endl;
1290 if (!ok) {
1291 coutE(NumIntegration) << "BayesianCalculator::GetInterval - Error from root finder when searching lower limit !" << std::endl;
1292 return;
1293 }
1294 fLower = rf.Root();
1295 }
1296 else {
1297 fLower = poi->getMin();
1298 }
1299 if (upperCutOff < 1.0) {
1300 cdf.SetOffset(upperCutOff);
1301 ccoutD(NumIntegration) << "Integrating posterior to get cdf and search upper interval limit at p =" << upperCutOff << std::endl;
1302 bool ok = rf.Solve(cdf, fLower,poi->getMax() , 200, fBrfPrecision, fBrfPrecision);
1303 if( cdf.HasError() )
1304 coutW(Eval) << "BayesianCalculator: Numerical error integrating the CDF " << std::endl;
1305 if (!ok) {
1306 coutE(NumIntegration) << "BayesianCalculator::GetInterval - Error from root finder when searching upper limit !" << std::endl;
1307 return;
1308 }
1309 fUpper = rf.Root();
1310 }
1311 else {
1312 fUpper = poi->getMax();
1313 }
1314
1315 fValidInterval = true;
1316}
1317
1318////////////////////////////////////////////////////////////////////////////////
1319/// approximate posterior in nbins using a TF1
1320/// scan the poi values and evaluate the posterior at each point
1321/// and save the result in a cloned TF1
1322/// For each point the posterior is evaluated by integrating the nuisance
1323/// parameters
1324
1326
1327 if (fApproxPosterior) {
1328 // if number of bins of existing function is >= requested one - no need to redo the scan
1329 if (fApproxPosterior->GetNpx() >= fNScanBins) return;
1330 // otherwise redo the scan
1331 delete fApproxPosterior;
1332 fApproxPosterior = nullptr;
1333 }
1334
1335
1336 RooAbsReal * posterior = GetPosteriorFunction();
1337 if (!posterior) return;
1338
1339
1340 TF1 * tmp = posterior->asTF(fPOI);
1341 assert(tmp != nullptr);
1342 // binned the function in nbins and evaluate at those points
1343 if (fNScanBins > 0) tmp->SetNpx(fNScanBins); // if not use default of TF1 (which is 100)
1344
1345 coutI(Eval) << "BayesianCalculator - scan posterior function in nbins = " << tmp->GetNpx() << std::endl;
1346
1347 fApproxPosterior = (TF1*) tmp->Clone();
1348 // save this function for future reuse
1349 // I can delete now original posterior and use this approximated copy
1350 delete tmp;
1351 TString name = posterior->GetName() + TString("_approx");
1352 TString title = posterior->GetTitle() + TString("_approx");
1353 RooAbsReal * posterior2 = new RooTFnBinding(name,title,fApproxPosterior,fPOI);
1354 if (posterior == fIntegratedLikelihood) {
1355 delete fIntegratedLikelihood;
1356 fIntegratedLikelihood = posterior2;
1357 }
1358 else if (posterior == fLikelihood) {
1359 delete fLikelihood;
1360 fLikelihood = posterior2;
1361 }
1362 else {
1363 assert(1); // should never happen this case
1364 }
1365}
1366
1367////////////////////////////////////////////////////////////////////////////////
1368/// compute the interval using the approximate posterior function
1369
1370void BayesianCalculator::ComputeIntervalFromApproxPosterior(double lowerCutOff, double upperCutOff ) const {
1371
1372 ccoutD(Eval) << "BayesianCalculator: Compute interval from the approximate posterior " << std::endl;
1373
1375 if (!fApproxPosterior) return;
1376
1377 double prob[2];
1378 double limits[2] = {0,0};
1379 prob[0] = lowerCutOff;
1380 prob[1] = upperCutOff;
1381 fApproxPosterior->GetQuantiles(2,limits,prob);
1382 fLower = limits[0];
1383 fUpper = limits[1];
1384 fValidInterval = true;
1385}
1386
1387////////////////////////////////////////////////////////////////////////////////
1388/// compute the shortest interval from the histogram representing the posterior
1389
1390
1392 coutI(Eval) << "BayesianCalculator - computing shortest interval with CL = " << 1.-fSize << std::endl;
1393
1394 // compute via the approx posterior function
1396 if (!fApproxPosterior) return;
1397
1398 TH1D * h1 = dynamic_cast<TH1D*>(fApproxPosterior->GetHistogram() );
1399 assert(h1 != nullptr);
1401 // get bins and sort them
1402 double * bins = h1->GetArray();
1403 // exclude under/overflow bins
1404 int n = h1->GetSize()-2;
1405 std::vector<int> index(n);
1406 // exclude bins[0] (the underflow bin content)
1407 TMath::Sort(n, bins+1, &index[0]);
1408 // find cut off as test size
1409 double sum = 0;
1410 double actualCL = 0;
1411 double upper = h1->GetXaxis()->GetXmin();
1412 double lower = h1->GetXaxis()->GetXmax();
1413 double norm = h1->GetSumOfWeights();
1414
1415 for (int i = 0; i < n; ++i) {
1416 int idx = index[i];
1417 double p = bins[ idx] / norm;
1418 sum += p;
1419 if (sum > 1.-fSize ) {
1420 actualCL = sum - p;
1421 break;
1422 }
1423
1424 // histogram bin content starts from 1
1425 if ( h1->GetBinLowEdge(idx+1) < lower)
1426 lower = h1->GetBinLowEdge(idx+1);
1427 if ( h1->GetXaxis()->GetBinUpEdge(idx+1) > upper)
1428 upper = h1->GetXaxis()->GetBinUpEdge(idx+1);
1429 }
1430
1431 ccoutD(Eval) << "BayesianCalculator::ComputeShortestInterval - actual interval CL = "
1432 << actualCL << " difference from requested is " << (actualCL-(1.-fSize))/fSize*100. << "% "
1433 << " limits are [ " << lower << " , " << " upper ] " << std::endl;
1434
1435
1436 if (lower < upper) {
1437 fLower = lower;
1438 fUpper = upper;
1439
1440
1441
1442 if ( std::abs(actualCL-(1.-fSize)) > 0.1*(1.-fSize) )
1443 coutW(Eval) << "BayesianCalculator::ComputeShortestInterval - actual interval CL = "
1444 << actualCL << " differs more than 10% from desired CL value - must increase nbins "
1445 << n << " to an higher value " << std::endl;
1446 }
1447 else
1448 coutE(Eval) << "BayesianCalculator::ComputeShortestInterval " << n << " bins are not sufficient " << std::endl;
1449
1450 fValidInterval = true;
1451
1452}
1453
1454
1455
1456
1457} // end namespace RooStats
size_t fSize
#define f(i)
Definition RSha256.hxx:104
#define h(i)
Definition RSha256.hxx:106
#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.
Int_t getSize() const
Return the number of elements in the collection.
const char * GetName() const override
Returns name of object.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
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
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
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
RooGenericPdf is a concrete implementation of a probability density function, which takes a RooArgLis...
A RooPlot is a 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
RooRealVar represents a 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:214
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:496
1-D histogram with a double per channel (see TH1 documentation)}
Definition TH1.h:620
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:9058
TAxis * GetXaxis()
Definition TH1.h:322
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:9069
void SetName(const char *name) override
Change the name of this histogram.
Definition TH1.cxx:8877
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition TH1.cxx:7834
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:1183
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2334
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:636
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