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
359 std::unique_ptr<RooDataSet> chain{fChain->GetAsDataSet(SelectVars(fParameters),
361 RooArgList* paramsList = new RooArgList();
362 for (Int_t i = 0; i < fDimension; i++)
363 paramsList->add(*fAxes[i]);
364
365 fKeysPdf = new RooNDKeysPdf("keysPDF", "Keys PDF", *paramsList, *chain, "a");
366 fCutoffVar = new RooRealVar("cutoff", "cutoff", 0);
367 fHeaviside = new Heaviside("heaviside", "Heaviside", *fKeysPdf, *fCutoffVar);
368 fProduct = new RooProduct("product", "Keys PDF & Heaviside Product",
370}
371
372////////////////////////////////////////////////////////////////////////////////
373
375{
376 if (fAxes == nullptr || fChain == nullptr) {
377 coutE(Eval) << "* Error in MCMCInterval::CreateHist(): " <<
378 "Crucial data member was nullptr." << endl;
379 coutE(Eval) << "Make sure to fully construct/initialize." << endl;
380 return;
381 }
382 if (fHist != nullptr) {
383 delete fHist;
384 fHist = nullptr;
385 }
386
387 if (fNumBurnInSteps >= fChain->Size()) {
389 "MCMCInterval::CreateHist: creation of histogram failed: " <<
390 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
391 "in Markov chain." << endl;
392 return;
393 }
394
395 if (fDimension == 1)
396 fHist = new TH1F("posterior", "MCMC Posterior Histogram",
397 fAxes[0]->numBins(), fAxes[0]->getMin(), fAxes[0]->getMax());
398
399 else if (fDimension == 2)
400 fHist = new TH2F("posterior", "MCMC Posterior Histogram",
401 fAxes[0]->numBins(), fAxes[0]->getMin(), fAxes[0]->getMax(),
402 fAxes[1]->numBins(), fAxes[1]->getMin(), fAxes[1]->getMax());
403
404 else if (fDimension == 3)
405 fHist = new TH3F("posterior", "MCMC Posterior Histogram",
406 fAxes[0]->numBins(), fAxes[0]->getMin(), fAxes[0]->getMax(),
407 fAxes[1]->numBins(), fAxes[1]->getMin(), fAxes[1]->getMax(),
408 fAxes[2]->numBins(), fAxes[2]->getMin(), fAxes[2]->getMax());
409
410 else {
411 coutE(Eval) << "* Error in MCMCInterval::CreateHist() : " <<
412 "TH1* couldn't handle dimension: " << fDimension << endl;
413 return;
414 }
415
416 // Fill histogram
417 Int_t size = fChain->Size();
418 const RooArgSet* entry;
419 for (Int_t i = fNumBurnInSteps; i < size; i++) {
420 entry = fChain->Get(i);
421 if (fDimension == 1)
422 ((TH1F*)fHist)->Fill(entry->getRealValue(fAxes[0]->GetName()),
423 fChain->Weight());
424 else if (fDimension == 2)
425 ((TH2F*)fHist)->Fill(entry->getRealValue(fAxes[0]->GetName()),
426 entry->getRealValue(fAxes[1]->GetName()),
427 fChain->Weight());
428 else
429 ((TH3F*)fHist)->Fill(entry->getRealValue(fAxes[0]->GetName()),
430 entry->getRealValue(fAxes[1]->GetName()),
431 entry->getRealValue(fAxes[2]->GetName()),
432 fChain->Weight());
433 }
434
435 if (fDimension >= 1)
437 if (fDimension >= 2)
439 if (fDimension >= 3)
441}
442
443////////////////////////////////////////////////////////////////////////////////
444
446{
447 if (fAxes == nullptr || fChain == nullptr) {
448 coutE(InputArguments) << "* Error in MCMCInterval::CreateSparseHist(): "
449 << "Crucial data member was nullptr." << endl;
450 coutE(InputArguments) << "Make sure to fully construct/initialize."
451 << endl;
452 return;
453 }
454 if (fSparseHist != nullptr)
455 delete fSparseHist;
456
457 std::vector<double> min(fDimension);
458 std::vector<double> max(fDimension);
459 std::vector<Int_t> bins(fDimension);
460 for (Int_t i = 0; i < fDimension; i++) {
461 min[i] = fAxes[i]->getMin();
462 max[i] = fAxes[i]->getMax();
463 bins[i] = fAxes[i]->numBins();
464 }
465 fSparseHist = new THnSparseF("posterior", "MCMC Posterior Histogram",
466 fDimension, bins.data(), min.data(), max.data());
467
468 // kbelasco: it appears we need to call Sumw2() just to get the
469 // histogram to keep a running total of the weight so that Getsumw doesn't
470 // just return 0
472
473 if (fNumBurnInSteps >= fChain->Size()) {
475 "MCMCInterval::CreateSparseHist: creation of histogram failed: " <<
476 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
477 "in Markov chain." << endl;
478 }
479
480 // Fill histogram
481 Int_t size = fChain->Size();
482 const RooArgSet* entry;
483 std::vector<double> x(fDimension);
484 for (Int_t i = fNumBurnInSteps; i < size; i++) {
485 entry = fChain->Get(i);
486 for (Int_t ii = 0; ii < fDimension; ii++)
487 x[ii] = entry->getRealValue(fAxes[ii]->GetName());
488 fSparseHist->Fill(x.data(), fChain->Weight());
489 }
490}
491
492////////////////////////////////////////////////////////////////////////////////
493
495{
496 if (fParameters.empty() || fChain == nullptr) {
497 coutE(Eval) << "* Error in MCMCInterval::CreateDataHist(): " <<
498 "Crucial data member was nullptr or empty." << endl;
499 coutE(Eval) << "Make sure to fully construct/initialize." << endl;
500 return;
501 }
502
503 if (fNumBurnInSteps >= fChain->Size()) {
505 "MCMCInterval::CreateDataHist: creation of histogram failed: " <<
506 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
507 "in Markov chain." << endl;
508 fDataHist = nullptr;
509 return;
510 }
511
512 fDataHist = std::unique_ptr<RooDataHist>{fChain->GetAsDataHist(SelectVars(fParameters),
513 EventRange(fNumBurnInSteps, fChain->Size()))}.release();
514}
515
516////////////////////////////////////////////////////////////////////////////////
517
519{
520 fVector.clear();
521 fVecWeight = 0;
522
523 if (fChain == nullptr) {
524 coutE(InputArguments) << "* Error in MCMCInterval::CreateVector(): " <<
525 "Crucial data member (Markov chain) was nullptr." << endl;
526 coutE(InputArguments) << "Make sure to fully construct/initialize."
527 << endl;
528 return;
529 }
530
531 if (fNumBurnInSteps >= fChain->Size()) {
533 "MCMCInterval::CreateVector: creation of vector failed: " <<
534 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
535 "in Markov chain." << endl;
536 }
537
538 // Fill vector
540 fVector.resize(size);
541 Int_t i;
542 Int_t chainIndex;
543 for (i = 0; i < size; i++) {
544 chainIndex = i + fNumBurnInSteps;
545 fVector[i] = chainIndex;
546 fVecWeight += fChain->Weight(chainIndex);
547 }
548
549 stable_sort(fVector.begin(), fVector.end(),
551}
552
553////////////////////////////////////////////////////////////////////////////////
554
556{
558 fParameters.add(parameters);
560 if (fAxes != nullptr)
561 delete[] fAxes;
563 Int_t n = 0;
564 for (auto *obj : fParameters) {
565 if (dynamic_cast<RooRealVar*>(obj) != nullptr)
566 fAxes[n] = static_cast<RooRealVar*>(obj);
567 else
568 coutE(Eval) << "* Error in MCMCInterval::SetParameters: " <<
569 obj->GetName() << " not a RooRealVar*" << std::endl;
570 n++;
571 }
572}
573
574////////////////////////////////////////////////////////////////////////////////
575
577{
578 switch (fIntervalType) {
579 case kShortest:
581 break;
582 case kTailFraction:
584 break;
585 default:
586 coutE(InputArguments) << "MCMCInterval::DetermineInterval(): " <<
587 "Error: Interval type not set" << endl;
588 break;
589 }
590}
591
592////////////////////////////////////////////////////////////////////////////////
593
595{
596 if (fUseKeys)
598 else
600}
601
602////////////////////////////////////////////////////////////////////////////////
603
605{
606 if (fLeftSideTF < 0 || fLeftSideTF > 1) {
607 coutE(InputArguments) << "MCMCInterval::DetermineTailFractionInterval: "
608 << "Fraction must be in the range [0, 1]. "
609 << fLeftSideTF << "is not allowed." << endl;
610 return;
611 }
612
613 if (fDimension != 1) {
614 coutE(InputArguments) << "MCMCInterval::DetermineTailFractionInterval(): "
615 << "Error: Can only find a tail-fraction interval for 1-D intervals"
616 << endl;
617 return;
618 }
619
620 if (fAxes == nullptr) {
621 coutE(InputArguments) << "MCMCInterval::DetermineTailFractionInterval(): "
622 << "Crucial data member was nullptr." << endl;
623 coutE(InputArguments) << "Make sure to fully construct/initialize."
624 << endl;
625 return;
626 }
627
628 // kbelasco: fill in code here to find interval
629 //
630 // also make changes so that calling GetPosterior...() returns nullptr
631 // when fIntervalType == kTailFraction, since there really
632 // is no posterior for this type of interval determination
633 if (fVector.empty())
635
636 if (fVector.empty() || fVecWeight == 0) {
637 // if size is still 0, then creation failed.
638 // if fVecWeight == 0, then there are no entries (indicates the same
639 // error as fVector.empty() because that only happens when
640 // fNumBurnInSteps >= fChain->Size())
641 // either way, reset and return
642 fVector.clear();
643 fTFLower = -1.0 * RooNumber::infinity();
645 fTFConfLevel = 0.0;
646 fVecWeight = 0;
647 return;
648 }
649
650 RooRealVar* param = fAxes[0];
651
652 double c = fConfidenceLevel;
653 double leftTailCutoff = fVecWeight * (1 - c) * fLeftSideTF;
654 double rightTailCutoff = fVecWeight * (1 - c) * (1 - fLeftSideTF);
655 double leftTailSum = 0;
656 double rightTailSum = 0;
657
658 // kbelasco: consider changing these values to +infinity and -infinity
659 double ll = param->getMin();
660 double ul = param->getMax();
661
662 double x;
663 double w;
664
665 // save a lot of GetName() calls if compiler does not already optimize this
666 const char* name = param->GetName();
667
668 // find lower limit
669 Int_t i;
670 for (i = 0; i < (Int_t)fVector.size(); i++) {
672 w = fChain->Weight();
673
674 if (TMath::Abs(leftTailSum + w - leftTailCutoff) <
675 TMath::Abs(leftTailSum - leftTailCutoff)) {
676 // moving the lower limit to x would bring us closer to the desired
677 // left tail size
678 ll = x;
679 leftTailSum += w;
680 } else
681 break;
682 }
683
684 // find upper limit
685 for (i = (Int_t)fVector.size() - 1; i >= 0; i--) {
687 w = fChain->Weight();
688
689 if (TMath::Abs(rightTailSum + w - rightTailCutoff) <
690 TMath::Abs(rightTailSum - rightTailCutoff)) {
691 // moving the lower limit to x would bring us closer to the desired
692 // left tail size
693 ul = x;
694 rightTailSum += w;
695 } else
696 break;
697 }
698
699 fTFLower = ll;
700 fTFUpper = ul;
701 fTFConfLevel = 1 - (leftTailSum + rightTailSum) / fVecWeight;
702}
703
704////////////////////////////////////////////////////////////////////////////////
705
707{
708 if (fKeysPdf == nullptr)
710
711 if (fKeysPdf == nullptr) {
712 // if fKeysPdf is still nullptr, then it means CreateKeysPdf failed
713 // so clear all the data members this function would normally determine
714 // and return
715 fFull = 0.0;
716 fKeysCutoff = -1;
717 fKeysConfLevel = 0.0;
718 return;
719 }
720
721 // now we have a keys pdf of the posterior
722
723 double cutoff = 0.0;
724 fCutoffVar->setVal(cutoff);
725 double full = std::unique_ptr<RooAbsReal>{fProduct->createIntegral(fParameters, NormSet(fParameters))}->getVal(fParameters);
726 fFull = full;
727 if (full < 0.98) {
728 coutW(Eval) << "Warning: Integral of Keys PDF came out to " << full
729 << " instead of expected value 1. Will continue using this "
730 << "factor to normalize further integrals of this PDF." << endl;
731 }
732
733 // kbelasco: Is there a better way to set the search range?
734 // from 0 to max value of Keys
735 // kbelasco: how to get max value?
736 //double max = product.maxVal(product.getMaxVal(fParameters));
737
738 double volume = 1.0;
739 for (auto *var : static_range_cast<RooRealVar*>(fParameters))
740 volume *= (var->getMax() - var->getMin());
741
742 double topCutoff = full / volume;
743 double bottomCutoff = topCutoff;
744 double confLevel = CalcConfLevel(topCutoff, full);
745 if (AcceptableConfLevel(confLevel)) {
746 fKeysConfLevel = confLevel;
747 fKeysCutoff = topCutoff;
748 return;
749 }
750 bool changed = false;
751 // find high end of range
752 while (confLevel > fConfidenceLevel) {
753 topCutoff *= 2.0;
754 confLevel = CalcConfLevel(topCutoff, full);
755 if (AcceptableConfLevel(confLevel)) {
756 fKeysConfLevel = confLevel;
757 fKeysCutoff = topCutoff;
758 return;
759 }
760 changed = true;
761 }
762 if (changed) {
763 bottomCutoff = topCutoff / 2.0;
764 } else {
765 changed = false;
766 bottomCutoff /= 2.0;
767 confLevel = CalcConfLevel(bottomCutoff, full);
768 if (AcceptableConfLevel(confLevel)) {
769 fKeysConfLevel = confLevel;
770 fKeysCutoff = bottomCutoff;
771 return;
772 }
773 while (confLevel < fConfidenceLevel) {
774 bottomCutoff /= 2.0;
775 confLevel = CalcConfLevel(bottomCutoff, full);
776 if (AcceptableConfLevel(confLevel)) {
777 fKeysConfLevel = confLevel;
778 fKeysCutoff = bottomCutoff;
779 return;
780 }
781 changed = true;
782 }
783 if (changed) {
784 topCutoff = bottomCutoff * 2.0;
785 }
786 }
787
788 coutI(Eval) << "range set: [" << bottomCutoff << ", " << topCutoff << "]"
789 << endl;
790
791 cutoff = (topCutoff + bottomCutoff) / 2.0;
792 confLevel = CalcConfLevel(cutoff, full);
793
794 // need to use WithinDeltaFraction() because sometimes the integrating the
795 // posterior in this binary search seems to not have enough granularity to
796 // find an acceptable conf level (small no. of strange cases).
797 // WithinDeltaFraction causes the search to terminate when
798 // topCutoff is essentially equal to bottomCutoff (compared to the magnitude
799 // of their mean).
800 while (!AcceptableConfLevel(confLevel) &&
801 !WithinDeltaFraction(topCutoff, bottomCutoff)) {
802 if (confLevel > fConfidenceLevel)
803 bottomCutoff = cutoff;
804 else if (confLevel < fConfidenceLevel)
805 topCutoff = cutoff;
806 cutoff = (topCutoff + bottomCutoff) / 2.0;
807 coutI(Eval) << "cutoff range: [" << bottomCutoff << ", "
808 << topCutoff << "]" << endl;
809 confLevel = CalcConfLevel(cutoff, full);
810 }
811
812 fKeysCutoff = cutoff;
813 fKeysConfLevel = confLevel;
814}
815
816////////////////////////////////////////////////////////////////////////////////
817
819{
820 if (fUseSparseHist)
822 else
824}
825
826////////////////////////////////////////////////////////////////////////////////
827
829{
830 Long_t numBins;
831 if (fSparseHist == nullptr)
833
834 if (fSparseHist == nullptr) {
835 // if fSparseHist is still nullptr, then CreateSparseHist failed
836 fHistCutoff = -1;
837 fHistConfLevel = 0.0;
838 return;
839 }
840
841 numBins = (Long_t)fSparseHist->GetNbins();
842
843 std::vector<Long_t> bins(numBins);
844 for (Int_t ibin = 0; ibin < numBins; ibin++)
845 bins[ibin] = (Long_t)ibin;
846 std::stable_sort(bins.begin(), bins.end(), CompareSparseHistBins(fSparseHist));
847
848 double nEntries = fSparseHist->GetSumw();
849 double sum = 0;
850 double content;
851 Int_t i;
852 // see above note on indexing to understand numBins - 3
853 for (i = numBins - 1; i >= 0; i--) {
854 content = fSparseHist->GetBinContent(bins[i]);
855 if ((sum + content) / nEntries >= fConfidenceLevel) {
856 fHistCutoff = content;
857 if (fIsHistStrict) {
858 sum += content;
859 i--;
860 break;
861 } else {
862 i++;
863 break;
864 }
865 }
866 sum += content;
867 }
868
869 if (fIsHistStrict) {
870 // keep going to find the sum
871 for ( ; i >= 0; i--) {
872 content = fSparseHist->GetBinContent(bins[i]);
873 if (content == fHistCutoff)
874 sum += content;
875 else
876 break; // content must be < fHistCutoff
877 }
878 } else {
879 // backtrack to find the cutoff and sum
880 for ( ; i < numBins; i++) {
881 content = fSparseHist->GetBinContent(bins[i]);
882 if (content > fHistCutoff) {
883 fHistCutoff = content;
884 break;
885 } else // content == fHistCutoff
886 sum -= content;
887 if (i == numBins - 1)
888 // still haven't set fHistCutoff correctly yet, and we have no bins
889 // left, so set fHistCutoff to something higher than the tallest bin
890 fHistCutoff = content + 1.0;
891 }
892 }
893
894 fHistConfLevel = sum / nEntries;
895}
896
897////////////////////////////////////////////////////////////////////////////////
898
900{
901 Int_t numBins;
902 if (fDataHist == nullptr)
904 if (fDataHist == nullptr) {
905 // if fDataHist is still nullptr, then CreateDataHist failed
906 fHistCutoff = -1;
907 fHistConfLevel = 0.0;
908 return;
909 }
910
911 numBins = fDataHist->numEntries();
912
913 std::vector<Int_t> bins(numBins);
914 for (Int_t ibin = 0; ibin < numBins; ibin++)
915 bins[ibin] = ibin;
916 std::stable_sort(bins.begin(), bins.end(), CompareDataHistBins(fDataHist));
917
918 double nEntries = fDataHist->sum(false);
919 double sum = 0;
920 double content;
921 Int_t i;
922 for (i = numBins - 1; i >= 0; i--) {
923 fDataHist->get(bins[i]);
924 content = fDataHist->weight();
925 if ((sum + content) / nEntries >= fConfidenceLevel) {
926 fHistCutoff = content;
927 if (fIsHistStrict) {
928 sum += content;
929 i--;
930 break;
931 } else {
932 i++;
933 break;
934 }
935 }
936 sum += content;
937 }
938
939 if (fIsHistStrict) {
940 // keep going to find the sum
941 for ( ; i >= 0; i--) {
942 fDataHist->get(bins[i]);
943 content = fDataHist->weight();
944 if (content == fHistCutoff)
945 sum += content;
946 else
947 break; // content must be < fHistCutoff
948 }
949 } else {
950 // backtrack to find the cutoff and sum
951 for ( ; i < numBins; i++) {
952 fDataHist->get(bins[i]);
953 content = fDataHist->weight();
954 if (content > fHistCutoff) {
955 fHistCutoff = content;
956 break;
957 } else // content == fHistCutoff
958 sum -= content;
959 if (i == numBins - 1)
960 // still haven't set fHistCutoff correctly yet, and we have no bins
961 // left, so set fHistCutoff to something higher than the tallest bin
962 fHistCutoff = content + 1.0;
963 }
964 }
965
966 fHistConfLevel = sum / nEntries;
967}
968
969////////////////////////////////////////////////////////////////////////////////
970
972{
973 if (fIntervalType == kShortest) {
974 if (fUseKeys)
975 return fKeysConfLevel;
976 else
977 return fHistConfLevel;
978 } else if (fIntervalType == kTailFraction) {
979 return fTFConfLevel;
980 } else {
981 coutE(InputArguments) << "MCMCInterval::GetActualConfidenceLevel: "
982 << "not implemented for this type of interval. Returning 0." << endl;
983 return 0;
984 }
985}
986
987////////////////////////////////////////////////////////////////////////////////
988
990{
991 switch (fIntervalType) {
992 case kShortest:
993 return LowerLimitShortest(param);
994 case kTailFraction:
995 return LowerLimitTailFraction(param);
996 default:
997 coutE(InputArguments) << "MCMCInterval::LowerLimit(): " <<
998 "Error: Interval type not set" << endl;
999 return RooNumber::infinity();
1000 }
1001}
1002
1003////////////////////////////////////////////////////////////////////////////////
1004
1006{
1007 switch (fIntervalType) {
1008 case kShortest:
1009 return UpperLimitShortest(param);
1010 case kTailFraction:
1011 return UpperLimitTailFraction(param);
1012 default:
1013 coutE(InputArguments) << "MCMCInterval::UpperLimit(): " <<
1014 "Error: Interval type not set" << endl;
1015 return RooNumber::infinity();
1016 }
1017}
1018
1019////////////////////////////////////////////////////////////////////////////////
1020
1022{
1023 if (fTFLower == -1.0 * RooNumber::infinity())
1025
1026 return fTFLower;
1027}
1028
1029////////////////////////////////////////////////////////////////////////////////
1030
1032{
1035
1036 return fTFUpper;
1037}
1038
1039////////////////////////////////////////////////////////////////////////////////
1040
1042{
1043 if (fUseKeys)
1044 return LowerLimitByKeys(param);
1045 else
1046 return LowerLimitByHist(param);
1047}
1048
1049////////////////////////////////////////////////////////////////////////////////
1050
1052{
1053 if (fUseKeys)
1054 return UpperLimitByKeys(param);
1055 else
1056 return UpperLimitByHist(param);
1057}
1058
1059////////////////////////////////////////////////////////////////////////////////
1060/// Determine the lower limit for param on this interval
1061/// using the binned data set
1062
1064{
1065 if (fUseSparseHist)
1066 return LowerLimitBySparseHist(param);
1067 else
1068 return LowerLimitByDataHist(param);
1069}
1070
1071////////////////////////////////////////////////////////////////////////////////
1072/// Determine the upper limit for param on this interval
1073/// using the binned data set
1074
1076{
1077 if (fUseSparseHist)
1078 return UpperLimitBySparseHist(param);
1079 else
1080 return UpperLimitByDataHist(param);
1081}
1082
1083////////////////////////////////////////////////////////////////////////////////
1084/// Determine the lower limit for param on this interval
1085/// using the binned data set
1086
1088{
1089 if (fDimension != 1) {
1090 coutE(InputArguments) << "In MCMCInterval::LowerLimitBySparseHist: "
1091 << "Sorry, will not compute lower limit unless dimension == 1" << endl;
1092 return param.getMin();
1093 }
1094 if (fHistCutoff < 0)
1095 DetermineBySparseHist(); // this initializes fSparseHist
1096
1097 if (fHistCutoff < 0) {
1098 // if fHistCutoff < 0 still, then determination of interval failed
1099 coutE(Eval) << "In MCMCInterval::LowerLimitBySparseHist: "
1100 << "couldn't determine cutoff. Check that num burn in steps < num "
1101 << "steps in the Markov chain. Returning param.getMin()." << endl;
1102 return param.getMin();
1103 }
1104
1105 std::vector<Int_t> coord(fDimension);
1106 for (Int_t d = 0; d < fDimension; d++) {
1107 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1108 Long_t numBins = (Long_t)fSparseHist->GetNbins();
1109 double lowerLimit = param.getMax();
1110 double val;
1111 for (Long_t i = 0; i < numBins; i++) {
1112 if (fSparseHist->GetBinContent(i, &coord[0]) >= fHistCutoff) {
1113 val = fSparseHist->GetAxis(d)->GetBinCenter(coord[d]);
1114 if (val < lowerLimit)
1115 lowerLimit = val;
1116 }
1117 }
1118 return lowerLimit;
1119 }
1120 }
1121 return param.getMin();
1122}
1123
1124////////////////////////////////////////////////////////////////////////////////
1125/// Determine the lower limit for param on this interval
1126/// using the binned data set
1127
1129{
1130 if (fHistCutoff < 0)
1131 DetermineByDataHist(); // this initializes fDataHist
1132
1133 if (fHistCutoff < 0) {
1134 // if fHistCutoff < 0 still, then determination of interval failed
1135 coutE(Eval) << "In MCMCInterval::LowerLimitByDataHist: "
1136 << "couldn't determine cutoff. Check that num burn in steps < num "
1137 << "steps in the Markov chain. Returning param.getMin()." << endl;
1138 return param.getMin();
1139 }
1140
1141 for (Int_t d = 0; d < fDimension; d++) {
1142 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1143 Int_t numBins = fDataHist->numEntries();
1144 double lowerLimit = param.getMax();
1145 double val;
1146 for (Int_t i = 0; i < numBins; i++) {
1147 fDataHist->get(i);
1148 if (fDataHist->weight() >= fHistCutoff) {
1149 val = fDataHist->get()->getRealValue(param.GetName());
1150 if (val < lowerLimit)
1151 lowerLimit = val;
1152 }
1153 }
1154 return lowerLimit;
1155 }
1156 }
1157 return param.getMin();
1158}
1159
1160////////////////////////////////////////////////////////////////////////////////
1161/// Determine the upper limit for param on this interval
1162/// using the binned data set
1163
1165{
1166 if (fDimension != 1) {
1167 coutE(InputArguments) << "In MCMCInterval::UpperLimitBySparseHist: "
1168 << "Sorry, will not compute upper limit unless dimension == 1" << endl;
1169 return param.getMax();
1170 }
1171 if (fHistCutoff < 0)
1172 DetermineBySparseHist(); // this initializes fSparseHist
1173
1174 if (fHistCutoff < 0) {
1175 // if fHistCutoff < 0 still, then determination of interval failed
1176 coutE(Eval) << "In MCMCInterval::UpperLimitBySparseHist: "
1177 << "couldn't determine cutoff. Check that num burn in steps < num "
1178 << "steps in the Markov chain. Returning param.getMax()." << endl;
1179 return param.getMax();
1180 }
1181
1182 std::vector<Int_t> coord(fDimension);
1183 for (Int_t d = 0; d < fDimension; d++) {
1184 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1185 Long_t numBins = (Long_t)fSparseHist->GetNbins();
1186 double upperLimit = param.getMin();
1187 double val;
1188 for (Long_t i = 0; i < numBins; i++) {
1189 if (fSparseHist->GetBinContent(i, &coord[0]) >= fHistCutoff) {
1190 val = fSparseHist->GetAxis(d)->GetBinCenter(coord[d]);
1191 if (val > upperLimit)
1192 upperLimit = val;
1193 }
1194 }
1195 return upperLimit;
1196 }
1197 }
1198 return param.getMax();
1199}
1200
1201////////////////////////////////////////////////////////////////////////////////
1202/// Determine the upper limit for param on this interval
1203/// using the binned data set
1204
1206{
1207 if (fHistCutoff < 0)
1208 DetermineByDataHist(); // this initializes fDataHist
1209
1210 if (fHistCutoff < 0) {
1211 // if fHistCutoff < 0 still, then determination of interval failed
1212 coutE(Eval) << "In MCMCInterval::UpperLimitByDataHist: "
1213 << "couldn't determine cutoff. Check that num burn in steps < num "
1214 << "steps in the Markov chain. Returning param.getMax()." << endl;
1215 return param.getMax();
1216 }
1217
1218 for (Int_t d = 0; d < fDimension; d++) {
1219 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1220 Int_t numBins = fDataHist->numEntries();
1221 double upperLimit = param.getMin();
1222 double val;
1223 for (Int_t i = 0; i < numBins; i++) {
1224 fDataHist->get(i);
1225 if (fDataHist->weight() >= fHistCutoff) {
1226 val = fDataHist->get()->getRealValue(param.GetName());
1227 if (val > upperLimit)
1228 upperLimit = val;
1229 }
1230 }
1231 return upperLimit;
1232 }
1233 }
1234 return param.getMax();
1235}
1236
1237////////////////////////////////////////////////////////////////////////////////
1238/// Determine the lower limit for param on this interval
1239/// using the keys pdf
1240
1242{
1243 if (fKeysCutoff < 0)
1245
1246 if (fKeysDataHist == nullptr)
1248
1249 if (fKeysCutoff < 0 || fKeysDataHist == nullptr) {
1250 // failure in determination of cutoff and/or creation of histogram
1251 coutE(Eval) << "in MCMCInterval::LowerLimitByKeys(): "
1252 << "couldn't find lower limit, check that the number of burn in "
1253 << "steps < number of total steps in the Markov chain. Returning "
1254 << "param.getMin()" << endl;
1255 return param.getMin();
1256 }
1257
1258 for (Int_t d = 0; d < fDimension; d++) {
1259 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1260 Int_t numBins = fKeysDataHist->numEntries();
1261 double lowerLimit = param.getMax();
1262 double val;
1263 for (Int_t i = 0; i < numBins; i++) {
1264 fKeysDataHist->get(i);
1265 if (fKeysDataHist->weight() >= fKeysCutoff) {
1266 val = fKeysDataHist->get()->getRealValue(param.GetName());
1267 if (val < lowerLimit)
1268 lowerLimit = val;
1269 }
1270 }
1271 return lowerLimit;
1272 }
1273 }
1274 return param.getMin();
1275}
1276
1277////////////////////////////////////////////////////////////////////////////////
1278/// Determine the upper limit for param on this interval
1279/// using the keys pdf
1280
1282{
1283 if (fKeysCutoff < 0)
1285
1286 if (fKeysDataHist == nullptr)
1288
1289 if (fKeysCutoff < 0 || fKeysDataHist == nullptr) {
1290 // failure in determination of cutoff and/or creation of histogram
1291 coutE(Eval) << "in MCMCInterval::UpperLimitByKeys(): "
1292 << "couldn't find upper limit, check that the number of burn in "
1293 << "steps < number of total steps in the Markov chain. Returning "
1294 << "param.getMax()" << endl;
1295 return param.getMax();
1296 }
1297
1298 for (Int_t d = 0; d < fDimension; d++) {
1299 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1300 Int_t numBins = fKeysDataHist->numEntries();
1301 double upperLimit = param.getMin();
1302 double val;
1303 for (Int_t i = 0; i < numBins; i++) {
1304 fKeysDataHist->get(i);
1305 if (fKeysDataHist->weight() >= fKeysCutoff) {
1306 val = fKeysDataHist->get()->getRealValue(param.GetName());
1307 if (val > upperLimit)
1308 upperLimit = val;
1309 }
1310 }
1311 return upperLimit;
1312 }
1313 }
1314 return param.getMax();
1315}
1316
1317////////////////////////////////////////////////////////////////////////////////
1318/// Determine the approximate maximum value of the Keys PDF
1319
1321{
1322 if (fKeysCutoff < 0)
1324
1325 if (fKeysDataHist == nullptr)
1327
1328 if (fKeysDataHist == nullptr) {
1329 // failure in determination of cutoff and/or creation of histogram
1330 coutE(Eval) << "in MCMCInterval::KeysMax(): "
1331 << "couldn't find Keys max value, check that the number of burn in "
1332 << "steps < number of total steps in the Markov chain. Returning 0"
1333 << endl;
1334 return 0;
1335 }
1336
1337 Int_t numBins = fKeysDataHist->numEntries();
1338 double max = 0;
1339 double w;
1340 for (Int_t i = 0; i < numBins; i++) {
1341 fKeysDataHist->get(i);
1342 w = fKeysDataHist->weight();
1343 if (w > max)
1344 max = w;
1345 }
1346
1347 return max;
1348}
1349
1350////////////////////////////////////////////////////////////////////////////////
1351
1353{
1354 if (fHistCutoff < 0)
1356
1357 return fHistCutoff;
1358}
1359
1360////////////////////////////////////////////////////////////////////////////////
1361
1363{
1364 if (fKeysCutoff < 0)
1366
1367 // kbelasco: if fFull hasn't been set (because Keys creation failed because
1368 // fNumBurnInSteps >= fChain->Size()) then this will return infinity, which
1369 // seems ok to me since it will indicate error
1370
1371 return fKeysCutoff / fFull;
1372}
1373
1374////////////////////////////////////////////////////////////////////////////////
1375
1376double MCMCInterval::CalcConfLevel(double cutoff, double full)
1377{
1378 fCutoffVar->setVal(cutoff);
1379 std::unique_ptr<RooAbsReal> integral{fProduct->createIntegral(fParameters, NormSet(fParameters))};
1380 double confLevel = integral->getVal(fParameters) / full;
1381 coutI(Eval) << "cutoff = " << cutoff << ", conf = " << confLevel << endl;
1382 return confLevel;
1383}
1384
1385////////////////////////////////////////////////////////////////////////////////
1386
1388{
1389 if(fConfidenceLevel == 0)
1390 coutE(InputArguments) << "Error in MCMCInterval::GetPosteriorHist: "
1391 << "confidence level not set " << endl;
1392 if (fHist == nullptr)
1393 CreateHist();
1394
1395 if (fHist == nullptr)
1396 // if fHist is still nullptr, then CreateHist failed
1397 return nullptr;
1398
1399 return (TH1*) fHist->Clone("MCMCposterior_hist");
1400}
1401
1402////////////////////////////////////////////////////////////////////////////////
1403
1405{
1406 if (fConfidenceLevel == 0)
1407 coutE(InputArguments) << "Error in MCMCInterval::GetPosteriorKeysPdf: "
1408 << "confidence level not set " << endl;
1409 if (fKeysPdf == nullptr)
1410 CreateKeysPdf();
1411
1412 if (fKeysPdf == nullptr)
1413 // if fKeysPdf is still nullptr, then it means CreateKeysPdf failed
1414 return nullptr;
1415
1416 return (RooNDKeysPdf*) fKeysPdf->Clone("MCMCPosterior_keys");
1417}
1418
1419////////////////////////////////////////////////////////////////////////////////
1420
1422{
1423 if (fConfidenceLevel == 0)
1424 coutE(InputArguments) << "MCMCInterval::GetPosteriorKeysProduct: "
1425 << "confidence level not set " << endl;
1426 if (fProduct == nullptr) {
1427 CreateKeysPdf();
1429 }
1430
1431 if (fProduct == nullptr)
1432 // if fProduct is still nullptr, then it means CreateKeysPdf failed
1433 return nullptr;
1434
1435 return (RooProduct*) fProduct->Clone("MCMCPosterior_keysproduct");
1436}
1437
1438////////////////////////////////////////////////////////////////////////////////
1439
1441{
1442 // returns list of parameters
1443 return new RooArgSet(fParameters);
1444}
1445
1446////////////////////////////////////////////////////////////////////////////////
1447
1449{
1450 return (TMath::Abs(confLevel - fConfidenceLevel) < fEpsilon);
1451}
1452
1453////////////////////////////////////////////////////////////////////////////////
1454
1456{
1457 return (TMath::Abs(a - b) < TMath::Abs(fDelta * (a + b)/2));
1458}
1459
1460////////////////////////////////////////////////////////////////////////////////
1461
1463{
1464 if (fAxes == nullptr)
1465 return;
1466 if (fProduct == nullptr)
1468 if (fProduct == nullptr)
1469 // if fProduct still nullptr, then creation failed
1470 return;
1471
1472 //RooAbsBinning** savedBinning = new RooAbsBinning*[fDimension];
1473 std::vector<Int_t> savedBins(fDimension);
1474 Int_t i;
1475 double numBins;
1476 RooRealVar* var;
1477
1478 // kbelasco: Note - the accuracy is only increased here if the binning for
1479 // each RooRealVar is uniform
1480
1481 // kbelasco: look into why saving the binnings and replacing them doesn't
1482 // work (replaces with 1 bin always).
1483 // Note: this code modifies the binning for the parameters (if they are
1484 // uniform) and sets them back to what they were. If the binnings are not
1485 // uniform, this code does nothing.
1486
1487 // first scan through fAxes to make sure all binnings are uniform, or else
1488 // we can't change the number of bins because there seems to be an error
1489 // when setting the binning itself rather than just the number of bins
1490 bool tempChangeBinning = true;
1491 for (i = 0; i < fDimension; i++) {
1492 if (!fAxes[i]->getBinning(nullptr, false, false).isUniform()) {
1493 tempChangeBinning = false;
1494 break;
1495 }
1496 }
1497
1498 // kbelasco: for 1 dimension this should be fine, but for more dimensions
1499 // the total number of bins in the histogram increases exponentially with
1500 // the dimension, so don't do this above 1-D for now.
1501 if (fDimension >= 2)
1502 tempChangeBinning = false;
1503
1504 if (tempChangeBinning) {
1505 // set high number of bins for high accuracy on lower/upper limit by keys
1506 for (i = 0; i < fDimension; i++) {
1507 var = fAxes[i];
1508 //savedBinning[i] = &var->getBinning("__binning_clone", false, true);
1509 savedBins[i] = var->getBinning(nullptr, false, false).numBins();
1510 numBins = (var->getMax() - var->getMin()) / fEpsilon;
1511 var->setBins((Int_t)numBins);
1512 }
1513 }
1514
1515 fKeysDataHist = new RooDataHist("_productDataHist",
1516 "Keys PDF & Heaviside Product Data Hist", fParameters);
1518
1519 if (tempChangeBinning) {
1520 // set the binning back to normal
1521 for (i = 0; i < fDimension; i++)
1522 //fAxes[i]->setBinning(*savedBinning[i], nullptr);
1523 //fAxes[i]->setBins(savedBinning[i]->numBins(), nullptr);
1524 fAxes[i]->setBins(savedBins[i], nullptr);
1525 }
1526}
1527
1528////////////////////////////////////////////////////////////////////////////////
1529
1530bool MCMCInterval::CheckParameters(const RooArgSet& parameterPoint) const
1531{
1532 // check that the parameters are correct
1533
1534 if (parameterPoint.getSize() != fParameters.getSize() ) {
1535 coutE(Eval) << "MCMCInterval: size is wrong, parameters don't match" << std::endl;
1536 return false;
1537 }
1538 if ( ! parameterPoint.equals( fParameters ) ) {
1539 coutE(Eval) << "MCMCInterval: size is ok, but parameters don't match" << std::endl;
1540 return false;
1541 }
1542 return true;
1543}
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:91
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.
RooFit::OwningPtr< RooAbsReal > createIntegral(const RooArgSet &iset, const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
Create an object that represents the integral of the function over one or more observables listed in ...
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:103
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
Generic N-dimensional implementation of a kernel estimation p.d.f.
static constexpr double infinity()
Return internal infinity representation.
Definition RooNumber.h:25
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:37
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 RooFit::OwningPtr< RooDataHist > GetAsDataHist(RooArgSet *whichVars=nullptr) const
get this MarkovChain as a RooDataHist whose entries contain the values of whichVars.
virtual RooFit::OwningPtr< RooDataSet > GetAsDataSet(RooArgSet *whichVars=nullptr) const
get this MarkovChain as a RooDataSet 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 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:2734
2-D histogram with a float per channel (see TH1 documentation)}
Definition TH2.h:258
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 JSONIO.h:26
@ 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