Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
MCMCInterval.cxx
Go to the documentation of this file.
1// @(#)root/roostats:$Id$
2// Authors: Kevin Belasco 17/06/2009
3// Authors: Kyle Cranmer 17/06/2009
4/*************************************************************************
5 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class RooStats::MCMCInterval
13 \ingroup Roostats
14
15 MCMCInterval is a concrete implementation of the RooStats::ConfInterval
16 interface. It takes as input Markov Chain of data points in the parameter
17 space generated by Monte Carlo using the Metropolis algorithm. From the Markov
18 Chain, the confidence interval can be determined in two ways:
19
20#### Using a Kernel-Estimated PDF: (not the default method)
21
22 A RooNDKeysPdf is constructed from the data set using adaptive kernel width.
23 With this RooNDKeysPdf F, we then integrate over the most likely domain in the
24 parameter space (tallest points in the posterior RooNDKeysPdf) until the target
25 confidence level is reached within an acceptable neighborhood as defined by
26 SetEpsilon(). More specifically: we calculate the following for different
27 cutoff values C until we reach the target confidence level: \f$\int_{ F >= C } F
28 d{normset} \f$.
29 Important note: this is not the default method because of a bug in constructing
30 the RooNDKeysPdf from a weighted data set. Configure to use this method by
31 calling SetUseKeys(true), and the data set will be interpreted without weights.
32
33
34#### Using a binned data set: (the default method)
35
36 This is the binned analog of the continuous integrative method that uses the
37 kernel-estimated PDF. The points in the Markov Chain are put into a binned
38 data set and the interval is then calculated by adding the heights of the bins
39 in decreasing order until the desired level of confidence has been reached.
40 Note that this means the actual confidence level is >= the confidence level
41 prescribed by the client (unless the user calls SetHistStrict(false)). This
42 method is the default but may not remain as such in future releases, so you may
43 wish to explicitly configure to use this method by calling SetUseKeys(false)
44
45
46 These are not the only ways for the confidence interval to be determined, and
47 other possibilities are being considered being added, especially for the
48 1-dimensional case.
49
50
51 One can ask an MCMCInterval for the lower and upper limits on a specific
52 parameter of interest in the interval. Note that this works better for some
53 distributions (ones with exactly one local maximum) than others, and sometimes
54 has little value.
55*/
56
57
58#include "Rtypes.h"
59
60#include "TMath.h"
61
64#include "RooStats/Heaviside.h"
65#include "RooDataHist.h"
66#include "RooNDKeysPdf.h"
67#include "RooProduct.h"
69#include "RooRealVar.h"
70#include "RooArgList.h"
71#include "TH1.h"
72#include "TH1F.h"
73#include "TH2F.h"
74#include "TH3F.h"
75#include "RooMsgService.h"
76#include "RooGlobalFunc.h"
77#include "TObject.h"
78#include "THnSparse.h"
79#include "RooNumber.h"
80
81#include <cstdlib>
82#include <string>
83#include <algorithm>
84
85
86using namespace RooFit;
87using namespace RooStats;
88using std::endl;
89
90////////////////////////////////////////////////////////////////////////////////
91
93 : ConfInterval(name), fTFLower(-RooNumber::infinity()), fTFUpper(RooNumber::infinity())
94{
95 fVector.clear();
96}
97
98////////////////////////////////////////////////////////////////////////////////
99
100MCMCInterval::MCMCInterval(const char *name, const RooArgSet &parameters, MarkovChain &chain)
101 : ConfInterval(name), fChain(&chain), fTFLower(-RooNumber::infinity()), fTFUpper(RooNumber::infinity())
102{
103 fVector.clear();
104 SetParameters(parameters);
105}
106
107////////////////////////////////////////////////////////////////////////////////
108
110
112 CompareDataHistBins(RooDataHist* hist) : fDataHist(hist) {}
114 double n1 = fDataHist->weight(bin1);
115 double n2 = fDataHist->weight(bin2);
116 return (n1 < n2);
117 }
119};
120
122 CompareSparseHistBins(THnSparse* hist) : fSparseHist(hist) {}
124 double n1 = fSparseHist->GetBinContent(bin1);
125 double n2 = fSparseHist->GetBinContent(bin2);
126 return (n1 < n2);
127 }
129};
130
133 fChain(chain), fParam(param) {}
135 double xi = fChain->Get(i)->getRealValue(fParam->GetName());
136 double xj = fChain->Get(j)->getRealValue(fParam->GetName());
137 return (xi < xj);
138 }
141};
142
143////////////////////////////////////////////////////////////////////////////////
144/// kbelasco: for this method, consider running DetermineInterval() if
145/// fKeysPdf==nullptr, fSparseHist==nullptr, fDataHist==nullptr, or fVector.empty()
146/// rather than just returning false. Though this should not be an issue
147/// because nobody should be able to get an MCMCInterval that has their interval
148/// or posterior representation nullptr/empty since they should only get this
149/// through the MCMCCalculator
150
151bool MCMCInterval::IsInInterval(const RooArgSet& point) const
152{
153 if (fIntervalType == kShortest) {
154 if (fUseKeys) {
155 if (fKeysPdf == nullptr)
156 return false;
157
158 // evaluate keyspdf at point and return whether >= cutoff
159 RooStats::SetParameters(&point, const_cast<RooArgSet *>(&fParameters));
160 return fKeysPdf->getVal(&fParameters) >= fKeysCutoff;
161 } else {
162 if (fUseSparseHist) {
163 if (fSparseHist == nullptr)
164 return false;
165
166 // evaluate sparse hist at bin where point lies and return
167 // whether >= cutoff
169 const_cast<RooArgSet*>(&fParameters));
170 Long_t bin;
171 // kbelasco: consider making x static
172 std::vector<double> x(fDimension);
173 for (Int_t i = 0; i < fDimension; i++)
174 x[i] = fAxes[i]->getVal();
175 bin = fSparseHist->GetBin(x.data(), false);
176 double weight = fSparseHist->GetBinContent((Long64_t)bin);
177 return (weight >= (double)fHistCutoff);
178 } else {
179 if (fDataHist == nullptr)
180 return false;
181
182 // evaluate data hist at bin where point lies and return whether
183 // >= cutoff
184 Int_t bin;
185 bin = fDataHist->getIndex(point);
186 return (fDataHist->weight(bin) >= (double)fHistCutoff);
187 }
188 }
189 } else if (fIntervalType == kTailFraction) {
190 if (fVector.empty())
191 return false;
192
193 // return whether value of point is within the range
194 double x = point.getRealValue(fAxes[0]->GetName());
195 if (fTFLower <= x && x <= fTFUpper)
196 return true;
197
198 return false;
199 }
200
201 coutE(InputArguments) << "Error in MCMCInterval::IsInInterval: "
202 << "Interval type not set. Returning false." << std::endl;
203 return false;
204}
205
206////////////////////////////////////////////////////////////////////////////////
207
209{
210 fConfidenceLevel = cl;
212}
213
214// kbelasco: update this or just take it out
215// kbelasco: consider keeping this around but changing the implementation
216// to set the number of bins for each RooRealVar and then recreating the
217// histograms
218//void MCMCInterval::SetNumBins(Int_t numBins)
219//{
220// if (numBins > 0) {
221// fPreferredNumBins = numBins;
222// for (Int_t d = 0; d < fDimension; d++)
223// fNumBins[d] = numBins;
224// }
225// else {
226// coutE(Eval) << "* Error in MCMCInterval::SetNumBins: " <<
227// "Negative number of bins given: " << numBins << std::endl;
228// return;
229// }
230//
231// // If the histogram already exists, recreate it with the new bin numbers
232// if (fHist != nullptr)
233// CreateHist();
234//}
235
236////////////////////////////////////////////////////////////////////////////////
237
239{
240 Int_t size = axes.size();
241 if (size != fDimension) {
242 coutE(InputArguments) << "* Error in MCMCInterval::SetAxes: " <<
243 "number of variables in axes (" << size <<
244 ") doesn't match number of parameters ("
245 << fDimension << ")" << std::endl;
246 return;
247 }
248 for (Int_t i = 0; i < size; i++)
249 fAxes[i] = static_cast<RooRealVar*>(axes.at(i));
250}
251
252////////////////////////////////////////////////////////////////////////////////
253
255{
256 // kbelasco: check here for memory leak. does RooNDKeysPdf use
257 // the RooArgList passed to it or does it make a clone?
258 // also check for memory leak from chain, does RooNDKeysPdf clone that?
259 if (fAxes.empty() || fParameters.empty()) {
260 coutE(InputArguments) << "Error in MCMCInterval::CreateKeysPdf: "
261 << "parameters have not been set." << std::endl;
262 return;
263 }
264
265 if (fNumBurnInSteps >= fChain->Size()) {
267 "MCMCInterval::CreateKeysPdf: creation of Keys PDF failed: " <<
268 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
269 "in Markov chain." << std::endl;
270 fKeysPdf.reset();
271 fCutoffVar.reset();
272 fHeaviside.reset();
273 fProduct.reset();
274 return;
275 }
276
277 std::unique_ptr<RooAbsData> chain{fChain->GetAsConstDataSet()->reduce(SelectVars(fParameters), EventRange(fNumBurnInSteps, fChain->Size()))};
278
280 for (Int_t i = 0; i < fDimension; i++)
281 paramsList.add(*fAxes[i]);
282
283 fKeysPdf = std::make_unique<RooNDKeysPdf>("keysPDF", "Keys PDF", paramsList, static_cast<RooDataSet&>(*chain), "a");
284 fCutoffVar = std::make_unique<RooRealVar>("cutoff", "cutoff", 0);
285 fHeaviside = std::make_unique<Heaviside>("heaviside", "Heaviside", *fKeysPdf, *fCutoffVar);
286 fProduct = std::make_unique<RooProduct>("product", "Keys PDF & Heaviside Product",
288}
289
290////////////////////////////////////////////////////////////////////////////////
291
293{
294 if (fAxes.empty() || fChain == nullptr) {
295 coutE(Eval) << "* Error in MCMCInterval::CreateHist(): " <<
296 "Crucial data member was nullptr." << std::endl;
297 coutE(Eval) << "Make sure to fully construct/initialize." << std::endl;
298 return;
299 }
300 fHist.reset();
301
302 if (fNumBurnInSteps >= fChain->Size()) {
304 "MCMCInterval::CreateHist: creation of histogram failed: " <<
305 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
306 "in Markov chain." << std::endl;
307 return;
308 }
309
310 if (fDimension == 1) {
311 fHist = std::make_unique<TH1F>("posterior", "MCMC Posterior Histogram",
312 fAxes[0]->numBins(), fAxes[0]->getMin(), fAxes[0]->getMax());
313
314 } else if (fDimension == 2) {
315 fHist = std::make_unique<TH2F>("posterior", "MCMC Posterior Histogram",
316 fAxes[0]->numBins(), fAxes[0]->getMin(), fAxes[0]->getMax(),
317 fAxes[1]->numBins(), fAxes[1]->getMin(), fAxes[1]->getMax());
318
319 } else if (fDimension == 3) {
320 fHist = std::make_unique<TH3F>("posterior", "MCMC Posterior Histogram",
321 fAxes[0]->numBins(), fAxes[0]->getMin(), fAxes[0]->getMax(),
322 fAxes[1]->numBins(), fAxes[1]->getMin(), fAxes[1]->getMax(),
323 fAxes[2]->numBins(), fAxes[2]->getMin(), fAxes[2]->getMax());
324
325 } else {
326 coutE(Eval) << "* Error in MCMCInterval::CreateHist() : " <<
327 "TH1* couldn't handle dimension: " << fDimension << std::endl;
328 return;
329 }
330
331 // Fill histogram
332 Int_t size = fChain->Size();
333 const RooArgSet* entry;
334 for (Int_t i = fNumBurnInSteps; i < size; i++) {
335 entry = fChain->Get(i);
336 if (fDimension == 1) {
337 (static_cast<TH1F&>(*fHist)).Fill(entry->getRealValue(fAxes[0]->GetName()),
338 fChain->Weight());
339 } else if (fDimension == 2) {
340 (static_cast<TH2F&>(*fHist)).Fill(entry->getRealValue(fAxes[0]->GetName()),
341 entry->getRealValue(fAxes[1]->GetName()),
342 fChain->Weight());
343 } else {
344 (static_cast<TH3F &>(*fHist))
345 .Fill(entry->getRealValue(fAxes[0]->GetName()), entry->getRealValue(fAxes[1]->GetName()),
346 entry->getRealValue(fAxes[2]->GetName()), fChain->Weight());
347 }
348 }
349
350 if (fDimension >= 1)
351 fHist->GetXaxis()->SetTitle(fAxes[0]->GetName());
352 if (fDimension >= 2)
353 fHist->GetYaxis()->SetTitle(fAxes[1]->GetName());
354 if (fDimension >= 3)
355 fHist->GetZaxis()->SetTitle(fAxes[2]->GetName());
356}
357
358////////////////////////////////////////////////////////////////////////////////
359
361{
362 if (fAxes.empty() || fChain == nullptr) {
363 coutE(InputArguments) << "* Error in MCMCInterval::CreateSparseHist(): "
364 << "Crucial data member was nullptr." << std::endl;
365 coutE(InputArguments) << "Make sure to fully construct/initialize."
366 << std::endl;
367 return;
368 }
369 std::vector<double> min(fDimension);
370 std::vector<double> max(fDimension);
371 std::vector<Int_t> bins(fDimension);
372 for (Int_t i = 0; i < fDimension; i++) {
373 min[i] = fAxes[i]->getMin();
374 max[i] = fAxes[i]->getMax();
375 bins[i] = fAxes[i]->numBins();
376 }
377 fSparseHist = std::make_unique<THnSparseF>("posterior", "MCMC Posterior Histogram",
378 fDimension, bins.data(), min.data(), max.data());
379
380 // kbelasco: it appears we need to call Sumw2() just to get the
381 // histogram to keep a running total of the weight so that Getsumw doesn't
382 // just return 0
383 fSparseHist->Sumw2();
384
385 if (fNumBurnInSteps >= fChain->Size()) {
387 "MCMCInterval::CreateSparseHist: creation of histogram failed: " <<
388 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
389 "in Markov chain." << std::endl;
390 }
391
392 // Fill histogram
393 Int_t size = fChain->Size();
394 const RooArgSet* entry;
395 std::vector<double> x(fDimension);
396 for (Int_t i = fNumBurnInSteps; i < size; i++) {
397 entry = fChain->Get(i);
398 for (Int_t ii = 0; ii < fDimension; ii++)
399 x[ii] = entry->getRealValue(fAxes[ii]->GetName());
400 fSparseHist->Fill(x.data(), fChain->Weight());
401 }
402}
403
404////////////////////////////////////////////////////////////////////////////////
405
407{
408 if (fParameters.empty() || fChain == nullptr) {
409 coutE(Eval) << "* Error in MCMCInterval::CreateDataHist(): " <<
410 "Crucial data member was nullptr or empty." << std::endl;
411 coutE(Eval) << "Make sure to fully construct/initialize." << std::endl;
412 return;
413 }
414
415 if (fNumBurnInSteps >= fChain->Size()) {
417 "MCMCInterval::CreateDataHist: creation of histogram failed: " <<
418 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
419 "in Markov chain." << std::endl;
420 fDataHist = nullptr;
421 return;
422 }
423
424 std::unique_ptr<RooAbsData> data{fChain->GetAsConstDataSet()->reduce(SelectVars(fParameters), EventRange(fNumBurnInSteps, fChain->Size()))};
425 fDataHist = std::unique_ptr<RooDataHist>{static_cast<RooDataSet &>(*data).binnedClone()};
426}
427
428////////////////////////////////////////////////////////////////////////////////
429
431{
432 fVector.clear();
433 fVecWeight = 0;
434
435 if (fChain == nullptr) {
436 coutE(InputArguments) << "* Error in MCMCInterval::CreateVector(): " <<
437 "Crucial data member (Markov chain) was nullptr." << std::endl;
438 coutE(InputArguments) << "Make sure to fully construct/initialize."
439 << std::endl;
440 return;
441 }
442
443 if (fNumBurnInSteps >= fChain->Size()) {
445 "MCMCInterval::CreateVector: creation of vector failed: " <<
446 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
447 "in Markov chain." << std::endl;
448 }
449
450 // Fill vector
451 Int_t size = fChain->Size() - fNumBurnInSteps;
452 fVector.resize(size);
453 Int_t i;
455 for (i = 0; i < size; i++) {
457 fVector[i] = chainIndex;
458 fVecWeight += fChain->Weight(chainIndex);
459 }
460
461 stable_sort(fVector.begin(), fVector.end(),
462 CompareVectorIndices(fChain.get(), param));
463}
464
465////////////////////////////////////////////////////////////////////////////////
466
468{
470 fParameters.add(parameters);
472 fAxes.resize(fDimension);
473 Int_t n = 0;
474 for (auto *obj : fParameters) {
475 if (dynamic_cast<RooRealVar *>(obj) != nullptr) {
476 fAxes[n] = static_cast<RooRealVar*>(obj);
477 } else {
478 coutE(Eval) << "* Error in MCMCInterval::SetParameters: " << obj->GetName() << " not a RooRealVar*"
479 << std::endl;
480 }
481 n++;
482 }
483}
484
485////////////////////////////////////////////////////////////////////////////////
486
488{
489 switch (fIntervalType) {
490 case kShortest:
492 break;
493 case kTailFraction:
495 break;
496 default:
497 coutE(InputArguments) << "MCMCInterval::DetermineInterval(): " <<
498 "Error: Interval type not set" << std::endl;
499 break;
500 }
501}
502
503////////////////////////////////////////////////////////////////////////////////
504
506{
507 if (fUseKeys) {
509 } else {
511 }
512}
513
514////////////////////////////////////////////////////////////////////////////////
515
517{
519 coutE(InputArguments) << "MCMCInterval::DetermineTailFractionInterval: "
520 << "Fraction must be in the range [0, 1]. "
521 << fLeftSideTF << "is not allowed." << std::endl;
522 return;
523 }
524
525 if (fDimension != 1) {
526 coutE(InputArguments) << "MCMCInterval::DetermineTailFractionInterval(): "
527 << "Error: Can only find a tail-fraction interval for 1-D intervals"
528 << std::endl;
529 return;
530 }
531
532 if (fAxes.empty()) {
533 coutE(InputArguments) << "MCMCInterval::DetermineTailFractionInterval(): "
534 << "Crucial data member was nullptr." << std::endl;
535 coutE(InputArguments) << "Make sure to fully construct/initialize."
536 << std::endl;
537 return;
538 }
539
540 // kbelasco: fill in code here to find interval
541 //
542 // also make changes so that calling GetPosterior...() returns nullptr
543 // when fIntervalType == kTailFraction, since there really
544 // is no posterior for this type of interval determination
545 if (fVector.empty())
547
548 if (fVector.empty() || fVecWeight == 0) {
549 // if size is still 0, then creation failed.
550 // if fVecWeight == 0, then there are no entries (indicates the same
551 // error as fVector.empty() because that only happens when
552 // fNumBurnInSteps >= fChain->Size())
553 // either way, reset and return
554 fVector.clear();
555 fTFLower = -1.0 * RooNumber::infinity();
557 fTFConfLevel = 0.0;
558 fVecWeight = 0;
559 return;
560 }
561
562 RooRealVar* param = fAxes[0];
563
564 double c = fConfidenceLevel;
565 double leftTailCutoff = fVecWeight * (1 - c) * fLeftSideTF;
566 double rightTailCutoff = fVecWeight * (1 - c) * (1 - fLeftSideTF);
567 double leftTailSum = 0;
568 double rightTailSum = 0;
569
570 // kbelasco: consider changing these values to +infinity and -infinity
571 double ll = param->getMin();
572 double ul = param->getMax();
573
574 double x;
575 double w;
576
577 // save a lot of GetName() calls if compiler does not already optimize this
578 const char* name = param->GetName();
579
580 // find lower limit
581 Int_t i;
582 for (i = 0; i < (Int_t)fVector.size(); i++) {
583 x = fChain->Get(fVector[i])->getRealValue(name);
584 w = fChain->Weight();
585
586 if (std::abs(leftTailSum + w - leftTailCutoff) <
587 std::abs(leftTailSum - leftTailCutoff)) {
588 // moving the lower limit to x would bring us closer to the desired
589 // left tail size
590 ll = x;
591 leftTailSum += w;
592 } else
593 break;
594 }
595
596 // find upper limit
597 for (i = (Int_t)fVector.size() - 1; i >= 0; i--) {
598 x = fChain->Get(fVector[i])->getRealValue(name);
599 w = fChain->Weight();
600
601 if (std::abs(rightTailSum + w - rightTailCutoff) <
602 std::abs(rightTailSum - rightTailCutoff)) {
603 // moving the lower limit to x would bring us closer to the desired
604 // left tail size
605 ul = x;
606 rightTailSum += w;
607 } else
608 break;
609 }
610
611 fTFLower = ll;
612 fTFUpper = ul;
614}
615
616////////////////////////////////////////////////////////////////////////////////
617
619{
620 if (fKeysPdf == nullptr)
622
623 if (fKeysPdf == nullptr) {
624 // if fKeysPdf is still nullptr, then it means CreateKeysPdf failed
625 // so clear all the data members this function would normally determine
626 // and return
627 fFull = 0.0;
628 fKeysCutoff = -1;
629 fKeysConfLevel = 0.0;
630 return;
631 }
632
633 // now we have a keys pdf of the posterior
634
635 double cutoff = 0.0;
636 fCutoffVar->setVal(cutoff);
637 double full = std::unique_ptr<RooAbsReal>{fProduct->createIntegral(fParameters, NormSet(fParameters))}->getVal(fParameters);
638 fFull = full;
639 if (full < 0.98) {
640 coutW(Eval) << "Warning: Integral of Keys PDF came out to " << full
641 << " instead of expected value 1. Will continue using this "
642 << "factor to normalize further integrals of this PDF." << std::endl;
643 }
644
645 // kbelasco: Is there a better way to set the search range?
646 // from 0 to max value of Keys
647 // kbelasco: how to get max value?
648 //double max = product.maxVal(product.getMaxVal(fParameters));
649
650 double volume = 1.0;
652 volume *= (var->getMax() - var->getMin());
653
654 double topCutoff = full / volume;
655 double bottomCutoff = topCutoff;
656 double confLevel = CalcConfLevel(topCutoff, full);
660 return;
661 }
662 bool changed = false;
663 // find high end of range
664 while (confLevel > fConfidenceLevel) {
665 topCutoff *= 2.0;
670 return;
671 }
672 changed = true;
673 }
674 if (changed) {
675 bottomCutoff = topCutoff / 2.0;
676 } else {
677 changed = false;
678 bottomCutoff /= 2.0;
683 return;
684 }
685 while (confLevel < fConfidenceLevel) {
686 bottomCutoff /= 2.0;
691 return;
692 }
693 changed = true;
694 }
695 if (changed) {
696 topCutoff = bottomCutoff * 2.0;
697 }
698 }
699
700 coutI(Eval) << "range set: [" << bottomCutoff << ", " << topCutoff << "]"
701 << std::endl;
702
703 cutoff = (topCutoff + bottomCutoff) / 2.0;
705
706 // need to use WithinDeltaFraction() because sometimes the integrating the
707 // posterior in this binary search seems to not have enough granularity to
708 // find an acceptable conf level (small no. of strange cases).
709 // WithinDeltaFraction causes the search to terminate when
710 // topCutoff is essentially equal to bottomCutoff (compared to the magnitude
711 // of their mean).
716 } else if (confLevel < fConfidenceLevel) {
718 }
719 cutoff = (topCutoff + bottomCutoff) / 2.0;
720 coutI(Eval) << "cutoff range: [" << bottomCutoff << ", "
721 << topCutoff << "]" << std::endl;
723 }
724
727}
728
729////////////////////////////////////////////////////////////////////////////////
730
732{
733 if (fUseSparseHist) {
735 } else {
737 }
738}
739
740////////////////////////////////////////////////////////////////////////////////
741
743{
744 Long_t numBins;
745 if (fSparseHist == nullptr)
747
748 if (fSparseHist == nullptr) {
749 // if fSparseHist is still nullptr, then CreateSparseHist failed
750 fHistCutoff = -1;
751 fHistConfLevel = 0.0;
752 return;
753 }
754
755 numBins = (Long_t)fSparseHist->GetNbins();
756
757 std::vector<Long_t> bins(numBins);
758 for (Int_t ibin = 0; ibin < numBins; ibin++)
759 bins[ibin] = (Long_t)ibin;
760 std::stable_sort(bins.begin(), bins.end(), CompareSparseHistBins(fSparseHist.get()));
761
762 double nEntries = fSparseHist->GetSumw();
763 double sum = 0;
764 double content;
765 Int_t i;
766 // see above note on indexing to understand numBins - 3
767 for (i = numBins - 1; i >= 0; i--) {
768 content = fSparseHist->GetBinContent(bins[i]);
769 if ((sum + content) / nEntries >= fConfidenceLevel) {
771 if (fIsHistStrict) {
772 sum += content;
773 i--;
774 break;
775 } else {
776 i++;
777 break;
778 }
779 }
780 sum += content;
781 }
782
783 if (fIsHistStrict) {
784 // keep going to find the sum
785 for ( ; i >= 0; i--) {
786 content = fSparseHist->GetBinContent(bins[i]);
787 if (content == fHistCutoff) {
788 sum += content;
789 } else {
790 break; // content must be < fHistCutoff
791 }
792 }
793 } else {
794 // backtrack to find the cutoff and sum
795 for ( ; i < numBins; i++) {
796 content = fSparseHist->GetBinContent(bins[i]);
797 if (content > fHistCutoff) {
799 break;
800 } else // content == fHistCutoff
801 sum -= content;
802 if (i == numBins - 1) {
803 // still haven't set fHistCutoff correctly yet, and we have no bins
804 // left, so set fHistCutoff to something higher than the tallest bin
805 fHistCutoff = content + 1.0;
806 }
807 }
808 }
809
811}
812
813////////////////////////////////////////////////////////////////////////////////
814
816{
817 Int_t numBins;
818 if (fDataHist == nullptr)
820 if (fDataHist == nullptr) {
821 // if fDataHist is still nullptr, then CreateDataHist failed
822 fHistCutoff = -1;
823 fHistConfLevel = 0.0;
824 return;
825 }
826
827 numBins = fDataHist->numEntries();
828
829 std::vector<Int_t> bins(numBins);
830 for (Int_t ibin = 0; ibin < numBins; ibin++)
831 bins[ibin] = ibin;
832 std::stable_sort(bins.begin(), bins.end(), CompareDataHistBins(fDataHist.get()));
833
834 double nEntries = fDataHist->sum(false);
835 double sum = 0;
836 double content;
837 Int_t i;
838 for (i = numBins - 1; i >= 0; i--) {
839 content = fDataHist->weight(bins[i]);
840 if ((sum + content) / nEntries >= fConfidenceLevel) {
842 if (fIsHistStrict) {
843 sum += content;
844 i--;
845 break;
846 } else {
847 i++;
848 break;
849 }
850 }
851 sum += content;
852 }
853
854 if (fIsHistStrict) {
855 // keep going to find the sum
856 for ( ; i >= 0; i--) {
857 content = fDataHist->weight(bins[i]);
858 if (content == fHistCutoff) {
859 sum += content;
860 } else {
861 break; // content must be < fHistCutoff
862 }
863 }
864 } else {
865 // backtrack to find the cutoff and sum
866 for ( ; i < numBins; i++) {
867 content = fDataHist->weight(bins[i]);
868 if (content > fHistCutoff) {
870 break;
871 } else // content == fHistCutoff
872 sum -= content;
873 if (i == numBins - 1) {
874 // still haven't set fHistCutoff correctly yet, and we have no bins
875 // left, so set fHistCutoff to something higher than the tallest bin
876 fHistCutoff = content + 1.0;
877 }
878 }
879 }
880
882}
883
884////////////////////////////////////////////////////////////////////////////////
885
887{
888 if (fIntervalType == kShortest) {
889 if (fUseKeys) {
890 return fKeysConfLevel;
891 } else {
892 return fHistConfLevel;
893 }
894 } else if (fIntervalType == kTailFraction) {
895 return fTFConfLevel;
896 } else {
897 coutE(InputArguments) << "MCMCInterval::GetActualConfidenceLevel: "
898 << "not implemented for this type of interval. Returning 0." << std::endl;
899 return 0;
900 }
901}
902
903////////////////////////////////////////////////////////////////////////////////
904
906{
907 switch (fIntervalType) {
908 case kShortest:
909 return LowerLimitShortest(param);
910 case kTailFraction:
911 return LowerLimitTailFraction(param);
912 default:
913 coutE(InputArguments) << "MCMCInterval::LowerLimit(): " <<
914 "Error: Interval type not set" << std::endl;
915 return RooNumber::infinity();
916 }
917}
918
919////////////////////////////////////////////////////////////////////////////////
920
922{
923 switch (fIntervalType) {
924 case kShortest:
925 return UpperLimitShortest(param);
926 case kTailFraction:
927 return UpperLimitTailFraction(param);
928 default:
929 coutE(InputArguments) << "MCMCInterval::UpperLimit(): " <<
930 "Error: Interval type not set" << std::endl;
931 return RooNumber::infinity();
932 }
933}
934
935////////////////////////////////////////////////////////////////////////////////
936
938{
939 if (fTFLower == -1.0 * RooNumber::infinity())
941
942 return fTFLower;
943}
944
945////////////////////////////////////////////////////////////////////////////////
946
954
955////////////////////////////////////////////////////////////////////////////////
956
958{
959 if (fUseKeys) {
960 return LowerLimitByKeys(param);
961 } else {
962 return LowerLimitByHist(param);
963 }
964}
965
966////////////////////////////////////////////////////////////////////////////////
967
969{
970 if (fUseKeys) {
971 return UpperLimitByKeys(param);
972 } else {
973 return UpperLimitByHist(param);
974 }
975}
976
977////////////////////////////////////////////////////////////////////////////////
978/// Determine the lower limit for param on this interval
979/// using the binned data set
980
982{
983 if (fUseSparseHist) {
984 return LowerLimitBySparseHist(param);
985 } else {
986 return LowerLimitByDataHist(param);
987 }
988}
989
990////////////////////////////////////////////////////////////////////////////////
991/// Determine the upper limit for param on this interval
992/// using the binned data set
993
995{
996 if (fUseSparseHist) {
997 return UpperLimitBySparseHist(param);
998 } else {
999 return UpperLimitByDataHist(param);
1000 }
1001}
1002
1003////////////////////////////////////////////////////////////////////////////////
1004/// Determine the lower limit for param on this interval
1005/// using the binned data set
1006
1008{
1009 if (fDimension != 1) {
1010 coutE(InputArguments) << "In MCMCInterval::LowerLimitBySparseHist: "
1011 << "Sorry, will not compute lower limit unless dimension == 1" << std::endl;
1012 return param.getMin();
1013 }
1014 if (fHistCutoff < 0)
1015 DetermineBySparseHist(); // this initializes fSparseHist
1016
1017 if (fHistCutoff < 0) {
1018 // if fHistCutoff < 0 still, then determination of interval failed
1019 coutE(Eval) << "In MCMCInterval::LowerLimitBySparseHist: "
1020 << "couldn't determine cutoff. Check that num burn in steps < num "
1021 << "steps in the Markov chain. Returning param.getMin()." << std::endl;
1022 return param.getMin();
1023 }
1024
1025 std::vector<Int_t> coord(fDimension);
1026 for (Int_t d = 0; d < fDimension; d++) {
1027 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1028 Long_t numBins = (Long_t)fSparseHist->GetNbins();
1029 double lowerLimit = param.getMax();
1030 double val;
1031 for (Long_t i = 0; i < numBins; i++) {
1032 if (fSparseHist->GetBinContent(i, &coord[0]) >= fHistCutoff) {
1033 val = fSparseHist->GetAxis(d)->GetBinCenter(coord[d]);
1034 if (val < lowerLimit)
1035 lowerLimit = val;
1036 }
1037 }
1038 return lowerLimit;
1039 }
1040 }
1041 return param.getMin();
1042}
1043
1044////////////////////////////////////////////////////////////////////////////////
1045/// Determine the lower limit for param on this interval
1046/// using the binned data set
1047
1049{
1050 if (fHistCutoff < 0)
1051 DetermineByDataHist(); // this initializes fDataHist
1052
1053 if (fHistCutoff < 0) {
1054 // if fHistCutoff < 0 still, then determination of interval failed
1055 coutE(Eval) << "In MCMCInterval::LowerLimitByDataHist: "
1056 << "couldn't determine cutoff. Check that num burn in steps < num "
1057 << "steps in the Markov chain. Returning param.getMin()." << std::endl;
1058 return param.getMin();
1059 }
1060
1061 for (Int_t d = 0; d < fDimension; d++) {
1062 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1063 Int_t numBins = fDataHist->numEntries();
1064 double lowerLimit = param.getMax();
1065 double val;
1066 for (Int_t i = 0; i < numBins; i++) {
1067 if (fDataHist->weight(i) >= fHistCutoff) {
1068 val = fDataHist->get(i)->getRealValue(param.GetName());
1069 if (val < lowerLimit)
1070 lowerLimit = val;
1071 }
1072 }
1073 return lowerLimit;
1074 }
1075 }
1076 return param.getMin();
1077}
1078
1079////////////////////////////////////////////////////////////////////////////////
1080/// Determine the upper limit for param on this interval
1081/// using the binned data set
1082
1084{
1085 if (fDimension != 1) {
1086 coutE(InputArguments) << "In MCMCInterval::UpperLimitBySparseHist: "
1087 << "Sorry, will not compute upper limit unless dimension == 1" << std::endl;
1088 return param.getMax();
1089 }
1090 if (fHistCutoff < 0)
1091 DetermineBySparseHist(); // this initializes fSparseHist
1092
1093 if (fHistCutoff < 0) {
1094 // if fHistCutoff < 0 still, then determination of interval failed
1095 coutE(Eval) << "In MCMCInterval::UpperLimitBySparseHist: "
1096 << "couldn't determine cutoff. Check that num burn in steps < num "
1097 << "steps in the Markov chain. Returning param.getMax()." << std::endl;
1098 return param.getMax();
1099 }
1100
1101 std::vector<Int_t> coord(fDimension);
1102 for (Int_t d = 0; d < fDimension; d++) {
1103 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1104 Long_t numBins = (Long_t)fSparseHist->GetNbins();
1105 double upperLimit = param.getMin();
1106 double val;
1107 for (Long_t i = 0; i < numBins; i++) {
1108 if (fSparseHist->GetBinContent(i, &coord[0]) >= fHistCutoff) {
1109 val = fSparseHist->GetAxis(d)->GetBinCenter(coord[d]);
1110 if (val > upperLimit)
1111 upperLimit = val;
1112 }
1113 }
1114 return upperLimit;
1115 }
1116 }
1117 return param.getMax();
1118}
1119
1120////////////////////////////////////////////////////////////////////////////////
1121/// Determine the upper limit for param on this interval
1122/// using the binned data set
1123
1125{
1126 if (fHistCutoff < 0)
1127 DetermineByDataHist(); // this initializes fDataHist
1128
1129 if (fHistCutoff < 0) {
1130 // if fHistCutoff < 0 still, then determination of interval failed
1131 coutE(Eval) << "In MCMCInterval::UpperLimitByDataHist: "
1132 << "couldn't determine cutoff. Check that num burn in steps < num "
1133 << "steps in the Markov chain. Returning param.getMax()." << std::endl;
1134 return param.getMax();
1135 }
1136
1137 for (Int_t d = 0; d < fDimension; d++) {
1138 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1139 Int_t numBins = fDataHist->numEntries();
1140 double upperLimit = param.getMin();
1141 double val;
1142 for (Int_t i = 0; i < numBins; i++) {
1143 if (fDataHist->weight(i) >= fHistCutoff) {
1144 val = fDataHist->get(i)->getRealValue(param.GetName());
1145 if (val > upperLimit)
1146 upperLimit = val;
1147 }
1148 }
1149 return upperLimit;
1150 }
1151 }
1152 return param.getMax();
1153}
1154
1155////////////////////////////////////////////////////////////////////////////////
1156/// Determine the lower limit for param on this interval
1157/// using the keys pdf
1158
1160{
1161 if (fKeysCutoff < 0)
1163
1164 if (fKeysDataHist == nullptr)
1166
1167 if (fKeysCutoff < 0 || fKeysDataHist == nullptr) {
1168 // failure in determination of cutoff and/or creation of histogram
1169 coutE(Eval) << "in MCMCInterval::LowerLimitByKeys(): "
1170 << "couldn't find lower limit, check that the number of burn in "
1171 << "steps < number of total steps in the Markov chain. Returning "
1172 << "param.getMin()" << std::endl;
1173 return param.getMin();
1174 }
1175
1176 for (Int_t d = 0; d < fDimension; d++) {
1177 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1178 Int_t numBins = fKeysDataHist->numEntries();
1179 double lowerLimit = param.getMax();
1180 double val;
1181 for (Int_t i = 0; i < numBins; i++) {
1182 if (fKeysDataHist->weight(i) >= fKeysCutoff) {
1183 val = fKeysDataHist->get(i)->getRealValue(param.GetName());
1184 if (val < lowerLimit)
1185 lowerLimit = val;
1186 }
1187 }
1188 return lowerLimit;
1189 }
1190 }
1191 return param.getMin();
1192}
1193
1194////////////////////////////////////////////////////////////////////////////////
1195/// Determine the upper limit for param on this interval
1196/// using the keys pdf
1197
1199{
1200 if (fKeysCutoff < 0)
1202
1203 if (fKeysDataHist == nullptr)
1205
1206 if (fKeysCutoff < 0 || fKeysDataHist == nullptr) {
1207 // failure in determination of cutoff and/or creation of histogram
1208 coutE(Eval) << "in MCMCInterval::UpperLimitByKeys(): "
1209 << "couldn't find upper limit, check that the number of burn in "
1210 << "steps < number of total steps in the Markov chain. Returning "
1211 << "param.getMax()" << std::endl;
1212 return param.getMax();
1213 }
1214
1215 for (Int_t d = 0; d < fDimension; d++) {
1216 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1217 Int_t numBins = fKeysDataHist->numEntries();
1218 double upperLimit = param.getMin();
1219 double val;
1220 for (Int_t i = 0; i < numBins; i++) {
1221 if (fKeysDataHist->weight(i) >= fKeysCutoff) {
1222 val = fKeysDataHist->get(i)->getRealValue(param.GetName());
1223 if (val > upperLimit)
1224 upperLimit = val;
1225 }
1226 }
1227 return upperLimit;
1228 }
1229 }
1230 return param.getMax();
1231}
1232
1233////////////////////////////////////////////////////////////////////////////////
1234/// Determine the approximate maximum value of the Keys PDF
1235
1237{
1238 if (fKeysCutoff < 0)
1240
1241 if (fKeysDataHist == nullptr)
1243
1244 if (fKeysDataHist == nullptr) {
1245 // failure in determination of cutoff and/or creation of histogram
1246 coutE(Eval) << "in MCMCInterval::KeysMax(): "
1247 << "couldn't find Keys max value, check that the number of burn in "
1248 << "steps < number of total steps in the Markov chain. Returning 0"
1249 << std::endl;
1250 return 0;
1251 }
1252
1253 Int_t numBins = fKeysDataHist->numEntries();
1254 double max = 0;
1255 double w;
1256 for (Int_t i = 0; i < numBins; i++) {
1257 w = fKeysDataHist->weight(i);
1258 if (w > max)
1259 max = w;
1260 }
1261
1262 return max;
1263}
1264
1265////////////////////////////////////////////////////////////////////////////////
1266
1268{
1269 if (fHistCutoff < 0)
1271
1272 return fHistCutoff;
1273}
1274
1275////////////////////////////////////////////////////////////////////////////////
1276
1278{
1279 if (fKeysCutoff < 0)
1281
1282 // kbelasco: if fFull hasn't been set (because Keys creation failed because
1283 // fNumBurnInSteps >= fChain->Size()) then this will return infinity, which
1284 // seems ok to me since it will indicate error
1285
1286 return fKeysCutoff / fFull;
1287}
1288
1289////////////////////////////////////////////////////////////////////////////////
1290
1291double MCMCInterval::CalcConfLevel(double cutoff, double full)
1292{
1293 fCutoffVar->setVal(cutoff);
1294 std::unique_ptr<RooAbsReal> integral{fProduct->createIntegral(fParameters, NormSet(fParameters))};
1295 double confLevel = integral->getVal(fParameters) / full;
1296 coutI(Eval) << "cutoff = " << cutoff << ", conf = " << confLevel << std::endl;
1297 return confLevel;
1298}
1299
1300////////////////////////////////////////////////////////////////////////////////
1301
1303{
1304 if (fConfidenceLevel == 0) {
1305 coutE(InputArguments) << "Error in MCMCInterval::GetPosteriorHist: "
1306 << "confidence level not set " << std::endl;
1307 }
1308 if (fHist == nullptr)
1309 CreateHist();
1310
1311 if (fHist == nullptr) {
1312 // if fHist is still nullptr, then CreateHist failed
1313 return nullptr;
1314 }
1315
1316 return static_cast<TH1*>(fHist->Clone("MCMCposterior_hist"));
1317}
1318
1319////////////////////////////////////////////////////////////////////////////////
1320
1322{
1323 if (fConfidenceLevel == 0) {
1324 coutE(InputArguments) << "Error in MCMCInterval::GetPosteriorKeysPdf: "
1325 << "confidence level not set " << std::endl;
1326 }
1327 if (fKeysPdf == nullptr)
1328 CreateKeysPdf();
1329
1330 if (fKeysPdf == nullptr) {
1331 // if fKeysPdf is still nullptr, then it means CreateKeysPdf failed
1332 return nullptr;
1333 }
1334
1335 return static_cast<RooNDKeysPdf*>(fKeysPdf->Clone("MCMCPosterior_keys"));
1336}
1337
1338////////////////////////////////////////////////////////////////////////////////
1339
1341{
1342 if (fConfidenceLevel == 0) {
1343 coutE(InputArguments) << "MCMCInterval::GetPosteriorKeysProduct: "
1344 << "confidence level not set " << std::endl;
1345 }
1346 if (fProduct == nullptr) {
1347 CreateKeysPdf();
1349 }
1350
1351 if (fProduct == nullptr) {
1352 // if fProduct is still nullptr, then it means CreateKeysPdf failed
1353 return nullptr;
1354 }
1355
1356 return static_cast<RooProduct*>(fProduct->Clone("MCMCPosterior_keysproduct"));
1357}
1358
1359////////////////////////////////////////////////////////////////////////////////
1360
1362{
1363 // returns list of parameters
1364 return new RooArgSet(fParameters);
1365}
1366
1367////////////////////////////////////////////////////////////////////////////////
1368
1370{
1371 return (std::abs(confLevel - fConfidenceLevel) < fEpsilon);
1372}
1373
1374////////////////////////////////////////////////////////////////////////////////
1375
1377{
1378 return (std::abs(a - b) < std::abs(fDelta * (a + b)/2));
1379}
1380
1381////////////////////////////////////////////////////////////////////////////////
1382
1384{
1385 if (fAxes.empty())
1386 return;
1387 if (fProduct == nullptr)
1389 if (fProduct == nullptr) {
1390 // if fProduct still nullptr, then creation failed
1391 return;
1392 }
1393
1394 //RooAbsBinning** savedBinning = new RooAbsBinning*[fDimension];
1395 std::vector<Int_t> savedBins(fDimension);
1396 Int_t i;
1397 double numBins;
1398 RooRealVar* var;
1399
1400 // kbelasco: Note - the accuracy is only increased here if the binning for
1401 // each RooRealVar is uniform
1402
1403 // kbelasco: look into why saving the binnings and replacing them doesn't
1404 // work (replaces with 1 bin always).
1405 // Note: this code modifies the binning for the parameters (if they are
1406 // uniform) and sets them back to what they were. If the binnings are not
1407 // uniform, this code does nothing.
1408
1409 // first scan through fAxes to make sure all binnings are uniform, or else
1410 // we can't change the number of bins because there seems to be an error
1411 // when setting the binning itself rather than just the number of bins
1412 bool tempChangeBinning = true;
1413 for (i = 0; i < fDimension; i++) {
1414 if (!fAxes[i]->getBinning(nullptr, false, false).isUniform()) {
1415 tempChangeBinning = false;
1416 break;
1417 }
1418 }
1419
1420 // kbelasco: for 1 dimension this should be fine, but for more dimensions
1421 // the total number of bins in the histogram increases exponentially with
1422 // the dimension, so don't do this above 1-D for now.
1423 if (fDimension >= 2)
1424 tempChangeBinning = false;
1425
1426 if (tempChangeBinning) {
1427 // set high number of bins for high accuracy on lower/upper limit by keys
1428 for (i = 0; i < fDimension; i++) {
1429 var = fAxes[i];
1430 //savedBinning[i] = &var->getBinning("__binning_clone", false, true);
1431 savedBins[i] = var->getBinning(nullptr, false, false).numBins();
1432 numBins = (var->getMax() - var->getMin()) / fEpsilon;
1433 var->setBins((Int_t)numBins);
1434 }
1435 }
1436
1437 fKeysDataHist = std::make_unique<RooDataHist>("_productDataHist",
1438 "Keys PDF & Heaviside Product Data Hist", fParameters);
1439 fProduct->fillDataHist(fKeysDataHist.get(), &fParameters, 1.);
1440
1441 if (tempChangeBinning) {
1442 // set the binning back to normal
1443 for (i = 0; i < fDimension; i++) {
1444 //fAxes[i]->setBinning(*savedBinning[i], nullptr);
1445 //fAxes[i]->setBins(savedBinning[i]->numBins(), nullptr);
1446 fAxes[i]->setBins(savedBins[i], nullptr);
1447 }
1448 }
1449}
1450
1451////////////////////////////////////////////////////////////////////////////////
1452
1454{
1455 // check that the parameters are correct
1456
1457 if (parameterPoint.size() != fParameters.size() ) {
1458 coutE(Eval) << "MCMCInterval: size is wrong, parameters don't match" << std::endl;
1459 return false;
1460 }
1461 if ( ! parameterPoint.equals( fParameters ) ) {
1462 coutE(Eval) << "MCMCInterval: size is ok, but parameters don't match" << std::endl;
1463 return false;
1464 }
1465 return true;
1466}
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define coutI(a)
#define coutW(a)
#define coutE(a)
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:68
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
char name[80]
Definition TGX11.cxx:148
TRObject operator()(const T1 &t1) const
double getRealValue(const char *name, double defVal=0.0, bool verbose=false) const
Get value of a RooAbsReal stored in set with given name.
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Storage_t::size_type size() const
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.
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:22
RooAbsArg * at(Int_t idx) const
Return object at given index, or nullptr if index is out of range.
Definition RooArgList.h:110
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
Container class to hold N-dimensional binned data.
Definition RooDataHist.h:40
Container class to hold unbinned data.
Definition RooDataSet.h:32
RooFit::OwningPtr< RooDataHist > binnedClone(const char *newName=nullptr, const char *newTitle=nullptr) const
Return binned clone of this dataset.
Generic N-dimensional implementation of a kernel estimation p.d.f.
static constexpr double infinity()
Return internal infinity representation.
Definition RooNumber.h:25
Represents the product of a given set of RooAbsReal objects.
Definition RooProduct.h:29
Variable that can be changed from the outside.
Definition RooRealVar.h:37
void setBins(Int_t nBins, const char *name=nullptr, bool shared=true)
Create a uniform binning under name 'name' for this variable.
const RooAbsBinning & getBinning(const char *name=nullptr, bool verbose=true, bool createOnTheFly=false, bool shared=true) const override
Return binning definition with name.
ConfInterval is an interface class for a generic interval in the RooStats framework.
virtual void CreateDataHist()
virtual void DetermineByDataHist()
virtual void DetermineShortestInterval()
virtual double GetActualConfidenceLevel()
virtual double GetKeysPdfCutoff() { return fKeysCutoff; }
double fKeysConfLevel
the actual conf level determined by keys
virtual void CreateVector(RooRealVar *param)
std::unique_ptr< Heaviside > fHeaviside
the Heaviside function
virtual double LowerLimitByDataHist(RooRealVar &param)
determine lower limit using histogram
double fDelta
topCutoff (a) considered == bottomCutoff (b) iff (std::abs(a - b) < std::abs(fDelta * (a + b)/2)); Th...
double fConfidenceLevel
Requested confidence level (eg. 0.95 for 95% CL)
virtual double UpperLimitBySparseHist(RooRealVar &param)
determine upper limit using histogram
std::unique_ptr< MarkovChain > fChain
the markov chain
enum IntervalType fIntervalType
virtual double UpperLimit(RooRealVar &param)
get the highest value of param that is within the confidence interval
std::unique_ptr< RooDataHist > fDataHist
the binned Markov Chain data
virtual void SetAxes(RooArgList &axes)
Set which parameters go on which axis.
virtual void DetermineByKeys()
double fTFLower
lower limit of the tail-fraction interval
bool fUseSparseHist
whether to use sparse hist (vs. RooDataHist)
double fVecWeight
sum of weights of all entries in fVector
double fLeftSideTF
left side tail-fraction for interval
bool AcceptableConfLevel(double confLevel)
virtual void DetermineBySparseHist()
double GetKeysMax()
Determine the approximate maximum value of the Keys PDF.
virtual double LowerLimitBySparseHist(RooRealVar &param)
determine lower limit using histogram
bool WithinDeltaFraction(double a, double b)
double fKeysCutoff
cutoff keys pdf value to be in interval
virtual double LowerLimitShortest(RooRealVar &param)
get the lower limit of param in the shortest confidence interval Note that this works better for some...
virtual double LowerLimitTailFraction(RooRealVar &param)
determine lower limit of the lower confidence interval
virtual TH1 * GetPosteriorHist()
set the number of bins to use (same for all axes, for now) virtual void SetNumBins(Int_t numBins);
std::unique_ptr< RooRealVar > fCutoffVar
cutoff variable to use for integrating keys pdf
Int_t fDimension
number of variables
void SetConfidenceLevel(double cl) override
set the desired confidence level (see GetActualConfidenceLevel()) Note: calling this function trigger...
MCMCInterval(const char *name=nullptr)
default constructor
std::unique_ptr< RooProduct > fProduct
the (keysPdf * heaviside) product
std::vector< RooRealVar * > fAxes
array of pointers to RooRealVars representing
virtual void DetermineTailFractionInterval()
double fTFConfLevel
the actual conf level of tail-fraction interval
double fHistConfLevel
the actual conf level determined by hist
virtual void CreateSparseHist()
double fFull
Value of intergral of fProduct.
std::unique_ptr< RooDataHist > fKeysDataHist
data hist representing product
virtual double UpperLimitByDataHist(RooRealVar &param)
determine upper limit using histogram
virtual void DetermineInterval()
std::unique_ptr< TH1 > fHist
the binned Markov Chain data
virtual double CalcConfLevel(double cutoff, double full)
virtual double LowerLimitByHist(RooRealVar &param)
determine lower limit using histogram
virtual double LowerLimit(RooRealVar &param)
get the lowest value of param that is within the confidence interval
virtual double UpperLimitShortest(RooRealVar &param)
get the upper limit of param in the confidence interval Note that this works better for some distribu...
bool CheckParameters(const RooArgSet &point) const override
check if parameters are correct. (dummy implementation to start)
std::vector< Int_t > fVector
vector containing the Markov chain data
virtual double LowerLimitByKeys(RooRealVar &param)
determine lower limit in the shortest interval by using keys pdf
virtual RooProduct * GetPosteriorKeysProduct()
Get a clone of the (keyspdf * heaviside) product of the posterior.
double fTFUpper
upper limit of the tail-fraction interval
double fHistCutoff
cutoff bin size to be in interval
RooArgSet * GetParameters() const override
return a set containing the parameters of this interval the caller owns the returned RooArgSet*
std::unique_ptr< RooNDKeysPdf > fKeysPdf
the kernel estimation pdf
virtual double UpperLimitTailFraction(RooRealVar &param)
determine upper limit of the lower confidence interval
bool fIsHistStrict
whether the specified confidence level is a floor for the actual confidence level (strict),...
virtual RooNDKeysPdf * GetPosteriorKeysPdf()
Get a clone of the keys pdf of the posterior.
virtual double UpperLimitByHist(RooRealVar &param)
determine upper limit using histogram
virtual void CreateKeysPdf()
virtual double UpperLimitByKeys(RooRealVar &param)
determine upper limit in the shortest interval by using keys pdf
Int_t fNumBurnInSteps
number of steps to discard as burn in, starting from the first
std::unique_ptr< THnSparse > fSparseHist
the binned Markov Chain data
virtual void CreateHist()
bool fUseKeys
whether to use kernel estimation
RooArgSet fParameters
parameters of interest for this interval
bool IsInInterval(const RooArgSet &point) const override
determine whether this point is in the confidence interval
virtual void DetermineByHist()
virtual void SetParameters(const RooArgSet &parameters)
Set the parameters of interest for this interval and change other internal data members accordingly.
virtual void CreateKeysDataHist()
double fEpsilon
acceptable error for Keys interval determination
virtual double GetKeysPdfCutoff()
get the cutoff RooNDKeysPdf value for being considered in the confidence interval
virtual double GetHistCutoff()
get the cutoff bin height for being considered in the confidence interval
Stores the steps in a Markov Chain of points.
Definition MarkovChain.h:26
1-D histogram with a float per channel (see TH1 documentation)
Definition TH1.h:878
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
2-D histogram with a float per channel (see TH1 documentation)
Definition TH2.h:345
3-D histogram with a float per channel (see TH1 documentation)
Definition TH3.h:369
Efficient multidimensional histogram.
Definition THnSparse.h:37
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
RooCmdArg SelectVars(const RooArgSet &vars)
RooCmdArg EventRange(Int_t nStart, Int_t nStop)
RooCmdArg NormSet(Args_t &&... argsOrArgSet)
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition CodegenImpl.h:72
@ InputArguments
Namespace for the RooStats classes.
Definition CodegenImpl.h:66
void SetParameters(const RooArgSet *desiredVals, RooArgSet *paramsToChange)
RooDataHist * fDataHist
CompareDataHistBins(RooDataHist *hist)
CompareSparseHistBins(THnSparse *hist)
CompareVectorIndices(MarkovChain *chain, RooRealVar *param)
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2338