15#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
16#define protected public
63 return RooCmdArg(
"ReuseNLL", flag, 0, 0, 0, 0, 0, 0, 0);
66xRooNLLVar xRooFit::createNLL(
const std::shared_ptr<RooAbsPdf> pdf,
const std::shared_ptr<RooAbsData>
data,
74 return createNLL(std::shared_ptr<RooAbsPdf>(&pdf, [](
RooAbsPdf *) {}),
92 return createNLL(pdf,
data,
l);
95std::shared_ptr<const RooFitResult>
97 const std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>> &
data,
105std::shared_ptr<const RooFitResult> xRooFit::fitTo(
RooAbsPdf &pdf,
106 const std::pair<RooAbsData *, const RooAbsCollection *> &
data,
114std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>>
115xRooFit::generateFrom(
RooAbsPdf &pdf,
const std::shared_ptr<const RooFitResult> &fr,
bool expected,
int seed)
118 std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>> out;
123 auto _allVars = std::unique_ptr<RooAbsCollection>(pdf.
getVariables());
124 auto _snap = std::unique_ptr<RooAbsCollection>(_allVars->snapshot());
125 *_allVars = fr->constPars();
126 *_allVars = fr->floatParsFinal();
129 auto _globs = std::unique_ptr<RooAbsCollection>(fr->constPars().selectByAttrib(
"global",
true));
140 std::function<std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooArgSet>>(
RooAbsPdf *)> genSubPdf;
143 std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooArgSet>> _out;
146 std::unique_ptr<RooArgSet> _obs(_pdf->getVariables());
147 _obs->remove(fr->constPars(),
true,
true);
148 _obs->remove(fr->floatParsFinal(),
true,
true);
150 if (!_globs->empty()) {
155 std::unique_ptr<RooArgSet> globs(_pdf->getObservables(t));
156 globs->snapshot(*toy_gobs);
157 if (!toy_gobs->
empty() &&
161 *toy_gobs = *std::unique_ptr<RooDataSet>(_pdf->generate(*globs, 1))->
get();
166 for (
auto thePdf : pp->pdfList()) {
167 auto gob = std::unique_ptr<RooArgSet>(thePdf->getObservables(*globs));
170 if (gob->size() > 1) {
171 Warning(
"generate",
"%s contains multiple global obs: %s", thePdf->GetName(),
172 gob->contentsString().c_str());
176 std::unique_ptr<RooArgSet> cpars(thePdf->getParameters(*globs));
178 bool foundServer =
false;
187 <<
"AsymptoticCalculator::MakeAsimovData:constraint term " << thePdf->GetName()
188 <<
" of type " << className <<
" is a non-supported type - result might be not correct "
207 <<
"AsymptoticCalculator::MakeAsimovData:constraint term " << thePdf->
GetName()
208 <<
" has no direct dependence on global observable- cannot generate it " << std::endl;
220 RooFIter itc(thePdf->serverMIterator());
227 if (thetaGamma == 0) {
229 <<
"AsymptoticCalculator::MakeAsimovData:constraint term " << thePdf->
GetName()
230 <<
" is a Gamma distribution and no server named theta is found. Assume that the Gamma "
235 RooFIter iter2(thePdf->serverMIterator());
244 <<
"AsymptoticCalculator::MakeAsimovData:constraint term " << thePdf->
GetName()
245 <<
" constraint term has more server depending on nuisance- cannot generate it "
250 if (thetaGamma && thetaGamma->
getVal() > 0)
260 <<
"AsymptoticCalculator::MakeAsimovData - can't find nuisance for constraint term - global "
261 "observables will not be set to Asimov value "
262 << thePdf->GetName() << std::endl;
263 std::cerr <<
"Parameters: " << std::endl;
265 std::cerr <<
"Observables: " << std::endl;
270 Error(
"generate",
"Cannot generate global observables, pdf is: %s::%s", _pdf->ClassName(),
276 _out.second.reset(toy_gobs);
284 uuid,
TString::Format(
"%s %s", _pdf->GetTitle(), (expected) ?
"Expected" :
"Toy"), *_obs,
"weightVar"));
286 for (
auto &
c : s->indexCat()) {
287#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 22, 00)
288 std::string cLabel =
c.first.c_str();
290 std::string cLabel =
c->GetName();
292 auto p = s->getPdf(cLabel.c_str());
295 auto toy = genSubPdf(
p);
296 if (toy.second && _out.second)
297 *
const_cast<RooArgSet *
>(_out.second.get()) = *toy.second;
298 _obs->setCatLabel(s->indexCat().GetName(), cLabel.c_str());
299 for (
int i = 0; i < toy.first->numEntries(); i++) {
300 *_obs = *toy.first->get(i);
301 _out.first->add(*_obs, toy.first->weight());
307 std::map<RooRealVar *, std::shared_ptr<RooAbsBinning>> binnings;
309 for (
auto &o : *_obs) {
313 if (_pdf->isBinnedDistribution(*
r)) {
314 binnings[
r] = std::shared_ptr<RooAbsBinning>(
r->getBinning().clone(
r->getBinning().GetName()));
315 auto res = _pdf->binBoundaries(*
r, -std::numeric_limits<double>::infinity(),
316 std::numeric_limits<double>::infinity());
317 std::vector<double> boundaries;
318 boundaries.reserve(res->size());
319 for (
auto &rr : *res) {
320 if (boundaries.empty() || std::abs(boundaries.back() - rr) > 1
e-3 ||
321 std::abs(boundaries.back() - rr) > 1
e-5 * boundaries.back())
322 boundaries.push_back(rr);
324 r->setBinning(
RooBinning(boundaries.size() - 1, &boundaries[0]));
326 }
else if (
r->numBins(
r->getBinning().GetName()) == 0 && expected) {
328 binnings[
r] = std::shared_ptr<RooAbsBinning>(
r->getBinning().clone(
r->getBinning().GetName()));
339 _out.first.reset(
new RooDataSet(
"",
"Toy", _tmp,
"weightVar"));
340 _out.first->add(_tmp);
342 if (_pdf->canBeExtended()) {
351 _out.first = std::unique_ptr<RooDataSet>{_pdf->generate(*_obs,
RooFit::ExpectedData(expected))};
355 _out.first->SetName(
TUUID().AsString());
357 for (
auto &
b : binnings) {
359 auto binning =
b.second;
360 v->setBinning(*binning);
363 auto x =
dynamic_cast<RooRealVar *
>(_out.first->get()->find(
v->GetName()));
364 auto r =
x->getRange();
365 if (
r.first > binning->lowBound())
366 x->setMin(binning->lowBound());
367 if (
r.second < binning->highBound())
368 x->setMax(binning->highBound());
373 out = genSubPdf(&pdf);
374 out.first->SetName(uuid);
376#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
379 w->setStringAttribute(
"fitResult", fr->GetName());
388std::shared_ptr<RooLinkedList> xRooFit::createNLLOptions()
401std::shared_ptr<ROOT::Fit::FitConfig> xRooFit::createFitConfig()
403 auto fFitConfig = std::make_shared<ROOT::Fit::FitConfig>();
404 auto &fitConfig = *fFitConfig;
405 fitConfig.SetParabErrors(
true);
406 fitConfig.MinimizerOptions().SetMinimizerType(
"Minuit2");
407 fitConfig.MinimizerOptions().SetErrorDef(0.5);
408 fitConfig.SetParabErrors(
true);
409 fitConfig.SetMinosErrors(
true);
410 fitConfig.MinimizerOptions().SetMaxFunctionCalls(
412 fitConfig.MinimizerOptions().SetMaxIterations(-1);
413 fitConfig.MinimizerOptions().SetStrategy(0);
417 fitConfig.MinimizerOptions().SetPrintLevel(-2);
420 auto extraOpts =
const_cast<ROOT::Math::IOptions *
>(fitConfig.MinimizerOptions().ExtraOptions());
421 extraOpts->
SetValue(
"OptimizeConst", 2);
423 extraOpts->SetValue(
"StrategySequence",
"0s01s12s2m");
424 extraOpts->SetValue(
"LogSize", 0);
425 extraOpts->SetValue(
"BoundaryCheck",
427 extraOpts->SetValue(
"TrackProgress", 30);
440 if (signum == SIGINT) {
441 std::cout <<
"Minimization interrupted ... will exit as soon as possible" << std::endl;
473 return std::numeric_limits<double>::quiet_NaN();
475 if (
prevMin == std::numeric_limits<double>::infinity())
477 if (!std::isnan(out))
494 mutable double minVal = std::numeric_limits<double>::infinity();
495 mutable double prevMin = std::numeric_limits<double>::infinity();
502std::shared_ptr<const RooFitResult>
503xRooFit::minimize(
RooAbsReal &nll,
const std::shared_ptr<ROOT::Fit::FitConfig> &_fitConfig)
506 auto myFitConfig = _fitConfig ? _fitConfig : createFitConfig();
507 auto &fitConfig = *myFitConfig;
513 if (resultTitle ==
"")
530 auto _nllVars = std::unique_ptr<RooAbsCollection>(_nll->getVariables());
532 std::unique_ptr<RooAbsCollection> constPars(_nllVars->selectByAttrib(
"Constant",
kTRUE));
533 constPars->add(fUserPars,
true);
534 std::unique_ptr<RooAbsCollection> floatPars(_nllVars->selectByAttrib(
"Constant",
kFALSE));
537 double boundaryCheck = 0;
540 if (fitConfig.MinimizerOptions().ExtraOptions()) {
541 fitConfig.MinimizerOptions().ExtraOptions()->GetNamedValue(
"StrategySequence", s);
542 fitConfig.MinimizerOptions().ExtraOptions()->GetIntValue(
"TrackProgress", _progress);
543 fitConfig.MinimizerOptions().ExtraOptions()->GetRealValue(
"BoundaryCheck", boundaryCheck);
544 fitConfig.MinimizerOptions().ExtraOptions()->GetIntValue(
"LogSize", logSize);
554 if (
auto keys = nllDir->GetListOfKeys(); keys) {
555 for (
auto &&k : *keys) {
557 if (cl->InheritsFrom(
"RooFitResult")) {
560 if (!cachedFit->floatParsFinal().equals(*floatPars)) {
563 for (
auto &
p : *constPars) {
569 if (
auto _p =
dynamic_cast<RooAbsReal *
>(cachedFit->constPars().find(
p->
GetName())); _p) {
572 if (!_p->getAttribute(
"global") && std::abs(_p->getVal() -
v->getVal()) > 1
e-12) {
580 return std::shared_ptr<RooFitResult>(cachedFit);
594 int printLevel = fitConfig.MinimizerOptions().PrintLevel();
600 if (floatPars->getSize() == 0 || fitConfig.MinimizerOptions().MaxFunctionCalls() == 1) {
601 std::shared_ptr<RooFitResult>
result;
603 parsList.
add(*floatPars);
605 result = std::make_shared<RooFitResult>();
607 result->SetTitle(resultTitle);
608 result->setFinalParList(parsList);
609 result->setInitParList(parsList);
613 result->setCovarianceMatrix(
d);
615 result->setMinNLL(_nll->getVal());
617 result->setStatus(floatPars->getSize() == 0 ? 0 : 1);
633 int strategy = fitConfig.MinimizerOptions().Strategy();
642 std::unique_ptr<RooFitResult> out;
644 auto logger = (logSize > 0) ? std::make_unique<cout_redirect>(logs, logSize) :
nullptr;
664 std::vector<std::pair<std::string, int>> statusHistory;
673 int constOptimize = 2;
696 if (minim ==
"Minuit2")
697 sIdx = m_strategy.
Index(
'0' + strategy);
698 else if (minim ==
"Minuit")
699 sIdx = m_strategy.
Index(
'm');
704 while (tries < maxtries && sIdx != -1) {
705 status = _minimizer.
minimize(minim, algo);
713 throw std::runtime_error(
"Keyboard interrupt while minimizing");
717 status = _minimizer.
fitter()
721 statusHistory.emplace_back(
725 if (status % 1000 == 0)
728 if (status == 4 && minim !=
"Minuit") {
729 if (printLevel >= -1)
730 Warning(
"fitTo",
"%s Hit max function calls of %d", fitName.
Data(),
733 if (printLevel >= -1)
734 Warning(
"fitTo",
"will try doubling this");
746 if (printLevel >= -1)
747 Warning(
"fitTo",
"%s Status=%d (edm=%f, tol=%f, strat=%d), tries=#%d...", fitName.
Data(), status,
752 if (sIdx == m_strategy.
Length() - 1) {
756 if (m_strategy(sIdx + 1) ==
'm') {
758 algo =
"migradImproved";
759 }
else if (m_strategy(sIdx + 1) ==
's') {
762 strategy =
int(m_strategy(sIdx + 1) -
'0');
782 if (printLevel >= -1 && status != 0) {
783 Warning(
"fitTo",
"%s final status is %d", fitName.
Data(), status);
805 throw std::runtime_error(
"Keyboard interrupt while hesse calculating");
807 if (
_status != 0 && status == 0 && printLevel >= -1) {
817 out = std::unique_ptr<RooFitResult>{_minimizer.
save(fitName, resultTitle)};
819 out->setStatusHistory(statusHistory);
822 const_cast<RooArgList &
>(out->constPars()).addClone(fUserPars,
true);
827 RooFIter itr = floatPars->fwdIterator();
829 int limit_status = 0;
830 std::string listpars;
831 while ((
a = itr.
next())) {
835 double vRange =
v->
getMax() -
v->getMin();
836 if (
v->getMin() >
v->getVal() - vRange * boundaryCheck ||
837 v->getMax() <
v->getVal() + vRange * boundaryCheck) {
841 auto tmp =
v->getVal();
842 v->setVal(
v->getMin());
843 double boundary_nll = _nll->getVal();
844 if (boundary_nll <= out->minNll()) {
845 static_cast<RooRealVar *
>(out->floatParsFinal().find(
v->GetName()))->
setVal(
v->getMin());
846 out->setMinNLL(boundary_nll);
854 if (
v->hasRange(
"physical"))
856 listpars +=
v->GetName();
859 (
v->getMin() >
v->getVal() -
v->getError() ||
v->getMax() <
v->getVal() +
v->getError())) {
860 if (printLevel >= 0) {
861 Info(
"minimize",
"PARLIM: %s (%f +/- %f) range (%f - %f)",
v->GetName(),
v->getVal(),
v->getError(),
862 v->getMin(),
v->getMax());
867 if (limit_status == 900) {
869 Warning(
"miminize",
"BOUNDCHK: Parameters within %g%% limit in fit result: %s", boundaryCheck * 100,
871 }
else if (limit_status > 0) {
873 Warning(
"miminize",
"BOUNDCHK: Parameters near limit in fit result");
877 statusHistory.emplace_back(
"BOUNDCHK", limit_status);
878 out->setStatusHistory(statusHistory);
879 out->setStatus(out->status() + limit_status);
905 out->setMinNLL(_nll->getVal());
908 for (
auto o : out->floatParsFinal()) {
910 v->removeAsymError();
914 if (fitConfig.MinimizerOptions().MinimizerType() != actualFirstMinimizer) {
915 fitConfig.MinimizerOptions().SetMinimizerType(actualFirstMinimizer);
923 if (status == 0 &&
minos) {
924 std::unique_ptr<RooAbsCollection> pars(floatPars->selectByAttrib(
"minos",
true));
925 for (
auto p : *pars) {
926 xRooFit::minos(nll, *out,
p->
GetName(), myFitConfig);
929 *floatPars = out->floatParsFinal();
933 *floatPars = out->floatParsInit();
936 if (out && !logs.empty()) {
938 const_cast<RooArgList &
>(out->constPars()).addOwned(std::make_unique<RooStringVar>(
".log",
"log", logs.c_str()));
941 if (out && cacheDir && cacheDir->
IsWritable()) {
948 std::string configName;
949 if (!fitConfig.MinimizerOptions().ExtraOptions()->GetValue(
"Name", configName)) {
950 auto extraOpts =
const_cast<ROOT::Math::IOptions *
>(fitConfig.MinimizerOptions().ExtraOptions());
952 extraOpts->SetValue(
"Name", configName.data());
954 if (!dir->GetKey(configName.data())) {
955 dir->WriteObject(&fitConfig, configName.data());
959 .addOwned(std::make_unique<RooStringVar>(
".fitConfigName",
"fitConfigName", configName.c_str()));
961 dir->WriteObject(out.get(), out->GetName());
965 return std::shared_ptr<const RooFitResult>(std::move(out));
971 const std::shared_ptr<ROOT::Fit::FitConfig> &_fitConfig)
982 auto myFitConfig = _fitConfig ? _fitConfig : createFitConfig();
983 auto &fitConfig = *myFitConfig;
985 bool pErrs = fitConfig.ParabErrors();
986 fitConfig.SetParabErrors(
false);
987 double mErrs = fitConfig.MinosErrors();
988 fitConfig.SetMinosErrors(
false);
990 double val_best = par_hat->getVal();
991 double val_err = (par_hat->hasError() ? par_hat->getError() : -1);
992 double nll_min = ufit.
minNll();
996 bool isConst = par->isConstant();
997 par->setConstant(
true);
999 auto findValue = [&](
double val_guess,
double N_sigma = 1,
double precision = 0.002,
int printLevel = 0) {
1002 double sigma_guess = std::abs((val_guess - val_best) / N_sigma);
1005 10 * precision * sigma_guess;
1006 bool lastOverflow =
false, lastUnderflow =
false;
1007 while (std::abs(val_pre - val_guess) > precision * sigma_guess) {
1008 val_pre = val_guess;
1009 if (val_guess > 0 && par->getMax() < val_guess)
1010 par->setMax(2 * val_guess);
1011 if (val_guess < 0 && par->getMin() > val_guess)
1012 par->setMin(2 * val_guess);
1013 par->setVal(val_guess);
1014 auto result = xRooFit::minimize(nll, myFitConfig);
1017 return std::numeric_limits<double>::quiet_NaN();
1019 double nll_val =
result->minNll();
1020 status +=
result->status() * 10;
1021 tmu = 2 * (nll_val - nll_min);
1022 sigma_guess = std::abs(val_guess - val_best) / sqrt(tmu);
1026 std::cout <<
"Warning: Alternative best-fit of " << par->GetName() <<
" @ " << val_guess <<
" vs "
1027 << val_best << std::endl;
1028 double new_guess = val_guess + (val_guess - val_best);
1029 val_best = val_guess;
1030 val_guess = new_guess;
1031 sigma_guess = std::abs((val_guess - val_best) / N_sigma);
1032 val_pre = val_guess - 10 * precision * sigma_guess;
1033 status = (status / 10) * 10 + 1;
1037 double corr = (val_pre - val_best - N_sigma * sigma_guess);
1042 if (printLevel > 1) {
1046 std::cout <<
"NLL min: " << nll_min << std::endl;
1047 std::cout <<
"N_sigma*sigma(pre): " << std::abs(val_pre - val_best) << std::endl;
1048 std::cout <<
"sigma(guess): " << sigma_guess << std::endl;
1049 std::cout <<
"par(guess): " << val_guess + corr << std::endl;
1050 std::cout <<
"true val: " << val_best << std::endl;
1051 std::cout <<
"tmu: " << tmu << std::endl;
1052 std::cout <<
"Precision: " << sigma_guess * precision << std::endl;
1053 std::cout <<
"Correction: " << (-corr < 0 ?
" " :
"") << -corr << std::endl;
1054 std::cout <<
"N_sigma*sigma(guess): " << std::abs(val_guess - val_best) << std::endl;
1055 std::cout << std::endl;
1057 if (val_guess > par->getMax()) {
1059 val_guess = par->getMin();
1062 lastOverflow =
true;
1063 lastUnderflow =
false;
1064 val_guess = par->getMax() - 1
e-12;
1065 }
else if (val_guess < par->getMin()) {
1066 if (lastUnderflow) {
1067 val_guess = par->getMin();
1070 lastOverflow =
false;
1071 lastUnderflow =
true;
1072 val_guess = par->getMin() + 1
e-12;
1074 lastUnderflow =
false;
1075 lastOverflow =
false;
1080 status = (status / 10) * 10 + 3;
1088 status = (status / 10) * 10 + 2;
1089 }
else if (lastUnderflow) {
1092 status = (status / 10) * 10 + 2;
1096 std::cout <<
"Found sigma for nll " << nll.
GetName() <<
": " << (val_guess - val_best) / N_sigma << std::endl;
1098 std::cout <<
"Finished in " << nrItr <<
" iterations." << std::endl;
1100 std::cout << std::endl;
1101 return (val_guess - val_best) / N_sigma;
1106 par_hat->setError(std::numeric_limits<double>::quiet_NaN());
1107 double lo = par_hat->getErrorLo();
1108 double hi = par_hat->getErrorHi();
1109 if (std::isnan(
hi)) {
1110 hi = findValue(val_best + val_err, 1);
1112 if (std::isnan(lo)) {
1113 lo = -findValue(val_best - val_err, -1);
1118 fitConfig.SetParabErrors(pErrs);
1119 fitConfig.SetMinosErrors(mErrs);
1120 par->setConstant(isConst);
1122 std::vector<std::pair<std::string, int>> statusHistory;
1126 statusHistory.emplace_back(
TString::Format(
"xMINOS_%s", parName), status);
1127 const_cast<RooFitResult &
>(ufit).setStatusHistory(statusHistory);
1140 std::deque<RooAbsArg *> topPdfs;
1142 for (
auto p :
w.allPdfs()) {
1143 if (
p->hasClients())
1145 flagCount +=
p->getAttribute(
"hypoTest");
1146 if (
p->getAttribute(
"hypoTest"))
1147 topPdfs.push_front(
p);
1149 topPdfs.push_back(
p);
1151 if (topPdfs.empty()) {
1152 Error(
"hypoTest",
"Cannot find top-level pdf in workspace");
1154 }
else if (topPdfs.size() > 1) {
1156 if (flagCount == 0) {
1157 Error(
"hypoTest",
"Multiple top-level pdfs. Flag which one to test with "
1158 "w->pdf(\"pdfName\")->setAttribute(\"hypoTest\",true)");
1160 }
else if (flagCount != 1) {
1161 Error(
"hypoTest",
"Multiple top-level pdfs flagged for hypoTest -- pick one.");
1165 model =
dynamic_cast<RooAbsPdf *
>(topPdfs.front());
1167 Info(
"hypoTest",
"Using PDF: %s", model->
GetName());
1173 std::shared_ptr<RooArgSet> obsGlobs =
nullptr;
1175 for (
auto p :
w.allData()) {
1177 Error(
"hypoTest",
"Multiple datasets in workspace. Flag which one to test with "
1178 "w->data(\"dataName\")->setAttribute(\"hypoTest\",true)");
1185 Error(
"hypoTest",
"No data -- cannot determine observables");
1189 Info(
"hypoTest",
"Using Dataset: %s", obsData->
GetName());
1192 auto _globs = xRooNode(
w).datasets()[obsData->
GetName()]->globs();
1193 obsGlobs = std::make_shared<RooArgSet>();
1194 obsGlobs->addClone(_globs.argList());
1195 Info(
"hypoTest",
"Using Globs: %s", (obsGlobs->empty()) ?
" <NONE>" : obsGlobs->contentsString().c_str());
1200 auto _vars = std::unique_ptr<RooArgSet>(model->
getVariables());
1203 for (
auto _v : *_vars) {
1208 if (poi.
size() > 1) {
1209 auto _const = std::unique_ptr<RooAbsCollection>(poi.
selectByAttrib(
"Constant",
true));
1213 if (!args.
empty()) {
1217 Error(
"hypoTest",
"No POI detected: add the hypoPoints binning to at least one non-const model parameter e.g.:\n "
1218 "w->var(\"mu\")->setBinning(RooUniformBinning(0.5,10.5,10),\"hypoPoints\"))");
1227 auto nllOpts = createNLLOptions();
1228 auto fitConfig = createFitConfig();
1230 xRooNLLVar nll(*model, std::make_pair(obsData, obsGlobs.get()), *nllOpts);
1231 nll.SetFitConfig(fitConfig);
1233 if (poi.
size() == 1) {
1236 double altVal = (mu->getStringAttribute(
"altVal")) ?
TString(mu->getStringAttribute(
"altVal")).Atof()
1237 : std::numeric_limits<double>::quiet_NaN();
1239 if (std::isnan(altVal) && mu->hasRange(
"physical")) {
1241 altVal = mu->getMin(
"physical");
1242 Info(
"hypoTest",
"No altVal specified - using min of given physical range = %g", altVal);
1244 if (!std::isnan(altVal))
1245 Info(
"hypoTest",
"alt hypo: %g - CLs activated", altVal);
1247 Info(
"hypoTest",
"No altVal found - to specify setStringAttribute(\"altVal\",\"<value>\") on POI or set "
1248 "the physical range");
1250 bool doCLs = !std::isnan(altVal) && std::abs(mu->getMin(
"hypoPoints")) > altVal &&
1251 std::abs(mu->getMax(
"hypoPoints")) > altVal;
1253 const char *sCL = (doCLs) ?
"CLs" :
"null";
1254 Info(
"hypoTest",
"%s testing active", sCL);
1264 std::vector<int> expSig = {-2, -1, 0, 1, 2};
1265 if (std::isnan(altVal))
1267 std::map<int, TGraphErrors> exp_pcls, exp_cls;
1268 for (
auto &s : expSig) {
1270 TString::Format(
"Expected (%d#sigma) p_{%s};%s", s, sCL, mu->GetTitle()));
1272 TString::Format(
"Expected (%d#sigma) %s;%s", s, sCL, mu->GetTitle()));
1276 double _out = std::numeric_limits<double>::quiet_NaN();
1277 bool lastAbove =
false;
1278 for (
int i = 0; i < pValues.GetN(); i++) {
1279 bool thisAbove = pValues.GetPointY(i) >= (1. - CL);
1280 if (i != 0 && thisAbove != lastAbove) {
1283 _out = pValues.GetPointX(i - 1) + (pValues.GetPointX(i) - pValues.GetPointX(i - 1)) *
1284 ((1. - CL) - pValues.GetPointY(i - 1)) /
1285 (pValues.GetPointY(i) - pValues.GetPointY(i - 1));
1287 lastAbove = thisAbove;
1292 auto testPoint = [&](
double testVal) {
1293 auto hp = nll.hypoPoint(mu->GetName(), testVal, altVal, pllType);
1294 obs_ts->SetPoint(obs_ts->GetN(), testVal, hp.pll().first);
1295 obs_ts->SetPointError(obs_ts->GetN() - 1, 0, hp.pll().second);
1297 if (nToysNull > 0) {
1300 obs_pcls->SetPoint(obs_pcls->GetN(), testVal, (doCLs) ? hp.pCLs_asymp().first : hp.pNull_asymp().first);
1301 obs_pcls->SetPointError(obs_pcls->GetN() - 1, 0, (doCLs) ? hp.pCLs_asymp().second : hp.pNull_asymp().second);
1302 for (
auto &s : expSig) {
1303 exp_pcls[s].SetPoint(exp_pcls[s].GetN(), testVal,
1304 (doCLs) ? hp.pCLs_asymp(s).first : hp.pNull_asymp(s).
first);
1307 Info(
"hypoTest",
"%s=%g: %s=%g sigma_mu=%g %s=%g", mu->GetName(), testVal, obs_ts->GetName(),
1308 obs_ts->GetPointY(obs_ts->GetN() - 1), hp.sigma_mu().first, obs_pcls->GetName(),
1309 obs_pcls->GetPointY(obs_pcls->GetN() - 1));
1311 Info(
"hypoTest",
"%s=%g: %s=%g %s=%g", mu->GetName(), testVal, obs_ts->GetName(),
1312 obs_ts->GetPointY(obs_ts->GetN() - 1), obs_pcls->GetName(), obs_pcls->GetPointY(obs_pcls->GetN() - 1));
1315 if (mu->getBins(
"hypoPoints") <= 0) {
1318 testPoint(mu->getMin(
"hypoPoints"));
1319 testPoint(mu->getMax(
"hypoPoints"));
1320 testPoint((mu->getMax(
"hypoPoints") + mu->getMin(
"hypoPoints")) / 2.);
1322 while (std::abs(obs_pcls->GetPointY(obs_pcls->GetN() - 1) - (1. - CL)) > 0.01) {
1324 double nextTest = getLimit(*obs_pcls);
1325 if (std::isnan(nextTest))
1327 testPoint(nextTest);
1329 for (
auto s : expSig) {
1330 while (std::abs(exp_pcls[s].GetPointY(exp_pcls[s].GetN() - 1) - (1. - CL)) > 0.01) {
1332 double nextTest = getLimit(exp_pcls[s]);
1333 if (std::isnan(nextTest))
1335 testPoint(nextTest);
1340 for (
auto &s : expSig)
1344 for (
int i = 0; i <= mu->getBins(
"hypoPoints"); i++) {
1345 testPoint((i == mu->getBins(
"hypoPoints")) ? mu->getBinning(
"hypoPoints").binHigh(i - 1)
1346 : mu->getBinning(
"hypoPoints").binLow(i));
1350 obs_cls->SetPoint(obs_cls->GetN(), getLimit(*obs_pcls), 0.05);
1351 for (
auto &s : expSig) {
1352 exp_cls[s].SetPoint(exp_cls[s].GetN(), getLimit(exp_pcls[s]), 0.05);
1356 if (exp_pcls[2].GetN() > 1) {
1362 band2down->
SetNameTitle(
".pCLs_2sigma_downUncert",
"");
1368 for (
int i = 0; i < exp_pcls[2].GetN(); i++) {
1369 band2->
SetPoint(band2->
GetN(), exp_pcls[2].GetPointX(i),
1370 exp_pcls[2].GetPointY(i) - exp_pcls[2].GetErrorYlow(i));
1371 band2up->
SetPoint(band2up->
GetN(), exp_pcls[2].GetPointX(i),
1372 exp_pcls[2].GetPointY(i) + exp_pcls[2].GetErrorYhigh(i));
1374 for (
int i = exp_pcls[2].GetN() - 1; i >= 0; i--) {
1375 band2up->
SetPoint(band2up->
GetN(), exp_pcls[2].GetPointX(i),
1376 exp_pcls[2].GetPointY(i) - exp_pcls[2].GetErrorYlow(i));
1378 for (
int i = 0; i < exp_pcls[-2].GetN(); i++) {
1379 band2down->
SetPoint(band2down->
GetN(), exp_pcls[-2].GetPointX(i),
1380 exp_pcls[-2].GetPointY(i) + exp_pcls[-2].GetErrorYhigh(i));
1382 for (
int i = exp_pcls[-2].GetN() - 1; i >= 0; i--) {
1383 band2->
SetPoint(band2->
GetN(), exp_pcls[-2].GetPointX(i),
1384 exp_pcls[-2].GetPointY(i) + exp_pcls[-2].GetErrorYhigh(i));
1385 band2down->
SetPoint(band2down->
GetN(), exp_pcls[-2].GetPointX(i),
1386 exp_pcls[-2].GetPointY(i) - exp_pcls[-2].GetErrorYlow(i));
1396 band2down->
Draw(
"F");
1399 if (exp_pcls[1].GetN() > 1) {
1405 band2down->
SetNameTitle(
".pCLs_1sigma_downUncert",
"");
1411 for (
int i = 0; i < exp_pcls[1].GetN(); i++) {
1412 band2->
SetPoint(band2->
GetN(), exp_pcls[1].GetPointX(i),
1413 exp_pcls[1].GetPointY(i) - exp_pcls[1].GetErrorYlow(i));
1414 band2up->
SetPoint(band2up->
GetN(), exp_pcls[1].GetPointX(i),
1415 exp_pcls[1].GetPointY(i) + exp_pcls[1].GetErrorYhigh(i));
1417 for (
int i = exp_pcls[1].GetN() - 1; i >= 0; i--) {
1418 band2up->
SetPoint(band2up->
GetN(), exp_pcls[1].GetPointX(i),
1419 exp_pcls[1].GetPointY(i) - exp_pcls[1].GetErrorYlow(i));
1421 for (
int i = 0; i < exp_pcls[-1].GetN(); i++) {
1422 band2down->
SetPoint(band2down->
GetN(), exp_pcls[-1].GetPointX(i),
1423 exp_pcls[-1].GetPointY(i) + exp_pcls[-1].GetErrorYhigh(i));
1425 for (
int i = exp_pcls[-1].GetN() - 1; i >= 0; i--) {
1426 band2->
SetPoint(band2->
GetN(), exp_pcls[-1].GetPointX(i),
1427 exp_pcls[-1].GetPointY(i) + exp_pcls[-1].GetErrorYhigh(i));
1428 band2down->
SetPoint(band2down->
GetN(), exp_pcls[-1].GetPointX(i),
1429 exp_pcls[-1].GetPointY(i) - exp_pcls[-1].GetErrorYlow(i));
1436 band2down->
Draw(
"F");
1440 if (exp_cls[0].GetN() > 0) {
1441 exp_pcls[0].SetLineStyle(2);
1442 exp_pcls[0].SetFillColor(
kGreen);
1443 exp_pcls[0].SetMarkerStyle(0);
1447 obs_pcls->Draw(
gPad->GetListOfPrimitives()->IsEmpty() ?
"ALP" :
"LP");
1449 obs_ts->SetLineColor(
kRed);
1450 obs_ts->SetMarkerColor(
kRed);
1454 auto l =
new TLegend(0.5, 0.6, 1. -
gPad->GetRightMargin(), 1. -
gPad->GetTopMargin());
1455 l->SetName(
"legend");
1456 l->AddEntry(obs_ts, obs_ts->GetTitle(),
"LPE");
1457 l->AddEntry(obs_pcls, obs_pcls->GetTitle(),
"LPE");
1459 l->AddEntry(expPlot,
"Expected",
"LFE");
1463 obs_cls->SetMarkerStyle(29);
1464 obs_cls->SetEditable(
false);
1465 obs_cls->Draw(
"LP");
1466 for (
auto s : expSig) {
1467 exp_cls[s].SetMarkerStyle(29);
1468 exp_cls[s].SetEditable(
false);
1469 exp_cls[s].DrawClone(
"LP");
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
double evaluate() const override
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
ProgressMonitor(const ProgressMonitor &other, const char *name=0)
virtual ~ProgressMonitor()
ProgressMonitor(RooAbsReal &f, int interval=30)
virtual TObject * clone(const char *newname) const override
static ProgressMonitor * me
static void interruptHandler(int signum)
Class describing the configuration of the fit, options and parameter settings using the ROOT::Fit::Pa...
bool UpdateAfterFit() const
Update configuration after a fit using the FitResult.
void SetMinosErrors(bool on=true)
set Minos erros computation to be performed after fitting
const std::string & MinimizerAlgoType() const
return type of minimizer algorithms
bool ParabErrors() const
do analysis for parabolic errors
void SetUpdateAfterFit(bool on=true)
Update configuration after a fit using the FitResult.
void SetParamsSettings(unsigned int npar, const double *params, const double *vstep=nullptr)
set the parameter settings from number of parameters and a vector of values and optionally step value...
const std::vector< ROOT::Fit::ParameterSettings > & ParamsSettings() const
get the vector of parameter settings (const method)
void SetParabErrors(bool on=true)
set parabolic erros
const std::string & MinimizerType() const
return type of minimizer package
ROOT::Math::MinimizerOptions & MinimizerOptions()
access to the minimizer control parameter (non const method)
bool MinosErrors() const
do minos errors analysis on the parameters
bool IsValid() const
True if fit successful, otherwise false.
double Edm() const
Expected distance from minimum.
int Status() const
minimizer status code
const FitResult & Result() const
get fit result
const FitConfig & Config() const
access to the fit configuration (const method)
class implementing generic options for a numerical algorithm Just store the options in a map of strin...
Generic interface for defining configuration options of a numerical algorithm.
void SetValue(const char *name, double val)
generic methods for retrieving options
bool GetValue(const char *name, T &t) const
void SetMaxFunctionCalls(unsigned int maxfcn)
set maximum of function calls
void SetMaxIterations(unsigned int maxiter)
set maximum iterations (one iteration can have many function calls)
int Strategy() const
strategy
const IOptions * ExtraOptions() const
return extra options (NULL pointer if they are not present)
double Tolerance() const
absolute tolerance
unsigned int MaxIterations() const
max iterations
unsigned int MaxFunctionCalls() const
max number of function calls
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
bool dependsOn(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=nullptr, bool valueOnly=false) const
Test whether we depend on (ie, are served by) any object in the specified collection.
bool isConstant() const
Check if the "Constant" attribute is set.
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key 'key'.
virtual void constOptimizeTestStatistic(ConstOpCode opcode, bool doAlsoTrackingOpt=true)
Interface function signaling a request to perform constant term optimization.
bool getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
RooFit::OwningPtr< RooArgSet > getVariables(bool stripDisconnected=true) const
Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
RooAbsArg * findServer(const char *name) const
Return server of this with name name. Returns nullptr if not found.
RooAbsCollection * selectByAttrib(const char *name, bool value) const
Create a subset of the current collection, consisting only of those elements with the specified attri...
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
Storage_t const & get() const
Const access to the underlying stl container.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Storage_t::size_type size() const
RooAbsArg * first() const
virtual RooAbsArg * addClone(const RooAbsArg &var, bool silent=false)
Add a clone of the specified argument to list.
std::string contentsString() const
Return comma separated list of contained object names as STL string.
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooAbsData is the common abstract base class for binned and unbinned datasets.
virtual double getMax(const char *name=nullptr) const
Get maximum of currently defined range.
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
RooArgList is a container object that can hold multiple RooAbsArg objects.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Class RooBinning is an implements RooAbsBinning in terms of an array of boundary values,...
RooCmdArg is a named container for two doubles, two integers two object points and three string point...
RooDataSet is a container class to hold unbinned data.
RooRealVar * weightVar() const
Returns a pointer to the weight variable (if set).
A one-time forward iterator working on RooLinkedList or RooAbsCollection.
RooAbsArg * next()
Return next element or nullptr if at end.
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
Int_t statusCodeHistory(UInt_t icycle) const
const char * statusLabelHistory(UInt_t icycle) const
const RooArgList & floatParsFinal() const
Return list of floating parameters after fit.
Int_t status() const
Return MINUIT status code.
UInt_t numStatusHistory() const
double minNll() const
Return minimized -log(L) value.
xRooFitResult minimize(const std::shared_ptr< ROOT::Fit::FitConfig > &=nullptr)
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
RooMinimizer is a wrapper class around ROOT::Fit:Fitter that provides a seamless interface between th...
void optimizeConst(int flag)
If flag is true, perform constant term optimization on function being minimized.
RooFit::OwningPtr< RooFitResult > save(const char *name=nullptr, const char *title=nullptr)
Save and return a RooFitResult snapshot of current minimizer status.
int hesse()
Execute HESSE.
int minimize(const char *type, const char *alg=nullptr)
Minimise the function passed in the constructor.
void setStrategy(int strat)
Change MINUIT strategy to istrat.
ROOT::Fit::Fitter * fitter()
Return underlying ROOT fitter object.
static RooMsgService & instance()
Return reference to singleton instance.
void setGlobalKillBelow(RooFit::MsgLevel level)
RooFit::MsgLevel globalKillBelow() const
void setNoRounding(bool flag=true)
Switch off/on rounding of x to the nearest integer.
RooProdPdf is an efficient implementation of a product of PDFs of the form.
static TRandom * randomGenerator()
Return a pointer to a singleton random-number generator implementation.
RooRealVar represents a variable that can be changed from the outside.
void setVal(double value) override
Set value of variable to 'value'.
void setError(double value)
bool hasBinning(const char *name) const override
Returns true if variable has a binning named 'name'.
RooSimultaneous facilitates simultaneous fitting of multiple PDFs to subsets of a given dataset.
static RooAbsData * GenerateAsimovData(const RooAbsPdf &pdf, const RooArgSet &observables)
generate the asimov data for the observables (not the global ones) need to deal with the case of a si...
RooStringVar is a RooAbsArg implementing string values.
The RooWorkspace is a persistable container for RooFit projects.
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
static TCanvas * MakeDefCanvas()
Static function to build a default canvas.
TClass instances represent classes, structs and namespaces in the ROOT type system.
TClass * IsA() const override
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
const char * AsString() const
Return the date & time as a string (ctime() format).
Describe directory structure in memory.
virtual TDirectory * GetDirectory(const char *namecycle, Bool_t printError=false, const char *funcname="GetDirectory")
Find a directory using apath.
std::enable_if_t<!std::is_base_of< TObject, T >::value, Int_t > WriteObject(const T *obj, const char *name, Option_t *option="", Int_t bufsize=0)
Write an object with proper type checking.
virtual Bool_t IsWritable() const
virtual TDirectory * mkdir(const char *name, const char *title="", Bool_t returnExistingDirectory=kFALSE)
Create a sub-directory "a" or a hierarchy of sub-directories "a/b/c/...".
A TGraphErrors is a TGraph with error bars.
A TGraph is an object made of two arrays X and Y with npoints each.
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
void Draw(Option_t *chopt="") override
Draw this graph with its current attributes.
void SetNameTitle(const char *name="", const char *title="") override
Set graph name and title.
Book space in a file, create I/O buffers, to fill them, (un)compress them.
This class displays a legend box (TPaveText) containing several legend entries.
TMatrixTBase< Element > & ResizeTo(Int_t nrows, Int_t ncols, Int_t=-1) override
Set size of the matrix to nrows x ncols New dynamic elements are created, the overlapping part of the...
The TNamed class is the base class for all named ROOT classes.
TObject * Clone(const char *newname="") const override
Make a clone of an object using the Streamer facility.
const char * GetName() const override
Returns name of object.
Mother of all ROOT objects.
virtual const char * GetName() const
Returns name of object.
virtual TObject * DrawClone(Option_t *option="") const
Draw a clone of this object in the current selected pad with: gROOT->SetSelectedPad(c1).
virtual void Delete(Option_t *option="")
Delete this object.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
void RedrawAxis(Option_t *option="") override
Redraw the frame axis.
virtual void SetSeed(ULong_t seed=0)
Set the random generator seed.
virtual UInt_t Integer(UInt_t imax)
Returns a random integer uniformly distributed on the interval [ 0, imax-1 ].
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
void Continue()
Resume a stopped stopwatch.
Provides iteration through tokens of a given string.
Bool_t NextToken()
Get the next token, it is stored in this TString.
Double_t Atof() const
Return floating-point value contained in string.
Bool_t IsFloat() const
Returns kTRUE if string contains a floating point or integer number.
const char * Data() const
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
This class defines a UUID (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDent...
TDatime GetTime() const
Get time from UUID.
const char * AsString() const
Return UUID as string. Copy string immediately since it will be reused.
RooCmdArg Offset(std::string const &mode)
RooCmdArg Optimize(Int_t flag=2)
RooCmdArg Extended(bool flag=true)
RooCmdArg ExpectedData(bool flag=true)
MsgLevel
Verbosity level for RooMsgService::StreamConfig in RooMsgService.
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
Sort the n elements of the array a of generic templated type Element.
#define BEGIN_XROOFIT_NAMESPACE
#define END_XROOFIT_NAMESPACE