20#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
21#define protected public
73std::shared_ptr<RooLinkedList> xRooFit::sDefaultNLLOptions =
nullptr;
74std::shared_ptr<ROOT::Fit::FitConfig> xRooFit::sDefaultFitConfig =
nullptr;
76const char *xRooFit::GetVersion()
80const char *xRooFit::GetVersionDate()
87 return RooCmdArg(
"ReuseNLL", flag, 0, 0, 0,
nullptr,
nullptr,
nullptr,
nullptr);
97 return RooCmdArg(
"StrategySequence", 0, 0, 0, 0, val);
105xRooNLLVar xRooFit::createNLL(
const std::shared_ptr<RooAbsPdf> pdf,
const std::shared_ptr<RooAbsData>
data,
113 return createNLL(std::shared_ptr<RooAbsPdf>(&pdf, [](
RooAbsPdf *) {}),
131 return createNLL(pdf,
data,
l);
134std::shared_ptr<const RooFitResult>
136 const std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>> &
data,
144std::shared_ptr<const RooFitResult> xRooFit::fitTo(
RooAbsPdf &pdf,
145 const std::pair<RooAbsData *, const RooAbsCollection *> &
data,
153std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>>
157 std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooAbsCollection>> out;
163 auto _allVars = std::unique_ptr<RooAbsCollection>(pdf.
getVariables());
164 auto _snap = std::unique_ptr<RooAbsCollection>(_allVars->snapshot());
165 *_allVars = fr->constPars();
166 *_allVars = fr->floatParsFinal();
169 auto _globs = std::unique_ptr<RooAbsCollection>(fr->constPars().selectByAttrib(
"global",
true));
180 std::function<std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooArgSet>>(
RooAbsPdf *)> genSubPdf;
183 std::pair<std::shared_ptr<RooAbsData>, std::shared_ptr<const RooArgSet>> _out;
186 std::unique_ptr<RooArgSet> _obs(_pdf->getVariables());
187 _obs->remove(fr->constPars(),
true,
true);
188 _obs->remove(fr->floatParsFinal(),
true,
true);
190 if (!_globs->empty()) {
195 std::unique_ptr<RooArgSet> globs(_pdf->getObservables(t));
196 globs->snapshot(*toy_gobs);
197 if (!toy_gobs->
empty() &&
201 *toy_gobs = *std::unique_ptr<RooDataSet>(_pdf->generate(*globs, 1))->
get();
206 for (
auto thePdf : pp->pdfList()) {
207 auto gob = std::unique_ptr<RooArgSet>(thePdf->getObservables(*globs));
210 if (gob->size() > 1) {
211 Warning(
"generate",
"%s contains multiple global obs: %s", thePdf->GetName(),
212 gob->contentsString().c_str());
216 std::unique_ptr<RooArgSet> cpars(thePdf->getParameters(*globs));
218 bool foundServer =
false;
226 !(cClass && strcmp(cClass->
GetName(),
"SimpleGaussianConstraint") == 0)) {
229 <<
"xRooFit::generateFrom : constraint term " << thePdf->GetName() <<
" of type "
230 << className <<
" is a non-supported type - result might be not correct " << std::endl;
248 <<
"xRooFit::generateFrom : constraint term " << thePdf->
GetName()
249 <<
" has no direct dependence on global observable- cannot generate it " << std::endl;
261 for (
RooAbsArg *a2 : thePdf->servers()) {
267 if (thetaGamma ==
nullptr) {
269 <<
"xRooFit::generateFrom : constraint term " << thePdf->
GetName()
270 <<
" is a Gamma distribution and no server named theta is found. Assume that the Gamma "
275 for (
RooAbsArg *a2 : thePdf->servers()) {
283 <<
"xRooFit::generateFrom : constraint term " << thePdf->
GetName()
284 <<
" constraint term has more server depending on nuisance- cannot generate it "
289 if (thetaGamma && thetaGamma->
getVal() > 0) {
300 <<
"xRooFit::generateFrom : can't find nuisance for constraint term - global "
301 "observables will not be set to Asimov value "
302 << thePdf->GetName() <<
" glob = " << rrv.
GetName() << std::endl;
303 std::cerr <<
"Parameters: " << std::endl;
305 std::cerr <<
"Observables: " << std::endl;
310 Error(
"generate",
"Cannot generate global observables, pdf is: %s::%s", _pdf->ClassName(),
316 _out.second.reset(toy_gobs);
323 _out.first = std::make_unique<RooDataSet>(
324 uuid,
TString::Format(
"%s %s", _pdf->GetTitle(), (expected) ?
"Expected" :
"Toy"), *_obs,
327 for (
auto &
c : s->indexCat()) {
328#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 22, 00)
329 std::string cLabel =
c.first;
331 std::string cLabel =
c->GetName();
333 auto p = s->getPdf(cLabel.c_str());
336 auto toy = genSubPdf(
p);
337 if (toy.second && _out.second)
338 *
const_cast<RooArgSet *
>(_out.second.get()) = *toy.second;
339 _obs->setCatLabel(s->indexCat().GetName(), cLabel.c_str());
340 for (
int i = 0; i < toy.first->numEntries(); i++) {
341 *_obs = *toy.first->get(i);
342 _out.first->add(*_obs, toy.first->weight());
348 std::map<RooRealVar *, std::shared_ptr<RooAbsBinning>> binnings;
350 for (
auto &o : *_obs) {
354 if (
auto res = _pdf->binBoundaries(*
r, -std::numeric_limits<double>::infinity(),
355 std::numeric_limits<double>::infinity())) {
356 binnings[
r] = std::shared_ptr<RooAbsBinning>(
r->getBinning().clone(
r->getBinning().GetName()));
358 std::vector<double> boundaries;
359 boundaries.reserve(res->size());
360 for (
auto &rr : *res) {
361 if (boundaries.empty() || std::abs(boundaries.back() - rr) > 1
e-3 ||
362 std::abs(boundaries.back() - rr) > 1
e-5 * boundaries.back())
363 boundaries.push_back(rr);
365 r->setBinning(
RooBinning(boundaries.size() - 1, &boundaries[0]));
367 }
else if (
r->numBins(
r->getBinning().GetName()) == 0 && expected) {
369 binnings[
r] = std::shared_ptr<RooAbsBinning>(
r->getBinning().clone(
r->getBinning().GetName()));
380 _out.first = std::make_unique<RooDataSet>(
"",
"Toy", _tmp,
RooFit::WeightVar(
"weightVar"));
381 _out.first->add(_tmp);
383 if (_pdf->canBeExtended()) {
393 _out.first = std::unique_ptr<RooDataSet>{_pdf->generate(*_obs,
RooFit::ExpectedData(expected))};
397 _out.first->SetName(
TUUID().AsString());
399 for (
auto &
b : binnings) {
401 auto binning =
b.second;
402 v->setBinning(*binning);
405 auto x =
dynamic_cast<RooRealVar *
>(_out.first->get()->find(
v->GetName()));
406 auto r =
x->getRange();
407 if (
r.first > binning->lowBound())
408 x->setMin(binning->lowBound());
409 if (
r.second < binning->highBound())
410 x->setMax(binning->highBound());
415 out = genSubPdf(&pdf);
416 out.first->SetName(expected ? (
TString(fr->GetName()) +
"_asimov") : uuid);
420 out.first->setGlobalObservables(*out.second);
424#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
427 w->setStringAttribute(
"fitResult", fr->GetName());
428 w->setAttribute(
"expected", expected);
438#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
439 auto _ws = pdf.
_myws;
446 for (
auto obj : _ws->components()) {
447 for (
int i = 0; i < obj->numCaches(); i++) {
453 p->setNormRange(
p->normRange());
455 obj->setValueDirty();
463std::shared_ptr<RooLinkedList> xRooFit::createNLLOptions()
469 for (
auto opt : *defaultNLLOptions()) {
470 out->Add(opt->Clone(
nullptr));
476std::shared_ptr<RooLinkedList> xRooFit::defaultNLLOptions()
478 if (sDefaultNLLOptions)
479 return sDefaultNLLOptions;
485 return sDefaultNLLOptions;
488std::shared_ptr<ROOT::Fit::FitConfig> xRooFit::createFitConfig()
490 return std::make_shared<ROOT::Fit::FitConfig>(*defaultFitConfig());
493std::shared_ptr<ROOT::Fit::FitConfig> xRooFit::defaultFitConfig()
495 if (sDefaultFitConfig)
496 return sDefaultFitConfig;
497 sDefaultFitConfig = std::make_shared<ROOT::Fit::FitConfig>();
498 auto &fitConfig = *sDefaultFitConfig;
499 fitConfig.SetParabErrors(
true);
500 fitConfig.MinimizerOptions().SetMinimizerType(
"Minuit2");
501 fitConfig.MinimizerOptions().SetErrorDef(0.5);
502 fitConfig.SetParabErrors(
true);
503 fitConfig.SetMinosErrors(
true);
504 fitConfig.MinimizerOptions().SetMaxFunctionCalls(
506 fitConfig.MinimizerOptions().SetMaxIterations(-1);
507 fitConfig.MinimizerOptions().SetStrategy(-1);
511 fitConfig.MinimizerOptions().SetPrintLevel(-2);
514 auto extraOpts =
const_cast<ROOT::Math::IOptions *
>(fitConfig.MinimizerOptions().ExtraOptions());
515#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 29, 00)
519 extraOpts->SetValue(
"HesseStrategySequence",
"23");
521 extraOpts->SetValue(
"StrategySequence",
"0s01s12s2m");
522 extraOpts->SetValue(
"HesseStrategySequence",
"2");
527 extraOpts->SetValue(
"LogSize", 0);
528 extraOpts->SetValue(
"BoundaryCheck",
530 extraOpts->SetValue(
"TrackProgress", 30);
537 return sDefaultFitConfig;
542 return const_cast<ROOT::Math::IOptions *
>(defaultFitConfig()->MinimizerOptions().ExtraOptions());
553 std::cerr << msg << std::endl;
564 std::cout << msg << std::endl;
575 if (signum == SIGINT) {
576 printCout(
"Minimization interrupted ... will exit as soon as possible");
587 fFunc(
"func",
"func", this,
f),
593 vars.reset(std::unique_ptr<RooAbsCollection>(
f.getVariables())->selectByAttrib(
"Constant",
false));
626 throw std::runtime_error(
"Keyboard interrupt");
627 return std::numeric_limits<double>::quiet_NaN();
630 if (
prevMin == std::numeric_limits<double>::infinity()) {
634 if (!std::isnan(out)) {
646 std::stringstream sout;
655 nRequired *= (nRequired - 1);
667 std::vector<std::pair<double, std::string>> parDeltas;
670 parDeltas.emplace_back(std::pair<double, std::string>(
673 std::sort(parDeltas.begin(), parDeltas.end(),
674 [](
auto &left,
auto &right) { return std::abs(left.first) > std::abs(right.first); });
676 for (i = 0; i < std::min(3,
int(parDeltas.size())); i++) {
677 if (parDeltas.at(i).first == 0)
681 sout << parDeltas.at(i).second << (parDeltas.at(i).first >= 0 ?
"+" :
"-") <<
"="
682 << std::abs(parDeltas.at(i).first) <<
"(" <<
minPars.
getRealValue(parDeltas.at(i).second.c_str())
685 if (i <
int(parDeltas.size()) && parDeltas.at(i).first != 0)
690 if (
gROOT->FromPopUp() &&
gROOT->GetListOfBrowsers()->At(0)) {
691 auto browser =
dynamic_cast<TBrowser *
>(
gROOT->GetListOfBrowsers()->At(0));
692 std::string status = sout.str();
695 std::string status_part;
696 if (status.find(
" : ") != std::string::npos) {
697 status_part = status.substr(0, status.find(
" : "));
698 status = status.substr(status.find(
" : ") + 3);
700 status_part = status;
703 browser->SetStatusText(status_part.c_str(), col);
722 mutable double minVal = std::numeric_limits<double>::infinity();
723 mutable double prevMin = std::numeric_limits<double>::infinity();
732 std::shared_ptr<RooAbsCollection>
vars;
745 const std::shared_ptr<ROOT::Fit::FitConfig> &_fitConfig,
746 const std::shared_ptr<RooLinkedList> &nllOpts)
750 auto &fitConfig = *myFitConfig;
754 TString resultTitle = nll.getStringAttribute(
"fitresultTitle");
756 if (resultTitle ==
"")
761 if (nll.getStringAttribute(
"userPars")) {
762 TStringToken st(nll.getStringAttribute(
"userPars"),
",");
765 TString parVal = nll.getStringAttribute(parName);
774 auto _nllVars = std::unique_ptr<RooAbsCollection>(_nll->getVariables());
776 std::unique_ptr<RooAbsCollection> constPars(_nllVars->selectByAttrib(
"Constant",
true));
777 constPars->add(fUserPars,
true);
778 std::unique_ptr<RooAbsCollection> floatPars(_nllVars->selectByAttrib(
"Constant",
false));
781 double boundaryCheck = 0;
785#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 29, 00)
786 int hesseStrategy = 3;
788 int hesseStrategy = 2;
790 if (fitConfig.MinimizerOptions().ExtraOptions()) {
791 fitConfig.MinimizerOptions().ExtraOptions()->GetNamedValue(
"StrategySequence", s);
792 fitConfig.MinimizerOptions().ExtraOptions()->GetIntValue(
"TrackProgress", _progress);
793 fitConfig.MinimizerOptions().ExtraOptions()->GetRealValue(
"BoundaryCheck", boundaryCheck);
794 fitConfig.MinimizerOptions().ExtraOptions()->GetIntValue(
"LogSize", logSize);
795 fitConfig.MinimizerOptions().ExtraOptions()->GetIntValue(
"HesseStrategy", hesseStrategy);
796 fitConfig.MinimizerOptions().ExtraOptions()->GetNamedValue(
"HesseStrategySequence", hs);
806 if (
auto nllDir = cacheDir->
GetDirectory(nll.GetName()); nllDir) {
807 if (
auto keys = nllDir->GetListOfKeys(); keys) {
808 for (
auto &&k : *keys) {
810 if (cl->InheritsFrom(
"RooFitResult")) {
812 nllDir->GetList() ?
dynamic_cast<StoredFitResult *
>(nllDir->GetList()->FindObject(k->GetName()))
815 (storedFr) ? storedFr->
fr.get() :
dynamic_cast<TKey *
>(k)->ReadObject<RooFitResult>();
819 nllDir->Add(storedFr);
824 if (!cachedFit->floatParsFinal().equals(*floatPars)) {
827 for (
auto &
p : *constPars) {
834 _p->getCurrentIndex() !=
c->getCurrentIndex()) {
843 if (
auto _p =
dynamic_cast<RooAbsReal *
>(cachedFit->constPars().find(
p->
GetName())); _p) {
846 if (!_p->getAttribute(
"global") && std::abs(_p->getVal() -
v->getVal()) > 1
e-12) {
869 if (nll.getAttribute(
"readOnly"))
872 int printLevel = fitConfig.MinimizerOptions().PrintLevel();
878 if (floatPars->empty() || fitConfig.MinimizerOptions().MaxFunctionCalls() == 1) {
879 std::shared_ptr<RooFitResult>
result;
881 parsList.
add(*floatPars);
883 result = std::make_shared<RooFitResult>();
885 result->SetTitle(resultTitle);
886 result->setFinalParList(parsList);
887 result->setInitParList(parsList);
891 result->setCovarianceMatrix(
d);
892 result->setCovQual(floatPars->empty() ? 3 : -1);
893 result->setMinNLL(_nll->getVal());
895 result->setStatus(floatPars->empty() ? 0 : 1);
897 std::vector<std::pair<std::string, int>> statusHistory;
898 statusHistory.emplace_back(std::make_pair(
"EVAL",
result->status()));
899 result->setStatusHistory(statusHistory);
904 cacheDir->
mkdir(nll.GetName());
905 if (
auto dir = cacheDir->
GetDirectory(nll.GetName()); dir) {
908 if (strlen(nllOpts->GetName()) == 0) {
911 if (!dir->FindKey(nllOpts->GetName())) {
912 dir->WriteObject(nllOpts.get(), nllOpts->GetName());
924 std::shared_ptr<RooFitResult> out;
928 for (
auto p : *floatPars) {
929 if (
p->isCategory()) {
933 if (!floatCats.
empty()) {
934 RooSuperCategory allCats(
"floatCats",
"Floating categorical parameters", floatCats);
935 std::unique_ptr<RooAbsCollection> _snap(floatCats.
snapshot());
938 std::shared_ptr<const RooFitResult> bestFr;
939 for (
auto c : allCats) {
941 Info(
"minimize",
"Minimizing with discrete %s",
c.first.c_str());
942 auto fr =
minimize(nll, _fitConfig, nllOpts);
944 Warning(
"minimize",
"Minimization with discrete %s failed",
c.first.c_str());
947 if (!bestFr || fr->minNll() < bestFr->minNll()) {
958 out = std::make_shared<RooFitResult>(*bestFr);
959 const_cast<RooArgList &
>(out->floatParsFinal())
960 .addClone(*std::unique_ptr<RooAbsCollection>(out->constPars().selectCommon(floatCats)));
961 const_cast<RooArgList &
>(out->floatParsInit()).addClone(*_snap);
962 const_cast<RooArgList &
>(out->constPars()).remove(floatCats);
966 bool restore = !fitConfig.UpdateAfterFit();
967 bool minos = fitConfig.MinosErrors();
970 int strategy = fitConfig.MinimizerOptions().Strategy();
972 if (_progress && printLevel >= -2) {
976 auto logger = (logSize > 0) ? std::make_unique<cout_redirect>(logs, logSize) :
nullptr;
977 std::unique_ptr<RooMinimizer> _minimizerPtr = std::make_unique<RooMinimizer>(*_nll);
979 _minimizer->
fitter()->Config() = fitConfig;
991 bool autoMaxCalls = (_minimizer->
fitter()->Config().MinimizerOptions().MaxFunctionCalls() == 0);
993 _minimizer->
fitter()->Config().MinimizerOptions().SetMaxFunctionCalls(
994 500 * floatPars->size() * floatPars->size());
996 if (_minimizer->
fitter()->Config().MinimizerOptions().MaxIterations() == 0) {
997 _minimizer->
fitter()->Config().MinimizerOptions().SetMaxIterations(500 * floatPars->size());
1000 std::unique_ptr<RooAbsCollection> floatInitVals(floatPars->snapshot());
1001 bool hesse = _minimizer->
fitter()->Config().ParabErrors();
1002 _minimizer->
fitter()->Config().SetParabErrors(
1004 _minimizer->
fitter()->Config().SetMinosErrors(
false);
1005 _minimizer->
fitter()->Config().SetUpdateAfterFit(
true);
1007 std::vector<std::pair<std::string, int>> statusHistory;
1012 TString actualFirstMinimizer = _minimizer->
fitter()->Config().MinimizerType();
1017 TString minim = _minimizer->
fitter()->Config().MinimizerType();
1018 TString algo = _minimizer->
fitter()->Config().MinimizerAlgoType();
1019 if (minim ==
"Minuit2") {
1020 if (strategy == -1) {
1023 sIdx = m_strategy.
Index(
'0' + strategy);
1026 Warning(
"minimize",
"Strategy %d not specified in StrategySequence %s ... defaulting to start of sequence",
1027 strategy, m_strategy.
Data());
1030 }
else if (minim ==
"Minuit")
1031 sIdx = m_strategy.
Index(
'm');
1036 while (tries < maxtries && sIdx != -1) {
1037 if (m_strategy(sIdx) ==
'm') {
1039 algo =
"migradImproved";
1040 }
else if (m_strategy(sIdx) ==
's') {
1042 }
else if (m_strategy(sIdx) ==
'h') {
1044 }
else if (m_strategy(sIdx) ==
'r') {
1048 *floatPars = *floatInitVals;
1049 std::unique_ptr<RooMinimizer> _minimizerPtr2 = std::make_unique<RooMinimizer>(*_nll);
1050 auto initPars = _minimizerPtr2->fitter()->Config().ParamsSettings();
1051 auto initOpts = _minimizerPtr2->fitter()->Config().MinimizerOptions();
1052 _minimizerPtr2->fitter()->Config() = _minimizer->
fitter()->Config();
1053 _minimizerPtr2->fitter()->Config().SetParamsSettings({});
1054 _minimizerPtr = std::move(_minimizerPtr2);
1055 _minimizer = _minimizerPtr.get();
1057 statusHistory.emplace_back(
"Reset", 0);
1060 fff->prevMin = fff->minVal;
1064 strategy =
int(m_strategy(sIdx) -
'0');
1070 fff->fState = minim + algo + std::to_string(_minimizer->
fitter()->Config().MinimizerOptions().Strategy());
1073 status = _minimizer->
minimize(minim, algo);
1074 }
catch (
const std::exception &
e) {
1075 std::cerr <<
"Exception while minimizing: " <<
e.what() << std::endl;
1077 if (first && actualFirstMinimizer != _minimizer->
fitter()->Config().MinimizerType())
1078 actualFirstMinimizer = _minimizer->
fitter()->Config().MinimizerType();
1084 throw std::runtime_error(
"Keyboard interrupt while minimizing");
1088 status = _minimizer->
fitter()
1091 minim = _minimizer->
fitter()->Config().MinimizerType();
1092 statusHistory.emplace_back(_minimizer->
fitter()->Config().MinimizerType() +
1093 _minimizer->
fitter()->Config().MinimizerAlgoType() +
1094 std::to_string(_minimizer->
fitter()->Config().MinimizerOptions().Strategy()),
1096 if (status % 1000 == 0)
1099 if (status == 4 && minim !=
"Minuit") {
1100 if (printLevel >= -1) {
1101 Warning(
"fitTo",
"%s Hit max function calls of %d", fitName.
Data(),
1102 _minimizer->
fitter()->Config().MinimizerOptions().MaxFunctionCalls());
1105 if (printLevel >= -1)
1106 Warning(
"fitTo",
"will try doubling this");
1107 _minimizer->
fitter()->Config().MinimizerOptions().SetMaxFunctionCalls(
1108 _minimizer->
fitter()->Config().MinimizerOptions().MaxFunctionCalls() * 2);
1109 _minimizer->
fitter()->Config().MinimizerOptions().SetMaxIterations(
1110 _minimizer->
fitter()->Config().MinimizerOptions().MaxIterations() * 2);
1118 if (printLevel >= -1) {
1120 fitName.
Data(), _minimizer->
fitter()->Config().MinimizerType().c_str(),
1121 _minimizer->
fitter()->Config().MinimizerAlgoType().c_str(), status,
1122 _minimizer->
fitter()->Result().Edm(),
1123 _minimizer->
fitter()->Config().MinimizerOptions().Tolerance(),
1124 _minimizer->
fitter()->Config().MinimizerOptions().Strategy(), tries)
1129 if (sIdx == m_strategy.
Length() - 1) {
1136 auto mini_sIdx = sIdx;
1149 if (printLevel >= -1 && status != 0) {
1150 Warning(
"fitTo",
"%s final status is %d", fitName.
Data(), status);
1159 int miniStrat = _minimizer->
fitter()->Config().MinimizerOptions().Strategy();
1160 double dCovar = std::numeric_limits<double>::quiet_NaN();
1167 if (hesse && m_hessestrategy.
Length() != 0 &&
1168 (m_strategy(sIdx) ==
'h' || (_minimizer->
fitter()->Result().IsValid()))) {
1191 if (hesseStrategy == -1) {
1194 sIdx = m_hessestrategy.
Index(
'0' + hesseStrategy);
1198 "HesseStrategy %d not specified in HesseStrategySequence %s ... defaulting to start of sequence",
1199 hesseStrategy, m_hessestrategy.
Data());
1202 while (sIdx != -1) {
1203 hesseStrategy =
int(m_hessestrategy(sIdx) -
'0');
1205 if (strategy == 2 && hesseStrategy == 2) {
1207 if (_minimizer->
fitter()->GetMinimizer()->CovMatrixStatus() == 3) {
1210 if (sIdx >= m_hessestrategy.
Length() - 1) {
1217 _minimizer->
fitter()->Config().MinimizerOptions().SetStrategy(hesseStrategy);
1222 fff->fState =
TString::Format(
"Hesse%d", _minimizer->
fitter()->Config().MinimizerOptions().Strategy());
1223 fff->counter2 = fff->counter;
1233 auto _status = _minimizer->
hesse();
1256 statusHistory.push_back(std::pair<std::string, int>(
1257 TString::Format(
"Hesse%d", _minimizer->
fitter()->Config().MinimizerOptions().Strategy()), _status));
1261 throw std::runtime_error(
"Keyboard interrupt while hesse calculating");
1263 if ((_status != 0 || _minimizer->
fitter()->GetMinimizer()->CovMatrixStatus() != 3) && status == 0 &&
1266 _minimizer->
fitter()->GetMinimizer()->CovMatrixStatus())
1270 if (_status == 0 && _minimizer->
fitter()->GetMinimizer()->CovMatrixStatus() == 3) {
1273 }
else if (_status == 0) {
1275 statusHistory.back().second = _minimizer->
fitter()->GetMinimizer()->CovMatrixStatus();
1278 if (sIdx >= m_hessestrategy.
Length() - 1) {
1285 if (
gEnv->
GetValue(
"XRooFit.ResumeInvalidFits",
false) &&
1286 (statusHistory.back().second == 1 || statusHistory.back().second == 2) &&
1287 mini_sIdx < (m_strategy.
Length() - 1)) {
1289 goto resetMinimization;
1294 if (status == 0 &&
minos) {
1295 if (std::unique_ptr<RooAbsCollection> mpars(floatPars->selectByAttrib(
"minos",
true)); !mpars->empty()) {
1297 fff->fState =
"Minos";
1299 fff->prevMin = fff->minVal;
1301 auto _status = _minimizer->
minos(*mpars);
1302 statusHistory.push_back(std::pair(
"Minos", _status));
1307 out = std::unique_ptr<RooFitResult>{_minimizer->
save(fitName, resultTitle)};
1313 if (out->status() == -1 && !_minimizer->
fitter()->Result().IsValid() && _minimizer->
fitter()->Result().Status()) {
1314 out->setStatus(_minimizer->
fitter()->Result().Status());
1319 if (out->status() == 0 && out->covQual() != 3 && hesse) {
1320 if (out->covQual() == 2) {
1328 if (printLevel >= -2 && miniStrat < _minimizer->fitter()->Config().MinimizerOptions().Strategy() && hesse &&
1329 out->edm() > _minimizer->
fitter()->Config().MinimizerOptions().Tolerance() * 1
e-2 && out->status() != 3) {
1332 std::stringstream ss;
1333 ss <<
"Warning: post-Hesse edm " << out->edm()
1334 <<
" > 10xMaxEDM (MaxEDM=" << _minimizer->
fitter()->Config().MinimizerOptions().Tolerance() * 1
e-3
1335 <<
"). Consider increasing your minimization strategy";
1342 out->setStatusHistory(statusHistory);
1345 const_cast<RooArgList &
>(out->constPars()).addClone(fUserPars,
true);
1347 if (!std::isnan(dCovar)) {
1349 .addClone(
RooRealVar(
".dCovar",
"dCovar from minimization", dCovar),
true);
1352 if (boundaryCheck) {
1355 int limit_status = 0;
1356 std::string listpars;
1357 for (
auto *
v : dynamic_range_cast<RooRealVar *>(*floatPars)) {
1360 double vRange =
v->getMax() -
v->getMin();
1361 if (
v->getMin() >
v->getVal() - vRange * boundaryCheck ||
1362 v->getMax() <
v->getVal() + vRange * boundaryCheck) {
1366 auto tmp =
v->getVal();
1367 v->setVal(
v->getMin());
1368 double boundary_nll = _nll->getVal();
1369 if (boundary_nll <= out->minNll()) {
1370 static_cast<RooRealVar *
>(out->floatParsFinal().find(
v->GetName()))->
setVal(
v->getMin());
1371 out->setMinNLL(boundary_nll);
1379 if (
v->hasRange(
"physical"))
1381 listpars +=
v->GetName();
1384 (
v->getMin() >
v->getVal() -
v->getError() ||
v->getMax() <
v->getVal() +
v->getError())) {
1385 if (printLevel >= 0) {
1386 Info(
"minimize",
"PARLIM: %s (%f +/- %f) range (%f - %f)",
v->GetName(),
v->getVal(),
v->getError(),
1387 v->getMin(),
v->getMax());
1389 limit_status = 9000;
1392 if (limit_status == 900) {
1393 if (printLevel >= 0) {
1394 Warning(
"minimize",
"BOUNDCHK: Parameters within %g%% limit in fit result: %s", boundaryCheck * 100,
1397 }
else if (limit_status > 0) {
1398 if (printLevel >= 0)
1399 Warning(
"minimize",
"BOUNDCHK: Parameters near limit in fit result");
1403 statusHistory.emplace_back(
"BOUNDCHK", limit_status);
1404 out->setStatusHistory(statusHistory);
1405 out->setStatus(out->status() + limit_status);
1431 out->setMinNLL(_nll->getVal());
1434 for (
auto o : out->floatParsFinal()) {
1436 v && !
v->
getAttribute(
"minos") && !
v->getAttribute(
"xminos") && !
v->getAttribute(
"xMinos"))
1437 v->removeAsymError();
1441 if (fitConfig.MinimizerOptions().MinimizerType() != actualFirstMinimizer) {
1442 fitConfig.MinimizerOptions().SetMinimizerType(actualFirstMinimizer);
1445 if (_progress && printLevel >= -2) {
1450 if (out && out->status() == 0 &&
minos) {
1452 for (
auto label : {
"xminos",
"xMinos"}) {
1453 std::unique_ptr<RooAbsCollection> pars(floatPars->selectByAttrib(label,
true));
1454 for (
auto p : *pars) {
1455 Info(
"minimize",
"Computing xminos error for %s",
p->
GetName());
1459 *floatPars = out->floatParsFinal();
1464 *floatPars = out->floatParsInit();
1467 if (out && !logs.empty()) {
1469#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 28, 00)
1470 const_cast<RooArgList &
>(out->constPars()).addOwned(std::make_unique<RooStringVar>(
".log",
"log", logs.c_str()));
1476 if (out && cacheDir && cacheDir->
IsWritable()) {
1480 cacheDir->
mkdir(nll.GetName());
1481 if (
auto dir = cacheDir->
GetDirectory(nll.GetName()); dir) {
1484 if (strlen(nllOpts->GetName()) == 0) {
1487 if (!dir->FindKey(nllOpts->GetName())) {
1488 dir->WriteObject(nllOpts.get(), nllOpts->GetName());
1493 std::string configName;
1494 if (!fitConfig.MinimizerOptions().ExtraOptions()->GetValue(
"Name", configName)) {
1495 auto extraOpts =
const_cast<ROOT::Math::IOptions *
>(fitConfig.MinimizerOptions().ExtraOptions());
1497 extraOpts->SetValue(
"Name", configName.data());
1499 if (!dir->GetKey(configName.data())) {
1500 dir->WriteObject(&fitConfig, configName.data());
1503#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 28, 00)
1505 .addOwned(std::make_unique<RooStringVar>(
".fitConfigName",
"fitConfigName", configName.c_str()));
1508 .addOwned(*
new RooStringVar(
".fitConfigName",
"fitConfigName", configName.c_str()));
1510 dir->WriteObject(out.get(), out->GetName());
1524 const std::shared_ptr<ROOT::Fit::FitConfig> &_fitConfig)
1527 auto par =
dynamic_cast<RooRealVar *
>(std::unique_ptr<RooArgSet>(nll.getVariables())->find(parName));
1536 auto &fitConfig = *myFitConfig;
1538 bool pErrs = fitConfig.ParabErrors();
1539 fitConfig.SetParabErrors(
false);
1540 double mErrs = fitConfig.MinosErrors();
1541 fitConfig.SetMinosErrors(
false);
1543 double val_best = par_hat->getVal();
1544 double val_err = (par_hat->hasError() ? par_hat->getError() : -1);
1545 double orig_err = val_err;
1546 double nll_min = ufit.
minNll();
1550 bool isConst = par->isConstant();
1551 par->setConstant(
true);
1553 auto findValue = [&](
double val_guess,
double N_sigma = 1,
double precision = 0.002,
int printLevel = 0) {
1556 double sigma_guess = std::abs((val_guess - val_best) / N_sigma);
1559 10 * precision * sigma_guess;
1560 bool lastOverflow =
false;
1561 bool lastUnderflow =
false;
1562 while (std::abs(val_pre - val_guess) > precision * sigma_guess) {
1563 val_pre = val_guess;
1564 if (val_guess > 0 && par->getMax() < val_guess)
1565 par->setMax(2 * val_guess);
1566 if (val_guess < 0 && par->getMin() > val_guess)
1567 par->setMin(2 * val_guess);
1568 par->setVal(val_guess);
1573 return std::numeric_limits<double>::quiet_NaN();
1575 double nll_val =
result->minNll();
1576 status +=
result->status() * 10;
1577 tmu = 2 * (nll_val - nll_min);
1578 sigma_guess = std::abs(val_guess - val_best) / sqrt(tmu);
1582 std::cout <<
"Warning: Alternative best-fit of " << par->GetName() <<
" @ " << val_guess <<
" vs "
1583 << val_best <<
" (delta=" << tmu / 2. <<
")" << std::endl;
1584 double new_guess = val_guess + (val_guess - val_best);
1585 val_best = val_guess;
1586 val_guess = new_guess;
1587 sigma_guess = std::abs((val_guess - val_best) / N_sigma);
1588 val_pre = val_guess - 10 * precision * sigma_guess;
1589 status = (status / 10) * 10 + 1;
1593 double corr = (val_pre - val_best - N_sigma * sigma_guess);
1598 if (printLevel > 1) {
1602 std::cout <<
"NLL min: " << nll_min << std::endl;
1603 std::cout <<
"N_sigma*sigma(pre): " << std::abs(val_pre - val_best) << std::endl;
1604 std::cout <<
"sigma(guess): " << sigma_guess << std::endl;
1605 std::cout <<
"par(guess): " << val_guess + corr << std::endl;
1606 std::cout <<
"true val: " << val_best << std::endl;
1607 std::cout <<
"tmu: " << tmu << std::endl;
1608 std::cout <<
"Precision: " << sigma_guess * precision << std::endl;
1609 std::cout <<
"Correction: " << (-corr < 0 ?
" " :
"") << -corr << std::endl;
1610 std::cout <<
"N_sigma*sigma(guess): " << std::abs(val_guess - val_best) << std::endl;
1611 std::cout << std::endl;
1613 if (val_guess > par->getMax()) {
1615 val_guess = par->getMin();
1618 lastOverflow =
true;
1619 lastUnderflow =
false;
1620 val_guess = par->getMax() - 1
e-12;
1621 }
else if (val_guess < par->getMin()) {
1622 if (lastUnderflow) {
1623 val_guess = par->getMin();
1626 lastOverflow =
false;
1627 lastUnderflow =
true;
1628 val_guess = par->getMin() + 1
e-12;
1630 lastUnderflow =
false;
1631 lastOverflow =
false;
1636 status = (status / 10) * 10 + 3;
1644 status = (status / 10) * 10 + 2;
1645 }
else if (lastUnderflow) {
1648 status = (status / 10) * 10 + 2;
1652 std::cout <<
"Found sigma for nll " << nll.GetName() <<
": " << (val_guess - val_best) / N_sigma << std::endl;
1654 std::cout <<
"Finished in " << nrItr <<
" iterations." << std::endl;
1656 std::cout << std::endl;
1657 return (val_guess - val_best) / N_sigma;
1662 par_hat->setError(std::numeric_limits<double>::quiet_NaN());
1663 double lo = par_hat->getErrorLo();
1664 double hi = par_hat->getErrorHi();
1665 if (std::isnan(
hi)) {
1666 hi = findValue(val_best + val_err, 1) + val_best -
1671 if (std::isnan(lo)) {
1672 lo = -findValue(val_best - val_err, -1) + val_best -
1678 fitConfig.SetParabErrors(pErrs);
1679 fitConfig.SetMinosErrors(mErrs);
1680 par->setConstant(isConst);
1682 std::vector<std::pair<std::string, int>> statusHistory;
1686 statusHistory.emplace_back(
TString::Format(
"xMinos:%s", parName), status);
1687 const_cast<RooFitResult &
>(ufit).setStatusHistory(statusHistory);
1700 std::deque<RooAbsArg *> topPdfs;
1702 for (
auto p :
w.allPdfs()) {
1703 if (
p->hasClients())
1705 flagCount +=
p->getAttribute(
"hypoTest");
1706 if (
p->getAttribute(
"hypoTest")) {
1707 topPdfs.push_front(
p);
1709 topPdfs.push_back(
p);
1712 if (topPdfs.empty()) {
1713 Error(
"hypoTest",
"Cannot find top-level pdf in workspace");
1715 }
else if (topPdfs.size() > 1) {
1717 if (flagCount == 0) {
1718 Error(
"hypoTest",
"Multiple top-level pdfs. Flag which one to test with "
1719 "w->pdf(\"pdfName\")->setAttribute(\"hypoTest\",true)");
1721 }
else if (flagCount != 1) {
1722 Error(
"hypoTest",
"Multiple top-level pdfs flagged for hypoTest -- pick one.");
1728 Info(
"hypoTest",
"Using PDF: %s", model->GetName());
1734 std::shared_ptr<RooArgSet> obsGlobs =
nullptr;
1736 for (
auto p :
w.allData()) {
1738 Error(
"hypoTest",
"Multiple datasets in workspace. Flag which one to test with "
1739 "w->data(\"dataName\")->setAttribute(\"hypoTest\",true)");
1746 Error(
"hypoTest",
"No data -- cannot determine observables");
1750 Info(
"hypoTest",
"Using Dataset: %s", obsData->
GetName());
1753 auto _globs = xRooNode(
w).datasets()[obsData->
GetName()]->globs();
1754 obsGlobs = std::make_shared<RooArgSet>();
1755 obsGlobs->addClone(_globs.argList());
1756 Info(
"hypoTest",
"Using Globs: %s", (obsGlobs->empty()) ?
" <NONE>" : obsGlobs->contentsString().c_str());
1761 auto _vars = std::unique_ptr<RooArgSet>(model->getVariables());
1764 for (
auto _v : *_vars) {
1769 if (poi.
size() > 1) {
1770 auto _const = std::unique_ptr<RooAbsCollection>(poi.
selectByAttrib(
"Constant",
true));
1774 if (!args.
empty()) {
1778 Error(
"hypoTest",
"No POI detected: add the hypoPoints binning to at least one non-const model parameter e.g.:\n "
1779 "w->var(\"mu\")->setBinning(RooUniformBinning(0.5,10.5,10),\"hypoPoints\"))");
1791 xRooNLLVar
nll(*model, std::make_pair(obsData, obsGlobs.get()), *nllOpts);
1792 nll.SetFitConfig(fitConfig);
1794 if (poi.
size() == 1) {
1797 double altVal = (mu->getStringAttribute(
"altVal")) ?
TString(mu->getStringAttribute(
"altVal")).Atof()
1798 : std::numeric_limits<double>::quiet_NaN();
1800 if (std::isnan(altVal) && mu->hasRange(
"physical")) {
1802 altVal = mu->getMin(
"physical");
1803 Info(
"hypoTest",
"No altVal specified - using min of given physical range = %g", altVal);
1805 if (!std::isnan(altVal)) {
1806 Info(
"hypoTest",
"alt hypo: %g - CLs activated", altVal);
1808 Info(
"hypoTest",
"No altVal found - to specify setStringAttribute(\"altVal\",\"<value>\") on POI or set "
1809 "the physical range");
1812 bool doCLs = !std::isnan(altVal) && std::abs(mu->getMin(
"hypoPoints")) > altVal &&
1813 std::abs(mu->getMax(
"hypoPoints")) > altVal;
1815 const char *sCL = (doCLs) ?
"CLs" :
"null";
1816 Info(
"hypoTest",
"%s testing active", sCL);
1826 std::vector<int> expSig = {-2, -1, 0, 1, 2};
1827 if (std::isnan(altVal))
1829 std::map<int, TGraphErrors> exp_pcls;
1830 std::map<int, TGraphErrors> exp_cls;
1831 for (
auto &s : expSig) {
1833 TString::Format(
"Expected (%d#sigma) p_{%s};%s", s, sCL, mu->GetTitle()));
1835 TString::Format(
"Expected (%d#sigma) %s;%s", s, sCL, mu->GetTitle()));
1839 double _out = std::numeric_limits<double>::quiet_NaN();
1840 bool lastAbove =
false;
1841 for (
int i = 0; i < pValues.GetN(); i++) {
1842 bool thisAbove = pValues.GetPointY(i) >= (1. - CL);
1843 if (i != 0 && thisAbove != lastAbove) {
1846 _out = pValues.GetPointX(i - 1) + (pValues.GetPointX(i) - pValues.GetPointX(i - 1)) *
1847 ((1. - CL) - pValues.GetPointY(i - 1)) /
1848 (pValues.GetPointY(i) - pValues.GetPointY(i - 1));
1850 lastAbove = thisAbove;
1855 auto testPoint = [&](
double testVal) {
1856 auto hp =
nll.hypoPoint(mu->GetName(), testVal, altVal, pllType);
1857 obs_ts->SetPoint(obs_ts->GetN(), testVal, hp.pll().first);
1858 obs_ts->SetPointError(obs_ts->GetN() - 1, 0, hp.pll().second);
1860 if (nToysNull > 0) {
1863 obs_pcls->SetPoint(obs_pcls->GetN(), testVal, (doCLs) ? hp.pCLs_asymp().first : hp.pNull_asymp().first);
1864 obs_pcls->SetPointError(obs_pcls->GetN() - 1, 0, (doCLs) ? hp.pCLs_asymp().second : hp.pNull_asymp().second);
1865 for (
auto &s : expSig) {
1866 exp_pcls[s].SetPoint(exp_pcls[s].GetN(), testVal,
1867 (doCLs) ? hp.pCLs_asymp(s).first : hp.pNull_asymp(s).first);
1870 Info(
"hypoTest",
"%s=%g: %s=%g sigma_mu=%g %s=%g", mu->GetName(), testVal, obs_ts->GetName(),
1871 obs_ts->GetPointY(obs_ts->GetN() - 1), hp.sigma_mu().first, obs_pcls->GetName(),
1872 obs_pcls->GetPointY(obs_pcls->GetN() - 1));
1874 Info(
"hypoTest",
"%s=%g: %s=%g %s=%g", mu->GetName(), testVal, obs_ts->GetName(),
1875 obs_ts->GetPointY(obs_ts->GetN() - 1), obs_pcls->GetName(), obs_pcls->GetPointY(obs_pcls->GetN() - 1));
1879 if (mu->getBins(
"hypoPoints") <= 0) {
1882 testPoint(mu->getMin(
"hypoPoints"));
1883 testPoint(mu->getMax(
"hypoPoints"));
1884 testPoint((mu->getMax(
"hypoPoints") + mu->getMin(
"hypoPoints")) / 2.);
1886 while (std::abs(obs_pcls->GetPointY(obs_pcls->GetN() - 1) - (1. - CL)) > 0.01) {
1888 double nextTest = getLimit(*obs_pcls);
1889 if (std::isnan(nextTest))
1891 testPoint(nextTest);
1893 for (
auto s : expSig) {
1894 while (std::abs(exp_pcls[s].GetPointY(exp_pcls[s].GetN() - 1) - (1. - CL)) > 0.01) {
1896 double nextTest = getLimit(exp_pcls[s]);
1897 if (std::isnan(nextTest))
1899 testPoint(nextTest);
1904 for (
auto &s : expSig)
1908 for (
int i = 0; i <= mu->getBins(
"hypoPoints"); i++) {
1909 testPoint((i == mu->getBins(
"hypoPoints")) ? mu->getBinning(
"hypoPoints").binHigh(i - 1)
1910 : mu->getBinning(
"hypoPoints").binLow(i));
1914 obs_cls->SetPoint(obs_cls->GetN(), getLimit(*obs_pcls), 0.05);
1915 for (
auto &s : expSig) {
1916 exp_cls[s].SetPoint(exp_cls[s].GetN(), getLimit(exp_pcls[s]), 0.05);
1920 if (exp_pcls[2].GetN() > 1) {
1926 band2down->
SetNameTitle(
".pCLs_2sigma_downUncert",
"");
1932 for (
int i = 0; i < exp_pcls[2].GetN(); i++) {
1933 band2->
SetPoint(band2->
GetN(), exp_pcls[2].GetPointX(i),
1934 exp_pcls[2].GetPointY(i) - exp_pcls[2].GetErrorYlow(i));
1935 band2up->
SetPoint(band2up->
GetN(), exp_pcls[2].GetPointX(i),
1936 exp_pcls[2].GetPointY(i) + exp_pcls[2].GetErrorYhigh(i));
1938 for (
int i = exp_pcls[2].GetN() - 1; i >= 0; i--) {
1939 band2up->
SetPoint(band2up->
GetN(), exp_pcls[2].GetPointX(i),
1940 exp_pcls[2].GetPointY(i) - exp_pcls[2].GetErrorYlow(i));
1942 for (
int i = 0; i < exp_pcls[-2].GetN(); i++) {
1943 band2down->
SetPoint(band2down->
GetN(), exp_pcls[-2].GetPointX(i),
1944 exp_pcls[-2].GetPointY(i) + exp_pcls[-2].GetErrorYhigh(i));
1946 for (
int i = exp_pcls[-2].GetN() - 1; i >= 0; i--) {
1947 band2->
SetPoint(band2->
GetN(), exp_pcls[-2].GetPointX(i),
1948 exp_pcls[-2].GetPointY(i) + exp_pcls[-2].GetErrorYhigh(i));
1949 band2down->
SetPoint(band2down->
GetN(), exp_pcls[-2].GetPointX(i),
1950 exp_pcls[-2].GetPointY(i) - exp_pcls[-2].GetErrorYlow(i));
1955 auto ax =
static_cast<TNamed *
>(band2->
Clone(
".axis"));
1960 band2down->
Draw(
"F");
1963 if (exp_pcls[1].GetN() > 1) {
1969 band2down->
SetNameTitle(
".pCLs_1sigma_downUncert",
"");
1975 for (
int i = 0; i < exp_pcls[1].GetN(); i++) {
1976 band2->
SetPoint(band2->
GetN(), exp_pcls[1].GetPointX(i),
1977 exp_pcls[1].GetPointY(i) - exp_pcls[1].GetErrorYlow(i));
1978 band2up->
SetPoint(band2up->
GetN(), exp_pcls[1].GetPointX(i),
1979 exp_pcls[1].GetPointY(i) + exp_pcls[1].GetErrorYhigh(i));
1981 for (
int i = exp_pcls[1].GetN() - 1; i >= 0; i--) {
1982 band2up->
SetPoint(band2up->
GetN(), exp_pcls[1].GetPointX(i),
1983 exp_pcls[1].GetPointY(i) - exp_pcls[1].GetErrorYlow(i));
1985 for (
int i = 0; i < exp_pcls[-1].GetN(); i++) {
1986 band2down->
SetPoint(band2down->
GetN(), exp_pcls[-1].GetPointX(i),
1987 exp_pcls[-1].GetPointY(i) + exp_pcls[-1].GetErrorYhigh(i));
1989 for (
int i = exp_pcls[-1].GetN() - 1; i >= 0; i--) {
1990 band2->
SetPoint(band2->
GetN(), exp_pcls[-1].GetPointX(i),
1991 exp_pcls[-1].GetPointY(i) + exp_pcls[-1].GetErrorYhigh(i));
1992 band2down->
SetPoint(band2down->
GetN(), exp_pcls[-1].GetPointX(i),
1993 exp_pcls[-1].GetPointY(i) - exp_pcls[-1].GetErrorYlow(i));
2000 band2down->
Draw(
"F");
2004 if (exp_cls[0].GetN() > 0) {
2005 exp_pcls[0].SetLineStyle(2);
2006 exp_pcls[0].SetFillColor(
kGreen);
2007 exp_pcls[0].SetMarkerStyle(0);
2008 expPlot = exp_pcls[0].DrawClone(
"L");
2011 obs_pcls->Draw(
gPad->GetListOfPrimitives()->IsEmpty() ?
"ALP" :
"LP");
2013 obs_ts->SetLineColor(
kRed);
2014 obs_ts->SetMarkerColor(
kRed);
2018 auto l =
new TLegend(0.5, 0.6, 1. -
gPad->GetRightMargin(), 1. -
gPad->GetTopMargin());
2019 l->SetName(
"legend");
2020 l->AddEntry(obs_ts, obs_ts->GetTitle(),
"LPE");
2021 l->AddEntry(obs_pcls, obs_pcls->GetTitle(),
"LPE");
2023 l->AddEntry(expPlot,
"Expected",
"LFE");
2027 obs_cls->SetMarkerStyle(29);
2028 obs_cls->SetEditable(
false);
2029 obs_cls->Draw(
"LP");
2030 for (
auto s : expSig) {
2031 exp_cls[s].SetMarkerStyle(29);
2032 exp_cls[s].SetEditable(
false);
2033 exp_cls[s].DrawClone(
"LP");
2047 double factor = pow(10.0, digits - ceil(log10(std::abs(
value))));
2048 return std::round(
value * factor) / factor;
2052 const double multiplier = std::pow(10.0, decimal_places);
2053 return std::round(
value * multiplier) / multiplier;
2060 if (!std::isinf(out.second)) {
2061 auto tmp = out.second;
2063 int expo = (out.second == 0) ? 0 : (
int)std::floor(std::log10(std::abs(out.second)));
2066 out.first = (expo >= 0) ? round(out.first) :
round_to_decimal(out.first, -expo);
2067 }
else if (out.second != 0) {
2068 out.first = (expo >= 0) ? round(out.first) :
round_to_decimal(out.first, -expo + 1);
static void indent(ostringstream &buf, int indent_level)
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
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
R__EXTERN TSystem * gSystem
double getValV(const RooArgSet *) const override
Return value of object.
double evaluate() const override
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
bool setData(RooAbsData &data, bool cloneData) override
ProgressMonitor(const ProgressMonitor &other, const char *name=nullptr)
~ProgressMonitor() override
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Interface for detailed printing of object.
TObject * clone(const char *newname) const override
std::shared_ptr< RooAbsCollection > vars
bool getParameters(const RooArgSet *observables, RooArgSet &outputSet, bool stripDisconnected) const override
Fills a list with leaf nodes in the arg tree starting with ourself as top node that don't match any o...
void applyWeightSquared(bool flag) override
Disables or enables the usage of squared weights.
ProgressMonitor(RooAbsReal &f, int interval=30)
static ProgressMonitor * me
double defaultErrorLevel() const override
static void interruptHandler(int signum)
StoredFitResult(RooFitResult *_fr)
std::shared_ptr< RooFitResult > fr
!
static int minos(RooAbsReal &nll, const RooFitResult &ufit, const char *parName="", const std::shared_ptr< ROOT::Fit::FitConfig > &_fitConfig=nullptr)
static std::shared_ptr< const RooFitResult > minimize(RooAbsReal &nll, const std::shared_ptr< ROOT::Fit::FitConfig > &fitConfig=nullptr, const std::shared_ptr< RooLinkedList > &nllOpts=nullptr)
static std::shared_ptr< RooLinkedList > createNLLOptions()
static TCanvas * hypoTest(RooWorkspace &w, const xRooFit::Asymptotics::PLLType &pllType=xRooFit::Asymptotics::Unknown)
static std::shared_ptr< ROOT::Fit::FitConfig > createFitConfig()
static std::pair< double, double > matchPrecision(const std::pair< double, double > &in)
This xRooNLLVar object has several special methods, e.g.
xRooFitResult minimize(const std::shared_ptr< ROOT::Fit::FitConfig > &=nullptr)
Class describing the configuration of the fit, options and parameter settings using the ROOT::Fit::Pa...
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
Common abstract base class for objects that represent a value and a "shape" in RooFit.
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.
RooWorkspace * _myws
! In which workspace do I live, if any
bool isConstant() const
Check if the "Constant" attribute is set.
RooFit::OwningPtr< RooArgSet > getParameters(const RooAbsData *data, bool stripDisconnected=true) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
RooWorkspace * workspace() const
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 expression tree)
virtual void applyWeightSquared(bool flag)
Disables or enables the usage of squared weights.
RooAbsArg * findServer(const char *name) const
Return server of this with name name. Returns nullptr if not found.
A space to attach TBranches.
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 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.
void assignFast(const RooAbsCollection &other, bool setValDirty=true) const
Functional equivalent of assign() but assumes this and other collection have same layout.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
void setAttribAll(const Text_t *name, bool value=true)
Set given attribute in each element of the collection by calling each elements setAttribute() functio...
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.
Abstract base class for binned and unbinned datasets.
Abstract interface for all probability density functions.
Abstract base class for objects that represent a real value and implements functionality common to al...
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
virtual double defaultErrorLevel() const
virtual bool setData(RooAbsData &, bool=true)
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Structure printing.
RooArgList is a container object that can hold multiple RooAbsArg objects.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
RooArgSet * selectByAttrib(const char *name, bool value) const
Use RooAbsCollection::selectByAttrib(), but return as RooArgSet.
Implements a RooAbsBinning in terms of an array of boundary values, posing no constraints on the choi...
Named container for two doubles, two integers two object points and three string pointers that can be...
Container class to hold unbinned data.
RooRealVar * weightVar() const
Returns a pointer to the weight variable (if set).
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.
Collection class for internal use, storing a collection of RooAbsArg pointers in a doubly linked list...
Wrapper class around ROOT::Math::Minimizer that provides a seamless interface between the minimizer f...
auto fitter()
Return underlying ROOT fitter object.
RooFit::OwningPtr< RooFitResult > save(const char *name=nullptr, const char *title=nullptr)
Save and return a RooFitResult snapshot of current minimizer status.
int minos()
Execute MINOS.
int hesse()
Execute HESSE.
int minimize(const char *type, const char *alg=nullptr)
Minimise the function passed in the constructor.
void setStrategy(int istrat)
Change MINUIT strategy to istrat.
static RooMsgService & instance()
Return reference to singleton instance.
void setGlobalKillBelow(RooFit::MsgLevel level)
RooFit::MsgLevel globalKillBelow() const
Implementation of a RooCacheManager<RooAbsCacheElement> that specializes in the storage of cache elem...
void setNoRounding(bool flag=true)
Switch off/on rounding of x to the nearest integer.
Efficient implementation of a product of PDFs of the form.
static TRandom * randomGenerator()
Return a pointer to a singleton random-number generator implementation.
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'.
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...
A RooAbsArg implementing string values.
Joins several RooAbsCategoryLValue objects into a single category.
bool setIndex(value_type index, bool printError=true) override
Set the value of the super category to the specified index.
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.
Using a TBrowser one can browse all ROOT objects.
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.
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/...".
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
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.
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
const char * GetName() const override
Returns name of object.
Mother of all ROOT objects.
virtual const char * GetName() const
Returns name of object.
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
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
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 WeightVar(const char *name="weight", bool reinterpretAsWeight=false)
RooCmdArg Offset(std::string const &mode)
RooCmdArg Extended(bool flag=true)
RooCmdArg ExpectedData(bool flag=true)
double nll(double pdf, double weight, int binnedL, int doBinOffset)
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.
void writeStdoutLine(const char *msg)
bool isPythonInitialized()
void writeStderrLine(const char *msg)
#define BEGIN_XROOFIT_NAMESPACE
#define END_XROOFIT_NAMESPACE
double round_to_decimal(double value, int decimal_places)
void printCout(const char *msg)
void printCerr(const char *msg)
double round_to_digits(double value, int digits)