89 ClassImp(RooStats::MCMCInterval);
91 using namespace RooFit;
92 using namespace RooStats;
95 static const Double_t DEFAULT_EPSILON = 0.01;
96 static const Double_t DEFAULT_DELTA = 10e-6;
100 MCMCInterval::MCMCInterval(
const char* name)
103 fConfidenceLevel = 0.0;
104 fHistConfLevel = 0.0;
105 fKeysConfLevel = 0.0;
116 fKeysDataHist = NULL;
124 fUseSparseHist = kFALSE;
125 fIsHistStrict = kTRUE;
126 fEpsilon = DEFAULT_EPSILON;
127 fDelta = DEFAULT_DELTA;
128 fIntervalType = kShortest;
129 fTFLower = -1.0 * RooNumber::infinity();
130 fTFUpper = RooNumber::infinity();
137 MCMCInterval::MCMCInterval(
const char* name,
138 const RooArgSet& parameters, MarkovChain& chain) : ConfInterval(name)
141 fConfidenceLevel = 0.0;
142 fHistConfLevel = 0.0;
143 fKeysConfLevel = 0.0;
154 fKeysDataHist = NULL;
160 fUseSparseHist = kFALSE;
161 fIsHistStrict = kTRUE;
162 fEpsilon = DEFAULT_EPSILON;
163 SetParameters(parameters);
164 fDelta = DEFAULT_DELTA;
165 fIntervalType = kShortest;
166 fTFLower = -1.0 * RooNumber::infinity();
167 fTFUpper = RooNumber::infinity();
174 MCMCInterval::~MCMCInterval()
186 delete fKeysDataHist;
190 struct CompareDataHistBins {
191 CompareDataHistBins(RooDataHist* hist) : fDataHist(hist) {}
192 bool operator() (Int_t bin1 , Int_t bin2) {
193 fDataHist->get(bin1);
194 Double_t n1 = fDataHist->weight();
195 fDataHist->get(bin2);
196 Double_t n2 = fDataHist->weight();
199 RooDataHist* fDataHist;
202 struct CompareSparseHistBins {
203 CompareSparseHistBins(THnSparse* hist) : fSparseHist(hist) {}
204 bool operator() (Long_t bin1, Long_t bin2) {
205 Double_t n1 = fSparseHist->GetBinContent(bin1);
206 Double_t n2 = fSparseHist->GetBinContent(bin2);
209 THnSparse* fSparseHist;
212 struct CompareVectorIndices {
213 CompareVectorIndices(MarkovChain* chain, RooRealVar* param) :
214 fChain(chain), fParam(param) {}
215 bool operator() (Int_t i, Int_t j) {
216 Double_t xi = fChain->Get(i)->getRealValue(fParam->GetName());
217 Double_t xj = fChain->Get(j)->getRealValue(fParam->GetName());
232 Bool_t MCMCInterval::IsInInterval(
const RooArgSet& point)
const
234 if (fIntervalType == kShortest) {
236 if (fKeysPdf == NULL)
240 RooStats::SetParameters(&point, const_cast<RooArgSet *>(&fParameters));
241 return fKeysPdf->getVal(&fParameters) >= fKeysCutoff;
243 if (fUseSparseHist) {
244 if (fSparseHist == NULL)
249 RooStats::SetParameters(&point,
250 const_cast<RooArgSet*>(&fParameters));
253 Double_t* x =
new Double_t[fDimension];
254 for (Int_t i = 0; i < fDimension; i++)
255 x[i] = fAxes[i]->getVal();
256 bin = fSparseHist->GetBin(x, kFALSE);
257 Double_t weight = fSparseHist->GetBinContent((Long64_t)bin);
259 return (weight >= (Double_t)fHistCutoff);
261 if (fDataHist == NULL)
267 bin = fDataHist->getIndex(point);
269 return (fDataHist->weight() >= (Double_t)fHistCutoff);
272 }
else if (fIntervalType == kTailFraction) {
273 if (fVector.size() == 0)
277 Double_t x = point.getRealValue(fAxes[0]->GetName());
278 if (fTFLower <= x && x <= fTFUpper)
284 coutE(InputArguments) <<
"Error in MCMCInterval::IsInInterval: "
285 <<
"Interval type not set. Returning false." << endl;
291 void MCMCInterval::SetConfidenceLevel(Double_t cl)
293 fConfidenceLevel = cl;
321 void MCMCInterval::SetAxes(RooArgList& axes)
323 Int_t size = axes.getSize();
324 if (size != fDimension) {
325 coutE(InputArguments) <<
"* Error in MCMCInterval::SetAxes: " <<
326 "number of variables in axes (" << size <<
327 ") doesn't match number of parameters ("
328 << fDimension <<
")" << endl;
331 for (Int_t i = 0; i < size; i++)
332 fAxes[i] = (RooRealVar*)axes.at(i);
337 void MCMCInterval::CreateKeysPdf()
342 if (fAxes == NULL || fParameters.getSize() == 0) {
343 coutE(InputArguments) <<
"Error in MCMCInterval::CreateKeysPdf: "
344 <<
"parameters have not been set." << endl;
348 if (fNumBurnInSteps >= fChain->Size()) {
349 coutE(InputArguments) <<
350 "MCMCInterval::CreateKeysPdf: creation of Keys PDF failed: " <<
351 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
352 "in Markov chain." << endl;
364 RooDataSet* chain = fChain->GetAsDataSet(SelectVars(fParameters),
365 EventRange(fNumBurnInSteps, fChain->Size()));
366 RooArgList* paramsList =
new RooArgList();
367 for (Int_t i = 0; i < fDimension; i++)
368 paramsList->add(*fAxes[i]);
372 fKeysPdf =
new RooNDKeysPdf(
"keysPDF",
"Keys PDF", *paramsList, *chain,
"a");
373 fCutoffVar =
new RooRealVar(
"cutoff",
"cutoff", 0);
374 fHeaviside =
new Heaviside(
"heaviside",
"Heaviside", *fKeysPdf, *fCutoffVar);
375 fProduct =
new RooProduct(
"product",
"Keys PDF & Heaviside Product",
376 RooArgSet(*fKeysPdf, *fHeaviside));
381 void MCMCInterval::CreateHist()
383 if (fAxes == NULL || fChain == NULL) {
384 coutE(Eval) <<
"* Error in MCMCInterval::CreateHist(): " <<
385 "Crucial data member was NULL." << endl;
386 coutE(Eval) <<
"Make sure to fully construct/initialize." << endl;
392 if (fNumBurnInSteps >= fChain->Size()) {
393 coutE(InputArguments) <<
394 "MCMCInterval::CreateHist: creation of histogram failed: " <<
395 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
396 "in Markov chain." << endl;
402 fHist =
new TH1F(
"posterior",
"MCMC Posterior Histogram",
403 fAxes[0]->numBins(), fAxes[0]->getMin(), fAxes[0]->getMax());
405 else if (fDimension == 2)
406 fHist =
new TH2F(
"posterior",
"MCMC Posterior Histogram",
407 fAxes[0]->numBins(), fAxes[0]->getMin(), fAxes[0]->getMax(),
408 fAxes[1]->numBins(), fAxes[1]->getMin(), fAxes[1]->getMax());
410 else if (fDimension == 3)
411 fHist =
new TH3F(
"posterior",
"MCMC Posterior Histogram",
412 fAxes[0]->numBins(), fAxes[0]->getMin(), fAxes[0]->getMax(),
413 fAxes[1]->numBins(), fAxes[1]->getMin(), fAxes[1]->getMax(),
414 fAxes[2]->numBins(), fAxes[2]->getMin(), fAxes[2]->getMax());
417 coutE(Eval) <<
"* Error in MCMCInterval::CreateHist() : " <<
418 "TH1* couldn't handle dimension: " << fDimension << endl;
423 Int_t size = fChain->Size();
424 const RooArgSet* entry;
425 for (Int_t i = fNumBurnInSteps; i < size; i++) {
426 entry = fChain->Get(i);
428 ((TH1F*)fHist)->Fill(entry->getRealValue(fAxes[0]->GetName()),
430 else if (fDimension == 2)
431 ((TH2F*)fHist)->Fill(entry->getRealValue(fAxes[0]->GetName()),
432 entry->getRealValue(fAxes[1]->GetName()),
435 ((TH3F*)fHist)->Fill(entry->getRealValue(fAxes[0]->GetName()),
436 entry->getRealValue(fAxes[1]->GetName()),
437 entry->getRealValue(fAxes[2]->GetName()),
442 fHist->GetXaxis()->SetTitle(fAxes[0]->GetName());
444 fHist->GetYaxis()->SetTitle(fAxes[1]->GetName());
446 fHist->GetZaxis()->SetTitle(fAxes[2]->GetName());
451 void MCMCInterval::CreateSparseHist()
453 if (fAxes == NULL || fChain == NULL) {
454 coutE(InputArguments) <<
"* Error in MCMCInterval::CreateSparseHist(): "
455 <<
"Crucial data member was NULL." << endl;
456 coutE(InputArguments) <<
"Make sure to fully construct/initialize."
460 if (fSparseHist != NULL)
463 Double_t* min =
new Double_t[fDimension];
464 Double_t* max =
new Double_t[fDimension];
465 Int_t* bins =
new Int_t[fDimension];
466 for (Int_t i = 0; i < fDimension; i++) {
467 min[i] = fAxes[i]->getMin();
468 max[i] = fAxes[i]->getMax();
469 bins[i] = fAxes[i]->numBins();
471 fSparseHist =
new THnSparseF(
"posterior",
"MCMC Posterior Histogram",
472 fDimension, bins, min, max);
481 fSparseHist->Sumw2();
483 if (fNumBurnInSteps >= fChain->Size()) {
484 coutE(InputArguments) <<
485 "MCMCInterval::CreateSparseHist: creation of histogram failed: " <<
486 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
487 "in Markov chain." << endl;
491 Int_t size = fChain->Size();
492 const RooArgSet* entry;
493 Double_t* x =
new Double_t[fDimension];
494 for (Int_t i = fNumBurnInSteps; i < size; i++) {
495 entry = fChain->Get(i);
496 for (Int_t ii = 0; ii < fDimension; ii++)
497 x[ii] = entry->getRealValue(fAxes[ii]->GetName());
498 fSparseHist->Fill(x, fChain->Weight());
505 void MCMCInterval::CreateDataHist()
507 if (fParameters.getSize() == 0 || fChain == NULL) {
508 coutE(Eval) <<
"* Error in MCMCInterval::CreateDataHist(): " <<
509 "Crucial data member was NULL or empty." << endl;
510 coutE(Eval) <<
"Make sure to fully construct/initialize." << endl;
514 if (fNumBurnInSteps >= fChain->Size()) {
515 coutE(InputArguments) <<
516 "MCMCInterval::CreateDataHist: creation of histogram failed: " <<
517 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
518 "in Markov chain." << endl;
523 fDataHist = fChain->GetAsDataHist(SelectVars(fParameters),
524 EventRange(fNumBurnInSteps, fChain->Size()));
529 void MCMCInterval::CreateVector(RooRealVar* param)
534 if (fChain == NULL) {
535 coutE(InputArguments) <<
"* Error in MCMCInterval::CreateVector(): " <<
536 "Crucial data member (Markov chain) was NULL." << endl;
537 coutE(InputArguments) <<
"Make sure to fully construct/initialize."
542 if (fNumBurnInSteps >= fChain->Size()) {
543 coutE(InputArguments) <<
544 "MCMCInterval::CreateVector: creation of vector failed: " <<
545 "Number of burn-in steps (num steps to ignore) >= number of steps " <<
546 "in Markov chain." << endl;
550 Int_t size = fChain->Size() - fNumBurnInSteps;
551 fVector.resize(size);
554 for (i = 0; i < size; i++) {
555 chainIndex = i + fNumBurnInSteps;
556 fVector[i] = chainIndex;
557 fVecWeight += fChain->Weight(chainIndex);
560 stable_sort(fVector.begin(), fVector.end(),
561 CompareVectorIndices(fChain, param));
566 void MCMCInterval::SetParameters(
const RooArgSet& parameters)
568 fParameters.removeAll();
569 fParameters.add(parameters);
570 fDimension = fParameters.getSize();
573 fAxes =
new RooRealVar*[fDimension];
574 TIterator* it = fParameters.createIterator();
577 while ((obj = it->Next()) != NULL) {
578 if (dynamic_cast<RooRealVar*>(obj) != NULL)
579 fAxes[n] = (RooRealVar*)obj;
581 coutE(Eval) <<
"* Error in MCMCInterval::SetParameters: " <<
582 obj->GetName() <<
" not a RooRealVar*" << std::endl;
590 void MCMCInterval::DetermineInterval()
592 switch (fIntervalType) {
594 DetermineShortestInterval();
597 DetermineTailFractionInterval();
600 coutE(InputArguments) <<
"MCMCInterval::DetermineInterval(): " <<
601 "Error: Interval type not set" << endl;
608 void MCMCInterval::DetermineShortestInterval()
618 void MCMCInterval::DetermineTailFractionInterval()
620 if (fLeftSideTF < 0 || fLeftSideTF > 1) {
621 coutE(InputArguments) <<
"MCMCInterval::DetermineTailFractionInterval: "
622 <<
"Fraction must be in the range [0, 1]. "
623 << fLeftSideTF <<
"is not allowed." << endl;
627 if (fDimension != 1) {
628 coutE(InputArguments) <<
"MCMCInterval::DetermineTailFractionInterval(): "
629 <<
"Error: Can only find a tail-fraction interval for 1-D intervals"
635 coutE(InputArguments) <<
"MCMCInterval::DetermineTailFractionInterval(): "
636 <<
"Crucial data member was NULL." << endl;
637 coutE(InputArguments) <<
"Make sure to fully construct/initialize."
647 if (fVector.size() == 0)
648 CreateVector(fAxes[0]);
650 if (fVector.size() == 0 || fVecWeight == 0) {
657 fTFLower = -1.0 * RooNumber::infinity();
658 fTFUpper = RooNumber::infinity();
664 RooRealVar* param = fAxes[0];
666 Double_t c = fConfidenceLevel;
667 Double_t leftTailCutoff = fVecWeight * (1 - c) * fLeftSideTF;
668 Double_t rightTailCutoff = fVecWeight * (1 - c) * (1 - fLeftSideTF);
669 Double_t leftTailSum = 0;
670 Double_t rightTailSum = 0;
673 Double_t ll = param->getMin();
674 Double_t ul = param->getMax();
680 const char* name = param->GetName();
684 for (i = 0; i < (Int_t)fVector.size(); i++) {
685 x = fChain->Get(fVector[i])->getRealValue(name);
686 w = fChain->Weight();
688 if (TMath::Abs(leftTailSum + w - leftTailCutoff) <
689 TMath::Abs(leftTailSum - leftTailCutoff)) {
699 for (i = (Int_t)fVector.size() - 1; i >= 0; i--) {
700 x = fChain->Get(fVector[i])->getRealValue(name);
701 w = fChain->Weight();
703 if (TMath::Abs(rightTailSum + w - rightTailCutoff) <
704 TMath::Abs(rightTailSum - rightTailCutoff)) {
715 fTFConfLevel = 1 - (leftTailSum + rightTailSum) / fVecWeight;
720 void MCMCInterval::DetermineByKeys()
722 if (fKeysPdf == NULL)
725 if (fKeysPdf == NULL) {
731 fKeysConfLevel = 0.0;
737 Double_t cutoff = 0.0;
738 fCutoffVar->setVal(cutoff);
739 RooAbsReal* integral = fProduct->createIntegral(fParameters, NormSet(fParameters));
740 Double_t full = integral->getVal(fParameters);
744 coutW(Eval) <<
"Warning: Integral of Keys PDF came out to " << full
745 <<
" instead of expected value 1. Will continue using this "
746 <<
"factor to normalize further integrals of this PDF." << endl;
754 Double_t volume = 1.0;
755 TIterator* it = fParameters.createIterator();
757 while ((var = (RooRealVar*)it->Next()) != NULL)
758 volume *= (var->getMax() - var->getMin());
761 Double_t topCutoff = full / volume;
762 Double_t bottomCutoff = topCutoff;
763 Double_t confLevel = CalcConfLevel(topCutoff, full);
764 if (AcceptableConfLevel(confLevel)) {
765 fKeysConfLevel = confLevel;
766 fKeysCutoff = topCutoff;
769 Bool_t changed = kFALSE;
771 while (confLevel > fConfidenceLevel) {
773 confLevel = CalcConfLevel(topCutoff, full);
774 if (AcceptableConfLevel(confLevel)) {
775 fKeysConfLevel = confLevel;
776 fKeysCutoff = topCutoff;
782 bottomCutoff = topCutoff / 2.0;
786 confLevel = CalcConfLevel(bottomCutoff, full);
787 if (AcceptableConfLevel(confLevel)) {
788 fKeysConfLevel = confLevel;
789 fKeysCutoff = bottomCutoff;
792 while (confLevel < fConfidenceLevel) {
794 confLevel = CalcConfLevel(bottomCutoff, full);
795 if (AcceptableConfLevel(confLevel)) {
796 fKeysConfLevel = confLevel;
797 fKeysCutoff = bottomCutoff;
803 topCutoff = bottomCutoff * 2.0;
807 coutI(Eval) <<
"range set: [" << bottomCutoff <<
", " << topCutoff <<
"]"
810 cutoff = (topCutoff + bottomCutoff) / 2.0;
811 confLevel = CalcConfLevel(cutoff, full);
819 while (!AcceptableConfLevel(confLevel) &&
820 !WithinDeltaFraction(topCutoff, bottomCutoff)) {
821 if (confLevel > fConfidenceLevel)
822 bottomCutoff = cutoff;
823 else if (confLevel < fConfidenceLevel)
825 cutoff = (topCutoff + bottomCutoff) / 2.0;
826 coutI(Eval) <<
"cutoff range: [" << bottomCutoff <<
", "
827 << topCutoff <<
"]" << endl;
828 confLevel = CalcConfLevel(cutoff, full);
831 fKeysCutoff = cutoff;
832 fKeysConfLevel = confLevel;
837 void MCMCInterval::DetermineByHist()
840 DetermineBySparseHist();
842 DetermineByDataHist();
847 void MCMCInterval::DetermineBySparseHist()
850 if (fSparseHist == NULL)
853 if (fSparseHist == NULL) {
856 fHistConfLevel = 0.0;
860 numBins = (Long_t)fSparseHist->GetNbins();
862 std::vector<Long_t> bins(numBins);
863 for (Int_t ibin = 0; ibin < numBins; ibin++)
864 bins[ibin] = (Long_t)ibin;
865 std::stable_sort(bins.begin(), bins.end(), CompareSparseHistBins(fSparseHist));
867 Double_t nEntries = fSparseHist->GetSumw();
872 for (i = numBins - 1; i >= 0; i--) {
873 content = fSparseHist->GetBinContent(bins[i]);
874 if ((sum + content) / nEntries >= fConfidenceLevel) {
875 fHistCutoff = content;
890 for ( ; i >= 0; i--) {
891 content = fSparseHist->GetBinContent(bins[i]);
892 if (content == fHistCutoff)
899 for ( ; i < numBins; i++) {
900 content = fSparseHist->GetBinContent(bins[i]);
901 if (content > fHistCutoff) {
902 fHistCutoff = content;
906 if (i == numBins - 1)
909 fHistCutoff = content + 1.0;
913 fHistConfLevel = sum / nEntries;
918 void MCMCInterval::DetermineByDataHist()
921 if (fDataHist == NULL)
923 if (fDataHist == NULL) {
926 fHistConfLevel = 0.0;
930 numBins = fDataHist->numEntries();
932 std::vector<Int_t> bins(numBins);
933 for (Int_t ibin = 0; ibin < numBins; ibin++)
935 std::stable_sort(bins.begin(), bins.end(), CompareDataHistBins(fDataHist));
937 Double_t nEntries = fDataHist->sum(kFALSE);
941 for (i = numBins - 1; i >= 0; i--) {
942 fDataHist->get(bins[i]);
943 content = fDataHist->weight();
944 if ((sum + content) / nEntries >= fConfidenceLevel) {
945 fHistCutoff = content;
960 for ( ; i >= 0; i--) {
961 fDataHist->get(bins[i]);
962 content = fDataHist->weight();
963 if (content == fHistCutoff)
970 for ( ; i < numBins; i++) {
971 fDataHist->get(bins[i]);
972 content = fDataHist->weight();
973 if (content > fHistCutoff) {
974 fHistCutoff = content;
978 if (i == numBins - 1)
981 fHistCutoff = content + 1.0;
985 fHistConfLevel = sum / nEntries;
990 Double_t MCMCInterval::GetActualConfidenceLevel()
992 if (fIntervalType == kShortest) {
994 return fKeysConfLevel;
996 return fHistConfLevel;
997 }
else if (fIntervalType == kTailFraction) {
1000 coutE(InputArguments) <<
"MCMCInterval::GetActualConfidenceLevel: "
1001 <<
"not implemented for this type of interval. Returning 0." << endl;
1008 Double_t MCMCInterval::LowerLimit(RooRealVar& param)
1010 switch (fIntervalType) {
1012 return LowerLimitShortest(param);
1014 return LowerLimitTailFraction(param);
1016 coutE(InputArguments) <<
"MCMCInterval::LowerLimit(): " <<
1017 "Error: Interval type not set" << endl;
1018 return RooNumber::infinity();
1024 Double_t MCMCInterval::UpperLimit(RooRealVar& param)
1026 switch (fIntervalType) {
1028 return UpperLimitShortest(param);
1030 return UpperLimitTailFraction(param);
1032 coutE(InputArguments) <<
"MCMCInterval::UpperLimit(): " <<
1033 "Error: Interval type not set" << endl;
1034 return RooNumber::infinity();
1040 Double_t MCMCInterval::LowerLimitTailFraction(RooRealVar& )
1042 if (fTFLower == -1.0 * RooNumber::infinity())
1043 DetermineTailFractionInterval();
1050 Double_t MCMCInterval::UpperLimitTailFraction(RooRealVar& )
1052 if (fTFUpper == RooNumber::infinity())
1053 DetermineTailFractionInterval();
1060 Double_t MCMCInterval::LowerLimitShortest(RooRealVar& param)
1063 return LowerLimitByKeys(param);
1065 return LowerLimitByHist(param);
1070 Double_t MCMCInterval::UpperLimitShortest(RooRealVar& param)
1073 return UpperLimitByKeys(param);
1075 return UpperLimitByHist(param);
1082 Double_t MCMCInterval::LowerLimitByHist(RooRealVar& param)
1085 return LowerLimitBySparseHist(param);
1087 return LowerLimitByDataHist(param);
1094 Double_t MCMCInterval::UpperLimitByHist(RooRealVar& param)
1097 return UpperLimitBySparseHist(param);
1099 return UpperLimitByDataHist(param);
1106 Double_t MCMCInterval::LowerLimitBySparseHist(RooRealVar& param)
1108 if (fDimension != 1) {
1109 coutE(InputArguments) <<
"In MCMCInterval::LowerLimitBySparseHist: "
1110 <<
"Sorry, will not compute lower limit unless dimension == 1" << endl;
1111 return param.getMin();
1113 if (fHistCutoff < 0)
1114 DetermineBySparseHist();
1116 if (fHistCutoff < 0) {
1118 coutE(Eval) <<
"In MCMCInterval::LowerLimitBySparseHist: "
1119 <<
"couldn't determine cutoff. Check that num burn in steps < num "
1120 <<
"steps in the Markov chain. Returning param.getMin()." << endl;
1121 return param.getMin();
1124 std::vector<Int_t> coord(fDimension);
1125 for (Int_t d = 0; d < fDimension; d++) {
1126 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1127 Long_t numBins = (Long_t)fSparseHist->GetNbins();
1128 Double_t lowerLimit = param.getMax();
1130 for (Long_t i = 0; i < numBins; i++) {
1131 if (fSparseHist->GetBinContent(i, &coord[0]) >= fHistCutoff) {
1132 val = fSparseHist->GetAxis(d)->GetBinCenter(coord[d]);
1133 if (val < lowerLimit)
1140 return param.getMin();
1147 Double_t MCMCInterval::LowerLimitByDataHist(RooRealVar& param)
1149 if (fHistCutoff < 0)
1150 DetermineByDataHist();
1152 if (fHistCutoff < 0) {
1154 coutE(Eval) <<
"In MCMCInterval::LowerLimitByDataHist: "
1155 <<
"couldn't determine cutoff. Check that num burn in steps < num "
1156 <<
"steps in the Markov chain. Returning param.getMin()." << endl;
1157 return param.getMin();
1160 for (Int_t d = 0; d < fDimension; d++) {
1161 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1162 Int_t numBins = fDataHist->numEntries();
1163 Double_t lowerLimit = param.getMax();
1165 for (Int_t i = 0; i < numBins; i++) {
1167 if (fDataHist->weight() >= fHistCutoff) {
1168 val = fDataHist->get()->getRealValue(param.GetName());
1169 if (val < lowerLimit)
1176 return param.getMin();
1183 Double_t MCMCInterval::UpperLimitBySparseHist(RooRealVar& param)
1185 if (fDimension != 1) {
1186 coutE(InputArguments) <<
"In MCMCInterval::UpperLimitBySparseHist: "
1187 <<
"Sorry, will not compute upper limit unless dimension == 1" << endl;
1188 return param.getMax();
1190 if (fHistCutoff < 0)
1191 DetermineBySparseHist();
1193 if (fHistCutoff < 0) {
1195 coutE(Eval) <<
"In MCMCInterval::UpperLimitBySparseHist: "
1196 <<
"couldn't determine cutoff. Check that num burn in steps < num "
1197 <<
"steps in the Markov chain. Returning param.getMax()." << endl;
1198 return param.getMax();
1201 std::vector<Int_t> coord(fDimension);
1202 for (Int_t d = 0; d < fDimension; d++) {
1203 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1204 Long_t numBins = (Long_t)fSparseHist->GetNbins();
1205 Double_t upperLimit = param.getMin();
1207 for (Long_t i = 0; i < numBins; i++) {
1208 if (fSparseHist->GetBinContent(i, &coord[0]) >= fHistCutoff) {
1209 val = fSparseHist->GetAxis(d)->GetBinCenter(coord[d]);
1210 if (val > upperLimit)
1217 return param.getMax();
1224 Double_t MCMCInterval::UpperLimitByDataHist(RooRealVar& param)
1226 if (fHistCutoff < 0)
1227 DetermineByDataHist();
1229 if (fHistCutoff < 0) {
1231 coutE(Eval) <<
"In MCMCInterval::UpperLimitByDataHist: "
1232 <<
"couldn't determine cutoff. Check that num burn in steps < num "
1233 <<
"steps in the Markov chain. Returning param.getMax()." << endl;
1234 return param.getMax();
1237 for (Int_t d = 0; d < fDimension; d++) {
1238 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1239 Int_t numBins = fDataHist->numEntries();
1240 Double_t upperLimit = param.getMin();
1242 for (Int_t i = 0; i < numBins; i++) {
1244 if (fDataHist->weight() >= fHistCutoff) {
1245 val = fDataHist->get()->getRealValue(param.GetName());
1246 if (val > upperLimit)
1253 return param.getMax();
1260 Double_t MCMCInterval::LowerLimitByKeys(RooRealVar& param)
1262 if (fKeysCutoff < 0)
1265 if (fKeysDataHist == NULL)
1266 CreateKeysDataHist();
1268 if (fKeysCutoff < 0 || fKeysDataHist == NULL) {
1270 coutE(Eval) <<
"in MCMCInterval::LowerLimitByKeys(): "
1271 <<
"couldn't find lower limit, check that the number of burn in "
1272 <<
"steps < number of total steps in the Markov chain. Returning "
1273 <<
"param.getMin()" << endl;
1274 return param.getMin();
1277 for (Int_t d = 0; d < fDimension; d++) {
1278 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1279 Int_t numBins = fKeysDataHist->numEntries();
1280 Double_t lowerLimit = param.getMax();
1282 for (Int_t i = 0; i < numBins; i++) {
1283 fKeysDataHist->get(i);
1284 if (fKeysDataHist->weight() >= fKeysCutoff) {
1285 val = fKeysDataHist->get()->getRealValue(param.GetName());
1286 if (val < lowerLimit)
1293 return param.getMin();
1300 Double_t MCMCInterval::UpperLimitByKeys(RooRealVar& param)
1302 if (fKeysCutoff < 0)
1305 if (fKeysDataHist == NULL)
1306 CreateKeysDataHist();
1308 if (fKeysCutoff < 0 || fKeysDataHist == NULL) {
1310 coutE(Eval) <<
"in MCMCInterval::UpperLimitByKeys(): "
1311 <<
"couldn't find upper limit, check that the number of burn in "
1312 <<
"steps < number of total steps in the Markov chain. Returning "
1313 <<
"param.getMax()" << endl;
1314 return param.getMax();
1317 for (Int_t d = 0; d < fDimension; d++) {
1318 if (strcmp(fAxes[d]->GetName(), param.GetName()) == 0) {
1319 Int_t numBins = fKeysDataHist->numEntries();
1320 Double_t upperLimit = param.getMin();
1322 for (Int_t i = 0; i < numBins; i++) {
1323 fKeysDataHist->get(i);
1324 if (fKeysDataHist->weight() >= fKeysCutoff) {
1325 val = fKeysDataHist->get()->getRealValue(param.GetName());
1326 if (val > upperLimit)
1333 return param.getMax();
1339 Double_t MCMCInterval::GetKeysMax()
1341 if (fKeysCutoff < 0)
1344 if (fKeysDataHist == NULL)
1345 CreateKeysDataHist();
1347 if (fKeysDataHist == NULL) {
1349 coutE(Eval) <<
"in MCMCInterval::KeysMax(): "
1350 <<
"couldn't find Keys max value, check that the number of burn in "
1351 <<
"steps < number of total steps in the Markov chain. Returning 0"
1356 Int_t numBins = fKeysDataHist->numEntries();
1359 for (Int_t i = 0; i < numBins; i++) {
1360 fKeysDataHist->get(i);
1361 w = fKeysDataHist->weight();
1371 Double_t MCMCInterval::GetHistCutoff()
1373 if (fHistCutoff < 0)
1381 Double_t MCMCInterval::GetKeysPdfCutoff()
1383 if (fKeysCutoff < 0)
1390 return fKeysCutoff / fFull;
1395 Double_t MCMCInterval::CalcConfLevel(Double_t cutoff, Double_t full)
1397 RooAbsReal* integral;
1399 fCutoffVar->setVal(cutoff);
1400 integral = fProduct->createIntegral(fParameters, NormSet(fParameters));
1401 confLevel = integral->getVal(fParameters) / full;
1402 coutI(Eval) <<
"cutoff = " << cutoff <<
", conf = " << confLevel << endl;
1410 TH1* MCMCInterval::GetPosteriorHist()
1412 if(fConfidenceLevel == 0)
1413 coutE(InputArguments) <<
"Error in MCMCInterval::GetPosteriorHist: "
1414 <<
"confidence level not set " << endl;
1422 return (TH1*) fHist->Clone(
"MCMCposterior_hist");
1427 RooNDKeysPdf* MCMCInterval::GetPosteriorKeysPdf()
1429 if (fConfidenceLevel == 0)
1430 coutE(InputArguments) <<
"Error in MCMCInterval::GetPosteriorKeysPdf: "
1431 <<
"confidence level not set " << endl;
1432 if (fKeysPdf == NULL)
1435 if (fKeysPdf == NULL)
1439 return (RooNDKeysPdf*) fKeysPdf->Clone(
"MCMCPosterior_keys");
1444 RooProduct* MCMCInterval::GetPosteriorKeysProduct()
1446 if (fConfidenceLevel == 0)
1447 coutE(InputArguments) <<
"MCMCInterval::GetPosteriorKeysProduct: "
1448 <<
"confidence level not set " << endl;
1449 if (fProduct == NULL) {
1454 if (fProduct == NULL)
1458 return (RooProduct*) fProduct->Clone(
"MCMCPosterior_keysproduct");
1463 RooArgSet* MCMCInterval::GetParameters()
const
1466 return new RooArgSet(fParameters);
1471 Bool_t MCMCInterval::AcceptableConfLevel(Double_t confLevel)
1473 return (TMath::Abs(confLevel - fConfidenceLevel) < fEpsilon);
1478 Bool_t MCMCInterval::WithinDeltaFraction(Double_t a, Double_t b)
1480 return (TMath::Abs(a - b) < TMath::Abs(fDelta * (a + b)/2));
1485 void MCMCInterval::CreateKeysDataHist()
1489 if (fProduct == NULL)
1491 if (fProduct == NULL)
1496 Int_t* savedBins =
new Int_t[fDimension];
1513 Bool_t tempChangeBinning =
true;
1514 for (i = 0; i < fDimension; i++) {
1515 if (!fAxes[i]->getBinning(NULL,
false,
false).isUniform()) {
1516 tempChangeBinning =
false;
1524 if (fDimension >= 2)
1525 tempChangeBinning =
false;
1527 if (tempChangeBinning) {
1529 for (i = 0; i < fDimension; i++) {
1532 savedBins[i] = var->getBinning(NULL,
false,
false).numBins();
1533 numBins = (var->getMax() - var->getMin()) / fEpsilon;
1534 var->setBins((Int_t)numBins);
1538 fKeysDataHist =
new RooDataHist(
"_productDataHist",
1539 "Keys PDF & Heaviside Product Data Hist", fParameters);
1540 fKeysDataHist = fProduct->fillDataHist(fKeysDataHist, &fParameters, 1.);
1542 if (tempChangeBinning) {
1544 for (i = 0; i < fDimension; i++)
1547 fAxes[i]->setBins(savedBins[i], NULL);
1556 Bool_t MCMCInterval::CheckParameters(
const RooArgSet& parameterPoint)
const
1560 if (parameterPoint.getSize() != fParameters.getSize() ) {
1561 coutE(Eval) <<
"MCMCInterval: size is wrong, parameters don't match" << std::endl;
1564 if ( ! parameterPoint.equals( fParameters ) ) {
1565 coutE(Eval) <<
"MCMCInterval: size is ok, but parameters don't match" << std::endl;