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 gROOT->GetListOfColors()->Clear();
338 for (
auto col : *
colors) {
339 gROOT->GetListOfColors()->Add(col);
345 for (
auto &
d : _ws->allData()) {
346 for (
auto &
a : *
d->get()) {
347 if (
auto v = _ws->var(
a->GetName());
v) {
348 v->setAttribute(
"obs");
349 }
else if (
auto c = _ws->cat(
a->GetName());
c) {
350 c->setAttribute(
"obs");
354 checkCount +=
d->TestBit(1 << 20);
357 if (checkCount == 0 && !_ws->allData().empty())
358 _ws->allData().back()->SetBit(1 << 20,
true);
361 for (
auto s : *_set) {
363 _ws->var(s->GetName())->setStringAttribute(
"nominal",
TString::Format(
"%f",
v->getVal()));
371 if (k ==
"globalObservables" ||
TString(k).
EndsWith(
"_GlobalObservables")) {
374 s->setAttribute(
"obs");
375 s->setAttribute(
"global");
378 const_cast<RooArgSet &
>(
v).setAttribAll(
"obs");
381 s->setAttribute(
"poi");
393 const_cast<RooArgSet &
>(
v).setAttribAll(
"np");
396 if (!_allGlobs.
empty() &&
GETWSSETS(_ws).count(
"globalObservables") == 0) {
397 _ws->defineSet(
"globalObservables", _allGlobs);
402 if (!_ws->allPdfs().empty()) {
403 std::set<RooRealVar *> noErrorPars;
404 std::string parNames;
405 for (
auto &
p :
np()) {
409 if (!
v->hasError()) {
410 noErrorPars.insert(
v);
411 if (!parNames.empty())
416 if (!noErrorPars.empty()) {
418 "Inferring initial errors of %d parameters (%s%s) (give all nuisance parameters an error to avoid "
420 int(noErrorPars.size()), (*noErrorPars.begin())->GetName(), (noErrorPars.size() > 1) ?
",..." :
"");
423 for (
auto &
a : *this) {
424 if (noErrorPars.empty()) {
427 if (
a->fFolder ==
"!pdfs") {
429 auto fr =
a->floats().reduced(parNames).fitResult(
"prefit");
431 std::set<RooRealVar *> foundPars;
432 for (
auto &
v : noErrorPars) {
433 if (
auto arg =
dynamic_cast<RooRealVar *
>(_fr->floatParsFinal().find(
v->GetName()));
434 arg && arg->hasError()) {
435 v->setError(arg->getError());
439 for (
auto &
v : foundPars) {
440 noErrorPars.erase(
v);
451 if (strlen(GetTitle()) == 0) {
468 (comp.InheritsFrom(
"RooAbsArg") && dynamic_cast<const
RooAbsArg *>(&comp)->getStringAttribute(
"alias"))
469 ? dynamic_cast<const
RooAbsArg *>(&comp)->getStringAttribute(
"alias")
478 if (
auto a = std::dynamic_pointer_cast<RooAbsArg>(comp);
a &&
a->getStringAttribute(
"alias"))
479 return a->getStringAttribute(
"alias");
481 return comp->GetName();
499 if (
auto o = get<RooAbsReal>(); o) {
500 if (o->isSelectedComp() && !val) {
503 o->setAttribute(
"hidden");
504 }
else if (!o->isSelectedComp() && !val) {
509 o->setAttribute(
"hidden",
false);
512 item->CheckItem(!o->getAttribute(
"hidden"));
513 if (o->isSelectedComp()) {
516 item->SetColor(
kGray);
521 if (
auto o =
get(); o) {
523 o->SetBit(1 << 20, val);
524 if (
auto fr = get<RooFitResult>(); fr) {
525 if (
auto _ws =
ws(); _ws) {
528 if (!_ws->genobj(fr->GetName())) {
530 if (
auto wfr =
dynamic_cast<RooFitResult *
>(_ws->genobj(fr->GetName()))) {
535 _allVars = fr->floatParsFinal();
536 _allVars = fr->constPars();
537 for (
auto &i : fr->floatParsInit()) {
543 for (
auto oo : _ws->allGenericObjects()) {
544 if (
auto ffr =
dynamic_cast<RooFitResult *
>(oo); ffr && ffr != fr) {
545 ffr->ResetBit(1 << 20);
549 _ws->allVars() = fr->floatParsInit();
553 if (
auto first = item->GetParent()->GetFirstChild()) {
555 if (first->HasCheckBox()) {
556 auto _obj =
static_cast<xRooNode *
>(first->GetUserData());
557 first->CheckItem(_obj->get() && _obj->get()->TestBit(1 << 20));
559 }
while ((first = first->GetNextSibling()));
568 static bool blockBrowse =
false;
572 auto b2 =
dynamic_cast<TBrowser *
>(
gROOT->GetListOfBrowsers()->Last());
573 if (!b2 || !b2->GetBrowserImp()) {
580 b2 =
new TBrowser(
"nodeBrowser",
this,
"RooFit Browser");
582 }
else if (strcmp(b2->GetName(),
"nodeBrowser") == 0) {
584 b2->BrowseObject(
this);
596 _b->GotoDir(
nullptr);
607 if (
auto first = item->GetFirstChild()) {
609 if (first->HasCheckBox()) {
610 auto _obj =
static_cast<xRooNode *
>(first->GetUserData());
611 first->CheckItem(_obj->get() &&
612 (_obj->get()->TestBit(1 << 20) ||
615 }
while ((first = first->GetNextSibling()));
626 if (
auto _fr = get<RooFitResult>(); _fr &&
fBrowsables.empty()) {
628 fBrowsables.push_back(std::make_shared<xRooNode>(
".Draw(\"pull\")",
nullptr, *
this));
629 fBrowsables.push_back(std::make_shared<xRooNode>(
".Draw(\"corrcolztext\")",
nullptr, *
this));
630 if (std::unique_ptr<RooAbsCollection>(_fr->floatParsFinal().selectByAttrib(
"poi",
true))->size() == 1) {
631 fBrowsables.push_back(std::make_shared<xRooNode>(
".Draw(\"impact\")",
nullptr, *
this));
637 if (
auto s = get<TStyle>()) {
638 s->SetFillAttributes();
645 Draw(
b->GetDrawOption());
647 }
catch (
const std::exception &
e) {
650 (
gROOT->GetListOfBrowsers()->At(0))
653 "Exception",
e.what(),
658 bool hasFolders =
false;
660 for (
auto &
c : *
this) {
661 if (!
c->fFolder.empty()) {
670 auto _folders =
find(
".folders");
672 _folders = emplace_back(std::make_shared<xRooNode>(
".folders",
nullptr, *
this));
675 for (
auto &
v : *
this) {
676 if (!
v->fFolder.empty() && !_folders->find(
v->fFolder,
false)) {
677 _folders->emplace_back(std::make_shared<xRooNode>(
v->fFolder.c_str(),
nullptr, *
this));
681 for (
auto &
v : *_folders) {
684 _name = _name(1, _name.
Length());
685 b->Add(
v.get(), _name);
689 for (
auto &
v : *
this) {
690 if (hasFolders && !
v->fFolder.empty())
692 if (strcmp(
v->GetName(),
".folders") == 0)
696 if (_fr && ((_fr->status() == 0 && _fr->numStatusHistory() == 0) || (_fr->floatParsFinal().empty()))) {
700 if (
v->get<
RooAbsPdf>() && get<RooSimultaneous>())
704 _name = _name(strlen(
v->get()->ClassName()) + 2, _name.
Length());
712 :
v->get()->GetName());
714 }
else if (
v->get() && !
v->get<
TFile>() && !
TString(
v->GetName()).BeginsWith(
'/'))
716 if (
auto _type =
v->GetNodeType(); strlen(_type)) {
724 for (
size_t i = 0; i < fv->dependents().
size(); i++) {
730 for (
size_t i = 0; i < gv->dependents().
size(); i++) {
737 TString nameSave(
v->TNamed::GetName());
738 TString titleSave(
v->TNamed::GetTitle());
739 if (
auto o =
v->get(); o)
740 v->TNamed::SetNameTitle(o->GetName(), o->ClassName());
741 b->Add(
v.get(), _name, _checked);
742 if (
auto o =
v->get(); o)
743 v->TNamed::SetNameTitle(nameSave, titleSave);
744 if (_checked != -1) {
745 dynamic_cast<TQObject *
>(
b->GetBrowserImp())
746 ->Connect(
"Checked(TObject *, bool)",
ClassName(),
v.get(),
"Checked(TObject *, bool)");
749 if (_fr->status() || _fr->covQual() != 3) {
750 v->GetTreeItem(
b)->SetColor((_fr->numStatusHistory() || _fr->floatParsFinal().empty()) ?
kRed :
kBlue);
751 }
else if (_fr->numStatusHistory() == 0) {
752 v->GetTreeItem(
b)->SetColor(
kGray);
755 if ((
v->fFolder ==
"!np" ||
v->fFolder ==
"!poi")) {
757 v->GetTreeItem(
b)->SetColor(
kGray);
759 v->GetTreeItem(
b)->ClearColor();
763 if (
auto fits = _htr->GetFitInfo()) {
764 for (
int i = 0; i < fits->numEntries(); i++) {
766 if (fits->get(i)->getCatIndex(
"type") != 5 && fits->get(i)->getRealValue(
"status") != 0) {
767 v->GetTreeItem(
b)->SetColor(
kRed);
772 v->GetTreeItem(
b)->SetColor(
kBlue);
799 if (_name ==
".memory")
801 TString nameSave(
v->TNamed::GetName());
802 TString titleSave(
v->TNamed::GetTitle());
803 if (
auto o =
v->get(); o)
804 v->TNamed::SetNameTitle(o->GetName(), o->ClassName());
805 b->Add(
v.get(), _name, -1);
806 if (
auto o =
v->get(); o)
807 v->TNamed::SetNameTitle(nameSave, titleSave);
810 b->SetSelected(
this);
823 auto v = std::make_shared<xRooNode>(
vars());
834 if (strcmp(
b->GetName(),
".vars") == 0)
857 if (
auto v = var();
v)
858 return v->getBinWidth(bin - 1, GetName());
863 if (
auto v = rvar();
v) {
864 return (bin ==
v->getBinning(GetName()).numBins() + 1) ?
v->getBinning(GetName()).binHigh(bin - 2)
865 :
v->getBinning(GetName()).binLow(bin - 1);
871 if (
auto v = rvar();
v)
872 return (bin == 0) ?
v->getBinning(GetName()).binLow(bin) :
v->getBinning(GetName()).binHigh(bin - 1);
878 return (binning() && strlen(binning()->GetTitle())) ? binning()->GetTitle() : GetParent()->GetTitle();
885 dynamic_cast<TNamed *
>(GetParent())->SetTitle(title);
889 void Set(
Int_t nbins,
const double *xbins)
override
892 v->setBinning(
RooBinning(nbins, xbins), GetName());
897 std::vector<double> bins(nbins + 1);
898 for (
int i = 0; i <= nbins; i++)
899 bins.at(i) = xbins[i];
900 return Set(nbins, &bins[0]);
912 Int_t FindFixBin(
double x)
const override {
return (binning()) ? (binning()->binNumber(
x) + 1) :
x; }
923 if (
auto _owned =
find(
".memory"); _owned) {
924 for (
auto &o : *_owned) {
925 if (
name == o->GetName()) {
926 if (
type.empty() || o->get()->InheritsFrom(
type.c_str()))
935 while (!_provider && _parent) {
936 _provider = _parent->fProvider;
937 _parent = _parent->fParent;
940 return _provider->getObject(
name,
type);
943 std::shared_ptr<TObject> out;
944 if (
auto arg =
ws()->arg(
name.c_str()); arg) {
945 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
946 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
951 if (
auto arg =
ws()->
data(
name.c_str()); arg) {
952 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
953 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
958 if (
auto arg =
ws()->genobj(
name.c_str()); arg) {
959 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
960 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
965 if (
auto arg =
ws()->embeddedData(
name.c_str()); arg) {
966 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
967 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
973 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
974 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
981 if (
auto arg = get<RooAbsArg>()) {
984 arg->treeNodeServerList(&nodes);
985 if (
auto server = nodes.
find(
name.c_str())) {
986 return std::shared_ptr<TObject>(server, [](
TObject *) {});
997 cat && cat->numTypes() !=
fXAxis->GetNbins()) {
1004 if (
auto a = get<RooAbsArg>();
a &&
a->isFundamental())
1009 auto o = get<RooAbsReal>();
1013 if (
auto xName = o->getStringAttribute(
"xvar"); xName) {
1023 (o->dependsOn(*
dynamic_cast<RooAbsArg *
>(_parentX->GetParent())) ||
vars().empty())) {
1025 }
else if (
auto _obs =
obs(); !_obs.empty()) {
1026 for (
auto &
v : _obs) {
1035 }
else if (
auto _pars =
pars(); !_pars.empty()) {
1036 for (
auto &
v : _pars) {
1052 if (o !=
dynamic_cast<TObject *
>(
x)) {
1057 TString binningName = o->getStringAttribute(
"binning");
1058 auto _bnames =
x->getBinningNames();
1059 bool hasBinning =
false;
1060 for (
auto &
b : _bnames) {
1061 if (
b == binningName) {
1069 Warning(
"GetXaxis",
"Binning %s not defined on %s - clearing", binningName.
Data(),
1071 o->setStringAttribute(
"binning",
nullptr);
1075 if (binningName ==
"" && o !=
dynamic_cast<TObject *
>(
x)) {
1077 auto __bnames =
x->getBinningNames();
1078 for (
auto &
b : __bnames) {
1081 if (
b == o->GetName()) {
1082 binningName = o->GetName();
1086 if (binningName ==
"") {
1092 (std::list<double> *)(
nullptr),
1093 o->binBoundaries(*
dynamic_cast<RooAbsRealLValue *
>(
x), -std::numeric_limits<double>::infinity(),
1094 std::numeric_limits<double>::infinity()));
1096 std::vector<double> _bins;
1097 for (
auto &
b : *
bins) {
1098 if (_bins.empty() || std::abs(_bins.back() -
b) > 1
e-5 * _bins.back())
1101 fXAxis = std::make_shared<Axis2>(_bins.size() - 1, &_bins[0]);
1103 if (
auto _v =
dynamic_cast<RooRealVar *
>(
x); _v) {
1104 _v->setBinning(
RooBinning(_bins.size() - 1, &_bins[0], o->GetName()), o->
GetName());
1105 _v->getBinning(o->GetName())
1110 binningName = o->GetName();
1112 }
else if (_parentX) {
1114 binningName = _parentX->GetName();
1121 if (
r->getBinning(binningName).isUniform()) {
1122 fXAxis = std::make_shared<Axis2>(
x->numBins(binningName),
r->getMin(binningName),
r->getMax(binningName));
1124 fXAxis = std::make_shared<Axis2>(
x->numBins(binningName),
r->getBinning(binningName).array());
1126 }
else if (
auto cat =
dynamic_cast<RooCategory *
>(
x)) {
1127 std::vector<double>
bins = {};
1128 for (
int i = 0; i <=
x->numBins(binningName); i++)
1130 fXAxis = std::make_shared<Axis2>(
x->numBins(binningName), &
bins[0]);
1133 std::map<int, std::string> cats;
1134 for (
auto &
c : *cat) {
1135 if (cat->isStateInRange(binningName,
c.first.c_str())) {
1136 cats[
c.second] =
c.first;
1139 for (
auto &[
_, label] : cats) {
1140 fXAxis->SetBinLabel(i++, label.c_str());
1145 fXAxis->SetName(binningName);
1152 if (
auto o =
get(); o) {
1153 if (o->InheritsFrom(
"RooWorkspace"))
1155 if (o->InheritsFrom(
"RooAbsData"))
1157 if (o->InheritsFrom(
"RooSimultaneous"))
1160 if (o->InheritsFrom(
"RooProdPdf"))
1162 if (o->InheritsFrom(
"RooRealSumPdf") || o->InheritsFrom(
"RooAddPdf"))
1165 if (o->InheritsFrom(
"RooFitResult")) {
1166 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitRooFitResult",
true)) {
1167 gClient->GetMimeTypeList()->AddType(
"xRooFitRooFitResult",
"xRooFitRooFitResult",
"package.xpm",
1168 "package.xpm",
"->Browse()");
1170 return "xRooFitRooFitResult";
1172 if (o->InheritsFrom(
"RooRealVar") || o->InheritsFrom(
"RooCategory")) {
1173 if (get<RooAbsArg>()->getAttribute(
"obs")) {
1174 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitObs",
true)) {
1175 gClient->GetMimeTypeList()->AddType(
"xRooFitObs",
"xRooFitObs",
"x_pic.xpm",
"x_pic.xpm",
"->Browse()");
1177 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitGlobs",
true)) {
1178 gClient->GetMimeTypeList()->AddType(
"xRooFitGlobs",
"xRooFitGlobs",
"z_pic.xpm",
"z_pic.xpm",
1181 return (get<RooAbsArg>()->getAttribute(
"global") ?
"xRooFitGlobs" :
"xRooFitObs");
1185 if (o->InheritsFrom(
"TStyle")) {
1186 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitTStyle",
true)) {
1187 gClient->GetMimeTypeList()->AddType(
"xRooFitTStyle",
"xRooFitTStyle",
"bld_colorselect.xpm",
1188 "bld_colorselect.xpm",
"->Browse()");
1190 return "xRooFitTStyle";
1192 if (o->InheritsFrom(
"RooConstVar")) {
1198 return "TMethodBrowsable-leaf";
1200 if (o->InheritsFrom(
"RooStats::HypoTestInverterResult")) {
1201 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitScanStyle",
true)) {
1202 gClient->GetMimeTypeList()->AddType(
"xRooFitScanStyle",
"xRooFitScanStyle",
"f2_s.xpm",
"f2_s.xpm",
1205 return "xRooFitScanStyle";
1207 if (o->InheritsFrom(
"RooStats::HypoTestResult")) {
1208 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitTestStyle",
true)) {
1209 gClient->GetMimeTypeList()->AddType(
"xRooFitTestStyle",
"xRooFitTestStyle",
"diamond.xpm",
"diamond.xpm",
1212 return "xRooFitTestStyle";
1214 if (o->InheritsFrom(
"RooStats::HistFactory::FlexibleInterpVar"))
1215 return "TBranchElement-folder";
1216 if (o->InheritsFrom(
"RooAbsPdf")) {
1217 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitPDFStyle",
true)) {
1218 gClient->GetMimeTypeList()->AddType(
"xRooFitPDFStyle",
"xRooFitPDFStyle",
"pdf.xpm",
"pdf.xpm",
1221 return "xRooFitPDFStyle";
1223 if (o->InheritsFrom(
"RooStats::ModelConfig")) {
1224 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitMCStyle",
true)) {
1225 gClient->GetMimeTypeList()->AddType(
"xRooFitMCStyle",
"xRooFitMCStyle",
"app_t.xpm",
"app_t.xpm",
1228 return "xRooFitMCStyle";
1232 _ax && (
a->isBinnedDistribution(*
dynamic_cast<RooAbsArg *
>(_ax->GetParent())) ||
1234 std::unique_ptr<std::list<double>>(
a->binBoundaries(
1235 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
1236 std::numeric_limits<double>::infinity()))))) {
1241 return o->ClassName();
1252 if (o->InheritsFrom(
"RooStats::HistFactory::FlexibleInterpVar"))
1254 if (o->InheritsFrom(
"PiecewiseInterpolation"))
1256 if (o->InheritsFrom(
"RooHistFunc"))
1257 return (
dynamic_cast<RooAbsArg *
>(o)->getAttribute(
"density")) ?
"ConstDensityHisto" :
"ConstHisto";
1258 if (o->InheritsFrom(
"RooBinWidthFunction"))
1260 if (o->InheritsFrom(
"ParamHistFunc"))
1262 if (o->InheritsFrom(
"RooRealVar"))
1264 if (o->InheritsFrom(
"RooConstVar"))
1272 xRooNode out(
".coords",
nullptr, *
this);
1274 auto _p = std::shared_ptr<xRooNode>(
const_cast<xRooNode *
>(
this), [](
xRooNode *) {});
1304 if (
auto pos = pName.
Index(
'='); pos != -1) {
1305 if (pos > 0 && pName(pos - 1) ==
'<') {
1308 pName = pName(pos + 1, pName.
Length());
1310 pName = pName(0, pName.
Index(
'<'));
1313 _obs->setVal((high + low) / 2.);
1314 static_cast<RooRealVar *
>(_obs.get())->setRange(
"coordRange", low, high);
1316 "coordRange",
"coordRange");
1318 out.emplace_back(std::make_shared<xRooNode>(_obs->GetName(), _obs, _p));
1323 }
else if (
auto _obs = _p->getObject<
RooAbsArg>(pName(0, pos)); _obs) {
1326 _cat->setLabel(pName(pos + 1, pName.
Length()));
1327 }
else if (
auto _var =
dynamic_cast<RooAbsRealLValue *
>(_obs.get()); _var) {
1331 out.emplace_back(std::make_shared<xRooNode>(_obs->GetName(), _obs, _p));
1333 throw std::runtime_error(
"Unknown observable, could not find");
1345 }
catch (
const std::exception &
e) {
1354 }
catch (
const std::exception &
e) {
1363 if (strcmp(
GetName(),
".poi") == 0) {
1369 throw std::runtime_error(
TString::Format(
"%s is not a poi", toRemove.GetName()));
1371 toRemove.get<
RooAbsArg>()->setAttribute(
"poi",
false);
1374 }
else if (strcmp(
GetName(),
".factors") == 0 || strcmp(
GetName(),
".constraints") == 0 ||
1375 strcmp(
GetName(),
".components") == 0) {
1381 pdf =
p->pdfList().find(
child.GetName());
1384 auto i =
p->pdfList().index(*pdf);
1386#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
1387 const_cast<RooArgList &
>(
p->pdfList()).remove(*pdf);
1388#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
1389 p->_pdfNSetList.erase(
p->_pdfNSetList.begin() + i);
1391 auto nset =
p->_pdfNSetList.At(i);
1392 p->_pdfNSetList.Remove(nset);
1395 if (
p->_extendedIndex == i)
1396 p->_extendedIndex = -1;
1397 else if (
p->_extendedIndex > i)
1398 p->_extendedIndex--;
1410 arg = p2->components().find(
child.GetName());
1414#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
1415 p2->_compRSet.remove(*arg);
1417 const_cast<RooArgList &
>(p2->realComponents()).remove(*arg);
1419 p2->removeServer(*arg,
true);
1424 bool removed =
false;
1427 c->constraints().Remove(toRemove);
1429 }
catch (std::runtime_error &) {
1439 arg = p4->funcList().find(
child.GetName());
1443 auto idx = p4->funcList().index(arg);
1447 const_cast<RooArgList &
>(p4->funcList()).remove(*arg);
1448 p4->removeServer(*arg,
true);
1450 std::vector<RooAbsArg *> _coefs;
1451 for (
size_t ii = 0; ii < const_cast<RooArgList &>(p4->coefList()).size(); ii++) {
1452 if (ii !=
size_t(idx))
1453 _coefs.push_back(
const_cast<RooArgList &
>(p4->coefList()).
at(ii));
1455 const_cast<RooArgList &
>(p4->coefList()).removeAll();
1456 for (
auto &
a : _coefs)
1467 arg = p5->pdfList().find(
child.GetName());
1471 auto idx = p5->pdfList().index(arg);
1475 const_cast<RooArgList &
>(p5->pdfList()).remove(*arg);
1476 p5->removeServer(*arg,
true);
1478 std::vector<RooAbsArg *> _coefs;
1479 for (
size_t ii = 0; ii < const_cast<RooArgList &>(p5->coefList()).size(); ii++) {
1480 if (ii !=
size_t(idx))
1481 _coefs.push_back(
const_cast<RooArgList &
>(p5->coefList()).
at(ii));
1483 const_cast<RooArgList &
>(p5->coefList()).removeAll();
1484 for (
auto &
a : _coefs)
1495 arg = p6->list().find(
child.GetName());
1499 const_cast<RooArgList &
>(p6->list()).remove(*arg);
1500 p6->removeServer(*arg,
true);
1506 if (
auto w = get<RooWorkspace>();
w) {
1508 auto arg =
w->components().find(
child.GetName());
1515 if (arg->hasClients()) {
1516 throw std::runtime_error(
1517 TString::Format(
"Cannot remove %s from workspace %s, because it has dependencies - first remove from those",
1520 const_cast<RooArgSet &
>(
w->components()).remove(*arg);
1521 Info(
"Remove",
"Deleted %s from workspace %s", out.GetName(),
GetName());
1523 }
else if (get<RooProduct>() || get<RooProdPdf>()) {
1525 }
else if (get<RooRealSumPdf>() || get<RooAddPdf>() || get<RooAddition>()) {
1529 throw std::runtime_error(
"Removal not implemented for object type " +
1539 ~AutoUpdater() {
n.browse(); }
1542 AutoUpdater xxx(*
this);
1545 bool considerType(sOpt ==
"+");
1561 if (strcmp(
GetName(),
".factors") == 0) {
1564 }
else if (strcmp(
GetName(),
".components") == 0) {
1567 }
else if (strcmp(
GetName(),
".variations") == 0) {
1570 }
else if (strcmp(
GetName(),
".constraints") == 0) {
1576 }
else if ((strcmp(
GetName(),
".globs") == 0)) {
1579 out->setAttribute(
"obs");
1580 out->setAttribute(
"global");
1583 throw std::runtime_error(
"Failed to add global observable");
1584 }
else if ((strcmp(
GetName(),
".poi") == 0)) {
1587 out->setAttribute(
"poi");
1595 throw std::runtime_error(
"Failed to add parameter of interest");
1602 }
else if (strcmp(
GetName(),
".datasets()") == 0) {
1607 throw std::runtime_error(
1608 "Datasets can only be created for pdfs or workspaces (except if generated dataset, then must be pdf)");
1611 if (sOpt ==
"asimov" || sOpt ==
"toy") {
1613 auto _fr =
fParent->fitResult();
1614 if (strlen(_fr->GetName()) == 0) {
1617 auto ds =
fParent->generate(_fr, sOpt ==
"asimov");
1618 if (strlen(
child.GetName())) {
1629 }
else if (!_ws->obj(_fr->GetName())) {
1635 auto parentObs =
fParent->obs();
1636 auto _obs = parentObs.argList();
1638 std::unique_ptr<RooAbsCollection> _globs(_obs.selectByAttrib(
"global",
true));
1640 _obs.remove(*_globs);
1646 _obs.add(*
dynamic_cast<RooAbsArg *
>(ax->GetParent()));
1649 if (
auto _d = _ws->data(
child.GetName()); _d) {
1652 l.remove(*_d->get(),
true,
true);
1656 throw std::runtime_error(
"Cannot extend dataset with new columns");
1667 if (
auto __d = _ws->data(
child.GetName()))
1668 __d->SetBit(1 << 20, _ws->allData().size() == 1);
1676 auto out = std::shared_ptr<TObject>(_ws->data(
child.GetName()), [](
TObject *) {});
1685 throw std::runtime_error(
"Cannot create dataset");
1690 throw std::runtime_error(
"Cannot add to null object with no parentage");
1692 auto _ref = emplace_back(std::shared_ptr<xRooNode>(&
const_cast<xRooNode &
>(
child), [](
TObject *) {}));
1697 std::rethrow_exception(std::current_exception());
1702 throw std::runtime_error(
"No object");
1706 if (
auto p = get<RooAbsData>();
p) {
1708 bb->Add(
child, opt);
1712 throw std::runtime_error(
"Can only add datasets to a dataset");
1717 auto _globs =
globs();
1718 for (
auto &glob :
child.globs()) {
1719 if (
auto g = _globs.find(glob->GetName()); !
g) {
1721 }
else if (
g->GetContent() != glob->GetContent()) {
1722 Warning(
"Add",
"Global observable %s=%g in dataset %s mismatches %s value %g ... ignoring latter",
1723 g->GetName(),
g->GetContent(),
GetName(),
child.GetName(), glob->GetContent());
1727 if (
auto _dglobs =
p->getGlobalObservables()) {
1730 for (
auto g : _globs)
1733 p->setGlobalObservables(globsToAdd);
1737 for (
auto col : *_data->get()) {
1738 if (!
p->get()->contains(*col)) {
1739 ds->addColumn(*col);
1743 ds->SetTitle(
TString(ds->GetTitle()) +
" + " + _data->GetTitle());
1749 throw std::runtime_error(
"Can only add histogram or dataset to data");
1753 throw std::runtime_error(
"Could not find pdf");
1754 auto _ax = _pdf->GetXaxis();
1756 throw std::runtime_error(
"Cannot determine binning to add data");
1765 l.remove(*
p->get(),
true,
true);
1769 throw std::runtime_error(
"Cannot extend dataset with new columns");
1776 for (
auto &o :
obs) {
1778 if (
auto dv =
dynamic_cast<RooRealVar *
>(
p->get()->find(
v->GetName())); dv) {
1779 if (
v->getMin() < dv->getMin())
1780 dv->setMin(
v->getMin());
1781 if (
v->getMax() > dv->getMax())
1782 dv->setMax(
v->getMax());
1785 if (
auto dc =
dynamic_cast<RooCategory *
>(
p->get()->find(
c->GetName())); dc) {
1786 if (!dc->hasLabel(
c->getCurrentLabel())) {
1787 dc->defineType(
c->getCurrentLabel(),
c->getCurrentIndex());
1793 for (
int i = 1; i <= _h->GetNbinsX(); i++) {
1795 if (!_h->GetXaxis()->GetBinLabel(i)) {
1796 throw std::runtime_error(
1797 TString::Format(
"Categorical observable %s requires bin labels", _ax->GetParent()->GetName()));
1798 }
else if (!cat->hasLabel(_h->GetXaxis()->GetBinLabel(i))) {
1799 throw std::runtime_error(
TString::Format(
"Categorical observable %s does not have label %s",
1800 _ax->GetParent()->GetName(), _h->GetXaxis()->GetBinLabel(i)));
1802 cat->setLabel(_h->GetXaxis()->GetBinLabel(i));
1805 dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent())->setVal(_h->GetBinCenter(i));
1807 p->add(
obs, _h->GetBinContent(i));
1813 if (
auto p = get<RooAddPdf>();
p) {
1817 auto _pdf = std::dynamic_pointer_cast<RooAbsPdf>(out);
1819 throw std::runtime_error(
"Something went wrong with pdf acquisition");
1826 if (
auto _boundaries = std::unique_ptr<std::list<double>>(_p->binBoundaries(
1827 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
1828 std::numeric_limits<double>::infinity()));
1829 !_boundaries && _ax->GetNbins() > 0) {
1830#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 24, 00)
1831 Warning(
"Add",
"Adding unbinned pdf %s to binned %s - will wrap with RooBinSamplingPdf(...)",
1833 _p = acquireNew<RooBinSamplingPdf>(
TString::Format(
"%s_binned", _p->GetName()), _p->GetTitle(),
1835 _p->setStringAttribute(
"alias", std::dynamic_pointer_cast<RooAbsArg>(out)->getStringAttribute(
"alias"));
1836 if (!_p->getStringAttribute(
"alias"))
1837 _p->setStringAttribute(
"alias", out->GetName());
1839 throw std::runtime_error(
1840 "unsupported addition of unbinned pdf to binned model - please upgrade to at least ROOT 6.24");
1846 if (!(_pdf->canBeExtended() &&
p->coefList().empty())) {
1850 if (_pdf->canBeExtended()) {
1855 .add(*acquireNew<RooExtendedBinding>(
TString::Format(
"%s_extBind", _pdf->GetName()),
1861 for (
auto i =
p->coefList().size(); i <
p->pdfList().size(); i++) {
1863 .add(*acquireNew<RooExtendedBinding>(
1866 *
static_cast<RooAbsPdf *
>(
p->pdfList().at(i))));
1869 const_cast<RooArgList &
>(
p->coefList()).add(*acquire2<RooAbsArg, RooRealVar>(
"1",
"1", 1));
1872 *
reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(
p) +
1874 *
reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(
p) +
1877 const_cast<RooArgList &
>(
p->pdfList()).add(*_pdf);
1881 (!
child.get() && getObject<RooAbsReal>(
child.GetName()))) &&
1884 bool tooMany(
false);
1897 }
else if (!tooMany) {
1902 _sumpdf.get<
RooAbsArg>()->setStringAttribute(
"alias",
"samples");
1903 return _sumpdf.Add(
child);
1908 if (
auto p = get<RooRealSumPdf>();
p) {
1909 std::shared_ptr<TObject> out;
1910 auto cc =
child.fComp;
1911 bool isConverted = (cc !=
child.convertForAcquisition(*
this, sOpt));
1914 if (std::dynamic_pointer_cast<TH1>(cc) && !
TString(cc->GetOption()).
Contains(
"nostyle")) {
1918 if (!
child.fComp && getObject<RooAbsReal>(
child.GetName())) {
1919 Info(
"Add",
"Adding existing function %s to %s",
child.GetName(),
p->
GetName());
1920 out = getObject<RooAbsReal>(
child.GetName());
1923 if (!out && !
child.fComp) {
1924 std::shared_ptr<RooAbsArg> _func;
1935 std::make_unique<TH1D>(
child.GetName(),
child.GetTitle(), _ax->GetNbins(), _ax->binning()->array());
1937 h->GetXaxis()->SetName(
TString::Format(
"%s;%s", _ax->GetParent()->GetName(), _ax->GetName()));
1940 }
else if (_obs.size() == 1) {
1944 TString binningName =
p->getStringAttribute(
"binning");
1945 for (
auto &
b : _bnames) {
1953 auto h = std::make_unique<TH1D>(
child.GetName(),
child.GetTitle(), _x->numBins(binningName),
1954 _x->getBinningPtr(binningName)->array());
1956 h->GetXaxis()->SetName(
1960 Info(
"Add",
"Created densityhisto factor %s (xaxis=%s) for %s", _func->GetName(), _obs.at(0)->GetName(),
1963 throw std::runtime_error(
"Unsupported creation of new component in SumPdf for this many obs");
1969 _func->setStringAttribute(
"alias",
child.GetName());
1973 if (
auto _f = std::dynamic_pointer_cast<RooHistFunc>(
1977 _f->setAttribute(
"density");
1978 if (_f->getAttribute(
"autodensity")) {
1980 for (
int i = 0; i < _f->dataHist().numEntries(); i++) {
1981 auto bin_pars = _f->dataHist().get(i);
1982 _f->dataHist().set(*bin_pars, _f->dataHist().weight() / _f->dataHist().binVolume(*bin_pars));
1984 _f->setAttribute(
"autodensity",
false);
1985 _f->setValueDirty();
1994 Info(
"Add",
"Created %s factor RooHistFunc::%s for %s",
1995 _f->getAttribute(
"density") ?
"densityhisto" :
"histo", _f->GetName(),
p->
GetName());
1999 if (
auto _p = std::dynamic_pointer_cast<RooAbsPdf>(out); _p) {
2003 TString newName(_p->GetName());
2005 newName +=
"_components";
2006 Warning(
"Add",
"converting samples to components");
2011 if (
auto _boundaries = std::unique_ptr<std::list<double>>(_p->binBoundaries(
2012 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
2013 std::numeric_limits<double>::infinity()));
2014 !_boundaries && _ax->GetNbins() > 0) {
2015#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 24, 00)
2016 Warning(
"Add",
"Adding unbinned pdf %s to binned %s - will wrap with RooBinSamplingPdf(...)",
2018 _p = acquireNew<RooBinSamplingPdf>(
TString::Format(
"%s_binned", _p->GetName()), _p->GetTitle(),
2020 _p->setStringAttribute(
"alias", std::dynamic_pointer_cast<RooAbsArg>(out)->getStringAttribute(
"alias"));
2021 if (!_p->getStringAttribute(
"alias"))
2022 _p->setStringAttribute(
"alias", out->GetName());
2024 throw std::runtime_error(
2025 "unsupported addition of unbinned pdf to binned model - please upgrade to at least ROOT 6.24");
2032 if (!_p->canBeExtended()) {
2033 _p = acquireNew<RooExtendPdf>(
TString::Format(
"%s_extended", _p->GetName()), _p->GetTitle(), *_p,
2034 *acquire2<RooAbsReal, RooRealVar>(
"1",
"1", 1));
2037 return *(
Replace(*acquireNew<RooAddPdf>(newName, _p->GetTitle(),
RooArgList(*
p, *_p)))
2041 if (
auto _f = std::dynamic_pointer_cast<RooAbsReal>(out); _f) {
2050 if (
auto _boundaries = std::unique_ptr<std::list<double>>(_f->binBoundaries(
2051 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
2052 std::numeric_limits<double>::infinity()));
2053 !_boundaries && _ax->GetNbins() > 0) {
2054#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 24, 00)
2057 "Adding unbinned function %s to binned %s - will wrap with RooRealSumPdf(RooBinSamplingPdf(...))",
2059 auto sumPdf = acquireNew<RooRealSumPdf>(
TString::Format(
"%s_pdfWrapper", _f->GetName()), _f->GetTitle(),
2060 *_f, *acquire2<RooAbsArg, RooRealVar>(
"1",
"1", 1),
true);
2061 sumPdf->setStringAttribute(
"alias", _f->getStringAttribute(
"alias"));
2062 if (!sumPdf->getStringAttribute(
"alias"))
2063 sumPdf->setStringAttribute(
"alias", out->GetName());
2064 _f = acquireNew<RooBinSamplingPdf>(
TString::Format(
"%s_binned", _f->GetName()), _f->GetTitle(),
2066 _f->setStringAttribute(
"alias", std::dynamic_pointer_cast<RooAbsArg>(out)->getStringAttribute(
"alias"));
2067 if (!_f->getStringAttribute(
"alias"))
2068 _f->setStringAttribute(
"alias", out->GetName());
2070 throw std::runtime_error(
2071 "unsupported addition of unbinned function to binned model - please upgrade to at least ROOT 6.24");
2076 const_cast<RooArgList &
>(
p->coefList()).add(*acquire2<RooAbsArg, RooRealVar>(
"1",
"1", 1));
2079 if (!
p->getStringAttribute(
"binning"))
2080 p->setStringAttribute(
"binning", _f->getStringAttribute(
"binning"));
2083 if (
auto gf =
p->getStringAttribute(
"global_factors"); gf) {
2086 auto fac = getObject<RooAbsReal>(pattern.
Data());
2088 throw std::runtime_error(
TString::Format(
"Could not find global factor %s", pattern.
Data()));
2097 p->setStringAttribute(
"xvar",
nullptr);
2101 }
else if (
auto p2 = get<RooProdPdf>(); p2) {
2108 bool tooMany(
false);
2121 }
else if (!tooMany) {
2122 auto out = this->
operator[](
"components")->Add(child);
2126 (!
child.get() && getObject<RooAbsReal>(
child.GetName()))) &&
2130 bool tooMany(
false);
2139 }
else if (
auto _p2 =
pp->get<
RooAddPdf>(); _p2) {
2141 for (
auto &_pdfa :
pp->components()) {
2155 }
else if (_backup) {
2158 }
else if (!tooMany) {
2159 auto out = this->
operator[](
"samples")->Add(child);
2162 p2->setStringAttribute(
"xvar",
nullptr);
2166 }
else if (
auto s = get<RooSimultaneous>(); s) {
2174 }
else if (
auto w = get<RooWorkspace>();
w) {
2175 child.convertForAcquisition(
2176 *
this,
child.get() ?
"" :
"func" );
2180 if (!
w->import(*_d)) {
2183 std::unique_ptr<RooAbsCollection>(
w->allVars().selectCommon(*_d->get()))->setAttribAll(
"obs");
2185 if (_d->getGlobalObservables()) {
2186 std::unique_ptr<RooAbsCollection>
globs(
w->allVars().selectCommon(*_d->get()));
2187 globs->setAttribAll(
"obs");
2188 globs->setAttribAll(
"global");
2192 throw std::runtime_error(
2203 if (!
child.empty() ||
child.fFolder ==
"!pdfs") {
2206 std::string catName =
"channelCat";
2207 if (!
child.empty()) {
2208 if (
TString ss =
child.at(0)->GetName(); ss.Contains(
"=")) {
2209 catName = ss(0, ss.Index(
'='));
2212 auto _cat = acquire<RooCategory>(catName.c_str(), catName.c_str());
2213 _cat->setAttribute(
"obs");
2214 auto out = acquireNew<RooSimultaneous>(
child.GetName(),
child.GetTitle(), *_cat);
2215 Info(
"Add",
"Created pdf RooSimultaneous::%s in workspace %s", out->GetName(),
w->GetName());
2220 if (sOpt ==
"pdf") {
2222 if (get<RooWorkspace>()) {
2226 }
else if (sOpt ==
"channel") {
2228 if (get<RooSimultaneous>()) {
2230 }
else if (get<RooWorkspace>()) {
2231 std::shared_ptr<TObject> out;
2232 child.convertForAcquisition(*
this);
2235 }
else if (!
child.fComp) {
2236 out = acquireNew<RooProdPdf>(
child.GetName(),
2238 Info(
"Add",
"Created channel RooProdPdf::%s in workspace %s", out->GetName(),
get()->
GetName());
2242 }
else if (sOpt ==
"sample" || sOpt ==
"func") {
2243 if (get<RooProdPdf>()) {
2246 return _mainChild.Add(
child, sOpt ==
"func" ?
"func" :
"");
2248 return (*
this)[
"samples"]->Add(
child, sOpt ==
"func" ?
"func" :
"");
2251 }
else if (sOpt ==
"dataset") {
2252 if (get<RooWorkspace>()) {
2254 return (*this).datasets().Add(
child);
2261 if (get<RooSimultaneous>()) {
2265 }
else if (get<RooProduct>() || get<RooProdPdf>()) {
2311 if (
auto a = get<RooAbsArg>()) {
2312 a->setAttribute(
"hidden", set);
2321 auto a = get<RooAbsArg>();
2323 return a->getAttribute(
"hidden");
2330 if (
get() == rhs.
get()) {
2380 if (
auto s = get<RooSimultaneous>(); s) {
2381 auto chans =
bins();
2382 if (!chans.empty()) {
2388 for (
auto &
c : chans) {
2390 cName = cName(cName.
Index(
'=') + 1, cName.
Length());
2393 c->shallowCopy(
name +
"_" +
c->get()->GetName(), std::shared_ptr<xRooNode>(&out, [](
xRooNode *) {}));
2394 pdf->addPdf(*
dynamic_cast<RooAbsPdf *
>(c_copy.get()), cName);
2399 }
else if (
auto p =
dynamic_cast<RooProdPdf *
>(o);
p) {
2401 std::shared_ptr<RooProdPdf> pdf =
2402 std::dynamic_pointer_cast<RooProdPdf>(out.acquire(std::shared_ptr<TObject>(
p->
Clone()),
false,
2407 std::dynamic_pointer_cast<RooAbsArg>(out.acquire(std::shared_ptr<TObject>(
main->Clone()),
false,
true));
2408 std::cout << newMain <<
" " << newMain->GetName() << std::endl;
2423 static std::unique_ptr<cout_redirect> capture;
2424 std::string captureStr;
2425 bool doCapture =
false;
2426 if (!capture &&
gROOT->FromPopUp()) {
2427 capture = std::make_unique<cout_redirect>(captureStr);
2450 if (
get() &&
get() !=
this) {
2452 if (_more || (get<RooAbsArg>() && get<RooAbsArg>()->isFundamental()) || get<RooConstVar>() ||
2453 get<RooAbsData>() || get<RooProduct>() || get<RooFitResult>()) {
2455 auto _snap = std::unique_ptr<RooAbsCollection>(_deps.snapshot());
2458 if (
auto _fr = get<RooFitResult>(); _fr &&
dynamic_cast<RooStringVar *
>(_fr->constPars().
find(
".log"))) {
2459 std::cout <<
"Minimization Logs:" << std::endl;
2460 std::cout << dynamic_cast<RooStringVar *>(_fr->constPars().find(
".log"))->getVal() << std::endl;
2462 _deps.assignValueOnly(*_snap);
2472 if (
auto fv = get<RooFormulaVar>()) {
2474 for (
size_t i = 0; i < fv->dependents().
size(); i++) {
2478 }
else if (
auto gv = get<RooGenericPdf>()) {
2480 for (
size_t i = 0; i < gv->dependents().
size(); i++) {
2488 }
else if (!
get()) {
2489 std::cout << std::endl;
2493 std::vector<std::string> folderNames;
2494 for (
auto &k : *
this) {
2495 if (std::find(folderNames.begin(), folderNames.end(), k->fFolder) == folderNames.end()) {
2496 folderNames.push_back(k->fFolder);
2499 for (
auto &
f : folderNames) {
2503 for (
int j = 0; j <
indent; j++)
2505 std::cout <<
f << std::endl;
2508 for (
auto &k : *
this) {
2509 if (k->fFolder !=
f) {
2513 for (
int j = 0; j < iindent; j++)
2515 std::cout << i++ <<
") " << k->GetName() <<
" : ";
2519 auto _deps = k->coords(
false).argList();
2520 auto _snap = std::unique_ptr<RooAbsCollection>(_deps.snapshot());
2522 k->get()->Print(sOpt);
2523 _deps.assignValueOnly(*_snap);
2526 if (
auto _type = k->GetNodeType(); strlen(_type)) {
2534 for (
size_t j = 0; j < fv->dependents().
size(); j++) {
2540 for (
size_t j = 0; j < gv->dependents().
size(); j++) {
2545 std::cout << k->get()->ClassName() <<
"::" << k->get()->GetName() << _suffix.
Data() << std::endl;
2548 k->Print(sOpt +
TString::Format(
"depth=%dindent=%d", depth - 1, iindent + 1));
2551 std::cout <<
" NULL " << std::endl;
2557 size_t lastBreak = 0;
2558 std::string captureStrWithBreaks;
2559 for (
size_t i = 0; i < captureStr.size(); i++) {
2560 captureStrWithBreaks += captureStr[i];
2561 if (captureStr[i] ==
'\n') {
2564 if (i - lastBreak > 150) {
2565 captureStrWithBreaks +=
'\n';
2570 (
gROOT->GetListOfBrowsers()->At(0))
2574 captureStrWithBreaks.c_str());
2582 if (
auto v = get<RooRealVar>();
v) {
2585 double mean = std::numeric_limits<double>::quiet_NaN();
2586 double sigma = mean;
2595 mean = std::numeric_limits<double>::quiet_NaN();
2598 constrType =
"normal";
2599 }
else if (constrType ==
"normal") {
2602 }
else if (constrType ==
"gaussian") {
2606 throw std::runtime_error(
"No error on parameter for gaussian constraint");
2609 constrType =
"normal";
2610 }
else if (constrType ==
"poisson") {
2612 throw std::runtime_error(
"No error on parameter for poisson constraint");
2614 sigma = pow(
v->getVal() /
v->getError(), 2);
2617 if (constrType ==
"poisson") {
2619 double tau_val =
sigma;
2620 auto globs = acquire<RooRealVar>(
Form(
"globs_%s",
v->GetName()),
Form(
"globs_%s",
v->GetName()),
2621 v->getVal() * tau_val, (
v->getVal() - 5 *
v->getError()) * tau_val,
2622 (
v->getVal() + 5 *
v->getError()) * tau_val);
2623 globs->setConstant();
2624 globs->setAttribute(
"obs");
2625 globs->setAttribute(
"global");
2627 auto tau = acquireNew<RooConstVar>(
TString::Format(
"tau_%s",
v->GetName()),
"", tau_val);
2628 auto constr = acquireNew<RooPoisson>(
2637 v->setError(mean / sqrt(tau_val));
2638 Info(
"Constrain",
"Added poisson constraint pdf RooPoisson::%s (tau=%g) for %s", out->GetName(), tau_val,
2641 }
else if (constrType ==
"normal") {
2643 auto globs = acquire<RooRealVar>(
Form(
"globs_%s",
v->GetName()),
Form(
"globs_%s",
v->GetName()), mean,
2645 globs->setAttribute(
"obs");
2646 globs->setAttribute(
"global");
2647 globs->setConstant();
2650 auto constr = acquireNew<RooGaussian>(
2656 Info(
"Constrain",
"Added gaussian constraint pdf RooGaussian::%s (mean=%g,sigma=%g) for %s", out->GetName(),
2663 auto _me = get<RooAbsArg>();
2665 throw std::runtime_error(
"Cannot constrain non arg");
2668 if (!
p->dependsOn(*_me)) {
2669 throw std::runtime_error(
"Constraint does not depend on constrainee");
2678 throw std::runtime_error(
"Nowhere to put constraint");
2681 auto childGlobs =
child.globs();
2682 if (!childGlobs.empty()) {
2683 for (
auto d :
x->datasets()) {
2687 d->get<
RooAbsData>()->setGlobalObservables(newGlobs);
2693 if (k ==
"globalObservables" ||
TString(k).
EndsWith(
"_GlobalObservables")) {
2702 for (
auto &
c : *
x) {
2708 return x->Multiply(
child);
2710 return x->Add(
child,
"+");
2723 ~AutoUpdater() {
n.browse(); }
2726 AutoUpdater xxx(*
this);
2733 auto o = std::dynamic_pointer_cast<RooAbsReal>(
acquire(
child.fComp));
2756 ?
fParent->mainChild()->GetName()
2761 binFactors =
fParent->factors().find(
"binFactors");
2763 throw std::runtime_error(
2770 for (
auto &
b : binFactors->bins()) {
2771 auto p = acquireNew<RooProduct>(
TString::Format(
"%s_bin%d", binFactors->get()->GetName(), i),
2773 p->setStringAttribute(
"alias",
TString::Format(
"%s=%g", binFactors->GetXaxis()->GetParent()->GetName(),
2774 binFactors->GetXaxis()->GetBinCenter(i)));
2781 auto _bin = binFactors->bins().at(
fBinNumber - 1);
2782 if (
auto phf = binFactors->get<
ParamHistFunc>(); phf && _bin) {
2783#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
2788 if (strcmp(_bin->GetName(),
"1") == 0) {
2790 for (std::size_t i = 0; i < pSet.
size(); i++) {
2792 all.
add(*pSet.
at(i));
2800 _bin->fBinNumber = -1;
2801 return _bin->Multiply(
child, opt);
2829 auto _ref = emplace_back(std::shared_ptr<xRooNode>(&
const_cast<xRooNode &
>(
child), [](
TObject *) {}));
2834 std::rethrow_exception(std::current_exception());
2842 if (
auto o = getObject<RooAbsReal>(
child.GetName())) {
2846 Info(
"Multiply",
"Scaled %s by existing factor %s::%s",
2850 }
else if (sOpt ==
"norm") {
2857 Info(
"Multiply",
"Scaled %s by new norm factor %s",
2862 throw std::runtime_error(
TString::Format(
"Failed to create new normFactor %s",
child.GetName()));
2866 Info(
"Multiply",
"Scaled %s by new norm factor %s",
2870 }
else if (sOpt ==
"shape" || sOpt ==
"histo" || sOpt ==
"blankshape") {
2875 for (
int i = 1; i <=
h->GetNbinsX(); i++) {
2876 h->SetBinContent(i, 1);
2881 h->SetTitle(
child.GetTitle());
2886 Info(
"Multiply",
"Scaled %s by new %s factor %s",
2891 }
else if (sOpt ==
"overall") {
2892 auto out =
Multiply(acquireNew<RooStats::HistFactory::FlexibleInterpVar>(
2893 child.GetName(),
child.GetTitle(),
RooArgList(), 1, std::vector<double>(), std::vector<double>()));
2895 Info(
"Multiply",
"Scaled %s by new overall factor %s",
2899 }
else if (sOpt ==
"func" &&
ws()) {
2904 Info(
"Multiply",
"Scaled %s by new func factor %s",
2911 if (
auto h =
child.get<
TH1>();
h && strlen(
h->GetOption()) == 0 && strlen(opt) > 0) {
2915 if (
auto w = get<RooWorkspace>();
w) {
2917 std::shared_ptr<TObject> out;
2918 child.convertForAcquisition(*
this);
2924 if (strcmp(
GetName(),
".coef") == 0) {
2929 if (
p->coefList().empty() && !
p->pdfList().empty()) {
2930 for (
auto _pdf :
p->pdfList()) {
2932 .add(*acquireNew<RooExtendedBinding>(
TString::Format(
"%s_extBind", _pdf->GetName()),
2936 Info(
"Multiply",
"Created RooExtendedBinding coefficients for all pdfs of %s so that can multiply coef",
2938 *
reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(
p) +
2940 *
reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(
p) +
2943 for (
size_t i = 0; i <
p->pdfList().size(); i++) {
2945 auto coefs =
p->coefList().at(i);
2954 for (
size_t j = 0; j <
p->coefList().size(); j++) {
2956 oldCoefs.
add(*newCoefs);
2958 oldCoefs.add(*
p->coefList().at(j));
2961 const_cast<RooArgList &
>(
p->coefList()).removeAll();
2962 const_cast<RooArgList &
>(
p->coefList()).add(oldCoefs);
2969 throw std::runtime_error(
"this coefs case is not supported");
2972 if (
auto p = get<RooProduct>();
p) {
2973 std::shared_ptr<TObject> out;
2974 auto cc =
child.fComp;
2975 bool isConverted = (
child.convertForAcquisition(*
this) != cc);
2980 if (
auto _f = std::dynamic_pointer_cast<RooHistFunc>(
2982 _f && _f->getAttribute(
"autodensity")) {
2984 bool hasDensity =
false;
2992 if (_f->getAttribute(
"density")) {
2995 for (
int i = 0; i < _f->dataHist().numEntries(); i++) {
2996 auto bin_pars = _f->dataHist().get(i);
2997 _f->dataHist().set(*bin_pars, _f->dataHist().weight() / _f->dataHist().binVolume(*bin_pars));
2999 _f->setValueDirty();
3006 _f->setAttribute(
"autodensity",
false);
3010 Info(
"Multiply",
"Created %s factor %s in %s",
3014 Info(
"Multiply",
"Created shape factor %s in %s",
child->GetName(),
p->
GetName());
3017 if (
auto _f = std::dynamic_pointer_cast<RooAbsReal>(out); _f) {
3018#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3019 p->_compRSet.add(*_f);
3021 const_cast<RooArgList &
>(
p->realComponents()).add(*_f);
3027 for (
auto &_par : _out.
pars()) {
3030 for (
auto &_constr : _par->constraints()) {
3031 if (strcmp(s, _constr->get()->GetName()) == 0) {
3038 Info(
"Multiply",
"Pulling in %s boundConstraint: %s", _par->GetName(), s);
3039 auto _pdf = getObject<RooAbsPdf>(s);
3041 throw std::runtime_error(
"Couldn't find boundConstraint");
3043 _par->Constrain(_pdf);
3050 }
else if (
auto p2 = get<RooProdPdf>(); p2) {
3052 std::shared_ptr<TObject> out;
3053 child.convertForAcquisition(*
this);
3062 std::shared_ptr<RooAbsPdf> _pdf;
3063 if (!
child.get() && strcmp(
child.GetName(),
"components") == 0) {
3064 auto _sumpdf = acquireNew<RooAddPdf>(
3065 Form(
"%s_%s", p2->GetName(),
child.GetName()),
3071 auto _sumpdf = acquireNew<RooRealSumPdf>(
3072 Form(
"%s_%s", p2->GetName(),
child.GetName()),
3076 _sumpdf->setFloor(
true);
3079 _pdf->setStringAttribute(
"alias",
child.GetName());
3081 _pdf->setStringAttribute(
"xvar", p2->getStringAttribute(
"xvar"));
3082 _pdf->setStringAttribute(
"binning", p2->getStringAttribute(
"binning"));
3084 Info(
"Multiply",
"Created %s::%s in channel %s", _pdf->ClassName(), _pdf->GetName(), p2->GetName());
3089 if (
auto _pdf = std::dynamic_pointer_cast<RooAbsPdf>(out); _pdf) {
3090#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3091 const_cast<RooArgList &
>(p2->pdfList()).add(*_pdf);
3092#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
3093 p2->_pdfNSetList.emplace_back(std::make_unique<RooArgSet>(
"nset"));
3097 if (!p2->canBeExtended() && _pdf->canBeExtended()) {
3098 p2->_extendedIndex = p2->_pdfList.size() - 1;
3107 }
else if (
auto p3 = get<RooRealSumPdf>(); p3) {
3109 std::shared_ptr<TObject> out;
3110 child.convertForAcquisition(*
this);
3116 TString s = p3->getStringAttribute(
"global_factors");
3119 s += out->GetName();
3120 p3->setStringAttribute(
"global_factors", s);
3123 "Flagged %s as a global factor in channel %s (is applied to all current and future samples in the channel)",
3124 out->GetName(), p3->GetName());
3135 std::set<RooAbsArg *> cl;
3136 for (
auto &arg : p5->clients()) {
3142 if (cl.size() > 1) {
3147 Warning(
"Multiply",
"Scaling %s that has multiple clients", p5->GetName());
3153 for (
auto &
a : p5->attributes())
3154 new_p->setAttribute(
a.c_str());
3155 for (
auto &
a : p5->stringAttributes())
3156 new_p->setStringAttribute(
a.first.c_str(),
a.second.c_str());
3157 if (!new_p->getStringAttribute(
"alias"))
3158 new_p->setStringAttribute(
"alias", p5->GetName());
3160 new_p->setAttribute(
Form(
"ORIGNAME:%s", old_p->GetName()));
3161 for (
auto arg : cl) {
3162 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
3170 if (!
child.get() && strlen(opt) == 0)
3173 throw std::runtime_error(
3175 (!
child.get() && strlen(opt) == 0) ?
" (forgot to specify factor type?)" :
""));
3181 auto p5 = get<RooAbsArg>();
3183 throw std::runtime_error(
"Only replacement of RooAbsArg is supported");
3192 new_p = std::dynamic_pointer_cast<RooAbsArg>(out).get();
3194 std::set<RooAbsArg *> cl;
3195 for (
auto &arg : p5->clients()) {
3203 if (cl.size() > 1) {
3208 std::stringstream clientList;
3210 clientList <<
c->GetName() <<
",";
3211 Warning(
"Replace",
"Replacing %s in all clients: %s", p5->GetName(), clientList.str().c_str());
3215 new_p->setAttribute(
Form(
"ORIGNAME:%s", p5->GetName()));
3216 for (
auto arg : cl) {
3221 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
3232 ~AutoUpdater() {
n.browse(); }
3235 AutoUpdater xxx(*
this);
3240 auto _ref = emplace_back(std::shared_ptr<xRooNode>(&
const_cast<xRooNode &
>(
child), [](
TObject *) {}));
3245 std::rethrow_exception(std::current_exception());
3257 std::string label =
child.GetName();
3258 if (
auto pos = label.find(
'='); pos != std::string::npos)
3259 label = label.substr(pos + 1);
3260 if (!s->indexCat().hasLabel(label)) {
3263 std::shared_ptr<TObject> out;
3264 child.convertForAcquisition(*
this);
3267 }
else if (!
child.fComp) {
3268 out = acquireNew<RooProdPdf>(
TString::Format(
"%s_%s", s->GetName(), label.c_str()),
3270 Info(
"Vary",
"Created channel RooProdPdf::%s in model %s", out->GetName(), s->GetName());
3273 if (
auto _pdf = std::dynamic_pointer_cast<RooAbsPdf>(out); _pdf) {
3274 s->addPdf(*_pdf, label.c_str());
3283 }
else if (
auto p = get<RooStats::HistFactory::FlexibleInterpVar>();
p) {
3286 child.convertForAcquisition(*
this);
3288 if (!_c &&
child.get()) {
3289 throw std::runtime_error(
"Only pure consts can be set as variations of a flexible interpvar");
3291#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3292 double value = (_c ? _c->getVal() :
p->_nominal);
3293 double nomVal =
p->_nominal;
3295 double value = (_c ? _c->getVal() :
p->nominal());
3296 double nomVal =
p->nominal();
3300 if (cName ==
"nominal") {
3305 throw std::runtime_error(
"unsupported variation form");
3307 std::string parName = cName(0, cName.
Index(
'='));
3309 if (parVal != 1 && parVal != -1) {
3310 throw std::runtime_error(
"unsupported variation magnitude");
3312 bool high = parVal > 0;
3314 if (parName.empty()) {
3323 if (!
p->findServer(*
v)) {
3324#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3325 p->_paramList.add(*
v);
3326 p->_low.push_back(0);
3327 p->_high.push_back(0);
3328 p->_interpCode.push_back(4);
3331 const_cast<std::vector<double> &
>(
p->low()).push_back(0);
3332 const_cast<std::vector<double> &
>(
p->high()).push_back(0);
3333 const_cast<std::vector<int> &
>(
p->interpolationCodes()).push_back(4);
3335 v->setAttribute(
Form(
"SYMMETRIC%s_%s", high ?
"+" :
"-",
GetName()));
3340 if (
v->getAttribute(
Form(
"SYMMETRIC+_%s",
GetName()))) {
3341 p->setLow(*
v, 2 * nomVal -
value);
3343 v->setAttribute(
Form(
"SYMMETRIC-_%s",
GetName()),
false);
3346 if (
v->getAttribute(
Form(
"SYMMETRIC-_%s",
GetName()))) {
3347 p->setHigh(*
v, 2 * nomVal -
value);
3349 v->setAttribute(
Form(
"SYMMETRIC+_%s",
GetName()),
false);
3357 }
else if (
auto p2 = get<PiecewiseInterpolation>(); p2) {
3360 throw std::runtime_error(
"unsupported variation form");
3364 if (parVal != 1 && parVal != -1) {
3365 throw std::runtime_error(
"unsupported variation magnitude");
3367#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3370 throw std::runtime_error(
3371 TString::Format(
"Interpolating %s instead of RooHistFunc", p2->_nominal.absArg()->ClassName()));
3376 throw std::runtime_error(
3377 TString::Format(
"Interpolating %s instead of RooHistFunc", p2->nominalHist()->ClassName()));
3383 for (
auto par : p2->paramList()) {
3384 if (parName == par->GetName()) {
3385 f =
dynamic_cast<RooHistFunc *
>((parVal > 0 ? p2->highList() : p2->lowList()).
at(i));
3386 otherf =
dynamic_cast<RooHistFunc *
>((parVal > 0 ? p2->lowList() : p2->highList()).
at(i));
3394 auto v = acquire<RooRealVar>(parName, parName, -5, 5);
3398 std::shared_ptr<RooHistFunc> up(
3400 std::shared_ptr<RooHistFunc> down(
3403#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3404 std::unique_ptr<RooDataHist>
h1(
3405 static_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", up->GetName()))));
3406 std::unique_ptr<RooDataHist> h2(
3407 static_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", down->GetName()))));
3408 up->_dataHist =
dynamic_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", up->GetName())));
3409 down->_dataHist =
dynamic_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", down->GetName())));
3412 down->cloneAndOwnDataHist(
TString::Format(
"hist_%s", down->GetName()));
3414 auto ups = std::dynamic_pointer_cast<RooHistFunc>(
acquire(up,
false,
true));
3415 auto downs = std::dynamic_pointer_cast<RooHistFunc>(
acquire(down,
false,
true));
3416#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3417 p2->_highSet.add(*ups.get());
3418 p2->_lowSet.add(*downs.get());
3419 p2->_interpCode.push_back(4);
3420 p2->_paramSet.add(*
v);
3422 const_cast<RooArgList &
>(p2->highList()).add(*ups);
3423 const_cast<RooArgList &
>(p2->lowList()).add(*downs);
3424 const_cast<std::vector<int> &
>(p2->interpolationCodes()).push_back(4);
3425 const_cast<RooArgList &
>(p2->paramList()).add(*
v);
3427 p2->setValueDirty();
3428 f = ((parVal > 0) ? ups : downs).
get();
3429 otherf = ((parVal > 0) ? downs : ups).
get();
3431 f->setStringAttribute(
"symmetrizes", otherf->
GetName());
3432 f->setStringAttribute(
"symmetrize_nominal", nomf->
GetName());
3451 }
else if (
auto p3 = get<RooConstVar>(); p3) {
3454 if (p3->getAttribute(
"RooRealConstant_Factory_Object")) {
3455 throw std::runtime_error(
"Cannot vary pure constants");
3461 std::set<RooAbsArg *> cl;
3462 for (
auto &arg : p3->clients()) {
3467 if (cl.size() > 1) {
3472 Warning(
"Vary",
"Varying %s that has multiple clients", p3->GetName());
3475 p3->setStringAttribute(
"origName", p3->GetName());
3477 p3->SetName(
Form(
"%s_nominal", p3->GetName()));
3479 auto new_p = acquireNew<RooStats::HistFactory::FlexibleInterpVar>(
n, p3->GetTitle(),
RooArgList(), p3->getVal(),
3480 std::vector<double>(), std::vector<double>());
3483 for (
auto &
a : p3->attributes())
3484 new_p->setAttribute(
a.c_str());
3485 for (
auto &
a : p3->stringAttributes())
3486 new_p->setStringAttribute(
a.first.c_str(),
a.second.c_str());
3489 new_p->setAttribute(
Form(
"ORIGNAME:%s", old_p->GetName()));
3490 for (
auto arg : cl) {
3491 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
3497 }
else if (
auto p4 = get<RooAbsReal>(); p4) {
3501 std::set<RooAbsArg *> cl;
3502 for (
auto &arg : p4->clients()) {
3507 if (cl.size() > 1) {
3512 Warning(
"Vary",
"Varying %s that has multiple clients", p4->GetName());
3515 p4->setStringAttribute(
"origName", p4->GetName());
3517 p4->SetName(
Form(
"%s_nominal", p4->GetName()));
3522 for (
auto &
a : p4->attributes())
3523 new_p->setAttribute(
a.c_str());
3524 for (
auto &
a : p4->stringAttributes())
3525 new_p->setStringAttribute(
a.first.c_str(),
a.second.c_str());
3528 new_p->setAttribute(
Form(
"ORIGNAME:%s", old_p->GetName()));
3529 for (
auto arg : cl) {
3530 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
3571 if (
auto a = get<RooAbsArg>();
a && strcmp(
a->GetName(),
GetName()) && !
a->getStringAttribute(
"alias")) {
3572 a->setStringAttribute(
"alias",
GetName());
3575 throw std::runtime_error(
"Cannot determine type");
3580 if (
auto h =
dynamic_cast<const TH1 *
>(&o);
h) {
3591 bool _isData = get<RooAbsData>();
3597 throw std::runtime_error(
"no xaxis");
3598 auto _v =
dynamic_cast<RooRealVar *
>(ax->GetParent());
3601 _b.
b =
dynamic_cast<RooAbsBinning *
>(_v->getBinningPtr(
nullptr)->Clone());
3602 if (
h->GetXaxis()->IsVariableBinSize()) {
3603 _v->setBinning(
RooBinning(
h->GetNbinsX(),
h->GetXaxis()->GetXbins()->GetArray()));
3605 _v->setBinning(
RooUniformBinning(
h->GetXaxis()->GetXmin(),
h->GetXaxis()->GetXmax(),
h->GetNbinsX()));
3611 for (
int bin = 1; bin <=
h->GetNbinsX(); bin++) {
3619 if (!_isData &&
h->GetSumw2N() && !
SetBinError(bin,
h->GetBinError(bin)))
3620 throw std::runtime_error(
"Failed setting stat error");
3624 }
else if (
auto _c =
dynamic_cast<const RooConstVar *
>(&o); _c) {
3626 if (
auto a = get<RooAbsArg>();
3627 (
a &&
a->isFundamental()) || get<RooConstVar>() || get<RooStats::HistFactory::FlexibleInterpVar>()) {
3630 }
else if (get<RooAbsData>()) {
3636 throw std::runtime_error(
"Assignment failed");
3663 auto _pars =
pars();
3666 std::map<RooAbsRealLValue *, double> valsToSet;
3668 auto idx = pattern.
Index(
'=');
3671 (idx == -1) ? std::numeric_limits<double>::quiet_NaN() :
TString(pattern(idx + 1, pattern.
Length())).
Atof();
3672 for (
auto p : _pars.argList()) {
3674 p->setAttribute(
"Constant",
true);
3675 if (!std::isnan(val)) {
3686 for (
auto &
d : _dsets) {
3687 if (
d->get()->TestBit(1 << 20)) {
3688 dsetName =
d->get()->GetName();
3692 auto _nll =
nll(dsetName.
Data());
3694 for (
auto [
p,
v] : valsToSet) {
3697 _nll.fitConfigOptions()->SetValue(
"LogSize", 65536);
3698 _nll.fitConfig()->MinimizerOptions().SetPrintLevel(0);
3699 auto fr = _nll.minimize();
3702 throw std::runtime_error(
"Fit Failed");
3705 for (
unsigned int i = 0; i < fr->numStatusHistory(); i++) {
3706 statusCodes +=
TString::Format(
"\n%s = %d", fr->statusLabelHistory(i), fr->statusCodeHistory(i));
3709 (
gROOT->GetListOfBrowsers()->At(0))
3712 if (fr->status() != 0) {
3714 TString::Format(
"%s\nData = %s\nFit Status Code = %d\nCov Quality = %d\n-------------%s",
3715 fr->GetName(), dsetName.
Data(), fr->status(), fr->covQual(), statusCodes.
Data()),
3717 }
else if (fr->covQual() != 3 && _nll.fitConfig()->ParabErrors()) {
3718 new TGMsgBox(
gClient->GetRoot(),
w,
"Fit Finished with Bad Covariance Quality",
3719 TString::Format(
"%s\nData = %s\nFit Status Code = %d\nCov Quality = %d\n-------------%s",
3720 fr->GetName(), dsetName.
Data(), fr->status(), fr->covQual(), statusCodes.
Data()),
3724 TString::Format(
"%s\nData = %s\nFit Status Code = %d\nCov Quality = %d\n-------------%s",
3725 fr->GetName(), dsetName.
Data(), fr->status(), fr->covQual(), statusCodes.
Data()));
3727 }
catch (
const std::exception &
e) {
3730 (
gROOT->GetListOfBrowsers()->At(0))
3740 datasets().
Add(datasetName, expected ?
"asimov" :
"toy");
3741 }
catch (
const std::exception &
e) {
3744 (
gROOT->GetListOfBrowsers()->At(0))
3747 "Exception",
e.what(),
3753 double highX ,
const char *constParValues)
3762 for (
auto &
d : _dsets) {
3763 if (
d->get()->TestBit(1 << 20)) {
3764 dsetName =
d->get()->GetName();
3768 auto _pars =
pars();
3769 std::unique_ptr<RooAbsCollection> snap(_pars.argList().snapshot());
3772 auto idx = pattern.
Index(
'=');
3775 (idx == -1) ? std::numeric_limits<double>::quiet_NaN() :
TString(pattern(idx + 1, pattern.
Length())).
Atof();
3776 for (
auto par : _pars.argList()) {
3778 par->setAttribute(
"Constant",
true);
3779 if (!std::isnan(val)) {
3792 hs.SetTitle(sWhat +
" scan" + ((dsetName !=
"") ?
TString::Format(
" [data=%s]", dsetName.
Data()) :
""));
3793 int scanStatus = hs.scan(sWhat +
" visualize", nBinsX, lowX, highX);
3794 if (scanStatus != 0) {
3797 (
gROOT->GetListOfBrowsers()->At(0))
3800 "Scan Finished with Bad Status Code",
3801 TString::Format(
"%s\nData = %s\nScan Status Code = %d", hs.GetName(), dsetName.
Data(), scanStatus),
3806 if (
auto res = hs.result())
3810 _pars.argList() = *snap;
3812 }
catch (
const std::exception &
e) {
3815 (
gROOT->GetListOfBrowsers()->At(0))
3826 }
catch (
const std::exception &
e) {
3835#if ROOT_VERSION_CODE > ROOT_VERSION(6, 29, 00)
3840 for (
auto a : *
this) {
3847 for (
auto c : args) {
3853 f.SetParName(i,
c->GetName());
3855 f.SetParLimits(i,
v->getMin(),
v->getMax());
3856 if (
v->isConstant())
3857 f.FixParameter(i,
v->getVal());
3859 f.SetParameter(i,
v->getVal());
3860 f.SetParError(i,
v->getError());
3871 (
gROOT->GetListOfBrowsers()->At(0))
3877 for (i = 0; i <
f.GetNpar(); i++) {
3878 auto c = args.
find(
f.GetParName(i));
3883 f.GetParLimits(i, low, high);
3885 v->setConstant(low);
3887 v->setRange(low, high);
3897 throw std::runtime_error(
"Failed to SetContent");
3898 }
catch (
const std::exception &
e) {
3912 std::shared_ptr<TH1D>
h;
3913 auto _b =
dynamic_cast<Axis2 *
>(ax)->binning();
3916 if (_b->isUniform()) {
3921 h->SetOption(
"nostyle");
3922 h->SetDirectory(
nullptr);
3924 h->GetXaxis()->SetName(
TString::Format(
"%s;%s", ax->GetParent()->GetName(), ax->GetName()));
3932 if (get<RooProduct>()) {
3936 if (get<RooAbsData>()) {
3937 if (
auto _data = get<RooDataSet>(); _data) {
3938 auto _ax = (bin) ?
GetXaxis() :
nullptr;
3940 throw std::runtime_error(
"Cannot determine binning to fill data");
3942 if (_ax && _ax->GetNbins() < bin) {
3943 throw std::out_of_range(
TString::Format(
"%s range %s only has %d bins", _ax->GetParent()->GetName(),
3944 _ax->GetName(), _ax->GetNbins()));
3950 for (
auto _c :
coords()) {
3954 cut +=
TString::Format(
"%s==%d", _cat->GetName(), _cat->getCurrentIndex());
3961 TString::Format(
"%s>=%f&&%s<%f", _rv->GetName(), _rv->getMin(_rv->getStringAttribute(
"coordRange")),
3962 _rv->GetName(), _rv->getMax(_rv->getStringAttribute(
"coordRange")));
3965 throw std::runtime_error(
"SetBinContent of data: Unsupported coordinate type");
3974 cut2 =
TString::Format(
"%s >= %f && %s < %f", _ax->GetParent()->GetName(), _ax->GetBinLowEdge(bin),
3975 _ax->GetParent()->GetName(), _ax->GetBinUpEdge(bin));
4007 l.remove(*_data->get(),
true,
true);
4012 _data->addColumn(*
x);
4022 for (
auto &o :
obs) {
4024 if (
auto dv =
dynamic_cast<RooRealVar *
>(_data->get()->find(
v->GetName())); dv) {
4025 if (
v->getMin() < dv->getMin())
4026 dv->setMin(
v->getMin());
4027 if (
v->getMax() > dv->getMax())
4028 dv->setMax(
v->getMax());
4031 if (
auto dc =
dynamic_cast<RooCategory *
>(_data->get()->find(
c->GetName())); dc) {
4032 if (!dc->hasLabel(
c->getCurrentLabel())) {
4033 dc->defineType(
c->getCurrentLabel(),
c->getCurrentIndex());
4042 if (
auto _nentries = std::unique_ptr<RooAbsData>(_data->reduce(cutFormula))->numEntries();
4043 _nentries != _ax->GetNbins()) {
4046 if (_nentries > 0) {
4047 Info(
"SetBinContent",
"Binning %s in channel: %s",
GetName(), cut.
Data());
4048 auto _reduced = std::unique_ptr<RooAbsData>(_data->reduce(icutFormula));
4050 for (
int j = 0; j < _reduced->numEntries(); j++) {
4051 auto _obs = _reduced->get(j);
4052 _data->add(*_obs, _reduced->weight());
4055 for (
int i = 1; i <= _ax->GetNbins(); i++) {
4059 dynamic_cast<RooAbsLValue *
>(_ax->GetParent())->setBin(i - 1, _ax->GetName());
4060 _data->add(
obs, _contents.
at(i - 1));
4065 if (std::unique_ptr<RooAbsData>(_data->reduce(cutFormula2))->numEntries() > 0) {
4066 auto _reduced = std::unique_ptr<RooAbsData>(_data->reduce(icutFormula2));
4068 for (
int j = 0; j < _reduced->numEntries(); j++) {
4069 auto _obs = _reduced->get(j);
4070 _data->add(*_obs, _reduced->weight());
4074 dynamic_cast<RooAbsLValue *
>(_ax->GetParent())->setBin(bin - 1, _ax->GetName());
4077 return bb->SetBinContent(bin,
value, par, parVal);
4080 }
else if (get<RooDataHist>()) {
4081 throw std::runtime_error(
"RooDataHist not supported yet");
4085 if (
auto _varies =
variations(); !_varies.empty() || (par && strlen(par))) {
4086 if (!par || strlen(par) == 0) {
4087 return _varies[
"nominal"]->SetBinContent(bin,
value, par, parVal);
4088 }
else if (
auto it = _varies.find(
Form(
"%s=%g", par, parVal)); it) {
4089 return it->SetBinContent(bin,
value);
4101 if (!par || strlen(par) == 0) {
4114 if (strcmp(
c->GetName(),
Form(
"%g",
c->getVal())) == 0) {
4117#if ROOT_VERSION_CODE < ROOT_VERSION(6, 24, 00)
4130 auto bin_pars =
f->dataHist().get(bin - 1);
4131 if (
f->getAttribute(
"density")) {
4132 value /=
f->dataHist().binVolume(*bin_pars);
4134 f->dataHist().set(*bin_pars,
value);
4137 if (
auto otherfName =
f->getStringAttribute(
"symmetrized_by"); otherfName) {
4139 f->setStringAttribute(
"symmetrized_by",
nullptr);
4140 if (
auto x = getObject<RooAbsArg>(otherfName);
x) {
4141 x->setStringAttribute(
"symmetrizes",
nullptr);
4142 x->setStringAttribute(
"symmetrize_nominal",
nullptr);
4144 }
else if (
auto otherfName2 =
f->getStringAttribute(
"symmetrizes"); otherfName2) {
4145 auto nomf = getObject<RooHistFunc>(
f->getStringAttribute(
"symmetrize_nominal"));
4146 auto otherf = getObject<RooHistFunc>(otherfName2);
4147 if (nomf && otherf) {
4148 otherf->dataHist().set(*bin_pars, 2 * nomf->dataHist().weight(bin - 1) -
value);
4149 otherf->setValueDirty();
4156 f2->setNominal(
value);
4165 push_back(std::make_shared<xRooNode>(
data));
4172 return node->SetBinContent(bin,
value);
4179 push_back(std::make_shared<xRooNode>(
data));
4186 return node->SetContents(obj);
4193 if (get<RooProduct>()) {
4197 if (
auto _varies =
variations(); !_varies.empty()) {
4198 return _varies[
"nominal"]->SetBinError(bin,
value);
4213 while (_prodParent && !_prodParent->get<
RooProduct>() && !_prodParent->get<
RooAbsPdf>()) {
4215 _prodParent.reset();
4218 _prodParent = _prodParent->fParent;
4221 (_prodParent && !_prodParent->get<
RooAbsPdf>()) ? _prodParent->factors().find(
"statFactor") :
nullptr;
4222 auto f_stat = (_f_stat) ? _f_stat->get<
ParamHistFunc>() :
nullptr;
4223 if (_f_stat && _f_stat->get() && !f_stat) {
4224 throw std::runtime_error(
"stat factor must be a paramhistfunc");
4233 for (
auto &
p :
xRooNode(
"tmp", *
f, std::shared_ptr<xRooNode>(
nullptr)).
vars()) {
4238 auto h = std::unique_ptr<TH1>(
f->dataHist().createHistogram(parNames
4245 h->SetName(
"statFactor");
4247 h->SetOption(
"blankshape");
4250 auto toMultiply =
this;
4254 f_stat =
dynamic_cast<ParamHistFunc *
>(toMultiply->Multiply(*h).get());
4256 throw std::runtime_error(
"Failed creating stat shapeFactor");
4262 TString prefix =
f->getStringAttribute(
"statPrefix");
4263 if (
value && prefix ==
"") {
4267 while (_p && !(_p->get()->InheritsFrom(
"RooRealSumPdf") || _p->get()->InheritsFrom(
"RooAddPdf") ||
4268 _p->get()->InheritsFrom(
"RooWorkspace") || _p->get()->InheritsFrom(
"RooAddition"))) {
4273 auto newVar = (
value == 0) ? getObject<RooRealVar>(
"1")
4274 : acquire<RooRealVar>(
Form(
"%s_bin%d", prefix.
Data(), bin),
4275 Form(
"%s_bin%d", prefix.
Data(), bin), 1);
4276#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
4281 auto var =
dynamic_cast<RooRealVar *
>(&pSet[bin - 1]);
4283 if (newVar.get() != var) {
4287 for (std::size_t i = 0; i < pSet.
size(); i++) {
4288 if (
int(i) != bin - 1) {
4289 all.
add(*pSet.
at(i));
4300 if (strcmp(rrv->GetName(),
"1") != 0) {
4301 TString origName = (
f->getStringAttribute(
"origName")) ?
f->getStringAttribute(
"origName") :
GetName();
4303 auto bin_pars =
f->dataHist().get(bin - 1);
4304 auto _binContent =
f->dataHist().weight();
4305 if (
f->getAttribute(
"density")) {
4306 _binContent *=
f->dataHist().binVolume(*bin_pars);
4311 for (
auto &[s, sv] : rrv->stringAttributes()) {
4312 if (s.find(
"sumw_") == 0) {
4314 }
else if (s.find(
"sumw2_") == 0) {
4318 if (sumw2 && sumw2 != std::numeric_limits<double>::infinity()) {
4319 double tau = pow(sumw, 2) / sumw2;
4320 rrv->setError((tau < 1
e-15) ? 1e15 : ( 1. / sqrt(tau)));
4321 rrv->setConstant(
false);
4323 auto _constr =
v.constraints();
4325 if (_constr.empty()) {
4326 rrv->setStringAttribute(
"boundConstraint", _constr.Add(
"poisson").get()->GetName());
4328 auto _glob = _constr.at(0)->obs().at(0)->get<
RooRealVar>();
4331 double _min = tau * (1. - 5. * sqrt(1. / tau));
4332 double _max = tau * (1. + 5. * sqrt(1. / tau));
4333 _glob->setRange(_min, _max);
4335 _constr.at(0)->pp().at(0)->SetBinContent(0, tau);
4336 rrv->setStringAttribute(
"boundConstraint", _constr.at(0)->get()->GetName());
4338 rrv->setRange(std::max((1. - 5. * sqrt(1. / tau)), 1
e-15), 1. + 5. * sqrt(1. / tau));
4341 if (
auto _constr =
v.constraints(); !_constr.empty()) {
4342 v.constraints().Remove(*_constr.at(0));
4347 rrv->setConstant(sumw2 == 0);
4359 auto res =
find(
name, browseResult);
4361 throw std::out_of_range(
name +
" does not exist");
4370 if (
auto _w = get<RooWorkspace>(); _w)
4372 if (
auto a = get<RooAbsArg>();
a &&
GETWS(
a)) {
4383 xRooNode out(
".constraints",
nullptr, *