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
99 return a->workspace();
107 return w->getSnapshots();
111 return b->GetActBrowser();
115 return b->GetRootDir();
119 return b->GetListTree();
121#define GETDMP(o, m) \
122 *reinterpret_cast<void **>(reinterpret_cast<unsigned char *>(o) + o->Class()->GetDataMemberOffset(#m))
173#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
177#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 24, 00)
206#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");
345 checkCount +=
d->TestBit(1 << 20);
348 if (checkCount == 0 && !_ws->allData().empty())
349 _ws->allData().back()->SetBit(1 << 20,
true);
352 for (
auto s : *_set) {
354 _ws->var(s->GetName())->setStringAttribute(
"nominal",
TString::Format(
"%f",
v->getVal()));
362 if (k ==
"globalObservables" ||
TString(k).
EndsWith(
"_GlobalObservables")) {
365 s->setAttribute(
"obs");
366 s->setAttribute(
"global");
369 const_cast<RooArgSet &
>(
v).setAttribAll(
"obs");
372 s->setAttribute(
"poi");
384 const_cast<RooArgSet &
>(
v).setAttribAll(
"np");
387 if (!_allGlobs.
empty() &&
GETWSSETS(_ws).count(
"globalObservables") == 0) {
388 _ws->defineSet(
"globalObservables", _allGlobs);
393 if (!_ws->allPdfs().empty()) {
394 std::set<RooRealVar *> noErrorPars;
395 std::string parNames;
396 for (
auto &
p :
np()) {
400 if (!
v->hasError()) {
401 noErrorPars.insert(
v);
402 if (!parNames.empty())
407 if (!noErrorPars.empty()) {
410 "Inferring initial errors of %d parameters (give all nuisance parameters an error to avoid this msg)",
411 int(noErrorPars.size()));
414 for (
auto &
a : *this) {
415 if (
a->fFolder ==
"!models") {
417 auto fr =
a->floats().reduced(parNames).fitResult(
"prefit");
419 for (
auto &
v : noErrorPars) {
420 if (
auto arg =
dynamic_cast<RooRealVar *
>(_fr->floatParsFinal().find(
v->GetName()));
421 arg && arg->hasError()) {
422 v->setError(arg->getError());
434 if (strlen(GetTitle()) == 0) {
450 (comp.InheritsFrom(
"RooAbsArg") && dynamic_cast<const
RooAbsArg *>(&comp)->getStringAttribute(
"alias"))
451 ? dynamic_cast<const
RooAbsArg *>(&comp)->getStringAttribute(
"alias")
460 if (
auto a = std::dynamic_pointer_cast<RooAbsArg>(comp);
a &&
a->getStringAttribute(
"alias"))
461 return a->getStringAttribute(
"alias");
463 return comp->GetName();
481 if (
auto o = get<RooAbsReal>(); o) {
482 if (o->isSelectedComp() && !val) {
485 o->setAttribute(
"hidden");
486 }
else if (!o->isSelectedComp() && !val) {
491 o->setAttribute(
"hidden",
false);
494 item->CheckItem(!o->getAttribute(
"hidden"));
495 if (o->isSelectedComp())
498 item->SetColor(
kGray);
502 if (
auto o =
get(); o) {
504 o->SetBit(1 << 20, val);
505 if (
auto fr = get<RooFitResult>(); fr) {
506 if (
auto _ws =
ws(); _ws) {
509 if (!_ws->genobj(fr->GetName())) {
511 if (
auto wfr =
dynamic_cast<RooFitResult *
>(_ws->genobj(fr->GetName()))) {
516 _allVars = fr->floatParsFinal();
517 _allVars = fr->constPars();
518 for (
auto &i : fr->floatParsInit()) {
524 for (
auto oo : _ws->allGenericObjects()) {
525 if (
auto ffr =
dynamic_cast<RooFitResult *
>(oo); ffr && ffr != fr) {
526 ffr->ResetBit(1 << 20);
530 _ws->allVars() = fr->floatParsInit();
534 if (
auto first = item->GetParent()->GetFirstChild()) {
536 if (
first->HasCheckBox()) {
538 first->CheckItem(_obj->get() && _obj->get()->TestBit(1 << 20));
549 static bool blockBrowse =
false;
553 auto b2 =
dynamic_cast<TBrowser *
>(
gROOT->GetListOfBrowsers()->Last());
554 if (!b2 || !b2->GetBrowserImp()) {
561 b2 =
new TBrowser(
"nodeBrowser",
this,
"RooFit Browser");
563 }
else if (strcmp(b2->GetName(),
"nodeBrowser") == 0) {
565 b2->BrowseObject(
this);
588 if (
auto first = item->GetFirstChild()) {
590 if (
first->HasCheckBox()) {
592 first->CheckItem(_obj->get() &&
593 (_obj->get()->TestBit(1 << 20) ||
607 if (
auto _fr = get<RooFitResult>(); _fr &&
fBrowsables.empty()) {
609 fBrowsables.push_back(std::make_shared<xRooNode>(
".Draw(\"pull\")",
nullptr, *
this));
610 fBrowsables.push_back(std::make_shared<xRooNode>(
".Draw(\"corrcolztext\")",
nullptr, *
this));
611 if (std::unique_ptr<RooAbsCollection>(_fr->floatParsFinal().selectByAttrib(
"poi",
true))->size() == 1) {
612 fBrowsables.push_back(std::make_shared<xRooNode>(
".Draw(\"impact\")",
nullptr, *
this));
618 if (
auto s = get<TStyle>()) {
619 s->SetFillAttributes();
626 Draw(
b->GetDrawOption());
628 }
catch (
const std::exception &
e) {
631 (
gROOT->GetListOfBrowsers()->At(0))
634 "Exception",
e.what(),
639 bool hasFolders =
false;
641 for (
auto &
c : *
this) {
642 if (!
c->fFolder.empty()) {
651 auto _folders =
find(
".folders");
653 _folders = emplace_back(std::make_shared<xRooNode>(
".folders",
nullptr, *
this));
656 for (
auto &
v : *
this) {
657 if (
v->fFolder !=
"" && !_folders->find(
v->fFolder,
false)) {
658 _folders->emplace_back(std::make_shared<xRooNode>(
v->fFolder.c_str(),
nullptr, *
this));
662 for (
auto &
v : *_folders) {
665 _name = _name(1, _name.
Length());
666 b->Add(
v.get(), _name);
670 for (
auto &
v : *
this) {
671 if (hasFolders && !
v->fFolder.empty())
673 if (strcmp(
v->GetName(),
".folders") == 0)
677 if (_fr && ((_fr->status() == 0 && _fr->numStatusHistory() == 0) || (_fr->floatParsFinal().empty()))) {
681 if (
v->get<
RooAbsPdf>() && get<RooSimultaneous>())
685 _name = _name(strlen(
v->get()->ClassName()) + 2, _name.
Length());
693 :
v->get()->GetName());
694 }
else if (
v->get() && !
v->get<
TFile>() && !
TString(
v->GetName()).BeginsWith(
'/'))
696 if (
auto _type =
v->GetNodeType(); strlen(_type)) {
704 for (
size_t i = 0; i < fv->dependents().
size(); i++) {
710 for (
size_t i = 0; i < gv->dependents().
size(); i++) {
717 TString nameSave(
v->TNamed::GetName());
718 TString titleSave(
v->TNamed::GetTitle());
719 if (
auto o =
v->get(); o)
720 v->TNamed::SetNameTitle(o->GetName(), o->ClassName());
721 b->Add(
v.get(), _name, _checked);
722 if (
auto o =
v->get(); o)
723 v->TNamed::SetNameTitle(nameSave, titleSave);
724 if (_checked != -1) {
725 dynamic_cast<TQObject *
>(
b->GetBrowserImp())
726 ->Connect(
"Checked(TObject *, bool)",
ClassName(),
v.get(),
"Checked(TObject *, bool)");
729 if (_fr->status() || _fr->covQual() != 3) {
730 v->GetTreeItem(
b)->SetColor((_fr->numStatusHistory() || _fr->floatParsFinal().empty()) ?
kRed :
kBlue);
731 }
else if (_fr->numStatusHistory() == 0) {
732 v->GetTreeItem(
b)->SetColor(
kGray);
735 if ((
v->fFolder ==
"!np" ||
v->fFolder ==
"!poi")) {
737 v->GetTreeItem(
b)->SetColor(
kGray);
739 v->GetTreeItem(
b)->ClearColor();
743 if (
auto fits = _htr->GetFitInfo()) {
744 for (
int i = 0; i < fits->numEntries(); i++) {
746 if (fits->get(i)->getCatIndex(
"type") != 5 && fits->get(i)->getRealValue(
"status") != 0) {
747 v->GetTreeItem(
b)->SetColor(
kRed);
752 v->GetTreeItem(
b)->SetColor(
kBlue);
779 if (_name ==
".memory")
781 TString nameSave(
v->TNamed::GetName());
782 TString titleSave(
v->TNamed::GetTitle());
783 if (
auto o =
v->get(); o)
784 v->TNamed::SetNameTitle(o->GetName(), o->ClassName());
785 b->Add(
v.get(), _name, -1);
786 if (
auto o =
v->get(); o)
787 v->TNamed::SetNameTitle(nameSave, titleSave);
790 b->SetSelected(
this);
803 auto v = std::make_shared<xRooNode>(
vars());
814 if (strcmp(
b->GetName(),
".vars") == 0)
837 if (
auto v = var();
v)
838 return v->getBinWidth(bin - 1, GetName());
843 if (
auto v = rvar();
v)
844 return (bin ==
v->getBinning(GetName()).numBins() + 1) ?
v->getBinning(GetName()).binHigh(bin - 2)
845 :
v->getBinning(GetName()).binLow(bin - 1);
850 if (
auto v = rvar();
v)
851 return (bin == 0) ?
v->getBinning(GetName()).binLow(bin) :
v->getBinning(GetName()).binHigh(bin - 1);
857 return (binning() && strlen(binning()->GetTitle())) ? binning()->GetTitle() : GetParent()->GetTitle();
864 dynamic_cast<TNamed *
>(GetParent())->SetTitle(title);
867 void Set(
Int_t nbins,
const double *xbins)
override
870 v->setBinning(
RooBinning(nbins, xbins), GetName());
875 std::vector<double> bins(nbins + 1);
876 for (
int i = 0; i <= nbins; i++)
877 bins.at(i) = xbins[i];
878 return Set(nbins, &bins[0]);
890 Int_t FindFixBin(
double x)
const override {
return (binning()) ? (binning()->binNumber(
x) + 1) :
x; }
901 if (
auto _owned =
find(
".memory"); _owned) {
902 for (
auto &o : *_owned) {
903 if (
name == o->GetName()) {
904 if (
type.empty() || o->get()->InheritsFrom(
type.c_str()))
913 while (!_provider && _parent) {
914 _provider = _parent->fProvider;
915 _parent = _parent->fParent;
918 return _provider->getObject(
name,
type);
921 std::shared_ptr<TObject> out;
922 if (
auto arg =
ws()->arg(
name.c_str()); arg) {
923 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
924 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
929 if (
auto arg =
ws()->
data(
name.c_str()); arg) {
930 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
931 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
936 if (
auto arg =
ws()->genobj(
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()->embeddedData(
name.c_str()); arg) {
944 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
945 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
951 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
952 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
967 cat && cat->numTypes() !=
fXAxis->GetNbins()) {
974 if (
auto a = get<RooAbsArg>();
a &&
a->isFundamental())
979 auto o = get<RooAbsReal>();
983 if (
auto xName = o->getStringAttribute(
"xvar"); xName) {
993 (o->dependsOn(*
dynamic_cast<RooAbsArg *
>(_parentX->GetParent())) ||
vars().size() == 0)) {
995 }
else if (
auto _obs =
obs(); !_obs.empty()) {
996 for (
auto &
v : _obs) {
1005 }
else if (
auto _pars =
pars(); !_pars.empty()) {
1006 for (
auto &
v : _pars) {
1022 if (o !=
dynamic_cast<TObject *
>(
x)) {
1027 TString binningName = o->getStringAttribute(
"binning");
1028 auto _bnames =
x->getBinningNames();
1029 bool hasBinning =
false;
1030 for (
auto &
b : _bnames) {
1031 if (
b == binningName) {
1039 Warning(
"GetXaxis",
"Binning %s not defined on %s - clearing", binningName.
Data(),
1041 o->setStringAttribute(
"binning",
nullptr);
1045 if (binningName ==
"" && o !=
dynamic_cast<TObject *
>(
x)) {
1047 auto __bnames =
x->getBinningNames();
1048 for (
auto &
b : __bnames) {
1051 if (
b == o->GetName()) {
1052 binningName = o->GetName();
1056 if (binningName ==
"") {
1062 (std::list<double> *)(
nullptr),
1063 o->binBoundaries(*
dynamic_cast<RooAbsRealLValue *
>(
x), -std::numeric_limits<double>::infinity(),
1064 std::numeric_limits<double>::infinity()));
1066 std::vector<double> _bins;
1067 for (
auto &
b : *
bins) {
1068 if (_bins.empty() || std::abs(_bins.back() -
b) > 1
e-5 * _bins.back())
1071 fXAxis = std::make_shared<Axis2>(_bins.size() - 1, &_bins[0]);
1073 if (
auto _v =
dynamic_cast<RooRealVar *
>(
x); _v) {
1074 _v->setBinning(
RooBinning(_bins.size() - 1, &_bins[0], o->GetName()), o->
GetName());
1075 _v->getBinning(o->GetName())
1080 binningName = o->GetName();
1082 }
else if (_parentX) {
1084 binningName = _parentX->GetName();
1091 if (
r->getBinning(binningName).isUniform()) {
1092 fXAxis = std::make_shared<Axis2>(
x->numBins(binningName),
r->getMin(binningName),
r->getMax(binningName));
1094 fXAxis = std::make_shared<Axis2>(
x->numBins(binningName),
r->getBinning(binningName).array());
1097 std::vector<double>
bins = {};
1098 for (
int i = 0; i <=
x->numBins(binningName); i++)
1100 fXAxis = std::make_shared<Axis2>(
x->numBins(binningName), &
bins[0]);
1102 for (
int i = 0; i <
x->numBins(binningName); i++) {
1108 fXAxis->SetName(binningName);
1115 if (
auto o =
get(); o) {
1116 if (o->InheritsFrom(
"RooWorkspace"))
1118 if (o->InheritsFrom(
"RooAbsData"))
1120 if (o->InheritsFrom(
"RooSimultaneous"))
1123 if (o->InheritsFrom(
"RooProdPdf"))
1125 if (o->InheritsFrom(
"RooRealSumPdf") || o->InheritsFrom(
"RooAddPdf"))
1128 if (o->InheritsFrom(
"RooFitResult")) {
1129 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitRooFitResult",
true)) {
1130 gClient->GetMimeTypeList()->AddType(
"xRooFitRooFitResult",
"xRooFitRooFitResult",
"package.xpm",
1131 "package.xpm",
"->Browse()");
1133 return "xRooFitRooFitResult";
1135 if (o->InheritsFrom(
"RooRealVar") || o->InheritsFrom(
"RooCategory")) {
1136 if (get<RooAbsArg>()->getAttribute(
"obs")) {
1137 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitObs",
true)) {
1138 gClient->GetMimeTypeList()->AddType(
"xRooFitObs",
"xRooFitObs",
"x_pic.xpm",
"x_pic.xpm",
"->Browse()");
1140 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitGlobs",
true)) {
1141 gClient->GetMimeTypeList()->AddType(
"xRooFitGlobs",
"xRooFitGlobs",
"z_pic.xpm",
"z_pic.xpm",
1144 return (get<RooAbsArg>()->getAttribute(
"global") ?
"xRooFitGlobs" :
"xRooFitObs");
1148 if (o->InheritsFrom(
"TStyle")) {
1149 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitTStyle",
true)) {
1150 gClient->GetMimeTypeList()->AddType(
"xRooFitTStyle",
"xRooFitTStyle",
"bld_colorselect.xpm",
1151 "bld_colorselect.xpm",
"->Browse()");
1153 return "xRooFitTStyle";
1155 if (o->InheritsFrom(
"RooConstVar")) {
1161 return "TMethodBrowsable-leaf";
1163 if (o->InheritsFrom(
"RooStats::HypoTestInverterResult")) {
1164 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitScanStyle",
true)) {
1165 gClient->GetMimeTypeList()->AddType(
"xRooFitScanStyle",
"xRooFitScanStyle",
"f2_s.xpm",
"f2_s.xpm",
1168 return "xRooFitScanStyle";
1170 if (o->InheritsFrom(
"RooStats::HypoTestResult")) {
1171 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitTestStyle",
true)) {
1172 gClient->GetMimeTypeList()->AddType(
"xRooFitTestStyle",
"xRooFitTestStyle",
"diamond.xpm",
"diamond.xpm",
1175 return "xRooFitTestStyle";
1177 if (o->InheritsFrom(
"RooStats::HistFactory::FlexibleInterpVar"))
1178 return "TBranchElement-folder";
1179 if (o->InheritsFrom(
"RooAbsPdf")) {
1180 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitPDFStyle",
true)) {
1181 gClient->GetMimeTypeList()->AddType(
"xRooFitPDFStyle",
"xRooFitPDFStyle",
"pdf.xpm",
"pdf.xpm",
1184 return "xRooFitPDFStyle";
1188 _ax && (
a->isBinnedDistribution(*
dynamic_cast<RooAbsArg *
>(_ax->GetParent())) ||
1190 std::unique_ptr<std::list<double>>(
a->binBoundaries(
1191 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
1192 std::numeric_limits<double>::infinity()))))) {
1197 return o->ClassName();
1208 if (o->InheritsFrom(
"RooStats::HistFactory::FlexibleInterpVar"))
1210 if (o->InheritsFrom(
"PiecewiseInterpolation"))
1212 if (o->InheritsFrom(
"RooHistFunc"))
1213 return (
dynamic_cast<RooAbsArg *
>(o)->getAttribute(
"density")) ?
"ConstDensityHisto" :
"ConstHisto";
1214 if (o->InheritsFrom(
"RooBinWidthFunction"))
1216 if (o->InheritsFrom(
"ParamHistFunc"))
1218 if (o->InheritsFrom(
"RooRealVar"))
1220 if (o->InheritsFrom(
"RooConstVar"))
1228 xRooNode out(
".coords",
nullptr, *
this);
1230 auto _p = std::shared_ptr<xRooNode>(
const_cast<xRooNode *
>(
this), [](
xRooNode *) {});
1233 if (
auto pos = pName.
Index(
'='); pos != -1) {
1234 if (pos > 0 && pName(pos - 1) ==
'<') {
1237 pName = pName(pos + 1, pName.
Length());
1239 pName = pName(0, pName.
Index(
'<'));
1242 _obs->setVal((high + low) / 2.);
1243 static_cast<RooRealVar *
>(_obs.get())->setRange(
"coordRange", low, high);
1245 "coordRange",
"coordRange");
1247 out.emplace_back(std::make_shared<xRooNode>(_obs->GetName(), _obs, _p));
1252 }
else if (
auto _obs = _p->getObject<
RooAbsArg>(pName(0, pos)); _obs) {
1255 _cat->setLabel(pName(pos + 1, pName.
Length()));
1256 }
else if (
auto _var =
dynamic_cast<RooAbsRealLValue *
>(_obs.get()); _var) {
1260 out.emplace_back(std::make_shared<xRooNode>(_obs->GetName(), _obs, _p));
1262 throw std::runtime_error(
"Unknown observable, could not find");
1274 }
catch (
const std::exception &
e) {
1283 }
catch (
const std::exception &
e) {
1292 if (strcmp(
GetName(),
".poi") == 0) {
1298 throw std::runtime_error(
TString::Format(
"%s is not a poi", toRemove.GetName()));
1300 toRemove.get<
RooAbsArg>()->setAttribute(
"poi",
false);
1303 }
else if (strcmp(
GetName(),
".factors") == 0 || strcmp(
GetName(),
".constraints") == 0 ||
1304 strcmp(
GetName(),
".components") == 0) {
1310 pdf =
p->pdfList().find(
child.GetName());
1313 auto i =
p->pdfList().index(*pdf);
1315#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
1316 const_cast<RooArgList &
>(
p->pdfList()).remove(*pdf);
1317#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
1318 p->_pdfNSetList.erase(
p->_pdfNSetList.begin() + i);
1320 auto nset =
p->_pdfNSetList.At(i);
1321 p->_pdfNSetList.Remove(nset);
1324 if (
p->_extendedIndex == i)
1325 p->_extendedIndex = -1;
1326 else if (
p->_extendedIndex > i)
1327 p->_extendedIndex--;
1339 arg = p2->components().find(
child.GetName());
1343#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
1344 p2->_compRSet.remove(*arg);
1346 const_cast<RooArgList &
>(p2->realComponents()).remove(*arg);
1348 p2->removeServer(*arg,
true);
1353 bool removed =
false;
1356 c->constraints().Remove(toRemove);
1358 }
catch (std::runtime_error &) {
1368 arg = p4->funcList().find(
child.GetName());
1372 auto idx = p4->funcList().index(arg);
1376 const_cast<RooArgList &
>(p4->funcList()).remove(*arg);
1377 p4->removeServer(*arg,
true);
1379 std::vector<RooAbsArg *> _coefs;
1380 for (
size_t ii = 0; ii < const_cast<RooArgList &>(p4->coefList()).size(); ii++) {
1381 if (ii !=
size_t(idx))
1382 _coefs.push_back(
const_cast<RooArgList &
>(p4->coefList()).
at(ii));
1384 const_cast<RooArgList &
>(p4->coefList()).removeAll();
1385 for (
auto &
a : _coefs)
1396 if (
auto w = get<RooWorkspace>();
w) {
1398 auto arg =
w->components().find(
child.GetName());
1405 if (arg->hasClients()) {
1406 throw std::runtime_error(
1407 TString::Format(
"Cannot remove %s from workspace %s, because it has dependencies - first remove from those",
1410 const_cast<RooArgSet &
>(
w->components()).remove(*arg);
1411 Info(
"Remove",
"Deleted %s from workspace %s", out.GetName(),
GetName());
1413 }
else if (get<RooProduct>() || get<RooProdPdf>()) {
1415 }
else if (get<RooRealSumPdf>()) {
1419 throw std::runtime_error(
"Removal not implemented for this type of object");
1428 ~AutoUpdater() {
n.browse(); }
1431 AutoUpdater xxx(*
this);
1434 bool considerType(sOpt ==
"+");
1450 if (strcmp(
GetName(),
".factors") == 0) {
1453 }
else if (strcmp(
GetName(),
".components") == 0) {
1456 }
else if (strcmp(
GetName(),
".variations") == 0) {
1459 }
else if (strcmp(
GetName(),
".constraints") == 0) {
1465 }
else if ((strcmp(
GetName(),
".globs") == 0)) {
1468 out->setAttribute(
"obs");
1469 out->setAttribute(
"global");
1472 throw std::runtime_error(
"Failed to add global observable");
1473 }
else if ((strcmp(
GetName(),
".poi") == 0)) {
1476 out->setAttribute(
"poi");
1479 throw std::runtime_error(
"Failed to add parameter of interest");
1486 }
else if (strcmp(
GetName(),
".datasets()") == 0) {
1491 throw std::runtime_error(
1492 "Datasets can only be created for pdfs or workspaces (except if generated dataset, then must be pdf)");
1495 if (sOpt ==
"asimov" || sOpt ==
"toy") {
1497 auto _fr = std::dynamic_pointer_cast<const RooFitResult>(
fParent->fitResult().fComp);
1498 if (strlen(_fr->GetName()) == 0)
1499 std::const_pointer_cast<RooFitResult>(_fr)->SetName(
TUUID().AsString());
1501 if (strlen(
child.GetName()))
1502 asi.first->SetName(
child.GetName());
1504 _ws->import(*asi.first);
1506 if (_fr->numStatusHistory() == 0) {
1510 }
else if (!_ws->obj(_fr->GetName())) {
1514#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
1515 _ws->saveSnapshot(asi.first->GetName(), *asi.second,
1519 _tmp.
add(*asi.second);
1520 _ws->saveSnapshot(asi.first->GetName(), _tmp,
true);
1526 auto parentObs =
fParent->obs();
1527 auto _obs = parentObs.argList();
1529 std::unique_ptr<RooAbsCollection> _globs(_obs.selectByAttrib(
"global",
true));
1531 _obs.remove(*_globs);
1537 _obs.add(*
dynamic_cast<RooAbsArg *
>(ax->GetParent()));
1540 if (
auto _d = _ws->data(
child.GetName()); _d) {
1543 l.remove(*_d->get(),
true,
true);
1547 throw std::runtime_error(
"Cannot extend dataset with new columns");
1558 if (
auto __d = _ws->data(
child.GetName()))
1559 __d->SetBit(1 << 20, _ws->allData().size() == 1);
1567 auto out = std::shared_ptr<TObject>(_ws->data(
child.GetName()), [](
TObject *) {});
1576 throw std::runtime_error(
"Cannot create dataset");
1581 throw std::runtime_error(
"Cannot add to null object with no parentage");
1583 auto _ref = emplace_back(std::shared_ptr<xRooNode>(&
const_cast<xRooNode &
>(
child), [](
TObject *) {}));
1588 std::rethrow_exception(std::current_exception());
1593 throw std::runtime_error(
"No object");
1597 if (
auto p = get<RooAbsData>();
p) {
1599 bb->Add(
child, opt);
1603 throw std::runtime_error(
"Can only add datasets to a dataset");
1608 auto _globs =
globs();
1609 for (
auto &glob :
child.globs()) {
1610 if (
auto g = _globs.find(glob->GetName()); !
g) {
1612 }
else if (
g->GetContent() != glob->GetContent()) {
1613 Warning(
"Add",
"Global observable %s=%g in dataset mismatches child value %g ... ignoring child",
1614 g->GetName(),
g->GetContent(), glob->GetContent());
1618 if (
auto _dglobs =
p->getGlobalObservables()) {
1621 for (
auto g : _globs)
1624 p->setGlobalObservables(globsToAdd);
1628 for (
auto col : *_data->get()) {
1629 if (!
p->get()->contains(*col)) {
1630 ds->addColumn(*col);
1638 throw std::runtime_error(
"Can only add histogram or dataset to data");
1642 throw std::runtime_error(
"Could not find pdf");
1643 auto _ax = _pdf->GetXaxis();
1645 throw std::runtime_error(
"Cannot determine binning to add data");
1654 l.remove(*
p->get(),
true,
true);
1658 throw std::runtime_error(
"Cannot extend dataset with new columns");
1665 for (
auto &o :
obs) {
1667 if (
auto dv =
dynamic_cast<RooRealVar *
>(
p->get()->find(
v->GetName())); dv) {
1668 if (
v->getMin() < dv->getMin())
1669 dv->setMin(
v->getMin());
1670 if (
v->getMax() > dv->getMax())
1671 dv->setMax(
v->getMax());
1674 if (
auto dc =
dynamic_cast<RooCategory *
>(
p->get()->find(
c->GetName())); dc) {
1675 if (!dc->hasLabel(
c->getCurrentLabel())) {
1676 dc->defineType(
c->getCurrentLabel(),
c->getCurrentIndex());
1682 for (
int i = 1; i <= _h->GetNbinsX(); i++) {
1684 if (!_h->GetXaxis()->GetBinLabel(i)) {
1685 throw std::runtime_error(
1686 TString::Format(
"Categorical observable %s requires bin labels", _ax->GetParent()->GetName()));
1687 }
else if (!cat->hasLabel(_h->GetXaxis()->GetBinLabel(i))) {
1688 throw std::runtime_error(
TString::Format(
"Categorical observable %s does not have label %s",
1689 _ax->GetParent()->GetName(), _h->GetXaxis()->GetBinLabel(i)));
1691 cat->setLabel(_h->GetXaxis()->GetBinLabel(i));
1694 dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent())->setVal(_h->GetBinCenter(i));
1696 p->add(
obs, _h->GetBinContent(i));
1702 if (
auto p = get<RooAddPdf>();
p) {
1706 auto _pdf = std::dynamic_pointer_cast<RooAbsPdf>(out);
1708 throw std::runtime_error(
"Something went wrong with pdf acquisition");
1715 if (
auto _boundaries = std::unique_ptr<std::list<double>>(_p->binBoundaries(
1716 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
1717 std::numeric_limits<double>::infinity()));
1718 !_boundaries && _ax->GetNbins() > 0) {
1719#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 24, 00)
1720 Warning(
"Add",
"Adding unbinned pdf %s to binned %s - will wrap with RooBinSamplingPdf(...)",
1722 _p = acquireNew<RooBinSamplingPdf>(
TString::Format(
"%s_binned", _p->GetName()), _p->GetTitle(),
1724 _p->setStringAttribute(
"alias", std::dynamic_pointer_cast<RooAbsArg>(out)->getStringAttribute(
"alias"));
1725 if (!_p->getStringAttribute(
"alias"))
1726 _p->setStringAttribute(
"alias", out->GetName());
1728 throw std::runtime_error(
1729 "unsupported addition of unbinned pdf to binned model - please upgrade to at least ROOT 6.24");
1735 if (!(_pdf->canBeExtended() &&
p->coefList().empty())) {
1739 if (_pdf->canBeExtended()) {
1744 .add(*acquireNew<RooExtendedBinding>(
TString::Format(
"%s_extBind", _pdf->GetName()),
1748 const_cast<RooArgList &
>(
p->coefList()).add(*acquire2<RooAbsArg, RooRealVar>(
"1",
"1", 1));
1751 const_cast<RooArgList &
>(
p->pdfList()).add(*_pdf);
1755 (!
child.get() && getObject<RooAbsReal>(
child.GetName()))) &&
1758 bool tooMany(
false);
1771 }
else if (!tooMany) {
1776 _sumpdf.get<
RooAbsArg>()->setStringAttribute(
"alias",
"samples");
1777 return _sumpdf.Add(
child);
1782 if (
auto p = get<RooRealSumPdf>();
p) {
1783 std::shared_ptr<TObject> out;
1784 auto cc =
child.fComp;
1785 bool isConverted = (cc !=
child.convertForAcquisition(*
this, sOpt));
1788 if (!
child.fComp && getObject<RooAbsReal>(
child.GetName())) {
1789 Info(
"Add",
"Adding existing function %s to %s",
child.GetName(),
p->
GetName());
1790 out = getObject<RooAbsReal>(
child.GetName());
1793 if (!out && !
child.fComp) {
1794 std::shared_ptr<RooAbsArg> _func;
1805 std::make_unique<TH1D>(
child.GetName(),
child.GetTitle(), _ax->GetNbins(), _ax->binning()->array());
1807 h->GetXaxis()->SetName(
TString::Format(
"%s;%s", _ax->GetParent()->GetName(), _ax->GetName()));
1810 }
else if (_obs.size() == 1) {
1814 TString binningName =
p->getStringAttribute(
"binning");
1815 for (
auto &
b : _bnames) {
1823 auto h = std::make_unique<TH1D>(
child.GetName(),
child.GetTitle(), _x->numBins(binningName),
1824 _x->getBinningPtr(binningName)->array());
1826 h->GetXaxis()->SetName(
1830 Info(
"Add",
"Created densityhisto factor %s (xaxis=%s) for %s", _func->GetName(), _obs.at(0)->GetName(),
1833 throw std::runtime_error(
"Unsupported creation of new component in SumPdf for this many obs");
1839 _func->setStringAttribute(
"alias",
child.GetName());
1843 if (
auto _f = std::dynamic_pointer_cast<RooHistFunc>(
1847 _f->setAttribute(
"density");
1848 if (_f->getAttribute(
"autodensity")) {
1850 for (
int i = 0; i < _f->dataHist().numEntries(); i++) {
1851 auto bin_pars = _f->dataHist().get(i);
1852 _f->dataHist().set(*bin_pars, _f->dataHist().weight() / _f->dataHist().binVolume(*bin_pars));
1854 _f->setAttribute(
"autodensity",
false);
1855 _f->setValueDirty();
1864 Info(
"Add",
"Created %s factor RooHistFunc::%s for %s",
1865 _f->getAttribute(
"density") ?
"densityhisto" :
"histo", _f->GetName(),
p->
GetName());
1868 if (
auto _p = std::dynamic_pointer_cast<RooAbsPdf>(out); _p) {
1872 TString newName(_p->GetName());
1874 newName +=
"_components";
1875 Warning(
"Add",
"converting samples to components");
1880 if (
auto _boundaries = std::unique_ptr<std::list<double>>(_p->binBoundaries(
1881 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
1882 std::numeric_limits<double>::infinity()));
1883 !_boundaries && _ax->GetNbins() > 0) {
1884#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 24, 00)
1885 Warning(
"Add",
"Adding unbinned pdf %s to binned %s - will wrap with RooBinSamplingPdf(...)",
1887 _p = acquireNew<RooBinSamplingPdf>(
TString::Format(
"%s_binned", _p->GetName()), _p->GetTitle(),
1889 _p->setStringAttribute(
"alias", std::dynamic_pointer_cast<RooAbsArg>(out)->getStringAttribute(
"alias"));
1890 if (!_p->getStringAttribute(
"alias"))
1891 _p->setStringAttribute(
"alias", out->GetName());
1893 throw std::runtime_error(
1894 "unsupported addition of unbinned pdf to binned model - please upgrade to at least ROOT 6.24");
1901 if (!_p->canBeExtended()) {
1902 _p = acquireNew<RooExtendPdf>(
TString::Format(
"%s_extended", _p->GetName()), _p->GetTitle(), *_p,
1903 *acquire2<RooAbsReal, RooRealVar>(
"1",
"1", 1));
1906 return *(
Replace(*acquireNew<RooAddPdf>(newName, _p->GetTitle(),
RooArgList(*
p, *_p)))
1910 if (
auto _f = std::dynamic_pointer_cast<RooAbsReal>(out); _f) {
1919 if (
auto _boundaries = std::unique_ptr<std::list<double>>(_f->binBoundaries(
1920 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
1921 std::numeric_limits<double>::infinity()));
1922 !_boundaries && _ax->GetNbins() > 0) {
1923#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 24, 00)
1926 "Adding unbinned function %s to binned %s - will wrap with RooRealSumPdf(RooBinSamplingPdf(...))",
1928 auto sumPdf = acquireNew<RooRealSumPdf>(
TString::Format(
"%s_pdfWrapper", _f->GetName()), _f->GetTitle(),
1929 *_f, *acquire2<RooAbsArg, RooRealVar>(
"1",
"1", 1),
true);
1930 sumPdf->setStringAttribute(
"alias", _f->getStringAttribute(
"alias"));
1931 if (!sumPdf->getStringAttribute(
"alias"))
1932 sumPdf->setStringAttribute(
"alias", out->GetName());
1933 _f = acquireNew<RooBinSamplingPdf>(
TString::Format(
"%s_binned", _f->GetName()), _f->GetTitle(),
1935 _f->setStringAttribute(
"alias", std::dynamic_pointer_cast<RooAbsArg>(out)->getStringAttribute(
"alias"));
1936 if (!_f->getStringAttribute(
"alias"))
1937 _f->setStringAttribute(
"alias", out->GetName());
1939 throw std::runtime_error(
1940 "unsupported addition of unbinned function to binned model - please upgrade to at least ROOT 6.24");
1945 const_cast<RooArgList &
>(
p->coefList()).add(*acquire2<RooAbsArg, RooRealVar>(
"1",
"1", 1));
1948 if (!
p->getStringAttribute(
"binning"))
1949 p->setStringAttribute(
"binning", _f->getStringAttribute(
"binning"));
1952 if (
auto gf =
p->getStringAttribute(
"global_factors"); gf) {
1955 auto fac = getObject<RooAbsReal>(pattern.
Data());
1957 throw std::runtime_error(
TString::Format(
"Could not find global factor %s", pattern.
Data()));
1966 p->setStringAttribute(
"xvar",
nullptr);
1970 }
else if (
auto p2 = get<RooProdPdf>(); p2) {
1977 bool tooMany(
false);
1990 }
else if (!tooMany) {
1991 auto out = this->
operator[](
"components")->Add(child);
1995 (!
child.get() && getObject<RooAbsReal>(
child.GetName()))) &&
1999 bool tooMany(
false);
2008 }
else if (
auto _p2 =
pp->get<
RooAddPdf>(); _p2) {
2010 for (
auto &_pdfa :
pp->components()) {
2024 }
else if (_backup) {
2027 }
else if (!tooMany) {
2028 auto out = this->
operator[](
"samples")->Add(child);
2031 p2->setStringAttribute(
"xvar",
nullptr);
2035 }
else if (
auto s = get<RooSimultaneous>(); s) {
2043 }
else if (
auto w = get<RooWorkspace>();
w) {
2044 child.convertForAcquisition(*
this);
2048 if (!
w->import(*_d)) {
2051 throw std::runtime_error(
TString::Format(
"Could not import dataset %s into workspace %s",
child.GetName(),
w->GetName()).
Data());
2060 if (!
child.empty() ||
child.fFolder ==
"!models") {
2063 std::string catName =
"channelCat";
2064 if (!
child.empty()) {
2065 if (
TString ss =
child.at(0)->GetName(); ss.Contains(
"=")) {
2066 catName = ss(0, ss.Index(
'='));
2069 auto _cat = acquire<RooCategory>(catName.c_str(), catName.c_str());
2070 _cat->setAttribute(
"obs");
2071 auto out = acquireNew<RooSimultaneous>(
child.GetName(),
child.GetTitle(), *_cat);
2072 Info(
"Add",
"Created model RooSimultaneous::%s in workspace %s", out->GetName(),
w->GetName());
2077 if (sOpt ==
"model") {
2079 if (get<RooWorkspace>()) {
2083 }
else if (sOpt ==
"channel") {
2085 if (get<RooSimultaneous>()) {
2087 }
else if (get<RooWorkspace>()) {
2088 std::shared_ptr<TObject> out;
2089 child.convertForAcquisition(*
this);
2092 else if (!
child.fComp) {
2093 out = acquireNew<RooProdPdf>(
child.GetName(),
2095 Info(
"Add",
"Created channel RooProdPdf::%s in workspace %s", out->GetName(),
get()->
GetName());
2099 }
else if (sOpt ==
"sample" || sOpt ==
"func") {
2100 if (get<RooProdPdf>()) {
2103 return _mainChild.Add(
child, sOpt ==
"func" ?
"func" :
"");
2105 return (*
this)[
"samples"]->Add(
child, sOpt ==
"func" ?
"func" :
"");
2108 }
else if (sOpt ==
"dataset") {
2109 if (get<RooWorkspace>()) {
2111 return (*this).datasets().Add(
child);
2118 if (get<RooSimultaneous>()) {
2122 }
else if (get<RooProduct>() || get<RooProdPdf>()) {
2168 if (
auto a = get<RooAbsArg>()) {
2169 a->setAttribute(
"hidden", set);
2178 auto a = get<RooAbsArg>();
2180 return a->getAttribute(
"hidden");
2187 if (
get() == rhs.
get()) {
2237 if (
auto s = get<RooSimultaneous>(); s) {
2238 auto chans =
bins();
2239 if (!chans.empty()) {
2245 for (
auto &
c : chans) {
2247 cName = cName(cName.
Index(
'=') + 1, cName.
Length());
2250 c->shallowCopy(
name +
"_" +
c->get()->GetName(), std::shared_ptr<xRooNode>(&out, [](
xRooNode *) {}));
2251 pdf->addPdf(*
dynamic_cast<RooAbsPdf *
>(c_copy.get()), cName);
2256 }
else if (
auto p =
dynamic_cast<RooProdPdf *
>(o);
p) {
2258 std::shared_ptr<RooProdPdf> pdf =
2259 std::dynamic_pointer_cast<RooProdPdf>(out.acquire(std::shared_ptr<TObject>(
p->
Clone()),
false,
2264 std::dynamic_pointer_cast<RooAbsArg>(out.acquire(std::shared_ptr<TObject>(
main->Clone()),
false,
true));
2265 std::cout << newMain <<
" " << newMain->GetName() << std::endl;
2280 static std::unique_ptr<cout_redirect> capture;
2281 std::string captureStr;
2282 bool doCapture =
false;
2283 if (!capture &&
gROOT->FromPopUp()) {
2284 capture = std::make_unique<cout_redirect>(captureStr);
2307 if (
get() &&
get() !=
this) {
2309 if (_more || (get<RooAbsArg>() && get<RooAbsArg>()->isFundamental()) || get<RooConstVar>() ||
2310 get<RooAbsData>() || get<RooProduct>() || get<RooFitResult>()) {
2312 auto _snap = std::unique_ptr<RooAbsCollection>(_deps.snapshot());
2315 if (
auto _fr = get<RooFitResult>(); _fr &&
dynamic_cast<RooStringVar *
>(_fr->constPars().
find(
".log"))) {
2316 std::cout <<
"Minimization Logs:" << std::endl;
2317 std::cout << dynamic_cast<RooStringVar *>(_fr->constPars().find(
".log"))->getVal() << std::endl;
2319 _deps.assignValueOnly(*_snap);
2329 if (
auto fv = get<RooFormulaVar>()) {
2331 for (
size_t i = 0; i < fv->dependents().
size(); i++) {
2335 }
else if (
auto gv = get<RooGenericPdf>()) {
2337 for (
size_t i = 0; i < gv->dependents().
size(); i++) {
2345 }
else if (!
get()) {
2346 std::cout << std::endl;
2350 std::vector<std::string> folderNames;
2351 for (
auto &k : *
this) {
2352 if (std::find(folderNames.begin(), folderNames.end(), k->fFolder) == folderNames.end()) {
2353 folderNames.push_back(k->fFolder);
2356 for (
auto &
f : folderNames) {
2360 for (
int j = 0; j <
indent; j++)
2362 std::cout <<
f << std::endl;
2365 for (
auto &k : *
this) {
2366 if (k->fFolder !=
f) {
2370 for (
int j = 0; j < iindent; j++)
2372 std::cout << i++ <<
") " << k->GetName() <<
" : ";
2376 auto _deps = k->coords(
false).argList();
2377 auto _snap = std::unique_ptr<RooAbsCollection>(_deps.snapshot());
2379 k->get()->Print(sOpt);
2380 _deps.assignValueOnly(*_snap);
2383 if (
auto _type = k->GetNodeType(); strlen(_type)) {
2391 for (
size_t j = 0; j < fv->dependents().
size(); j++) {
2397 for (
size_t j = 0; j < gv->dependents().
size(); j++) {
2402 std::cout << k->get()->ClassName() <<
"::" << k->get()->GetName() << _suffix.
Data() << std::endl;
2405 k->Print(sOpt +
TString::Format(
"depth=%dindent=%d", depth - 1, iindent + 1));
2408 std::cout <<
" NULL " << std::endl;
2414 size_t lastBreak = 0;
2415 std::string captureStrWithBreaks;
2416 for (
size_t i = 0; i < captureStr.size(); i++) {
2417 captureStrWithBreaks += captureStr[i];
2418 if (captureStr[i] ==
'\n') {
2421 if (i - lastBreak > 150) {
2422 captureStrWithBreaks +=
'\n';
2427 (
gROOT->GetListOfBrowsers()->At(0))
2431 captureStrWithBreaks.c_str());
2439 if (
auto v = get<RooRealVar>();
v) {
2442 double mean = std::numeric_limits<double>::quiet_NaN();
2443 double sigma = mean;
2452 mean = std::numeric_limits<double>::quiet_NaN();
2455 constrType =
"normal";
2456 }
else if (constrType ==
"normal") {
2459 }
else if (constrType ==
"gaussian") {
2463 throw std::runtime_error(
"No error on parameter for gaussian constraint");
2466 constrType =
"normal";
2467 }
else if (constrType ==
"poisson") {
2469 throw std::runtime_error(
"No error on parameter for poisson constraint");
2471 sigma = pow(
v->getVal() /
v->getError(), 2);
2474 if (constrType ==
"poisson") {
2476 double tau_val =
sigma;
2477 auto globs = acquire<RooRealVar>(
Form(
"globs_%s",
v->GetName()),
Form(
"globs_%s",
v->GetName()),
2478 v->getVal() * tau_val, (
v->getVal() - 5 *
v->getError()) * tau_val,
2479 (
v->getVal() + 5 *
v->getError()) * tau_val);
2480 globs->setConstant();
2481 globs->setAttribute(
"obs");
2482 globs->setAttribute(
"global");
2484 auto tau = acquireNew<RooConstVar>(
TString::Format(
"tau_%s",
v->GetName()),
"", tau_val);
2485 auto constr = acquireNew<RooPoisson>(
2494 v->setError(mean / sqrt(tau_val));
2495 Info(
"Constrain",
"Added poisson constraint pdf RooPoisson::%s (tau=%g) for %s", out->GetName(), tau_val,
2498 }
else if (constrType ==
"normal") {
2500 auto globs = acquire<RooRealVar>(
Form(
"globs_%s",
v->GetName()),
Form(
"globs_%s",
v->GetName()), mean,
2502 globs->setAttribute(
"obs");
2503 globs->setAttribute(
"global");
2504 globs->setConstant();
2507 auto constr = acquireNew<RooGaussian>(
2513 Info(
"Constrain",
"Added gaussian constraint pdf RooGaussian::%s (mean=%g,sigma=%g) for %s", out->GetName(),
2520 auto _me = get<RooAbsArg>();
2522 throw std::runtime_error(
"Cannot constrain non arg");
2525 if (!
p->dependsOn(*_me)) {
2526 throw std::runtime_error(
"Constraint does not depend on constrainee");
2535 throw std::runtime_error(
"Nowhere to put constraint");
2541 for (
auto &
c : *
x) {
2547 return x->Multiply(
child);
2549 return x->Add(
child,
"+");
2562 ~AutoUpdater() {
n.browse(); }
2565 AutoUpdater xxx(*
this);
2572 auto o = std::dynamic_pointer_cast<RooAbsReal>(
acquire(
child.fComp));
2595 ?
fParent->mainChild()->GetName()
2600 binFactors =
fParent->factors().find(
"binFactors");
2602 throw std::runtime_error(
2609 for (
auto &
b : binFactors->bins()) {
2610 auto p = acquireNew<RooProduct>(
TString::Format(
"%s_bin%d", binFactors->get()->GetName(), i),
2612 p->setStringAttribute(
"alias",
TString::Format(
"%s=%g", binFactors->GetXaxis()->GetParent()->GetName(),
2613 binFactors->GetXaxis()->GetBinCenter(i)));
2620 auto _bin = binFactors->bins().at(
fBinNumber - 1);
2621 if (
auto phf = binFactors->get<
ParamHistFunc>(); phf && _bin) {
2622#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
2627 if (strcmp(_bin->GetName(),
"1") == 0) {
2629 for (
int i = 0; i < pSet.
getSize(); i++) {
2631 all.
add(*pSet.
at(i));
2638 _bin->fBinNumber = -1;
2639 return _bin->Multiply(
child, opt);
2667 auto _ref = emplace_back(std::shared_ptr<xRooNode>(&
const_cast<xRooNode &
>(
child), [](
TObject *) {}));
2672 std::rethrow_exception(std::current_exception());
2680 if (
auto o = getObject<RooAbsReal>(
child.GetName())) {
2684 Info(
"Multiply",
"Scaled %s by existing factor %s::%s",
2687 }
else if (sOpt ==
"norm") {
2694 Info(
"Multiply",
"Scaled %s by new norm factor %s",
2698 throw std::runtime_error(
TString::Format(
"Failed to create new normFactor %s",
child.GetName()));
2702 Info(
"Multiply",
"Scaled %s by new norm factor %s",
2705 }
else if (sOpt ==
"shape" || sOpt ==
"histo" || sOpt ==
"blankshape") {
2710 for (
int i = 1; i <=
h->GetNbinsX(); i++) {
2711 h->SetBinContent(i, 1);
2716 h->SetTitle(
child.GetTitle());
2721 Info(
"Multiply",
"Scaled %s by new %s factor %s",
2725 }
else if (sOpt ==
"overall") {
2726 auto out =
Multiply(acquireNew<RooStats::HistFactory::FlexibleInterpVar>(
2727 child.GetName(),
child.GetTitle(),
RooArgList(), 1, std::vector<double>(), std::vector<double>()));
2729 Info(
"Multiply",
"Scaled %s by new overall factor %s",
2732 }
else if (sOpt ==
"func" &&
ws()) {
2737 Info(
"Multiply",
"Scaled %s by new func factor %s",
2743 if (
auto h =
child.get<
TH1>();
h && strlen(
h->GetOption()) == 0 && strlen(opt) > 0) {
2747 if (
auto w = get<RooWorkspace>();
w) {
2749 std::shared_ptr<TObject> out;
2750 child.convertForAcquisition(*
this);
2756 if (strcmp(
GetName(),
".coef") == 0) {
2759 for (
size_t i = 0; i <
p->pdfList().size(); i++) {
2761 auto coefs =
p->coefList().at(i);
2770 for (
size_t j = 0; j <
p->coefList().size(); j++) {
2772 oldCoefs.
add(*newCoefs);
2774 oldCoefs.add(*
p->coefList().at(j));
2776 const_cast<RooArgList &
>(
p->coefList()).removeAll();
2777 const_cast<RooArgList &
>(
p->coefList()).add(oldCoefs);
2784 throw std::runtime_error(
"this coefs case is not supported");
2787 if (
auto p = get<RooProduct>();
p) {
2788 std::shared_ptr<TObject> out;
2789 auto cc =
child.fComp;
2790 bool isConverted = (
child.convertForAcquisition(*
this) != cc);
2795 if (
auto _f = std::dynamic_pointer_cast<RooHistFunc>(
2797 _f && _f->getAttribute(
"autodensity")) {
2799 bool hasDensity =
false;
2807 if (_f->getAttribute(
"density")) {
2810 for (
int i = 0; i < _f->dataHist().numEntries(); i++) {
2811 auto bin_pars = _f->dataHist().get(i);
2812 _f->dataHist().set(*bin_pars, _f->dataHist().weight() / _f->dataHist().binVolume(*bin_pars));
2814 _f->setValueDirty();
2821 _f->setAttribute(
"autodensity",
false);
2825 Info(
"Multiply",
"Created %s factor %s in %s",
2829 Info(
"Multiply",
"Created shape factor %s in %s",
child->GetName(),
p->
GetName());
2832 if (
auto _f = std::dynamic_pointer_cast<RooAbsReal>(out); _f) {
2833#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
2834 p->_compRSet.add(*_f);
2836 const_cast<RooArgList &
>(
p->realComponents()).add(*_f);
2842 for (
auto &_par : _out.
pars()) {
2845 for (
auto &_constr : _par->constraints()) {
2846 if (strcmp(s, _constr->get()->GetName()) == 0) {
2853 Info(
"Multiply",
"Pulling in %s boundConstraint: %s", _par->GetName(), s);
2854 auto _pdf = getObject<RooAbsPdf>(s);
2856 throw std::runtime_error(
"Couldn't find boundConstraint");
2858 _par->Constrain(_pdf);
2865 }
else if (
auto p2 = get<RooProdPdf>(); p2) {
2867 std::shared_ptr<TObject> out;
2868 child.convertForAcquisition(*
this);
2877 std::shared_ptr<RooAbsPdf> _pdf;
2878 if (!
child.get() && strcmp(
child.GetName(),
"components") == 0) {
2879 auto _sumpdf = acquireNew<RooAddPdf>(
Form(
"%s_%s", p2->GetName(),
child.GetName()),
2880 (strlen(
child.GetTitle()) && strcmp(
child.GetTitle(),
child.GetName()))
2886 auto _sumpdf = acquireNew<RooRealSumPdf>(
2887 Form(
"%s_%s", p2->GetName(),
child.GetName()),
2891 _sumpdf->setFloor(
true);
2894 _pdf->setStringAttribute(
"alias",
child.GetName());
2896 _pdf->setStringAttribute(
"xvar", p2->getStringAttribute(
"xvar"));
2897 _pdf->setStringAttribute(
"binning", p2->getStringAttribute(
"binning"));
2899 Info(
"Multiply",
"Created %s::%s in channel %s", _pdf->ClassName(), _pdf->GetName(), p2->GetName());
2904 if (
auto _pdf = std::dynamic_pointer_cast<RooAbsPdf>(out); _pdf) {
2905#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
2906 const_cast<RooArgList &
>(p2->pdfList()).add(*_pdf);
2907#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
2908 p2->_pdfNSetList.emplace_back(std::make_unique<RooArgSet>(
"nset"));
2912 if (!p2->canBeExtended() && _pdf->canBeExtended()) {
2913 p2->_extendedIndex = p2->_pdfList.size() - 1;
2922 }
else if (
auto p3 = get<RooRealSumPdf>(); p3) {
2924 std::shared_ptr<TObject> out;
2925 child.convertForAcquisition(*
this);
2931 TString s = p3->getStringAttribute(
"global_factors");
2934 s += out->GetName();
2935 p3->setStringAttribute(
"global_factors", s);
2938 "Flagged %s as a global factor in channel %s (is applied to all current and future samples in the channel)",
2939 out->GetName(), p3->GetName());
2950 std::set<RooAbsArg *> cl;
2951 for (
auto &arg : p5->clients()) {
2957 if (cl.size() > 1) {
2962 Warning(
"Multiply",
"Scaling %s that has multiple clients", p5->GetName());
2968 for (
auto &
a : p5->attributes())
2969 new_p->setAttribute(
a.c_str());
2970 for (
auto &
a : p5->stringAttributes())
2971 new_p->setStringAttribute(
a.first.c_str(),
a.second.c_str());
2972 if (!new_p->getStringAttribute(
"alias"))
2973 new_p->setStringAttribute(
"alias", p5->GetName());
2975 new_p->setAttribute(
Form(
"ORIGNAME:%s", old_p->GetName()));
2976 for (
auto arg : cl) {
2977 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
2985 if (!
child.get() && strlen(opt) == 0)
2988 throw std::runtime_error(
2990 (!
child.get() && strlen(opt) == 0) ?
" (forgot to specify factor type?)" :
""));
2996 auto p5 = get<RooAbsArg>();
2998 throw std::runtime_error(
"Only replacement of RooAbsArg is supported");
3007 new_p = std::dynamic_pointer_cast<RooAbsArg>(out).get();
3009 std::set<RooAbsArg *> cl;
3010 for (
auto &arg : p5->clients()) {
3018 if (cl.size() > 1) {
3023 std::stringstream clientList;
3025 clientList <<
c->GetName() <<
",";
3026 Warning(
"Replace",
"Replacing %s in all clients: %s", p5->GetName(), clientList.str().c_str());
3030 new_p->setAttribute(
Form(
"ORIGNAME:%s", p5->GetName()));
3031 for (
auto arg : cl) {
3036 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
3047 ~AutoUpdater() {
n.browse(); }
3050 AutoUpdater xxx(*
this);
3055 auto _ref = emplace_back(std::shared_ptr<xRooNode>(&
const_cast<xRooNode &
>(
child), [](
TObject *) {}));
3060 std::rethrow_exception(std::current_exception());
3072 std::string label =
child.GetName();
3073 if (
auto pos = label.find(
"="); pos != std::string::npos)
3074 label = label.substr(pos + 1);
3075 if (!s->indexCat().hasLabel(label)) {
3078 std::shared_ptr<TObject> out;
3079 child.convertForAcquisition(*
this);
3082 else if (!
child.fComp) {
3083 out = acquireNew<RooProdPdf>(
TString::Format(
"%s_%s", s->GetName(), label.c_str()),
3085 Info(
"Vary",
"Created channel RooProdPdf::%s in model %s", out->GetName(), s->GetName());
3088 if (
auto _pdf = std::dynamic_pointer_cast<RooAbsPdf>(out); _pdf) {
3089 s->addPdf(*_pdf, label.c_str());
3098 }
else if (
auto p = get<RooStats::HistFactory::FlexibleInterpVar>();
p) {
3101 child.convertForAcquisition(*
this);
3103 if (!_c &&
child.get()) {
3104 throw std::runtime_error(
"Only pure consts can be set as variations of a flexible interpvar");
3106#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3107 double value = (_c ? _c->getVal() :
p->_nominal);
3108 double nomVal =
p->_nominal;
3110 double value = (_c ? _c->getVal() :
p->nominal());
3111 double nomVal =
p->nominal();
3115 if (cName ==
"nominal") {
3120 throw std::runtime_error(
"unsupported variation form");
3122 std::string parName = cName(0, cName.
Index(
'='));
3124 if (parVal != 1 && parVal != -1) {
3125 throw std::runtime_error(
"unsupported variation magnitude");
3127 bool high = parVal > 0;
3129 if (parName.empty()) {
3138 if (!
p->findServer(*
v)) {
3139#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3140 p->_paramList.add(*
v);
3141 p->_low.push_back(0);
3142 p->_high.push_back(0);
3143 p->_interpCode.push_back(4);
3146 const_cast<std::vector<double> &
>(
p->low()).push_back(0);
3147 const_cast<std::vector<double> &
>(
p->high()).push_back(0);
3148 const_cast<std::vector<int> &
>(
p->interpolationCodes()).push_back(4);
3150 v->setAttribute(
Form(
"SYMMETRIC%s_%s", high ?
"+" :
"-",
GetName()));
3155 if (
v->getAttribute(
Form(
"SYMMETRIC+_%s",
GetName()))) {
3156 p->setLow(*
v, 2 * nomVal -
value);
3158 v->setAttribute(
Form(
"SYMMETRIC-_%s",
GetName()),
false);
3161 if (
v->getAttribute(
Form(
"SYMMETRIC-_%s",
GetName()))) {
3162 p->setHigh(*
v, 2 * nomVal -
value);
3164 v->setAttribute(
Form(
"SYMMETRIC+_%s",
GetName()),
false);
3172 }
else if (
auto p2 = get<PiecewiseInterpolation>(); p2) {
3175 throw std::runtime_error(
"unsupported variation form");
3179 if (parVal != 1 && parVal != -1) {
3180 throw std::runtime_error(
"unsupported variation magnitude");
3182#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3185 throw std::runtime_error(
3186 TString::Format(
"Interpolating %s instead of RooHistFunc", p2->_nominal.absArg()->ClassName()));
3191 throw std::runtime_error(
3192 TString::Format(
"Interpolating %s instead of RooHistFunc", p2->nominalHist()->ClassName()));
3198 for (
auto par : p2->paramList()) {
3199 if (parName == par->GetName()) {
3200 f =
dynamic_cast<RooHistFunc *
>((parVal > 0 ? p2->highList() : p2->lowList()).
at(i));
3201 otherf =
dynamic_cast<RooHistFunc *
>((parVal > 0 ? p2->lowList() : p2->highList()).
at(i));
3209 auto v = acquire<RooRealVar>(parName, parName, -5, 5);
3213 std::shared_ptr<RooHistFunc> up(
3215 std::shared_ptr<RooHistFunc> down(
3218#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3219 std::unique_ptr<RooDataHist>
h1(
3220 static_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", up->GetName()))));
3221 std::unique_ptr<RooDataHist> h2(
3222 static_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", down->GetName()))));
3223 up->_dataHist =
dynamic_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", up->GetName())));
3224 down->_dataHist =
dynamic_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", down->GetName())));
3227 down->cloneAndOwnDataHist(
TString::Format(
"hist_%s", down->GetName()));
3229 auto ups = std::dynamic_pointer_cast<RooHistFunc>(
acquire(up,
false,
true));
3230 auto downs = std::dynamic_pointer_cast<RooHistFunc>(
acquire(down,
false,
true));
3231#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3232 p2->_highSet.add(*ups.get());
3233 p2->_lowSet.add(*downs.get());
3234 p2->_interpCode.push_back(4);
3235 p2->_paramSet.add(*
v);
3237 const_cast<RooArgList &
>(p2->highList()).add(*ups.get());
3238 const_cast<RooArgList &
>(p2->lowList()).add(*downs.get());
3239 const_cast<std::vector<int> &
>(p2->interpolationCodes()).push_back(4);
3240 const_cast<RooArgList &
>(p2->paramList()).add(*
v);
3242 p2->setValueDirty();
3243 f = ((parVal > 0) ? ups : downs).
get();
3244 otherf = ((parVal > 0) ? downs : ups).
get();
3246 f->setStringAttribute(
"symmetrizes", otherf->
GetName());
3247 f->setStringAttribute(
"symmetrize_nominal", nomf->
GetName());
3266 }
else if (
auto p3 = get<RooConstVar>(); p3) {
3269 if (p3->getAttribute(
"RooRealConstant_Factory_Object")) {
3270 throw std::runtime_error(
"Cannot vary pure constants");
3276 std::set<RooAbsArg *> cl;
3277 for (
auto &arg : p3->clients()) {
3282 if (cl.size() > 1) {
3287 Warning(
"Vary",
"Varying %s that has multiple clients", p3->GetName());
3290 p3->setStringAttribute(
"origName", p3->GetName());
3292 p3->SetName(
Form(
"%s_nominal", p3->GetName()));
3294 auto new_p = acquireNew<RooStats::HistFactory::FlexibleInterpVar>(
n, p3->GetTitle(),
RooArgList(), p3->getVal(),
3295 std::vector<double>(), std::vector<double>());
3298 for (
auto &
a : p3->attributes())
3299 new_p->setAttribute(
a.c_str());
3300 for (
auto &
a : p3->stringAttributes())
3301 new_p->setStringAttribute(
a.first.c_str(),
a.second.c_str());
3304 new_p->setAttribute(
Form(
"ORIGNAME:%s", old_p->GetName()));
3305 for (
auto arg : cl) {
3306 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
3312 }
else if (
auto p4 = get<RooAbsReal>(); p4) {
3316 std::set<RooAbsArg *> cl;
3317 for (
auto &arg : p4->clients()) {
3322 if (cl.size() > 1) {
3327 Warning(
"Vary",
"Varying %s that has multiple clients", p4->GetName());
3330 p4->setStringAttribute(
"origName", p4->GetName());
3332 p4->SetName(
Form(
"%s_nominal", p4->GetName()));
3337 for (
auto &
a : p4->attributes())
3338 new_p->setAttribute(
a.c_str());
3339 for (
auto &
a : p4->stringAttributes())
3340 new_p->setStringAttribute(
a.first.c_str(),
a.second.c_str());
3343 new_p->setAttribute(
Form(
"ORIGNAME:%s", old_p->GetName()));
3344 for (
auto arg : cl) {
3345 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
3386 if (
auto a = get<RooAbsArg>();
a && strcmp(
a->GetName(),
GetName()) && !
a->getStringAttribute(
"alias")) {
3387 a->setStringAttribute(
"alias",
GetName());
3390 throw std::runtime_error(
"Cannot determine type");
3395 if (
auto h =
dynamic_cast<const TH1 *
>(&o);
h) {
3406 bool _isData = get<RooAbsData>();
3412 throw std::runtime_error(
"no xaxis");
3413 auto _v =
dynamic_cast<RooRealVar *
>(ax->GetParent());
3416 _b.
b =
dynamic_cast<RooAbsBinning *
>(_v->getBinningPtr(0)->Clone());
3417 if (
h->GetXaxis()->IsVariableBinSize()) {
3418 _v->setBinning(
RooBinning(
h->GetNbinsX(),
h->GetXaxis()->GetXbins()->GetArray()));
3420 _v->setBinning(
RooUniformBinning(
h->GetXaxis()->GetXmin(),
h->GetXaxis()->GetXmax(),
h->GetNbinsX()));
3426 for (
int bin = 1; bin <=
h->GetNbinsX(); bin++) {
3434 if (!_isData &&
h->GetSumw2N() && !
SetBinError(bin,
h->GetBinError(bin)))
3435 throw std::runtime_error(
"Failed setting stat error");
3439 }
else if (
auto _c =
dynamic_cast<const RooConstVar *
>(&o); _c) {
3441 if (
auto a = get<RooAbsArg>();
3442 (
a &&
a->isFundamental()) || get<RooConstVar>() || get<RooStats::HistFactory::FlexibleInterpVar>()) {
3445 }
else if (get<RooAbsData>()) {
3451 throw std::runtime_error(
"Assignment failed");
3478 auto _pars =
pars();
3482 auto idx = pattern.
Index(
'=');
3485 (idx == -1) ? std::numeric_limits<double>::quiet_NaN() :
TString(pattern(idx + 1, pattern.
Length())).
Atof();
3486 for (
auto p : _pars.argList()) {
3488 p->setAttribute(
"Constant",
true);
3489 if (!std::isnan(val)) {
3498 for (
auto &
d : _dsets) {
3499 if (
d->get()->TestBit(1 << 20)) {
3500 dsetName =
d->get()->GetName();
3504 auto _nll =
nll(dsetName.
Data());
3505 _nll.fitConfigOptions()->SetValue(
"LogSize", 65536);
3506 _nll.fitConfig()->MinimizerOptions().SetPrintLevel(0);
3507 auto fr = _nll.minimize();
3510 throw std::runtime_error(
"Fit Failed");
3513 for (
unsigned int i = 0; i < fr->numStatusHistory(); i++) {
3514 statusCodes +=
TString::Format(
"\n%s = %d", fr->statusLabelHistory(i), fr->statusCodeHistory(i));
3517 (
gROOT->GetListOfBrowsers()->At(0))
3520 if (fr->status() != 0) {
3522 TString::Format(
"%s\nData = %s\nFit Status Code = %d\nCov Quality = %d\n-------------%s",
3523 fr->GetName(), dsetName.
Data(), fr->status(), fr->covQual(), statusCodes.
Data()),
3525 }
else if (fr->covQual() != 3 && _nll.fitConfig()->ParabErrors()) {
3526 new TGMsgBox(
gClient->GetRoot(),
w,
"Fit Finished with Bad Covariance Quality",
3527 TString::Format(
"%s\nData = %s\nFit Status Code = %d\nCov Quality = %d\n-------------%s",
3528 fr->GetName(), dsetName.
Data(), fr->status(), fr->covQual(), statusCodes.
Data()),
3532 TString::Format(
"%s\nData = %s\nFit Status Code = %d\nCov Quality = %d\n-------------%s",
3533 fr->GetName(), dsetName.
Data(), fr->status(), fr->covQual(), statusCodes.
Data()));
3535 }
catch (
const std::exception &
e) {
3538 (
gROOT->GetListOfBrowsers()->At(0))
3548 datasets().
Add(datasetName, expected ?
"asimov" :
"toy");
3549 }
catch (
const std::exception &
e) {
3552 (
gROOT->GetListOfBrowsers()->At(0))
3555 "Exception",
e.what(),
3561 double highX ,
const char *constParValues)
3570 for (
auto &
d : _dsets) {
3571 if (
d->get()->TestBit(1 << 20)) {
3572 dsetName =
d->get()->GetName();
3576 auto _pars =
pars();
3577 std::unique_ptr<RooAbsCollection> snap(_pars.argList().snapshot());
3580 auto idx = pattern.
Index(
'=');
3583 (idx == -1) ? std::numeric_limits<double>::quiet_NaN() :
TString(pattern(idx + 1, pattern.
Length())).
Atof();
3584 for (
auto par : _pars.argList()) {
3586 par->setAttribute(
"Constant",
true);
3587 if (!std::isnan(val)) {
3600 hs.SetTitle(sWhat +
" scan" + ((dsetName !=
"") ?
TString::Format(
" [data=%s]", dsetName.
Data()) :
""));
3601 int scanStatus = hs.scan(sWhat +
" visualize", nBinsX, lowX, highX);
3602 if (scanStatus != 0) {
3605 (
gROOT->GetListOfBrowsers()->At(0))
3608 "Scan Finished with Bad Status Code",
3609 TString::Format(
"%s\nData = %s\nScan Status Code = %d", hs.GetName(), dsetName.
Data(), scanStatus),
3614 if (
auto res = hs.result())
3618 _pars.argList() = *snap;
3620 }
catch (
const std::exception &
e) {
3623 (
gROOT->GetListOfBrowsers()->At(0))
3634 }
catch (
const std::exception &
e) {
3644 throw std::runtime_error(
"Failed to SetContent");
3645 }
catch (
const std::exception &
e) {
3659 std::shared_ptr<TH1D>
h;
3660 auto _b =
dynamic_cast<Axis2 *
>(ax)->binning();
3663 if (_b->isUniform()) {
3670 h->GetXaxis()->SetName(
TString::Format(
"%s;%s", ax->GetParent()->GetName(), ax->GetName()));
3678 if (get<RooProduct>()) {
3682 if (get<RooAbsData>()) {
3683 if (
auto _data = get<RooDataSet>(); _data) {
3684 auto _ax = (bin) ?
GetXaxis() :
nullptr;
3686 throw std::runtime_error(
"Cannot determine binning to fill data");
3688 if (_ax && _ax->GetNbins() < bin)
3689 throw std::out_of_range(
TString::Format(
"%s range %s only has %d bins", _ax->GetParent()->GetName(),
3690 _ax->GetName(), _ax->GetNbins()));
3695 for (
auto _c :
coords()) {
3699 cut +=
TString::Format(
"%s==%d", _cat->GetName(), _cat->getCurrentIndex());
3706 TString::Format(
"%s>=%f&&%s<%f", _rv->GetName(), _rv->getMin(_rv->getStringAttribute(
"coordRange")),
3707 _rv->GetName(), _rv->getMax(_rv->getStringAttribute(
"coordRange")));
3710 throw std::runtime_error(
"SetBinContent of data: Unsupported coordinate type");
3719 cut2 =
TString::Format(
"%s >= %f && %s < %f", _ax->GetParent()->GetName(), _ax->GetBinLowEdge(bin),
3720 _ax->GetParent()->GetName(), _ax->GetBinUpEdge(bin));
3752 l.remove(*_data->get(),
true,
true);
3757 _data->addColumn(*
x);
3767 for (
auto &o :
obs) {
3769 if (
auto dv =
dynamic_cast<RooRealVar *
>(_data->get()->find(
v->GetName())); dv) {
3770 if (
v->getMin() < dv->getMin())
3771 dv->setMin(
v->getMin());
3772 if (
v->getMax() > dv->getMax())
3773 dv->setMax(
v->getMax());
3776 if (
auto dc =
dynamic_cast<RooCategory *
>(_data->get()->find(
c->GetName())); dc) {
3777 if (!dc->hasLabel(
c->getCurrentLabel())) {
3778 dc->defineType(
c->getCurrentLabel(),
c->getCurrentIndex());
3787 if (
auto _nentries = std::unique_ptr<RooAbsData>(_data->reduce(cutFormula))->numEntries();
3788 _nentries != _ax->GetNbins()) {
3791 if (_nentries > 0) {
3792 Info(
"SetBinContent",
"Binning %s in channel: %s",
GetName(), cut.
Data());
3793 auto _reduced = std::unique_ptr<RooAbsData>(_data->reduce(icutFormula));
3795 for (
int j = 0; j < _reduced->numEntries(); j++) {
3796 auto _obs = _reduced->get(j);
3797 _data->add(*_obs, _reduced->weight());
3800 for (
int i = 1; i <= _ax->GetNbins(); i++) {
3804 dynamic_cast<RooAbsLValue *
>(_ax->GetParent())->setBin(i - 1, _ax->GetName());
3805 _data->add(
obs, _contents.
at(i - 1));
3810 if (std::unique_ptr<RooAbsData>(_data->reduce(cutFormula2))->numEntries() > 0) {
3811 auto _reduced = std::unique_ptr<RooAbsData>(_data->reduce(icutFormula2));
3813 for (
int j = 0; j < _reduced->numEntries(); j++) {
3814 auto _obs = _reduced->get(j);
3815 _data->add(*_obs, _reduced->weight());
3819 dynamic_cast<RooAbsLValue *
>(_ax->GetParent())->setBin(bin - 1, _ax->GetName());
3822 return bb->SetBinContent(bin,
value, par, parVal);
3825 }
else if (get<RooDataHist>()) {
3826 throw std::runtime_error(
"RooDataHist not supported yet");
3830 if (
auto _varies =
variations(); !_varies.empty() || (par && strlen(par))) {
3831 if (!par || strlen(par) == 0) {
3832 return _varies[
"nominal"]->SetBinContent(bin,
value, par, parVal);
3833 }
else if (
auto it = _varies.find(
Form(
"%s=%g", par, parVal)); it) {
3834 return it->SetBinContent(bin,
value);
3846 if (!par || strlen(par) == 0) {
3859 if (strcmp(
c->GetName(),
Form(
"%g",
c->getVal())) == 0) {
3862#if ROOT_VERSION_CODE < ROOT_VERSION(6, 24, 00)
3875 auto bin_pars =
f->dataHist().get(bin - 1);
3876 if (
f->getAttribute(
"density")) {
3877 value /=
f->dataHist().binVolume(*bin_pars);
3879 f->dataHist().set(*bin_pars,
value);
3882 if (
auto otherfName =
f->getStringAttribute(
"symmetrized_by"); otherfName) {
3884 f->setStringAttribute(
"symmetrized_by",
nullptr);
3885 if (
auto x = getObject<RooAbsArg>(otherfName);
x) {
3886 x->setStringAttribute(
"symmetrizes",
nullptr);
3887 x->setStringAttribute(
"symmetrize_nominal",
nullptr);
3889 }
else if (
auto otherfName2 =
f->getStringAttribute(
"symmetrizes"); otherfName2) {
3890 auto nomf = getObject<RooHistFunc>(
f->getStringAttribute(
"symmetrize_nominal"));
3891 auto otherf = getObject<RooHistFunc>(otherfName2);
3892 if (nomf && otherf) {
3893 otherf->dataHist().set(*bin_pars, 2 * nomf->dataHist().weight(bin - 1) -
value);
3894 otherf->setValueDirty();
3901 f2->setNominal(
value);
3913 return datasets()[dataName]->SetContents(obj);
3920 if (get<RooProduct>()) {
3924 if (
auto _varies =
variations(); !_varies.empty()) {
3925 return _varies[
"nominal"]->SetBinError(bin,
value);
3940 while (_prodParent && !_prodParent->get<
RooProduct>() && !_prodParent->get<
RooAbsPdf>()) {
3942 _prodParent.reset();
3945 _prodParent = _prodParent->fParent;
3948 (_prodParent && !_prodParent->get<
RooAbsPdf>()) ? _prodParent->factors().find(
"statFactor") :
nullptr;
3949 auto f_stat = (_f_stat) ? _f_stat->get<
ParamHistFunc>() :
nullptr;
3950 if (_f_stat && _f_stat->get() && !f_stat) {
3951 throw std::runtime_error(
"stat factor must be a paramhistfunc");
3960 for (
auto &
p :
xRooNode(
"tmp", *
f, std::shared_ptr<xRooNode>(
nullptr)).
vars()) {
3965 auto h = std::unique_ptr<TH1>(
f->dataHist().createHistogram(parNames
3972 h->SetName(
"statFactor");
3974 h->SetOption(
"blankshape");
3977 auto toMultiply =
this;
3981 f_stat =
dynamic_cast<ParamHistFunc *
>(toMultiply->Multiply(*h).get());
3983 throw std::runtime_error(
"Failed creating stat shapeFactor");
3989 TString prefix =
f->getStringAttribute(
"statPrefix");
3990 if (
value && prefix ==
"") {
3994 while (_p && !(_p->get()->InheritsFrom(
"RooRealSumPdf") || _p->get()->InheritsFrom(
"RooAddPdf") ||
3995 _p->get()->InheritsFrom(
"RooWorkspace") || _p->get()->InheritsFrom(
"RooAddition"))) {
4000 auto newVar = (
value == 0) ? getObject<RooRealVar>(
"1")
4001 : acquire<RooRealVar>(
Form(
"%s_bin%d", prefix.
Data(), bin),
4002 Form(
"%s_bin%d", prefix.
Data(), bin), 1);
4003#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
4008 auto var =
dynamic_cast<RooRealVar *
>(&pSet[bin - 1]);
4010 if (newVar.get() != var) {
4014 for (
int i = 0; i < pSet.
getSize(); i++) {
4016 all.
add(*pSet.
at(i));
4027 if (strcmp(rrv->GetName(),
"1") != 0) {
4028 TString origName = (
f->getStringAttribute(
"origName")) ?
f->getStringAttribute(
"origName") :
GetName();
4030 auto bin_pars =
f->dataHist().get(bin - 1);
4031 auto _binContent =
f->dataHist().weight();
4032 if (
f->getAttribute(
"density")) {
4033 _binContent *=
f->dataHist().binVolume(*bin_pars);
4038 for (
auto &[s, sv] : rrv->stringAttributes()) {
4039 if (s.find(
"sumw_") == 0) {
4041 }
else if (s.find(
"sumw2_") == 0) {
4045 if (sumw2 && sumw2 != std::numeric_limits<double>::infinity()) {
4046 double tau = pow(sumw, 2) / sumw2;
4047 rrv->setError((tau < 1
e-15) ? 1e15 : ( 1. / sqrt(tau)));
4048 rrv->setConstant(
false);
4050 auto _constr =
v.constraints();
4052 if (_constr.empty()) {
4053 rrv->setStringAttribute(
"boundConstraint", _constr.Add(
"poisson").get()->GetName());
4055 auto _glob = _constr.at(0)->obs().at(0)->get<
RooRealVar>();
4058 double _min = tau * (1. - 5. * sqrt(1. / tau));
4059 double _max = tau * (1. + 5. * sqrt(1. / tau));
4060 _glob->setRange(_min, _max);
4062 _constr.at(0)->pp().at(0)->SetBinContent(0, tau);
4063 rrv->setStringAttribute(
"boundConstraint", _constr.at(0)->get()->GetName());
4065 rrv->setRange(std::max((1. - 5. * sqrt(1. / tau)), 1
e-15), 1. + 5. * sqrt(1. / tau));
4068 if (
auto _constr =
v.constraints(); !_constr.empty()) {
4069 v.constraints().Remove(*_constr.at(0));
4074 rrv->setConstant(sumw2 == 0);
4086 auto res =
find(
name, browseResult);
4088 throw std::out_of_range(
name +
" does not exist");
4097 if (
auto _w = get<RooWorkspace>(); _w)
4099 if (
auto a = get<RooAbsArg>();
a &&
GETWS(
a)) {
4110 xRooNode out(
".constraints",
nullptr, *
this);
4113 getConstraint = [&](
const xRooNode &
n,
RooAbsArg &par, std::set<RooAbsPdf *> ignore) {
4115 if (ignore.count(_pdf))
4117 ignore.insert(_pdf);
4123 for (
auto &
c :
n.bins()) {
4124 if (
auto oo = getConstraint(*
c.get(), par, ignore); oo) {
4134 for (
auto p : _ws->allPdfs()) {
4135 if (ignore.count(
static_cast<RooAbsPdf *
>(
p)))
4137 if (
p->dependsOn(par)) {
4138 out.emplace_back(std::make_shared<xRooNode>(par.GetName(), *
p, *
this));
4144 return getConstraint(*
n.fParent.get(), par, ignore);
4146 for (
auto p : o->pdfList()) {
4147 if (ignore.count(
static_cast<RooAbsPdf *
>(
p)))
4149 if (
p->dependsOn(par)) {
4150 out.emplace_back(std::make_shared<xRooNode>(par.GetName(), *
p, *
this));
4156 for (
auto &
p :
vars()) {
4160 if (
v->getAttribute(
"Constant") &&
v != get<RooAbsReal>())
4162 if (
v->getAttribute(
"obs"))
4164 getConstraint(*
this, *
v, {get<RooAbsPdf>()});
4172 auto it = out.std::vector<std::shared_ptr<xRooNode>>
::begin();
4173 while (it != out.std::vector<std::shared_ptr<xRooNode>>
::end()) {
4174 bool removeIt =
false;
4175 for (
auto &
c : out) {
4176 if (
c.get() == it->get())
4180 std::set<std::string> parNames;
4181 std::string _cName =
c->GetName();
4183 parNames.insert(_cName.substr(0, _cName.find(
';')));
4184 _cName = _cName.substr(_cName.find(
';') + 1);
4185 }
while (_cName.find(
';') != std::string::npos);
4186 parNames.insert(_cName);
4187 _cName = it->get()->GetName();
4189 parNames.insert(_cName.substr(0, _cName.find(
';')));
4190 _cName = _cName.substr(_cName.find(
';') + 1);
4191 }
while (_cName.find(
';') != std::string::npos);
4192 parNames.insert(_cName);
4194 for (
auto &
x : parNames) {
4195 if (!_cName.empty())
4199 c->TNamed::SetName(_cName.c_str());
4211 if (get<RooAbsArg>() && get<RooAbsArg>()->isFundamental()) {
4212 for (
auto &o : out) {
4213 o->TNamed::SetName(o->get()->GetName());
4227 sName =
TString(
"factory:") + sName;
4231 if (
auto h = get<TH1>();
h) {
4233 std::map<std::string, std::string> stringAttrs;
4235 auto pos = sOpt2.
Index(
"=");
4236 auto start = sOpt2.
Index(
";") + 1;
4242 stringAttrs[sOpt2(start, pos - start)] = sOpt2(pos + 1,
end - pos - 1);
4248 origName = origName(1, origName.
Length());
4251 newObjName(1, newObjName.
Length());
4257 TString varName =
h->GetXaxis()->GetName();
4258 std::string binningName = newObjName.
Data();
4259 if (
auto pos = varName.Index(
';'); pos != -1) {
4260 binningName = varName(pos + 1, varName.Length());
4261 varName = varName(0, pos);
4264 if (varName ==
"xaxis" &&
4266 if (
auto ax = acquirer.
GetXaxis(); ax) {
4267 varName = ax->GetParent()->GetName();
4269 binningName = ax->GetName();
4270 }
else if (acquirer.
obs().size() == 1)
4271 varName = acquirer.
obs().
at(0)->get()->GetName();
4273 auto x = acquirer.
acquire<
RooRealVar>(varName,
h->GetXaxis()->GetTitle(),
h->GetXaxis()->GetXmin(),
4274 h->GetXaxis()->GetXmax());
4275 if (
x->getMin() >
h->GetXaxis()->GetXmin())
4276 x->setMin(
h->GetXaxis()->GetXmin());
4277 if (
x->getMax() <
h->GetXaxis()->GetXmax())
4278 x->setMax(
h->GetXaxis()->GetXmax());
4279 if (!
x->hasBinning(binningName.c_str())) {
4280 if (
h->GetXaxis()->IsVariableBinSize()) {
4281 x->setBinning(
RooBinning(
h->GetNbinsX(),
h->GetXaxis()->GetXbins()->GetArray()), binningName.c_str());
4284 RooUniformBinning(
h->GetXaxis()->GetXmin(),
h->GetXaxis()->GetXmax(),
h->GetXaxis()->GetNbins()),
4285 binningName.c_str());
4287 x->getBinning(binningName.c_str()).
SetTitle(
h->GetXaxis()->GetTitle());
4288 if (
x->getBinningNames().size() == 2) {
4290 x->setBinning(
x->getBinning(binningName.c_str()));
4294 if (
x->getBinning(binningName.c_str()).numBins() !=
h->GetNbinsX()) {
4295 throw std::runtime_error(
4296 TString::Format(
"binning mismatch for binning %s of %s", binningName.c_str(),
x->GetName()));
4300 std::shared_ptr<RooAbsArg> _f;
4306 for (
auto &[k,
v] : stringAttrs) {
4309 x->setAttribute(
"obs",
true);
4310 }
else if (sOpt2.
Contains(
"shape")) {
4312 for (
int i = 0; i <
x->getBinning(binningName.c_str()).numBins(); i++) {
4313 std::shared_ptr<RooAbsArg> arg;
4314 if (sOpt2.
Contains(
"blankshape")) {
4320 if (
h->GetMinimumStored() != -1111 ||
h->GetMaximumStored() != -1111) {
4322 h->GetBinContent(i + 1),
h->GetMinimumStored(),
4323 h->GetMaximumStored());
4326 h->GetBinContent(i + 1));
4333 auto tmp =
dynamic_cast<RooAbsBinning *
>(
x->getBinningPtr(0)->Clone());
4334 x->setBinning(
x->getBinning(binningName.c_str()));
4336#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
4337 dynamic_cast<ParamHistFunc *
>(_f.get())->_paramSet.setName(
"paramSet");
4340 .setName(
"paramSet");
4342 x->setBinning(*tmp);
4344 for (
auto &[k,
v] : stringAttrs) {
4345 _f->setStringAttribute(k.c_str(),
v.c_str());
4349 binningName.c_str() );
4351 throw std::runtime_error(
"Couldn't make data hist");
4356 f->setAttribute(
"autodensity");
4359 for (
auto &[k,
v] : stringAttrs) {
4360 _f->setStringAttribute(k.c_str(),
v.c_str());
4364 _f->setStringAttribute(
"xvar",
x->GetName());
4365 _f->setStringAttribute(
"binning", binningName.c_str());
4366 if (strcmp(_f->GetName(), origName.
Data()) && !_f->getStringAttribute(
"alias"))
4367 _f->setStringAttribute(
"alias", origName);
4370 xRooNode tmp(
h->GetName(), _f, acquirer);
4372 _f = std::dynamic_pointer_cast<RooAbsArg>(tmp.
fComp);
4375 _f->setStringAttribute(
"xvar",
x->GetName());
4376 _f->setStringAttribute(
"binning", binningName.c_str());
4379 if (strcmp(_f->GetName(), origName.
Data()) && !_f->getStringAttribute(
"alias"))
4380 _f->setStringAttribute(
"alias"