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
86
87using namespace RooFit;
88using namespace RooStats;
89using namespace std;
90
91static const double DEFAULT_EPSILON = 0.01;
92static const double DEFAULT_DELTA = 10e-6;
93
94////////////////////////////////////////////////////////////////////////////////
95
98{
99 fConfidenceLevel = 0.0;
100 fHistConfLevel = 0.0;
101 fKeysConfLevel = 0.0;
102 fTFConfLevel = 0.0;
103 fFull = 0.0;
104 fChain = nullptr;
105 fAxes = nullptr;
106 fDataHist = nullptr;
107 fSparseHist = nullptr;
108 fVector.clear();
109 fKeysPdf = nullptr;
110 fProduct = nullptr;
111 fHeaviside = nullptr;
112 fKeysDataHist = nullptr;
113 fCutoffVar = nullptr;
114 fHist = nullptr;
115 fNumBurnInSteps = 0;
116 fHistCutoff = -1;
117 fKeysCutoff = -1;
118 fDimension = 1;
119 fUseKeys = false;
120 fUseSparseHist = false;
121 fIsHistStrict = true;
125 fTFLower = -1.0 * RooNumber::infinity();
127 fVecWeight = 0;
128 fLeftSideTF = -1;
129}
130
131////////////////////////////////////////////////////////////////////////////////
132
134 const RooArgSet& parameters, MarkovChain& chain) : ConfInterval(name)
135{
136 fNumBurnInSteps = 0;
137 fConfidenceLevel = 0.0;
138 fHistConfLevel = 0.0;
139 fKeysConfLevel = 0.0;
140 fTFConfLevel = 0.0;
141 fFull = 0.0;
142 fAxes = nullptr;
143 fChain = &chain;
144 fDataHist = nullptr;
145 fSparseHist = nullptr;
146 fVector.clear();
147 fKeysPdf = nullptr;
148 fProduct = nullptr;
149 fHeaviside = nullptr;
150 fKeysDataHist = nullptr;
151 fCutoffVar = nullptr;
152 fHist = nullptr;
153 fHistCutoff = -1;
154 fKeysCutoff = -1;
155 fUseKeys = false;
156 fUseSparseHist = false;
157 fIsHistStrict = true;
159 SetParameters(parameters);
162 fTFLower = -1.0 * RooNumber::infinity();
164 fVecWeight = 0;
165 fLeftSideTF = -1;
166}
167
168////////////////////////////////////////////////////////////////////////////////
169
171{
172 // destructor
173 delete[] fAxes;
174 delete fHist;
175 delete fChain;
176 // kbelasco: check here for memory management errors
177 delete fDataHist;
178 delete fSparseHist;
179 delete fKeysPdf;
180 delete fProduct;
181 delete fHeaviside;
182 delete fKeysDataHist;
183 delete fCutoffVar;
184}
185
187 CompareDataHistBins(RooDataHist* hist) : fDataHist(hist) {}
188 bool operator() (Int_t bin1 , Int_t bin2) {
189 fDataHist->get(bin1);
190 double n1 = fDataHist->weight();
191 fDataHist->get(bin2);
192 double n2 = fDataHist->weight();
193 return (n1 < n2);
194 }
196};
197
199 CompareSparseHistBins(THnSparse* hist) : fSparseHist(hist) {}
200 bool operator() (Long_t bin1, Long_t bin2) {
201 double n1 = fSparseHist->GetBinContent(bin1);
202 double n2 = fSparseHist->GetBinContent(bin2);
203 return (n1 < n2);
204 }
206};
207
210 fChain(chain), fParam(param) {}
212 double xi = fChain->Get(i)->getRealValue(fParam->GetName());
213 double xj = fChain->Get(j)->getRealValue(fParam->GetName());
214 return (xi < xj);
215 }
218};
219
220////////////////////////////////////////////////////////////////////////////////
221/// kbelasco: for this method, consider running DetermineInterval() if
222/// fKeysPdf==nullptr, fSparseHist==nullptr, fDataHist==nullptr, or fVector.empty()
223/// rather than just returning false. Though this should not be an issue
224/// because nobody should be able to get an MCMCInterval that has their interval
225/// or posterior representation nullptr/empty since they should only get this
226/// through the MCMCCalculator
227
228bool MCMCInterval::IsInInterval(const RooArgSet& point) const
229{
230 if (fIntervalType == kShortest) {
231 if (fUseKeys) {
232 if (fKeysPdf == nullptr)
233 return false;
234
235 // evaluate keyspdf at point and return whether >= cutoff
236 RooStats::SetParameters(&point, const_cast<RooArgSet *>(&fParameters));
238 } else {
239 if (fUseSparseHist) {
240 if (fSparseHist == nullptr)
241 return false;
242
243 // evaluate sparse hist at bin where point lies and return
244 // whether >= cutoff
246 const_cast<RooArgSet*>(&fParameters));
247 Long_t bin;
248 // kbelasco: consider making x static
249 std::vector<double> x(fDimension);
250 for (Int_t i = 0; i < fDimension; i++)
251 x[i] = fAxes[i]->getVal();
252 bin = fSparseHist->GetBin(x.data(), false);
253 double weight = fSparseHist->GetBinContent((Long64_t)bin);
254 return (weight >= (double)fHistCutoff);
255 } else {
256 if (fDataHist == nullptr)
257 return false;
258
259 // evaluate data hist at bin where point lies and return whether
260 // >= cutoff
261 Int_t bin;
262 bin = fDataHist->getIndex(point);
263 fDataHist->get(bin);
264 return (fDataHist->weight() >= (double)fHistCutoff);
265 }
266 }
267 } else if (fIntervalType == kTailFraction) {
268 if (fVector.empty())
269 return false;
270
271 // return whether value of point is within the range
272 double x = point.getRealValue(fAxes[0]->GetName());
273 if (fTFLower <= x && x <= fTFUpper)
274 return true;
275
276 return false;
277 }
278
279 coutE(InputArguments) << "Error in MCMCInterval::IsInInterval: "
280 << "Interval type not set. Returning false." << endl;
281 return false;
282}
283
284////////////////////////////////////////////////////////////////////////////////
285
287{
288 fConfidenceLevel = cl;
290}
291
292// kbelasco: update this or just take it out
293// kbelasco: consider keeping this around but changing the implementation
294// to set the number of bins for each RooRealVar and then recreating the
295// histograms
296//void MCMCInterval::SetNumBins(Int_t numBins)
297//{
298// if (numBins > 0) {
299// fPreferredNumBins = numBins;
300// for (Int_t d = 0; d < fDimension; d++)
301// fNumBins[d] = numBins;
302// }
303// else {
304// coutE(Eval) << "* Error in MCMCInterval::SetNumBins: " <<
305// "Negative number of bins given: " << numBins << endl;
306// return;
307// }
308//
309// // If the histogram already exists, recreate it with the new bin numbers
310// if (fHist != nullptr)
311// CreateHist();
312//}
313
314////////////////////////////////////////////////////////////////////////////////
315
317{
318 Int_t size = axes.getSize();
319 if (size != fDimension) {
320 coutE(InputArguments) << "* Error in MCMCInterval::SetAxes: " <<
321 "number of variables in axes (" << size <<
322 ") doesn't match number of parameters ("
323 << fDimension << ")" << endl;
324 return;
325 }
326 for (Int_t i = 0; i < size; i++)
327 fAxes[i] = (RooRealVar*)axes.at(i);
328}
329
330////////////////////////////////////////////////////////////////////////////////
331
333{
334 // kbelasco: check here for memory leak. does RooNDKeysPdf use
335 // the RooArgList passed to it or does it make a clone?
336 // also check for memory leak from chain, does RooNDKeysPdf clone that?
337 if (fAxes == nullptr || fParameters.empty()) {
338 coutE(InputArguments) << "Error in MCMCInterval::CreateKeysPdf: "
339 << "parameters have not been set." << endl;
340 return;
341 }
342
343 if (fNumBurnInSteps >= fChain->Size()) {
345 "MCMCInterval::CreateKeysPdf: creation of Keys PDF failed: " <<
346 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
347 "in Markov chain." << endl;
348 delete fKeysPdf;
349 delete fCutoffVar;
350 delete fHeaviside;
351 delete fProduct;
352 fKeysPdf = nullptr;
353 fCutoffVar = nullptr;
354 fHeaviside = nullptr;
355 fProduct = nullptr;
356 return;
357 }
358
361 RooArgList* paramsList = new RooArgList();
362 for (Int_t i = 0; i < fDimension; i++)
363 paramsList->add(*fAxes[i]);
364
365 // kbelasco: check for memory leaks with chain. who owns it? does
366 // RooNDKeysPdf take ownership?
367 fKeysPdf = new RooNDKeysPdf("keysPDF", "Keys PDF", *paramsList, *chain, "a");
368 fCutoffVar = new RooRealVar("cutoff", "cutoff", 0);
369 fHeaviside = new Heaviside("heaviside", "Heaviside", *fKeysPdf, *fCutoffVar);
370 fProduct = new RooProduct("product", "Keys PDF & Heaviside Product",
372}
373
374////////////////////////////////////////////////////////////////////////////////
375
377{
378 if (fAxes == nullptr || fChain == nullptr) {
379 coutE(Eval) << "* Error in MCMCInterval::CreateHist(): " <<
380 "Crucial data member was nullptr." << endl;
381 coutE(Eval) << "Make sure to fully construct/initialize." << endl;
382 return;
383 }
384 if (fHist != nullptr) {
385 delete fHist;
386 fHist = nullptr;
387 }
388
389 if (fNumBurnInSteps >= fChain->Size()) {
391 "MCMCInterval::CreateHist: creation of histogram failed: " <<
392 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
393 "in Markov chain." << endl;
394 return;
395 }
396
397 if (fDimension == 1)
398 fHist = new TH1F("posterior", "MCMC Posterior Histogram",
399 fAxes[0]->numBins(), fAxes[0]->getMin(), fAxes[0]->getMax());
400
401 else if (fDimension == 2)
402 fHist = new TH2F("posterior", "MCMC Posterior Histogram",
403 fAxes[0]->numBins(), fAxes[0]->getMin(), fAxes[0]->getMax(),
404 fAxes[1]->numBins(), fAxes[1]->getMin(), fAxes[1]->getMax());
405
406 else if (fDimension == 3)
407 fHist = new TH3F("posterior", "MCMC Posterior Histogram",
408 fAxes[0]->numBins(), fAxes[0]->getMin(), fAxes[0]->getMax(),
409 fAxes[1]->numBins(), fAxes[1]->getMin(), fAxes[1]->getMax(),
410 fAxes[2]->numBins(), fAxes[2]->getMin(), fAxes[2]->getMax());
411
412 else {
413 coutE(Eval) << "* Error in MCMCInterval::CreateHist() : " <<
414 "TH1* couldn't handle dimension: " << fDimension << endl;
415 return;
416 }
417
418 // Fill histogram
419 Int_t size = fChain->Size();
420 const RooArgSet* entry;
421 for (Int_t i = fNumBurnInSteps; i < size; i++) {
422 entry = fChain->Get(i);
423 if (fDimension == 1)
424 ((TH1F*)fHist)->Fill(entry->getRealValue(fAxes[0]->GetName()),
425 fChain->Weight());
426 else if (fDimension == 2)
427 ((TH2F*)fHist)->Fill(entry->getRealValue(fAxes[0]->GetName()),
428 entry->getRealValue(fAxes[1]->GetName()),
429 fChain->Weight());
430 else
431 ((TH3F*)fHist)->Fill(entry->getRealValue(fAxes[0]->GetName()),
432 entry->getRealValue(fAxes[1]->GetName()),
433 entry->getRealValue(fAxes[2]->GetName()),
434 fChain->Weight());
435 }
436
437 if (fDimension >= 1)
439 if (fDimension >= 2)
441 if (fDimension >= 3)
443}
444
445////////////////////////////////////////////////////////////////////////////////
446
448{
449 if (fAxes == nullptr || fChain == nullptr) {
450 coutE(InputArguments) << "* Error in MCMCInterval::CreateSparseHist(): "
451 << "Crucial data member was nullptr." << endl;
452 coutE(InputArguments) << "Make sure to fully construct/initialize."
453 << endl;
454 return;
455 }
456 if (fSparseHist != nullptr)
457 delete fSparseHist;
458
459 std::vector<double> min(fDimension);
460 std::vector<double> max(fDimension);
461 std::vector<Int_t> bins(fDimension);
462 for (Int_t i = 0; i < fDimension; i++) {
463 min[i] = fAxes[i]->getMin();
464 max[i] = fAxes[i]->getMax();
465 bins[i] = fAxes[i]->numBins();
466 }
467 fSparseHist = new THnSparseF("posterior", "MCMC Posterior Histogram",
468 fDimension, bins.data(), min.data(), max.data());
469
470 // kbelasco: it appears we need to call Sumw2() just to get the
471 // histogram to keep a running total of the weight so that Getsumw doesn't
472 // just return 0
474
475 if (fNumBurnInSteps >= fChain->Size()) {
477 "MCMCInterval::CreateSparseHist: creation of histogram failed: " <<
478 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
479 "in Markov chain." << endl;
480 }
481
482 // Fill histogram
483 Int_t size = fChain->Size();
484 const RooArgSet* entry;
485 std::vector<double> x(fDimension);
486 for (Int_t i = fNumBurnInSteps; i < size; i++) {
487 entry = fChain->Get(i);
488 for (Int_t ii = 0; ii < fDimension; ii++)
489 x[ii] = entry->getRealValue(fAxes[ii]->GetName());
490 fSparseHist->Fill(x.data(), fChain->Weight());
491 }
492}
493
494////////////////////////////////////////////////////////////////////////////////
495
497{
498 if (fParameters.empty() || fChain == nullptr) {
499 coutE(Eval) << "* Error in MCMCInterval::CreateDataHist(): " <<
500 "Crucial data member was nullptr or empty." << endl;
501 coutE(Eval) << "Make sure to fully construct/initialize." << endl;
502 return;
503 }
504
505 if (fNumBurnInSteps >= fChain->Size()) {
507 "MCMCInterval::CreateDataHist: creation of histogram failed: " <<
508 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
509 "in Markov chain." << endl;
510 fDataHist = nullptr;
511 return;
512 }
513
516}
517
518////////////////////////////////////////////////////////////////////////////////
519
521{
522 fVector.clear();
523 fVecWeight = 0;
524
525 if (fChain == nullptr) {
526 coutE(InputArguments) << "* Error in MCMCInterval::CreateVector(): " <<
527 "Crucial data member (Markov chain) was nullptr." << endl;
528 coutE(InputArguments) << "Make sure to fully construct/initialize."
529 << endl;
530 return;
531 }
532
533 if (fNumBurnInSteps >= fChain->Size()) {
535 "MCMCInterval::CreateVector: creation of vector failed: " <<
536 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
537 "in Markov chain." << endl;
538 }
539
540 // Fill vector
542 fVector.resize(size);
543 Int_t i;
544 Int_t chainIndex;
545 for (i = 0; i < size; i++) {
546 chainIndex = i + fNumBurnInSteps;
547 fVector[i] = chainIndex;
548 fVecWeight += fChain->Weight(chainIndex);
549 }
550
551 stable_sort(fVector.begin(), fVector.end(),
553}
554
555////////////////////////////////////////////////////////////////////////////////
556
558{
560 fParameters.add(parameters);
562 if (fAxes != nullptr)
563 delete[] fAxes;
565 Int_t n = 0;
566 for (auto *obj : fParameters) {
567 if (dynamic_cast<RooRealVar*>(obj) != nullptr)
568 fAxes[n] = static_cast<RooRealVar*>(obj);
569 else
570 coutE(Eval) << "* Error in MCMCInterval::SetParameters: " <<
571 obj->GetName() << " not a RooRealVar*" << std::endl;
572 n++;
573 }
574}
575
576////////////////////////////////////////////////////////////////////////////////
577
579{
580 switch (fIntervalType) {
581 case kShortest:
583 break;
584 case kTailFraction:
586 break;
587 default:
588 coutE(InputArguments) << "MCMCInterval::DetermineInterval(): " <<
589 "Error: Interval type not set" << endl;
590 break;
591 }
592}
593
594////////////////////////////////////////////////////////////////////////////////
595
597{
598 if (fUseKeys)
600 else
602}
603
604////////////////////////////////////////////////////////////////////////////////
605
607{
608 if (fLeftSideTF < 0 || fLeftSideTF > 1) {
609 coutE(InputArguments) << "MCMCInterval::DetermineTailFractionInterval: "
610 << "Fraction must be in the range [0, 1]. "
611 << fLeftSideTF << "is not allowed." << endl;
612 return;
613 }
614
615 if (fDimension != 1) {
616 coutE(InputArguments) << "MCMCInterval::DetermineTailFractionInterval(): "
617 << "Error: Can only find a tail-fraction interval for 1-D intervals"
618 << endl;
619 return;
620 }
621
622 if (fAxes == nullptr) {
623 coutE(InputArguments) << "MCMCInterval::DetermineTailFractionInterval(): "
624 << "Crucial data member was nullptr." << endl;
625 coutE(InputArguments) << "Make sure to fully construct/initialize."
626 << endl;
627 return;
628 }
629
630 // kbelasco: fill in code here to find interval
631 //
632 // also make changes so that calling GetPosterior...() returns nullptr
633 // when fIntervalType == kTailFraction, since there really
634 // is no posterior for this type of interval determination
635 if (fVector.empty())
637
638 if (fVector.empty() || fVecWeight == 0) {
639 // if size is still 0, then creation failed.
640 // if fVecWeight == 0, then there are no entries (indicates the same
641 // error as fVector.empty() because that only happens when
642 // fNumBurnInSteps >= fChain->Size())
643 // either way, reset and return
644 fVector.clear();
645 fTFLower = -1.0 * RooNumber::infinity();
647 fTFConfLevel = 0.0;
648 fVecWeight = 0;
649 return;
650 }
651
652 RooRealVar* param = fAxes[0];
653
654 double c = fConfidenceLevel;
655 double leftTailCutoff = fVecWeight * (1 - c) * fLeftSideTF;
656 double rightTailCutoff = fVecWeight * (1 - c) * (1 - fLeftSideTF);
657 double leftTailSum = 0;
658 double rightTailSum = 0;
659
660 // kbelasco: consider changing these values to +infinity and -infinity
661 double ll = param->getMin();
662 double ul = param->getMax();
663
664 double x;
665 double w;
666
667 // save a lot of GetName() calls if compiler does not already optimize this
668 const char* name = param->GetName();
669
670 // find lower limit
671 Int_t i;
672 for (i = 0; i < (Int_t)fVector.size(); i++) {
674 w = fChain->Weight();
675
676 if (TMath::Abs(leftTailSum + w - leftTailCutoff) <
677 TMath::Abs(leftTailSum - leftTailCutoff)) {
678 // moving the lower limit to x would bring us closer to the desired
679 // left tail size
680 ll = x;
681 leftTailSum += w;
682 } else
683 break;
684 }
685
686 // find upper limit
687 for (i = (Int_t)fVector.size() - 1; i >= 0; i--) {
689 w = fChain->Weight();
690
691 if (TMath::Abs(rightTailSum + w - rightTailCutoff) <
692 TMath::Abs(rightTailSum - rightTailCutoff)) {
693 // moving the lower limit to x would bring us closer to the desired
694 // left tail size
695 ul = x;
696 rightTailSum += w;
697 } else
698 break;
699 }
700
701 fTFLower = ll;
702 fTFUpper = ul;
703 fTFConfLevel = 1 - (leftTailSum + rightTailSum) / fVecWeight;
704}
705
706////////////////////////////////////////////////////////////////////////////////
707
709{
710 if (fKeysPdf == nullptr)
712
713 if (fKeysPdf == nullptr) {
714 // if fKeysPdf is still nullptr, then it means CreateKeysPdf failed
715 // so clear all the data members this function would normally determine
716 // and return
717 fFull = 0.0;
718 fKeysCutoff = -1;
719 fKeysConfLevel = 0.0;
720 return;
721 }
722
723 // now we have a keys pdf of the posterior
724
725 double cutoff = 0.0;
726 fCutoffVar->setVal(cutoff);
727 double full = std::unique_ptr<RooAbsReal>{fProduct->createIntegral(fParameters, NormSet(fParameters))}->getVal(fParameters);
728 fFull = full;
729 if (full < 0.98) {
730 coutW(Eval) << "Warning: Integral of Keys PDF came out to " << full
731 << " instead of expected value 1. Will continue using this "
732 << "factor to normalize further integrals of this PDF." << endl;
733 }
734
735 // kbelasco: Is there a better way to set the search range?
736 // from 0 to max value of Keys
737 // kbelasco: how to get max value?
738 //double max = product.maxVal(product.getMaxVal(fParameters));
739
740 double volume = 1.0;
741 for (auto *var : static_range_cast<RooRealVar*>(fParameters))
742 volume *= (var->getMax() - var->getMin());
743
744 double topCutoff = full / volume;
745 double bottomCutoff = topCutoff;
746 double confLevel = CalcConfLevel(topCutoff, full);
747 if (AcceptableConfLevel(confLevel)) {
748 fKeysConfLevel = confLevel;
749 fKeysCutoff = topCutoff;
750 return;
751 }
752 bool changed = false;
753 // find high end of range
754 while (confLevel > fConfidenceLevel) {
755 topCutoff *= 2.0;
756 confLevel = CalcConfLevel(topCutoff, full);
757 if (AcceptableConfLevel(confLevel)) {
758 fKeysConfLevel = confLevel;
759 fKeysCutoff = topCutoff;
760 return;
761 }
762 changed = true;
763 }
764 if (changed) {
765 bottomCutoff = topCutoff / 2.0;
766 } else {
767 changed = false;
768 bottomCutoff /= 2.0;
769 confLevel = CalcConfLevel(bottomCutoff, full);
770 if (AcceptableConfLevel(confLevel)) {
771 fKeysConfLevel = confLevel;
772 fKeysCutoff = bottomCutoff;
773 return;
774 }
775 while (confLevel < fConfidenceLevel) {
776 bottomCutoff /= 2.0;
777 confLevel = CalcConfLevel(bottomCutoff, full);
778 if (AcceptableConfLevel(confLevel)) {
779 fKeysConfLevel = confLevel;
780 fKeysCutoff = bottomCutoff;
781 return;
782 }
783 changed = true;
784 }
785 if (changed) {
786 topCutoff = bottomCutoff * 2.0;
787 }
788 }
789
790 coutI(Eval) << "range set: [" << bottomCutoff << ", " << topCutoff << "]"
791 << endl;
792
793 cutoff = (topCutoff + bottomCutoff) / 2.0;
794 confLevel = CalcConfLevel(cutoff, full);
795
796 // need to use WithinDeltaFraction() because sometimes the integrating the
797 // posterior in this binary search seems to not have enough granularity to
798 // find an acceptable conf level (small no. of strange cases).
799 // WithinDeltaFraction causes the search to terminate when
800 // topCutoff is essentially equal to bottomCutoff (compared to the magnitude
801 // of their mean).
802 while (!AcceptableConfLevel(confLevel) &&
803 !WithinDeltaFraction(topCutoff, bottomCutoff)) {
804 if (confLevel > fConfidenceLevel)
805 bottomCutoff = cutoff;
806 else if (confLevel < fConfidenceLevel)
807 topCutoff = cutoff;
808 cutoff = (topCutoff + bottomCutoff) / 2.0;
809 coutI(Eval) << "cutoff range: [" << bottomCutoff << ", "
810 << topCutoff << "]" << endl;
811 confLevel = CalcConfLevel(cutoff, full);
812 }
813
814 fKeysCutoff = cutoff;
815 fKeysConfLevel = confLevel;
816}
817
818////////////////////////////////////////////////////////////////////////////////
819
821{
822 if (fUseSparseHist)
824 else
826}
827
828////////////////////////////////////////////////////////////////////////////////
829
831{
832 Long_t numBins;
833 if (fSparseHist == nullptr)
835
836 if (fSparseHist == nullptr) {
837 // if fSparseHist is still nullptr, then CreateSparseHist failed
838 fHistCutoff = -1;
839 fHistConfLevel = 0.0;
840 return;
841 }
842
843 numBins = (Long_t)fSparseHist->GetNbins();
844
845 std::vector<Long_t> bins(numBins);
846 for (Int_t ibin = 0; ibin < numBins; ibin++)
847 bins[ibin] = (Long_t)ibin;
848 std::stable_sort(bins.begin(), bins.end(), CompareSparseHistBins(fSparseHist));
849
850 double nEntries = fSparseHist->GetSumw();
851 double sum = 0;
852 double content;
853 Int_t i;
854 // see above note on indexing to understand numBins - 3
855 for (i = numBins - 1; i >= 0; i--) {
856 content = fSparseHist->GetBinContent(bins[i]);
857 if ((sum + content) / nEntries >= fConfidenceLevel) {
858 fHistCutoff = content;
859 if (fIsHistStrict) {
860 sum += content;
861 i--;
862 break;
863 } else {
864 i++;
865 break;
866 }
867 }
868 sum += content;
869 }
870
871 if (fIsHistStrict) {
872 // keep going to find the sum
873 for ( ; i >= 0; i--) {
874 content = fSparseHist->GetBinContent(bins[i]);
875 if (content == fHistCutoff)
876 sum += content;
877 else
878 break; // content must be < fHistCutoff
879 }
880 } else {
881 // backtrack to find the cutoff and sum
882 for ( ; i < numBins; i++) {
883 content = fSparseHist->GetBinContent(bins[i]);
884 if (content > fHistCutoff) {
885 fHistCutoff = content;
886 break;
887 } else // content == fHistCutoff
888 sum -= content;
889 if (i == numBins - 1)
890 // still haven't set fHistCutoff correctly yet, and we have no bins
891 // left, so set fHistCutoff to something higher than the tallest bin
892 fHistCutoff = content + 1.0;
893 }
894 }
895
896 fHistConfLevel = sum / nEntries;
897}
898
899////////////////////////////////////////////////////////////////////////////////
900
902{
903 Int_t numBins;
904 if (fDataHist == nullptr)
906 if (fDataHist == nullptr) {
907 // if fDataHist is still nullptr, then CreateDataHist failed
908 fHistCutoff = -1;
909 fHistConfLevel = 0.0;
910 return;
911 }
912
913 numBins = fDataHist->numEntries();
914
915 std::vector<Int_t> bins(numBins);
916 for (Int_t ibin = 0; ibin < numBins; ibin++)
917 bins[ibin] = ibin;
918 std::stable_sort(bins.begin(), bins.end(), CompareDataHistBins(fDataHist));
919
920 double nEntries = fDataHist->sum(false);
921 double sum = 0;
922 double content;
923 Int_t i;
924 for (i = numBins - 1; i >= 0; i--) {
925 fDataHist->get(bins[i]);
926 content = fDataHist->weight();
927 if ((sum + content) / nEntries >= fConfidenceLevel) {
928 fHistCutoff = content;
929 if (fIsHistStrict) {
930 sum += content;
931 i--;
932 break;
933 } else {
934 i++;
935 break;
936 }
937 }
938 sum += content;
939 }
940
941 if (fIsHistStrict) {
942 // keep going to find the sum
943 for ( ; i >= 0; i--) {
944 fDataHist->get(bins[i]);
945 content = fDataHist->weight();
946 if (content == fHistCutoff)
947 sum += content;
948 else
949 break; // content must be < fHistCutoff
950 }
951 } else {
952 // backtrack to find the cutoff and sum
953 for ( ; i < numBins; i++) {
954 fDataHist->get(bins[i]);
955 content = fDataHist->weight();
956 if (content > fHistCutoff) {
957 fHistCutoff = content;
958 break;
959 } else // content == fHistCutoff
960 sum -= content;
961 if (i == numBins - 1)
962 // still haven't set fHistCutoff correctly yet, and we have no bins
963 // left, so set fHistCutoff to something higher than the tallest bin
964 fHistCutoff = content + 1.0;
965 }
966 }
967
968 fHistConfLevel = sum / nEntries;
969}
970
971////////////////////////////////////////////////////////////////////////////////
972
974{
975 if (fIntervalType == kShortest) {
976 if (fUseKeys)
977 return fKeysConfLevel;
978 else
979 return fHistConfLevel;
980 } else if (fIntervalType == kTailFraction) {
981 return fTFConfLevel;
982 } else {
983 coutE(InputArguments) << "MCMCInterval::GetActualConfidenceLevel: "
984 << "not implemented for this type of interval. Returning 0." << endl;
985 return 0;
986 }
987}
988
989////////////////////////////////////////////////////////////////////////////////
990
992{
993 switch (fIntervalType) {
994 case kShortest:
995 return LowerLimitShortest(param);
996 case kTailFraction:
997 return LowerLimitTailFraction(param);
998 default:
999 coutE(InputArguments) << "MCMCInterval::LowerLimit(): " <<
1000 "Error: Interval type not set" << endl;
1001 return RooNumber::infinity();
1002 }
1003}
1004
1005////////////////////////////////////////////////////////////////////////////////
1006
1008{
1009 switch (fIntervalType) {
1010 case kShortest:
1011 return UpperLimitShortest(param);
1012 case kTailFraction:
1013 return UpperLimitTailFraction(param);
1014 default:
1015 coutE(InputArguments) << "MCMCInterval::UpperLimit(): " <<
1016 "Error: Interval type not set" << endl;
1017 return RooNumber::infinity();
1018 }
1019}
1020
1021////////////////////////////////////////////////////////////////////////////////
1022
1024{
1025 if (fTFLower == -1.0 * RooNumber::infinity())
1027
1028 return fTFLower;
1029}
1030
1031////////////////////////////////////////////////////////////////////////////////
1032
1034{
1037
1038 return fTFUpper;
1039}
1040
1041////////////////////////////////////////////////////////////////////////////////
1042
1044{
1045 if (fUseKeys)
1046 return LowerLimitByKeys(param);
1047 else
1048 return LowerLimitByHist(param);
1049}
1050
1051////////////////////////////////////////////////////////////////////////////////
1052
1054{
1055 if (fUseKeys)
1056 return UpperLimitByKeys(param);
1057 else
1058 return UpperLimitByHist(param);
1059}
1060
1061////////////////////////////////////////////////////////////////////////////////
1062/// Determine the lower limit for param on this interval
1063/// using the binned data set
1064
1066{
1067 if (fUseSparseHist)
1068 return LowerLimitBySparseHist(param);
1069 else
1070 return LowerLimitByDataHist(param);
1071}
1072
1073////////////////////////////////////////////////////////////////////////////////
1074/// Determine the upper limit for param on this interval
1075/// using the binned data set
1076
1078{
1079 if (fUseSparseHist)
1080 return UpperLimitBySparseHist(param);
1081 else
1082 return UpperLimitByDataHist(param);
1083}
1084
1085////////////////////////////////////////////////////////////////////////////////
1086/// Determine the lower limit for param on this interval
1087/// using the binned data set
1088
1090{
1091 if (fDimension != 1) {
1092 coutE(InputArguments) << "In MCMCInterval::LowerLimitBySparseHist: "
1093 << "Sorry, will not compute lower limit unless dimension == 1" << endl;
1094 return param.getMin();
1095 }
1096 if (fHistCutoff < 0)
1097 DetermineBySparseHist(); // this initializes fSparseHist
1098
1099 if (fHistCutoff < 0) {
1100 // if fHistCutoff < 0 still, then determination of interval failed
1101 coutE(Eval) << "In MCMCInterval::LowerLimitBySparseHist: "
1102 << "couldn't determine cutoff. Check that num burn in steps < num "
1103 << "steps in the Markov chain. Returning param.getMin()." << endl;
1104 return param.getMin();
1105 }
1106
1107 std::vector<Int_t> coord(fDimension);
1108 for (Int_t d = 0; d < fDimension; d++) {
1109 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1110 Long_t numBins = (Long_t)fSparseHist->GetNbins();
1111 double lowerLimit = param.getMax();
1112 double val;
1113 for (Long_t i = 0; i < numBins; i++) {
1114 if (fSparseHist->GetBinContent(i, &coord[0]) >= fHistCutoff) {
1115 val = fSparseHist->GetAxis(d)->GetBinCenter(coord[d]);
1116 if (val < lowerLimit)
1117 lowerLimit = val;
1118 }
1119 }
1120 return lowerLimit;
1121 }
1122 }
1123 return param.getMin();
1124}
1125
1126////////////////////////////////////////////////////////////////////////////////
1127/// Determine the lower limit for param on this interval
1128/// using the binned data set
1129
1131{
1132 if (fHistCutoff < 0)
1133 DetermineByDataHist(); // this initializes fDataHist
1134
1135 if (fHistCutoff < 0) {
1136 // if fHistCutoff < 0 still, then determination of interval failed
1137 coutE(Eval) << "In MCMCInterval::LowerLimitByDataHist: "
1138 << "couldn't determine cutoff. Check that num burn in steps < num "
1139 << "steps in the Markov chain. Returning param.getMin()." << endl;
1140 return param.getMin();
1141 }
1142
1143 for (Int_t d = 0; d < fDimension; d++) {
1144 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1145 Int_t numBins = fDataHist->numEntries();
1146 double lowerLimit = param.getMax();
1147 double val;
1148 for (Int_t i = 0; i < numBins; i++) {
1149 fDataHist->get(i);
1150 if (fDataHist->weight() >= fHistCutoff) {
1151 val = fDataHist->get()->getRealValue(param.GetName());
1152 if (val < lowerLimit)
1153 lowerLimit = val;
1154 }
1155 }
1156 return lowerLimit;
1157 }
1158 }
1159 return param.getMin();
1160}
1161
1162////////////////////////////////////////////////////////////////////////////////
1163/// Determine the upper limit for param on this interval
1164/// using the binned data set
1165
1167{
1168 if (fDimension != 1) {
1169 coutE(InputArguments) << "In MCMCInterval::UpperLimitBySparseHist: "
1170 << "Sorry, will not compute upper limit unless dimension == 1" << endl;
1171 return param.getMax();
1172 }
1173 if (fHistCutoff < 0)
1174 DetermineBySparseHist(); // this initializes fSparseHist
1175
1176 if (fHistCutoff < 0) {
1177 // if fHistCutoff < 0 still, then determination of interval failed
1178 coutE(Eval) << "In MCMCInterval::UpperLimitBySparseHist: "
1179 << "couldn't determine cutoff. Check that num burn in steps < num "
1180 << "steps in the Markov chain. Returning param.getMax()." << endl;
1181 return param.getMax();
1182 }
1183
1184 std::vector<Int_t> coord(fDimension);
1185 for (Int_t d = 0; d < fDimension; d++) {
1186 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1187 Long_t numBins = (Long_t)fSparseHist->GetNbins();
1188 double upperLimit = param.getMin();
1189 double val;
1190 for (Long_t i = 0; i < numBins; i++) {
1191 if (fSparseHist->GetBinContent(i, &coord[0]) >= fHistCutoff) {
1192 val = fSparseHist->GetAxis(d)->GetBinCenter(coord[d]);
1193 if (val > upperLimit)
1194 upperLimit = val;
1195 }
1196 }
1197 return upperLimit;
1198 }
1199 }
1200 return param.getMax();
1201}
1202
1203////////////////////////////////////////////////////////////////////////////////
1204/// Determine the upper limit for param on this interval
1205/// using the binned data set
1206
1208{
1209 if (fHistCutoff < 0)
1210 DetermineByDataHist(); // this initializes fDataHist
1211
1212 if (fHistCutoff < 0) {
1213 // if fHistCutoff < 0 still, then determination of interval failed
1214 coutE(Eval) << "In MCMCInterval::UpperLimitByDataHist: "
1215 << "couldn't determine cutoff. Check that num burn in steps < num "
1216 << "steps in the Markov chain. Returning param.getMax()." << endl;
1217 return param.getMax();
1218 }
1219
1220 for (Int_t d = 0; d < fDimension; d++) {
1221 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1222 Int_t numBins = fDataHist->numEntries();
1223 double upperLimit = param.getMin();
1224 double val;
1225 for (Int_t i = 0; i < numBins; i++) {
1226 fDataHist->get(i);
1227 if (fDataHist->weight() >= fHistCutoff) {
1228 val = fDataHist->get()->getRealValue(param.GetName());
1229 if (val > upperLimit)
1230 upperLimit = val;
1231 }
1232 }
1233 return upperLimit;
1234 }
1235 }
1236 return param.getMax();
1237}
1238
1239////////////////////////////////////////////////////////////////////////////////
1240/// Determine the lower limit for param on this interval
1241/// using the keys pdf
1242
1244{
1245 if (fKeysCutoff < 0)
1247
1248 if (fKeysDataHist == nullptr)
1250
1251 if (fKeysCutoff < 0 || fKeysDataHist == nullptr) {
1252 // failure in determination of cutoff and/or creation of histogram
1253 coutE(Eval) << "in MCMCInterval::LowerLimitByKeys(): "
1254 << "couldn't find lower limit, check that the number of burn in "
1255 << "steps < number of total steps in the Markov chain. Returning "
1256 << "param.getMin()" << endl;
1257 return param.getMin();
1258 }
1259
1260 for (Int_t d = 0; d < fDimension; d++) {
1261 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1262 Int_t numBins = fKeysDataHist->numEntries();
1263 double lowerLimit = param.getMax();
1264 double val;
1265 for (Int_t i = 0; i < numBins; i++) {
1266 fKeysDataHist->get(i);
1267 if (fKeysDataHist->weight() >= fKeysCutoff) {
1268 val = fKeysDataHist->get()->getRealValue(param.GetName());
1269 if (val < lowerLimit)
1270 lowerLimit = val;
1271 }
1272 }
1273 return lowerLimit;
1274 }
1275 }
1276 return param.getMin();
1277}
1278
1279////////////////////////////////////////////////////////////////////////////////
1280/// Determine the upper limit for param on this interval
1281/// using the keys pdf
1282
1284{
1285 if (fKeysCutoff < 0)
1287
1288 if (fKeysDataHist == nullptr)
1290
1291 if (fKeysCutoff < 0 || fKeysDataHist == nullptr) {
1292 // failure in determination of cutoff and/or creation of histogram
1293 coutE(Eval) << "in MCMCInterval::UpperLimitByKeys(): "
1294 << "couldn't find upper limit, check that the number of burn in "
1295 << "steps < number of total steps in the Markov chain. Returning "
1296 << "param.getMax()" << endl;
1297 return param.getMax();
1298 }
1299
1300 for (Int_t d = 0; d < fDimension; d++) {
1301 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1302 Int_t numBins = fKeysDataHist->numEntries();
1303 double upperLimit = param.getMin();
1304 double val;
1305 for (Int_t i = 0; i < numBins; i++) {
1306 fKeysDataHist->get(i);
1307 if (fKeysDataHist->weight() >= fKeysCutoff) {
1308 val = fKeysDataHist->get()->getRealValue(param.GetName());
1309 if (val > upperLimit)
1310 upperLimit = val;
1311 }
1312 }
1313 return upperLimit;
1314 }
1315 }
1316 return param.getMax();
1317}
1318
1319////////////////////////////////////////////////////////////////////////////////
1320/// Determine the approximate maximum value of the Keys PDF
1321
1323{
1324 if (fKeysCutoff < 0)
1326
1327 if (fKeysDataHist == nullptr)
1329
1330 if (fKeysDataHist == nullptr) {
1331 // failure in determination of cutoff and/or creation of histogram
1332 coutE(Eval) << "in MCMCInterval::KeysMax(): "
1333 << "couldn't find Keys max value, check that the number of burn in "
1334 << "steps < number of total steps in the Markov chain. Returning 0"
1335 << endl;
1336 return 0;
1337 }
1338
1339 Int_t numBins = fKeysDataHist->numEntries();
1340 double max = 0;
1341 double w;
1342 for (Int_t i = 0; i < numBins; i++) {
1343 fKeysDataHist->get(i);
1344 w = fKeysDataHist->weight();
1345 if (w > max)
1346 max = w;
1347 }
1348
1349 return max;
1350}
1351
1352////////////////////////////////////////////////////////////////////////////////
1353
1355{
1356 if (fHistCutoff < 0)
1358
1359 return fHistCutoff;
1360}
1361
1362////////////////////////////////////////////////////////////////////////////////
1363
1365{
1366 if (fKeysCutoff < 0)
1368
1369 // kbelasco: if fFull hasn't been set (because Keys creation failed because
1370 // fNumBurnInSteps >= fChain->Size()) then this will return infinity, which
1371 // seems ok to me since it will indicate error
1372
1373 return fKeysCutoff / fFull;
1374}
1375
1376////////////////////////////////////////////////////////////////////////////////
1377
1378double MCMCInterval::CalcConfLevel(double cutoff, double full)
1379{
1380 fCutoffVar->setVal(cutoff);
1381 std::unique_ptr<RooAbsReal> integral{fProduct->createIntegral(fParameters, NormSet(fParameters))};
1382 double confLevel = integral->getVal(fParameters) / full;
1383 coutI(Eval) << "cutoff = " << cutoff << ", conf = " << confLevel << endl;
1384 return confLevel;
1385}
1386
1387////////////////////////////////////////////////////////////////////////////////
1388
1390{
1391 if(fConfidenceLevel == 0)
1392 coutE(InputArguments) << "Error in MCMCInterval::GetPosteriorHist: "
1393 << "confidence level not set " << endl;
1394 if (fHist == nullptr)
1395 CreateHist();
1396
1397 if (fHist == nullptr)
1398 // if fHist is still nullptr, then CreateHist failed
1399 return nullptr;
1400
1401 return (TH1*) fHist->Clone("MCMCposterior_hist");
1402}
1403
1404////////////////////////////////////////////////////////////////////////////////
1405
1407{
1408 if (fConfidenceLevel == 0)
1409 coutE(InputArguments) << "Error in MCMCInterval::GetPosteriorKeysPdf: "
1410 << "confidence level not set " << endl;
1411 if (fKeysPdf == nullptr)
1412 CreateKeysPdf();
1413
1414 if (fKeysPdf == nullptr)
1415 // if fKeysPdf is still nullptr, then it means CreateKeysPdf failed
1416 return nullptr;
1417
1418 return (RooNDKeysPdf*) fKeysPdf->Clone("MCMCPosterior_keys");
1419}
1420
1421////////////////////////////////////////////////////////////////////////////////
1422
1424{
1425 if (fConfidenceLevel == 0)
1426 coutE(InputArguments) << "MCMCInterval::GetPosteriorKeysProduct: "
1427 << "confidence level not set " << endl;
1428 if (fProduct == nullptr) {
1429 CreateKeysPdf();
1431 }
1432
1433 if (fProduct == nullptr)
1434 // if fProduct is still nullptr, then it means CreateKeysPdf failed
1435 return nullptr;
1436
1437 return (RooProduct*) fProduct->Clone("MCMCPosterior_keysproduct");
1438}
1439
1440////////////////////////////////////////////////////////////////////////////////
1441
1443{
1444 // returns list of parameters
1445 return new RooArgSet(fParameters);
1446}
1447
1448////////////////////////////////////////////////////////////////////////////////
1449
1451{
1452 return (TMath::Abs(confLevel - fConfidenceLevel) < fEpsilon);
1453}
1454
1455////////////////////////////////////////////////////////////////////////////////
1456
1458{
1459 return (TMath::Abs(a - b) < TMath::Abs(fDelta * (a + b)/2));
1460}
1461
1462////////////////////////////////////////////////////////////////////////////////
1463
1465{
1466 if (fAxes == nullptr)
1467 return;
1468 if (fProduct == nullptr)
1470 if (fProduct == nullptr)
1471 // if fProduct still nullptr, then creation failed
1472 return;
1473
1474 //RooAbsBinning** savedBinning = new RooAbsBinning*[fDimension];
1475 std::vector<Int_t> savedBins(fDimension);
1476 Int_t i;
1477 double numBins;
1478 RooRealVar* var;
1479
1480 // kbelasco: Note - the accuracy is only increased here if the binning for
1481 // each RooRealVar is uniform
1482
1483 // kbelasco: look into why saving the binnings and replacing them doesn't
1484 // work (replaces with 1 bin always).
1485 // Note: this code modifies the binning for the parameters (if they are
1486 // uniform) and sets them back to what they were. If the binnings are not
1487 // uniform, this code does nothing.
1488
1489 // first scan through fAxes to make sure all binnings are uniform, or else
1490 // we can't change the number of bins because there seems to be an error
1491 // when setting the binning itself rather than just the number of bins
1492 bool tempChangeBinning = true;
1493 for (i = 0; i < fDimension; i++) {
1494 if (!fAxes[i]->getBinning(nullptr, false, false).isUniform()) {
1495 tempChangeBinning = false;
1496 break;
1497 }
1498 }
1499
1500 // kbelasco: for 1 dimension this should be fine, but for more dimensions
1501 // the total number of bins in the histogram increases exponentially with
1502 // the dimension, so don't do this above 1-D for now.
1503 if (fDimension >= 2)
1504 tempChangeBinning = false;
1505
1506 if (tempChangeBinning) {
1507 // set high number of bins for high accuracy on lower/upper limit by keys
1508 for (i = 0; i < fDimension; i++) {
1509 var = fAxes[i];
1510 //savedBinning[i] = &var->getBinning("__binning_clone", false, true);
1511 savedBins[i] = var->getBinning(nullptr, false, false).numBins();
1512 numBins = (var->getMax() - var->getMin()) / fEpsilon;
1513 var->setBins((Int_t)numBins);
1514 }
1515 }
1516
1517 fKeysDataHist = new RooDataHist("_productDataHist",
1518 "Keys PDF & Heaviside Product Data Hist", fParameters);
1520
1521 if (tempChangeBinning) {
1522 // set the binning back to normal
1523 for (i = 0; i < fDimension; i++)
1524 //fAxes[i]->setBinning(*savedBinning[i], nullptr);
1525 //fAxes[i]->setBins(savedBinning[i]->numBins(), nullptr);
1526 fAxes[i]->setBins(savedBins[i], nullptr);
1527 }
1528}
1529
1530////////////////////////////////////////////////////////////////////////////////
1531
1532bool MCMCInterval::CheckParameters(const RooArgSet& parameterPoint) const
1533{
1534 // check that the parameters are correct
1535
1536 if (parameterPoint.getSize() != fParameters.getSize() ) {
1537 coutE(Eval) << "MCMCInterval: size is wrong, parameters don't match" << std::endl;
1538 return false;
1539 }
1540 if ( ! parameterPoint.equals( fParameters ) ) {
1541 coutE(Eval) << "MCMCInterval: size is ok, but parameters don't match" << std::endl;
1542 return false;
1543 }
1544 return true;
1545}
static const double DEFAULT_EPSILON
static const double DEFAULT_DELTA
#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
#define e(i)
Definition RSha256.hxx:103
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
Definition RtypesCore.h:45
long Long_t
Definition RtypesCore.h:54
long long Long64_t
Definition RtypesCore.h:80
#define ClassImp(name)
Definition Rtypes.h:377
char name[80]
Definition TGX11.cxx:110
THnSparseT< TArrayF > THnSparseF
Definition THnSparse.h:220
TRObject operator()(const T1 &t1) const
TObject * Clone(const char *newname=nullptr) const override
Make a clone of an object using the Streamer facility.
Definition RooAbsArg.h:86
Int_t numBins() const
Return number of bins.
bool equals(const RooAbsCollection &otherColl) const
Check if this and other collection have identically-named contents.
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.
Int_t getSize() const
Return the number of elements in the collection.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
Int_t numBins(const char *rangeName=nullptr) const override
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.
RooDataHist * fillDataHist(RooDataHist *hist, const RooArgSet *nset, double scaleFactor, bool correctForBinVolume=false, bool showProgress=false) const
Fill a RooDataHist with values sampled from this function at the bin centers.
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:91
RooFit::OwningPtr< RooAbsReal > createIntegral(const RooArgSet &iset, const RooCmdArg &arg1, const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none()) const
Create an object that represents the integral of the function over one or more observables std::liste...
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:55
The RooDataHist is a container class to hold N-dimensional binned data.
Definition RooDataHist.h:39
double sum(bool correctForBinSize, bool inverseCorr=false) const
Return the sum of the weights of all bins in the histogram.
Int_t getIndex(const RooAbsCollection &coord, bool fast=false) const
Calculate bin number of the given coordinates.
double weight(std::size_t i) const
Return weight of i-th bin.
const RooArgSet * get() const override
Get bin centre of current bin.
Definition RooDataHist.h:76
RooDataSet is a container class to hold unbinned data.
Definition RooDataSet.h:57
Generic N-dimensional implementation of a kernel estimation p.d.f.
static constexpr double infinity()
Return internal infinity representation.
Definition RooNumber.h:24
A RooProduct represents the product of a given set of RooAbsReal objects.
Definition RooProduct.h:29
RooRealVar represents a variable that can be changed from the outside.
Definition RooRealVar.h:40
void setVal(double value) override
Set value of variable to 'value'.
const RooAbsBinning & getBinning(const char *name=nullptr, bool verbose=true, bool createOnTheFly=false) const override
Return binning definition with name.
void setBins(Int_t nBins, const char *name=nullptr)
Create a uniform binning under name 'name' for this variable.
ConfInterval is an interface class for a generic interval in the RooStats framework.
Represents the Heaviside function.
Definition Heaviside.h:18
MCMCInterval is a concrete implementation of the RooStats::ConfInterval interface.
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)
RooDataHist * fDataHist
the binned Markov Chain data
virtual double LowerLimitByDataHist(RooRealVar &param)
determine lower limit using histogram
double fDelta
topCutoff (a) considered == bottomCutoff (b) iff
double fConfidenceLevel
Requested confidence level (eg. 0.95 for 95% CL)
TH1 * fHist
the binned Markov Chain data
virtual double UpperLimitBySparseHist(RooRealVar &param)
determine upper limit using histogram
enum IntervalType fIntervalType
virtual double UpperLimit(RooRealVar &param)
get the highest value of param that is within the confidence interval
RooRealVar * fCutoffVar
cutoff variable to use for integrating keys pdf
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.
RooProduct * fProduct
the (keysPdf * heaviside) product
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);
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
RooRealVar ** fAxes
array of pointers to RooRealVars representing the axes of the histogram fAxes[0] represents x-axis,...
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()
Heaviside * fHeaviside
the Heaviside function
double fFull
Value of intergral of fProduct.
virtual double UpperLimitByDataHist(RooRealVar &param)
determine upper limit using histogram
virtual void DetermineInterval()
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...
THnSparse * fSparseHist
the binned Markov Chain data
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
MarkovChain * fChain
the markov chain
RooArgSet * GetParameters() const override
return a set containing the parameters of this interval the caller owns the returned RooArgSet*
virtual double UpperLimitTailFraction(RooRealVar &param)
determine upper limit of the lower confidence interval
bool fIsHistStrict
whether the specified confidence level is a
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
virtual void CreateHist()
bool fUseKeys
whether to use kernel estimation
RooDataHist * fKeysDataHist
data hist representing product
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()
RooNDKeysPdf * fKeysPdf
the kernel estimation pdf
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:30
virtual RooDataHist * GetAsDataHist(RooArgSet *whichVars=nullptr) const
get this MarkovChain as a RooDataHist whose entries contain the values of whichVars.
virtual const RooArgSet * Get(Int_t i) const
get the entry at position i
Definition MarkovChain.h:51
virtual double Weight() const
get the weight of the current (last indexed) entry
virtual RooDataSet * GetAsDataSet(RooArgSet *whichVars=nullptr) const
get this MarkovChain as a RooDataSet whose entries contain the values of whichVars.
virtual Int_t Size() const
get the number of steps in the chain
Definition MarkovChain.h:49
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:478
1-D histogram with a float per channel (see TH1 documentation)}
Definition TH1.h:577
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:58
TAxis * GetZaxis()
Definition TH1.h:324
TAxis * GetXaxis()
Definition TH1.h:322
TAxis * GetYaxis()
Definition TH1.h:323
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
Definition TH1.cxx:2727
2-D histogram with a float per channel (see TH1 documentation)}
Definition TH2.h:257
3-D histogram with a float per channel (see TH1 documentation)}
Definition TH3.h:268
Long64_t Fill(const Double_t *x, Double_t w=1.)
Definition THnBase.h:149
Double_t GetSumw() const
Definition THnBase.h:211
TAxis * GetAxis(Int_t dim) const
Definition THnBase.h:130
Efficient multidimensional histogram.
Definition THnSparse.h:36
Double_t GetBinContent(const Int_t *idx) const
Forwards to THnBase::GetBinContent() overload.
Definition THnSparse.h:120
Long64_t GetBin(const Int_t *idx) const override
Definition THnSparse.h:95
void Sumw2() override
Enable calculation of errors.
Long64_t GetNbins() const override
Definition THnSparse.h:92
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
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 Common.h:18
@ InputArguments
Namespace for the RooStats classes.
Definition Asimov.h:19
void SetParameters(const RooArgSet *desiredVals, RooArgSet *paramsToChange)
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123
RooDataHist * fDataHist
CompareDataHistBins(RooDataHist *hist)
CompareSparseHistBins(THnSparse *hist)
CompareVectorIndices(MarkovChain *chain, RooRealVar *param)
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345