47#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
49#define protected public
70#define GETWS(a) a->_myws
71#define GETWSSETS(w) w->_namedSets
72#define GETWSSNAPSHOTS(w) w->_snapshots
73#define GETACTBROWSER(b) b->fActBrowser
74#define GETROOTDIR(b) b->fRootDir
75#define GETLISTTREE(b) b->fListTree
76#define GETDMP(o, m) o->m
101 return a->workspace();
109 return w->getSnapshots();
113 return b->GetActBrowser();
117 return b->GetRootDir();
121 return b->GetListTree();
123#define GETDMP(o, m) \
124 *reinterpret_cast<void **>(reinterpret_cast<unsigned char *>(o) + o->Class()->GetDataMemberOffset(#m))
175#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
179#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 24, 00)
208#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
214xRooNode::InteractiveObject *xRooNode::gIntObj =
nullptr;
215std::map<std::string, std::tuple<std::function<
double(
double,
double,
double)>,
bool>> xRooNode::auxFunctions;
216void xRooNode::SetAuxFunction(
const char *title,
const std::function<
double(
double,
double,
double)> &func,
219 auxFunctions[title] = std::make_tuple(func, symmetrize);
238xRooNode::xRooNode(
const char *classname,
const char *
name,
const char *title)
244#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
247 xRooNode(*
w, std::make_shared<xRooNode>()).sterilize();
253 if (
auto a = get<TNamed>();
a)
258xRooNode::xRooNode(
const char *
name,
const std::shared_ptr<TObject> &comp,
const std::shared_ptr<xRooNode> &parent)
259 :
TNamed(
name,
""), fComp(comp), fParent(parent)
269#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
270 fComp = std::make_shared<RooWorkspace>(
"workspace",
name);
275 Error(
"xRooNode",
"Error reading json workspace %s",
name);
280 Error(
"xRooNode",
"json format workspaces available only in ROOT 6.26 onwards");
286 auto _file = std::make_shared<TFile>(
291 auto keys = _file->GetListOfKeys();
293 for (
auto &&k : *keys) {
299#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
300 dynamic_cast<RooWorkspace *>(ws)->_embeddedDataList.Delete();
302 xRooNode(*ws, std::make_shared<xRooNode>()).sterilize();
308 fParent = std::make_shared<xRooNode>(
316 }
else if (pathName.EndsWith(
".root") || pathName.EndsWith(
".json")) {
321 if (
auto _ws = get<RooWorkspace>(); _ws && (!parent || parent->get<
TFile>())) {
328 for (
auto f : *
gROOT->GetListOfFiles()) {
329 if ((
dynamic_cast<TFile *
>(
f)->GetVersion() / 100) > (
gROOT->GetVersionInt() / 100)) {
330 Warning(
"xRooNode",
"There is file open with version %d > current version %d ... results may be wrong",
331 dynamic_cast<TFile *
>(
f)->GetVersion(),
gROOT->GetVersionInt());
337 for (
auto &
d : _ws->allData()) {
338 for (
auto &
a : *
d->get()) {
339 if (
auto v = _ws->var(
a->GetName());
v) {
340 v->setAttribute(
"obs");
341 }
else if (
auto c = _ws->cat(
a->GetName());
c) {
342 c->setAttribute(
"obs");
346 checkCount +=
d->TestBit(1 << 20);
349 if (checkCount == 0 && !_ws->allData().empty())
350 _ws->allData().back()->SetBit(1 << 20,
true);
353 for (
auto s : *_set) {
355 _ws->var(s->GetName())->setStringAttribute(
"nominal",
TString::Format(
"%f",
v->getVal()));
363 if (k ==
"globalObservables" ||
TString(k).
EndsWith(
"_GlobalObservables")) {
366 s->setAttribute(
"obs");
367 s->setAttribute(
"global");
370 const_cast<RooArgSet &
>(
v).setAttribAll(
"obs");
373 s->setAttribute(
"poi");
385 const_cast<RooArgSet &
>(
v).setAttribAll(
"np");
388 if (!_allGlobs.
empty() &&
GETWSSETS(_ws).count(
"globalObservables") == 0) {
389 _ws->defineSet(
"globalObservables", _allGlobs);
394 if (!_ws->allPdfs().empty()) {
395 std::set<RooRealVar *> noErrorPars;
396 std::string parNames;
397 for (
auto &
p :
np()) {
401 if (!
v->hasError()) {
402 noErrorPars.insert(
v);
403 if (!parNames.empty())
408 if (!noErrorPars.empty()) {
410 "Inferring initial errors of %d parameters (%s%s) (give all nuisance parameters an error to avoid "
412 int(noErrorPars.size()), (*noErrorPars.begin())->GetName(), (noErrorPars.size() > 1) ?
",..." :
"");
415 for (
auto &
a : *this) {
416 if (noErrorPars.empty()) {
419 if (
a->fFolder ==
"!pdfs") {
421 auto fr =
a->floats().reduced(parNames).fitResult(
"prefit");
423 std::set<RooRealVar *> foundPars;
424 for (
auto &
v : noErrorPars) {
425 if (
auto arg =
dynamic_cast<RooRealVar *
>(_fr->floatParsFinal().find(
v->GetName()));
426 arg && arg->hasError()) {
427 v->setError(arg->getError());
431 for (
auto &
v : foundPars) {
432 noErrorPars.erase(
v);
443 if (strlen(GetTitle()) == 0) {
460 (comp.InheritsFrom(
"RooAbsArg") && dynamic_cast<const
RooAbsArg *>(&comp)->getStringAttribute(
"alias"))
461 ? dynamic_cast<const
RooAbsArg *>(&comp)->getStringAttribute(
"alias")
470 if (
auto a = std::dynamic_pointer_cast<RooAbsArg>(comp);
a &&
a->getStringAttribute(
"alias"))
471 return a->getStringAttribute(
"alias");
473 return comp->GetName();
491 if (
auto o = get<RooAbsReal>(); o) {
492 if (o->isSelectedComp() && !val) {
495 o->setAttribute(
"hidden");
496 }
else if (!o->isSelectedComp() && !val) {
501 o->setAttribute(
"hidden",
false);
504 item->CheckItem(!o->getAttribute(
"hidden"));
505 if (o->isSelectedComp()) {
508 item->SetColor(
kGray);
513 if (
auto o =
get(); o) {
515 o->SetBit(1 << 20, val);
516 if (
auto fr = get<RooFitResult>(); fr) {
517 if (
auto _ws =
ws(); _ws) {
520 if (!_ws->genobj(fr->GetName())) {
522 if (
auto wfr =
dynamic_cast<RooFitResult *
>(_ws->genobj(fr->GetName()))) {
527 _allVars = fr->floatParsFinal();
528 _allVars = fr->constPars();
529 for (
auto &i : fr->floatParsInit()) {
535 for (
auto oo : _ws->allGenericObjects()) {
536 if (
auto ffr =
dynamic_cast<RooFitResult *
>(oo); ffr && ffr != fr) {
537 ffr->ResetBit(1 << 20);
541 _ws->allVars() = fr->floatParsInit();
545 if (
auto first = item->GetParent()->GetFirstChild()) {
547 if (first->HasCheckBox()) {
548 auto _obj =
static_cast<xRooNode *
>(first->GetUserData());
549 first->CheckItem(_obj->get() && _obj->get()->TestBit(1 << 20));
551 }
while ((first = first->GetNextSibling()));
560 static bool blockBrowse =
false;
564 auto b2 =
dynamic_cast<TBrowser *
>(
gROOT->GetListOfBrowsers()->Last());
565 if (!b2 || !b2->GetBrowserImp()) {
572 b2 =
new TBrowser(
"nodeBrowser",
this,
"RooFit Browser");
574 }
else if (strcmp(b2->GetName(),
"nodeBrowser") == 0) {
576 b2->BrowseObject(
this);
588 _b->GotoDir(
nullptr);
599 if (
auto first = item->GetFirstChild()) {
601 if (first->HasCheckBox()) {
602 auto _obj =
static_cast<xRooNode *
>(first->GetUserData());
603 first->CheckItem(_obj->get() &&
604 (_obj->get()->TestBit(1 << 20) ||
607 }
while ((first = first->GetNextSibling()));
618 if (
auto _fr = get<RooFitResult>(); _fr &&
fBrowsables.empty()) {
620 fBrowsables.push_back(std::make_shared<xRooNode>(
".Draw(\"pull\")",
nullptr, *
this));
621 fBrowsables.push_back(std::make_shared<xRooNode>(
".Draw(\"corrcolztext\")",
nullptr, *
this));
622 if (std::unique_ptr<RooAbsCollection>(_fr->floatParsFinal().selectByAttrib(
"poi",
true))->size() == 1) {
623 fBrowsables.push_back(std::make_shared<xRooNode>(
".Draw(\"impact\")",
nullptr, *
this));
629 if (
auto s = get<TStyle>()) {
630 s->SetFillAttributes();
637 Draw(
b->GetDrawOption());
639 }
catch (
const std::exception &
e) {
642 (
gROOT->GetListOfBrowsers()->At(0))
645 "Exception",
e.what(),
650 bool hasFolders =
false;
652 for (
auto &
c : *
this) {
653 if (!
c->fFolder.empty()) {
662 auto _folders =
find(
".folders");
664 _folders = emplace_back(std::make_shared<xRooNode>(
".folders",
nullptr, *
this));
667 for (
auto &
v : *
this) {
668 if (!
v->fFolder.empty() && !_folders->find(
v->fFolder,
false)) {
669 _folders->emplace_back(std::make_shared<xRooNode>(
v->fFolder.c_str(),
nullptr, *
this));
673 for (
auto &
v : *_folders) {
676 _name = _name(1, _name.
Length());
677 b->Add(
v.get(), _name);
681 for (
auto &
v : *
this) {
682 if (hasFolders && !
v->fFolder.empty())
684 if (strcmp(
v->GetName(),
".folders") == 0)
688 if (_fr && ((_fr->status() == 0 && _fr->numStatusHistory() == 0) || (_fr->floatParsFinal().empty()))) {
692 if (
v->get<
RooAbsPdf>() && get<RooSimultaneous>())
696 _name = _name(strlen(
v->get()->ClassName()) + 2, _name.
Length());
704 :
v->get()->GetName());
706 }
else if (
v->get() && !
v->get<
TFile>() && !
TString(
v->GetName()).BeginsWith(
'/'))
708 if (
auto _type =
v->GetNodeType(); strlen(_type)) {
716 for (
size_t i = 0; i < fv->dependents().
size(); i++) {
722 for (
size_t i = 0; i < gv->dependents().
size(); i++) {
729 TString nameSave(
v->TNamed::GetName());
730 TString titleSave(
v->TNamed::GetTitle());
731 if (
auto o =
v->get(); o)
732 v->TNamed::SetNameTitle(o->GetName(), o->ClassName());
733 b->Add(
v.get(), _name, _checked);
734 if (
auto o =
v->get(); o)
735 v->TNamed::SetNameTitle(nameSave, titleSave);
736 if (_checked != -1) {
737 dynamic_cast<TQObject *
>(
b->GetBrowserImp())
738 ->Connect(
"Checked(TObject *, bool)",
ClassName(),
v.get(),
"Checked(TObject *, bool)");
741 if (_fr->status() || _fr->covQual() != 3) {
742 v->GetTreeItem(
b)->SetColor((_fr->numStatusHistory() || _fr->floatParsFinal().empty()) ?
kRed :
kBlue);
743 }
else if (_fr->numStatusHistory() == 0) {
744 v->GetTreeItem(
b)->SetColor(
kGray);
747 if ((
v->fFolder ==
"!np" ||
v->fFolder ==
"!poi")) {
749 v->GetTreeItem(
b)->SetColor(
kGray);
751 v->GetTreeItem(
b)->ClearColor();
755 if (
auto fits = _htr->GetFitInfo()) {
756 for (
int i = 0; i < fits->numEntries(); i++) {
758 if (fits->get(i)->getCatIndex(
"type") != 5 && fits->get(i)->getRealValue(
"status") != 0) {
759 v->GetTreeItem(
b)->SetColor(
kRed);
764 v->GetTreeItem(
b)->SetColor(
kBlue);
791 if (_name ==
".memory")
793 TString nameSave(
v->TNamed::GetName());
794 TString titleSave(
v->TNamed::GetTitle());
795 if (
auto o =
v->get(); o)
796 v->TNamed::SetNameTitle(o->GetName(), o->ClassName());
797 b->Add(
v.get(), _name, -1);
798 if (
auto o =
v->get(); o)
799 v->TNamed::SetNameTitle(nameSave, titleSave);
802 b->SetSelected(
this);
815 auto v = std::make_shared<xRooNode>(
vars());
826 if (strcmp(
b->GetName(),
".vars") == 0)
849 if (
auto v = var();
v)
850 return v->getBinWidth(bin - 1, GetName());
855 if (
auto v = rvar();
v) {
856 return (bin ==
v->getBinning(GetName()).numBins() + 1) ?
v->getBinning(GetName()).binHigh(bin - 2)
857 :
v->getBinning(GetName()).binLow(bin - 1);
863 if (
auto v = rvar();
v)
864 return (bin == 0) ?
v->getBinning(GetName()).binLow(bin) :
v->getBinning(GetName()).binHigh(bin - 1);
870 return (binning() && strlen(binning()->GetTitle())) ? binning()->GetTitle() : GetParent()->GetTitle();
877 dynamic_cast<TNamed *
>(GetParent())->SetTitle(title);
881 void Set(
Int_t nbins,
const double *xbins)
override
884 v->setBinning(
RooBinning(nbins, xbins), GetName());
889 std::vector<double> bins(nbins + 1);
890 for (
int i = 0; i <= nbins; i++)
891 bins.at(i) = xbins[i];
892 return Set(nbins, &bins[0]);
904 Int_t FindFixBin(
double x)
const override {
return (binning()) ? (binning()->binNumber(
x) + 1) :
x; }
915 if (
auto _owned =
find(
".memory"); _owned) {
916 for (
auto &o : *_owned) {
917 if (
name == o->GetName()) {
918 if (
type.empty() || o->get()->InheritsFrom(
type.c_str()))
927 while (!_provider && _parent) {
928 _provider = _parent->fProvider;
929 _parent = _parent->fParent;
932 return _provider->getObject(
name,
type);
935 std::shared_ptr<TObject> out;
936 if (
auto arg =
ws()->arg(
name.c_str()); arg) {
937 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
938 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
943 if (
auto arg =
ws()->
data(
name.c_str()); arg) {
944 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
945 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
950 if (
auto arg =
ws()->genobj(
name.c_str()); arg) {
951 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
952 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
957 if (
auto arg =
ws()->embeddedData(
name.c_str()); arg) {
958 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
959 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
965 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
966 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
973 if (
auto arg = get<RooAbsArg>()) {
976 arg->treeNodeServerList(&nodes);
977 if (
auto server = nodes.
find(
name.c_str())) {
978 return std::shared_ptr<TObject>(server, [](
TObject *) {});
989 cat && cat->numTypes() !=
fXAxis->GetNbins()) {
996 if (
auto a = get<RooAbsArg>();
a &&
a->isFundamental())
1001 auto o = get<RooAbsReal>();
1005 if (
auto xName = o->getStringAttribute(
"xvar"); xName) {
1015 (o->dependsOn(*
dynamic_cast<RooAbsArg *
>(_parentX->GetParent())) ||
vars().empty())) {
1017 }
else if (
auto _obs =
obs(); !_obs.empty()) {
1018 for (
auto &
v : _obs) {
1027 }
else if (
auto _pars =
pars(); !_pars.empty()) {
1028 for (
auto &
v : _pars) {
1044 if (o !=
dynamic_cast<TObject *
>(
x)) {
1049 TString binningName = o->getStringAttribute(
"binning");
1050 auto _bnames =
x->getBinningNames();
1051 bool hasBinning =
false;
1052 for (
auto &
b : _bnames) {
1053 if (
b == binningName) {
1061 Warning(
"GetXaxis",
"Binning %s not defined on %s - clearing", binningName.
Data(),
1063 o->setStringAttribute(
"binning",
nullptr);
1067 if (binningName ==
"" && o !=
dynamic_cast<TObject *
>(
x)) {
1069 auto __bnames =
x->getBinningNames();
1070 for (
auto &
b : __bnames) {
1073 if (
b == o->GetName()) {
1074 binningName = o->GetName();
1078 if (binningName ==
"") {
1084 (std::list<double> *)(
nullptr),
1085 o->binBoundaries(*
dynamic_cast<RooAbsRealLValue *
>(
x), -std::numeric_limits<double>::infinity(),
1086 std::numeric_limits<double>::infinity()));
1088 std::vector<double> _bins;
1089 for (
auto &
b : *
bins) {
1090 if (_bins.empty() || std::abs(_bins.back() -
b) > 1
e-5 * _bins.back())
1093 fXAxis = std::make_shared<Axis2>(_bins.size() - 1, &_bins[0]);
1095 if (
auto _v =
dynamic_cast<RooRealVar *
>(
x); _v) {
1096 _v->setBinning(
RooBinning(_bins.size() - 1, &_bins[0], o->GetName()), o->
GetName());
1097 _v->getBinning(o->GetName())
1102 binningName = o->GetName();
1104 }
else if (_parentX) {
1106 binningName = _parentX->GetName();
1113 if (
r->getBinning(binningName).isUniform()) {
1114 fXAxis = std::make_shared<Axis2>(
x->numBins(binningName),
r->getMin(binningName),
r->getMax(binningName));
1116 fXAxis = std::make_shared<Axis2>(
x->numBins(binningName),
r->getBinning(binningName).array());
1118 }
else if (
auto cat =
dynamic_cast<RooCategory *
>(
x)) {
1119 std::vector<double>
bins = {};
1120 for (
int i = 0; i <=
x->numBins(binningName); i++)
1122 fXAxis = std::make_shared<Axis2>(
x->numBins(binningName), &
bins[0]);
1125 std::map<int, std::string> cats;
1126 for (
auto &
c : *cat) {
1127 if (cat->isStateInRange(binningName,
c.first.c_str())) {
1128 cats[
c.second] =
c.first;
1131 for (
auto &[
_, label] : cats) {
1132 fXAxis->SetBinLabel(i++, label.c_str());
1137 fXAxis->SetName(binningName);
1144 if (
auto o =
get(); o) {
1145 if (o->InheritsFrom(
"RooWorkspace"))
1147 if (o->InheritsFrom(
"RooAbsData"))
1149 if (o->InheritsFrom(
"RooSimultaneous"))
1152 if (o->InheritsFrom(
"RooProdPdf"))
1154 if (o->InheritsFrom(
"RooRealSumPdf") || o->InheritsFrom(
"RooAddPdf"))
1157 if (o->InheritsFrom(
"RooFitResult")) {
1158 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitRooFitResult",
true)) {
1159 gClient->GetMimeTypeList()->AddType(
"xRooFitRooFitResult",
"xRooFitRooFitResult",
"package.xpm",
1160 "package.xpm",
"->Browse()");
1162 return "xRooFitRooFitResult";
1164 if (o->InheritsFrom(
"RooRealVar") || o->InheritsFrom(
"RooCategory")) {
1165 if (get<RooAbsArg>()->getAttribute(
"obs")) {
1166 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitObs",
true)) {
1167 gClient->GetMimeTypeList()->AddType(
"xRooFitObs",
"xRooFitObs",
"x_pic.xpm",
"x_pic.xpm",
"->Browse()");
1169 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitGlobs",
true)) {
1170 gClient->GetMimeTypeList()->AddType(
"xRooFitGlobs",
"xRooFitGlobs",
"z_pic.xpm",
"z_pic.xpm",
1173 return (get<RooAbsArg>()->getAttribute(
"global") ?
"xRooFitGlobs" :
"xRooFitObs");
1177 if (o->InheritsFrom(
"TStyle")) {
1178 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitTStyle",
true)) {
1179 gClient->GetMimeTypeList()->AddType(
"xRooFitTStyle",
"xRooFitTStyle",
"bld_colorselect.xpm",
1180 "bld_colorselect.xpm",
"->Browse()");
1182 return "xRooFitTStyle";
1184 if (o->InheritsFrom(
"RooConstVar")) {
1190 return "TMethodBrowsable-leaf";
1192 if (o->InheritsFrom(
"RooStats::HypoTestInverterResult")) {
1193 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitScanStyle",
true)) {
1194 gClient->GetMimeTypeList()->AddType(
"xRooFitScanStyle",
"xRooFitScanStyle",
"f2_s.xpm",
"f2_s.xpm",
1197 return "xRooFitScanStyle";
1199 if (o->InheritsFrom(
"RooStats::HypoTestResult")) {
1200 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitTestStyle",
true)) {
1201 gClient->GetMimeTypeList()->AddType(
"xRooFitTestStyle",
"xRooFitTestStyle",
"diamond.xpm",
"diamond.xpm",
1204 return "xRooFitTestStyle";
1206 if (o->InheritsFrom(
"RooStats::HistFactory::FlexibleInterpVar"))
1207 return "TBranchElement-folder";
1208 if (o->InheritsFrom(
"RooAbsPdf")) {
1209 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitPDFStyle",
true)) {
1210 gClient->GetMimeTypeList()->AddType(
"xRooFitPDFStyle",
"xRooFitPDFStyle",
"pdf.xpm",
"pdf.xpm",
1213 return "xRooFitPDFStyle";
1217 _ax && (
a->isBinnedDistribution(*
dynamic_cast<RooAbsArg *
>(_ax->GetParent())) ||
1219 std::unique_ptr<std::list<double>>(
a->binBoundaries(
1220 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
1221 std::numeric_limits<double>::infinity()))))) {
1226 return o->ClassName();
1237 if (o->InheritsFrom(
"RooStats::HistFactory::FlexibleInterpVar"))
1239 if (o->InheritsFrom(
"PiecewiseInterpolation"))
1241 if (o->InheritsFrom(
"RooHistFunc"))
1242 return (
dynamic_cast<RooAbsArg *
>(o)->getAttribute(
"density")) ?
"ConstDensityHisto" :
"ConstHisto";
1243 if (o->InheritsFrom(
"RooBinWidthFunction"))
1245 if (o->InheritsFrom(
"ParamHistFunc"))
1247 if (o->InheritsFrom(
"RooRealVar"))
1249 if (o->InheritsFrom(
"RooConstVar"))
1257 xRooNode out(
".coords",
nullptr, *
this);
1259 auto _p = std::shared_ptr<xRooNode>(
const_cast<xRooNode *
>(
this), [](
xRooNode *) {});
1289 if (
auto pos = pName.
Index(
'='); pos != -1) {
1290 if (pos > 0 && pName(pos - 1) ==
'<') {
1293 pName = pName(pos + 1, pName.
Length());
1295 pName = pName(0, pName.
Index(
'<'));
1298 _obs->setVal((high + low) / 2.);
1299 static_cast<RooRealVar *
>(_obs.get())->setRange(
"coordRange", low, high);
1301 "coordRange",
"coordRange");
1303 out.emplace_back(std::make_shared<xRooNode>(_obs->GetName(), _obs, _p));
1308 }
else if (
auto _obs = _p->getObject<
RooAbsArg>(pName(0, pos)); _obs) {
1311 _cat->setLabel(pName(pos + 1, pName.
Length()));
1312 }
else if (
auto _var =
dynamic_cast<RooAbsRealLValue *
>(_obs.get()); _var) {
1316 out.emplace_back(std::make_shared<xRooNode>(_obs->GetName(), _obs, _p));
1318 throw std::runtime_error(
"Unknown observable, could not find");
1330 }
catch (
const std::exception &
e) {
1339 }
catch (
const std::exception &
e) {
1348 if (strcmp(
GetName(),
".poi") == 0) {
1354 throw std::runtime_error(
TString::Format(
"%s is not a poi", toRemove.GetName()));
1356 toRemove.get<
RooAbsArg>()->setAttribute(
"poi",
false);
1359 }
else if (strcmp(
GetName(),
".factors") == 0 || strcmp(
GetName(),
".constraints") == 0 ||
1360 strcmp(
GetName(),
".components") == 0) {
1366 pdf =
p->pdfList().find(
child.GetName());
1369 auto i =
p->pdfList().index(*pdf);
1371#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
1372 const_cast<RooArgList &
>(
p->pdfList()).remove(*pdf);
1373#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
1374 p->_pdfNSetList.erase(
p->_pdfNSetList.begin() + i);
1376 auto nset =
p->_pdfNSetList.At(i);
1377 p->_pdfNSetList.Remove(nset);
1380 if (
p->_extendedIndex == i)
1381 p->_extendedIndex = -1;
1382 else if (
p->_extendedIndex > i)
1383 p->_extendedIndex--;
1395 arg = p2->components().find(
child.GetName());
1399#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
1400 p2->_compRSet.remove(*arg);
1402 const_cast<RooArgList &
>(p2->realComponents()).remove(*arg);
1404 p2->removeServer(*arg,
true);
1409 bool removed =
false;
1412 c->constraints().Remove(toRemove);
1414 }
catch (std::runtime_error &) {
1424 arg = p4->funcList().find(
child.GetName());
1428 auto idx = p4->funcList().index(arg);
1432 const_cast<RooArgList &
>(p4->funcList()).remove(*arg);
1433 p4->removeServer(*arg,
true);
1435 std::vector<RooAbsArg *> _coefs;
1436 for (
size_t ii = 0; ii < const_cast<RooArgList &>(p4->coefList()).size(); ii++) {
1437 if (ii !=
size_t(idx))
1438 _coefs.push_back(
const_cast<RooArgList &
>(p4->coefList()).
at(ii));
1440 const_cast<RooArgList &
>(p4->coefList()).removeAll();
1441 for (
auto &
a : _coefs)
1452 if (
auto w = get<RooWorkspace>();
w) {
1454 auto arg =
w->components().find(
child.GetName());
1461 if (arg->hasClients()) {
1462 throw std::runtime_error(
1463 TString::Format(
"Cannot remove %s from workspace %s, because it has dependencies - first remove from those",
1466 const_cast<RooArgSet &
>(
w->components()).remove(*arg);
1467 Info(
"Remove",
"Deleted %s from workspace %s", out.GetName(),
GetName());
1469 }
else if (get<RooProduct>() || get<RooProdPdf>()) {
1471 }
else if (get<RooRealSumPdf>()) {
1475 throw std::runtime_error(
"Removal not implemented for this type of object");
1484 ~AutoUpdater() {
n.browse(); }
1487 AutoUpdater xxx(*
this);
1490 bool considerType(sOpt ==
"+");
1506 if (strcmp(
GetName(),
".factors") == 0) {
1509 }
else if (strcmp(
GetName(),
".components") == 0) {
1512 }
else if (strcmp(
GetName(),
".variations") == 0) {
1515 }
else if (strcmp(
GetName(),
".constraints") == 0) {
1521 }
else if ((strcmp(
GetName(),
".globs") == 0)) {
1524 out->setAttribute(
"obs");
1525 out->setAttribute(
"global");
1528 throw std::runtime_error(
"Failed to add global observable");
1529 }
else if ((strcmp(
GetName(),
".poi") == 0)) {
1532 out->setAttribute(
"poi");
1535 throw std::runtime_error(
"Failed to add parameter of interest");
1542 }
else if (strcmp(
GetName(),
".datasets()") == 0) {
1547 throw std::runtime_error(
1548 "Datasets can only be created for pdfs or workspaces (except if generated dataset, then must be pdf)");
1551 if (sOpt ==
"asimov" || sOpt ==
"toy") {
1553 auto _fr =
fParent->fitResult();
1554 if (strlen(_fr->GetName()) == 0) {
1557 auto ds =
fParent->generate(_fr, sOpt ==
"asimov");
1558 if (strlen(
child.GetName())) {
1569 }
else if (!_ws->obj(_fr->GetName())) {
1575 auto parentObs =
fParent->obs();
1576 auto _obs = parentObs.argList();
1578 std::unique_ptr<RooAbsCollection> _globs(_obs.selectByAttrib(
"global",
true));
1580 _obs.remove(*_globs);
1586 _obs.add(*
dynamic_cast<RooAbsArg *
>(ax->GetParent()));
1589 if (
auto _d = _ws->data(
child.GetName()); _d) {
1592 l.remove(*_d->get(),
true,
true);
1596 throw std::runtime_error(
"Cannot extend dataset with new columns");
1607 if (
auto __d = _ws->data(
child.GetName()))
1608 __d->SetBit(1 << 20, _ws->allData().size() == 1);
1616 auto out = std::shared_ptr<TObject>(_ws->data(
child.GetName()), [](
TObject *) {});
1625 throw std::runtime_error(
"Cannot create dataset");
1630 throw std::runtime_error(
"Cannot add to null object with no parentage");
1632 auto _ref = emplace_back(std::shared_ptr<xRooNode>(&
const_cast<xRooNode &
>(
child), [](
TObject *) {}));
1637 std::rethrow_exception(std::current_exception());
1642 throw std::runtime_error(
"No object");
1646 if (
auto p = get<RooAbsData>();
p) {
1648 bb->Add(
child, opt);
1652 throw std::runtime_error(
"Can only add datasets to a dataset");
1657 auto _globs =
globs();
1658 for (
auto &glob :
child.globs()) {
1659 if (
auto g = _globs.find(glob->GetName()); !
g) {
1661 }
else if (
g->GetContent() != glob->GetContent()) {
1662 Warning(
"Add",
"Global observable %s=%g in dataset %s mismatches %s value %g ... ignoring latter",
1663 g->GetName(),
g->GetContent(),
GetName(),
child.GetName(), glob->GetContent());
1667 if (
auto _dglobs =
p->getGlobalObservables()) {
1670 for (
auto g : _globs)
1673 p->setGlobalObservables(globsToAdd);
1677 for (
auto col : *_data->get()) {
1678 if (!
p->get()->contains(*col)) {
1679 ds->addColumn(*col);
1683 ds->SetTitle(
TString(ds->GetTitle()) +
" + " + _data->GetTitle());
1689 throw std::runtime_error(
"Can only add histogram or dataset to data");
1693 throw std::runtime_error(
"Could not find pdf");
1694 auto _ax = _pdf->GetXaxis();
1696 throw std::runtime_error(
"Cannot determine binning to add data");
1705 l.remove(*
p->get(),
true,
true);
1709 throw std::runtime_error(
"Cannot extend dataset with new columns");
1716 for (
auto &o :
obs) {
1718 if (
auto dv =
dynamic_cast<RooRealVar *
>(
p->get()->find(
v->GetName())); dv) {
1719 if (
v->getMin() < dv->getMin())
1720 dv->setMin(
v->getMin());
1721 if (
v->getMax() > dv->getMax())
1722 dv->setMax(
v->getMax());
1725 if (
auto dc =
dynamic_cast<RooCategory *
>(
p->get()->find(
c->GetName())); dc) {
1726 if (!dc->hasLabel(
c->getCurrentLabel())) {
1727 dc->defineType(
c->getCurrentLabel(),
c->getCurrentIndex());
1733 for (
int i = 1; i <= _h->GetNbinsX(); i++) {
1735 if (!_h->GetXaxis()->GetBinLabel(i)) {
1736 throw std::runtime_error(
1737 TString::Format(
"Categorical observable %s requires bin labels", _ax->GetParent()->GetName()));
1738 }
else if (!cat->hasLabel(_h->GetXaxis()->GetBinLabel(i))) {
1739 throw std::runtime_error(
TString::Format(
"Categorical observable %s does not have label %s",
1740 _ax->GetParent()->GetName(), _h->GetXaxis()->GetBinLabel(i)));
1742 cat->setLabel(_h->GetXaxis()->GetBinLabel(i));
1745 dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent())->setVal(_h->GetBinCenter(i));
1747 p->add(
obs, _h->GetBinContent(i));
1753 if (
auto p = get<RooAddPdf>();
p) {
1757 auto _pdf = std::dynamic_pointer_cast<RooAbsPdf>(out);
1759 throw std::runtime_error(
"Something went wrong with pdf acquisition");
1766 if (
auto _boundaries = std::unique_ptr<std::list<double>>(_p->binBoundaries(
1767 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
1768 std::numeric_limits<double>::infinity()));
1769 !_boundaries && _ax->GetNbins() > 0) {
1770#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 24, 00)
1771 Warning(
"Add",
"Adding unbinned pdf %s to binned %s - will wrap with RooBinSamplingPdf(...)",
1773 _p = acquireNew<RooBinSamplingPdf>(
TString::Format(
"%s_binned", _p->GetName()), _p->GetTitle(),
1775 _p->setStringAttribute(
"alias", std::dynamic_pointer_cast<RooAbsArg>(out)->getStringAttribute(
"alias"));
1776 if (!_p->getStringAttribute(
"alias"))
1777 _p->setStringAttribute(
"alias", out->GetName());
1779 throw std::runtime_error(
1780 "unsupported addition of unbinned pdf to binned model - please upgrade to at least ROOT 6.24");
1786 if (!(_pdf->canBeExtended() &&
p->coefList().empty())) {
1790 if (_pdf->canBeExtended()) {
1795 .add(*acquireNew<RooExtendedBinding>(
TString::Format(
"%s_extBind", _pdf->GetName()),
1799 const_cast<RooArgList &
>(
p->coefList()).add(*acquire2<RooAbsArg, RooRealVar>(
"1",
"1", 1));
1802 const_cast<RooArgList &
>(
p->pdfList()).add(*_pdf);
1806 (!
child.get() && getObject<RooAbsReal>(
child.GetName()))) &&
1809 bool tooMany(
false);
1822 }
else if (!tooMany) {
1827 _sumpdf.get<
RooAbsArg>()->setStringAttribute(
"alias",
"samples");
1828 return _sumpdf.Add(
child);
1833 if (
auto p = get<RooRealSumPdf>();
p) {
1834 std::shared_ptr<TObject> out;
1835 auto cc =
child.fComp;
1836 bool isConverted = (cc !=
child.convertForAcquisition(*
this, sOpt));
1839 if (std::dynamic_pointer_cast<TH1>(cc) && !
TString(cc->GetOption()).
Contains(
"nostyle")) {
1843 if (!
child.fComp && getObject<RooAbsReal>(
child.GetName())) {
1844 Info(
"Add",
"Adding existing function %s to %s",
child.GetName(),
p->
GetName());
1845 out = getObject<RooAbsReal>(
child.GetName());
1848 if (!out && !
child.fComp) {
1849 std::shared_ptr<RooAbsArg> _func;
1860 std::make_unique<TH1D>(
child.GetName(),
child.GetTitle(), _ax->GetNbins(), _ax->binning()->array());
1862 h->GetXaxis()->SetName(
TString::Format(
"%s;%s", _ax->GetParent()->GetName(), _ax->GetName()));
1865 }
else if (_obs.size() == 1) {
1869 TString binningName =
p->getStringAttribute(
"binning");
1870 for (
auto &
b : _bnames) {
1878 auto h = std::make_unique<TH1D>(
child.GetName(),
child.GetTitle(), _x->numBins(binningName),
1879 _x->getBinningPtr(binningName)->array());
1881 h->GetXaxis()->SetName(
1885 Info(
"Add",
"Created densityhisto factor %s (xaxis=%s) for %s", _func->GetName(), _obs.at(0)->GetName(),
1888 throw std::runtime_error(
"Unsupported creation of new component in SumPdf for this many obs");
1894 _func->setStringAttribute(
"alias",
child.GetName());
1898 if (
auto _f = std::dynamic_pointer_cast<RooHistFunc>(
1902 _f->setAttribute(
"density");
1903 if (_f->getAttribute(
"autodensity")) {
1905 for (
int i = 0; i < _f->dataHist().numEntries(); i++) {
1906 auto bin_pars = _f->dataHist().get(i);
1907 _f->dataHist().set(*bin_pars, _f->dataHist().weight() / _f->dataHist().binVolume(*bin_pars));
1909 _f->setAttribute(
"autodensity",
false);
1910 _f->setValueDirty();
1919 Info(
"Add",
"Created %s factor RooHistFunc::%s for %s",
1920 _f->getAttribute(
"density") ?
"densityhisto" :
"histo", _f->GetName(),
p->
GetName());
1924 if (
auto _p = std::dynamic_pointer_cast<RooAbsPdf>(out); _p) {
1928 TString newName(_p->GetName());
1930 newName +=
"_components";
1931 Warning(
"Add",
"converting samples to components");
1936 if (
auto _boundaries = std::unique_ptr<std::list<double>>(_p->binBoundaries(
1937 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
1938 std::numeric_limits<double>::infinity()));
1939 !_boundaries && _ax->GetNbins() > 0) {
1940#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 24, 00)
1941 Warning(
"Add",
"Adding unbinned pdf %s to binned %s - will wrap with RooBinSamplingPdf(...)",
1943 _p = acquireNew<RooBinSamplingPdf>(
TString::Format(
"%s_binned", _p->GetName()), _p->GetTitle(),
1945 _p->setStringAttribute(
"alias", std::dynamic_pointer_cast<RooAbsArg>(out)->getStringAttribute(
"alias"));
1946 if (!_p->getStringAttribute(
"alias"))
1947 _p->setStringAttribute(
"alias", out->GetName());
1949 throw std::runtime_error(
1950 "unsupported addition of unbinned pdf to binned model - please upgrade to at least ROOT 6.24");
1957 if (!_p->canBeExtended()) {
1958 _p = acquireNew<RooExtendPdf>(
TString::Format(
"%s_extended", _p->GetName()), _p->GetTitle(), *_p,
1959 *acquire2<RooAbsReal, RooRealVar>(
"1",
"1", 1));
1962 return *(
Replace(*acquireNew<RooAddPdf>(newName, _p->GetTitle(),
RooArgList(*
p, *_p)))
1966 if (
auto _f = std::dynamic_pointer_cast<RooAbsReal>(out); _f) {
1975 if (
auto _boundaries = std::unique_ptr<std::list<double>>(_f->binBoundaries(
1976 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
1977 std::numeric_limits<double>::infinity()));
1978 !_boundaries && _ax->GetNbins() > 0) {
1979#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 24, 00)
1982 "Adding unbinned function %s to binned %s - will wrap with RooRealSumPdf(RooBinSamplingPdf(...))",
1984 auto sumPdf = acquireNew<RooRealSumPdf>(
TString::Format(
"%s_pdfWrapper", _f->GetName()), _f->GetTitle(),
1985 *_f, *acquire2<RooAbsArg, RooRealVar>(
"1",
"1", 1),
true);
1986 sumPdf->setStringAttribute(
"alias", _f->getStringAttribute(
"alias"));
1987 if (!sumPdf->getStringAttribute(
"alias"))
1988 sumPdf->setStringAttribute(
"alias", out->GetName());
1989 _f = acquireNew<RooBinSamplingPdf>(
TString::Format(
"%s_binned", _f->GetName()), _f->GetTitle(),
1991 _f->setStringAttribute(
"alias", std::dynamic_pointer_cast<RooAbsArg>(out)->getStringAttribute(
"alias"));
1992 if (!_f->getStringAttribute(
"alias"))
1993 _f->setStringAttribute(
"alias", out->GetName());
1995 throw std::runtime_error(
1996 "unsupported addition of unbinned function to binned model - please upgrade to at least ROOT 6.24");
2001 const_cast<RooArgList &
>(
p->coefList()).add(*acquire2<RooAbsArg, RooRealVar>(
"1",
"1", 1));
2004 if (!
p->getStringAttribute(
"binning"))
2005 p->setStringAttribute(
"binning", _f->getStringAttribute(
"binning"));
2008 if (
auto gf =
p->getStringAttribute(
"global_factors"); gf) {
2011 auto fac = getObject<RooAbsReal>(pattern.
Data());
2013 throw std::runtime_error(
TString::Format(
"Could not find global factor %s", pattern.
Data()));
2022 p->setStringAttribute(
"xvar",
nullptr);
2026 }
else if (
auto p2 = get<RooProdPdf>(); p2) {
2033 bool tooMany(
false);
2046 }
else if (!tooMany) {
2047 auto out = this->
operator[](
"components")->Add(child);
2051 (!
child.get() && getObject<RooAbsReal>(
child.GetName()))) &&
2055 bool tooMany(
false);
2064 }
else if (
auto _p2 =
pp->get<
RooAddPdf>(); _p2) {
2066 for (
auto &_pdfa :
pp->components()) {
2080 }
else if (_backup) {
2083 }
else if (!tooMany) {
2084 auto out = this->
operator[](
"samples")->Add(child);
2087 p2->setStringAttribute(
"xvar",
nullptr);
2091 }
else if (
auto s = get<RooSimultaneous>(); s) {
2099 }
else if (
auto w = get<RooWorkspace>();
w) {
2100 child.convertForAcquisition(*
this);
2104 if (!
w->import(*_d)) {
2107 throw std::runtime_error(
2118 if (!
child.empty() ||
child.fFolder ==
"!pdfs") {
2121 std::string catName =
"channelCat";
2122 if (!
child.empty()) {
2123 if (
TString ss =
child.at(0)->GetName(); ss.Contains(
"=")) {
2124 catName = ss(0, ss.Index(
'='));
2127 auto _cat = acquire<RooCategory>(catName.c_str(), catName.c_str());
2128 _cat->setAttribute(
"obs");
2129 auto out = acquireNew<RooSimultaneous>(
child.GetName(),
child.GetTitle(), *_cat);
2130 Info(
"Add",
"Created model RooSimultaneous::%s in workspace %s", out->GetName(),
w->GetName());
2135 if (sOpt ==
"pdf") {
2137 if (get<RooWorkspace>()) {
2141 }
else if (sOpt ==
"channel") {
2143 if (get<RooSimultaneous>()) {
2145 }
else if (get<RooWorkspace>()) {
2146 std::shared_ptr<TObject> out;
2147 child.convertForAcquisition(*
this);
2150 }
else if (!
child.fComp) {
2151 out = acquireNew<RooProdPdf>(
child.GetName(),
2153 Info(
"Add",
"Created channel RooProdPdf::%s in workspace %s", out->GetName(),
get()->
GetName());
2157 }
else if (sOpt ==
"sample" || sOpt ==
"func") {
2158 if (get<RooProdPdf>()) {
2161 return _mainChild.Add(
child, sOpt ==
"func" ?
"func" :
"");
2163 return (*
this)[
"samples"]->Add(
child, sOpt ==
"func" ?
"func" :
"");
2166 }
else if (sOpt ==
"dataset") {
2167 if (get<RooWorkspace>()) {
2169 return (*this).datasets().Add(
child);
2176 if (get<RooSimultaneous>()) {
2180 }
else if (get<RooProduct>() || get<RooProdPdf>()) {
2226 if (
auto a = get<RooAbsArg>()) {
2227 a->setAttribute(
"hidden", set);
2236 auto a = get<RooAbsArg>();
2238 return a->getAttribute(
"hidden");
2245 if (
get() == rhs.
get()) {
2295 if (
auto s = get<RooSimultaneous>(); s) {
2296 auto chans =
bins();
2297 if (!chans.empty()) {
2303 for (
auto &
c : chans) {
2305 cName = cName(cName.
Index(
'=') + 1, cName.
Length());
2308 c->shallowCopy(
name +
"_" +
c->get()->GetName(), std::shared_ptr<xRooNode>(&out, [](
xRooNode *) {}));
2309 pdf->addPdf(*
dynamic_cast<RooAbsPdf *
>(c_copy.get()), cName);
2314 }
else if (
auto p =
dynamic_cast<RooProdPdf *
>(o);
p) {
2316 std::shared_ptr<RooProdPdf> pdf =
2317 std::dynamic_pointer_cast<RooProdPdf>(out.acquire(std::shared_ptr<TObject>(
p->
Clone()),
false,
2322 std::dynamic_pointer_cast<RooAbsArg>(out.acquire(std::shared_ptr<TObject>(
main->Clone()),
false,
true));
2323 std::cout << newMain <<
" " << newMain->GetName() << std::endl;
2338 static std::unique_ptr<cout_redirect> capture;
2339 std::string captureStr;
2340 bool doCapture =
false;
2341 if (!capture &&
gROOT->FromPopUp()) {
2342 capture = std::make_unique<cout_redirect>(captureStr);
2365 if (
get() &&
get() !=
this) {
2367 if (_more || (get<RooAbsArg>() && get<RooAbsArg>()->isFundamental()) || get<RooConstVar>() ||
2368 get<RooAbsData>() || get<RooProduct>() || get<RooFitResult>()) {
2370 auto _snap = std::unique_ptr<RooAbsCollection>(_deps.snapshot());
2373 if (
auto _fr = get<RooFitResult>(); _fr &&
dynamic_cast<RooStringVar *
>(_fr->constPars().
find(
".log"))) {
2374 std::cout <<
"Minimization Logs:" << std::endl;
2375 std::cout << dynamic_cast<RooStringVar *>(_fr->constPars().find(
".log"))->getVal() << std::endl;
2377 _deps.assignValueOnly(*_snap);
2387 if (
auto fv = get<RooFormulaVar>()) {
2389 for (
size_t i = 0; i < fv->dependents().
size(); i++) {
2393 }
else if (
auto gv = get<RooGenericPdf>()) {
2395 for (
size_t i = 0; i < gv->dependents().
size(); i++) {
2403 }
else if (!
get()) {
2404 std::cout << std::endl;
2408 std::vector<std::string> folderNames;
2409 for (
auto &k : *
this) {
2410 if (std::find(folderNames.begin(), folderNames.end(), k->fFolder) == folderNames.end()) {
2411 folderNames.push_back(k->fFolder);
2414 for (
auto &
f : folderNames) {
2418 for (
int j = 0; j <
indent; j++)
2420 std::cout <<
f << std::endl;
2423 for (
auto &k : *
this) {
2424 if (k->fFolder !=
f) {
2428 for (
int j = 0; j < iindent; j++)
2430 std::cout << i++ <<
") " << k->GetName() <<
" : ";
2434 auto _deps = k->coords(
false).argList();
2435 auto _snap = std::unique_ptr<RooAbsCollection>(_deps.snapshot());
2437 k->get()->Print(sOpt);
2438 _deps.assignValueOnly(*_snap);
2441 if (
auto _type = k->GetNodeType(); strlen(_type)) {
2449 for (
size_t j = 0; j < fv->dependents().
size(); j++) {
2455 for (
size_t j = 0; j < gv->dependents().
size(); j++) {
2460 std::cout << k->get()->ClassName() <<
"::" << k->get()->GetName() << _suffix.
Data() << std::endl;
2463 k->Print(sOpt +
TString::Format(
"depth=%dindent=%d", depth - 1, iindent + 1));
2466 std::cout <<
" NULL " << std::endl;
2472 size_t lastBreak = 0;
2473 std::string captureStrWithBreaks;
2474 for (
size_t i = 0; i < captureStr.size(); i++) {
2475 captureStrWithBreaks += captureStr[i];
2476 if (captureStr[i] ==
'\n') {
2479 if (i - lastBreak > 150) {
2480 captureStrWithBreaks +=
'\n';
2485 (
gROOT->GetListOfBrowsers()->At(0))
2489 captureStrWithBreaks.c_str());
2497 if (
auto v = get<RooRealVar>();
v) {
2500 double mean = std::numeric_limits<double>::quiet_NaN();
2501 double sigma = mean;
2510 mean = std::numeric_limits<double>::quiet_NaN();
2513 constrType =
"normal";
2514 }
else if (constrType ==
"normal") {
2517 }
else if (constrType ==
"gaussian") {
2521 throw std::runtime_error(
"No error on parameter for gaussian constraint");
2524 constrType =
"normal";
2525 }
else if (constrType ==
"poisson") {
2527 throw std::runtime_error(
"No error on parameter for poisson constraint");
2529 sigma = pow(
v->getVal() /
v->getError(), 2);
2532 if (constrType ==
"poisson") {
2534 double tau_val =
sigma;
2535 auto globs = acquire<RooRealVar>(
Form(
"globs_%s",
v->GetName()),
Form(
"globs_%s",
v->GetName()),
2536 v->getVal() * tau_val, (
v->getVal() - 5 *
v->getError()) * tau_val,
2537 (
v->getVal() + 5 *
v->getError()) * tau_val);
2538 globs->setConstant();
2539 globs->setAttribute(
"obs");
2540 globs->setAttribute(
"global");
2542 auto tau = acquireNew<RooConstVar>(
TString::Format(
"tau_%s",
v->GetName()),
"", tau_val);
2543 auto constr = acquireNew<RooPoisson>(
2552 v->setError(mean / sqrt(tau_val));
2553 Info(
"Constrain",
"Added poisson constraint pdf RooPoisson::%s (tau=%g) for %s", out->GetName(), tau_val,
2556 }
else if (constrType ==
"normal") {
2558 auto globs = acquire<RooRealVar>(
Form(
"globs_%s",
v->GetName()),
Form(
"globs_%s",
v->GetName()), mean,
2560 globs->setAttribute(
"obs");
2561 globs->setAttribute(
"global");
2562 globs->setConstant();
2565 auto constr = acquireNew<RooGaussian>(
2571 Info(
"Constrain",
"Added gaussian constraint pdf RooGaussian::%s (mean=%g,sigma=%g) for %s", out->GetName(),
2578 auto _me = get<RooAbsArg>();
2580 throw std::runtime_error(
"Cannot constrain non arg");
2583 if (!
p->dependsOn(*_me)) {
2584 throw std::runtime_error(
"Constraint does not depend on constrainee");
2593 throw std::runtime_error(
"Nowhere to put constraint");
2599 for (
auto &
c : *
x) {
2605 return x->Multiply(
child);
2607 return x->Add(
child,
"+");
2620 ~AutoUpdater() {
n.browse(); }
2623 AutoUpdater xxx(*
this);
2630 auto o = std::dynamic_pointer_cast<RooAbsReal>(
acquire(
child.fComp));
2653 ?
fParent->mainChild()->GetName()
2658 binFactors =
fParent->factors().find(
"binFactors");
2660 throw std::runtime_error(
2667 for (
auto &
b : binFactors->bins()) {
2668 auto p = acquireNew<RooProduct>(
TString::Format(
"%s_bin%d", binFactors->get()->GetName(), i),
2670 p->setStringAttribute(
"alias",
TString::Format(
"%s=%g", binFactors->GetXaxis()->GetParent()->GetName(),
2671 binFactors->GetXaxis()->GetBinCenter(i)));
2678 auto _bin = binFactors->bins().at(
fBinNumber - 1);
2679 if (
auto phf = binFactors->get<
ParamHistFunc>(); phf && _bin) {
2680#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
2685 if (strcmp(_bin->GetName(),
"1") == 0) {
2687 for (std::size_t i = 0; i < pSet.
size(); i++) {
2689 all.
add(*pSet.
at(i));
2697 _bin->fBinNumber = -1;
2698 return _bin->Multiply(
child, opt);
2726 auto _ref = emplace_back(std::shared_ptr<xRooNode>(&
const_cast<xRooNode &
>(
child), [](
TObject *) {}));
2731 std::rethrow_exception(std::current_exception());
2739 if (
auto o = getObject<RooAbsReal>(
child.GetName())) {
2743 Info(
"Multiply",
"Scaled %s by existing factor %s::%s",
2747 }
else if (sOpt ==
"norm") {
2754 Info(
"Multiply",
"Scaled %s by new norm factor %s",
2759 throw std::runtime_error(
TString::Format(
"Failed to create new normFactor %s",
child.GetName()));
2763 Info(
"Multiply",
"Scaled %s by new norm factor %s",
2767 }
else if (sOpt ==
"shape" || sOpt ==
"histo" || sOpt ==
"blankshape") {
2772 for (
int i = 1; i <=
h->GetNbinsX(); i++) {
2773 h->SetBinContent(i, 1);
2778 h->SetTitle(
child.GetTitle());
2783 Info(
"Multiply",
"Scaled %s by new %s factor %s",
2788 }
else if (sOpt ==
"overall") {
2789 auto out =
Multiply(acquireNew<RooStats::HistFactory::FlexibleInterpVar>(
2790 child.GetName(),
child.GetTitle(),
RooArgList(), 1, std::vector<double>(), std::vector<double>()));
2792 Info(
"Multiply",
"Scaled %s by new overall factor %s",
2796 }
else if (sOpt ==
"func" &&
ws()) {
2801 Info(
"Multiply",
"Scaled %s by new func factor %s",
2808 if (
auto h =
child.get<
TH1>();
h && strlen(
h->GetOption()) == 0 && strlen(opt) > 0) {
2812 if (
auto w = get<RooWorkspace>();
w) {
2814 std::shared_ptr<TObject> out;
2815 child.convertForAcquisition(*
this);
2821 if (strcmp(
GetName(),
".coef") == 0) {
2824 for (
size_t i = 0; i <
p->pdfList().size(); i++) {
2826 auto coefs =
p->coefList().at(i);
2835 for (
size_t j = 0; j <
p->coefList().size(); j++) {
2837 oldCoefs.
add(*newCoefs);
2839 oldCoefs.add(*
p->coefList().at(j));
2842 const_cast<RooArgList &
>(
p->coefList()).removeAll();
2843 const_cast<RooArgList &
>(
p->coefList()).add(oldCoefs);
2850 throw std::runtime_error(
"this coefs case is not supported");
2853 if (
auto p = get<RooProduct>();
p) {
2854 std::shared_ptr<TObject> out;
2855 auto cc =
child.fComp;
2856 bool isConverted = (
child.convertForAcquisition(*
this) != cc);
2861 if (
auto _f = std::dynamic_pointer_cast<RooHistFunc>(
2863 _f && _f->getAttribute(
"autodensity")) {
2865 bool hasDensity =
false;
2873 if (_f->getAttribute(
"density")) {
2876 for (
int i = 0; i < _f->dataHist().numEntries(); i++) {
2877 auto bin_pars = _f->dataHist().get(i);
2878 _f->dataHist().set(*bin_pars, _f->dataHist().weight() / _f->dataHist().binVolume(*bin_pars));
2880 _f->setValueDirty();
2887 _f->setAttribute(
"autodensity",
false);
2891 Info(
"Multiply",
"Created %s factor %s in %s",
2895 Info(
"Multiply",
"Created shape factor %s in %s",
child->GetName(),
p->
GetName());
2898 if (
auto _f = std::dynamic_pointer_cast<RooAbsReal>(out); _f) {
2899#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
2900 p->_compRSet.add(*_f);
2902 const_cast<RooArgList &
>(
p->realComponents()).add(*_f);
2908 for (
auto &_par : _out.
pars()) {
2911 for (
auto &_constr : _par->constraints()) {
2912 if (strcmp(s, _constr->get()->GetName()) == 0) {
2919 Info(
"Multiply",
"Pulling in %s boundConstraint: %s", _par->GetName(), s);
2920 auto _pdf = getObject<RooAbsPdf>(s);
2922 throw std::runtime_error(
"Couldn't find boundConstraint");
2924 _par->Constrain(_pdf);
2931 }
else if (
auto p2 = get<RooProdPdf>(); p2) {
2933 std::shared_ptr<TObject> out;
2934 child.convertForAcquisition(*
this);
2943 std::shared_ptr<RooAbsPdf> _pdf;
2944 if (!
child.get() && strcmp(
child.GetName(),
"components") == 0) {
2945 auto _sumpdf = acquireNew<RooAddPdf>(
Form(
"%s_%s", p2->GetName(),
child.GetName()),
2946 (strlen(
child.GetTitle()) && strcmp(
child.GetTitle(),
child.GetName()))
2952 auto _sumpdf = acquireNew<RooRealSumPdf>(
2953 Form(
"%s_%s", p2->GetName(),
child.GetName()),
2957 _sumpdf->setFloor(
true);
2960 _pdf->setStringAttribute(
"alias",
child.GetName());
2962 _pdf->setStringAttribute(
"xvar", p2->getStringAttribute(
"xvar"));
2963 _pdf->setStringAttribute(
"binning", p2->getStringAttribute(
"binning"));
2965 Info(
"Multiply",
"Created %s::%s in channel %s", _pdf->ClassName(), _pdf->GetName(), p2->GetName());
2970 if (
auto _pdf = std::dynamic_pointer_cast<RooAbsPdf>(out); _pdf) {
2971#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
2972 const_cast<RooArgList &
>(p2->pdfList()).add(*_pdf);
2973#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
2974 p2->_pdfNSetList.emplace_back(std::make_unique<RooArgSet>(
"nset"));
2978 if (!p2->canBeExtended() && _pdf->canBeExtended()) {
2979 p2->_extendedIndex = p2->_pdfList.size() - 1;
2988 }
else if (
auto p3 = get<RooRealSumPdf>(); p3) {
2990 std::shared_ptr<TObject> out;
2991 child.convertForAcquisition(*
this);
2997 TString s = p3->getStringAttribute(
"global_factors");
3000 s += out->GetName();
3001 p3->setStringAttribute(
"global_factors", s);
3004 "Flagged %s as a global factor in channel %s (is applied to all current and future samples in the channel)",
3005 out->GetName(), p3->GetName());
3016 std::set<RooAbsArg *> cl;
3017 for (
auto &arg : p5->clients()) {
3023 if (cl.size() > 1) {
3028 Warning(
"Multiply",
"Scaling %s that has multiple clients", p5->GetName());
3034 for (
auto &
a : p5->attributes())
3035 new_p->setAttribute(
a.c_str());
3036 for (
auto &
a : p5->stringAttributes())
3037 new_p->setStringAttribute(
a.first.c_str(),
a.second.c_str());
3038 if (!new_p->getStringAttribute(
"alias"))
3039 new_p->setStringAttribute(
"alias", p5->GetName());
3041 new_p->setAttribute(
Form(
"ORIGNAME:%s", old_p->GetName()));
3042 for (
auto arg : cl) {
3043 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
3051 if (!
child.get() && strlen(opt) == 0)
3054 throw std::runtime_error(
3056 (!
child.get() && strlen(opt) == 0) ?
" (forgot to specify factor type?)" :
""));
3062 auto p5 = get<RooAbsArg>();
3064 throw std::runtime_error(
"Only replacement of RooAbsArg is supported");
3073 new_p = std::dynamic_pointer_cast<RooAbsArg>(out).get();
3075 std::set<RooAbsArg *> cl;
3076 for (
auto &arg : p5->clients()) {
3084 if (cl.size() > 1) {
3089 std::stringstream clientList;
3091 clientList <<
c->GetName() <<
",";
3092 Warning(
"Replace",
"Replacing %s in all clients: %s", p5->GetName(), clientList.str().c_str());
3096 new_p->setAttribute(
Form(
"ORIGNAME:%s", p5->GetName()));
3097 for (
auto arg : cl) {
3102 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
3113 ~AutoUpdater() {
n.browse(); }
3116 AutoUpdater xxx(*
this);
3121 auto _ref = emplace_back(std::shared_ptr<xRooNode>(&
const_cast<xRooNode &
>(
child), [](
TObject *) {}));
3126 std::rethrow_exception(std::current_exception());
3138 std::string label =
child.GetName();
3139 if (
auto pos = label.find(
'='); pos != std::string::npos)
3140 label = label.substr(pos + 1);
3141 if (!s->indexCat().hasLabel(label)) {
3144 std::shared_ptr<TObject> out;
3145 child.convertForAcquisition(*
this);
3148 }
else if (!
child.fComp) {
3149 out = acquireNew<RooProdPdf>(
TString::Format(
"%s_%s", s->GetName(), label.c_str()),
3151 Info(
"Vary",
"Created channel RooProdPdf::%s in model %s", out->GetName(), s->GetName());
3154 if (
auto _pdf = std::dynamic_pointer_cast<RooAbsPdf>(out); _pdf) {
3155 s->addPdf(*_pdf, label.c_str());
3164 }
else if (
auto p = get<RooStats::HistFactory::FlexibleInterpVar>();
p) {
3167 child.convertForAcquisition(*
this);
3169 if (!_c &&
child.get()) {
3170 throw std::runtime_error(
"Only pure consts can be set as variations of a flexible interpvar");
3172#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3173 double value = (_c ? _c->getVal() :
p->_nominal);
3174 double nomVal =
p->_nominal;
3176 double value = (_c ? _c->getVal() :
p->nominal());
3177 double nomVal =
p->nominal();
3181 if (cName ==
"nominal") {
3186 throw std::runtime_error(
"unsupported variation form");
3188 std::string parName = cName(0, cName.
Index(
'='));
3190 if (parVal != 1 && parVal != -1) {
3191 throw std::runtime_error(
"unsupported variation magnitude");
3193 bool high = parVal > 0;
3195 if (parName.empty()) {
3204 if (!
p->findServer(*
v)) {
3205#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3206 p->_paramList.add(*
v);
3207 p->_low.push_back(0);
3208 p->_high.push_back(0);
3209 p->_interpCode.push_back(4);
3212 const_cast<std::vector<double> &
>(
p->low()).push_back(0);
3213 const_cast<std::vector<double> &
>(
p->high()).push_back(0);
3214 const_cast<std::vector<int> &
>(
p->interpolationCodes()).push_back(4);
3216 v->setAttribute(
Form(
"SYMMETRIC%s_%s", high ?
"+" :
"-",
GetName()));
3221 if (
v->getAttribute(
Form(
"SYMMETRIC+_%s",
GetName()))) {
3222 p->setLow(*
v, 2 * nomVal -
value);
3224 v->setAttribute(
Form(
"SYMMETRIC-_%s",
GetName()),
false);
3227 if (
v->getAttribute(
Form(
"SYMMETRIC-_%s",
GetName()))) {
3228 p->setHigh(*
v, 2 * nomVal -
value);
3230 v->setAttribute(
Form(
"SYMMETRIC+_%s",
GetName()),
false);
3238 }
else if (
auto p2 = get<PiecewiseInterpolation>(); p2) {
3241 throw std::runtime_error(
"unsupported variation form");
3245 if (parVal != 1 && parVal != -1) {
3246 throw std::runtime_error(
"unsupported variation magnitude");
3248#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3251 throw std::runtime_error(
3252 TString::Format(
"Interpolating %s instead of RooHistFunc", p2->_nominal.absArg()->ClassName()));
3257 throw std::runtime_error(
3258 TString::Format(
"Interpolating %s instead of RooHistFunc", p2->nominalHist()->ClassName()));
3264 for (
auto par : p2->paramList()) {
3265 if (parName == par->GetName()) {
3266 f =
dynamic_cast<RooHistFunc *
>((parVal > 0 ? p2->highList() : p2->lowList()).
at(i));
3267 otherf =
dynamic_cast<RooHistFunc *
>((parVal > 0 ? p2->lowList() : p2->highList()).
at(i));
3275 auto v = acquire<RooRealVar>(parName, parName, -5, 5);
3279 std::shared_ptr<RooHistFunc> up(
3281 std::shared_ptr<RooHistFunc> down(
3284#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3285 std::unique_ptr<RooDataHist>
h1(
3286 static_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", up->GetName()))));
3287 std::unique_ptr<RooDataHist> h2(
3288 static_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", down->GetName()))));
3289 up->_dataHist =
dynamic_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", up->GetName())));
3290 down->_dataHist =
dynamic_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", down->GetName())));
3293 down->cloneAndOwnDataHist(
TString::Format(
"hist_%s", down->GetName()));
3295 auto ups = std::dynamic_pointer_cast<RooHistFunc>(
acquire(up,
false,
true));
3296 auto downs = std::dynamic_pointer_cast<RooHistFunc>(
acquire(down,
false,
true));
3297#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3298 p2->_highSet.add(*ups.get());
3299 p2->_lowSet.add(*downs.get());
3300 p2->_interpCode.push_back(4);
3301 p2->_paramSet.add(*
v);
3303 const_cast<RooArgList &
>(p2->highList()).add(*ups);
3304 const_cast<RooArgList &
>(p2->lowList()).add(*downs);
3305 const_cast<std::vector<int> &
>(p2->interpolationCodes()).push_back(4);
3306 const_cast<RooArgList &
>(p2->paramList()).add(*
v);
3308 p2->setValueDirty();
3309 f = ((parVal > 0) ? ups : downs).
get();
3310 otherf = ((parVal > 0) ? downs : ups).
get();
3312 f->setStringAttribute(
"symmetrizes", otherf->
GetName());
3313 f->setStringAttribute(
"symmetrize_nominal", nomf->
GetName());
3332 }
else if (
auto p3 = get<RooConstVar>(); p3) {
3335 if (p3->getAttribute(
"RooRealConstant_Factory_Object")) {
3336 throw std::runtime_error(
"Cannot vary pure constants");
3342 std::set<RooAbsArg *> cl;
3343 for (
auto &arg : p3->clients()) {
3348 if (cl.size() > 1) {
3353 Warning(
"Vary",
"Varying %s that has multiple clients", p3->GetName());
3356 p3->setStringAttribute(
"origName", p3->GetName());
3358 p3->SetName(
Form(
"%s_nominal", p3->GetName()));
3360 auto new_p = acquireNew<RooStats::HistFactory::FlexibleInterpVar>(
n, p3->GetTitle(),
RooArgList(), p3->getVal(),
3361 std::vector<double>(), std::vector<double>());
3364 for (
auto &
a : p3->attributes())
3365 new_p->setAttribute(
a.c_str());
3366 for (
auto &
a : p3->stringAttributes())
3367 new_p->setStringAttribute(
a.first.c_str(),
a.second.c_str());
3370 new_p->setAttribute(
Form(
"ORIGNAME:%s", old_p->GetName()));
3371 for (
auto arg : cl) {
3372 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
3378 }
else if (
auto p4 = get<RooAbsReal>(); p4) {
3382 std::set<RooAbsArg *> cl;
3383 for (
auto &arg : p4->clients()) {
3388 if (cl.size() > 1) {
3393 Warning(
"Vary",
"Varying %s that has multiple clients", p4->GetName());
3396 p4->setStringAttribute(
"origName", p4->GetName());
3398 p4->SetName(
Form(
"%s_nominal", p4->GetName()));
3403 for (
auto &
a : p4->attributes())
3404 new_p->setAttribute(
a.c_str());
3405 for (
auto &
a : p4->stringAttributes())
3406 new_p->setStringAttribute(
a.first.c_str(),
a.second.c_str());
3409 new_p->setAttribute(
Form(
"ORIGNAME:%s", old_p->GetName()));
3410 for (
auto arg : cl) {
3411 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
3452 if (
auto a = get<RooAbsArg>();
a && strcmp(
a->GetName(),
GetName()) && !
a->getStringAttribute(
"alias")) {
3453 a->setStringAttribute(
"alias",
GetName());
3456 throw std::runtime_error(
"Cannot determine type");
3461 if (
auto h =
dynamic_cast<const TH1 *
>(&o);
h) {
3472 bool _isData = get<RooAbsData>();
3478 throw std::runtime_error(
"no xaxis");
3479 auto _v =
dynamic_cast<RooRealVar *
>(ax->GetParent());
3482 _b.
b =
dynamic_cast<RooAbsBinning *
>(_v->getBinningPtr(
nullptr)->Clone());
3483 if (
h->GetXaxis()->IsVariableBinSize()) {
3484 _v->setBinning(
RooBinning(
h->GetNbinsX(),
h->GetXaxis()->GetXbins()->GetArray()));
3486 _v->setBinning(
RooUniformBinning(
h->GetXaxis()->GetXmin(),
h->GetXaxis()->GetXmax(),
h->GetNbinsX()));
3492 for (
int bin = 1; bin <=
h->GetNbinsX(); bin++) {
3500 if (!_isData &&
h->GetSumw2N() && !
SetBinError(bin,
h->GetBinError(bin)))
3501 throw std::runtime_error(
"Failed setting stat error");
3505 }
else if (
auto _c =
dynamic_cast<const RooConstVar *
>(&o); _c) {
3507 if (
auto a = get<RooAbsArg>();
3508 (
a &&
a->isFundamental()) || get<RooConstVar>() || get<RooStats::HistFactory::FlexibleInterpVar>()) {
3511 }
else if (get<RooAbsData>()) {
3517 throw std::runtime_error(
"Assignment failed");
3544 auto _pars =
pars();
3547 std::map<RooAbsRealLValue *, double> valsToSet;
3549 auto idx = pattern.
Index(
'=');
3552 (idx == -1) ? std::numeric_limits<double>::quiet_NaN() :
TString(pattern(idx + 1, pattern.
Length())).
Atof();
3553 for (
auto p : _pars.argList()) {
3555 p->setAttribute(
"Constant",
true);
3556 if (!std::isnan(val)) {
3567 for (
auto &
d : _dsets) {
3568 if (
d->get()->TestBit(1 << 20)) {
3569 dsetName =
d->get()->GetName();
3573 auto _nll =
nll(dsetName.
Data());
3575 for (
auto [
p,
v] : valsToSet) {
3578 _nll.fitConfigOptions()->SetValue(
"LogSize", 65536);
3579 _nll.fitConfig()->MinimizerOptions().SetPrintLevel(0);
3580 auto fr = _nll.minimize();
3583 throw std::runtime_error(
"Fit Failed");
3586 for (
unsigned int i = 0; i < fr->numStatusHistory(); i++) {
3587 statusCodes +=
TString::Format(
"\n%s = %d", fr->statusLabelHistory(i), fr->statusCodeHistory(i));
3590 (
gROOT->GetListOfBrowsers()->At(0))
3593 if (fr->status() != 0) {
3595 TString::Format(
"%s\nData = %s\nFit Status Code = %d\nCov Quality = %d\n-------------%s",
3596 fr->GetName(), dsetName.
Data(), fr->status(), fr->covQual(), statusCodes.
Data()),
3598 }
else if (fr->covQual() != 3 && _nll.fitConfig()->ParabErrors()) {
3599 new TGMsgBox(
gClient->GetRoot(),
w,
"Fit Finished with Bad Covariance Quality",
3600 TString::Format(
"%s\nData = %s\nFit Status Code = %d\nCov Quality = %d\n-------------%s",
3601 fr->GetName(), dsetName.
Data(), fr->status(), fr->covQual(), statusCodes.
Data()),
3605 TString::Format(
"%s\nData = %s\nFit Status Code = %d\nCov Quality = %d\n-------------%s",
3606 fr->GetName(), dsetName.
Data(), fr->status(), fr->covQual(), statusCodes.
Data()));
3608 }
catch (
const std::exception &
e) {
3611 (
gROOT->GetListOfBrowsers()->At(0))
3621 datasets().
Add(datasetName, expected ?
"asimov" :
"toy");
3622 }
catch (
const std::exception &
e) {
3625 (
gROOT->GetListOfBrowsers()->At(0))
3628 "Exception",
e.what(),
3634 double highX ,
const char *constParValues)
3643 for (
auto &
d : _dsets) {
3644 if (
d->get()->TestBit(1 << 20)) {
3645 dsetName =
d->get()->GetName();
3649 auto _pars =
pars();
3650 std::unique_ptr<RooAbsCollection> snap(_pars.argList().snapshot());
3653 auto idx = pattern.
Index(
'=');
3656 (idx == -1) ? std::numeric_limits<double>::quiet_NaN() :
TString(pattern(idx + 1, pattern.
Length())).
Atof();
3657 for (
auto par : _pars.argList()) {
3659 par->setAttribute(
"Constant",
true);
3660 if (!std::isnan(val)) {
3673 hs.SetTitle(sWhat +
" scan" + ((dsetName !=
"") ?
TString::Format(
" [data=%s]", dsetName.
Data()) :
""));
3674 int scanStatus = hs.scan(sWhat +
" visualize", nBinsX, lowX, highX);
3675 if (scanStatus != 0) {
3678 (
gROOT->GetListOfBrowsers()->At(0))
3681 "Scan Finished with Bad Status Code",
3682 TString::Format(
"%s\nData = %s\nScan Status Code = %d", hs.GetName(), dsetName.
Data(), scanStatus),
3687 if (
auto res = hs.result())
3691 _pars.argList() = *snap;
3693 }
catch (
const std::exception &
e) {
3696 (
gROOT->GetListOfBrowsers()->At(0))
3707 }
catch (
const std::exception &
e) {
3716#if ROOT_VERSION_CODE > ROOT_VERSION(6, 29, 00)
3721 for (
auto a : *
this) {
3728 for (
auto c : args) {
3734 f.SetParName(i,
c->GetName());
3736 f.SetParLimits(i,
v->getMin(),
v->getMax());
3737 if (
v->isConstant())
3738 f.FixParameter(i,
v->getVal());
3740 f.SetParameter(i,
v->getVal());
3741 f.SetParError(i,
v->getError());
3752 (
gROOT->GetListOfBrowsers()->At(0))
3758 for (i = 0; i <
f.GetNpar(); i++) {
3759 auto c = args.
find(
f.GetParName(i));
3764 f.GetParLimits(i, low, high);
3766 v->setConstant(low);
3768 v->setRange(low, high);
3778 throw std::runtime_error(
"Failed to SetContent");
3779 }
catch (
const std::exception &
e) {
3793 std::shared_ptr<TH1D>
h;
3794 auto _b =
dynamic_cast<Axis2 *
>(ax)->binning();
3797 if (_b->isUniform()) {
3802 h->SetOption(
"nostyle");
3803 h->SetDirectory(
nullptr);
3805 h->GetXaxis()->SetName(
TString::Format(
"%s;%s", ax->GetParent()->GetName(), ax->GetName()));
3813 if (get<RooProduct>()) {
3817 if (get<RooAbsData>()) {
3818 if (
auto _data = get<RooDataSet>(); _data) {
3819 auto _ax = (bin) ?
GetXaxis() :
nullptr;
3821 throw std::runtime_error(
"Cannot determine binning to fill data");
3823 if (_ax && _ax->GetNbins() < bin) {
3824 throw std::out_of_range(
TString::Format(
"%s range %s only has %d bins", _ax->GetParent()->GetName(),
3825 _ax->GetName(), _ax->GetNbins()));
3831 for (
auto _c :
coords()) {
3835 cut +=
TString::Format(
"%s==%d", _cat->GetName(), _cat->getCurrentIndex());
3842 TString::Format(
"%s>=%f&&%s<%f", _rv->GetName(), _rv->getMin(_rv->getStringAttribute(
"coordRange")),
3843 _rv->GetName(), _rv->getMax(_rv->getStringAttribute(
"coordRange")));
3846 throw std::runtime_error(
"SetBinContent of data: Unsupported coordinate type");
3855 cut2 =
TString::Format(
"%s >= %f && %s < %f", _ax->GetParent()->GetName(), _ax->GetBinLowEdge(bin),
3856 _ax->GetParent()->GetName(), _ax->GetBinUpEdge(bin));
3888 l.remove(*_data->get(),
true,
true);
3893 _data->addColumn(*
x);
3903 for (
auto &o :
obs) {
3905 if (
auto dv =
dynamic_cast<RooRealVar *
>(_data->get()->find(
v->GetName())); dv) {
3906 if (
v->getMin() < dv->getMin())
3907 dv->setMin(
v->getMin());
3908 if (
v->getMax() > dv->getMax())
3909 dv->setMax(
v->getMax());
3912 if (
auto dc =
dynamic_cast<RooCategory *
>(_data->get()->find(
c->GetName())); dc) {
3913 if (!dc->hasLabel(
c->getCurrentLabel())) {
3914 dc->defineType(
c->getCurrentLabel(),
c->getCurrentIndex());
3923 if (
auto _nentries = std::unique_ptr<RooAbsData>(_data->reduce(cutFormula))->numEntries();
3924 _nentries != _ax->GetNbins()) {
3927 if (_nentries > 0) {
3928 Info(
"SetBinContent",
"Binning %s in channel: %s",
GetName(), cut.
Data());
3929 auto _reduced = std::unique_ptr<RooAbsData>(_data->reduce(icutFormula));
3931 for (
int j = 0; j < _reduced->numEntries(); j++) {
3932 auto _obs = _reduced->get(j);
3933 _data->add(*_obs, _reduced->weight());
3936 for (
int i = 1; i <= _ax->GetNbins(); i++) {
3940 dynamic_cast<RooAbsLValue *
>(_ax->GetParent())->setBin(i - 1, _ax->GetName());
3941 _data->add(
obs, _contents.
at(i - 1));
3946 if (std::unique_ptr<RooAbsData>(_data->reduce(cutFormula2))->numEntries() > 0) {
3947 auto _reduced = std::unique_ptr<RooAbsData>(_data->reduce(icutFormula2));
3949 for (
int j = 0; j < _reduced->numEntries(); j++) {
3950 auto _obs = _reduced->get(j);
3951 _data->add(*_obs, _reduced->weight());
3955 dynamic_cast<RooAbsLValue *
>(_ax->GetParent())->setBin(bin - 1, _ax->GetName());
3958 return bb->SetBinContent(bin,
value, par, parVal);
3961 }
else if (get<RooDataHist>()) {
3962 throw std::runtime_error(
"RooDataHist not supported yet");
3966 if (
auto _varies =
variations(); !_varies.empty() || (par && strlen(par))) {
3967 if (!par || strlen(par) == 0) {
3968 return _varies[
"nominal"]->SetBinContent(bin,
value, par, parVal);
3969 }
else if (
auto it = _varies.find(
Form(
"%s=%g", par, parVal)); it) {
3970 return it->SetBinContent(bin,
value);
3982 if (!par || strlen(par) == 0) {
3995 if (strcmp(
c->GetName(),
Form(
"%g",
c->getVal())) == 0) {
3998#if ROOT_VERSION_CODE < ROOT_VERSION(6, 24, 00)
4011 auto bin_pars =
f->dataHist().get(bin - 1);
4012 if (
f->getAttribute(
"density")) {
4013 value /=
f->dataHist().binVolume(*bin_pars);
4015 f->dataHist().set(*bin_pars,
value);
4018 if (
auto otherfName =
f->getStringAttribute(
"symmetrized_by"); otherfName) {
4020 f->setStringAttribute(
"symmetrized_by",
nullptr);
4021 if (
auto x = getObject<RooAbsArg>(otherfName);
x) {
4022 x->setStringAttribute(
"symmetrizes",
nullptr);
4023 x->setStringAttribute(
"symmetrize_nominal",
nullptr);
4025 }
else if (
auto otherfName2 =
f->getStringAttribute(
"symmetrizes"); otherfName2) {
4026 auto nomf = getObject<RooHistFunc>(
f->getStringAttribute(
"symmetrize_nominal"));
4027 auto otherf = getObject<RooHistFunc>(otherfName2);
4028 if (nomf && otherf) {
4029 otherf->dataHist().set(*bin_pars, 2 * nomf->dataHist().weight(bin - 1) -
value);
4030 otherf->setValueDirty();
4037 f2->setNominal(
value);
4046 push_back(std::make_shared<xRooNode>(
data));
4053 return node->SetBinContent(bin,
value);
4060 push_back(std::make_shared<xRooNode>(
data));
4067 return node->SetContents(obj);
4074 if (get<RooProduct>()) {
4078 if (
auto _varies =
variations(); !_varies.empty()) {
4079 return _varies[
"nominal"]->SetBinError(bin,
value);
4094 while (_prodParent && !_prodParent->get<
RooProduct>() && !_prodParent->get<
RooAbsPdf>()) {
4096 _prodParent.reset();
4099 _prodParent = _prodParent->fParent;
4102 (_prodParent && !_prodParent->get<
RooAbsPdf>()) ? _prodParent->factors().find(
"statFactor") :
nullptr;
4103 auto f_stat = (_f_stat) ? _f_stat->get<
ParamHistFunc>() :
nullptr;
4104 if (_f_stat && _f_stat->get() && !f_stat) {
4105 throw std::runtime_error(
"stat factor must be a paramhistfunc");
4114 for (
auto &
p :
xRooNode(
"tmp", *
f, std::shared_ptr<xRooNode>(
nullptr)).
vars()) {
4119 auto h = std::unique_ptr<TH1>(
f->dataHist().createHistogram(parNames
4126 h->SetName(
"statFactor");
4128 h->SetOption(
"blankshape");
4131 auto toMultiply =
this;
4135 f_stat =
dynamic_cast<ParamHistFunc *
>(toMultiply->Multiply(*h).get());
4137 throw std::runtime_error(
"Failed creating stat shapeFactor");
4143 TString prefix =
f->getStringAttribute(
"statPrefix");
4144 if (
value && prefix ==
"") {
4148 while (_p && !(_p->get()->InheritsFrom(
"RooRealSumPdf") || _p->get()->InheritsFrom(
"RooAddPdf") ||
4149 _p->get()->InheritsFrom(
"RooWorkspace") || _p->get()->InheritsFrom(
"RooAddition"))) {
4154 auto newVar = (
value == 0) ? getObject<RooRealVar>(
"1")
4155 : acquire<RooRealVar>(
Form(
"%s_bin%d", prefix.
Data(), bin),
4156 Form(
"%s_bin%d", prefix.
Data(), bin), 1);
4157#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
4162 auto var =
dynamic_cast<RooRealVar *
>(&pSet[bin - 1]);
4164 if (newVar.get() != var) {
4168 for (std::size_t i = 0; i < pSet.
size(); i++) {
4169 if (
int(i) != bin - 1) {
4170 all.
add(*pSet.
at(i));
4181 if (strcmp(rrv->GetName(),
"1") != 0) {
4182 TString origName = (
f->getStringAttribute(
"origName")) ?
f->getStringAttribute(
"origName") :
GetName();
4184 auto bin_pars =
f->dataHist().get(bin - 1);
4185 auto _binContent =
f->dataHist().weight();
4186 if (
f->getAttribute(
"density")) {
4187 _binContent *=
f->dataHist().binVolume(*bin_pars);
4192 for (
auto &[s, sv] : rrv->stringAttributes()) {
4193 if (s.find(
"sumw_") == 0) {
4195 }
else if (s.find(
"sumw2_") == 0) {
4199 if (sumw2 && sumw2 != std::numeric_limits<double>::infinity()) {
4200 double tau = pow(sumw, 2) / sumw2;
4201 rrv->setError((tau < 1
e-15) ? 1e15 : ( 1. / sqrt(tau)));
4202 rrv->setConstant(
false);
4204 auto _constr =
v.constraints();
4206 if (_constr.empty()) {
4207 rrv->setStringAttribute(
"boundConstraint", _constr.Add(
"poisson").get()->GetName());
4209 auto _glob = _constr.at(0)->obs().at(0)->get<
RooRealVar>();
4212 double _min = tau * (1. - 5. * sqrt(1. / tau));
4213 double _max = tau * (1. + 5. * sqrt(1. / tau));
4214 _glob->setRange(_min, _max);
4216 _constr.at(0)->pp().at(0)->SetBinContent(0, tau);
4217 rrv->setStringAttribute(
"boundConstraint", _constr.at(0)->get()->GetName());
4219 rrv->setRange(std::max((1. - 5. * sqrt(1. / tau)), 1
e-15), 1. + 5. * sqrt(1. / tau));
4222 if (
auto _constr =
v.constraints(); !_constr.empty()) {
4223 v.constraints().Remove(*_constr.at(0));
4228 rrv->setConstant(sumw2 == 0);
4240 auto res =
find(
name, browseResult);
4242 throw std::out_of_range(
name +
" does not exist");
4251 if (
auto _w = get<RooWorkspace>(); _w)
4253 if (
auto a = get<RooAbsArg>();
a &&
GETWS(
a)) {
4264 xRooNode out(
".constraints",
nullptr, *
this);
4267 getConstraint = [&](
const xRooNode &
n,
RooAbsArg &par, std::set<RooAbsPdf *> ignore) {
4269 if (ignore.count(_pdf))
4271 ignore.insert(_pdf);
4277 for (
auto &
c :
n.bins()) {
4278 if (
auto oo = getConstraint(*
c, par, ignore); oo) {
4288 for (
auto p : _ws->allPdfs()) {
4289 if (ignore.count(
static_cast<RooAbsPdf *
>(
p)))
4291 if (
p->dependsOn(par)) {
4292 out.emplace_back(std::make_shared<xRooNode>(par.GetName(), *
p, *
this));
4298 return getConstraint(*
n.fParent, par, ignore);
4300 for (
auto p : o->pdfList()) {
4301 if (ignore.count(
static_cast<RooAbsPdf *
>(
p)))
4303 if (
p->dependsOn(par)) {
4304 out.emplace_back(std::make_shared<xRooNode>(par.GetName(), *
p, *
this));
4310 for (
auto &
p :
vars()) {
4314 if (
v->getAttribute(
"Constant") &&
v != get<RooAbsReal>())
4316 if (
v->getAttribute(
"obs"))
4318 getConstraint(*
this, *
v, {get<RooAbsPdf>()});
4326 auto it = out.std::vector<std::shared_ptr<xRooNode>>
::begin();
4327 while (it != out.std::vector<std::shared_ptr<xRooNode>>
::end()) {
4328 bool removeIt =
false;
4329 for (
auto &
c : out) {
4330 if (
c.get() == it->get())
4334 std::set<std::string> parNames;
4335 std::string _cName =
c->GetName();
4337 parNames.insert(_cName.substr(0, _cName.find(
';')));
4338 _cName = _cName.substr(_cName.find(
';') + 1);
4339 }
while (_cName.find(
';') != std::string::npos);
4340 parNames.insert(_cName);
4341 _cName = it->get()->GetName();
4343 parNames.insert(_cName.substr(0, _cName.find(
';')));
4344 _cName = _cName.substr(_cName.find(
';') + 1);
4345 }
while (_cName.find(
';') != std::string::npos);
4346 parNames.insert(_cName);
4348 for (
auto &
x : parNames) {
4349 if (!_cName.empty())
4353 c->TNamed::SetName(_cName.c_str());
4366 if (get<RooAbsArg>() && get<RooAbsArg>()->isFundamental()) {
4367 for (
auto &o : out) {
4368 o->TNamed::SetName(o->get()->GetName());
4382 sName =
TString(
"factory:") + sName;
4386 if (
auto h = get<TH1>();
h) {
4388 std::map<std::string, std::string> stringAttrs;
4390 auto pos = sOpt2.
Index(
"=");
4391 auto start = sOpt2.
Index(
";") + 1;
4397 stringAttrs[sOpt2(start, pos - start)] = sOpt2(pos + 1,
end - pos - 1);
4403 origName = origName(1, origName.
Length());
4406 newObjName(1, newObjName.
Length());
4413 TString varName =
h->GetXaxis()->GetName();
4414 std::string binningName = newObjName.
Data();
4415 if (
auto pos = varName.
Index(
';'); pos != -1) {
4416 binningName = varName(pos + 1, varName.
Length());
4417 varName = varName(0, pos);
4420 if (varName ==
"xaxis" &&
4422 if (
auto ax = acquirer.
GetXaxis(); ax) {
4423 varName = ax->GetParent()->GetName();
4425 binningName = ax->GetName();
4426 }
else if (acquirer.
obs().size() == 1)
4427 varName = acquirer.
obs().
at(0)->get()->GetName();
4429 auto x = acquirer.
acquire<
RooRealVar>(varName,
h->GetXaxis()->GetTitle(),
h->GetXaxis()->GetXmin(),
4430 h->GetXaxis()->GetXmax());
4431 if (
x->getMin() >
h->GetXaxis()->GetXmin())
4432 x->setMin(
h->GetXaxis()->GetXmin());
4433 if (
x->getMax() <
h->GetXaxis()->GetXmax())
4434 x->setMax(
h->GetXaxis()->GetXmax());
4435 if (!
x->hasBinning(binningName.c_str())) {
4436 if (
h->GetXaxis()->IsVariableBinSize()) {
4437 x->setBinning(
RooBinning(
h->GetNbinsX(),
h->GetXaxis()->GetXbins()->GetArray()), binningName.c_str());
4440 RooUniformBinning(
h->GetXaxis()->GetXmin(),
h->GetXaxis()->GetXmax(),
h->GetXaxis()->GetNbins()),
4441 binningName.c_str());
4443 x->getBinning(binningName.c_str()).
SetTitle(
h->GetXaxis()->GetTitle());
4444 if (
x->getBinningNames().size() == 2) {
4446 x->setBinning(
x->getBinning(binningName.c_str()));
4450 if (
x->getBinning(binningName.c_str()).numBins() !=
h->GetNbinsX()) {
4451 throw std::runtime_error(
4452 TString::Format(
"binning mismatch for binning %s of %s", binningName.c_str(),
x->GetName()));
4456 std::shared_ptr<RooAbsArg> _f;
4462 for (
auto &[k,
v] : stringAttrs) {
4465 x->setAttribute(
"obs",
true);
4466 }
else if (sOpt2.
Contains(
"shape")) {
4468 for (
int i = 0; i <
x->getBinning(binningName.c_str()).numBins(); i++) {
4469 std::shared_ptr<RooAbsArg> arg;
4470 if (sOpt2.
Contains(
"blankshape")) {
4476 if (
h->GetMinimumStored() != -1111 ||
h->GetMaximumStored() != -1111) {
4478 h->GetBinContent(i + 1),
h->GetMinimumStored(),
4479 h->GetMaximumStored());
4482 h->GetBinContent(i + 1));
4489 auto tmp =
dynamic_cast<RooAbsBinning *
>(
x->getBinningPtr(
nullptr)->Clone());
4490 x->setBinning(
x->getBinning(binningName.c_str()));
4492#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
4493 dynamic_cast<ParamHistFunc *
>(_f.get())->_paramSet.setName(
"paramSet");
4496 .setName(
"paramSet");
4498 x->setBinning(*tmp);
4500 for (
auto &[k,
v] : stringAttrs) {
4501 _f->setStringAttribute(k.c_str(),
v.c_str());
4505 binningName.c_str() );
4507 throw std::runtime_error(
"Couldn't make data hist");
4512 f->setAttribute(
"autodensity");
4515 for (
auto &[k,
v] : stringAttrs) {
4516 _f->setStringAttribute(k.c_str(),
v.c_str());
4520 _f->setStringAttribute(
"xvar",
x->GetName());
4521 _f->setStringAttribute(
"binning", binningName.c_str());
4522 if (strcmp(_f->GetName(), origName.
Data()) && !_f->getStringAttribute(
"alias"))
4523 _f->setStringAttribute(
"alias", origName);
4526 xRooNode tmp(
h->GetName(), _f, acquirer);
4528 _f = std::dynamic_pointer_cast<RooAbsArg>(tmp.fComp);
4531 _f->setStringAttribute(
"xvar",
x->GetName());
4532 _f->setStringAttribute(
"binning", binningName.c_str());
4535 if (strcmp(_f->GetName(), origName.
Data()) && !_f->getStringAttribute(
"alias"))
4536 _f->setStringAttribute(
"alias", origName);
4554 auto arg = get<RooAbsArg>();
4555 if (!initObject && !arg && !
gROOT->GetStyle(t)) {
4559 std::unique_ptr<TObject> argInitObject;
4564 if (arg->getStringAttribute(
"style")) {
4565 t = arg->getStringAttribute(
"style");
4566 }
else if (autoCreate) {
4568 argInitObject = std::make_unique<TH1D>(
GetName(),
GetTitle(), 1, 0, 1);
4569 initObject = argInitObject.get();
4575 std::shared_ptr<TStyle>
style;
4577 if (!
gROOT->GetStyle(t)) {
4578 if ((
style = getObject<TStyle>(t.
Data()))) {
4588 if (
auto x =
dynamic_cast<TAttLine *
>(initObject))
4590 if (
auto x =
dynamic_cast<TAttFill *
>(initObject))
4592 if (
auto x =
dynamic_cast<TAttMarker *
>(initObject))
4600 if (arg && !arg->getStringAttribute(
"style")) {
4601 arg->setStringAttribute(
"style",
style->GetName());
4607std::shared_ptr<TObject>
xRooNode::acquire(
const std::shared_ptr<TObject> &arg,
bool checkFactory,
bool mustBeNew)
4612 return fParent->acquire(arg, checkFactory, mustBeNew);
4616 if (_ws && (
get() == _ws || _ws->arg(
GetName()) || (arg && strcmp(arg->GetName(),
GetName()) == 0))) {
4619 if (
auto a =
dynamic_cast<RooAbsArg *
>(arg.get());
a) {
4620 auto out_arg = _ws->arg(
a->GetName());
4621 TString aName = arg->GetName();
4623 while (out_arg && mustBeNew) {
4625 out_arg = _ws->arg(
a->GetName());
4627 if (aName !=
a->GetName())
4628 Warning(
"acquire",
"Renaming to %s",
a->GetName());
4632 if (
auto res = _ws->factory(arg->GetName()); res) {
4639 Info(
"acquire",
"A copy of %s has been added to workspace %s",
a->GetName(), _ws->GetName());
4645 std::set<std::string> setNames;
4648 setNames.insert(aa.first);
4651 for (
auto &aa : setNames)
4653 out_arg = _ws->arg(
a->GetName());
4654 if (
GETWS(out_arg) != _ws) {
4655 out_arg->setWorkspace(*_ws);
4659 return std::shared_ptr<TObject>(out_arg, [](
TObject *) {});
4660 }
else if (
auto a2 =
dynamic_cast<RooAbsData *
>(arg.get()); a2) {
4666 return std::shared_ptr<TObject>(_ws->embeddedData(arg->GetName()), [](
TObject *) {});
4667 }
else if (arg->InheritsFrom(
"RooFitResult") || arg->InheritsFrom(
"TTree") || arg->IsA() ==
TStyle::Class() ||
4668 arg->
InheritsFrom(
"RooStats::HypoTestInverterResult") ||
4669 arg->InheritsFrom(
"RooStats::HypoTestResult")) {
4672 TString aName = arg->GetName();
4673 TObject *out_arg = _ws->genobj(arg->GetName());
4675 while (aNamed && out_arg && mustBeNew) {
4677 out_arg = _ws->genobj(aNamed->
GetName());
4680 if (aName != arg->GetName()) {
4681 Warning(
"acquire",
"Renaming to %s", arg->GetName());
4683 if (_ws->import(*arg,
false )) {
4687 out_arg = _ws->genobj(arg->GetName());
4705 return std::shared_ptr<TObject>(out_arg, [](
TObject *) {});
4712 auto out =
fProvider->getObject(arg->GetName(), arg->ClassName());
4716 auto _owned =
find(
".memory");
4718 _owned = emplace_back(std::make_shared<xRooNode>(
".memory",
nullptr, *
this));
4723 for (
auto &
r : *_owned) {
4724 if (strcmp(
r->GetName(), arg->GetName()) == 0 && strcmp(
r->get()->ClassName(), arg->ClassName()) == 0) {
4730 std::cout <<
GetName() <<
" taking over " << arg->ClassName() <<
"::" << arg->GetName() << std::endl;
4732 return _owned->emplace_back(std::make_shared<xRooNode>(arg->GetName(), arg, *
this))->fComp;
4760 auto _deps =
vars();
4772 auto a = get<RooAbsArg>();
4774 throw std::runtime_error(
"Cannot SetXaxis of non-arg");
4776 auto _x = acquire<RooRealVar>(
name, title, low, high);
4777 _x->setBinning(binning,
a->
GetName());
4778 _x->getBinning(
a->GetName()).SetTitle(title);
4779 if (_x->getBinningNames().size() == 2) {
4781 _x->setBinning(_x->getBinning(
a->GetName()));
4786 if (_x->getMax() < high)
4788 if (_x->getMin() > low)
4792 if (!_deps.find(
name) && get<RooAbsPdf>()) {
4794 _x->setAttribute(
"obs");
4797 a->setStringAttribute(
"xvar", _x->GetName());
4798 a->setStringAttribute(
"binning",
a->GetName());
4817 return find(
name,
false) !=
nullptr;
4822 std::string partname = (
name.find(
'/') != std::string::npos) ?
name.substr(0,
name.find(
'/')) :
name;
4824 : get<RooSimultaneous>();
4825 std::string extra = (_s) ? _s->indexCat().GetName() :
"";
4826 for (
auto &
child : *
this) {
4828 (_obj &&
name == _obj->GetName()) || (_obj && partname == _obj->GetName()) ||
4829 (!extra.empty() && ((extra +
"=" +
name) ==
child->GetName() ||
4830 (extra +
"=" + partname) ==
child->GetName()))) {
4834 return child->at(
name.substr(partname.length() + 1));
4840 for (
auto &child2 :
x.browse()) {
4841 if (
auto _obj = child2->get();
name == child2->GetName() || partname == child2->GetName() ||
4842 (_obj &&
name == _obj->GetName()) || (_obj && partname == _obj->GetName())) {
4845 if (partname !=
name &&
name != child2->GetName()) {
4846 return child2->at(
name.substr(partname.length() + 1));
4855 auto child2 =
at(s.Atoi());
4856 if (partname !=
name) {
4857 return child2->at(
name.substr(partname.length() + 1));
4866 std::string partname = (
name.find(
'/') != std::string::npos) ?
name.substr(0,
name.find(
'/')) :
name;
4869 : get<RooSimultaneous>();
4870 std::string extra = (_s) ? _s->indexCat().GetName() :
"";
4871 std::shared_ptr<xRooNode> folderNode;
4872 for (
auto &
child : *
this) {
4875 ((extra +
"=" +
name) ==
child->GetName() || (extra +
"=" + partname) ==
child->GetName()))) {
4878 return child->operator[](
name.substr(partname.length() + 1));
4884 for (
auto &child2 :
x.browse()) {
4885 if (
name == child2->GetName() || partname == child2->GetName()) {
4887 if (partname !=
name &&
name != child2->GetName()) {
4888 return child2->operator[](
name.substr(partname.length() + 1));
4894 if (
child->fFolder == (std::string(
"!") + partname)) {
4896 folderNode = std::make_shared<xRooNode>(
child->fFolder.c_str(),
nullptr, *
this);
4897 folderNode->push_back(
child);
4901 if (partname !=
name) {
4902 return folderNode->operator[](
name.substr(partname.length() + 1));
4908 auto child2 =
at(s.Atoi());
4909 if (partname !=
name) {
4910 return child2->operator[](
name.substr(partname.length() + 1));
4914 auto out = std::make_shared<xRooNode>(partname.c_str(),
nullptr, *
this);
4915 if (partname !=
name) {
4916 return out->operator[](
name.substr(partname.length() + 1));
4924 for (
auto o : *
gROOT->GetListOfBrowsers()) {
4926 if (!
b || !
b->GetBrowserImp())
4933 if (!
b->GetBrowserImp())
4949 for (
auto o : *
gROOT->GetListOfBrowsers()) {
4951 if (!
b || !
b->GetBrowserImp())
4958 if (
b->GetBrowserImp()) {
4964 if (
auto item =
GETLISTTREE(_b)->FindItemByObj(_root,
const_cast<xRooNode *
>(
this)); item) {
4975 if (
auto a = get<RooAbsArg>();
a)
4976 a->setStringAttribute(
"alias",
name);
4977 for (
auto o : *
gROOT->GetListOfBrowsers()) {
4978 if (
auto b =
dynamic_cast<TBrowser *
>(o);
b) {
4980 item->SetText(
name);
4988 if (
auto o = (get<TNamed>()); o) {
5003 auto findByObj = [&](
const std::shared_ptr<xRooNode> &
n) {
5004 std::vector<std::shared_ptr<xRooNode>> &nn = *
this;
5005 for (
auto &
c : nn) {
5006 if (
c->get() ==
n->get() && strcmp(
n->GetName(),
c->GetName()) == 0)
5009 return std::shared_ptr<xRooNode>(
nullptr);
5012 auto appendChildren = [&](
const xRooNode &
n) {
5014 const std::vector<std::shared_ptr<xRooNode>> &nn(
n);
5015 for (
auto &
c : nn) {
5016 if (
auto existing = findByObj(
c); existing) {
5018 existing->fFolder =
c->fFolder;
5028 const std::vector<std::shared_ptr<xRooNode>> &nn2(*
this);
5029 for (
auto &
c : nn2) {
5030 if (strlen(
c->GetName()) > 0 && (
c->GetName()[0] ==
'.')) {
5034 if (strcmp(
c->GetName(),
"!.pars") == 0) {
5045 size_t addedChildren = 0;
5049 if (get<RooWorkspace>()) {
5050 addedChildren += appendChildren(
datasets());
5064 addedChildren += appendChildren(
components());
5065 if (!get<RooWorkspace>())
5066 addedChildren += appendChildren(
factors());
5068 auto _coefs =
coefs();
5069 if (_coefs.get() && strcmp(_coefs->GetName(),
"1") != 0 && strcmp(_coefs->GetName(),
"ONE") != 0) {
5070 if (_coefs.size() == 1 && _coefs.get<
RooAddition>()) {
5071 if (strcmp(_coefs.at(0)->GetName(),
"1") != 0 &&
5072 strcmp(_coefs.at(0)->GetName(),
"ONE") != 0) {
5073 auto coef = std::make_shared<xRooNode>(
".coef", *_coefs.at(0)->get(), *
this);
5074 if (
auto existing = findByObj(coef); existing) {
5076 existing->fFolder = _coefs.at(0)->fFolder;
5082 if (
auto existing =
find(_coefs.GetName()); existing) {
5084 existing->fFolder = _coefs.fFolder;
5086 emplace_back(std::make_shared<xRooNode>(_coefs));
5090 addedChildren += appendChildren(
variations());
5091 if (get<ParamHistFunc>() || get<RooSimultaneous>())
5092 addedChildren += appendChildren(
bins());
5093 if (get<RooAbsData>())
5094 addedChildren += appendChildren(
obs());
5097 if (
auto arg = get<RooAbsArg>(); arg && addedChildren == 0) {
5098 for (
int i = 0; i < arg->numProxies(); i++) {
5099 auto _proxy = arg->getProxy(i);
5101 auto c = std::make_shared<xRooNode>(
TString::Format(
".%s", _proxy->name()), *(
a->absArg()), *
this);
5102 if (
auto existing = findByObj(
c); existing) {
5104 existing->fFolder =
c->fFolder;
5109 for (
auto a2 : *s) {
5110 auto c = std::make_shared<xRooNode>(*a2, *
this);
5111 if (arg->numProxies() != 1) {
5112 c->fFolder = std::string(
"!.") +
5115 if (
auto existing = findByObj(
c); existing) {
5117 existing->fFolder =
c->fFolder;
5133 }
else if (
auto ir = get<RooStats::HypoTestInverterResult>()) {
5137 if (strcmp(
c->GetName(),
".memory") == 0 &&
c->get<
xRooHypoSpace>()) {
5145 fBrowsables.emplace_back(std::make_shared<xRooNode>(
".memory", std::make_shared<xRooHypoSpace>(ir), *
this));
5152 for (
auto a : _axes) {
5153 if (
a != _axes.first())
5156 TString::Format(
"%s=%g",
a->GetName(), hp.coords->getRealValue(
a->GetName(), ir->GetXValue(i)));
5158 auto hpn = emplace_back(std::make_shared<xRooNode>(coordString, hp.hypoTestResult, hs));
5160 hpn->fBrowsables.emplace_back(std::make_shared<xRooNode>(
5166 std::vector<std::shared_ptr<xRooNode>> &nn = *
this;
5167 for (
auto &
c : nn) {
5177 }
else if (get<RooStats::HypoTestResult>()) {
5190 std::make_shared<xRooNLLVar::xRooHypoPoint>(std::dynamic_pointer_cast<RooStats::HypoTestResult>(
fComp));
5191 fBrowsables.emplace_back(std::make_shared<xRooNode>(
".memory", shp, *
this));
5197 if (
auto fit = hp->
ufit()) {
5198 fits.emplace_back(std::make_shared<xRooNode>(fit, *
this))->TNamed::SetName(
"ufit");
5201 fits.emplace_back(std::make_shared<xRooNode>(fit, *
this))->TNamed::SetName(
"cfit_null");
5204 fits.emplace_back(std::make_shared<xRooNode>(fit, *
this))->TNamed::SetName(
"cfit_alt");
5206 if (
auto fit = hp->
gfit()) {
5207 fits.emplace_back(std::make_shared<xRooNode>(fit, *
this))->TNamed::SetName(
"gfit");
5209 if (
auto asi = hp->
asimov()) {
5210 auto asiP = fits.emplace_back(std::make_shared<xRooNode>(
5211 asi->hypoTestResult ? asi->hypoTestResult : std::make_shared<RooStats::HypoTestResult>(asi->result()),
5213 asiP->TNamed::SetName(
"asimov");
5214 asiP->fBrowsables.emplace_back(std::make_shared<xRooNode>(
".memory", asi, asiP));
5216 appendChildren(fits);
5220 auto it = std::vector<std::shared_ptr<xRooNode>>
::begin();
5221 while (it != std::vector<std::shared_ptr<xRooNode>>
::end()) {
5222 if (it->get()->fTimes == 0) {
5223 for (
auto o : *
gROOT->GetListOfBrowsers()) {
5225 if (
b &&
b->GetBrowserImp()) {
5234 if (
auto item =
GETLISTTREE(_b)->FindItemByObj(_root,
this); item) {
5272 xRooNode out(
".obs", std::make_shared<RooArgList>(), *
this);
5274 for (
auto o :
vars()) {
5277 out.emplace_back(o);
5288 xRooNode out(
".globs", std::make_shared<RooArgList>(), *
this);
5290 for (
auto o :
obs()) {
5293 out.emplace_back(o);
5304 xRooNode out(
".robs", std::make_shared<RooArgList>(), *
this);
5306 for (
auto o :
obs()) {
5309 out.emplace_back(o);
5324 xRooNode out(
".pars", std::make_shared<RooArgList>(), *
this);
5326 for (
auto o :
vars()) {
5329 out.emplace_back(o);
5340 xRooNode out(
".consts", std::make_shared<RooArgList>(), *
this);
5342 for (
auto o :
pars()) {
5345 out.emplace_back(o);
5357 xRooNode out(
".floats", std::make_shared<RooArgList>(), *
this);
5359 for (
auto o :
pars()) {
5362 out.emplace_back(o);
5374 xRooNode out(
".poi", std::make_shared<RooArgList>(), *
this);
5376 for (
auto o :
pars()) {
5379 out.emplace_back(o);
5391 xRooNode out(
".np", std::make_shared<RooArgList>(), *
this);
5393 for (
auto o :
pars()) {
5395 (!o->get<
RooAbsArg>()->getAttribute(
"Constant") && !o->get<
RooAbsArg>()->getAttribute(
"poi") &&
5398 out.emplace_back(o);
5409 xRooNode out(
".pp", std::make_shared<RooArgList>(), *
this);
5411 for (
auto o :
pars()) {
5415 out.emplace_back(o);
5426 xRooNode out(
".vars", std::make_shared<RooArgList>(), *
this);
5428 if (
auto coll = get<RooAbsCollection>(); coll) {
5429 for (
auto &
x : *
this) {
5430 for (
auto &
y :
x->vars()) {
5436 if (
auto p = get<RooAbsArg>();
p) {
5442 p->leafNodeServerList(&allLeaves);
5443 for (
auto &
c : allLeaves) {
5445 if (!
c->getAttribute(
"global")) {
5447 out.emplace_back(std::make_shared<xRooNode>(*
c, *
this));
5449 if (
c->getAttribute(
"global")) {
5450 _globs.emplace_back(std::make_shared<xRooNode>(*
c, *
this));
5451 _globs.back()->fFolder =
"!globs";
5452 }
else if (
c->getAttribute(
"obs")) {
5453 out.back()->fFolder =
"!robs";
5454 }
else if (
c->getAttribute(
"poi")) {
5455 out.back()->fFolder =
"!poi";
5456 }
else if (
c->getAttribute(
"np") ||
5458 out.back()->fFolder =
"!np";
5460 out.back()->fFolder =
"!floats";
5462 out.back()->fFolder =
"!pp";
5466 for (
auto g : _globs) {
5468 out.emplace_back(
g);
5470 }
else if (
auto p2 = get<RooAbsData>(); p2) {
5471 for (
auto a : *p2->get()) {
5472 a->setAttribute(
"obs");
5473 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
5476 if (
auto _dglobs = p2->getGlobalObservables()) {
5477 for (
auto &
a : *_dglobs) {
5478 a->setAttribute(
"obs");
5479 a->setAttribute(
"global");
5480 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
5485 a->setAttribute(
"obs");
5486 a->setAttribute(
"global");
5487 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
5490 }
else if (
auto _ws =
ws(); _ws) {
5492 for (
auto a : *_globs2) {
5493 a->setAttribute(
"obs");
5494 a->setAttribute(
"global");
5495 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
5499 for (
auto &_g : _gl->second) {
5500 auto _clone = std::shared_ptr<RooAbsArg>(
dynamic_cast<RooAbsArg *
>(_g->Clone(_g->GetName())));
5501 if (
auto v = std::dynamic_pointer_cast<RooAbsRealLValue>(_clone);
v && _g->getStringAttribute(
"nominal"))
5502 v->setVal(
TString(_g->getStringAttribute(
"nominal")).
Atof());
5503 out.emplace_back(std::make_shared<xRooNode>(_clone, *
this));
5511 for (
auto &_g : *_globs3) {
5512 auto _clone = std::shared_ptr<RooAbsArg>(
dynamic_cast<RooAbsArg *
>(_g->Clone(_g->GetName())));
5513 if (
auto v = std::dynamic_pointer_cast<RooAbsRealLValue>(_clone);
v && _g->getStringAttribute(
"nominal"))
5514 v->setVal(
TString(_g->getStringAttribute(
"nominal")).
Atof());
5515 out.emplace_back(std::make_shared<xRooNode>(_clone, *
this));
5520 }
else if (
auto w = get<RooWorkspace>();
w) {
5521 for (
auto a :
w->allVars()) {
5522 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
5526 for (
auto a :
w->allCats()) {
5527 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
5536 xRooNode out(
".components",
nullptr, *
this);
5538 if (
auto p = get<RooAddPdf>();
p) {
5540 std::set<RooAbsArg *> donePdfs;
5541 for (
auto &o :
p->pdfList()) {
5542 if (donePdfs.count(o))
5544 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
5547 }
else if (
auto p2 = get<RooRealSumPdf>(); p2) {
5561 std::set<RooAbsArg *> doneFuncs;
5562 for (
auto &o : p2->funcList()) {
5563 if (doneFuncs.count(o))
5565 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
5566 doneFuncs.insert(o);
5568 }
else if (
auto p3 = get<RooAddition>(); p3) {
5569 for (
auto &o : p3->list()) {
5570 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
5572 }
else if (
auto p4 = get<RooAbsCollection>(); p4) {
5573 for (
auto &
a : *p4) {
5574 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
5576 }
else if (
auto p5 = get<RooWorkspace>(); p5) {
5577 for (
auto &o : p5->components()) {
5580 bool hasClients =
false;
5581 for (
auto &
c : o->clients()) {
5582 if (!
c->InheritsFrom(
"RooRealIntegral") && p5 ==
GETWS(
c)) {
5589 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
5590 if (o->InheritsFrom(
"RooAbsPdf")) {
5591 out.back()->fFolder =
"!pdfs";
5593 out.back()->fFolder =
"!scratch";
5596 for (
auto &o : p5->allGenericObjects()) {
5600 s = s(0, s.
Index(
';'));
5601 if (
auto _pdf = out.find(s.
Data()); _pdf) {
5603 out.emplace_back(std::make_shared<xRooNode>(fr->GetName(), *fr, _pdf));
5610 out.emplace_back(std::make_shared<xRooNode>(fr->GetName(), *fr, *
this));
5612 out.back()->fFolder =
"!fits";
5614 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
5615 if (strcmp(out.back()->get()->ClassName(),
"TStyle") == 0) {
5616 out.back()->fFolder =
"!styles";
5617 }
else if (strcmp(out.back()->get()->ClassName(),
"RooStats::HypoTestInverterResult") == 0) {
5618 out.back()->fFolder =
"!scans";
5620 out.back()->fFolder =
"!objects";
5627 if (k.find(
"CACHE_") == 0)
5629 out.emplace_back(std::make_shared<xRooNode>(k.c_str(),
v, *
this));
5630 out.back()->fFolder =
"!sets";
5636 while ((snap = iter->Next())) {
5637 out.emplace_back(std::make_shared<xRooNode>(*snap, *
this));
5638 out.back()->fFolder =
"!snapshots";
5644 out.emplace_back(
c);
5651 out.emplace_back(
c);
5665 xRooNode out(
".bins",
nullptr, *
this);
5667 if (
auto p = get<RooSimultaneous>();
p) {
5668 std::map<int, std::shared_ptr<xRooNode>> cats;
5669 for (
auto &
c :
p->indexCat()) {
5670 auto pp =
p->getPdf(
c.first.c_str());
5676 for (
auto &[
_,
n] : cats)
5677 out.emplace_back(
n);
5678 }
else if (
auto phf = get<ParamHistFunc>(); phf) {
5680#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
5681 auto &pSet = phf->_paramSet;
5683 auto &pSet = phf->paramList();
5685 for (
auto par : pSet) {
5686 out.emplace_back(std::make_shared<xRooNode>(*par, *
this));
5687 out.back()->fBinNumber = i;
5690 }
else if (
auto ax =
GetXaxis(); ax) {
5691 for (
int i = 1; i <= ax->GetNbins(); i++) {
5693 std::vector<RooAbsArg *> _factors;
5697 for (
auto &ss :
f->bins()[i - 1]->factors())
5698 _factors.push_back(ss->get<
RooAbsArg>());
5700 _factors.push_back(
f->bins()[i - 1]->get<
RooAbsArg>());
5704 out.emplace_back(std::make_shared<xRooNode>(
5705 TString::Format(
"%g<=%s<%g", ax->GetBinLowEdge(i), ax->GetParent()->GetName(), ax->GetBinLowEdge(i + 1)),
5706 _factors.empty() ? nullptr
5710 for (
auto f : _factors) {
5711#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
5717 out.back()->fBinNumber = i;
5727 bool isResidual =
false;
5735 if (!parent->fComp) {
5736 while (!parent->fComp && parent->fParent) {
5737 parent = parent->fParent;
5740 parent = parent->fParent;
5746 for (
auto &o :
p->funcList()) {
5748 if (i >=
p->coefList().size()) {
5750 coefs.add(
p->coefList());
5752 coefs.add(*
p->coefList().at(i));
5757 }
else if (
auto p2 = parent->get<
RooAddPdf>(); p2) {
5759 if (p2->coefList().empty()) {
5764 for (
auto &o : p2->pdfList()) {
5766 if (i >= p2->coefList().size()) {
5768 coefs.add(p2->coefList());
5770 coefs.add(*p2->coefList().at(i));
5781 auto coefSum =
coefs.empty()
5784 : std::make_shared<RooAddition>((isResidual) ?
".sumOfCoefs" :
".coefs",
5785 "Coefficients of",
coefs));
5786 xRooNode out(
".coef", coefSum ? std::dynamic_pointer_cast<RooAbsArg>(std::make_shared<RooFormulaVar>(
5787 ".coef",
"1-sum(otherCoefs)",
"1. - @0", *coefSum))
5789 if (coefSum &&
coefs.size() != 1) {
5790 out.emplace_back(std::make_shared<xRooNode>(
".memory",
nullptr, *
this))
5792 std::make_shared<xRooNode>(
".sumOfCoefs", coefSum, out));
5794 if (!
coefs.empty()) {
5798 }
else if (
coefs.size() == 1) {
5800 if (!
coefs.empty()) {
5809 xRooNode out(
".coefs", coefSum, *
this);
5819 xRooNode out(
".factors",
nullptr, *
this);
5821 if (
auto p = get<RooProdPdf>();
p) {
5823 if (
auto a = _main.get<
RooRealSumPdf>();
a && !
a->getStringAttribute(
"alias")) {
5824 a->setStringAttribute(
"alias",
"samples");
5826 a2->setStringAttribute(
"alias",
"components");
5828 int _npdfs =
p->pdfList().size();
5829 for (
auto &o :
p->pdfList()) {
5830 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
5831 if (_npdfs > 5 && o != _main.get())
5832 out.back()->fFolder =
"!constraints";
5834 }
else if (
auto p2 = get<RooProduct>(); p2) {
5835 for (
auto &o : p2->components()) {
5836 if (o->InheritsFrom(
"RooProduct")) {
5840 out.emplace_back(std::make_shared<xRooNode>(
n->GetName(),
n->fComp, *
this));
5843 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
5846 }
else if (
auto w = get<RooWorkspace>();
w) {
5852 for (
auto a :
w->allFunctions()) {
5853 if (_obs.contains(*
a))
5856 for (
auto c :
a->clients()) {
5858 if (
c->InheritsFrom(
"RooProduct"))
5862 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
5906 xRooNode out(
".variations",
nullptr, *
this);
5918 if (
auto p2 = get<PiecewiseInterpolation>(); p2) {
5919#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
5920 out.emplace_back(std::make_shared<xRooNode>(
"nominal", p2->_nominal.arg(), *
this));
5922 out.emplace_back(std::make_shared<xRooNode>(
"nominal", *(p2->nominalHist()), *
this));
5924 for (
size_t i = 0; i < p2->paramList().
size(); i++) {
5926 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=1", p2->paramList().at(i)->GetName()),
5927 *p2->highList().at(i), *
this));
5928 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=-1", p2->paramList().at(i)->GetName()),
5929 *p2->lowList().at(i), *
this));
5931 }
else if (
auto p3 = get<RooStats::HistFactory::FlexibleInterpVar>(); p3) {
5932#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
5933 out.emplace_back(std::make_shared<xRooNode>(
"nominal",
RooFit::RooConst(p3->_nominal), *
this));
5934 for (
size_t i = 0; i < p3->_paramList.size(); i++) {
5935 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=1", p3->_paramList.at(i)->GetName()),
5937 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=-1", p3->_paramList.at(i)->GetName()),
5941 out.emplace_back(std::make_shared<xRooNode>(
"nominal",
RooFit::RooConst(p3->nominal()), *
this));
5942 for (
size_t i = 0; i < p3->variables().
size(); i++) {
5943 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=1", p3->variables().at(i)->GetName()),
5945 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=-1", p3->variables().at(i)->GetName()),
5950 }
else if (
auto p4 = get<ParamHistFunc>(); p4) {
5969 for (
auto &k : *
this) {
5978 xRooNode out(
".datasets()",
nullptr, *
this);
5983 if (
auto _ws = get<RooWorkspace>(); _ws) {
5984 for (
auto &
d : _ws->allData()) {
5985 out.emplace_back(std::make_shared<xRooNode>(*
d, *
this));
5986 out.back()->fFolder =
"!datasets";
5988 }
else if (get<RooAbsPdf>() ||
5999 for (
auto _c :
coords()) {
6003 cut +=
TString::Format(
"%s==%d", _cat->GetName(), _cat->getCurrentIndex());
6011 cut +=
TString::Format(
"%s>=%f&&%s<%f", _rv->GetName(), _rv->getMin(_rv->getStringAttribute(
"coordRange")),
6012 _rv->GetName(), _rv->getMax(_rv->getStringAttribute(
"coordRange")));
6017 throw std::runtime_error(
"datasets(): Unsupported coordinate type");
6020 if (
auto s = get<RooSimultaneous>()) {
6022 bool hasMissing =
false;
6024 for (
auto cat : s->indexCat()) {
6025 if (!s->getPdf(cat.first.c_str())) {
6030 extraCut +=
TString::Format(
"%s==%d", s->indexCat().GetName(), cat.second);
6036 cut +=
"(" + extraCut +
")";
6037 cutobs.
add(s->indexCat());
6042 auto a =
dynamic_cast<RooAbsArg *
>(ax->GetParent());
6046 for (
auto &
child : *
this) {
6048 _datasets.push_back(
child);
6050 if (
auto __ws =
ws(); __ws) {
6053 _datasets.push_back(
d);
6057 for (
auto &
d : _datasets) {
6058 if (std::unique_ptr<RooAbsCollection>(
d->obs().argList().selectCommon(_obs))->size() == _obs.
size()) {
6065 out.emplace_back(std::make_shared<xRooNode>(
6070 out.back()->get<
RooAbsData>()->setGlobalObservables(*std::unique_ptr<RooAbsCollection>(
6072 if (
d->get()->TestBit(1 << 20))
6073 out.back()->get()->SetBit(1 << 20);
6075 out.back()->fBrowsables.emplace_back(std::make_shared<xRooNode>(
".sourceds",
d->fComp, *
this));
6077 out.emplace_back(std::make_shared<xRooNode>(
d->fComp, *
this));
6098 if (
b && strcmp(
b->GetName(),
name) == 0)
6107 if (
auto fr = get<RooFitResult>(); fr) {
6111 if (
auto theData = get<RooDataSet>(); theData) {
6113 TH1 *theHist =
nullptr;
6118 theHist =
dynamic_cast<TH1 *
>(o);
6120 theHist =
static_cast<TH1 *
>(theHist->
Clone());
6131 auto vo =
dynamic_cast<TObject *
>(
v);
6132 if (
v &&
obs().
find(vo->GetName())) {
6136 TString::Format(
"my temp hist;%s", strlen(vo->GetTitle()) ? vo->GetTitle() : vo->GetName()),
6137 cat->numTypes(), 0, cat->numTypes());
6139 std::map<int, std::string> cats;
6140 for (
auto &
c : *cat) {
6141 cats[
c.second] =
c.first;
6143 for (
auto &[
_, label] : cats) {
6147 auto _binning =
v->getBinningPtr(
nullptr);
6148 if (_binning->isUniform()) {
6151 TString::Format(
"my temp hist;%s", strlen(vo->GetTitle()) ? vo->GetTitle() : vo->GetName()),
6152 v->numBins(), _binning->lowBound(), _binning->highBound());
6156 TString::Format(
"my temp hist;%s", strlen(vo->GetTitle()) ? vo->GetTitle() : vo->GetName()),
6157 v->numBins(), _binning->array());
6161 throw std::runtime_error(
"Cannot draw dataset without parent PDF");
6164 theHist = _parentPdf->BuildHistogram(
v,
true);
6170 TH1 *xPos =
static_cast<TH1 *
>(theHist->
Clone(
"xPos"));
6172 TH1 *xPos2 =
static_cast<TH1 *
>(theHist->
Clone(
"xPos2"));
6174 auto nHist = std::unique_ptr<TH1>(
static_cast<TH1 *
>(theHist->
Clone(
"nEntries")));
6179 dataGraph->SetName(
GetName());
6180 dataGraph->SetTitle(strlen(theData->GetTitle()) ? theData->GetTitle() : theData->GetName());
6186 dataGraph->SetMarkerStyle(20);
6198 dataGraph->SetTitle(
TString::Format(
"%s = %f", dataGraph->GetTitle(), dataGraph->GetPointX(0)));
6211 auto _pos = pName.
Index(
'=');
6213 int nevent = theData->numEntries();
6214 for (
int i = 0; i < nevent; i++) {
6217 for (
auto _c : _coords) {
6219 if (cat->getIndex() != theData->get()->getCatIndex(cat->GetName())) {
6225 if (!rv->inRange(theData->get()->getRealValue(rv->GetName()), rv->getStringAttribute(
"coordRange"))) {
6233 cat && cat->
getLabel() != pName(_pos + 1, pName.Length())) {
6249 theHist->
Fill((
x) ? xvar->
getVal() : 0.5, theData->weight());
6250 nHist->Fill((
x) ? xvar->
getVal() : 0.5, 1);
6258 for (
int i = 0; i < theHist->
GetNbinsX(); i++) {
6259 if (includeZeros || nHist->GetBinContent(i + 1)) {
6262 dataGraph->SetPoint(dataGraph->GetN(),
6267 xErr = (xErr <= 0) ? 0. : sqrt(xErr);
6270 dataGraph->SetPointError(dataGraph->GetN() - 1, xErr, xErr,
6282 dataGraph->GetHistogram()->GetXaxis()->Set(theHist->
GetNbinsX(), 0, theHist->
GetNbinsX());
6283 for (
int i = 1; i <= theHist->
GetNbinsX(); i++)
6284 dataGraph->GetHistogram()->GetXaxis()->SetBinLabel(i, theHist->
GetXaxis()->
GetBinLabel(i));
6309 auto _style =
style(dataGraph);
6311 *
dynamic_cast<TAttLine *
>(dataGraph) = *_style;
6312 *
dynamic_cast<TAttFill *
>(dataGraph) = *_style;
6313 *
dynamic_cast<TAttMarker *
>(dataGraph) = *_style;
6318 throw std::runtime_error(
"Cannot build graph");
6324 if (
auto _w =
ws(); _w) {
6326 for (
auto o : _w->allGenericObjects()) {
6328 _fr->ResetBit(1 << 20);
6331 res->SetBit(1 << 20);
6333 auto allVars = _w->allVars();
6338 throw std::runtime_error(
"Not supported yet");
6352 throw std::runtime_error(
"Not a RooFitResult");
6358 if (get<RooFitResult>())
6360 if (get<RooAbsData>()) {
6361 if (
auto _fr =
find(
".fitResult"); _fr)
6363#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
6365 if (get<RooDataSet>() && get<RooDataSet>()->weightVar() &&
6366 get<RooDataSet>()->weightVar()->getStringAttribute(
"fitResult")) {
6367 return xRooNode(getObject<const RooFitResult>(get<RooDataSet>()->weightVar()->getStringAttribute(
"fitResult")),
6375 if (sOpt ==
"prefit") {
6382 auto _coefs =
coefs();
6388 std::unique_ptr<RooArgList> _pars(
dynamic_cast<RooArgList *
>(
pars().
argList().selectByAttrib(
"Constant",
false)));
6389 auto fr = std::make_shared<RooFitResult>(
"prefitResult",
"Prefit");
6390 fr->setFinalParList(*_pars);
6391 for (
auto &
p : fr->floatParsFinal()) {
6395 if (
auto s = _v->getStringAttribute(
"nominal"); s)
6398 std::shared_ptr<xRooNode> pConstr;
6399 for (
auto &
c : _constr) {
6402 bool isServer =
true;
6405 for (
auto s :
c->get<
RooAbsArg>()->servers()) {
6406 if (strcmp(s->GetName(),
p->
GetName()) == 0) {
6421 double prefitVal = 0;
6422 double prefitError = 0;
6423 for (
auto &_d : pConstr->vars()) {
6424 if (strcmp(
p->
GetName(), _d->get()->GetName()) == 0)
6428 prefitVal = prefitError;
6429 prefitError = _c->getVal();
6430 }
else if (prefitError == 0) {
6431 prefitError = _d->get<
RooAbsReal>()->getVal();
6437 if (pConstr->get<
RooGaussian>() && pConstr->browse().find(
".sigma")) {
6438 prefitError = pConstr->find(
".sigma")->get<
RooAbsReal>()->getVal();
6444 prefitVal /= prefitError;
6446 prefitError = 1. / sqrt(prefitError);
6448 if (!_v->getStringAttribute(
"nominal"))
6449 _v->setVal(prefitVal);
6450 _v->setError(prefitError);
6459 auto _globs =
globs();
6460 _args.add(_globs.argList());
6461 fr->setConstParList(_args);
6462 std::unique_ptr<RooArgList> _snap(
dynamic_cast<RooArgList *
>(_pars->snapshot()));
6463 for (
auto &
p : *_snap) {
6464 if (
auto atr =
p->getStringAttribute(
"initVal"); atr &&
dynamic_cast<RooRealVar *
>(
p))
6467 fr->setInitParList(*_snap);
6472 if (
auto _w =
ws(); _w) {
6473 auto checkFr = [&](
TObject *o) {
6477 for (
auto p :
pars()) {
6481 _fr->floatParsFinal().getCatIndex(cat->GetName(), std::numeric_limits<int>().max())) {
6486 if (_fr->floatParsFinal().find(
p->
GetName()) ||
6487 std::abs(_fr->constPars().getRealValue(
p->
GetName(), std::numeric_limits<double>::quiet_NaN()) -
6493 if (_fr->constPars().find(
p->
GetName()) ||
6495 _fr->floatParsFinal().getRealValue(
p->
GetName(), std::numeric_limits<double>::quiet_NaN()) -
6504 std::unique_ptr<RooArgList> _pars(
6506 auto fr = std::make_shared<RooFitResult>(
TString::Format(
"%s-dirty", _fr->GetName()));
6508 fr->setFinalParList(*_pars);
6511 auto cov = _fr->reducedCovarianceMatrix(*_pars);
6513 for (
size_t i = 0; i < _pars->size(); i++) {
6514 if (
auto v =
dynamic_cast<RooRealVar *
>(_pars->at(i))) {
6515 cov(i, i) = pow(
v->getError(), 2);
6520 fr->setCovarianceMatrix(cov);
6526 auto _globs =
globs();
6527 _args.add(_globs.argList());
6528 fr->setConstParList(_args);
6529 std::unique_ptr<RooArgList> _snap(
dynamic_cast<RooArgList *
>(_pars->snapshot()));
6530 for (
auto &
p : *_snap) {
6531 if (
auto atr =
p->getStringAttribute(
"initVal"); atr &&
dynamic_cast<RooRealVar *
>(
p))
6534 fr->setInitParList(*_snap);
6537 return xRooNode(*_fr, std::make_shared<xRooNode>(*_w, std::make_shared<xRooNode>()));
6541 for (
auto o : _w->allGenericObjects()) {
6542 auto out = checkFr(o);
6547 auto out = checkFr(o);
6554 if (
auto fr = getObject<RooFitResult>(
".fitResult"); fr) {
6560 auto _coefs =
coefs();
6566 std::unique_ptr<RooArgList> _pars(
dynamic_cast<RooArgList *
>(
pars().
argList().selectByAttrib(
"Constant",
false)));
6567 auto fr = std::make_shared<RooFitResult>(
TUUID().AsString());
6569 fr->setFinalParList(*_pars);
6575 for (
int i = 0; i < prevCov->
GetNcols(); i++) {
6576 for (
int j = 0; j < prevCov->
GetNrows(); j++) {
6577 cov(i, j) = (*prevCov)(i, j);
6582 for (
auto &
p : fr->floatParsFinal()) {
6583 if (!prevCov || i >= prevCov->
GetNcols()) {
6585 cov(i, i) = pow(
v->getError(), 2);
6592 int covQualBackup = fr->covQual();
6593 fr->setCovarianceMatrix(cov);
6594 fr->setCovQual(covQualBackup);
6599 auto _globs =
globs();
6600 _args.add(_globs.argList());
6601 fr->setConstParList(_args);
6602 std::unique_ptr<RooArgList> _snap(
dynamic_cast<RooArgList *
>(_pars->snapshot()));
6603 for (
auto &
p : *_snap) {
6604 if (
auto atr =
p->getStringAttribute(
"initVal"); atr &&
dynamic_cast<RooRealVar *
>(
p))
6607 fr->setInitParList(*_snap);
6628 if (!std::isnan(low) && !std::isnan(high) && get<RooRealVar>()) {
6629 if (range && strlen(range)) {
6630 get<RooRealVar>()->setRange(range, low, high);
6632 get<RooRealVar>()->setRange(low, high);
6636 if (
auto o = get<RooAbsArg>(); o)
6637 o->setStringAttribute(
"range", range);
6644 std::string &out =
fRange;
6645 if (
auto o = get<RooAbsArg>(); o && o->getStringAttribute(
"range"))
6646 out = o->getStringAttribute(
"range");
6648 while (out.empty() && _parent) {
6649 if (
auto o = _parent->get<
RooAbsArg>(); o && o->getStringAttribute(
"range"))
6650 out = o->getStringAttribute(
"range");
6651 _parent = _parent->fParent;
6666 for (
auto opt : *defaultOpts) {
6669 for (
auto &i : nllOpts) {
6671 Info(
"nll",
"Overriding NLL Option: %s", o->GetName());
6677 return nll(_data,
l);
6682 if (!get<RooAbsPdf>()) {
6684 if (get<RooWorkspace>()) {
6685 std::shared_ptr<xRooNode> mainModel;
6691 throw std::runtime_error(
TString::Format(
"Workspace has multiple models, you must specify which to "
6692 "generate with (found at least %s and %s)",
6693 mainModel->GetName(),
c->GetName()));
6698 return mainModel->generate(fr, expected, seed);
6706 if (get<RooSimultaneous>()) {
6707 std::string selected;
6709 bool hasDeselected =
false;
6710 for (
auto c :
bins()) {
6712 cName = cName(cName.
Index(
'=') + 1, cName.
Length());
6714 hasDeselected =
true;
6716 if (!fromds.empty())
6718 fromds += cName.
Data();
6721 if (!selected.empty())
6723 selected += cName.
Data();
6726 if (hasDeselected) {
6727 std::string dsetName =
"";
6728 if (!fromds.empty()) {
6731 for (
auto &
d : _dsets) {
6732 if (
d->get()->TestBit(1 << 20)) {
6733 dsetName =
d->get()->GetName();
6737 if (dsetName.empty()) {
6738 throw std::runtime_error(
6739 "Need at least one dataset selected (SetChecked) to use for deselected regions");
6743 if (!fromds.empty()) {
6760 if (!get<RooAbsPdf>()) {
6762 if (get<RooWorkspace>()) {
6763 std::shared_ptr<xRooNode> mainModel;
6769 throw std::runtime_error(
TString::Format(
"Workspace has multiple models, you must specify which to "
6770 "build nll with (found at least %s and %s)",
6771 mainModel->GetName(),
c->GetName()));
6776 return mainModel->nll(_data, opts);
6782 if (get<RooSimultaneous>()) {
6783 std::string selected;
6784 bool hasDeselected =
false;
6785 for (
auto c :
bins()) {
6787 hasDeselected =
true;
6790 cName = cName(cName.Index(
'=') + 1, cName.Length());
6791 if (!selected.empty())
6793 selected += cName.Data();
6803 if (strlen(_data.
GetName()) == 0) {
6806 _d = std::make_shared<xRooNode>(asi.first, *
this);
6809 std::make_shared<xRooNode>(
".globs", std::const_pointer_cast<RooAbsCollection>(asi.second), *_d));
6814 return nll(*_d, opts);
6819 me.push_back(std::make_shared<xRooNode>(_data));
6820 return nll(*me.datasets().at(_data.
GetName()), opts);
6823 auto _globs = _data.
globs();
6836 for (
int i = 0; i < opts.
GetSize(); i++) {
6839 if (strcmp(opts.
At(i)->
GetName(),
"GlobalObservables") == 0) {
6842 _opts->Add(opts.
At(i)->
Clone(
nullptr));
6850 std::dynamic_pointer_cast<RooAbsData>(_data.
fComp), *_opts);
6948 auto rangeName = (_range.empty()) ?
GetRange() : _range;
6949 if (!rangeName.empty()) {
6950 std::vector<TString> patterns;
6953 patterns.emplace_back(pattern);
6955 if (
auto s = get<RooSimultaneous>(); s) {
6960 for (
auto &
c :
bins()) {
6962 cName = cName(cName.
Index(
'=') + 1, cName.
Length());
6963 _cat.setLabel(cName);
6964 bool matchAny =
false;
6965 for (
auto &
p : patterns) {
6970 if (_cat.hasRange(
p) && _cat.inRange(
p)) {
6975 if ((matchAny && !invert) || (!matchAny && invert)) {
6980 }
else if (
get() && !get<RooAbsCollection>() && !
components().empty()) {
6984 std::vector<TObject *>
funcs;
6985 for (
auto &
c : out.components()) {
6986 bool matchAny =
false;
6987 for (
auto &
p : patterns) {
6993 if (!((matchAny && !invert) || (!matchAny && invert)))
6994 funcs.push_back(
c->get());
6998 if (!
funcs.empty()) {
7000 _pdf->setFloor(
false);
7006 }
else if (
auto fr = get<RooFitResult>()) {
7012 for (
auto c : _pars) {
7013 bool matchAny =
false;
7014 for (
auto &
p : patterns) {
7020 if (!((matchAny && !invert) || (!matchAny && invert))) {
7024 _pars.remove(_remPars,
true);
7026 auto _tmp = fr->reducedCovarianceMatrix(_pars);
7027 int covQualBackup = fr->covQual();
7028 fr->setCovarianceMatrix(_tmp);
7029 fr->setCovQual(covQualBackup);
7030 const_cast<RooArgList &
>(fr->floatParsFinal())
7031 .remove(_remPars,
true);
7034 }
else if (!
get() || get<RooAbsCollection>()) {
7038 bool notAllArgs =
false;
7039 bool isVars = (strcmp(
GetName(),
".vars") == 0);
7040 for (
auto c : *
this) {
7041 nobs += (
c->fFolder ==
"!robs" ||
c->fFolder ==
"!globs");
7042 bool matchAny =
false;
7043 for (
auto &
p : patterns) {
7045 (isVars &&
p ==
"x" && (
c->fFolder ==
"!robs" ||
c->fFolder ==
"!globs") && nobs == 1)) {
7050 if ((matchAny && !invert) || (!matchAny && invert)) {
7066 return get<RooArgList>() ?
xRooNode(std::make_shared<RooArgList>(),
fParent) : *
this;
7149 return static_cast<RooAbsPdf *
>(intpdf.absArg())->expectedEvents(nset);
7158 return getProjection(&intobs, _normSet, (_normRange.Length() > 0 ? _normRange.Data() :
nullptr), code)->getVal();
7167 fFunc(
"func",
"func", this,
f),
7168 fCoef(
"coef",
"coef", this),
7169 fExpPdf(
"expPdf",
"expPdf", this)
7174 fCoef.setArg(*coef);
7176 if (expPdf && expPdf->canBeExtended() && !(coef &&
dynamic_cast<RooAddPdf *
>(expPdf))) {
7177 fExpPdf.setArg(*expPdf);
7178 }
else if (
auto _p =
dynamic_cast<RooAbsPdf *
>(&
f);
7182 fExpectedEventsMode = expEvMode;
7187 fFunc(
"func", this, other.fFunc),
7188 fCoef(
"coef", this, other.fCoef),
7189 fExpPdf(
"expPdf", this, other.fExpPdf),
7190 fExpectedEventsMode(other.fExpectedEventsMode)
7197 return fFunc->binBoundaries(obs, xlo, xhi);
7202 return (fExpectedEventsMode ? 1. : fFunc) *
7203 ((fExpPdf.absArg()) ?
static_cast<RooAbsPdf *
>(fExpPdf.absArg())->expectedEvents(_normSet) : 1.) *
7204 (fCoef.absArg() ? fCoef : 1.);
7215#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 28, 00)
7216 double oo = getPropagatedError(fr, nset_in);
7217 if (std::isnan(oo)) {
7222 getParameters(&nset_in, allParamsInAbsReal);
7225 for (
auto *rrvFitRes : static_range_cast<RooRealVar *>(fr.
floatParsFinal())) {
7227 auto rrvInAbsReal =
static_cast<RooRealVar const *
>(allParamsInAbsReal.
find(*rrvFitRes));
7231 if (rrvFitRes->namePtr() == namePtr())
7235 if (!rrvFitRes->hasError() ||
7236 rrvFitRes->getError() <= std::abs(rrvFitRes->getVal()) * std::numeric_limits<double>::epsilon())
7245 if (std::abs(rrvInAbsReal->getVal() - rrvFitRes->getVal()) > 0.01 * rrvFitRes->getError()) {
7246 std::stringstream errMsg;
7248 <<
"RooAbsReal::getPropagatedError(): the parameters of the RooAbsReal don't have"
7249 <<
" the same values as in the fit result! The logic of getPropagatedError is broken in this case.";
7251 throw std::runtime_error(errMsg.str());
7254 paramList.
add(*rrvInAbsReal);
7256 if (paramList.
empty())
7259 std::vector<double> plusVar;
7260 std::vector<double> minusVar;
7261 plusVar.reserve(paramList.
size());
7262 minusVar.reserve(paramList.
size());
7268 for (std::size_t ivar = 0; ivar < paramList.
size(); ivar++) {
7270 auto &rrv =
static_cast<RooRealVar &
>(paramList[ivar]);
7272 double cenVal = rrv.
getVal();
7273 double errVal = sqrt(V(ivar, ivar));
7285 rrv.setVal(cenVal + errVal);
7286 plusVar.push_back(getVal(nset_in));
7289 rrv.setVal(cenVal - errVal);
7290 minusVar.push_back(getVal(nset_in));
7291#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
7315 std::vector<double> errVec(paramList.
size());
7316 for (std::size_t i = 0; i < paramList.
size(); i++) {
7317 errVec[i] = std::sqrt(V(i, i));
7318 for (std::size_t j = i; j < paramList.
size(); j++) {
7319 C(i, j) = V(i, j) / std::sqrt(V(i, i) * V(j, j));
7326 for (
unsigned int j = 0; j < plusVar.size(); j++) {
7327 F[j] = (plusVar[j] - minusVar[j]) / 2;
7331 double sum =
F * (C *
F);
7340 for (
auto *frv : static_range_cast<RooRealVar *>(fr.
floatParsFinal())) {
7341 if (frv->getError() > 1
e-20) {
7342 fpf_stripped.
add(*frv);
7357 std::vector<int> fpf_idx;
7358 for (
Int_t i = 0; i < fpf.
size(); i++) {
7361 paramList.
add(*par);
7362 fpf_idx.push_back(i);
7366 std::vector<double> plusVar, minusVar;
7372 for (
Int_t ivar = 0; ivar < paramList.
size(); ivar++) {
7376 double cenVal = rrv.
getVal();
7377 double errVal = sqrt(V(ivar, ivar));
7380 ((
RooRealVar *)paramList.
at(ivar))->setVal(cenVal + errVal);
7383 plusVar.push_back(cloneFunc->
getVal(nset));
7386 ((
RooRealVar *)paramList.
at(ivar))->setVal(cenVal - errVal);
7389 minusVar.push_back(cloneFunc->
getVal(nset));
7397 std::vector<double> errVec(paramList.
size());
7398 for (
int i = 0; i < paramList.
size(); i++) {
7399 errVec[i] = sqrt(V(i, i));
7400 for (
int j = i; j < paramList.
size(); j++) {
7401 C(i, j) = V(i, j) / sqrt(V(i, i) * V(j, j));
7408 for (
unsigned int j = 0; j < plusVar.size(); j++) {
7409 F[j] = (plusVar[j] - minusVar[j]) / 2;
7413 double sum =
F * (C *
F);
7427 bool fExpectedEventsMode =
false;
7435 std::cout <<
"Got signal " << signum << std::endl;
7436 if (signum == SIGINT) {
7437 std::cout <<
"Keyboard interrupt while building histogram" << std::endl;
7447 auto _doSterilize = [](
RooAbsArg *obj) {
7450 for (
int i = 0; i < obj->numCaches(); i++) {
7456 p->setNormRange(
p->normRange());
7458#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
7463 p->setProxyNormSet(
nullptr);
7464 p->_lastNSet =
nullptr;
7467 obj->setValueDirty();
7469 if (
auto w = get<RooWorkspace>();
w) {
7471 for (
auto &
c :
w->components()) {
7490 nClients =
a->clients().size();
7491 for (
auto obj :
a->clients()) {
7493 if (
a->clients().size() != nClients) {
7498 }
while (
a->clients().size() != nClients);
7500 func(get<RooAbsArg>());
7515 out.fComp = std::shared_ptr<TH1>(
BuildHistogram(
nullptr, !content, errors, -1, -1, fr));
7516 }
else if (
vars.size() == 1) {
7518 out.fComp = std::shared_ptr<TH1>(
BuildHistogram(
v, !content, errors, 1, 0, fr));
7520 throw std::runtime_error(
"multi-dim histo not yet supported");
7523 if (
auto h = out.get<
TH1>()) {
7524 if (
h->GetXaxis()->IsAlphanumeric()) {
7526 h->GetXaxis()->SetName(
"xaxis");
7530 auto hCopy =
static_cast<TH1 *
>(
h->Clone(
"nominal"));
7537 std::map<std::string, int> colorByTitle;
7538 std::set<std::string> allTitles;
7539 bool titleMatchName =
true;
7540 std::map<std::string, TH1 *> histGroups;
7541 std::vector<TH1 *> hhs;
7549 for (
auto &
c : *comps) {
7550 if (
c->fFolder ==
"!.coeffs")
7555 if (!cms_coefs.
empty()) {
7557 std::shared_ptr<TH1> prevHist(
static_cast<TH1 *
>(
h->Clone()));
7558 for (
auto c : cms_coefs) {
7562 Form(
"ORIGNAME:%s",
c->GetName()));
7563 f->redirectServers(
RooArgSet(zero),
false,
true);
7569 if (strlen(hh->GetTitle()) == 0)
7570 hh->SetTitle(
c->GetName());
7571 titleMatchName &= (
TString(
c->GetName()) == hh->GetTitle() ||
7573 std::shared_ptr<TH1> nextHist(
static_cast<TH1 *
>(hh->Clone()));
7574 hh->Add(prevHist.get(), -1.);
7577 prevHist = nextHist;
7581 auto hh = samp->BuildHistogram(
v,
false,
false, !
v ? -1 : 1, !
v ? -1 : 0, fr);
7585 if (strlen(hh->GetTitle()) == 0)
7586 hh->SetTitle(samp->GetName());
7587 titleMatchName &= (
TString(samp->GetName()) == hh->GetTitle() ||
7591 for (
auto &hh : hhs) {
7592 if (
h->GetXaxis()->IsAlphanumeric()) {
7594 hh->GetXaxis()->SetName(
"xaxis");
7595 for (
int i = 1; i <= hh->GetNbinsX(); i++)
7596 hh->GetXaxis()->SetBinLabel(i,
h->GetXaxis()->GetBinLabel(i));
7599 if (histGroups.find(hh->GetTitle()) == histGroups.end()) {
7600 histGroups[hh->GetTitle()] = hh;
7603 histGroups[hh->GetTitle()]->Add(hh);
7607 auto hhMin = (hh->GetMinimum() == 0) ? hh->GetMinimum(1
e-9) : hh->GetMinimum();
7608 if (!stack->
GetHists() &&
h->GetMinimum() > hhMin) {
7610 if (hhMin >= 0 && newMin < 0)
7611 newMin = hhMin * 0.99;
7612 h->SetMinimum(newMin);
7614 if (
auto it = colorByTitle.find(hh->GetTitle()); it != colorByTitle.end()) {
7615 hh->SetFillColor(it->second);
7619 hh->SetFillColor((count++) % 100);
7622 for (
auto hh2 : hhs) {
7623 if (hh != hh2 && hh2->GetFillColor() == hh->GetFillColor()) {
7629 colorByTitle[hh->GetTitle()] = hh->GetFillColor();
7641 stack->
Add(hh, thisOpt);
7642 allTitles.insert(hh->GetTitle());
7650 size_t e = std::min(allTitles.begin()->size(), allTitles.rbegin()->size());
7652 bool goodPrefix =
false;
7653 std::string commonSuffix;
7654 if (titleMatchName && ll->
GetEntries() > 1) {
7655 while (ii <
e - 1 && allTitles.begin()->at(ii) == allTitles.rbegin()->at(ii)) {
7657 if (allTitles.begin()->at(ii) ==
'_' || allTitles.begin()->at(ii) ==
' ')
7663 while (!stop && commonSuffix.size() <
size_t(
e - 1)) {
7664 commonSuffix = allTitles.begin()->substr(allTitles.begin()->length() - commonSuffix.length() - 1);
7665 for (
auto &t : allTitles) {
7667 commonSuffix = commonSuffix.substr(1);
7673 if (commonSuffix.find(
'_') == std::string::npos) {
7676 commonSuffix = commonSuffix.substr(commonSuffix.find(
'_'));
7685 std::map<std::string, std::string> reducedTitles;
7686 while (reducedTitles.size() != allTitles.size()) {
7688 std::map<std::string, int> titlesMap;
7689 for (
auto &s : allTitles) {
7690 if (reducedTitles.count(s))
7692 titlesMap[s.substr(0, jj)]++;
7694 for (
auto &s : allTitles) {
7695 if (titlesMap[s.substr(0, jj)] == 1 && (jj >= s.length() || s.at(jj) ==
' ' || s.at(jj) ==
'_')) {
7696 reducedTitles[s] = s.substr(0, jj);
7702 for (
int i = ll->
GetEntries() - 1; i >= 0; i--) {
7704 _title = _title.substr(ii < _title.size() ? ii : 0);
7705 if (!commonSuffix.empty() &&
TString(_title).
EndsWith(commonSuffix.c_str()))
7706 _title = _title.substr(0, _title.length() - commonSuffix.length());
7713 *
dynamic_cast<TAttLine *
>(ll->
At(i)) = *_style;
7714 *
dynamic_cast<TAttFill *
>(ll->
At(i)) = *_style;
7719 dynamic_cast<TAttFill *
>(ll->
At(i))->GetFillStyle() != 0) {
7726 h->GetListOfFunctions()->Add(stack,
"noclearsame");
7727 if (
h->GetSumw2() &&
h->GetSumw2()->GetSum()) {
7729 hCopy->SetFillColor(
h->GetLineColor());
7730 hCopy->SetMarkerStyle(0);
7731 h->GetListOfFunctions()->Add(hCopy->Clone(
".copy"),
"e2same");
7736 h->GetListOfFunctions()->Add(hCopy,
"histsame");
7737 if (
h->GetSumw2() &&
h->GetSumw2()->GetSum()) {
7739 h->SetFillColor(
h->GetLineColor());
7740 h->SetMarkerStyle(0);
7755 auto rar = get<RooAbsReal>();
7765 if (binStart != -1 || binEnd != -1) {
7776 h =
new TH1D(rar->GetName(), rar->GetTitle(), 1, 0, 1);
7777 h->GetXaxis()->SetBinLabel(1, rar->GetName());
7778 h->GetXaxis()->SetName(rar->GetName());
7783 bool setTitle =
false;
7787 h =
new TH1D(rar->GetName(), rar->GetTitle(), 1, 0, 1);
7789 h->GetXaxis()->SetBinLabel(1, rar->GetName());
7790 h->SetBinContent(1, rar->getVal());
7792 h->SetBinError(1,
x->getError());
7793 h->SetMaximum(
x->hasMax() ?
x->getMax()
7794 : (
h->GetBinContent(1) + std::max(std::abs(
h->GetBinContent(1) * 0.1), 50.)));
7795 h->SetMinimum(
x->hasMin() ?
x->getMin()
7796 : (
h->GetBinContent(1) - std::max(std::abs(
h->GetBinContent(1) * 0.1), 50.)));
7801 TString binningName = (_ax && _ax->GetParent() ==
x) ? _ax->GetName() : rar->getStringAttribute(
"binning");
7802 if (binningName ==
"")
7803 binningName = rar->GetName();
7804 if (
x->hasBinning(binningName)) {
7805 if (
x->getBinning(binningName).isUniform()) {
7806 h =
new TH1D(rar->GetName(), rar->GetTitle(),
x->numBins(binningName) <= 0 ? 100 :
x->numBins(binningName),
7807 x->getMin(binningName),
x->getMax(binningName));
7809 h =
new TH1D(rar->GetName(), rar->GetTitle(),
x->numBins(binningName),
x->getBinning(binningName).array());
7811 h->GetXaxis()->SetTitle(
x->getBinning(binningName).GetTitle());
7813 }
else if (
auto _boundaries =
7814 _or_func( (std::list<double> *)(
nullptr),
7815 rar->binBoundaries(*
x, -std::numeric_limits<double>::infinity(),
7816 std::numeric_limits<double>::infinity()));
7818 std::vector<double> _bins;
7819 for (
auto &
b : *_boundaries) {
7820 if (_bins.empty() || std::abs(_bins.back() -
b) > 1
e-5 * _bins.back())
7823 h =
new TH1D(rar->GetName(), rar->GetTitle(), _bins.size() - 1, &_bins[0]);
7825 }
else if (!
x->hasMax() || !
x->hasMin()) {
7827 h =
new TH1D(rar->GetName(), rar->GetTitle(),
v->numBins(),
x->getVal() * 0.2,
x->getVal() * 5);
7829 h =
new TH1D(rar->GetName(), rar->GetTitle(),
v->numBins(),
x->getBinning().array());
7833 h =
new TH1D(rar->GetName(), rar->GetTitle(),
v->numBins(rar->GetName()), 0,
v->numBins(rar->GetName()));
7836 std::map<int, std::string> cats;
7837 for (
auto &
c : *cat) {
7838 cats[
c.second] =
c.first;
7840 for (
auto &[
_, label] : cats) {
7841 h->GetXaxis()->SetBinLabel(i++, label.c_str());
7845 if (
auto o =
dynamic_cast<TObject *
>(
v); o && !setTitle) {
7846 h->GetXaxis()->SetTitle(o->GetTitle());
7851 if (
h->GetXaxis()->IsAlphanumeric()) {
7859 if (
auto s =
style(
nullptr,
false); s) {
7864 if (strlen(
h->GetXaxis()->GetTitle()) == 0)
7873 if (empty && !errors) {
7879 auto _coefs =
coefs();
7894 if (!
GETDMP(fr, _finalPars)) {
7922 for (
int i = 0; i < prevCov->
GetNcols(); i++) {
7923 for (
int j = 0; j < prevCov->
GetNrows(); j++) {
7924 cov(i, j) = (*prevCov)(i, j);
7930 if (!prevCov || i >= prevCov->
GetNcols()) {
7931 cov(i, i) = pow(
dynamic_cast<RooRealVar *
>(p2)->getError(), 2);
7935 int covQualBackup = fr->
covQual();
7946 int covQualBackup = fr->
covQual();
7954 bool hasErrors =
false;
7972 binEnd =
h->GetNbinsX();
7974 bool needBinWidth =
false;
7977 if (
x && (
p || _coefs.get() || rar->getAttribute(
"density"))) {
7979 needBinWidth =
true;
7983 spdf && spdf->
canBeExtended() && !spdf->getFloor() && !_coefs.get()) {
7995 for (
auto o : _obs) {
7997 rr->removeRange(
"coordRange");
7998 rr->setStringAttribute(
"coordRange",
nullptr);
8003 rr->removeRange(
"coordRange");
8004 rr->setStringAttribute(
"coordRange",
nullptr);
8014 bool hasRange =
false;
8015 for (
auto o : normSet) {
8017 rr && (rr->getStringAttribute(
"coordRange")) && strlen(rr->getStringAttribute(
"coordRange"))) {
8027 for (
auto pdf :
bins()) {
8034 dynamic_cast<RooAbsPdf *
>(_pdf)->setNormRange(
"coordRange");
8036 newrar->addPdf(*_pdf, pdf->coords()[s->indexCat().GetName()]->get<
RooCategory>()->getLabel());
8040 rar =
p->createProjection(
8044 dynamic_cast<RooAbsPdf *
>(rar)->setNormRange(
"coordRange");
8048 p->setNormRange(
"coordRange");
8053 rar = std::unique_ptr<RooAbsReal>{rar->createIntegral(
8059 std::unique_ptr<RooAbsReal>{rar->createIntegral(*_obs.get<
RooArgList>() )}
8065 bool scaleExpected = (
p &&
p->canBeExtended() && !_coefs.get());
8069 std::unique_ptr<RooArgSet> snap(normSet.
snapshot());
8071 std::vector<double> lapTimes;
8072 bool warned =
false;
8073 if (binStart == -1 && binEnd == -1) {
8077 for (
int i = std::max(1, binStart); i <= std::min(
h->GetNbinsX(), binEnd); i++) {
8080 x->setVal(
h->GetBinCenter(i));
8082 cat->setLabel(
h->GetXaxis()->GetBinLabel(i));
8086 if (
x && !
x->inRange(
"coordRange"))
8091 r = rar->getVal(
p ? &normSet :
nullptr);
8092#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
8097 if (
r && _coefs.get()) {
8101 r *=
h->GetBinWidth(i);
8103 if (scaleExpected) {
8106 r *= (
p->expectedEvents(normSet));
8109 h->SetBinContent(i,
r);
8117 .getSimplePropagatedError(*fr, normSet);
8118#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
8120 p->_normSet =
nullptr;
8125 .getPropagatedError(
8131 res *=
h->GetBinWidth(i);
8133 h->SetBinError(i, res);
8136 lapTimes.push_back(timeIt.
RealTime());
8137 double time_estimate =
8138 (lapTimes.size() > 1)
8139 ? (
h->GetNbinsX() * (std::accumulate(lapTimes.begin() + 1, lapTimes.end(), 0.) / (lapTimes.size() - 1)))
8141 if (!warned && (lapTimes.at(0) > 10 || (lapTimes.size() > 2 && time_estimate > 60.))) {
8143 t2.
Add(time_estimate);
8144 Warning(
"BuildHistogram",
"Building this histogram will take until %s", t2.
AsString());
8154 Warning(
"BuildHistogram",
"Skipping errors for remaining bins");
8167 std::vector<RooAbsArg *> extra;
8170 for (
auto _pdf : s->servers()) {
8172 extra.push_back(_pdf);
8175 extra.push_back(rar);
8178 for (
auto a : extra)
8184 if (!
p && !rar->getAttribute(
"density") && !needBinWidth) {
8185 h->GetYaxis()->SetTitle(rar->getStringAttribute(
"units"));
8186 }
else if ((
p &&
p->canBeExtended()) || (!
p && needBinWidth)) {
8187 h->GetYaxis()->SetTitle(
"Events");
8189 h->GetYaxis()->SetTitle(
"Probability Mass");
8191 h->GetYaxis()->SetMaxDigits(3);
8204 push_back(std::make_shared<xRooNode>(
data));
8212 return std::numeric_limits<double>::quiet_NaN();
8213 return node->GetBinContent(bin);
8219 if (binStart != binEnd || !
fParent) {
8224 std::vector<double> out;
8225 if (get<RooAbsData>()) {
8233 if (binStart == binEnd && binStart == -1) {
8236 for (
int i = 0; i <
g->GetN(); i++)
8237 integral +=
g->GetPointY(i);
8238 out.push_back(integral);
8242 for (
int i = binStart - 1; i <
g->GetN() && (binEnd == 0 || i < binEnd); i++) {
8243 out.push_back(
g->GetPointY(i));
8249 bool doIntegral =
false;
8250 if (binStart == binEnd && binStart == -1) {
8260 binEnd =
h->GetNbinsX();
8264 for (
int i = 1; i <=
h->GetNbinsX(); i++) {
8265 tot +=
h->GetBinContent(i);
8269 for (
int i = binStart; i <= binEnd; i++) {
8270 out.push_back(
h->GetBinContent(i));
8279 if (
auto a = get<RooAbsArg>();
a) {
8281 for (
auto &
l :
a->servers()) {
8301 if (
auto o =
get(); o) {
8310#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
8314 for (
int i = 0; i <
p->fCGnx; i++) {
8315 for (
int j = 0; j <
p->fCGny; j++) {
8316 p->fCollideGrid[i + j *
p->fCGnx] =
true;
8319 p->FillCollideGrid(o);
8323 Int_t nxmax =
p->fCGnx - iw - 1 -
p->fCGnx *
p->GetRightMargin();
8324 Int_t nymax =
p->fCGny - ih - 1 -
p->fCGny *
p->GetTopMargin();
8326 for (
Int_t j = nymax; j >= 0; j--) {
8327 for (
Int_t i = nxmax; i >= 0; i--) {
8328 if (
p->Collide(i, j, iw, ih)) {
8339 return p->PlaceBox(o,
w,
h, xl, yb,
"trw");
8347 gPad->PaintModified();
8353 auto l =
new TPaveText(
gPad->GetLeftMargin() + 0.02, 1. -
gPad->GetTopMargin() - 0.08, 0.6,
8354 1. -
gPad->GetTopMargin() - 0.08);
8355 l->SetBorderSize(0);
8356 if (
l->GetTextSize() == 0)
8364 l->ConvertNDCtoPad();
8370 if (
auto p =
dynamic_cast<TLegend *
>(
gPad->GetPrimitive(
"legend"));
p) {
8373 double w =
p->GetX2NDC() -
p->GetX1NDC();
8374 double h =
p->GetY2NDC() -
p->GetY1NDC();
8376 gPad->PaintModified();
8380 x = std::max(
x, (
gPad->GetLeftMargin() + 0.02));
8381 y = std::max(
y, (
gPad->GetBottomMargin() + 0.02));
8382 x = std::min(
x, (1. -
gPad->GetRightMargin() - 0.02) -
w);
8383 y = std::min(
y, (1. -
gPad->GetTopMargin() - 0.02) -
h);
8384 h = std::min(
h, (1. -
gPad->GetTopMargin() - 0.02) -
y);
8385 w = std::min(
w, (1. -
gPad->GetRightMargin() - 0.02) -
x);
8397 while ((
p !=
p->GetMother()) && (
p =
p->GetMother())) {
8398 if (
auto q =
dynamic_cast<TVirtualPad *
>(
p->GetPrimitive(
"legend"));
q) {
8406 if (
p && strcmp(
p->
GetName(),
"legend") == 0) {
8407 if (
l =
dynamic_cast<TLegend *
>(
p->GetPrimitive(
"legend"));
l || !create)
8411 gPad->GetBottomMargin());
8412 l->SetBorderSize(1);
8416 l =
new TLegend(0.6, 1. -
gPad->GetTopMargin() - 0.08, 0.75, 1. -
gPad->GetTopMargin() - 0.08);
8417 l->SetBorderSize(0);
8419 if (
l->GetTextSize() == 0) {
8427 l->SetName(
"legend");
8429 l->ConvertNDCtoPad();
8436 auto i = s.find(
"\n");
8437 if (i == std::string::npos) {
8440 return std::string(
"#splitline{") + s.substr(0, i) +
"}{" +
formatLegendString(s.substr(i + 1)) +
"}";
8449 for (
auto a : *
l->GetListOfPrimitives()) {
8453 if (
l->GetListOfPrimitives()->GetEntries() > 20)
8457 if (
auto nObj =
l->GetListOfPrimitives()->GetEntries(); nObj > 0) {
8459 int nn =
l->GetNColumns();
8461 if (nObj > 1 && (nObj % nn) == 1) {
8462 l->SetNColumns(
l->GetNColumns() + 1);
8463 if (
l->GetBorderSize() == 0) {
8464 l->SetX1NDC(
l->GetX2NDC() - 0.15 *
l->GetNColumns());
8467 if (
l->GetBorderSize() == 0) {
8468 l->SetY1NDC(
l->GetY2NDC() - 0.05 *
gPad->GetHNDC() * std::ceil((
double(nObj) /
l->GetNColumns())));
8484 fPad->GetCanvas()->Paint();
8485 fPad->GetCanvas()->Update();
8486#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 30, 00)
8487 fPad->GetCanvas()->ResetUpdated();
8502 if (
gROOT->FromPopUp()) {
8503 gROOT->SetFromPopUp(
false);
8506 }
catch (
const std::exception &
e) {
8509 (
gROOT->GetListOfBrowsers()->At(0))
8512 "Exception",
e.what(),
8515 gROOT->SetFromPopUp(
true);
8524 if (
auto ir = get<RooStats::HypoTestInverterResult>()) {
8528 }
else if (get<RooStats::HypoTestResult>()) {
8541 auto _dsets =
fParent->datasets();
8544 for (
auto &
d : _dsets) {
8545 if (
d->get()->TestBit(1 << 20)) {
8546 dsetName =
d->get()->GetName();
8550 auto hs =
fParent->nll(dsetName.
Data()).hypoSpace(get<RooRealVar>()->GetName());
8551 hs.limits(
"cls visualize");
8563 [](
double a,
double b,
double) {
8566 if (
b == 0 &&
a == 0)
8573 [](
double n,
double b,
double sigma) {
8577 t0 = 2. * (((
n == 0) ? 0 :
n * log(
n /
b)) - (
n -
b));
8580 double b_hathat = 0.5 * (
b - sigma2 + sqrt(pow(
b - sigma2, 2) + 4 *
n * sigma2));
8583 t0 = 2. * (((
n == 0) ? 0 :
n * log(
n / b_hathat)) + b_hathat -
n + pow(
b - b_hathat, 2) / (2. * sigma2));
8587 return (
n >=
b) ? sqrt(t0) : -sqrt(t0);
8595 std::vector<double> xPoints;
8598 int _idx = sOpt2.
Index(
"x=");
8599 int _eidx = sOpt2.
Index(
';', _idx);
8600 TString varPart = sOpt(_idx + 2, (_eidx < 0 ? sOpt2.
Length() : _eidx) - (_idx + 2));
8603 if (
auto _idx2 = varPart.
Index(
"("); _idx2 > 0) {
8604 varName = varPart(0, _idx2);
8614 }
else if (ii == 1) {
8616 }
else if (ii == 2) {
8624 for (
double x = min;
x <= max;
x += (max - min) / (nBins - 1)) {
8625 xPoints.push_back(
x);
8627 }
else if (nBins == 1)
8628 xPoints.push_back((min + max) / 2.);
8630 v = getObject<RooAbsLValue>(varName.Data()).get();
8632 throw std::runtime_error(
TString::Format(
"Could not find variable %s", varName.Data()));
8634 if (xPoints.empty() && !
obs().
find(varName.Data()) &&
8637 for (
int i = 0; i <
v->numBins(
GetName()); i++) {
8655 }
else if (get<RooAbsPdf>()) {
8657 forceNames = sOpt(sOpt2.
Index(
"force") + 5, sOpt2.
Length());
8658 sOpt = sOpt(0, sOpt2.
Index(
"force"));
8659 sOpt2 = sOpt2(0, sOpt2.
Index(
"force"));
8661 Error(
"Draw",
"Can only compute forces with PDFs");
8665 bool hasOverlay = sOpt2.
Contains(
"overlay");
8669 overlayName = sOpt(sOpt2.
Index(
"overlay") + 7, sOpt2.
Length());
8670 sOpt = sOpt(0, sOpt2.
Index(
"overlay"));
8671 sOpt2 = sOpt2(0, sOpt2.
Index(
"overlay"));
8676 sOpt +=
"auxSignif";
8678 std::string auxPlotTitle;
8689 bool nostack = sOpt.
Contains(
"nostack");
8691 bool hasSame = sOpt.
Contains(
"same");
8693 bool hasGoff = sOpt.
Contains(
"goff");
8695 bool hasFR = sOpt.
Contains(
"pull") && !get<RooFitResult>();
8697 bool hasText = sOpt.
Contains(
"text");
8698 bool hasTexte = sOpt.
Contains(
"texte");
8699 bool hasErrorOpt = sOpt.
Contains(
"e");
8703 }
else if (hasText) {
8706 if (auxPlotTitle ==
"Signif")
8713 TH1 *hAxis =
nullptr;
8715 auto clearPad = []() {
8717 if (
gPad->GetNumber() == 0) {
8729 if (!hasSame || !pad) {
8740 if (hAxis =
dynamic_cast<TH1 *
>(o); hAxis)
8760 auto adjustYRange = [&](
double min,
double max,
TH1 *hh =
nullptr,
bool symmetrize =
false) {
8768 double ymin = hh->GetMinimum();
8769 double ymax = hh->GetMaximum();
8770 if (hh->GetMaximumStored() == -1111)
8772 if (hh->GetMinimumStored() == -1111) {
8775 }
else if (
ymin < 0) {
8783 if (hh->GetSumw2()) {
8784 double smallestErrDown3 = -std::numeric_limits<double>::infinity();
8785 double smallestErrUp3 = std::numeric_limits<double>::infinity();
8786 for (
int i = 1; i <= hh->GetNbinsX(); i++) {
8787 smallestErrDown3 = std::max(smallestErrDown3, hh->GetBinContent(i) - 3 * hh->GetBinError(i));
8788 smallestErrUp3 = std::min(smallestErrUp3, hh->GetBinContent(i) + 3 * hh->GetBinError(i));
8790 max = std::max(max, smallestErrUp3);
8791 min = std::min(min, smallestErrDown3);
8793 bool change =
false;
8805 double down = hh->GetBinContent(1) -
ymin;
8806 double up =
ymax - hh->GetBinContent(1);
8808 ymax = hh->GetBinContent(1) + down;
8810 ymin = hh->GetBinContent(1) - up;
8813 if (hh == hAxis && pad && !pad->
GetLogy() &&
ymin > 0 && (log10(
ymax) - log10(max)) >= 3) {
8817 if (hh == hAxis && pad &&
ymin == 0 && pad->
GetLogy()) {
8822 hh->SetMinimum(
ymin);
8823 hh->SetMaximum(
ymax);
8824 hh->GetYaxis()->Set(1,
ymin,
ymax);
8831 double ymax = -std::numeric_limits<double>::infinity();
8832 double ymin = std::numeric_limits<double>::infinity();
8833 for (
int i = 0; i <
gr->
GetN(); i++) {
8840 if (!xPoints.empty()) {
8845 out->SetFillColor(out->GetLineColor());
8846 out->SetMarkerStyle(0);
8847 out->SetFillStyle(hasErrorOpt ? 3005 : 0);
8849 for (
auto &
x : xPoints) {
8853 out->SetPointEYlow(out->GetN() - 1,
GetError());
8854 out->SetPointEYhigh(out->GetN() - 1, out->GetErrorYlow(out->GetN() - 1));
8860 out->Draw(
TString(hasSame ?
"L" :
"AL") + (hasErrorOpt ?
"3" :
""));
8881 gPad->GetFrame()->SetFillStyle(1001);
8882 gPad->SetTopMargin(0);
8883 gPad->SetBottomMargin(0);
8884 gPad->SetName(
"pull");
8888 Error(
"Draw",
"Couldn't find pull graph");
8891 pullGraph->SetName(
"nominal");
8895 auto scaleHist =
static_cast<TH1 *
>(pullGraph->FindObject(
"scales"));
8897 throw std::runtime_error(
"Could not find scales in fit result");
8899 for (
auto i = 0; i < pullGraph->GetN(); i++) {
8901 g->
SetName(scaleHist->GetXaxis()->GetBinLabel(i + 1));
8904 Warning(
"Draw",
"Found a non-var in the floatParsFinal list: %s - this shouldn't happen",
g->GetName());
8908 "%s=%g +/- %s [%g,%g]", strlen(_p->GetTitle()) ? _p->GetTitle() : _p->GetName(), _p->getVal(),
8909 _p->hasAsymError() ?
TString::Format(
"(%g,%g)", _p->getAsymErrorHi(), _p->getAsymErrorLo()).
Data()
8911 scaleHist->GetBinContent(i + 1), scaleHist->GetBinError(i + 1)));
8912 g->SetPoint(0, pullGraph->GetPointX(i), pullGraph->GetPointY(i));
8913 g->SetPointEYhigh(0, pullGraph->GetErrorYhigh(i));
8914 g->SetPointEYlow(0, pullGraph->GetErrorYlow(i));
8915 g->SetEditable(
true);
8916 g->SetHighlight(
true);
8917 g->SetMarkerStyle(20);
8918 g->SetMarkerSize(0.5);
8926 _thisClone->AppendPad();
8939 if (
auto _simPdf = get<RooSimultaneous>();
8940 _simPdf && !(
v && strcmp(_simPdf->indexCat().GetName(),
dynamic_cast<TObject *
>(
v)->
GetName()) == 0)) {
8941 auto _channels =
bins();
8943 for (
auto &_v : _channels) {
8944 if (!_v->IsHidden())
8975 dynamic_cast<TPad *
>(pad)->DivideSquare(_size, 1
e-9, 1
e-9);
8977 auto _pad = pad->
GetPad(_size);
8980 _pad->SetPad(_pad->GetXlowNDC(), _pad->GetYlowNDC(), 1.0, _pad->GetYlowNDC() + _pad->GetHNDC());
8993 std::vector<TString> chanPatterns;
8994 if (_range && strlen(_range)) {
8997 chanPatterns.emplace_back(pattern);
9000 for (
auto &_v : _channels) {
9007 chanVar.setLabel(cName);
9008 bool inRange = chanPatterns.empty();
9009 for (
auto &
p : chanPatterns) {
9010 if (chanVar.inRange(
p)) {
9018 gPad->SetLeftMargin(std::min(
gPad->GetLeftMargin() * (1. /
gPad->GetWNDC()), 0.3));
9028 if (!
get() || get<RooArgList>()) {
9033 for (
auto &_v : *
this) {
9036 if (strcmp(
GetName(),
".vars") == 0) {
9040 if (strcmp(_v->get()->GetName(),
"1") == 0 || strcmp(_v->get()->GetName(),
"ONE") == 0 ||
9043 if (_v->get()->InheritsFrom(
"RooConstVar"))
9054 dynamic_cast<TPad *
>(pad)->DivideSquare(_size, 1
e-9, 1
e-9);
9057 for (
auto &_v : *
this) {
9060 if (strcmp(
GetName(),
".vars") == 0) {
9064 if (strcmp(_v->get()->GetName(),
"1") == 0 || strcmp(_v->get()->GetName(),
"ONE") == 0 ||
9067 if (_v->get()->InheritsFrom(
"RooConstVar"))
9076 gPad->SetLeftMargin(std::min(
gPad->GetLeftMargin() * (1. /
gPad->GetWNDC()), 0.3));
9094 if (
auto fr = get<RooFitResult>(); fr) {
9098 auto hist = fr->correlationHist(fr->GetName());
9099 hist->SetTitle(fr->GetTitle());
9102 hist->SetStats(
false);
9103 hist->SetDirectory(
nullptr);
9106 hist->GetXaxis()->SetTickSize(0);
9107 hist->GetYaxis()->SetTickSize(0);
9108 hist->SetMinimum(-100);
9111 gPad->SetGrid(1, 1);
9122 std::string poiName;
9125 poiName = sOpt3(sOpt3.
Index(
"breakdown:") + 10, sOpt3.
Length());
9127 std::unique_ptr<RooAbsCollection> _poi(fr->floatParsFinal().selectByAttrib(
"poi",
true));
9128 if (_poi->empty()) {
9129 throw std::runtime_error(
"No floating poi in the fit");
9130 }
else if (_poi->size() != 1) {
9131 throw std::runtime_error(
"Multiple poi in the fit");
9133 poiName = _poi->first()->GetName();
9137 throw std::runtime_error(
TString::Format(
"Cannot find parameter %s", poiName.c_str()));
9139 std::set<std::string> groups;
9140 for (
auto p : fr->floatParsFinal()) {
9143 }
else if (
p->getStringAttribute(
"group")) {
9144 groups.insert(
p->getStringAttribute(
"group"));
9157 roundedVal.second *= .1;
9165 for (
auto group : groups) {
9167 double variance = pow(
dynamic_cast<RooRealVar *
>(
poi)->getError(), 2);
9168 for (
auto p : fr->floatParsFinal()) {
9171 }
else if ((
p->getStringAttribute(
"group") &&
group ==
p->getStringAttribute(
"group")) ||
9177 int idx =
pars.index(poiName.c_str());
9178 double reducedVar = fr->conditionalCovarianceMatrix(
pars)(idx, idx);
9179 if (reducedVar > variance) {
9180 Warning(
"Draw",
"breakdown group %s variance bigger than preceding?",
group.c_str());
9186 std::pair(sqrt(variance - reducedVar), roundedVal.second));
9198 double variance = fr->conditionalCovarianceMatrix(*
poi)(0, 0);
9214 out->SetTitle(
"Fit Result Pulls");
9215 std::vector<TString> graphLabels;
9218 ugraph->
SetTitle(
"Fit Result Pulls");
9219 std::vector<TString> ugraphLabels;
9220 std::map<std::string, double> scale;
9221 std::map<std::string, double>
offset;
9222 for (
auto &
p : fr->floatParsFinal()) {
9227 if (std::isnan(_v->getErrorHi()) || std::isnan(_v->getErrorLo())) {
9228 Warning(
"Draw",
"%s error is invalid", _v->GetName());
9233 double prefitError = 0;
9234 double prefitVal = 0;
9235 double customScale = 0;
9238 prefitError = ip->getError();
9239 prefitVal = ip->getVal();
9242 std::shared_ptr<xRooNode> pConstr;
9245 if (_vv->hasRange(
"pullScale")) {
9246 customScale = (_vv->getMax(
"pullScale") - _vv->getMin(
"pullScale")) / 2.;
9249 for (
auto &
c : _constr) {
9252 bool isServer =
true;
9255 for (
auto s :
c->get<
RooAbsArg>()->servers()) {
9256 if (strcmp(s->GetName(),
p->
GetName()) == 0) {
9277 if (pConstr->get<
RooPoisson>() && pConstr->find(
".x")) {
9278 std::string xName = pConstr->find(
".x")->get()->GetName();
9279 prefitVal = pConstr->find(
".x")->get<
RooAbsReal>()->getVal();
9280 for (
auto &_d : pConstr->vars()) {
9281 if (strcmp(
p->
GetName(), _d->get()->GetName()) == 0)
9283 if (xName == _d->get()->GetName())
9289 prefitVal /= prefitError;
9291 prefitError = 1. / sqrt(prefitError);
9292 }
else if (
auto _g = pConstr->get<
RooGaussian>(); _g) {
9294 (pConstr->find(
".sigma")) ? pConstr->find(
".sigma")->get<
RooAbsReal>()->getVal() : prefitError;
9296 (pConstr->find(
".x")) ? pConstr->find(
".x")->get<
RooAbsReal>()->getVal() : 0;
9297 if (pConstr->find(
".x") &&
9300 prefitVal = pConstr->find(
".mean")->get<
RooAbsReal>()->getVal();
9305 prefitError = customScale;
9306 if (prefitError == 0) {
9307 Warning(
"Draw",
"failed to determine prefit error of %s, using post-fit error",
p->
GetName());
9308 prefitError = _v->getError();
9310 out->SetPoint(out->GetN(), out->GetN(), (_v->getVal() - prefitVal) / prefitError);
9311 out->SetPointError(out->GetN() - 1, 0, 0, (-_v->getErrorLo()) / prefitError,
9312 (_v->getErrorHi()) / prefitError);
9313 graphLabels.push_back(
p->
GetName());
9319 prefitError = customScale;
9320 if (prefitError == 0) {
9322 prefitError = (std::max({_v->getMax() - _v->getVal(), _v->getVal() - _v->getMin(), 4.}) / 4);
9323 ugraph->
SetPoint(ugraph->
GetN(), ugraph->
GetN(), (_v->getVal() - prefitVal) / prefitError);
9324 ugraph->
SetPointError(ugraph->
GetN() - 1, 0, 0, (-_v->getErrorLo()) / prefitError,
9325 (_v->getErrorHi()) / prefitError);
9326 ugraphLabels.push_back(
p->
GetName());
9328 out->SetPoint(out->GetN(), out->GetN(), (_v->getVal() - prefitVal) / prefitError);
9329 out->SetPointError(out->GetN() - 1, 0, 0, (-_v->getErrorLo()) / prefitError,
9330 (_v->getErrorHi()) / prefitError);
9331 graphLabels.push_back(
p->
GetName());
9339 prefitError = customScale;
9340 if (prefitError == 0) {
9341 prefitError = (std::max({_v->getMax() - _v->getVal(), _v->getVal() - _v->getMin(), 4.}) / 4);
9343 ugraph->
SetPoint(ugraph->
GetN(), ugraph->
GetN(), (_v->getVal() - prefitVal) / prefitError);
9344 ugraph->
SetPointError(ugraph->
GetN() - 1, 0, 0, (-_v->getErrorLo()) / prefitError,
9345 (_v->getErrorHi()) / prefitError);
9346 ugraphLabels.push_back(
p->
GetName());
9354 for (
int i = 0; i < ugraph->
GetN(); i++)
9356 int nUnconstrained = ugraph->
GetN();
9359 tmpList.
Add(ugraph);
9360 graph->Merge(&tmpList);
9363 for (
auto &
l : ugraphLabels) {
9364 graphLabels.push_back(
l);
9368 graph->SetMarkerStyle(20);
9369 graph->SetMarkerSize(0.5);
9371 graph->SetMaximum(4);
9372 graph->SetMinimum(-4);
9377 std::vector<std::pair<double, std::string>>
covariances;
9378 std::string poiName;
9379 double maxImpact = 0;
9383 poiName = sOpt3(sOpt3.
Index(
"impact:") + 7, sOpt3.
Length());
9385 std::unique_ptr<RooAbsCollection> _poi(fr->floatParsFinal().selectByAttrib(
"poi",
true));
9386 if (_poi->empty()) {
9387 throw std::runtime_error(
"No floating poi in the fit");
9388 }
else if (_poi->size() != 1) {
9389 throw std::runtime_error(
"Multiple poi in the fit");
9391 poiName = _poi->first()->GetName();
9393 RooAbsArg *
poi = fr->floatParsFinal().find(poiName.c_str());
9395 throw std::runtime_error(
TString::Format(
"Cannot find parameter %s", poiName.c_str()));
9397 size_t poiIdx = fr->floatParsFinal().index(*
poi);
9406 for (
auto &label : graphLabels) {
9407 covariances.emplace_back(fr->covarianceMatrix()(poiIdx, fr->floatParsFinal().index(label)) /
9408 dynamic_cast<RooRealVar *
>(fr->floatParsFinal().find(label))->getError(),
9412 [&](std::pair<double, std::string> i, std::pair<double, std::string> j) {
9413 return doHorizontal ? (std::abs(i.first) < std::abs(j.first))
9414 : (std::abs(i.first) > std::abs(j.first));
9418 std::vector<TString> sortedLabels;
9419 maxImpact = (doHorizontal) ?
covariances.back().first
9426 c.first *= 4. / (maxImpact * 1.2);
9427 sortedLabels.push_back(
c.second);
9429 for (; i < graphLabels.size(); i++) {
9430 if (graphLabels[i] ==
c.second) {
9440 tmpList2.
Add(&sortedGraph);
9441 graph->Merge(&tmpList2);
9443 graphLabels = sortedLabels;
9444 graph->SetTitle(
"Fit Result Impact");
9450 hist =
new TH2D(
GetName(), fr->GetTitle(), 100, -4, 4, std::max(
graph->GetN(), 1), -0.5,
9451 std::max(
graph->GetN(), 1) - 0.5);
9453 for (
auto &
l : graphLabels) {
9456 if (!graphLabels.empty())
9460 hist =
new TH2D(
GetName(), fr->GetTitle(), std::max(
graph->GetN(), 1), -0.5, std::max(
graph->GetN(), 1) - 0.5,
9463 for (
auto &
l : graphLabels) {
9466 if (!graphLabels.empty())
9474 auto histCopy =
dynamic_cast<TH1 *
>(hist->
Clone(
".axis"));
9477 auto _axis = (doHorizontal ? histCopy->GetYaxis() : histCopy->GetXaxis());
9487 graph->GetHistogram()->GetXaxis()->Set(std::max(
graph->GetN(), 1), -0.5, std::max(
graph->GetN(), 1) - 0.5);
9488 for (
int ii = 1; ii <= _axis->GetNbins(); ii++) {
9489 graph->GetHistogram()->GetXaxis()->SetBinLabel(ii, _axis->GetBinLabel(ii));
9504 gPad->Divide(1, 1, 1
e-9, 1
e-9);
9508 gPad->SetLeftMargin(0.4);
9510 gPad->SetBottomMargin(0.4);
9513 auto pNamesHist =
dynamic_cast<TH1F *
>(
graph->GetHistogram()->Clone(
"scales"));
9514 pNamesHist->
Sumw2();
9515 pNamesHist->SetDirectory(
nullptr);
9517 for (
int ii = 1; ii <=
graph->GetN(); ii++) {
9518 auto _p = fr->floatParsFinal().find(_axis->GetBinLabel(ii));
9519 pNamesHist->SetBinContent(ii,
offset[_p->GetName()]);
9520 pNamesHist->SetBinError(ii, scale[_p->GetName()]);
9521 _axis->SetBinLabel(ii, strlen(_p->GetTitle()) ? _p->GetTitle() : _p->GetName());
9527 for (
int ii = 2; ii >= 1; ii--) {
9531 pullBox->SetPoint(0, (doHorizontal) ? -ii : -0.5, (doHorizontal) ? -0.5 : 0);
9532 pullBox->SetPoint(1, (doHorizontal) ? ii : (_axis->GetNbins() - 0.5 - nUnconstrained),
9533 (doHorizontal) ? -0.5 : 0);
9534 pullBox->SetPointError(0, 0, (doHorizontal) ? (_axis->GetNbins() - nUnconstrained) : ii);
9535 pullBox->SetPointError(1, 0, (doHorizontal) ? (_axis->GetNbins() - nUnconstrained) : ii);
9539 auto pullLine =
new TGraph;
9540 pullLine->
SetName(
"0sigmaLine");
9542 pullLine->SetPoint(0, -0.5, 0);
9543 pullLine->SetPoint(1, _axis->GetNbins() - 0.5, 0);
9544 pullLine->SetLineStyle(2);
9545 pullLine->SetEditable(
false);
9549 if (nUnconstrained > 0) {
9551 pullLine->
SetName(
"dividerLine");
9553 pullLine->SetPoint(0,
graph->GetN() - 0.5 - nUnconstrained, -100);
9554 pullLine->SetPoint(1,
graph->GetN() - 0.5 - nUnconstrained, 100);
9555 pullLine->SetLineStyle(2);
9556 pullLine->SetEditable(
false);
9562 new TPaveText(
gPad->GetLeftMargin(), 1. -
gPad->GetTopMargin(), 1. -
gPad->GetRightMargin(), 0.98,
"NDCNB");
9569 std::string covQualTxt;
9570 switch (fr->covQual()) {
9571 case -1: covQualTxt =
"Unknown";
break;
9572 case 0: covQualTxt =
"Not calculated";
break;
9573 case 1: covQualTxt =
"Approximate";
break;
9574 case 2: covQualTxt =
"Forced Positive-Definite";
break;
9575 case 3: covQualTxt =
"Accurate";
break;
9580 std::string statusCodes;
9581 for (
unsigned int i = 0; i < fr->numStatusHistory(); i++) {
9582 statusCodes +=
TString::Format(
" %s = %d", fr->statusLabelHistory(i), fr->statusCodeHistory(i));
9589 gPad->SetTicks(0, 0);
9593 if (
int(
gPad->GetCanvas()->GetWh()) < pNamesHist->GetNbinsX() * 15) {
9594 gPad->GetCanvas()->SetCanvasSize(
gPad->GetCanvas()->GetWw(), pNamesHist->GetNbinsX() * 15);
9598 double factor = 475. /
gPad->GetCanvas()->GetWh();
9603 new TGaxis(_axis->GetXmin(), -4, _axis->GetXmin(), 4, -1.2 * maxImpact, 1.2 * maxImpact, 510,
"-S");
9627 for (
int tt = 0;
tt < 2;
tt++) {
9628 auto impact =
static_cast<TH1 *
>(
9631 impact->GetYaxis()->SetTitle(
TString::Format(
"#Delta%s/#sigma", poiName.c_str()));
9632 impact->SetBarWidth(0.9);
9633 impact->SetBarOffset(0.05);
9634 impact->SetLineColor(
kBlack);
9635 impact->SetFillColor(
kAzure - 4);
9636 impact->SetFillStyle(
tt == 0 ? 3013 : 1001);
9638 static_cast<TH1 *
>(impact->Clone(
TString::Format(
"%s_impact-",
tt == 0 ?
"prefit" :
"postfit")));
9640 impact2->SetFillColor(
kCyan);
9641 for (
int ii = 1; ii <= pNamesHist->GetNbinsX(); ii++) {
9643 if (
c.second != pNamesHist->GetXaxis()->GetBinLabel(ii))
9645 auto vv =
dynamic_cast<RooRealVar *
>(fr->floatParsFinal().find(
c.second.c_str()));
9646 auto vv_init =
dynamic_cast<RooRealVar *
>(fr->floatParsInit().find(
c.second.c_str()));
9647 impact->SetBinContent(ii, ((
tt == 0 && !vv_init->hasError()) || !
vv->hasError())
9649 :
c.first *
vv->getError() /
vv->getErrorHi() *
9650 (
tt == 0 ? (vv_init->getErrorHi() /
vv->getErrorHi()) : 1.));
9651 impact2->SetBinContent(ii, ((
tt == 0 && !vv_init->hasError()) || !
vv->hasError())
9653 :
c.first *
vv->getError() /
vv->getErrorLo() *
9654 (
tt == 0 ? (vv_init->getErrorLo() /
vv->getErrorLo()) : 1.));
9661 for (
int ii = -1; ii <= 1; ii++) {
9662 auto pullLine =
new TGraph;
9665 pullLine->SetPoint(0, -0.5, ii);
9666 pullLine->SetPoint(1, hist->
GetNbinsY() - 0.5, ii);
9667 pullLine->SetLineStyle(2);
9668 pullLine->SetEditable(
false);
9673 new TLegend(0.02, doHorizontal ? (1. - 0.22 * factor) : 0.02, 0.27, (doHorizontal ? 1. : 0.24));
9683 leg1->
AddEntry(hist->
FindObject(
"prefit_impact+"),
"#theta = #hat{#theta}+#Delta#theta",
"f");
9684 leg1->
AddEntry(hist->
FindObject(
"prefit_impact-"),
"#theta = #hat{#theta}-#Delta#theta",
"f");
9687 leg1->
AddEntry(hist->
FindObject(
"postfit_impact+"),
"#theta = #hat{#theta}+#Delta#theta",
"f");
9688 leg1->
AddEntry(hist->
FindObject(
"postfit_impact-"),
"#theta = #hat{#theta}-#Delta#theta",
"f");
9694 new TPaveText(
gPad->GetLeftMargin(), 1. -
gPad->AbsPixeltoY(14), 1. -
gPad->GetRightMargin(), 1.,
"NDC");
9701 : ((
gPad->AbsPixeltoY(0) -
gPad->AbsPixeltoY(10 / factor)) / (
gPad->GetY2() -
gPad->GetY1())));
9704 title->
AddText(histCopy->GetTitle());
9709 graph->SetEditable(
false);
9710 pNamesHist->SetLineWidth(0);
9711 pNamesHist->SetMarkerSize(0);
9712 graph->GetListOfFunctions()->Add(pNamesHist,
"same");
9716 for (
int p = 0;
p <
graph->GetN();
p++) {
9719 graph->GetErrorXhigh(
p));
9722 if (
f->InheritsFrom(
"TH1")) {
9731 else if (
auto g =
dynamic_cast<TGraph *
>(
f)) {
9732 for (
int p = 0;
p <
g->GetN();
p++) {
9733 g->SetPoint(
p,
g->GetPointY(
p),
g->GetPointX(
p));
9736 }
else if (
auto l =
dynamic_cast<TLine *
>(
f)) {
9739 l->
SetY1(_axis->GetXmax());
9740 l->
SetY2(_axis->GetXmax());
9746 graph->SetName(
"pulls");
9751 histCopy->Draw((sOpt.
Contains(
"impact") && !doHorizontal)
9767 auto hh =
dynamic_cast<TH1 *
>(histCopy->Clone(
".axiscopy"));
9771 (sOpt.
Contains(
"impact") && !doHorizontal)
9785 bool doneDraw =
false;
9786 for (
auto c : s->bins()) {
9787 auto _pad =
dynamic_cast<TPad *
>(
gPad->GetPrimitive(
c->GetName()));
9792 c->push_back(std::make_shared<xRooNode>(*
this));
9793 auto ds =
c->datasets().find(
GetName());
9794 c->resize(
c->size() - 1);
9796 std::cout <<
" no ds " <<
GetName() <<
" - this should never happen!" << std::endl;
9811 if (!s && hasSame) {
9814 bool doneDraw =
false;
9815 for (
auto o : *
gPad->GetListOfPrimitives()) {
9830 auto dataGraph =
BuildGraph(
v,
false, (!s && hasSame) ?
gPad :
nullptr);
9835 dataGraph->SetMarkerSize(dataGraph->GetMarkerSize() *
gPad->GetWNDC());
9840 for (
int i = 0; i < dataGraph->GetN(); i++)
9841 tot += dataGraph->GetPointY(i);
9842 dataGraph->Scale(1. / tot);
9847 dataGraph->Draw(
"Az0p");
9848 addLegendEntry(dataGraph, strlen(dataGraph->GetTitle()) ? dataGraph->GetTitle() :
GetName(),
"pEX0");
9854 bool noPoint =
false;
9857 for (
auto o : *
gPad->GetListOfPrimitives()) {
9858 if (
auto h =
dynamic_cast<TH1 *
>(o);
9859 h && strcmp(
h->GetXaxis()->GetName(),
dynamic_cast<TObject *
>(
v)->
GetName()) == 0) {
9860 dataGraph->SetPointY(0,
h->Interpolate(dataGraph->GetPointX(0)));
9867 if (
auto _pad =
dynamic_cast<TPad *
>(
gPad->FindObject(
"auxPad")); _pad) {
9868 if (
auto h =
dynamic_cast<TH1 *
>(_pad->GetPrimitive(
"auxHist"));
h) {
9871 histName = histName(0, histName.
Index(
'|'));
9872 if (
auto mainHist =
dynamic_cast<TH1 *
>(
gPad->GetPrimitive(histName));
9876 auto ratioGraph =
dynamic_cast<TGraphAsymmErrors *
>(dataGraph->Clone(dataGraph->GetName()));
9878 for (
int i = 0; i < ratioGraph->GetN(); i++) {
9879 double val = ratioGraph->GetPointY(i);
9880 int binNum = mainHist->FindFixBin(ratioGraph->GetPointX(i));
9881 double nom = mainHist->GetBinContent(binNum);
9882 double nomerr = mainHist->GetBinError(binNum);
9884 std::get<0>(
auxFunctions[
h->GetYaxis()->GetTitle()])(ratioGraph->GetPointY(i), nom, nomerr);
9885 double yup = std::get<0>(
auxFunctions[
h->GetYaxis()->GetTitle()])(val + ratioGraph->GetErrorYhigh(i),
9888 double ydown = yval - std::get<0>(
auxFunctions[
h->GetYaxis()->GetTitle()])(
9889 val - ratioGraph->GetErrorYlow(i), nom, nomerr);
9890 if (!std::isnan(yval)) {
9891 ratioGraph->SetPointY(i, yval);
9892 if (!std::isnan(yup))
9893 ratioGraph->SetPointEYhigh(i, yup);
9894 if (!std::isnan(ydown))
9895 ratioGraph->SetPointEYlow(i, ydown);
9900 while (i < ratioGraph->GetN()) {
9901 if (ratioGraph->GetPointY(i) == 0 && ratioGraph->GetErrorYhigh(i) == 0 &&
9902 ratioGraph->GetErrorYlow(i) == 0) {
9903 ratioGraph->RemovePoint(i);
9908 auto _tmpPad =
gPad;
9910 ratioGraph->Draw(
"z0psame");
9911 auto minMax = graphMinMax(ratioGraph);
9912 adjustYRange(minMax.first, minMax.second,
h, std::get<1>(
auxFunctions[
h->GetYaxis()->GetTitle()]));
9918 dataGraph->Draw(
"z0p same");
9919 addLegendEntry((noPoint) ?
nullptr : dataGraph, strlen(dataGraph->GetTitle()) ? dataGraph->GetTitle() :
GetName(),
9920 noPoint ?
"" :
"pEX0");
9923 adjustYRange(minMax.first, minMax.second);
9939 gr->
Draw(hasSame ?
"P" :
"AP");
9943 if (forceNames !=
"") {
9946 bool _drawn =
false;
9952 std::vector<double> valuesToDo = {initPar->
getVal()};
9953 if (initPar->hasError() || initPar->hasAsymError()) {
9954 valuesToDo.push_back(initPar->getVal() + initPar->getErrorLo());
9955 valuesToDo.push_back(initPar->getVal() + initPar->getErrorHi());
9958 for (
auto valueToDo : valuesToDo) {
9960 for (
auto &
d : _dsets) {
9961 if (!
d->get()->TestBit(1 << 20))
9965 auto _obs =
d->obs();
9966 auto x = _obs.find((
v) ?
dynamic_cast<TObject *
>(
v)->
GetName() : emptyHist->GetXaxis()->GetName());
9970 for (
int i = 0; i < nevent; i++) {
9973 for (
const auto &_c : _coords) {
9975 if (cat->getIndex() != theData->get()->getCatIndex(cat->GetName())) {
9985 auto val = _nll.pars()->getRealValue(initPar->GetName());
9987 _nll.pars()->setRealValue(initPar->GetName(), valueToDo);
9988 auto nllVal = _nll.getEntryVal(i);
9989 _nll.pars()->setRealValue(initPar->GetName(), initPar->getVal());
9990 auto nllVal2 = _nll.getEntryVal(i);
9991 _nll.pars()->setRealValue(initPar->GetName(), val);
9997 auto val = _nll.pars()->getRealValue(initPar->GetName());
9999 _nll.pars()->setRealValue(initPar->GetName(), valueToDo);
10000 auto _extTerm = _nll.extendedTerm();
10001 _nll.pars()->setRealValue(initPar->GetName(), initPar->getVal());
10002 auto _extTerm2 = _nll.extendedTerm();
10003 _nll.pars()->setRealValue(initPar->GetName(), val);
10004 for (
int i = 1; i <= emptyHist->GetNbinsX(); i++) {
10005 emptyHist->SetBinContent(i,
10006 emptyHist->GetBinContent(i) + (_extTerm2 - _extTerm) / emptyHist->GetNbinsX());
10007 emptyHist->SetBinError(i, 0);
10009 emptyHist->GetYaxis()->SetTitle(
"log (L(#theta)/L(#theta_{0}))");
10010 emptyHist->SetTitle(
TString::Format(
"#theta = %g", (ii > 1) ? valueToDo : val));
10012 emptyHist->SetLineColor(
kBlack);
10014 emptyHist->SetLineColor(
kRed);
10015 }
else if (ii == 3) {
10016 emptyHist->SetLineColor(
kBlue);
10018 emptyHist->Draw(_drawn ?
"same" :
"");
10025 auto rar = get<RooAbsReal>();
10034 rarNode =
find(
".pdf").
get();
10045 v = getObject<RooAbsLValue>(
h->GetXaxis()->IsAlphanumeric() ?
h->GetXaxis()->GetTimeFormatOnly()
10046 :
h->GetXaxis()->GetName())
10049 if (
h->GetXaxis()->IsAlphanumeric()) {
10054 if (rar->InheritsFrom(
"RooAbsPdf") && !(rar->InheritsFrom(
"RooRealSumPdf") || rar->InheritsFrom(
"RooAddPdf") ||
10055 rar->InheritsFrom(
"RooSimultaneous"))) {
10058 rar->leafNodeServerList(&s);
10065 for (
auto _p : s) {
10072 ss +=
TString::Format(
"%s=%g", strlen(_p->GetTitle()) ? _p->GetTitle() : _p->GetName(), _v->getVal());
10073 if (_v->hasError()) {
10084 gPad->SetGrid(0, 0);
10086 gPad->SetGrid(1, 1);
10090 TString clNameNoNamespace = rar->ClassName();
10091 clNameNoNamespace = clNameNoNamespace(clNameNoNamespace.
Last(
':') + 1, clNameNoNamespace.
Length());
10092 TString dOpt = (clNameNoNamespace.
Contains(
"Hist") ||
vv->isCategory() || rar->isBinnedDistribution(*
vv) ||
10093 h->GetNbinsX() == 1 || rar->getAttribute(
"BinnedLikelihood") ||
10095 std::unique_ptr<std::list<double>>(rar->binBoundaries(*
dynamic_cast<RooAbsRealLValue *
>(
vv),
10096 -std::numeric_limits<double>::infinity(),
10097 std::numeric_limits<double>::infinity()))))
10103 if (dOpt ==
"LF2" && !
components().empty()) {
10106 bool allHist =
true;
10108 TString _clName = s->get()->ClassName();
10109 _clName = _clName(_clName.
Last(
':') + 1, _clName.
Length());
10110 if (!(s->get() && _clName.
Contains(
"Hist"))) {
10122 gROOT->SetEditHistograms(
true);
10124 gROOT->SetEditHistograms(
false);
10138 bool hasError(
false);
10139 for (
int i = 0; i <
h->GetSumw2N(); i++) {
10140 if (
h->GetSumw2()->At(i)) {
10151 if (!hasSame &&
h->GetYaxis()->GetTitleFont() % 10 == 2) {
10152 h->GetYaxis()->SetTitleOffset(1.);
10155 TH1 *errHist =
nullptr;
10158 h->SetFillColor(
h->GetLineColor());
10159 h->SetMarkerStyle(0);
10160 errHist =
dynamic_cast<TH1 *
>(
h->Clone(
Form(
"%s_err",
h->GetName())));
10163 h->SetFillStyle(0);
10164 for (
int i = 1; i <=
h->GetNbinsX(); i++) {
10165 h->SetBinError(i, 0);
10177 auto _hist = (errHist) ? errHist :
h;
10178 auto hCopy = (errHist) ?
nullptr :
dynamic_cast<TH1 *
>(
h->Clone());
10181 _hist->GetListOfFunctions()->Add(node);
10182 _hist->GetListOfFunctions()->Add(
new TExec(
10185 "gROOT->SetEditHistograms(true);auto h = dynamic_cast<TH1*>(gPad->GetPrimitive(\"%s\")); if(h) { double "
10186 "range= h->GetMaximum()-h->GetMinimum(); if(auto n "
10187 "= dynamic_cast<xRooNode*>(h->GetListOfFunctions()->FindObject(\"%s\")); n && "
10188 "n->TestBit(TObject::kNotDeleted) && n->get<RooRealVar>()->getVal() != h->GetBinContent(1)) {"
10189 "h->SetBinContent(1, "
10190 "TString::Format(\"%%.2g\",int(h->GetBinContent(1)/(range*0.01))*range*0.01).Atof());n->SetContent( "
10191 "h->GetBinContent(1) ); for(auto pp : *h->GetListOfFunctions()) if(auto hh = "
10192 "dynamic_cast<TH1*>(pp))hh->SetBinContent(1,h->GetBinContent(1));} if(h->GetBinContent(1)==0.) "
10193 "h->SetBinContent(1,range*0.005); gPad->Modified();gPad->Update(); }",
10194 _hist->GetName(), node->GetName())));
10200 _hist->GetListOfFunctions()->Add(hCopy,
"TEXT HIST same");
10201 _hist->SetBinError(1, 0);
10203 _hist->SetStats(
false);
10205 _hist->Draw(((errHist) ?
"e2" :
""));
10210 bool overlayExisted =
false;
10213 if (
auto existing =
dynamic_cast<TH1 *
>(
gPad->GetPrimitive(
h->GetName())); existing) {
10218 overlayExisted =
true;
10220 TString oldStyle = (rar && rar->getStringAttribute(
"style")) ? rar->getStringAttribute(
"style") :
"";
10221 h->SetTitle(overlayName);
10247 rar->setStringAttribute(
"style", oldStyle ==
"" ?
nullptr : oldStyle.
Data());
10271 h->Draw(dOpt + sOpt);
10282 std::map<std::string, int> colorByTitle;
10283 std::set<std::string> allTitles;
10284 bool titleMatchName =
true;
10285 std::map<std::string, TH1 *> histGroups;
10286 std::vector<TH1 *> hhs;
10287 std::set<TH1 *> histsWithBadTitles;
10293 if (!rarNode->components().empty()) {
10294 auto comps = rarNode->components()[0];
10295 for (
auto &
c : *comps) {
10296 if (
c->fFolder ==
"!.coeffs")
10300 if (!cms_coefs.
empty()) {
10302 std::shared_ptr<TH1> prevHist(
static_cast<TH1 *
>(
h->Clone()));
10303 for (
auto c : cms_coefs) {
10305 std::unique_ptr<RooAbsReal>
f(
10306 dynamic_cast<RooAbsReal *
>(rarNode->components()[0]->get()->
Clone(
"tmpCopy")));
10308 Form(
"ORIGNAME:%s",
c->GetName()));
10309 f->redirectServers(
RooArgSet(zero),
false,
true);
10315 hh->Scale(sf->
getVal());
10316 if (strlen(hh->GetTitle()) == 0) {
10317 hh->SetTitle(
c->GetName());
10318 histsWithBadTitles.insert(hh);
10319 }
else if (strcmp(hh->GetName(), hh->GetTitle()) == 0) {
10320 histsWithBadTitles.insert(hh);
10322 titleMatchName &= (
TString(
c->GetName()) == hh->GetTitle() ||
10324 std::shared_ptr<TH1> nextHist(
static_cast<TH1 *
>(hh->Clone()));
10325 hh->Add(prevHist.get(), -1.);
10328 prevHist = nextHist;
10330 }
else if (get<RooSimultaneous>()) {
10334 for (
auto &chan :
bins()) {
10335 TString chanName(chan->GetName());
10336 chanName = chanName(chanName.
Index(
"=") + 1, chanName.
Length());
10337 auto samps = chan->mainChild();
10340 for (
auto &samp : samps.components()) {
10341 auto hh =
static_cast<TH1 *
>(
h->Clone(samp->GetName()));
10343 hh->SetTitle(samp->GetTitle());
10344 if (strlen(hh->GetTitle()) == 0) {
10345 hh->SetTitle(samp->GetName());
10346 histsWithBadTitles.insert(hh);
10347 }
else if (strcmp(hh->GetName(), hh->GetTitle()) == 0) {
10348 histsWithBadTitles.insert(hh);
10350 hh->SetTitle(
TString(hh->GetTitle())
10351 .ReplaceAll(
TString(chan->get()->GetName()) +
"_",
10353 titleMatchName &= (
TString(samp->GetName()) == hh->GetTitle() ||
10355 hh->SetBinContent(hh->GetXaxis()->FindFixBin(chanName), samp->GetContent());
10360 for (
auto &samp : rarNode->components()) {
10361 auto hh = samp->BuildHistogram(
v);
10363 hh->Scale(sf->
getVal());
10365 if (strlen(hh->GetTitle()) == 0) {
10366 hh->SetTitle(samp->GetName());
10367 histsWithBadTitles.insert(hh);
10368 }
else if (strcmp(hh->GetName(), hh->GetTitle()) == 0) {
10369 histsWithBadTitles.insert(hh);
10371 titleMatchName &= (
TString(samp->GetName()) == hh->GetTitle() ||
10376 if (!hhs.empty()) {
10377 for (
auto &hh : hhs) {
10378 allTitles.insert(hh->GetTitle());
10383 size_t e = std::min(allTitles.begin()->size(), allTitles.rbegin()->size());
10385 bool goodPrefix =
false;
10386 std::string commonSuffix;
10387 if (titleMatchName && hhs.size() > 1) {
10388 while (ii <
e - 1 && allTitles.begin()->at(ii) == allTitles.rbegin()->at(ii)) {
10390 if (allTitles.begin()->at(ii) ==
'_' || allTitles.begin()->at(ii) ==
' ')
10396 while (!stop && commonSuffix.size() <
size_t(
e - 1)) {
10397 commonSuffix = allTitles.begin()->substr(allTitles.begin()->length() - commonSuffix.length() - 1);
10398 for (
auto &t : allTitles) {
10400 commonSuffix = commonSuffix.substr(1);
10406 if (commonSuffix.find(
'_') == std::string::npos) {
10409 commonSuffix = commonSuffix.substr(commonSuffix.find(
'_'));
10418 std::map<std::string, std::string> reducedTitles;
10419 while (reducedTitles.size() != allTitles.size()) {
10421 std::map<std::string, int> titlesMap;
10422 for (
auto &s : allTitles) {
10423 if (reducedTitles.count(s))
10425 titlesMap[s.substr(0, jj)]++;
10427 for (
auto &s : allTitles) {
10428 if (titlesMap[s.substr(0, jj)] == 1 && (jj >= s.length() || s.at(jj) ==
' ' || s.at(jj) ==
'_')) {
10429 reducedTitles[s] = s.substr(0, jj);
10435 for (
auto ritr = hhs.rbegin(); ritr != hhs.rend(); ++ritr) {
10436 if (!histsWithBadTitles.count((*ritr))) {
10439 auto _title = (hhs.size() > 5) ? reducedTitles[(*ritr)->GetTitle()] : (*ritr)->GetTitle();
10440 _title = _title.substr(ii < _title.size() ? ii : 0);
10441 if (!commonSuffix.empty() &&
TString(_title).
EndsWith(commonSuffix.c_str()))
10442 _title = _title.substr(0, _title.length() - commonSuffix.length());
10443 (*ritr)->SetTitle(_title.c_str());
10447 for (
auto &hh : hhs) {
10449 if (histGroups.find(hh->GetTitle()) == histGroups.end()) {
10450 histGroups[hh->GetTitle()] = hh;
10453 histGroups[hh->GetTitle()]->Add(hh);
10458 auto hhMin = (hh->GetMinimum() == 0) ? hh->GetMinimum(1
e-9) : hh->GetMinimum();
10459 if (!stack->
GetHists() &&
h->GetMinimum() > hhMin) {
10461 if (hhMin >= 0 && newMin < 0)
10462 newMin = hhMin * 0.99;
10463 adjustYRange(newMin,
h->GetMaximum());
10476 stack->
Add(hh, thisOpt);
10479 stack->
Draw(
"noclear same");
10483 h->Draw(
"axissame");
10489 for (
auto ho : *ll) {
10490 TH1 *hh =
dynamic_cast<TH1 *
>(ho);
10493 bool createdStyle = (
xRooNode(*hh, *
this).
style(
nullptr,
false) ==
nullptr);
10495 if (createdStyle) {
10503 for (
auto ho2 : *ll) {
10504 TH1 *hh2 =
dynamic_cast<TH1 *
>(ho2);
10518 *
dynamic_cast<TAttLine *
>(hh) = *_style;
10519 *
dynamic_cast<TAttFill *
>(hh) = *_style;
10532 }
else if (!overlayExisted) {
10543 errHist->
Draw(dOpt + (dOpt.
Contains(
"LF2") ?
"e3same" :
"e2same"));
10544 double ymax = -std::numeric_limits<double>::infinity();
10545 double ymin = std::numeric_limits<double>::infinity();
10546 for (
int i = 1; i <= errHist->
GetNbinsX(); i++) {
10552 adjustYRange(
h->GetMinimum() * 0.9,
h->GetMaximum() * 1.1);
10555 if ((!auxPlotTitle.empty()) && !hasSame) {
10557 double padFrac = 0.3;
10558 auto _tmpPad =
gPad;
10559 gPad->SetBottomMargin(padFrac);
10560 auto ratioPad =
new TPad(
"auxPad",
"aux plot", 0, 0, 1, padFrac);
10561 ratioPad->SetFillColor(_tmpPad->GetFillColor());
10562 ratioPad->SetNumber(1);
10563 ratioPad->SetBottomMargin(ratioPad->GetBottomMargin() / padFrac);
10564 ratioPad->SetTopMargin(0.04);
10565 ratioPad->SetLeftMargin(
gPad->GetLeftMargin());
10566 ratioPad->SetRightMargin(
gPad->GetRightMargin());
10568 TH1 *ratioHist =
dynamic_cast<TH1 *
>((errHist) ? errHist->
Clone(
"auxHist") :
h->
Clone(
"auxHist"));
10577 auxPlotTitle.c_str()));
10580 ratioPad->SetGridy();
10582 for (
int i = 1; i <= ratioHist->
GetNbinsX(); i++) {
10590 double rHeight = 1. / padFrac;
10598#if ROOT_VERSION_CODE < ROOT_VERSION(6, 26, 00)
10607 auto _h =
dynamic_cast<TH1 *
>(ratioHist->
Clone(
"auxHist_clone"));
10609 _h->SetFillColor(0);
10615 TString::Format(
"auto h1 = (TH1*)%p; auto h2 = (TH1*)%p; if(h2->GetXaxis()->GetFirst() != "
10616 "h1->GetXaxis()->GetFirst() || h1->GetXaxis()->GetLast()!=h2->GetXaxis()->GetLast()) "
10617 "{h2->GetXaxis()->SetRange(h1->GetXaxis()->GetFirst(),h1->GetXaxis()->GetLast());if(gPad) "
10618 "{gPad->GetCanvas()->Paint();gPad->GetCanvas()->Update();}}",
10619 (
void *)ratioHist, (
void *)(
h))));
10620 ratioHist->
Draw((errHist ?
"e2" :
""));
10624 }
else if (
auto ratioPad =
dynamic_cast<TPad *
>(
gPad->GetPrimitive(
"auxPad")); hasSame && ratioPad) {
10628 if (
auto hr =
dynamic_cast<TH1 *
>(ratioPad->GetPrimitive(
"auxHist"));
10630 TString histName = hr->GetTitle();
10632 histName = histName(0, histName.
Index(
'|'));
10634 if (
auto hnom =
dynamic_cast<TH1 *
>(
gPad->GetPrimitive(histName)); hnom) {
10635 h =
dynamic_cast<TH1 *
>(
h->Clone(
h->GetName()));
10638 for (
int i = 1; i <= hnom->GetNbinsX(); i++) {
10639 double val =
h->GetBinContent(i);
10640 double err =
h->GetBinError(i);
10641 h->SetBinContent(i, std::get<0>(
auxFunctions[hr->GetYaxis()->GetTitle()])(
10642 h->GetBinContent(i), hnom->GetBinContent(i), hnom->GetBinError(i)));
10643 h->SetBinError(i, std::get<0>(
auxFunctions[hr->GetYaxis()->GetTitle()])(
10644 val + err, hnom->GetBinContent(i), hnom->GetBinError(i)) -
10645 h->GetBinContent(i));
10647 auto _tmpPad =
gPad;
10650 if (
auto existing =
dynamic_cast<TH1 *
>(ratioPad->GetPrimitive(
h->GetName())); existing) {
10655 overlayExisted =
true;
10662 double ymax = -std::numeric_limits<double>::infinity();
10663 double ymin = std::numeric_limits<double>::infinity();
10664 for (
int i = 1; i <=
h->GetNbinsX(); i++) {
10665 ymax = std::max(
ymax,
h->GetBinContent(i) +
h->GetBinError(i));
10666 ymin = std::min(
ymin,
h->GetBinContent(i) -
h->GetBinError(i));
10695 if (
auto _pdf = get<RooAbsPdf>();
10696 !hasSame && _pdf &&
coefs().empty()) {
10699 for (
auto &
d : _dsets) {
10700 if (
d->get()->TestBit(1 << 20)) {
10719 if (
auto w = get<RooWorkspace>();
w) {
10722#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
10731 Error(
"SaveAs",
"json format workspaces only in ROOT 6.26 onwards");
10736#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
10740 for (
auto &
c :
w->components()) {
10741 c->_eocache =
nullptr;
10745 if (!
w->writeToFile(
filename, sOpt !=
"update")) {
10749 if (
auto fitDb =
dynamic_cast<TFile *
>(
gROOT->GetListOfFiles()->FindObject(
"fitDatabase"))) {
10754 auto dir =
dest->GetDirectory(source->
GetName());
10759 auto key =
dynamic_cast<TKey *
>(k);
10769 if (dir->FindKey(key->GetName()))
10772 if (strcmp(classname,
"ROOT::Fit::FitConfig") == 0) {
10774 dir->WriteObject(fc, key->GetName());
10777 TObject *obj = key->ReadObj();
10779 dir->WriteTObject(obj, key->
GetName());
10786 CopyDir(fitDb, std::make_unique<TFile>(
filename,
"UPDATE").
get());
10793#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
10795 for (
auto &
c :
w->components()) {
10796 c->setExpensiveObjectCache(
w->expensiveObjectCache());
10806 return std::numeric_limits<double>::quiet_NaN();
10812 std::vector<double> out;
10813 out.reserve(
size());
10814 for (
auto child : *
this) {
10815 out.push_back(
child->GetContent());
10829 auto rho = _fr->correlationMatrix();
10833 auto _pars =
pars();
10838 for (
int m = 0;
m < rho.GetNrows();
m++) {
10839 auto p_m =
dynamic_cast<RooRealVar *
>(_fr->floatParsFinal().at(
m));
10845 auto tmp = _p->getVal();
10846 _p->setVal(p_m->getVal() + p_m->getErrorHi());
10848 _p->setVal(p_m->getVal() + p_m->getErrorLo());
10851 for (
int n = 0;
n < rho.GetNrows();
n++) {
10852 auto p_n =
dynamic_cast<RooRealVar *
>(_fr->floatParsFinal().at(
n));
10858 auto tmp2 = _p2->
getVal();
10859 _p2->setVal(p_n->getVal() + p_n->getErrorHi());
10860 auto nu_n = (p_n == p_m) ? nu_m :
contents();
10861 _p2->setVal(p_n->getVal() + p_n->getErrorLo());
10862 auto nu_n2 = (p_n == p_m) ? nu_m2 :
contents();
10864 for (
int i = 0; i < out.GetNrows(); i++) {
10865 for (
int j = 0; j < out.GetNrows(); j++) {
10866 out(i, j) += 0.25 * (nu_m[i] - nu_m2[i]) * rho(
m,
n) * (nu_n[j] - nu_n2[j]);
10877 double err = std::numeric_limits<double>::quiet_NaN();
10879 std::unique_ptr<RooAbsCollection> _snap;
10884 _pars = _fr->floatParsFinal();
10885 _pars = _fr->constPars();
10889 auto _coefs =
coefs();
10897 p->setNormRange(rangeName);
10898#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 27, 00)
10901 out *=
p->expectedEvents(*_obs.get<
RooArgList>());
10902#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
10904 p->_normSet =
nullptr;
10908 p->setNormRange(
nullptr);
10909 }
else if (
auto p2 =
dynamic_cast<RooAbsReal *
>(
get()); p2) {
10911 auto f = std::shared_ptr<RooAbsReal>(
10912 p2->createIntegral(*std::unique_ptr<RooArgSet>(p2->getObservables(*_obs.get<
RooArgList>())),
10916 out *=
f->getVal();
10919 }
else if (get<RooAbsData>()) {
10922 auto ax = (rangeName) ?
GetXaxis() :
nullptr;
10923 auto rv = (ax) ?
dynamic_cast<RooRealVar *
>(ax->GetParent()) :
nullptr;
10924 auto cv = (ax && !rv) ?
dynamic_cast<RooCategory *
>(ax->GetParent()) :
nullptr;
10926 for (
auto &
v : vals) {
10929 if (rv && !rv->inRange(ax->GetBinCenter(i), rangeName))
10931 if (cv && !cv->isStateInRange(rangeName, ax->GetBinLabel(i)))
10938 out = std::numeric_limits<double>::quiet_NaN();
10941 _pars.RooAbsCollection::operator=(*_snap);
10943 return std::make_pair(out, err);
10955 if (binStart != binEnd || !
fParent) {
10961 std::vector<double> out;
10967 std::shared_ptr<RooFitResult> fr = std::dynamic_pointer_cast<RooFitResult>(_fr.
fComp);
10970 auto _coefs =
coefs();
10980 fr = std::dynamic_pointer_cast<RooFitResult>(frn.fComp);
10983 if (!
GETDMP(fr.get(), _finalPars)) {
11007 if (!prevCov ||
size_t(prevCov->
GetNcols()) < fr->floatParsFinal().size()) {
11010 for (
int i = 0; i < prevCov->
GetNcols(); i++) {
11011 for (
int j = 0; j < prevCov->
GetNrows(); j++) {
11012 cov(i, j) = (*prevCov)(i, j);
11017 for (
auto &
p : fr->floatParsFinal()) {
11018 if (!prevCov || i >= prevCov->
GetNcols()) {
11019 cov(i, i) = pow(
dynamic_cast<RooRealVar *
>(
p)->getError(), 2);
11023 int covQualBackup = fr->covQual();
11024 fr->setCovarianceMatrix(cov);
11025 fr->setCovQual(covQualBackup);
11028 bool doBinWidth =
false;
11029 auto ax = (binStart == -1 && binEnd == -1) ?
nullptr :
GetXaxis();
11036 normSet.
add(*
dynamic_cast<RooAbsArg *
>(ax->GetParent()));
11039 if (
auto p =
dynamic_cast<RooAbsPdf *
>(o); ax && (
p || _coefs.get() || o->getAttribute(
"density"))) {
11045 binEnd = ax->GetNbins();
11050 for (
int bin = binStart; bin <= binEnd; bin++) {
11052 dynamic_cast<RooAbsLValue *
>(ax->GetParent())->setBin(bin - 1, ax->GetName());
11059#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
11061 p->_normSet =
nullptr;
11071 .getPropagatedError(*fr, normSet);
11074 res *= ax->GetBinWidth(bin);
11076 out.push_back(res);
11082std::string cling::printValue(
const xRooNode *
v)
11085 return "nullptr\n";
11088 size_t left =
v->size();
11089 for (
auto n : *
v) {
11095 out +=
n->GetName();
11096 if (out.length() > 100 && left > 0) {
11102 out = std::string(
Form(
"<%s> %s",
v->get() ?
v->get()->ClassName() :
"nullptr",
v->GetName())) + out;
11107 return "<nullptr>";
11109 return Form(
"<%s> %s",
v->get() ?
v->get()->ClassName() :
"nullptr",
v->GetName());
#define ROOT_VERSION(a, b, c)
#define ROOT_VERSION_CODE
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
static void indent(ostringstream &buf, int indent_level)
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
winID h TVirtualViewer3D TVirtualGLPainter p
winID h TVirtualViewer3D vv
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 dest
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 Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
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 Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
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 Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
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 char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t child
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void funcs
Option_t Option_t SetFillColor
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 Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
R__EXTERN TStyle * gStyle
R__EXTERN TSystem * gSystem
double GetBinLowEdge(Int_t bin) const override
Return low edge of bin.
double GetBinUpEdge(Int_t bin) const override
Return up edge of bin.
Int_t FindFixBin(double x) const override
Find bin number corresponding to abscissa x.
void Set(Int_t nbins, const double *xbins) override
Initialize axis with variable bins.
RooAbsRealLValue * rvar() const
void SetTitle(const char *title) override
Set the title of the TNamed.
void Set(Int_t nbins, double xmin, double xmax) override
Initialize axis with fix bins.
Int_t FindFixBin(const char *label) const override
Find bin number with label.
RooAbsLValue * var() const
const RooAbsBinning * binning() const
void Set(Int_t nbins, const float *xbins) override
Initialize axis with variable bins.
const char * GetTitle() const override
Returns title of object.
double GetBinWidth(Int_t bin) const override
Return bin width.
PadRefresher(TVirtualPad *p)
A class which maps the current values of a RooRealVar (or a set of RooRealVars) to one of a number of...
bool isBinnedDistribution(const RooArgSet &obs) const override
Tests if the distribution is binned. Unless overridden by derived classes, this always returns false.
bool selfNormalized() const override
Shows if a PDF is self-normalized, which means that no attempt is made to add a normalization term.
double getSimplePropagatedError(const RooFitResult &fr, const RooArgSet &nset_in) const
double evaluate() const override
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
TObject * clone(const char *newname) const override
std::list< double > * binBoundaries(RooAbsRealLValue &obs, double xlo, double xhi) const override
Retrieve bin boundaries if this distribution is binned in obs.
PdfWrapper(const PdfWrapper &other, const char *name=nullptr)
PdfWrapper(RooAbsReal &f, RooAbsReal *coef, bool expEvMode=false, RooAbsPdf *expPdf=nullptr)
The PiecewiseInterpolation is a class that can morph distributions into each other,...
static std::shared_ptr< RooLinkedList > createNLLOptions()
static std::pair< std::shared_ptr< RooAbsData >, std::shared_ptr< const RooAbsCollection > > generateFrom(RooAbsPdf &pdf, const RooFitResult &fr, bool expected=false, int seed=0)
static xRooNLLVar createNLL(const std::shared_ptr< RooAbsPdf > pdf, const std::shared_ptr< RooAbsData > data, const RooLinkedList &nllOpts)
static std::pair< double, double > matchPrecision(const std::pair< double, double > &in)
void Draw(Option_t *opt="") override
Default Draw method for all objects.
std::shared_ptr< xRooHypoPoint > asimov(bool readOnly=false)
std::shared_ptr< const RooFitResult > ufit(bool readOnly=false)
std::shared_ptr< const RooFitResult > cfit_null(bool readOnly=false)
std::shared_ptr< const RooFitResult > cfit_alt(bool readOnly=false)
std::shared_ptr< const RooFitResult > gfit()
void Draw(Option_t *opt="") override
Default Draw method for all objects.
This xRooNLLVar object has several special methods, e.g.
xRooHypoSpace hypoSpace(const char *parName, int nPoints, double low, double high, double alt_value=std::numeric_limits< double >::quiet_NaN(), const xRooFit::Asymptotics::PLLType &pllType=xRooFit::Asymptotics::Unknown)
The xRooNode class is designed to wrap over a TObject and provide functionality to aid with interacti...
void _Add_(const char *name, const char *opt)
xRooNode filter(const xRooNode &range) const
void _scan_(const char *what="plr", double nToys=0, const char *xvar="", int nPointsX=0, double lowX=0, double highX=0, const char *constParValues="")
std::vector< std::shared_ptr< xRooNode > > fBrowsables
xRooNLLVar nll(const xRooNode &_data, std::initializer_list< RooCmdArg > nllOpts) const
xRooNode poi() const
List of parameters of interest: parameters marked as "of interest" These parameters have the "poi" at...
void SetName(const char *name) override
Set the name of the TNamed.
TGListTreeItem * GetTreeItem(TBrowser *b) const
void SetTitle(const char *title) override
Set the title of the TNamed.
xRooNode Multiply(const xRooNode &child, Option_t *opt="")
xRooNode Replace(const xRooNode &node)
bool SetData(const TObject &obj, const xRooNode &data="obsData")
xRooNode datasets() const
xRooNode Remove(const xRooNode &child)
xRooNode globs() const
List of global observables of this node.
xRooNode Combine(const xRooNode &rhs)
xRooNode Add(const xRooNode &child, Option_t *opt="")
xRooNode(const char *type, const char *name, const char *title="")
const char * GetIconName() const override
Returns mime type name of object.
void Draw(Option_t *opt="") override
Default Draw method for all objects.
double GetBinError(int bin, const xRooNode &fr="") const
std::vector< double > GetBinErrors(int binStart=1, int binEnd=0, const xRooNode &fr="") const
bool _IsShowVars_() const
TGraph * BuildGraph(RooAbsLValue *v=nullptr, bool includeZeros=false, TVirtualPad *fromPad=nullptr) const
const std::shared_ptr< xRooNode > & at(size_t idx, bool browseResult=true) const
const char * GetNodeType() const
bool SetBinContent(int bin, double value, const char *par=nullptr, double parVal=1)
std::shared_ptr< xRooNode > operator[](size_t idx)
void Checked(TObject *obj, bool val)
void Print(Option_t *opt="") const override
Print TNamed name and title.
double GetContent() const
std::shared_ptr< T > acquireNew(Args &&...args)
std::shared_ptr< T > acquire2(Args &&...args)
xRooNode components() const
void SaveAs(const char *filename="", Option_t *option="") const override
Save this object in the file specified by filename.
xRooNode bins() const
bins of a channel or sample, or channels of a multi-channel pdf
std::shared_ptr< xRooNode > find(const std::string &name, bool browseResult=true) const
TGListTree * GetListTree(TBrowser *b) const
bool fInterrupted
appears that if was fXaxis then dialog box for SetXaxis will take as current value
xRooNode generate(const xRooNode &fr="", bool expected=false, int seed=0)
void Inspect() const override
Dump contents of this object in a graphics canvas.
std::shared_ptr< xRooNode > getBrowsable(const char *name) const
bool SetXaxis(const RooAbsBinning &binning)
RooArgList argList() const
bool SetBinData(int bin, double value, const xRooNode &data="obsData")
void SetHidden(bool set=true)
std::function< xRooNode(xRooNode *)> fBrowseOperation
std::vector< double > GetBinContents(int binStart=1, int binEnd=0) const
xRooNode pp() const
List of prespecified parameters: non-floatable parameters.
xRooNode constraints() const
std::shared_ptr< xRooNode > fProvider
std::shared_ptr< TStyle > style(TObject *initObject=nullptr, bool autoCreate=true) const
xRooNode mainChild() const
xRooNode fitResult(const char *opt="") const
std::shared_ptr< TAxis > fXAxis
only here so can have char* GetRange return so can return nullptr for no range set (required for RooC...
xRooNode coords(bool setVals=true) const
xRooNode Vary(const xRooNode &child)
xRooNode Constrain(const xRooNode &child)
static std::map< std::string, std::tuple< std::function< double(double, double, double)>, bool > > auxFunctions
xRooNode pars() const
List of parameters (non-observables) of this node.
void _SetContent_(double value)
void SetFitResult(const RooFitResult *fr=nullptr)
void _ShowVars_(bool set=true)
bool IsFolder() const override
Returns kTRUE in case object contains browsable objects (like containers or lists of other objects).
double GetBinData(int bin, const xRooNode &data="obsData")
bool SetBinError(int bin, double value)
void _Vary_(const char *what)
xRooNode histo(const xRooNode &vars="x", const xRooNode &fr="", bool content=true, bool errors=true) const
bool SetContents(const TObject &obj)
std::shared_ptr< TObject > fComp
std::vector< double > contents() const
RooWorkspace * ws() const
The RooWorkspace this node belong to, if any.
xRooNode shallowCopy(const std::string &name, std::shared_ptr< xRooNode > parent=nullptr)
void _generate_(const char *name="", bool expected=false)
void _fit_(const char *constParValues="")
std::shared_ptr< TObject > getObject(const std::string &name, const std::string &type="") const
xRooNode np() const
List of nuisance parameters: non-constant parameters that are not marked of interest,...
xRooNode floats() const
List of parameters that are currently non-constant These parameters do not have the "Constant" attrib...
bool contains(const std::string &name) const
xRooNode reduced(const std::string &range="", bool invert=false) const
xRooNode variations() const
std::string GetPath() const
auto begin() const -> xRooNodeIterator
std::shared_ptr< xRooNode > parentPdf() const
like a parent but only for use by getObject
bool SetContent(double value)
std::shared_ptr< xRooNode > fParent
std::pair< double, double > IntegralAndError(const xRooNode &fr="", const char *rangeName=nullptr) const
xRooNode robs() const
List of regular observables of this node.
TClass * IsA() const override
xRooNode & operator=(const TObject &o)
auto end() const -> xRooNodeIterator
TH1 * BuildHistogram(RooAbsLValue *v=nullptr, bool empty=false, bool errors=false, int binStart=1, int binEnd=0, const xRooNode &fr="") const
xRooNode consts() const
List of parameters that are currently constant.
void _SetBinContent_(int bin, double value, const char *par="", double parVal=1)
std::shared_ptr< TObject > acquire(const std::shared_ptr< TObject > &arg, bool checkFactory=false, bool mustBeNew=false)
void Browse(TBrowser *b=nullptr) override
Browse object. May be overridden for another default action.
xRooNode obs() const
List of observables (global and regular) of this node.
void SetRange(const char *range, double low=std::numeric_limits< double >::quiet_NaN(), double high=std::numeric_limits< double >::quiet_NaN())
static void SetAuxFunction(const char *title, const std::function< double(double, double, double)> &func, bool symmetrize=false)
std::shared_ptr< TObject > convertForAcquisition(xRooNode &acquirer, const char *opt="") const
double GetError(const xRooNode &fr="") const
xRooNode vars() const
List of variables (observables and parameters) of this node.
const char * GetRange() const
TMatrixDSym covariances(const xRooNode &fr="") const
Class describing the configuration of the fit, options and parameter settings using the ROOT::Fit::Pa...
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.
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string 'value' to this object under key 'key'.
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...
RooFit::OwningPtr< RooArgSet > getObservables(const RooArgSet &set, bool valueOnly=true) const
Given a set of possible observables, return the observables that this PDF depends on.
void SetName(const char *name) override
Set the name of the TNamed.
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key 'key'.
bool getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
void setAttribute(const Text_t *name, bool value=true)
Set (default) or clear a named boolean attribute of this object.
virtual bool isFundamental() const
Is this object a fundamental type that can be added to a dataset? Fundamental-type subclasses overrid...
Abstract base class for RooRealVar binning definitions.
virtual double highBound() const =0
virtual double lowBound() const =0
Abstract base class for objects that represent a discrete value that can be set from the outside,...
A space to attach TBranches.
virtual value_type getCurrentIndex() const
Return index number of current state.
const char * getLabel() const
Retrieve current label. Use getCurrentLabel() for more clarity.
Abstract container object that can hold multiple RooAbsArg objects.
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 void removeAll()
Remove all arguments from our set, deleting them if we own them.
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
RooAbsCollection * snapshot(bool deepCopy=true) const
Take a snap shot of current collection contents.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Storage_t::size_type size() const
void clear()
Clear contents. If the collection is owning, it will also delete the contents.
virtual RooAbsArg * addClone(const RooAbsArg &var, bool silent=false)
Add a clone of the specified argument to list.
bool selectCommon(const RooAbsCollection &refColl, RooAbsCollection &outColl) const
Create a subset of the current collection, consisting only of those elements that are contained as we...
RooAbsArg * find(const char *name) const
Find object with given name in list.
Abstract base class for binned and unbinned datasets.
RooFit::OwningPtr< RooAbsData > reduce(const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
Create a reduced copy of this dataset.
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
Abstract base class for objects that are lvalues, i.e.
virtual std::list< std::string > getBinningNames() const =0
Abstract interface for all probability density functions.
bool canBeExtended() const
If true, PDF can provide extended likelihood term.
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
void setBin(Int_t ibin, const char *rangeName=nullptr) override
Set value to center of bin 'ibin' of binning 'rangeName' (or of default binning if no range is specif...
bool hasRange(const char *name) const override
Check if variable has a binning with given name.
Context to temporarily change the error logging mode as long as the context is alive.
Abstract base class for objects that represent a real value and implements functionality common to al...
bool isSelectedComp() const
If true, the current pdf is a selected component (for use in plotting)
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
virtual void forceNumInt(bool flag=true)
Efficient implementation of a sum of PDFs of the form.
Calculates the sum of a set of RooAbsReal terms, or when constructed with two sets,...
RooArgList is a container object that can hold multiple RooAbsArg objects.
RooAbsArg * at(Int_t idx) const
Return object at given index, or nullptr if index is out of range.
Abstract interface for RooAbsArg proxy classes.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Implements a RooAbsBinning in terms of an array of boundary values, posing no constraints on the choi...
Object to represent discrete states.
bool defineType(const std::string &label)
Define a state with given name.
Named container for two doubles, two integers two object points and three string pointers that can be...
static const RooCmdArg & none()
Return reference to null argument.
Represents a constant real-valued object.
Container class to hold N-dimensional binned data.
Container class to hold unbinned data.
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
void setCovQual(Int_t val)
const TMatrixDSym & covarianceMatrix() const
Return covariance matrix.
TMatrixDSym reducedCovarianceMatrix(const RooArgList ¶ms) const
Return a reduced covariance matrix (Note that Vred is a simple sub-matrix of V, row/columns are order...
void setCovarianceMatrix(TMatrixDSym &V)
Store externally provided correlation matrix in this RooFitResult ;.
const RooArgList & constPars() const
Return list of constant parameters.
void SetName(const char *name) override
Change name of RooFitResult object.
Int_t covQual() const
Return MINUIT quality code of covariance matrix.
const RooArgList & floatParsFinal() const
Return list of floating parameters after fit.
void setFinalParList(const RooArgList &list)
Fill the list of final values of the floating parameters.
UInt_t numStatusHistory() const
Implementation of a probability density function that takes a RooArgList of servers and a C++ express...
A real-valued function sampled from a multidimensional histogram.
bool isBinnedDistribution(const RooArgSet &) const override
Tests if the distribution is binned. Unless overridden by derived classes, this always returns false.
Collection class for internal use, storing a collection of RooAbsArg pointers in a doubly linked list...
TObject * At(int index) const
Return object stored in sequential position given by index.
TIterator * MakeIterator(bool forward=true) const
Create a TIterator for this list.
static RooMsgService & instance()
Return reference to singleton instance.
StreamConfig & getStream(Int_t id)
void setGlobalKillBelow(RooFit::MsgLevel level)
RooFit::MsgLevel globalKillBelow() const
Implementation of a RooCacheManager<RooAbsCacheElement> that specializes in the storage of cache elem...
Efficient implementation of a product of PDFs of the form.
Represents the product of a given set of RooAbsReal objects.
A RooAbsPdf implementation that represent a projection of a given input p.d.f and the object returned...
RooProjectedPdf()
Default constructor.
Implements a PDF constructed from a sum of functions:
Variable that can be changed from the outside.
void setVal(double value) override
Set value of variable to 'value'.
void setError(double value)
bool hasError(bool allowZero=true) const
Facilitates simultaneous fitting of multiple PDFs to subsets of a given dataset.
const RooAbsCategoryLValue & indexCat() const
HypoTestResult is a base class for results from hypothesis tests.
A RooAbsArg implementing string values.
Persistable container for RooFit projects.
const std::map< std::string, RooArgSet > & sets() const
bool import(const RooAbsArg &arg, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}, const RooCmdArg &arg9={})
Import a RooAbsArg object, e.g.
bool removeSet(const char *name)
Remove a named set from the workspace.
RooFactoryWSTool & factory()
Return instance to factory tool.
const Double_t * GetArray() const
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title.
virtual Style_t GetTitleFont() const
virtual void SetLabelSize(Float_t size=0.04)
Set size of axis labels.
virtual void SetTitleSize(Float_t size=0.04)
Set size of axis title.
virtual Float_t GetTitleSize() const
virtual Float_t GetLabelSize() const
virtual Float_t GetTickLength() const
virtual Float_t GetTitleOffset() const
virtual void SetTickLength(Float_t length=0.03)
Set tick mark length.
virtual void SetNdivisions(Int_t n=510, Bool_t optim=kTRUE)
Set the number of divisions for this axis.
Fill Area Attributes class.
virtual Color_t GetFillColor() const
Return the fill area color.
virtual Style_t GetFillStyle() const
Return the fill area style.
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
virtual void SetLineColor(Color_t lcolor)
Set the line color.
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
virtual Font_t GetTextFont() const
Return the text font.
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Class to manage histogram axis.
virtual void LabelsOption(Option_t *option="h")
Set option(s) to draw axis with labels option can be:
virtual void SetBinLabel(Int_t bin, const char *label)
Set label for bin.
Bool_t IsAlphanumeric() const
Bool_t IsVariableBinSize() const
const char * GetTitle() const override
Returns title of object.
TAxis()
Default constructor.
const TArrayD * GetXbins() const
const char * GetBinLabel(Int_t bin) const
Return label for bin.
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x.
virtual const char * GetTimeFormatOnly() const
Return only the time format from the string fTimeFormat.
Using a TBrowser one can browse all ROOT objects.
TBrowserImp * GetBrowserImp() const
static TCanvas * MakeDefCanvas()
Static function to build a default canvas.
TClass instances represent classes, structs and namespaces in the ROOT type system.
Bool_t InheritsFrom(const char *cl) const override
Return kTRUE if this class inherits from a class with name "classname".
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.
void SetName(const char *name)
virtual Int_t GetEntries() const
virtual void RemoveAll(TCollection *col)
Remove all objects in collection col from this collection.
static Int_t GetColorPalette(Int_t i)
Static function returning the color number i in current palette.
static Int_t GetNumberOfColors()
Static function returning number of colors in the color palette.
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 TList * GetListOfKeys() const
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=nullptr)
Set the value of a resource or create a new resource.
TExec is a utility class that can be used to execute a C++ command when some event happens in a pad.
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...
Create a dialog for fit function parameter settings.
System file browser, used as TRootBrowser plug-in.
void AddFSDirectory(const char *entry, const char *path=nullptr, Option_t *opt="")
Add file system directory in the list tree.
A list tree is a widget that can contain a number of items arranged in a tree structure.
ROOT GUI Window base class.
virtual void SetName(const char *name)
virtual void SetTitle(const char *title="")
Change the title of the axis.
virtual void ImportAxisAttributes(TAxis *axis)
Internal method to import TAxis attributes to this TGaxis.
TGraph with asymmetric error bars.
virtual void SetPointError(Double_t exl, Double_t exh, Double_t eyl, Double_t eyh)
Set ex and ey values for point pointed by the mouse.
A TGraphErrors is a TGraph with error bars.
Double_t GetErrorYlow(Int_t bin) const override
It returns the error along Y at point i.
Double_t GetErrorYhigh(Int_t bin) const override
It returns the error along Y at point i.
A TGraph is an object made of two arrays X and Y with npoints each.
virtual void AddPoint(Double_t x, Double_t y)
Append a new point to the graph.
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
void SetName(const char *name="") override
Set graph name.
void Draw(Option_t *chopt="") override
Draw this graph with its current attributes.
virtual Double_t GetPointY(Int_t i) const
Get y value for point i.
void SetTitle(const char *title="") override
Change (i.e.
virtual void SetPointX(Int_t i, Double_t x)
Set x value for point i.
virtual void SetEditable(Bool_t editable=kTRUE)
if editable=kFALSE, the graph cannot be modified with the mouse by default a TGraph is editable
1-D histogram with a double per channel (see TH1 documentation)
1-D histogram with a float per channel (see TH1 documentation)
TH1 is the base class of all histogram classes in ROOT.
virtual void SetDirectory(TDirectory *dir)
By default, when a histogram is created, it is added to the list of histogram objects in the current ...
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
void SetTitle(const char *title) override
Change/set the title.
virtual Int_t GetNbinsY() const
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
@ kNoTitle
Don't draw the histogram title.
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
TObject * FindObject(const char *name) const override
Search object named name in the list of functions.
virtual Int_t GetNbinsX() const
virtual void SetMaximum(Double_t maximum=-1111)
virtual void SetBinError(Int_t bin, Double_t error)
Set the bin Error Note that this resets the bin eror option to be of Normal Type and for the non-empt...
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
void Draw(Option_t *option="") override
Draw this histogram with options.
virtual void SetMinimum(Double_t minimum=-1111)
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
TList * GetListOfFunctions() const
void SetName(const char *name) override
Change the name of this histogram.
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
virtual Bool_t Divide(TF1 *f1, Double_t c1=1)
Performs the operation: this = this/(c1*f1) if errors are defined (see TH1::Sumw2),...
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
2-D histogram with a double per channel (see TH1 documentation)
The Histogram stack class.
virtual void Add(TH1 *h, Option_t *option="")
Add a new histogram to the list.
void Draw(Option_t *chopt="") override
Draw this stack with its current attributes.
Book space in a file, create I/O buffers, to fill them, (un)compress them.
virtual const char * GetClassName() const
Storage class for one entry of a TLegend.
This class displays a legend box (TPaveText) containing several legend entries.
TLegendEntry * AddEntry(const TObject *obj, const char *label="", Option_t *option="lpf")
Add a new entry to this legend.
void SetNColumns(Int_t nColumns)
Set the number of columns for the legend.
void SetMargin(Float_t margin)
Use the TLine constructor to create a simple line.
virtual void SetY2(Double_t y2)
virtual void SetX2(Double_t x2)
virtual void SetX1(Double_t x1)
virtual void SetY1(Double_t y1)
void Add(TObject *obj) override
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
A TMultiGraph is a collection of TGraph (or derived) objects.
virtual void Add(TGraph *graph, Option_t *chopt="")
Add a new graph to the list of graphs.
void Draw(Option_t *chopt="") override
Draw this multigraph with its current attributes.
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.
const char * GetTitle() const override
Returns title of object.
void Clear(Option_t *option="") override
Set name and title to empty strings ("").
virtual void SetName(const char *name)
Set the name of the TNamed.
virtual void SetNameTitle(const char *name, const char *title)
Set all the TNamed parameters (name and title).
Mother of all ROOT objects.
virtual void Inspect() const
Dump contents of this object in a graphics canvas.
virtual const char * GetName() const
Returns name of object.
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
virtual const char * ClassName() const
Returns name of class to which the object belongs.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
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 Error(const char *method, const char *msgfmt,...) const
Issue error message.
virtual const char * GetTitle() const
Returns title of object.
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
@ kCanDelete
if object in a list can be deleted
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
The most important graphics class in the ROOT system.
A Pave (see TPave) with text, lines or/and boxes inside.
virtual TText * AddText(Double_t x1, Double_t y1, const char *label)
Add a new Text line to this pavetext at given coordinates.
virtual void SetMargin(Float_t margin=0.05)
virtual void SetY1NDC(Double_t y1)
virtual void ConvertNDCtoPad()
Convert pave coordinates from NDC to Pad coordinates.
virtual void SetName(const char *name="")
virtual void SetBorderSize(Int_t bordersize=4)
Sets the border size of the TPave box and shadow.
virtual void SetY2NDC(Double_t y2)
void SetEntryVal(Int_t, Double_t)
Set the value of a slice.
void SetEntryFillColor(Int_t, Int_t)
Set the color for the slice "i".
void SetRadius(Double_t)
Set the pie chart's radius' value.
void SetEntryLabel(Int_t, const char *text="Slice")
Set slice number "i" label.
void Draw(Option_t *option="l") override
Draw the pie chart.
This is the ROOT implementation of the Qt object communication mechanism (see also http://www....
Regular expression class.
This class creates a ROOT object browser, constituted by three main tabs.
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 Stop()
Stop the stopwatch.
Provides iteration through tokens of a given string.
Bool_t NextToken()
Get the next token, it is stored in this TString.
Bool_t IsDec() const
Returns true if all characters in string are decimal digits (0-9).
void ToLower()
Change string to lower-case.
Int_t Atoi() const
Return integer value of string.
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Double_t Atof() const
Return floating-point value contained in string.
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
const char * Data() const
TString & ReplaceAll(const TString &s1, const TString &s2)
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Int_t CountChar(Int_t c) const
Return number of times character c occurs in the string.
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
TStyle objects may be created to define special styles.
void SetPaintTextFormat(const char *format="g")
Int_t GetOptTitle() const
Float_t GetLabelSize(Option_t *axis="X") const
Return label size.
Float_t GetPadRightMargin() const
Style_t GetTitleFont(Option_t *axis="X") const
Return title font.
Bool_t GetHistMinimumZero() const
Float_t GetPadLeftMargin() const
Float_t GetTitleYSize() const
Double_t GetHistTopMargin() const
Float_t GetPadBottomMargin() const
const char * GetPaintTextFormat() const
Float_t GetPadTopMargin() const
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
The TTimeStamp encapsulates seconds and ns since EPOCH.
void Add(const TTimeStamp &offset)
Add "offset" as a delta time.
const char * AsString(const Option_t *option="") const
Return the date & time as a string.
This class defines a UUID (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDent...
const char * AsString() const
Return UUID as string. Copy string immediately since it will be reused.
static TVirtualPadEditor * GetPadEditor(Bool_t load=kTRUE)
Returns the pad editor dialog. Static method.
TVirtualPad is an abstract base class for the Pad and Canvas classes.
virtual void Modified(Bool_t flag=1)=0
virtual TList * GetListOfPrimitives() const =0
virtual void SetPad(const char *name, const char *title, Double_t xlow, Double_t ylow, Double_t xup, Double_t yup, Color_t color=35, Short_t bordersize=5, Short_t bordermode=-1)=0
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
const char * GetName() const override=0
Returns name of object.
virtual TVirtualPad * GetPad(Int_t subpadnumber) const =0
virtual void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0)=0
virtual Int_t GetLogy() const =0
virtual void SetLogy(Int_t value=1)=0
virtual TObject * GetPrimitive(const char *name) const =0
virtual void SetBorderSize(Short_t bordersize)=0
virtual void SetName(const char *name)=0
TClass * IsA() const override
double evaluate() const override
Evaluate projected p.d.f.
TObject * clone(const char *newname) const override
double expectedEvents(const RooArgSet *nset) const override
Return expected number of events to be used in calculation of extended likelihood.
ExtendMode extendMode() const override
Returns ability of PDF to provide extended likelihood terms.
RooCmdArg RecycleConflictNodes(bool flag=true)
RooConstVar & RooConst(double val)
RooCmdArg Embedded(bool flag=true)
RooCmdArg WeightVar(const char *name="weight", bool reinterpretAsWeight=false)
RooCmdArg GlobalObservables(Args_t &&... argsOrArgSet)
RooCmdArg Range(const char *rangeName, bool adjustNorm=true)
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
MsgLevel
Verbosity level for RooMsgService::StreamConfig in RooMsgService.
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Double_t ChisquareQuantile(Double_t p, Double_t ndf)
Evaluate the quantiles of the chi-squared probability distribution function.
#define BEGIN_XROOFIT_NAMESPACE
#define END_XROOFIT_NAMESPACE
void removeTopic(RooFit::MsgTopic oldTopic)
bool isNaNWithPayload() const
Test if this struct has a float packed into its mantissa.
static float unpackNaN(double val)
If val is NaN and a this NaN has been tagged as containing a payload, unpack the float from the manti...
static uint64_t sum(uint64_t i)
void(* gOldHandlerr)(int)
void addLegendEntry(TObject *o, const char *title, const char *opt)
void buildHistogramInterrupt(int signum)
auto GETACTBROWSER(TRootBrowser *b)
auto & GETWSSNAPSHOTS(RooWorkspace *w)
bool TopRightPlaceBox(TPad *p, TObject *o, double w, double h, double &xl, double &yb)
TPaveText * getPave(const char *name="labels", bool create=true, bool doPaint=false)
std::string formatLegendString(const std::string &s)
auto GETROOTDIR(TGFileBrowser *b)
const xRooNode * runningNode
auto GETLISTTREE(TGFileBrowser *b)
const T & _or_func(const T &a, const T &b)
TLegend * getLegend(bool create=true, bool doPaint=false)