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))
176#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
180#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 24, 00)
184#if ROOT_VERSION_CODE > ROOT_VERSION(6, 37, 00)
214#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
220xRooNode::InteractiveObject *xRooNode::gIntObj =
nullptr;
221std::map<std::string, std::tuple<std::function<
double(
double,
double,
double)>,
bool>> xRooNode::auxFunctions;
222void xRooNode::SetAuxFunction(
const char *title,
const std::function<
double(
double,
double,
double)> &func,
225 auxFunctions[title] = std::make_tuple(func, symmetrize);
244xRooNode::xRooNode(
const char *classname,
const char *
name,
const char *title)
250#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
253 xRooNode(*
w, std::make_shared<xRooNode>()).sterilize();
259 if (
auto a = get<TNamed>();
a)
264xRooNode::xRooNode(
const char *
name,
const std::shared_ptr<TObject> &comp,
const std::shared_ptr<xRooNode> &parent)
265 :
TNamed(
name,
""), fComp(comp), fParent(parent)
275#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
276 fComp = std::make_shared<RooWorkspace>(
"workspace",
name);
281 Error(
"xRooNode",
"Error reading json workspace %s",
name);
286 Error(
"xRooNode",
"json format workspaces available only in ROOT 6.26 onwards");
292 auto _file = std::make_shared<TFile>(
297 auto keys = _file->GetListOfKeys();
299 for (
auto &&k : *keys) {
305#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
306 dynamic_cast<RooWorkspace *>(ws)->_embeddedDataList.Delete();
308 xRooNode(*ws, std::make_shared<xRooNode>()).sterilize();
314 fParent = std::make_shared<xRooNode>(
322 }
else if (pathName.EndsWith(
".root") || pathName.EndsWith(
".json")) {
327 if (
auto _ws = get<RooWorkspace>(); _ws && (!parent || parent->get<
TFile>())) {
340 for (
auto f : *
gROOT->GetListOfFiles()) {
341 if ((
dynamic_cast<TFile *
>(
f)->GetVersion() / 100) > (
gROOT->GetVersionInt() / 100)) {
342 Warning(
"xRooNode",
"There is file open with version %d > current version %d ... results may be wrong",
343 dynamic_cast<TFile *
>(
f)->GetVersion(),
gROOT->GetVersionInt());
348 if (
auto colors =
dynamic_cast<TSeqCollection *
>(_ws->obj(
gROOT->GetListOfColors()->GetName()))) {
352 for (
auto col : *colors) {
353 if (!
gROOT->GetListOfColors()->FindObject(col->GetName())) {
354 gROOT->GetListOfColors()->Add(
gROOT->GetListOfColors()->IsOwner() ? col->Clone() : col);
364 for (
auto &
d : _ws->allData()) {
365 for (
auto &
a : *
d->
get()) {
366 if (
auto v = _ws->var(
a->GetName());
v) {
367 v->setAttribute(
"obs");
368 }
else if (
auto c = _ws->cat(
a->GetName());
c) {
369 c->setAttribute(
"obs");
373 checkCount +=
d->TestBit(1 << 20);
376 if (checkCount == 0 && !_ws->allData().empty())
377 _ws->allData().back()->SetBit(1 << 20,
true);
380 for (
auto s : *_set) {
382 _ws->var(s->GetName())->setStringAttribute(
"nominal",
TString::Format(
"%f",
v->getVal()));
390 if (k ==
"globalObservables" ||
TString(k).
EndsWith(
"_GlobalObservables")) {
393 s->setAttribute(
"obs");
394 s->setAttribute(
"global");
397 const_cast<RooArgSet &
>(
v).setAttribAll(
"obs");
400 s->setAttribute(
"poi");
412 const_cast<RooArgSet &
>(
v).setAttribAll(
"np");
415 if (!_allGlobs.
empty() &&
GETWSSETS(_ws).count(
"globalObservables") == 0) {
416 _ws->defineSet(
"globalObservables", _allGlobs);
421 if (!_ws->allPdfs().empty()) {
422 std::set<RooRealVar *> noErrorPars;
423 std::string parNames;
424 for (
auto &
p :
np()) {
428 if (!
v->hasError()) {
429 noErrorPars.insert(
v);
430 if (!parNames.empty())
432 parNames +=
v->GetName();
435 if (!noErrorPars.empty()) {
437 "Inferring initial errors of %d parameters (%s%s) (give all nuisance parameters an error to avoid "
439 int(noErrorPars.size()), (*noErrorPars.begin())->GetName(), (noErrorPars.size() > 1) ?
",..." :
"");
440 if (
gEnv->
GetValue(
"XRooFit.SkipInitParErrorInference",
false)) {
441 Warning(
"xRooNode",
"Skipping because XRooFit.SkipInitParErrorInference=true. This is expert-only, you "
442 "should fix your workspaces!");
446 for (
auto &
a : *this) {
447 if (noErrorPars.empty()) {
450 if (
a->fFolder ==
"!pdfs") {
452 auto fr =
a->floats().reduced(parNames).fitResult(
"prefit");
454 std::set<RooRealVar *> foundPars;
455 for (
auto &
v : noErrorPars) {
456 if (
auto arg =
dynamic_cast<RooRealVar *
>(_fr->floatParsFinal().find(
v->GetName()));
457 arg && arg->hasError()) {
458 v->setError(arg->getError());
462 for (
auto &
v : foundPars) {
463 noErrorPars.erase(
v);
475 if (strlen(GetTitle()) == 0) {
492 (comp.InheritsFrom(
"RooAbsArg") && dynamic_cast<const
RooAbsArg *>(&comp)->getStringAttribute(
"alias"))
493 ? dynamic_cast<const
RooAbsArg *>(&comp)->getStringAttribute(
"alias")
502 if (
auto a = std::dynamic_pointer_cast<RooAbsArg>(comp);
a &&
a->getStringAttribute(
"alias"))
503 return a->getStringAttribute(
"alias");
505 return comp->GetName();
518 bool isBool = (
v ==
"TRUE" ||
v ==
"FALSE");
519 if (
auto a = get<RooAbsArg>();
a) {
520 if (
value ==
nullptr ||
v ==
"NULLPTR") {
521 if (
a->getAttribute(
name))
522 a->setAttribute(
name,
false);
523 else if (
a->getStringAttribute(
name))
524 a->setStringAttribute(
name,
nullptr);
527 a->setAttribute(
name, (
v ==
"TRUE"));
538 for (
auto a : *
gROOT->GetListOfBrowsers()) {
541 if (
auto bi =
dynamic_cast<TRootBrowser *
>(
b->GetBrowserImp())) {
542 if (
auto fb =
dynamic_cast<TGFileBrowser *
>(bi->GetActBrowser())) {
559 if (
auto o = get<RooAbsReal>(); o) {
560 if (o->isSelectedComp() && !val) {
563 o->setAttribute(
"hidden");
564 }
else if (!o->isSelectedComp() && !val) {
569 o->setAttribute(
"hidden",
false);
572 item->CheckItem(!o->getAttribute(
"hidden"));
573 if (o->isSelectedComp()) {
576 item->SetColor(
kGray);
581 if (
auto o =
get(); o) {
583 o->SetBit(1 << 20, val);
584 if (
auto fr = get<RooFitResult>(); fr) {
585 if (
auto _ws =
ws(); _ws) {
588 if (fr->numStatusHistory() && !_ws->genobj(fr->GetName())) {
590 if (
auto wfr =
dynamic_cast<RooFitResult *
>(_ws->genobj(fr->GetName()))) {
595 _allVars = fr->floatParsFinal();
596 _allVars = fr->constPars();
597 for (
auto &i : fr->floatParsInit()) {
603 for (
auto oo : _ws->allGenericObjects()) {
604 if (
auto ffr =
dynamic_cast<RooFitResult *
>(oo); ffr && ffr != fr) {
605 ffr->ResetBit(1 << 20);
609 _ws->allVars() = fr->floatParsInit();
613 for (
auto a : *
gROOT->GetListOfBrowsers()) {
624 if (
auto first =
p->GetParent()->GetFirstChild()) {
626 if (first->HasCheckBox()) {
627 auto _obj =
static_cast<xRooNode *
>(first->GetUserData());
628 first->CheckItem(_obj->get() && _obj->get()->TestBit(1 << 20));
630 }
while ((first = first->GetNextSibling()));
635 if (
auto bi =
dynamic_cast<TRootBrowser *
>(
b->GetBrowserImp())) {
636 if (
auto fb =
dynamic_cast<TGFileBrowser *
>(bi->GetActBrowser())) {
642 if (
auto first = i->GetFirstChild()) {
644 if (first->IsOpen() &&
645 (
TString(first->GetText()) ==
"poi" ||
TString(first->GetText()) ==
"np")) {
646 fb->DoubleClicked(first, 0);
649 }
while ((first = first->GetNextSibling()));
667 static bool blockBrowse =
false;
671 auto b2 =
dynamic_cast<TBrowser *
>(
gROOT->GetListOfBrowsers()->Last());
672 if (!b2 || !b2->GetBrowserImp()) {
679 b2 =
new TBrowser(
"nodeBrowser",
this,
"RooFit Browser");
681 }
else if (strcmp(b2->GetName(),
"nodeBrowser") == 0) {
683 b2->BrowseObject(
this);
689 _b->GotoDir(
nullptr);
700 if (
auto first = item->GetFirstChild()) {
702 if (first->HasCheckBox()) {
703 auto _obj =
static_cast<xRooNode *
>(first->GetUserData());
704 first->CheckItem(_obj->get() &&
705 (_obj->get()->TestBit(1 << 20) ||
708 }
while ((first = first->GetNextSibling()));
719 if (
auto _fr = get<RooFitResult>(); _fr &&
fBrowsables.empty()) {
721 fBrowsables.push_back(std::make_shared<xRooNode>(
".Draw(\"pull\")",
nullptr, *
this));
722 fBrowsables.push_back(std::make_shared<xRooNode>(
".Draw(\"corr10colztext\")",
nullptr, *
this));
723 if (std::unique_ptr<RooAbsCollection>(_fr->floatParsFinal().selectByAttrib(
"poi",
true))->size() == 1) {
724 fBrowsables.push_back(std::make_shared<xRooNode>(
".Draw(\"impact\")",
nullptr, *
this));
730 if (
auto s = get<TStyle>()) {
731 s->SetFillAttributes();
738 Draw(
b->GetDrawOption());
740 }
catch (
const std::exception &
e) {
743 (
gROOT->GetListOfBrowsers()->At(0))
746 "Exception",
e.what(),
751 bool hasFolders =
false;
753 for (
auto &
c : *
this) {
754 if (!
c->fFolder.empty()) {
763 auto _folders =
find(
".folders");
765 _folders = emplace_back(std::make_shared<xRooNode>(
".folders",
nullptr, *
this));
768 for (
auto &
v : *
this) {
769 if (!
v->fFolder.empty() && !_folders->find(
v->fFolder,
false)) {
770 _folders->emplace_back(std::make_shared<xRooNode>(
v->fFolder.c_str(),
nullptr, *
this));
774 for (
auto &
v : *_folders) {
777 _name = _name(1, _name.
Length());
778 b->Add(
v.get(), _name);
782 for (
auto &
v : *
this) {
783 if (hasFolders && !
v->fFolder.empty())
785 if (strcmp(
v->GetName(),
".folders") == 0)
789 if (_fr && ((_fr->status() == 0 && _fr->numStatusHistory() == 0) || (_fr->floatParsFinal().empty()))) {
793 if (
v->get<
RooAbsPdf>() && get<RooSimultaneous>())
797 _name = _name(strlen(
v->get()->ClassName()) + 2, _name.
Length());
805 :
v->get()->GetName());
807 }
else if (
v->get() && !
v->get<
TFile>() && !
TString(
v->GetName()).BeginsWith(
'/'))
809 if (
auto _type =
v->GetNodeType(); strlen(_type)) {
817 for (
size_t i = 0; i < fv->dependents().
size(); i++) {
823 for (
size_t i = 0; i < gv->dependents().
size(); i++) {
829 std::set<int> interpCodes;
830 for (
auto &
c : pi->interpolationCodes())
831 interpCodes.insert(
c);
832 if (interpCodes.size() == 1) {
837 std::set<int> interpCodes;
838 for (
auto &
c : fiv->interpolationCodes())
839 interpCodes.insert(
c == 4 ? 5 :
c);
840 if (interpCodes.size() == 1) {
846 TString nameSave(
v->TNamed::GetName());
847 TString titleSave(
v->TNamed::GetTitle());
848 if (
auto o =
v->get(); o)
849 v->TNamed::SetNameTitle(o->GetName(), o->ClassName());
850 b->Add(
v.get(), _name, _checked);
851 if (
auto o =
v->get(); o)
852 v->TNamed::SetNameTitle(nameSave, titleSave);
853 if (_checked != -1) {
854 dynamic_cast<TQObject *
>(
b->GetBrowserImp())
855 ->Connect(
"Checked(TObject *, bool)",
ClassName(),
v.get(),
"Checked(TObject *, bool)");
858 if (_fr->status() || _fr->covQual() != 3) {
859 v->GetTreeItem(
b)->SetColor((_fr->numStatusHistory() && !_fr->floatParsFinal().empty()) ?
kRed :
kBlue);
860 }
else if (_fr->numStatusHistory() == 0) {
861 v->GetTreeItem(
b)->SetColor(
kGray);
864 if ((
v->fFolder ==
"!np" ||
v->fFolder ==
"!poi")) {
866 v->GetTreeItem(
b)->SetColor(
kGray);
868 v->GetTreeItem(
b)->ClearColor();
872 if (
auto fits = _htr->GetFitInfo()) {
873 for (
int i = 0; i < fits->numEntries(); i++) {
875 if (fits->get(i)->getCatIndex(
"type") != 5 && fits->get(i)->getRealValue(
"status") != 0) {
876 v->GetTreeItem(
b)->SetColor(
kRed);
881 v->GetTreeItem(
b)->SetColor(
kBlue);
908 if (_name ==
".memory")
910 TString nameSave(
v->TNamed::GetName());
911 TString titleSave(
v->TNamed::GetTitle());
912 if (
auto o =
v->get(); o)
913 v->TNamed::SetNameTitle(o->GetName(), o->ClassName());
914 b->Add(
v.get(), _name, -1);
915 if (
auto o =
v->get(); o)
916 v->TNamed::SetNameTitle(nameSave, titleSave);
919 b->SetSelected(
this);
932 auto v = std::make_shared<xRooNode>(
vars());
943 if (strcmp(
b->GetName(),
".vars") == 0)
966 if (
auto v = var();
v)
967 return v->getBinWidth(bin - 1, GetName());
972 if (
auto v = rvar();
v) {
973 return (bin ==
v->getBinning(GetName()).numBins() + 1) ?
v->getBinning(GetName()).binHigh(bin - 2)
974 :
v->getBinning(GetName()).binLow(bin - 1);
980 if (
auto v = rvar();
v)
981 return (bin == 0) ?
v->getBinning(GetName()).binLow(bin) :
v->getBinning(GetName()).binHigh(bin - 1);
987 return (binning() && strlen(binning()->GetTitle())) ? binning()->GetTitle() : GetParent()->GetTitle();
994 dynamic_cast<TNamed *
>(GetParent())->SetTitle(title);
998 void Set(
Int_t nbins,
const double *xbins)
override
1001 v->setBinning(
RooBinning(nbins, xbins), GetName());
1006 std::vector<double> bins(nbins + 1);
1007 for (
int i = 0; i <= nbins; i++)
1008 bins.at(i) = xbins[i];
1009 return Set(nbins, &bins[0]);
1032 if (
auto _owned =
find(
".memory"); _owned) {
1033 for (
auto &o : *_owned) {
1034 if (
name == o->GetName()) {
1035 if (
type.empty() || o->get()->InheritsFrom(
type.c_str()))
1044 while (!_provider && _parent) {
1045 _provider = _parent->fProvider;
1046 _parent = _parent->fParent;
1049 return _provider->getObject(
name,
type);
1052 std::shared_ptr<TObject> out;
1053 if (
auto arg =
ws()->arg(
name.c_str()); arg) {
1054 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
1055 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
1060 if (
auto arg =
ws()->
data(
name.c_str()); arg) {
1061 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
1062 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
1067 if (
auto arg =
ws()->genobj(
name.c_str()); arg) {
1068 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
1069 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
1074 if (
auto arg =
ws()->embeddedData(
name.c_str()); arg) {
1075 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
1076 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
1082 auto _tmp = std::shared_ptr<TObject>(arg, [](
TObject *) {});
1083 if (!
type.empty() && arg->InheritsFrom(
type.c_str()))
1090 if (
auto arg = get<RooAbsArg>()) {
1093 arg->treeNodeServerList(&nodes);
1094 if (
auto server = nodes.
find(
name.c_str())) {
1095 return std::shared_ptr<TObject>(server, [](
TObject *) {});
1106 cat && cat->numTypes() !=
fXAxis->GetNbins()) {
1113 if (
auto a = get<RooAbsArg>();
a &&
a->isFundamental())
1118 auto o = get<RooAbsReal>();
1122 if (
auto xName = o->getStringAttribute(
"xvar"); xName) {
1132 (o->dependsOn(*
dynamic_cast<RooAbsArg *
>(_parentX->GetParent())) ||
vars().empty())) {
1134 }
else if (
auto _obs =
obs(); !_obs.empty()) {
1135 for (
auto &
v : _obs) {
1144 }
else if (
auto _pars =
pars(); !_pars.empty()) {
1145 for (
auto &
v : _pars) {
1171 TString binningName = o->getStringAttribute(
"binning");
1172 auto _bnames =
x->getBinningNames();
1173 bool hasBinning =
false;
1174 for (
auto &
b : _bnames) {
1175 if (
b == binningName) {
1183 Warning(
"GetXaxis",
"Binning %s not defined on %s - clearing", binningName.
Data(),
1185 o->setStringAttribute(
"binning",
nullptr);
1189 if (binningName ==
"" && o !=
dynamic_cast<TObject *
>(
x)) {
1191 auto __bnames =
x->getBinningNames();
1192 for (
auto &
b : __bnames) {
1195 if (
b == o->GetName()) {
1196 binningName = o->GetName();
1200 if (binningName ==
"") {
1206 (std::list<double> *)(
nullptr),
1208 ? o->binBoundaries(*
dynamic_cast<RooAbsRealLValue *
>(
x), -std::numeric_limits<double>::infinity(),
1209 std::numeric_limits<double>::infinity())
1212 std::vector<double> _bins;
1213 for (
auto &
b : *
bins) {
1214 if (_bins.empty() || std::abs(_bins.back() -
b) > 1
e-5 * _bins.back())
1217 fXAxis = std::make_shared<Axis2>(_bins.size() - 1, &_bins[0]);
1219 if (
auto _v =
dynamic_cast<RooRealVar *
>(
x); _v) {
1220 _v->setBinning(
RooBinning(_bins.size() - 1, &_bins[0], o->GetName()), o->
GetName());
1221 _v->getBinning(o->GetName())
1226 binningName = o->GetName();
1228 }
else if (_parentX) {
1230 binningName = _parentX->GetName();
1237 if (
r->getBinning(binningName).isUniform()) {
1238 fXAxis = std::make_shared<Axis2>(
x->numBins(binningName),
r->getMin(binningName),
r->getMax(binningName));
1240 fXAxis = std::make_shared<Axis2>(
x->numBins(binningName),
r->getBinning(binningName).array());
1242 }
else if (
auto cat =
dynamic_cast<RooCategory *
>(
x)) {
1243 std::vector<double>
bins = {};
1244 for (
int i = 0; i <=
x->numBins(binningName); i++)
1246 fXAxis = std::make_shared<Axis2>(
x->numBins(binningName), &
bins[0]);
1249 std::map<int, std::string> cats;
1250 for (
auto &
c : *cat) {
1251 if (cat->isStateInRange(binningName,
c.first.c_str())) {
1252 cats[
c.second] =
c.first;
1255 for (
auto &[
_, label] : cats) {
1256 fXAxis->SetBinLabel(i++, label.c_str());
1261 fXAxis->SetName(binningName);
1268 if (
auto o =
get(); o) {
1269 if (o->InheritsFrom(
"RooWorkspace"))
1271 if (o->InheritsFrom(
"RooAbsData"))
1273 if (o->InheritsFrom(
"RooSimultaneous"))
1276 if (o->InheritsFrom(
"RooProdPdf"))
1278 if (o->InheritsFrom(
"RooRealSumPdf") || o->InheritsFrom(
"RooAddPdf"))
1281 if (o->InheritsFrom(
"RooFitResult")) {
1282 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitRooFitResult",
true)) {
1283 gClient->GetMimeTypeList()->AddType(
"xRooFitRooFitResult",
"xRooFitRooFitResult",
"package.xpm",
1284 "package.xpm",
"->Browse()");
1286 return "xRooFitRooFitResult";
1288 if (o->InheritsFrom(
"RooRealVar") || o->InheritsFrom(
"RooCategory")) {
1289 if (get<RooAbsArg>()->getAttribute(
"obs")) {
1290 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitObs",
true)) {
1291 gClient->GetMimeTypeList()->AddType(
"xRooFitObs",
"xRooFitObs",
"x_pic.xpm",
"x_pic.xpm",
"->Browse()");
1293 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitGlobs",
true)) {
1294 gClient->GetMimeTypeList()->AddType(
"xRooFitGlobs",
"xRooFitGlobs",
"z_pic.xpm",
"z_pic.xpm",
1297 return (get<RooAbsArg>()->getAttribute(
"global") ?
"xRooFitGlobs" :
"xRooFitObs");
1301 if (o->InheritsFrom(
"TStyle")) {
1302 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitTStyle",
true)) {
1303 gClient->GetMimeTypeList()->AddType(
"xRooFitTStyle",
"xRooFitTStyle",
"bld_colorselect.xpm",
1304 "bld_colorselect.xpm",
"->Browse()");
1306 return "xRooFitTStyle";
1308 if (o->InheritsFrom(
"RooConstVar")) {
1314 return "TMethodBrowsable-leaf";
1316 if (o->InheritsFrom(
"RooStats::HypoTestInverterResult")) {
1317 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitScanStyle",
true)) {
1318 gClient->GetMimeTypeList()->AddType(
"xRooFitScanStyle",
"xRooFitScanStyle",
"f2_s.xpm",
"f2_s.xpm",
1321 return "xRooFitScanStyle";
1323 if (o->InheritsFrom(
"RooStats::HypoTestResult")) {
1324 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitTestStyle",
true)) {
1325 gClient->GetMimeTypeList()->AddType(
"xRooFitTestStyle",
"xRooFitTestStyle",
"diamond.xpm",
"diamond.xpm",
1328 return "xRooFitTestStyle";
1330 if (o->InheritsFrom(
"RooStats::HistFactory::FlexibleInterpVar"))
1331 return "TBranchElement-folder";
1332 if (o->InheritsFrom(
"RooAbsPdf")) {
1333 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitPDFStyle",
true)) {
1334 gClient->GetMimeTypeList()->AddType(
"xRooFitPDFStyle",
"xRooFitPDFStyle",
"pdf.xpm",
"pdf.xpm",
1337 return "xRooFitPDFStyle";
1339 if (o->InheritsFrom(
"RooStats::ModelConfig")) {
1340 if (!
gClient->GetMimeTypeList()->GetIcon(
"xRooFitMCStyle",
true)) {
1341 gClient->GetMimeTypeList()->AddType(
"xRooFitMCStyle",
"xRooFitMCStyle",
"app_t.xpm",
"app_t.xpm",
1344 return "xRooFitMCStyle";
1348 _ax && (
a->isBinnedDistribution(*
dynamic_cast<RooAbsArg *
>(_ax->GetParent())) ||
1350 std::unique_ptr<std::list<double>>(
a->binBoundaries(
1351 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
1352 std::numeric_limits<double>::infinity()))))) {
1357 return o->ClassName();
1367 if (
auto rrs = get<RooRealSumPdf>(); rrs) {
1369 if (rrs->getAttribute(
"BinnedLikelihood"))
1370 return "BinnedLikelihood";
1373 if (o->InheritsFrom(
"RooStats::HistFactory::FlexibleInterpVar"))
1375 if (o->InheritsFrom(
"PiecewiseInterpolation")) {
1377 bool isHisto =
true;
1387 return (
dynamic_cast<RooAbsArg *
>(o)->getAttribute(
"density")) ?
"VariedDensity" :
"Varied";
1390 if (o->InheritsFrom(
"RooHistFunc"))
1391 return (
dynamic_cast<RooAbsArg *
>(o)->getAttribute(
"density")) ?
"SimpleDensity" :
"Simple";
1392 if (o->InheritsFrom(
"RooBinWidthFunction"))
1394 if (o->InheritsFrom(
"ParamHistFunc"))
1396 if (o->InheritsFrom(
"RooRealVar"))
1398 if (o->InheritsFrom(
"RooConstVar"))
1406 xRooNode out(
".coords",
nullptr, *
this);
1408 auto _p = std::shared_ptr<xRooNode>(
const_cast<xRooNode *
>(
this), [](
xRooNode *) {});
1438 if (
auto pos = pName.
Index(
'='); pos != -1) {
1439 if (pos > 0 && pName(pos - 1) ==
'<') {
1442 pName = pName(pos + 1, pName.
Length());
1444 pName = pName(0, pName.
Index(
'<'));
1447 _obs->setVal((high + low) / 2.);
1448 static_cast<RooRealVar *
>(_obs.get())->setRange(
"coordRange", low, high);
1450 "coordRange",
"coordRange");
1452 out.emplace_back(std::make_shared<xRooNode>(_obs->GetName(), _obs, _p));
1457 }
else if (
auto _obs = _p->getObject<
RooAbsArg>(pName(0, pos)); _obs) {
1460 _cat->setLabel(pName(pos + 1, pName.
Length()));
1461 }
else if (
auto _var =
dynamic_cast<RooAbsRealLValue *
>(_obs.get()); _var) {
1465 out.emplace_back(std::make_shared<xRooNode>(_obs->GetName(), _obs, _p));
1467 throw std::runtime_error(
"Unknown observable, could not find");
1479 }
catch (
const std::exception &
e) {
1488 }
catch (
const std::exception &
e) {
1497 if (strcmp(
GetName(),
".poi") == 0) {
1503 throw std::runtime_error(
TString::Format(
"%s is not a poi", toRemove.GetName()));
1505 toRemove.get<
RooAbsArg>()->setAttribute(
"poi",
false);
1508 }
else if (strcmp(
GetName(),
".factors") == 0 || strcmp(
GetName(),
".constraints") == 0 ||
1509 strcmp(
GetName(),
".components") == 0) {
1515 pdf =
p->pdfList().find(
child.GetName());
1518 auto i =
p->pdfList().index(*pdf);
1520#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
1521 const_cast<RooArgList &
>(
p->pdfList()).remove(*pdf);
1522#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
1523 p->_pdfNSetList.erase(
p->_pdfNSetList.begin() + i);
1525 auto nset =
p->_pdfNSetList.At(i);
1526 p->_pdfNSetList.Remove(nset);
1529 if (
p->_extendedIndex == i)
1530 p->_extendedIndex = -1;
1531 else if (
p->_extendedIndex > i)
1532 p->_extendedIndex--;
1544 arg = p2->components().find(
child.GetName());
1548#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
1549 p2->_compRSet.remove(*arg);
1551 const_cast<RooArgList &
>(p2->realComponents()).remove(*arg);
1553 p2->removeServer(*arg,
true);
1558 bool removed =
false;
1561 c->constraints().Remove(toRemove);
1563 }
catch (std::runtime_error &) {
1573 arg = p4->funcList().find(
child.GetName());
1577 auto idx = p4->funcList().index(arg);
1581 const_cast<RooArgList &
>(p4->funcList()).remove(*arg);
1582 p4->removeServer(*arg,
true);
1584 std::vector<RooAbsArg *> _coefs;
1585 for (
size_t ii = 0; ii < const_cast<RooArgList &>(p4->coefList()).size(); ii++) {
1586 if (ii !=
size_t(idx))
1587 _coefs.push_back(
const_cast<RooArgList &
>(p4->coefList()).
at(ii));
1589 const_cast<RooArgList &
>(p4->coefList()).removeAll();
1590 for (
auto &
a : _coefs)
1601 arg = p5->pdfList().find(
child.GetName());
1605 auto idx = p5->pdfList().index(arg);
1609 const_cast<RooArgList &
>(p5->pdfList()).remove(*arg);
1610 p5->removeServer(*arg,
true);
1612 std::vector<RooAbsArg *> _coefs;
1613 for (
size_t ii = 0; ii < const_cast<RooArgList &>(p5->coefList()).size(); ii++) {
1614 if (ii !=
size_t(idx))
1615 _coefs.push_back(
const_cast<RooArgList &
>(p5->coefList()).
at(ii));
1617 const_cast<RooArgList &
>(p5->coefList()).removeAll();
1618 for (
auto &
a : _coefs)
1629 arg = p6->list().find(
child.GetName());
1633 const_cast<RooArgList &
>(p6->list()).remove(*arg);
1634 p6->removeServer(*arg,
true);
1640 if (
auto w = get<RooWorkspace>();
w) {
1642 auto arg =
w->components().find(
child.GetName());
1649 if (arg->hasClients()) {
1650 throw std::runtime_error(
1651 TString::Format(
"Cannot remove %s from workspace %s, because it has dependencies - first remove from those",
1654 const_cast<RooArgSet &
>(
w->components()).remove(*arg);
1657 }
else if (get<RooProduct>() || get<RooProdPdf>()) {
1659 }
else if (get<RooRealSumPdf>() || get<RooAddPdf>() || get<RooAddition>()) {
1663 throw std::runtime_error(
"Removal not implemented for object type " +
1673 ~AutoUpdater() {
n.browse(); }
1676 AutoUpdater xxx(*
this);
1679 bool considerType(sOpt ==
"+");
1695 if (strcmp(
GetName(),
".factors") == 0) {
1698 }
else if (strcmp(
GetName(),
".components") == 0) {
1701 }
else if (strcmp(
GetName(),
".variations") == 0) {
1704 }
else if (strcmp(
GetName(),
".constraints") == 0) {
1710 }
else if ((strcmp(
GetName(),
".globs") == 0)) {
1713 out->setAttribute(
"obs");
1714 out->setAttribute(
"global");
1717 throw std::runtime_error(
"Failed to add global observable");
1718 }
else if ((strcmp(
GetName(),
".poi") == 0)) {
1721 out->setAttribute(
"poi");
1729 throw std::runtime_error(
"Failed to add parameter of interest");
1736 }
else if (strcmp(
GetName(),
".datasets()") == 0) {
1739 if (
find(_data->GetName())) {
1740 throw std::runtime_error(
TString::Format(
"Cannot add dataset %s, already exists for %s. If intending to "
1741 "combine datasets, please add directly to dataset",
1751 throw std::runtime_error(
1752 "Datasets can only be created for pdfs or workspaces (except if generated dataset, then must be pdf)");
1755 if (sOpt ==
"asimov" || sOpt ==
"toy") {
1757 auto _fr =
fParent->fitResult();
1758 if (strlen(_fr->GetName()) == 0) {
1761 auto ds =
fParent->generate(_fr, sOpt ==
"asimov");
1762 if (strlen(
child.GetName())) {
1763 ds.SetName(
child.GetName());
1773 }
else if (!_ws->obj(_fr->GetName())) {
1779 auto parentObs =
fParent->obs();
1780 auto _obs = parentObs.argList();
1782 std::unique_ptr<RooAbsCollection> _globs(_obs.selectByAttrib(
"global",
true));
1784 _obs.remove(*_globs);
1790 _obs.add(*
dynamic_cast<RooAbsArg *
>(ax->GetParent()));
1793 if (
auto _d = _ws->data(
child.GetName()); _d) {
1796 l.remove(*_d->get(),
true,
true);
1800 throw std::runtime_error(
"Cannot extend dataset with new columns");
1811 if (
auto __d = _ws->data(
child.GetName()))
1812 __d->SetBit(1 << 20, _ws->allData().size() == 1);
1820 auto out = std::shared_ptr<TObject>(_ws->data(
child.GetName()), [](
TObject *) {});
1829 throw std::runtime_error(
"Cannot create dataset");
1834 throw std::runtime_error(
"Cannot add to null object with no parentage");
1836 auto _ref = emplace_back(std::shared_ptr<xRooNode>(&
const_cast<xRooNode &
>(
child), [](
TObject *) {}));
1841 std::rethrow_exception(std::current_exception());
1846 throw std::runtime_error(
"No object");
1850 if (
auto p = get<RooAbsData>();
p) {
1852 bb->Add(
child, opt);
1856 throw std::runtime_error(
"Can only add datasets to a dataset");
1861 auto _globs =
globs();
1862 for (
auto &glob :
child.globs()) {
1863 if (
auto g = _globs.find(glob->GetName()); !
g) {
1865 }
else if (
g->GetContent() != glob->GetContent()) {
1866 Warning(
"Add",
"Global observable %s=%g in dataset %s mismatches %s value %g ... ignoring latter",
1867 g->GetName(),
g->GetContent(),
GetName(),
child.GetName(), glob->GetContent());
1871 if (
auto _dglobs =
p->getGlobalObservables()) {
1874 for (
auto g : _globs)
1877 p->setGlobalObservables(globsToAdd);
1881 std::set<std::pair<RooAbsCategory *, RooCategory *>> cats;
1883 for (
auto col : *_data->get()) {
1884 if (!
p->get()->contains(*col)) {
1885 ds->addColumn(*col);
1890 throw std::runtime_error(
1891 TString::Format(
"unexpected type for regular observable: %s", col->GetName()));
1893 bool iMatches =
true;
1894 for (
const auto &nameIdx : *
c) {
1895 if (!
c2->hasLabel(nameIdx.first) && !
c2->hasIndex(nameIdx.second)) {
1897 c2->defineType(nameIdx.first, nameIdx.second);
1898 }
else if (
c2->lookupIndex(nameIdx.first) != nameIdx.second) {
1904 cats.insert({
c,
c2});
1911 for (
int i = 0; i < _data->numEntries(); i++) {
1912 auto row = _data->get(i);
1913 auto w = _data->weight();
1914 ds->get()->assign(*row);
1915 for (
auto [
c,
c2] : cats) {
1916 c2->setLabel(row->getCatLabel(
c->GetName()));
1918 ds->add(*ds->get(),
w);
1922 ds->SetTitle(
TString(ds->GetTitle()) +
" + " + _data->GetTitle());
1927 if (
auto _ds =
dynamic_cast<RooDataSet *
>(
p); _arg && _ds) {
1929 _ds->addColumn(*_arg);
1935 throw std::runtime_error(
"Can only add histogram or var/expr or dataset to data");
1939 throw std::runtime_error(
"Could not find pdf");
1940 auto _ax = _pdf->GetXaxis();
1942 throw std::runtime_error(
"Cannot determine binning to add data");
1951 l.remove(*
p->get(),
true,
true);
1955 throw std::runtime_error(
"Cannot extend dataset with new columns");
1962 for (
auto &o :
obs) {
1964 if (
auto dv =
dynamic_cast<RooRealVar *
>(
p->get()->find(
v->GetName())); dv) {
1965 if (
v->getMin() < dv->getMin())
1966 dv->setMin(
v->getMin());
1967 if (
v->getMax() > dv->getMax())
1968 dv->setMax(
v->getMax());
1971 if (
auto dc =
dynamic_cast<RooCategory *
>(
p->get()->find(
c->GetName())); dc) {
1972 for (
const auto &nameIdx : *
c) {
1973 if (!dc->hasLabel(nameIdx.first)) {
1974 dc->defineType(nameIdx.first, nameIdx.second);
1981 for (
int i = 1; i <= _h->GetNbinsX(); i++) {
1983 if (!_h->GetXaxis()->GetBinLabel(i)) {
1984 throw std::runtime_error(
1985 TString::Format(
"Categorical observable %s requires bin labels", _ax->GetParent()->GetName()));
1986 }
else if (!cat->hasLabel(_h->GetXaxis()->GetBinLabel(i))) {
1987 throw std::runtime_error(
TString::Format(
"Categorical observable %s does not have label %s",
1988 _ax->GetParent()->GetName(), _h->GetXaxis()->GetBinLabel(i)));
1990 cat->setLabel(_h->GetXaxis()->GetBinLabel(i));
1993 dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent())->setVal(_h->GetBinCenter(i));
1995 p->add(
obs, _h->GetBinContent(i));
2001 if (
auto p = get<RooAddPdf>();
p) {
2002 auto cc =
child.fComp;
2004 child.convertForAcquisition(*
this, sOpt);
2008 auto _pdf = std::dynamic_pointer_cast<RooAbsPdf>(out);
2010 throw std::runtime_error(
"Something went wrong with pdf acquisition");
2017 if (
auto _boundaries = std::unique_ptr<std::list<double>>(_p->binBoundaries(
2018 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
2019 std::numeric_limits<double>::infinity()));
2020 !_boundaries && _ax->GetNbins() > 0) {
2021#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 24, 00)
2022 Warning(
"Add",
"Adding unbinned pdf %s to binned %s - will wrap with RooBinSamplingPdf(...)",
2024 _p = acquireNew<RooBinSamplingPdf>(
TString::Format(
"%s_binned", _p->GetName()), _p->GetTitle(),
2026 _p->setStringAttribute(
"alias", std::dynamic_pointer_cast<RooAbsArg>(out)->getStringAttribute(
"alias"));
2027 if (!_p->getStringAttribute(
"alias"))
2028 _p->setStringAttribute(
"alias", out->GetName());
2030 throw std::runtime_error(
2031 "unsupported addition of unbinned pdf to binned model - please upgrade to at least ROOT 6.24");
2037 if (!(_pdf->canBeExtended() &&
p->coefList().empty())) {
2041 if (_pdf->canBeExtended()) {
2043 std::cout <<
" warning " << _pdf->GetName() <<
" wont be correctly normalized" << std::endl;
2047 .add(*acquireNew<RooExtendedBinding>(
TString::Format(
"%s_extBind", _pdf->GetName()),
2053 for (
auto i =
p->coefList().size(); i <
p->pdfList().size(); i++) {
2055 .add(*acquireNew<RooExtendedBinding>(
2058 *
static_cast<RooAbsPdf *
>(
p->pdfList().at(i))));
2061 const_cast<RooArgList &
>(
p->coefList()).add(*acquire2<RooAbsArg, RooRealVar>(
"1",
"1", 1));
2064 *
reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(
p) +
2066 *
reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(
p) +
2069 const_cast<RooArgList &
>(
p->pdfList()).add(*_pdf);
2073 (!
child.get() && getObject<RooAbsReal>(
child.GetName()))) &&
2076 bool tooMany(
false);
2089 }
else if (!tooMany) {
2094 _sumpdf.get<
RooAbsArg>()->setStringAttribute(
"alias",
"samples");
2095 return _sumpdf.Add(
child);
2100 if (
auto p = get<RooRealSumPdf>();
p) {
2101 std::shared_ptr<TObject> out;
2102 auto cc =
child.fComp;
2103 bool isConverted = (cc !=
child.convertForAcquisition(*
this, sOpt));
2106 if (std::dynamic_pointer_cast<TH1>(cc) && !
TString(cc->GetOption()).
Contains(
"nostyle")) {
2107 xRooNode(out, *
this).styles(cc.get());
2110 if (!
child.fComp && getObject<RooAbsReal>(
child.GetName())) {
2111 Info(
"Add",
"Adding existing function %s to %s",
child.GetName(),
p->
GetName());
2112 out = getObject<RooAbsReal>(
child.GetName());
2115 if (!out && !
child.fComp) {
2116 std::shared_ptr<RooAbsArg> _func;
2124 std::unique_ptr<TH1D>
h;
2127 h = std::make_unique<TH1D>(
child.GetName(),
child.GetTitle(), _ax->GetNbins(),
2128 _ax->binning()->array());
2130 h->GetXaxis()->SetName(
TString::Format(
"%s;%s", _ax->GetParent()->GetName(), _ax->GetName()));
2132 _func = std::dynamic_pointer_cast<RooAbsArg>(
acquire(
xRooNode(*h).convertForAcquisition(*
this)));
2133 }
else if (_obs.size() == 1) {
2137 TString binningName =
p->getStringAttribute(
"binning");
2138 for (
auto &
b : _bnames) {
2144 std::unique_ptr<TH1D>
h;
2147 h = std::make_unique<TH1D>(
child.GetName(),
child.GetTitle(), _x->numBins(binningName),
2148 _x->getBinningPtr(binningName)->array());
2150 h->GetXaxis()->SetName(
2153 _func = std::dynamic_pointer_cast<RooAbsArg>(
acquire(
xRooNode(*h).convertForAcquisition(*
this)));
2154 Info(
"Add",
"Created SimpleDensity factor %s (xaxis=%s) for %s", _func->GetName(), _obs.at(0)->GetName(),
2157 throw std::runtime_error(
"Unsupported creation of new component in SumPdf for this many obs");
2163 _func->setStringAttribute(
"alias",
child.GetName());
2167 if (
auto _f = std::dynamic_pointer_cast<RooHistFunc>(
2171 _f->setAttribute(
"density");
2172 if (_f->getAttribute(
"autodensity")) {
2174 for (
int i = 0; i < _f->dataHist().numEntries(); i++) {
2175 auto bin_pars = _f->dataHist().get(i);
2176 _f->dataHist().set(*bin_pars, _f->dataHist().weight(i) / _f->dataHist().binVolume(*bin_pars));
2178 _f->setAttribute(
"autodensity",
false);
2179 _f->setValueDirty();
2184 for (
auto &
x :
xRooNode(
"tmp", _f).vars()) {
2188 Info(
"Add",
"Created %s factor RooHistFunc::%s for %s",
2189 _f->getAttribute(
"density") ?
"SimpleDensity" :
"Simple", _f->GetName(),
p->
GetName());
2193 if (
auto _p = std::dynamic_pointer_cast<RooAbsPdf>(out); _p) {
2199 newName +=
"_components";
2200 Warning(
"Add",
"converting samples to components");
2205 if (
auto _boundaries = std::unique_ptr<std::list<double>>(_p->binBoundaries(
2206 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
2207 std::numeric_limits<double>::infinity()));
2208 !_boundaries && _ax->GetNbins() > 0) {
2209#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 24, 00)
2210 Warning(
"Add",
"Adding unbinned pdf %s to binned %s - will wrap with RooBinSamplingPdf(...)",
2212 _p = acquireNew<RooBinSamplingPdf>(
TString::Format(
"%s_binned", _p->GetName()), _p->GetTitle(),
2214 _p->setStringAttribute(
"alias", std::dynamic_pointer_cast<RooAbsArg>(out)->getStringAttribute(
"alias"));
2215 if (!_p->getStringAttribute(
"alias"))
2216 _p->setStringAttribute(
"alias", out->GetName());
2218 throw std::runtime_error(
2219 "unsupported addition of unbinned pdf to binned model - please upgrade to at least ROOT 6.24");
2226 if (!_p->canBeExtended()) {
2227 _p = acquireNew<RooExtendPdf>(
TString::Format(
"%s_extended", _p->GetName()), _p->GetTitle(), *_p,
2228 *acquire2<RooAbsReal, RooRealVar>(
"1",
"1", 1));
2231 return *(
Replace(*acquireNew<RooAddPdf>(newName, _p->GetTitle(),
RooArgList(*
p, *_p)))
2235 if (
auto _f = std::dynamic_pointer_cast<RooAbsReal>(out); _f) {
2244 if (
auto _boundaries = std::unique_ptr<std::list<double>>(_f->binBoundaries(
2245 *
dynamic_cast<RooAbsRealLValue *
>(_ax->GetParent()), -std::numeric_limits<double>::infinity(),
2246 std::numeric_limits<double>::infinity()));
2247 !_boundaries && _ax->GetNbins() > 0) {
2248#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 24, 00)
2251 "Adding unbinned function %s to binned %s - will wrap with RooRealSumPdf(RooBinSamplingPdf(...))",
2253 auto sumPdf = acquireNew<RooRealSumPdf>(
TString::Format(
"%s_pdfWrapper", _f->GetName()), _f->GetTitle(),
2254 *_f, *acquire2<RooAbsArg, RooRealVar>(
"1",
"1", 1),
true);
2255 sumPdf->setStringAttribute(
"alias", _f->getStringAttribute(
"alias"));
2256 if (!sumPdf->getStringAttribute(
"alias"))
2257 sumPdf->setStringAttribute(
"alias", out->GetName());
2258 _f = acquireNew<RooBinSamplingPdf>(
TString::Format(
"%s_binned", _f->GetName()), _f->GetTitle(),
2260 _f->setStringAttribute(
"alias", std::dynamic_pointer_cast<RooAbsArg>(out)->getStringAttribute(
"alias"));
2261 if (!_f->getStringAttribute(
"alias"))
2262 _f->setStringAttribute(
"alias", out->GetName());
2264 throw std::runtime_error(
2265 "unsupported addition of unbinned function to binned model - please upgrade to at least ROOT 6.24");
2270 const_cast<RooArgList &
>(
p->coefList()).add(*acquire2<RooAbsArg, RooRealVar>(
"1",
"1", 1));
2273 if (!
p->getStringAttribute(
"binning"))
2274 p->setStringAttribute(
"binning", _f->getStringAttribute(
"binning"));
2277 if (
auto gf =
p->getStringAttribute(
"global_factors"); gf) {
2280 auto fac = getObject<RooAbsReal>(pattern.
Data());
2282 throw std::runtime_error(
TString::Format(
"Could not find global factor %s", pattern.
Data()));
2291 p->setStringAttribute(
"xvar",
nullptr);
2295 }
else if (
auto p2 = get<RooProdPdf>(); p2) {
2303 bool tooMany(
false);
2316 }
else if (!tooMany) {
2317 auto out = this->
operator[](
"components")->Add(child);
2321 (!
child.get() && getObject<RooAbsReal>(
child.GetName()))) &&
2325 bool tooMany(
false);
2334 }
else if (
auto _p2 =
pp->get<
RooAddPdf>(); _p2) {
2336 for (
auto &_pdfa :
pp->components()) {
2350 }
else if (_backup) {
2353 }
else if (!tooMany) {
2354 auto out = this->
operator[](
"samples")->Add(child);
2357 p2->setStringAttribute(
"xvar",
nullptr);
2361 }
else if (
auto s = get<RooSimultaneous>(); s) {
2369 }
else if (
auto w = get<RooWorkspace>();
w) {
2370 child.convertForAcquisition(
2371 *
this,
child.get() ?
"" :
"func" );
2375 if (!
w->import(*_d)) {
2378 std::unique_ptr<RooAbsCollection>(
w->allVars().selectCommon(*_d->get()))->setAttribAll(
"obs");
2380 if (_d->getGlobalObservables()) {
2381 std::unique_ptr<RooAbsCollection>
globs(
w->allVars().selectCommon(*_d->getGlobalObservables()));
2382 globs->setAttribAll(
"obs");
2383 globs->setAttribAll(
"global");
2387 throw std::runtime_error(
2398 if (!
child.empty() ||
child.fFolder ==
"!pdfs") {
2401 std::string catName =
"channelCat";
2402 if (!
child.empty()) {
2403 if (
TString ss =
child.at(0)->GetName(); ss.Contains(
"=")) {
2404 catName = ss(0, ss.Index(
'='));
2407 auto _cat = acquire<RooCategory>(catName.c_str(), catName.c_str());
2408 _cat->setAttribute(
"obs");
2409 auto out = acquireNew<RooSimultaneous>(
child.GetName(),
child.GetTitle(), *_cat);
2410 Info(
"Add",
"Created pdf RooSimultaneous::%s in workspace %s", out->GetName(),
w->GetName());
2413 }
else if (
auto coll = get<RooAbsCollection>(); coll &&
child.get<
RooAbsArg>()) {
2414 if (coll->isOwning()) {
2416 }
else if (
child.ws() !=
ws()) {
2424 if (sOpt ==
"pdf") {
2426 if (get<RooWorkspace>()) {
2430 }
else if (sOpt ==
"channel") {
2432 if (get<RooSimultaneous>()) {
2434 }
else if (get<RooWorkspace>()) {
2435 std::shared_ptr<TObject> out;
2436 child.convertForAcquisition(*
this);
2439 }
else if (!
child.fComp) {
2440 out = acquireNew<RooProdPdf>(
child.GetName(),
2442 Info(
"Add",
"Created channel RooProdPdf::%s in workspace %s", out->GetName(),
get()->
GetName());
2446 }
else if (sOpt ==
"sample" || sOpt ==
"func") {
2447 if (get<RooProdPdf>()) {
2450 return _mainChild.Add(
child, sOpt ==
"func" ?
"func" :
"");
2452 return (*
this)[
"samples"]->Add(
child, sOpt ==
"func" ?
"func" :
"");
2455 }
else if (sOpt ==
"dataset") {
2456 if (get<RooWorkspace>()) {
2458 return (*this).datasets().Add(
child);
2465 if (get<RooSimultaneous>()) {
2469 }
else if (get<RooProduct>() || get<RooProdPdf>()) {
2515 if (
auto a = get<RooAbsArg>()) {
2516 a->setAttribute(
"hidden", set);
2525 auto a = get<RooAbsArg>();
2527 return a->getAttribute(
"hidden");
2534 if (
get() == rhs.
get()) {
2539 if (
auto lhsa = get<RooAbsArg>(), rhsa = rhs.
get<
RooAbsArg>(); lhsa && rhsa && lhsa->isIdentical(*rhsa)) {
2546 std::set<std::string> pdfs;
2548 if ((*
this)[
"pdfs"]->find(
c->GetName())) {
2549 pdfs.insert(
c->GetName());
2553 Warning(
"Combine",
"No pdfs will be combined. Please check and/or rename pdfs to match");
2555 std::stringstream s;
2556 for (
auto &
p : pdfs)
2558 Info(
"Combine",
"pdfs that will be combined: %s", s.str().c_str());
2561 std::set<std::string> _np;
2563 for (
auto &
c : rhs.
np()) {
2564 if (mynp.find(
c->GetName())) {
2565 _np.insert(
c->GetName());
2569 Warning(
"Combine",
"No correlated np");
2571 std::stringstream s;
2574 Info(
"Combine",
"np that will be shared (correlated): %s", s.str().c_str());
2576 std::set<std::string> _poi;
2578 for (
auto &
c : rhs.
poi()) {
2579 if (mypoi.find(
c->GetName())) {
2580 _poi.insert(
c->GetName());
2584 Warning(
"Combine",
"No correlated poi");
2586 std::stringstream s;
2587 for (
auto &
p : _poi)
2589 Info(
"Combine",
"poi that will be shared (correlated): %s", s.str().c_str());
2607 if (get<RooWorkspace>() &&
2608 (
c->fFolder ==
"!scratch" ||
c->fFolder ==
"!sets" ||
c->fFolder ==
"!snapshots" ||
c->fFolder ==
"!models"))
2612 Info(
"Combine",
"Combining %s into %s",
c->GetPath().c_str(), _c->GetPath().c_str());
2614 _c->Combine(*
c,
true);
2618 Info(
"Combine",
"Adding %s into %s",
c->GetPath().c_str(),
GetPath().c_str());
2621 }
catch (std::exception &
e) {
2622 Warning(
"Combine",
"Could not combine %s into %s",
c->GetPath().c_str(),
GetPath().c_str());
2627 if (!get<RooWorkspace>()) {
2631 Info(
"Combine",
"Combining %s into %s",
f->GetPath().c_str(), _f->GetPath().c_str());
2633 _f->Combine(*
f,
true);
2636 Info(
"Combine",
"Multiplying %s into %s",
f->GetPath().c_str(),
GetPath().c_str());
2645 if (
c->fFolder ==
"!sets") {
2647 Info(
"Combine",
"Extending set %s",
c->GetName());
2650 Info(
"Combine",
"Defining set %s",
c->GetName());
2660 Info(
"Combine",
"Combining %s into %s", ds->GetPath().c_str(), _ds->GetPath().c_str());
2665 Info(
"Combine",
"Adding %s into %s", ds->GetPath().c_str(),
GetPath().c_str());
2675 Info(
"Combine",
"Combining variation %s into %s",
v->GetPath().c_str(), _v->GetPath().c_str());
2677 _v->Combine(*
v,
true);
2680 Info(
"Combine",
"Varying %s into %s",
v->GetPath().c_str(),
GetPath().c_str());
2686 if (get<RooSimultaneous>()) {
2688 for (
auto &
b : rhs.
bins()) {
2689 if (
auto _b =
bins().
find(
b->GetName()); _b) {
2690 Info(
"Combine",
"Combining %s into %s",
b->GetPath().c_str(), _b->GetPath().c_str());
2691 _b->Combine(*
b,
true);
2693 Info(
"Combine",
"Extending with %s into %s",
b->GetPath().c_str(),
GetPath().c_str());
2717 if (
auto s = get<RooSimultaneous>(); s) {
2718 auto chans =
bins();
2719 if (!chans.empty()) {
2725 for (
auto &
c : chans) {
2727 cName = cName(cName.
Index(
'=') + 1, cName.
Length());
2730 c->shallowCopy(
name +
"_" +
c->get()->GetName(), std::shared_ptr<xRooNode>(&out, [](
xRooNode *) {}));
2731 pdf->addPdf(*
dynamic_cast<RooAbsPdf *
>(c_copy.get()), cName);
2736 }
else if (
auto p =
dynamic_cast<RooProdPdf *
>(o);
p) {
2738 std::shared_ptr<RooProdPdf> pdf =
2739 std::dynamic_pointer_cast<RooProdPdf>(out.
acquire(std::shared_ptr<TObject>(
p->
Clone()),
false,
2744 std::dynamic_pointer_cast<RooAbsArg>(out.
acquire(std::shared_ptr<TObject>(
main->Clone()),
false,
true));
2745 std::cout << newMain <<
" " << newMain->GetName() << std::endl;
2760 static std::unique_ptr<cout_redirect> capture;
2761 std::string captureStr;
2762 bool doCapture =
false;
2763 if (!capture &&
gROOT->FromPopUp()) {
2764 capture = std::make_unique<cout_redirect>(captureStr);
2787 if (
get() &&
get() !=
this) {
2789 if (_more || (get<RooAbsArg>() && get<RooAbsArg>()->isFundamental()) || get<RooConstVar>() ||
2790 get<RooAbsData>() || get<RooProduct>() || get<RooFitResult>()) {
2792 auto _snap = std::unique_ptr<RooAbsCollection>(_deps.snapshot());
2795 if (
auto _fr = get<RooFitResult>(); _fr &&
dynamic_cast<RooStringVar *
>(_fr->constPars().
find(
".log"))) {
2796 std::cout <<
"Minimization Logs:" << std::endl;
2797 std::cout << dynamic_cast<RooStringVar *>(_fr->constPars().find(
".log"))->getVal() << std::endl;
2799 _deps.assignValueOnly(*_snap);
2809 if (
auto fv = get<RooFormulaVar>()) {
2811 for (
size_t i = 0; i < fv->dependents().
size(); i++) {
2815 }
else if (
auto gv = get<RooGenericPdf>()) {
2817 for (
size_t i = 0; i < gv->dependents().
size(); i++) {
2821 }
else if (
auto pi = get<PiecewiseInterpolation>()) {
2823 std::set<int> interpCodes;
2824 for (
auto &
c : pi->interpolationCodes())
2825 interpCodes.insert(
c);
2826 if (interpCodes.size() == 1) {
2829 }
else if (
auto fiv = get<RooStats::HistFactory::FlexibleInterpVar>()) {
2831 std::set<int> interpCodes;
2832 for (
auto &
c : fiv->interpolationCodes())
2833 interpCodes.insert(
c == 4 ? 5 :
c);
2834 if (interpCodes.size() == 1) {
2841 }
else if (!
get()) {
2842 std::cout << std::endl;
2846 std::vector<std::string> folderNames;
2847 for (
auto &k : *
this) {
2848 if (std::find(folderNames.begin(), folderNames.end(), k->fFolder) == folderNames.end()) {
2849 folderNames.push_back(k->fFolder);
2852 for (
auto &
f : folderNames) {
2856 for (
int j = 0; j <
indent; j++)
2858 std::cout <<
f << std::endl;
2861 for (
auto &k : *
this) {
2862 if (k->fFolder !=
f) {
2866 for (
int j = 0; j < iindent; j++)
2868 std::cout << i++ <<
") " << k->GetName() <<
" : ";
2872 auto _deps = k->coords(
false).argList();
2873 auto _snap = std::unique_ptr<RooAbsCollection>(_deps.snapshot());
2875 k->get()->Print(sOpt);
2876 _deps.assignValueOnly(*_snap);
2879 if (
auto _type = k->GetNodeType(); strlen(_type)) {
2887 for (
size_t j = 0; j < fv->dependents().
size(); j++) {
2893 for (
size_t j = 0; j < gv->dependents().
size(); j++) {
2899 std::set<int> interpCodes;
2900 for (
auto &
c : pi->interpolationCodes())
2901 interpCodes.insert(
c);
2902 if (interpCodes.size() == 1) {
2907 std::set<int> interpCodes;
2908 for (
auto &
c : fiv->interpolationCodes())
2909 interpCodes.insert(
c == 4 ? 5 :
c);
2910 if (interpCodes.size() == 1) {
2914 std::cout << k->get()->ClassName() <<
"::" << k->get()->GetName() << _suffix.
Data() << std::endl;
2917 k->Print(sOpt +
TString::Format(
"depth=%dindent=%d", depth - 1, iindent + 1));
2920 std::cout <<
" NULL " << std::endl;
2926 size_t lastBreak = 0;
2927 std::string captureStrWithBreaks;
2928 for (
size_t i = 0; i < captureStr.size(); i++) {
2929 captureStrWithBreaks += captureStr[i];
2930 if (captureStr[i] ==
'\n') {
2933 if (i - lastBreak > 150) {
2934 captureStrWithBreaks +=
'\n';
2939 (
gROOT->GetListOfBrowsers()->At(0))
2943 captureStrWithBreaks.c_str());
2951 if (
auto v = get<RooRealVar>();
v) {
2954 double mean = std::numeric_limits<double>::quiet_NaN();
2955 double sigma = mean;
2964 mean = std::numeric_limits<double>::quiet_NaN();
2967 constrType =
"normal";
2968 }
else if (constrType ==
"normal") {
2971 }
else if (constrType ==
"gaussian") {
2975 throw std::runtime_error(
"No error on parameter for gaussian constraint");
2978 constrType =
"normal";
2979 }
else if (constrType ==
"poisson") {
2981 throw std::runtime_error(
"No error on parameter for poisson constraint");
2983 sigma = pow(
v->getVal() /
v->getError(), 2);
2986 if (constrType ==
"poisson") {
2988 double tau_val =
sigma;
2989 auto globs = acquire<RooRealVar>(
Form(
"globs_%s",
v->GetName()),
Form(
"globs_%s",
v->GetName()),
2990 v->getVal() * tau_val, (
v->getVal() - 5 *
v->getError()) * tau_val,
2991 (
v->getVal() + 5 *
v->getError()) * tau_val);
2992 globs->setConstant();
2993 globs->setAttribute(
"obs");
2994 globs->setAttribute(
"global");
2996 auto tau = acquireNew<RooConstVar>(
TString::Format(
"tau_%s",
v->GetName()),
"", tau_val);
2997 auto constr = acquireNew<RooPoisson>(
3006 v->setError(mean / sqrt(tau_val));
3007 Info(
"Constrain",
"Added poisson constraint pdf RooPoisson::%s (tau=%g) for %s", out->GetName(), tau_val,
3010 }
else if (constrType ==
"normal") {
3012 auto globs = acquire<RooRealVar>(
Form(
"globs_%s",
v->GetName()),
Form(
"globs_%s",
v->GetName()), mean,
3014 globs->setAttribute(
"obs");
3015 globs->setAttribute(
"global");
3016 globs->setConstant();
3019 auto constr = acquireNew<RooGaussian>(
3025 Info(
"Constrain",
"Added gaussian constraint pdf RooGaussian::%s (mean=%g,sigma=%g) for %s", out->GetName(),
3032 auto _me = get<RooAbsArg>();
3034 throw std::runtime_error(
"Cannot constrain non arg");
3037 if (!
p->dependsOn(*_me)) {
3038 throw std::runtime_error(
"Constraint does not depend on constrainee");
3047 throw std::runtime_error(
"Nowhere to put constraint");
3050 auto childGlobs =
child.globs();
3051 if (!childGlobs.empty()) {
3052 for (
auto d :
x->datasets()) {
3056 d->get<
RooAbsData>()->setGlobalObservables(newGlobs);
3062 if (k ==
"globalObservables" ||
TString(k).
EndsWith(
"_GlobalObservables")) {
3071 for (
auto &
c : *
x) {
3077 return x->Multiply(
child);
3079 return x->Add(
child,
"+");
3092 ~AutoUpdater() {
n.browse(); }
3095 AutoUpdater xxx(*
this);
3102 auto o = std::dynamic_pointer_cast<RooAbsReal>(
acquire(
child.fComp));
3115 binFactors =
xRooNode(*c).factors().find(
"binFactors");
3125 ?
fParent->mainChild()->GetName()
3130 binFactors =
fParent->factors().find(
"binFactors");
3132 throw std::runtime_error(
3139 for (
auto &
b : binFactors->bins()) {
3140 auto p = acquireNew<RooProduct>(
TString::Format(
"%s_bin%d", binFactors->get()->GetName(), i),
3142 p->setStringAttribute(
"alias",
TString::Format(
"%s=%g", binFactors->GetXaxis()->GetParent()->GetName(),
3143 binFactors->GetXaxis()->GetBinCenter(i)));
3150 auto _bin = binFactors->bins().at(
fBinNumber - 1);
3151 if (
auto phf = binFactors->get<
ParamHistFunc>(); phf && _bin) {
3152#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3157 if (strcmp(_bin->GetName(),
"1") == 0) {
3159 for (std::size_t i = 0; i < pSet.
size(); i++) {
3161 all.
add(*pSet.
at(i));
3169 _bin->fBinNumber = -1;
3170 return _bin->Multiply(
child, opt);
3198 auto _ref = emplace_back(std::shared_ptr<xRooNode>(&
const_cast<xRooNode &
>(
child), [](
TObject *) {}));
3203 std::rethrow_exception(std::current_exception());
3211 if (
auto o = getObject<RooAbsReal>(
child.GetName())) {
3215 Info(
"Multiply",
"Scaled %s by existing factor %s::%s",
3219 }
else if (sOpt ==
"const") {
3222 Info(
"Multiply",
"Scaled %s by new const factor %s",
3226 }
else if (sOpt ==
"norm") {
3233 Info(
"Multiply",
"Scaled %s by new norm factor %s",
3238 throw std::runtime_error(
TString::Format(
"Failed to create new normFactor %s",
child.GetName()));
3242 Info(
"Multiply",
"Scaled %s by new norm factor %s",
3246 }
else if (sOpt ==
"shape" || sOpt ==
"simple" || sOpt ==
"blankshape") {
3251 for (
int i = 1; i <=
h->GetNbinsX(); i++) {
3252 h->SetBinContent(i, 1);
3257 h->SetTitle(
child.GetTitle());
3262 Info(
"Multiply",
"Scaled %s by new %s factor %s",
3267 }
else if (sOpt ==
"overall") {
3268 auto out =
Multiply(acquireNew<RooStats::HistFactory::FlexibleInterpVar>(
3269 child.GetName(),
child.GetTitle(),
RooArgList(), 1, std::vector<double>(), std::vector<double>()));
3271 Info(
"Multiply",
"Scaled %s by new overall factor %s",
3275 }
else if (sOpt ==
"func" &&
ws()) {
3280 Info(
"Multiply",
"Scaled %s by new func factor %s",
3287 if (
auto h =
child.get<
TH1>();
h && strlen(
h->GetOption()) == 0 && strlen(opt) > 0) {
3291 if (
auto w = get<RooWorkspace>();
w) {
3293 std::shared_ptr<TObject> out;
3294 child.convertForAcquisition(*
this);
3300 if (strcmp(
GetName(),
".coef") == 0) {
3305 if (
p->coefList().empty() && !
p->pdfList().empty()) {
3306 for (
auto _pdf :
p->pdfList()) {
3308 .add(*acquireNew<RooExtendedBinding>(
TString::Format(
"%s_extBind", _pdf->GetName()),
3312 Info(
"Multiply",
"Created RooExtendedBinding coefficients for all pdfs of %s so that can multiply coef",
3314 *
reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(
p) +
3316 *
reinterpret_cast<bool *
>(
reinterpret_cast<unsigned char *
>(
p) +
3319 for (
size_t i = 0; i <
p->pdfList().size(); i++) {
3321 auto coefs =
p->coefList().at(i);
3330 for (
size_t j = 0; j <
p->coefList().size(); j++) {
3332 oldCoefs.
add(*newCoefs);
3334 oldCoefs.add(*
p->coefList().at(j));
3337 const_cast<RooArgList &
>(
p->coefList()).removeAll();
3338 const_cast<RooArgList &
>(
p->coefList()).add(oldCoefs);
3347 for (
size_t i = 0; i < p2->funcList().
size(); i++) {
3349 auto coefs = p2->coefList().at(i);
3358 for (
size_t j = 0; j < p2->coefList().size(); j++) {
3360 oldCoefs.
add(*newCoefs);
3362 oldCoefs.add(*p2->coefList().at(j));
3365 const_cast<RooArgList &
>(p2->coefList()).removeAll();
3366 const_cast<RooArgList &
>(p2->coefList()).add(oldCoefs);
3373 throw std::runtime_error(
"this coefs case is not supported");
3376 if (
auto p = get<RooProduct>();
p) {
3377 std::shared_ptr<TObject> out;
3378 auto cc =
child.fComp;
3379 bool isConverted = (
child.convertForAcquisition(*
this) != cc);
3384 if (
auto _f = std::dynamic_pointer_cast<RooHistFunc>(
3386 _f && _f->getAttribute(
"autodensity")) {
3388 bool hasDensity =
false;
3396 if (_f->getAttribute(
"density")) {
3399 for (
int i = 0; i < _f->dataHist().numEntries(); i++) {
3400 auto bin_pars = _f->dataHist().get(i);
3401 _f->dataHist().set(*bin_pars, _f->dataHist().weight(i) / _f->dataHist().binVolume(*bin_pars));
3403 _f->setValueDirty();
3406 for (
auto &
x :
xRooNode(
"tmp", _f).vars()) {
3410 _f->setAttribute(
"autodensity",
false);
3414 Info(
"Multiply",
"Created %s factor %s in %s",
3418 Info(
"Multiply",
"Created Shape factor %s in %s",
child->GetName(),
p->
GetName());
3421 if (
auto _f = std::dynamic_pointer_cast<RooAbsReal>(out); _f) {
3422#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3423 p->_compRSet.add(*_f);
3425 const_cast<RooArgList &
>(
p->realComponents()).add(*_f);
3431 for (
auto &_par : _out.
pars()) {
3434 for (
auto &_constr : _par->constraints()) {
3435 if (strcmp(s, _constr->get()->GetName()) == 0) {
3442 Info(
"Multiply",
"Pulling in %s boundConstraint: %s", _par->GetName(), s);
3443 auto _pdf = getObject<RooAbsPdf>(s);
3445 throw std::runtime_error(
"Couldn't find boundConstraint");
3447 _par->Constrain(_pdf);
3454 }
else if (
auto p2 = get<RooProdPdf>(); p2) {
3456 std::shared_ptr<TObject> out;
3457 child.convertForAcquisition(*
this);
3466 std::shared_ptr<RooAbsPdf> _pdf;
3467 if (!
child.get() && strcmp(
child.GetName(),
"components") == 0) {
3468 auto _sumpdf = acquireNew<RooAddPdf>(
3469 Form(
"%s_%s", p2->GetName(),
child.GetName()),
3475 auto _sumpdf = acquireNew<RooRealSumPdf>(
3476 Form(
"%s_%s", p2->GetName(),
child.GetName()),
3480 _sumpdf->setFloor(
true);
3483 _pdf->setStringAttribute(
"alias",
child.GetName());
3485 _pdf->setStringAttribute(
"xvar", p2->getStringAttribute(
"xvar"));
3486 _pdf->setStringAttribute(
"binning", p2->getStringAttribute(
"binning"));
3488 Info(
"Multiply",
"Created %s::%s in channel %s", _pdf->ClassName(), _pdf->GetName(), p2->GetName());
3493 if (
auto _pdf = std::dynamic_pointer_cast<RooAbsPdf>(out); _pdf) {
3494#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3495 const_cast<RooArgList &
>(p2->pdfList()).add(*_pdf);
3496#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
3497 p2->_pdfNSetList.emplace_back(std::make_unique<RooArgSet>(
"nset"));
3501 if (!p2->canBeExtended() && _pdf->canBeExtended()) {
3502 p2->_extendedIndex = p2->_pdfList.size() - 1;
3511 }
else if (
auto p3 = get<RooRealSumPdf>(); p3) {
3513 std::shared_ptr<TObject> out;
3514 child.convertForAcquisition(*
this);
3520 TString s = p3->getStringAttribute(
"global_factors");
3523 s += out->GetName();
3524 p3->setStringAttribute(
"global_factors", s);
3527 "Flagged %s as a global factor in channel %s (is applied to all current and future samples in the channel)",
3528 out->GetName(), p3->GetName());
3539 std::set<RooAbsArg *> cl;
3540 for (
auto &arg : p5->clients()) {
3546 if (cl.size() > 1) {
3551 Warning(
"Multiply",
"Scaling %s that has multiple clients", p5->GetName());
3557 for (
auto &
a : p5->attributes())
3558 new_p->setAttribute(
a.c_str());
3559 for (
auto &
a : p5->stringAttributes())
3560 new_p->setStringAttribute(
a.first.c_str(),
a.second.c_str());
3561 if (!new_p->getStringAttribute(
"alias"))
3562 new_p->setStringAttribute(
"alias", p5->GetName());
3564 new_p->setAttribute(
Form(
"ORIGNAME:%s", old_p->GetName()));
3565 for (
auto arg : cl) {
3566 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
3574 if (!
child.get() && strlen(opt) == 0)
3577 throw std::runtime_error(
3579 (!
child.get() && strlen(opt) == 0) ?
" (forgot to specify factor type?)" :
""));
3585 auto p5 = get<RooAbsArg>();
3587 throw std::runtime_error(
"Only replacement of RooAbsArg is supported");
3596 new_p = std::dynamic_pointer_cast<RooAbsArg>(out).get();
3598 std::set<RooAbsArg *> cl;
3599 for (
auto &arg : p5->clients()) {
3607 if (cl.size() > 1) {
3612 std::stringstream clientList;
3614 clientList <<
c->GetName() <<
",";
3615 Warning(
"Replace",
"Replacing %s in all clients: %s", p5->GetName(), clientList.str().c_str());
3619 new_p->setAttribute(
Form(
"ORIGNAME:%s", p5->GetName()));
3620 for (
auto arg : cl) {
3625 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
3636 ~AutoUpdater() {
n.browse(); }
3639 AutoUpdater xxx(*
this);
3644 auto _ref = emplace_back(std::shared_ptr<xRooNode>(&
const_cast<xRooNode &
>(
child), [](
TObject *) {}));
3649 std::rethrow_exception(std::current_exception());
3661 std::string label =
child.GetName();
3662 if (
auto pos = label.find(
'='); pos != std::string::npos)
3663 label = label.substr(pos + 1);
3664 if (!s->indexCat().hasLabel(label)) {
3669 if (
auto bb = _ds->getBrowsable(
".sourceds")) {
3672 auto dsCat = _ds->robs()[s->indexCat().GetName()]->get<
RooCategory>();
3674 throw std::runtime_error(
TString::Format(
"Failed to find %s regular observable in %s dataset",
3675 s->indexCat().GetName(), _ds->GetName()));
3677 dsCat->defineType(label.c_str());
3683 std::shared_ptr<TObject> out;
3684 child.convertForAcquisition(*
this);
3687 }
else if (!
child.fComp) {
3688 out = acquireNew<RooProdPdf>(
TString::Format(
"%s_%s", s->GetName(), label.c_str()),
3690 Info(
"Vary",
"Created channel RooProdPdf::%s in model %s", out->GetName(), s->GetName());
3693 if (
auto _pdf = std::dynamic_pointer_cast<RooAbsPdf>(out); _pdf) {
3696 std::set<RooAbsData *> dsToUpdate;
3698 if (
auto bb = _ds->getBrowsable(
".sourceds")) {
3705 if (!dsToUpdate.empty()) {
3707 _pdf->leafNodeServerList(&leafs);
3708 std::unique_ptr<RooAbsCollection> globals(leafs.
selectByAttrib(
"global",
true));
3709 for (
auto _ds : dsToUpdate) {
3712 globs.addClone(*_ds->getGlobalObservables());
3713 for (
auto &aa : *globals) {
3715 globs.addClone(*aa);
3716 alist += std::string(aa->GetName()) +
",";
3719 if (!alist.empty()) {
3720 Warning(
"Vary",
"Adding %s to global observables of %s", alist.c_str(), _ds->GetName());
3721 _ds->setGlobalObservables(
globs);
3726 s->addPdf(*_pdf, label.c_str());
3735 }
else if (
auto p = get<RooStats::HistFactory::FlexibleInterpVar>();
p) {
3738 child.convertForAcquisition(*
this);
3740 if (!_c &&
child.get()) {
3741 throw std::runtime_error(
"Only pure consts can be set as variations of a flexible interpvar");
3743#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3744 double value = (_c ? _c->getVal() :
p->_nominal);
3745 double nomVal =
p->_nominal;
3747 double value = (_c ? _c->getVal() :
p->nominal());
3748 double nomVal =
p->nominal();
3752 if (cName ==
"nominal") {
3757 throw std::runtime_error(
"unsupported variation form");
3759 std::string parName = cName(0, cName.
Index(
'='));
3761 if (parVal != 1 && parVal != -1) {
3762 throw std::runtime_error(
"unsupported variation magnitude");
3764 bool high = parVal > 0;
3766 if (parName.empty()) {
3775 if (!
p->findServer(*
v)) {
3776#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3777 p->_paramList.add(*
v);
3778 p->_low.push_back(0);
3779 p->_high.push_back(0);
3780 p->_interpCode.push_back(4);
3783 const_cast<std::vector<double> &
>(
p->low()).push_back(0);
3784 const_cast<std::vector<double> &
>(
p->high()).push_back(0);
3785 const_cast<std::vector<int> &
>(
p->interpolationCodes()).push_back(4);
3787 v->setAttribute(
Form(
"SYMMETRIC%s_%s", high ?
"+" :
"-",
GetName()));
3792 if (
v->getAttribute(
Form(
"SYMMETRIC+_%s",
GetName()))) {
3793 p->setLow(*
v, 2 * nomVal -
value);
3795 v->setAttribute(
Form(
"SYMMETRIC-_%s",
GetName()),
false);
3798 if (
v->getAttribute(
Form(
"SYMMETRIC-_%s",
GetName()))) {
3799 p->setHigh(*
v, 2 * nomVal -
value);
3801 v->setAttribute(
Form(
"SYMMETRIC+_%s",
GetName()),
false);
3809 }
else if (
auto p2 = get<PiecewiseInterpolation>(); p2) {
3812 throw std::runtime_error(
"unsupported variation form");
3816 if (parVal != 1 && parVal != -1) {
3817 throw std::runtime_error(
"unsupported variation magnitude");
3819#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3822 throw std::runtime_error(
3823 TString::Format(
"Interpolating %s instead of RooHistFunc", p2->_nominal.absArg()->ClassName()));
3828 throw std::runtime_error(
3829 TString::Format(
"Interpolating %s instead of RooHistFunc", p2->nominalHist()->ClassName()));
3835 for (
auto par : p2->paramList()) {
3836 if (parName == par->GetName()) {
3837 f =
dynamic_cast<RooHistFunc *
>((parVal > 0 ? p2->highList() : p2->lowList()).
at(i));
3838 otherf =
dynamic_cast<RooHistFunc *
>((parVal > 0 ? p2->lowList() : p2->highList()).
at(i));
3846 auto v = acquire<RooRealVar>(parName, parName, -5, 5);
3850 std::shared_ptr<RooHistFunc> up(
3852 std::shared_ptr<RooHistFunc> down(
3855#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3856 std::unique_ptr<RooDataHist>
h1(
3857 static_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", up->GetName()))));
3858 std::unique_ptr<RooDataHist> h2(
3859 static_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", down->GetName()))));
3860 up->_dataHist =
dynamic_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", up->GetName())));
3861 down->_dataHist =
dynamic_cast<RooDataHist *
>(
f->dataHist().Clone(
Form(
"hist_%s", down->GetName())));
3864 down->cloneAndOwnDataHist(
TString::Format(
"hist_%s", down->GetName()));
3866 auto ups = std::dynamic_pointer_cast<RooHistFunc>(
acquire(up,
false,
true));
3867 auto downs = std::dynamic_pointer_cast<RooHistFunc>(
acquire(down,
false,
true));
3868#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
3869 p2->_highSet.add(*ups.get());
3870 p2->_lowSet.add(*downs.get());
3871 p2->_interpCode.push_back(4);
3872 p2->_paramSet.add(*
v);
3874 const_cast<RooArgList &
>(p2->highList()).add(*ups);
3875 const_cast<RooArgList &
>(p2->lowList()).add(*downs);
3876 const_cast<std::vector<int> &
>(p2->interpolationCodes()).push_back(4);
3877 const_cast<RooArgList &
>(p2->paramList()).add(*
v);
3879 p2->setValueDirty();
3880 f = ((parVal > 0) ? ups : downs).
get();
3881 otherf = ((parVal > 0) ? downs : ups).
get();
3883 f->setStringAttribute(
"symmetrizes", otherf->
GetName());
3884 f->setStringAttribute(
"symmetrize_nominal", nomf->
GetName());
3903#if ROOT_VERSION_CODE > ROOT_VERSION(6, 37, 00)
3904 }
else if (
auto pmr = get<RooMultiReal>(); pmr) {
3907 throw std::runtime_error(
"unsupported variation form");
3913 if (!pmr->indexCategory()->hasLabel(parVal.
Data())) {
3916 auto idx = pmr->indexCategory()->lookupIndex(parVal.
Data());
3918 throw std::runtime_error(
"Invalid index");
3921 child.convertForAcquisition(*
this);
3924 if (pmr->getModelList().empty()) {
3925 throw std::runtime_error(
"No real function given for variation, and no nominal function to clone");
3927 _c = std::dynamic_pointer_cast<RooAbsReal>(
3928 acquire(std::shared_ptr<TObject>(pmr->getModelList().at(0)->Clone(
3932 _c->setStringAttribute(
"alias",
child.GetName());
3934 const_cast<RooListProxy &
>(pmr->getModelList()).add(*_c);
3939 }
else if (
auto p3 = get<RooConstVar>(); p3) {
3942 if (p3->getAttribute(
"RooRealConstant_Factory_Object")) {
3943 throw std::runtime_error(
"Cannot vary pure constants");
3949 std::set<RooAbsArg *> cl;
3950 for (
auto &arg : p3->clients()) {
3955 if (cl.size() > 1) {
3960 Warning(
"Vary",
"Varying %s that has multiple clients", p3->GetName());
3963 p3->setStringAttribute(
"origName", p3->GetName());
3965 p3->SetName(
Form(
"%s_nominal", p3->GetName()));
3967 auto new_p = acquireNew<RooStats::HistFactory::FlexibleInterpVar>(
n, p3->GetTitle(),
RooArgList(), p3->getVal(),
3968 std::vector<double>(), std::vector<double>());
3971 for (
auto &
a : p3->attributes())
3972 new_p->setAttribute(
a.c_str());
3973 for (
auto &
a : p3->stringAttributes())
3974 new_p->setStringAttribute(
a.first.c_str(),
a.second.c_str());
3977 new_p->setAttribute(
Form(
"ORIGNAME:%s", old_p->GetName()));
3978 for (
auto arg : cl) {
3979 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
3985 }
else if (
auto p4 = get<RooAbsReal>(); p4) {
3989 std::set<RooAbsArg *> cl;
3990 for (
auto &arg : p4->clients()) {
3995 if (cl.size() > 1) {
4000 Warning(
"Vary",
"Varying %s that has multiple clients", p4->GetName());
4003 p4->setStringAttribute(
"origName", p4->GetName());
4005 p4->SetName(
Form(
"%s_nominal", p4->GetName()));
4007#if ROOT_VERSION_CODE > ROOT_VERSION(6, 37, 00)
4008 std::shared_ptr<RooAbsArg> new_p;
4014 if (parVal != 1 && parVal != -1) {
4016 auto idxCat = acquire<RooCategory>(parName, parName);
4018 throw std::runtime_error(
"Failed to acquire categorical index for RooMultiReal");
4021 if (idxCat->numTypes() == 0) {
4022 idxCat->defineType(
"nominal");
4024 Info(
"Vary",
"Creating a RooMultiReal with category %s", idxCat->GetName());
4025 auto newFunc = acquireNew<RooMultiReal>(
4026 n, p4->GetTitle(), *idxCat,
4028 const_cast<RooListProxy &
>(newFunc->getModelList()).add(*p4);
4041 for (
auto &
a : p4->attributes())
4042 new_p->setAttribute(
a.c_str());
4043 for (
auto &
a : p4->stringAttributes())
4044 new_p->setStringAttribute(
a.first.c_str(),
a.second.c_str());
4047 new_p->setAttribute(
Form(
"ORIGNAME:%s", old_p->GetName()));
4048 for (
auto arg : cl) {
4049 arg->redirectServers(
RooArgSet(*new_p),
false,
true);
4090 if (
auto a = get<RooAbsArg>();
a && strcmp(
a->GetName(),
GetName()) && !
a->getStringAttribute(
"alias")) {
4091 a->setStringAttribute(
"alias",
GetName());
4094 throw std::runtime_error(
"Cannot determine type");
4099 if (
auto h =
dynamic_cast<const TH1 *
>(&o);
h) {
4110 bool _isData = get<RooAbsData>();
4116 throw std::runtime_error(
"no xaxis");
4117 auto _v =
dynamic_cast<RooRealVar *
>(ax->GetParent());
4120 _b.
b =
dynamic_cast<RooAbsBinning *
>(_v->getBinningPtr(
nullptr)->Clone());
4121 if (
h->GetXaxis()->IsVariableBinSize()) {
4122 _v->setBinning(
RooBinning(
h->GetNbinsX(),
h->GetXaxis()->GetXbins()->GetArray()));
4124 _v->setBinning(
RooUniformBinning(
h->GetXaxis()->GetXmin(),
h->GetXaxis()->GetXmax(),
h->GetNbinsX()));
4130 for (
int bin = 1; bin <=
h->GetNbinsX(); bin++) {
4138 if (!_isData &&
h->GetSumw2N() && !
SetBinError(bin,
h->GetBinError(bin)))
4139 throw std::runtime_error(
"Failed setting stat error");
4143 }
else if (
auto _c =
dynamic_cast<const RooConstVar *
>(&o); _c) {
4145 if (
auto a = get<RooAbsArg>();
4146 (
a &&
a->isFundamental()) || get<RooConstVar>() || get<RooStats::HistFactory::FlexibleInterpVar>()) {
4149 }
else if (get<RooAbsData>()) {
4155 throw std::runtime_error(
"Assignment failed");
4185 auto _pars =
pars();
4188 std::map<RooAbsRealLValue *, double> valsToSet;
4190 auto idx = pattern.
Index(
'=');
4193 (idx == -1) ? std::numeric_limits<double>::quiet_NaN() :
TString(pattern(idx + 1, pattern.
Length())).
Atof();
4194 bool foundArg =
false;
4195 for (
auto p : _pars.argList()) {
4198 p->setAttribute(
"Constant",
true);
4199 if (!std::isnan(val)) {
4207 throw std::runtime_error(std::string(
"Unrecognised parameter: ") + pat.
Data());
4215 auto idx = pattern2.
Index(
'=');
4218 if (
auto o = defaultOpts->FindObject(pat)) {
4219 defaultOpts->Remove(o);
4223 val.
IsAlpha() ? val :
nullptr));
4229 for (
auto &
d : _dsets) {
4230 if (
d->get()->TestBit(1 << 20)) {
4231 dsetName =
d->get()->GetName();
4235 auto _nll =
nll(dsetName.
Data(), *defaultOpts);
4237 for (
auto [
p,
v] : valsToSet) {
4240 _nll.fitConfigOptions()->SetValue(
"LogSize", 65536);
4241 _nll.fitConfig()->MinimizerOptions().SetPrintLevel(0);
4242 auto fr = _nll.minimize();
4245 throw std::runtime_error(
"Fit Failed");
4248 for (
unsigned int i = 0; i < fr->numStatusHistory(); i++) {
4249 statusCodes +=
TString::Format(
"\n%s = %d", fr->statusLabelHistory(i), fr->statusCodeHistory(i));
4252 if(fr->status() == 0) {
4254 if (!_poi.empty()) {
4255 statusCodes +=
"\n\nPOI Post Fit Values\n-------------";
4256 for (
auto p : _poi) {
4260 statusCodes +=
TString::Format(
"\n%s : %g +/- %g", arg->GetName(), arg->getVal(), arg->getError());
4265 (
gROOT->GetListOfBrowsers()->At(0))
4269 if (_nll.fOpts->find(
"GoF")) {
4270 gofResult =
TString::Format(
"GoF p-value = %g (mainTerm = %g)\n", fr->constPars().getRealValue(
".pgof"),
4271 fr->constPars().getRealValue(
".mainterm_pgof"));
4273 if (fr->status() != 0) {
4275 TString::Format(
"%s\nData = %s\nFit Status Code = %d\nCov Quality = %d\n%s-------------%s",
4276 fr->GetName(), dsetName.
Data(), fr->status(), fr->covQual(), gofResult.
Data(),
4277 statusCodes.
Data()),
4279 }
else if (fr->covQual() != 3 && _nll.fitConfig()->ParabErrors()) {
4280 new TGMsgBox(
gClient->GetRoot(),
w,
"Fit Finished with Bad Covariance Quality",
4281 TString::Format(
"%s\nData = %s\nFit Status Code = %d\nCov Quality = %d\n%s-------------%s",
4282 fr->GetName(), dsetName.
Data(), fr->status(), fr->covQual(), gofResult.
Data(),
4283 statusCodes.
Data()),
4287 TString::Format(
"%s\nData = %s\nFit Status Code = %d\nCov Quality = %d\n%s-------------%s",
4288 fr->GetName(), dsetName.
Data(), fr->status(), fr->covQual(), gofResult.
Data(),
4289 statusCodes.
Data()));
4292 for (
auto a : *
gROOT->GetListOfBrowsers()) {
4303 if (
auto bi =
dynamic_cast<TRootBrowser *
>(
b->GetBrowserImp())) {
4304 if (
auto fb =
dynamic_cast<TGFileBrowser *
>(bi->GetActBrowser())) {
4305 fb->DoubleClicked(
p, 0);
4306 if (
auto first =
p->GetFirstChild()) {
4308 if (first->IsOpen() &&
TString(first->GetText()) ==
"fits") {
4309 fb->DoubleClicked(first, 0);
4311 }
while ((first = first->GetNextSibling()));
4321 }
catch (
const std::exception &
e) {
4324 (
gROOT->GetListOfBrowsers()->At(0))
4334 datasets().
Add(datasetName, expected ?
"asimov" :
"toy");
4337 for (
auto a : *
gROOT->GetListOfBrowsers()) {
4348 if (
auto bi =
dynamic_cast<TRootBrowser *
>(
b->GetBrowserImp())) {
4349 if (
auto fb =
dynamic_cast<TGFileBrowser *
>(bi->GetActBrowser())) {
4350 fb->DoubleClicked(
p, 0);
4351 if (
auto first =
p->GetFirstChild()) {
4353 if (first->IsOpen() &&
TString(first->GetText()) ==
"datasets") {
4354 fb->DoubleClicked(first, 0);
4356 }
while ((first = first->GetNextSibling()));
4366 }
catch (
const std::exception &
e) {
4369 (
gROOT->GetListOfBrowsers()->At(0))
4372 "Exception",
e.what(),
4378 double highX ,
const char *constParValues,
4379 const char *options)
4388 for (
auto &
d : _dsets) {
4389 if (
d->get()->TestBit(1 << 20)) {
4390 dsetName =
d->get()->GetName();
4394 auto _pars =
pars();
4395 std::unique_ptr<RooAbsCollection> snap(_pars.argList().snapshot());
4398 auto idx = pattern.
Index(
'=');
4401 (idx == -1) ? std::numeric_limits<double>::quiet_NaN() :
TString(pattern(idx + 1, pattern.
Length())).
Atof();
4402 bool foundArg =
false;
4403 for (
auto par : _pars.argList()) {
4406 par->setAttribute(
"Constant",
true);
4407 if (!std::isnan(val)) {
4413 throw std::runtime_error(std::string(
"Unrecognised parameter: ") + pat.
Data());
4421 auto idx = pattern2.
Index(
'=');
4424 if (
auto o = defaultOpts->FindObject(pat)) {
4425 defaultOpts->Remove(o);
4429 val.
IsAlpha() ? val :
nullptr));
4440 hs.SetTitle(sWhat +
" scan" + ((dsetName !=
"") ?
TString::Format(
" [data=%s]", dsetName.
Data()) :
""));
4441 int scanStatus = hs.scan(sWhat +
" visualize", nBinsX, lowX, highX);
4442 if (scanStatus != 0) {
4445 (
gROOT->GetListOfBrowsers()->At(0))
4448 "Scan Finished with Bad Status Code",
4449 TString::Format(
"%s\nData = %s\nScan Status Code = %d", hs.GetName(), dsetName.
Data(), scanStatus),
4453 if (
auto res = hs.result())
4457 _pars.argList() = *snap;
4460 for (
auto a : *
gROOT->GetListOfBrowsers()) {
4471 if (
auto bi =
dynamic_cast<TRootBrowser *
>(
b->GetBrowserImp())) {
4472 if (
auto fb =
dynamic_cast<TGFileBrowser *
>(bi->GetActBrowser())) {
4473 fb->DoubleClicked(
p, 0);
4474 if (
auto first =
p->GetFirstChild()) {
4476 if (first->IsOpen() &&
TString(first->GetText()) ==
"scans") {
4477 fb->DoubleClicked(first, 0);
4479 }
while ((first = first->GetNextSibling()));
4490 }
catch (
const std::exception &
e) {
4493 (
gROOT->GetListOfBrowsers()->At(0))
4504 }
catch (
const std::exception &
e) {
4513#if ROOT_VERSION_CODE > ROOT_VERSION(6, 29, 00)
4518 for (
auto a : *
this) {
4525 for (
auto c :
args) {
4531 f.SetParName(i,
c->GetName());
4533 f.SetParLimits(i,
v->getMin(),
v->getMax());
4534 if (
v->isConstant())
4535 f.FixParameter(i,
v->getVal());
4537 f.SetParameter(i,
v->getVal());
4538 f.SetParError(i,
v->getError());
4549 (
gROOT->GetListOfBrowsers()->At(0))
4555 for (i = 0; i <
f.GetNpar(); i++) {
4561 f.GetParLimits(i, low, high);
4563 v->setConstant(low);
4565 v->setRange(low, high);
4575 throw std::runtime_error(
"Failed to SetContent");
4576 }
catch (
const std::exception &
e) {
4590 std::shared_ptr<TH1D>
h;
4591 auto _b =
dynamic_cast<Axis2 *
>(ax)->binning();
4592 if (_b->isUniform()) {
4599 h->SetOption(
"nostyle");
4600 h->GetXaxis()->SetName(
TString::Format(
"%s;%s", ax->GetParent()->GetName(), ax->GetName()));
4608 if (get<RooProduct>()) {
4612 if (get<RooAbsData>()) {
4613 if (
auto _data = get<RooDataSet>(); _data) {
4614 auto _ax = (bin) ?
GetXaxis() :
nullptr;
4616 throw std::runtime_error(
"Cannot determine binning to fill data");
4618 if (_ax && _ax->GetNbins() < bin) {
4619 throw std::out_of_range(
TString::Format(
"%s range %s only has %d bins", _ax->GetParent()->GetName(),
4620 _ax->GetName(), _ax->GetNbins()));
4626 for (
auto _c :
coords()) {
4630 cut +=
TString::Format(
"%s==%d", _cat->GetName(), _cat->getCurrentIndex());
4637 TString::Format(
"%s>=%f&&%s<%f", _rv->GetName(), _rv->getMin(_rv->getStringAttribute(
"coordRange")),
4638 _rv->GetName(), _rv->getMax(_rv->getStringAttribute(
"coordRange")));
4641 throw std::runtime_error(
"SetBinContent of data: Unsupported coordinate type");
4650 cut2 =
TString::Format(
"%s >= %f && %s < %f", _ax->GetParent()->GetName(), _ax->GetBinLowEdge(bin),
4651 _ax->GetParent()->GetName(), _ax->GetBinUpEdge(bin));
4683 l.remove(*_data->get(),
true,
true);
4688 _data->addColumn(*
x);
4698 for (
auto &o :
obs) {
4700 if (
auto dv =
dynamic_cast<RooRealVar *
>(_data->get()->find(
v->GetName())); dv) {
4701 if (
v->getMin() < dv->getMin())
4702 dv->setMin(
v->getMin());
4703 if (
v->getMax() > dv->getMax())
4704 dv->setMax(
v->getMax());
4707 if (
auto dc =
dynamic_cast<RooCategory *
>(_data->get()->find(
c->GetName())); dc) {
4708 if (!dc->hasLabel(
c->getCurrentLabel())) {
4709 dc->defineType(
c->getCurrentLabel(),
c->getCurrentIndex());
4718 if (
auto _nentries = std::unique_ptr<RooAbsData>(_data->reduce(cutFormula))->numEntries();
4719 _nentries != _ax->GetNbins()) {
4722 if (_nentries > 0) {
4723 Info(
"SetBinContent",
"Binning %s in channel: %s",
GetName(), cut.
Data());
4724 auto _reduced = std::unique_ptr<RooAbsData>(_data->reduce(icutFormula));
4726 for (
int j = 0; j < _reduced->numEntries(); j++) {
4727 auto _obs = _reduced->get(j);
4728 _data->add(*_obs, _reduced->weight());
4731 for (
int i = 1; i <= _ax->GetNbins(); i++) {
4735 dynamic_cast<RooAbsLValue *
>(_ax->GetParent())->setBin(i - 1, _ax->GetName());
4736 _data->add(
obs, _contents.
at(i - 1));
4741 if (std::unique_ptr<RooAbsData>(_data->reduce(cutFormula2))->numEntries() > 0) {
4742 auto _reduced = std::unique_ptr<RooAbsData>(_data->reduce(icutFormula2));
4744 for (
int j = 0; j < _reduced->numEntries(); j++) {
4745 auto _obs = _reduced->get(j);
4746 _data->add(*_obs, _reduced->weight());
4750 dynamic_cast<RooAbsLValue *
>(_ax->GetParent())->setBin(bin - 1, _ax->GetName());
4753 return bb->SetBinContent(bin,
value, par, parVal);
4756 }
else if (get<RooDataHist>()) {
4757 throw std::runtime_error(
"RooDataHist not supported yet");
4761 if (
auto _varies =
variations(); !_varies.empty() || (par && strlen(par))) {
4762 if (!par || strlen(par) == 0) {
4763 return _varies[
"nominal"]->SetBinContent(bin,
value, par, parVal);
4764 }
else if (
auto it = _varies.find(
Form(
"%s=%g", par, parVal)); it) {
4765 return it->SetBinContent(bin,
value);
4777 if (!par || strlen(par) == 0) {
4790 if (strcmp(
c->GetName(),
Form(
"%g",
c->getVal())) == 0) {
4793#if ROOT_VERSION_CODE < ROOT_VERSION(6, 24, 00)
4806 auto bin_pars =
f->dataHist().get(bin - 1);
4807 if (
f->getAttribute(
"density")) {
4808 value /=
f->dataHist().binVolume(*bin_pars);
4810 f->dataHist().set(*bin_pars,
value);
4813 if (
auto otherfName =
f->getStringAttribute(
"symmetrized_by"); otherfName) {
4815 f->setStringAttribute(
"symmetrized_by",
nullptr);
4816 if (
auto x = getObject<RooAbsArg>(otherfName);
x) {
4817 x->setStringAttribute(
"symmetrizes",
nullptr);
4818 x->setStringAttribute(
"symmetrize_nominal",
nullptr);
4820 }
else if (
auto otherfName2 =
f->getStringAttribute(
"symmetrizes"); otherfName2) {
4821 auto nomf = getObject<RooHistFunc>(
f->getStringAttribute(
"symmetrize_nominal"));
4822 auto otherf = getObject<RooHistFunc>(otherfName2);
4823 if (nomf && otherf) {
4824 otherf->dataHist().set(*bin_pars, 2 * nomf->dataHist().weight(bin - 1) -
value);
4825 otherf->setValueDirty();
4832 f2->setNominal(
value);
4841 push_back(std::make_shared<xRooNode>(
data));
4848 return node->SetBinContent(bin,
value);
4855 push_back(std::make_shared<xRooNode>(
data));
4862 return node->SetContents(obj);
4869 if (get<RooProduct>()) {
4873 if (
auto _varies =
variations(); !_varies.empty()) {
4874 return _varies[
"nominal"]->SetBinError(bin,
value);
4889 while (_prodParent && !_prodParent->get<
RooProduct>() && !_prodParent->get<
RooAbsPdf>()) {
4891 _prodParent.reset();
4894 _prodParent = _prodParent->fParent;
4897 (_prodParent && !_prodParent->get<
RooAbsPdf>()) ? _prodParent->factors().find(
"statFactor") :
nullptr;
4898 auto f_stat = (_f_stat) ? _f_stat->get<
ParamHistFunc>() :
nullptr;
4899 if (_f_stat && _f_stat->get() && !f_stat) {
4900 throw std::runtime_error(
"stat factor must be a paramhistfunc");
4909 for (
auto &
p :
xRooNode(
"tmp", *
f, std::shared_ptr<xRooNode>(
nullptr)).vars()) {
4914 auto h = std::unique_ptr<TH1>(
f->dataHist().createHistogram(parNames
4921 h->SetName(
"statFactor");
4923 h->SetOption(
"blankshape");
4926 auto toMultiply =
this;
4930 f_stat =
dynamic_cast<ParamHistFunc *
>(toMultiply->Multiply(*h).get());
4932 throw std::runtime_error(
"Failed creating stat shapeFactor");
4938 TString prefix =
f->getStringAttribute(
"statPrefix");
4939 if (
value && prefix ==
"") {
4943 while (_p && !(_p->get()->InheritsFrom(
"RooRealSumPdf") || _p->get()->InheritsFrom(
"RooAddPdf") ||
4944 _p->get()->InheritsFrom(
"RooWorkspace") || _p->get()->InheritsFrom(
"RooAddition"))) {
4949 auto newVar = (
value == 0) ? getObject<RooRealVar>(
"1")
4950 : acquire<RooRealVar>(
Form(
"%s_bin%d", prefix.
Data(), bin),
4951 Form(
"#gamma^{%s}_{%d}", prefix.
Data(), bin), 1);
4952#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
4957 auto var =
dynamic_cast<RooRealVar *
>(&pSet[bin - 1]);
4959 if (newVar.get() != var) {
4963 for (std::size_t i = 0; i < pSet.
size(); i++) {
4964 if (
int(i) != bin - 1) {
4965 all.
add(*pSet.
at(i));
4976 if (strcmp(rrv->GetName(),
"1") != 0) {
4977 TString origName = (
f->getStringAttribute(
"origName")) ?
f->getStringAttribute(
"origName") :
GetName();
4979 auto bin_pars =
f->dataHist().get(bin - 1);
4980 auto _binContent =
f->dataHist().weight(bin - 1);
4981 if (
f->getAttribute(
"density")) {
4982 _binContent *=
f->dataHist().binVolume(*bin_pars);
4987 for (
auto &[s, sv] : rrv->stringAttributes()) {
4988 if (s.find(
"sumw_") == 0) {
4990 }
else if (s.find(
"sumw2_") == 0) {
4994 if (sumw2 && sumw2 != std::numeric_limits<double>::infinity()) {
4995 double tau = pow(sumw, 2) / sumw2;
4996 rrv->setError((tau < 1
e-15) ? 1e15 : ( 1. / sqrt(tau)));
4997 rrv->setConstant(
false);
4999 auto _constr =
v.constraints();
5001 if (_constr.empty()) {
5002 rrv->setStringAttribute(
"boundConstraint", _constr.Add(
"poisson").get()->GetName());
5004 auto _glob = _constr.at(0)->obs().at(0)->get<
RooRealVar>();
5007 double _min = tau * (1. - 5. * sqrt(1. / tau));
5008 double _max = tau * (1. + 5. * sqrt(1. / tau));
5009 _glob->setRange(_min, _max);
5011 _constr.at(0)->pp().at(0)->SetBinContent(0, tau);
5012 rrv->setStringAttribute(
"boundConstraint", _constr.at(0)->get()->GetName());
5014 rrv->setRange(std::max((1. - 5. * sqrt(1. / tau)), 1
e-15), 1. + 5. * sqrt(1. / tau));
5017 if (
auto _constr =
v.constraints(); !_constr.empty()) {
5018 v.constraints().Remove(*_constr.at(0));
5023 rrv->setConstant(sumw2 == 0);
5035 auto res =
find(
name, browseResult);
5037 throw std::out_of_range(
name +
" does not exist");
5046 if (
auto _w = get<RooWorkspace>(); _w)
5048 if (
auto a = get<RooAbsArg>();
a &&
GETWS(
a)) {
5059 xRooNode out(
".constraints",
nullptr, *
this);
5062 getConstraint = [&](
const xRooNode &
n,
RooAbsArg &par, std::set<RooAbsPdf *> ignore) {
5064 if (ignore.count(_pdf))
5066 ignore.insert(_pdf);
5072 for (
auto &
c :
n.bins()) {
5073 if (
auto oo = getConstraint(*
c, par, ignore); oo) {
5083 for (
auto p : _ws->allPdfs()) {
5084 if (ignore.count(
static_cast<RooAbsPdf *
>(
p)))
5086 if (
p->dependsOn(par)) {
5087 out.emplace_back(std::make_shared<xRooNode>(par.GetName(), *
p, *
this));
5093 return getConstraint(*
n.fParent, par, ignore);
5095 for (
auto p : o->pdfList()) {
5096 if (ignore.count(
static_cast<RooAbsPdf *
>(
p)))
5098 if (
p->dependsOn(par)) {
5099 out.emplace_back(std::make_shared<xRooNode>(par.GetName(), *
p, *
this));
5105 for (
auto &
p :
vars()) {
5109 if (
v->getAttribute(
"Constant") &&
v != get<RooAbsReal>())
5111 if (
v->getAttribute(
"obs"))
5113 getConstraint(*
this, *
v, {get<RooAbsPdf>()});
5121 auto it = out.std::vector<std::shared_ptr<xRooNode>>
::begin();
5122 while (it != out.std::vector<std::shared_ptr<xRooNode>>
::end()) {
5123 bool removeIt =
false;
5124 for (
auto &
c : out) {
5125 if (
c.get() == it->get())
5129 std::set<std::string> parNames;
5130 std::string _cName =
c->GetName();
5132 parNames.insert(_cName.substr(0, _cName.find(
';')));
5133 _cName = _cName.substr(_cName.find(
';') + 1);
5134 }
while (_cName.find(
';') != std::string::npos);
5135 parNames.insert(_cName);
5136 _cName = it->get()->GetName();
5138 parNames.insert(_cName.substr(0, _cName.find(
';')));
5139 _cName = _cName.substr(_cName.find(
';') + 1);
5140 }
while (_cName.find(
';') != std::string::npos);
5141 parNames.insert(_cName);
5143 for (
auto &
x : parNames) {
5144 if (!_cName.empty())
5148 c->TNamed::SetName(_cName.c_str());
5161 if (get<RooAbsArg>() && get<RooAbsArg>()->isFundamental()) {
5162 for (
auto &o : out) {
5163 o->TNamed::SetName(o->get()->GetName());
5177 sName =
TString(
"factory:") + sName;
5181 if (
auto h = get<TH1>();
h) {
5183 std::map<std::string, std::string> stringAttrs;
5185 auto pos = sOpt2.
Index(
"=");
5186 auto start = sOpt2.
Index(
";") + 1;
5192 stringAttrs[sOpt2(start, pos - start)] = sOpt2(pos + 1,
end - pos - 1);
5198 origName = origName(1, origName.
Length());
5201 newObjName(1, newObjName.
Length());
5208 TString varName =
h->GetXaxis()->GetName();
5209 std::string binningName = newObjName.
Data();
5210 if (
auto pos = varName.
Index(
';'); pos != -1) {
5211 binningName = varName(pos + 1, varName.
Length());
5212 varName = varName(0, pos);
5215 if (varName ==
"xaxis" &&
5217 if (
auto ax = acquirer.
GetXaxis(); ax) {
5218 varName = ax->GetParent()->GetName();
5220 binningName = ax->GetName();
5221 }
else if (acquirer.
obs().size() == 1)
5222 varName = acquirer.
obs().
at(0)->get()->GetName();
5224 auto x = acquirer.
acquire<
RooRealVar>(varName,
h->GetXaxis()->GetTitle(),
h->GetXaxis()->GetXmin(),
5225 h->GetXaxis()->GetXmax());
5226 if (
x->getMin() >
h->GetXaxis()->GetXmin())
5227 x->setMin(
h->GetXaxis()->GetXmin());
5228 if (
x->getMax() <
h->GetXaxis()->GetXmax())
5229 x->setMax(
h->GetXaxis()->GetXmax());
5230 if (!
x->hasBinning(binningName.c_str())) {
5231 if (
h->GetXaxis()->IsVariableBinSize()) {
5232 x->setBinning(
RooBinning(
h->GetNbinsX(),
h->GetXaxis()->GetXbins()->GetArray()), binningName.c_str());
5235 RooUniformBinning(
h->GetXaxis()->GetXmin(),
h->GetXaxis()->GetXmax(),
h->GetXaxis()->GetNbins()),
5236 binningName.c_str());
5238 x->getBinning(binningName.c_str()).
SetTitle(
h->GetXaxis()->GetTitle());
5239 if (
x->getBinningNames().size() == 2) {
5241 x->setBinning(
x->getBinning(binningName.c_str()));
5245 if (
x->getBinning(binningName.c_str()).numBins() !=
h->GetNbinsX()) {
5246 throw std::runtime_error(
5247 TString::Format(
"binning mismatch for binning %s of %s", binningName.c_str(),
x->GetName()));
5251 std::shared_ptr<RooAbsArg> _f;
5257 for (
auto &[k,
v] : stringAttrs) {
5258 _f->setStringAttribute(k.c_str(),
v.c_str());
5260 x->setAttribute(
"obs",
true);
5261 }
else if (sOpt2.
Contains(
"shape")) {
5263 for (
int i = 0; i <
x->getBinning(binningName.c_str()).numBins(); i++) {
5264 std::shared_ptr<RooAbsArg> arg;
5265 if (sOpt2.
Contains(
"blankshape")) {
5270 }
else if (
h->GetMinimumStored() != -1111 ||
h->GetMaximumStored() != -1111) {
5273 h->GetBinContent(i + 1),
h->GetMinimumStored(),
5274 h->GetMaximumStored());
5278 h->GetBinContent(i + 1));
5285 auto tmp =
dynamic_cast<RooAbsBinning *
>(
x->getBinningPtr(
nullptr)->Clone());
5286 x->setBinning(
x->getBinning(binningName.c_str()));
5288#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
5289 dynamic_cast<ParamHistFunc *
>(_f.get())->_paramSet.setName(
"paramSet");
5292 .setName(
"paramSet");
5294 x->setBinning(*tmp);
5296 for (
auto &[k,
v] : stringAttrs) {
5297 _f->setStringAttribute(k.c_str(),
v.c_str());
5301 binningName.c_str() );
5303 throw std::runtime_error(
"Couldn't make data hist");
5308 f->setAttribute(
"autodensity");
5311 for (
auto &[k,
v] : stringAttrs) {
5312 _f->setStringAttribute(k.c_str(),
v.c_str());
5316 _f->setStringAttribute(
"xvar",
x->GetName());
5317 _f->setStringAttribute(
"binning", binningName.c_str());
5318 if (strcmp(_f->GetName(), origName.
Data()) && !_f->getStringAttribute(
"alias"))
5319 _f->setStringAttribute(
"alias", origName);
5322 xRooNode tmp(
h->GetName(), _f, acquirer);
5324 _f = std::dynamic_pointer_cast<RooAbsArg>(tmp.
fComp);
5327 _f->setStringAttribute(
"xvar",
x->GetName());
5328 _f->setStringAttribute(
"binning", binningName.c_str());
5331 if (strcmp(_f->GetName(), origName.
Data()) && !_f->getStringAttribute(
"alias"))
5332 _f->setStringAttribute(
"alias", origName);
5352 return std::dynamic_pointer_cast<TStyle>(
styles(initObject, autoCreate).
fComp);
5359 auto arg = get<RooAbsArg>();
5360 if (!initObject && !arg && !
gROOT->GetStyle(t)) {
5364 std::unique_ptr<TObject> argInitObject;
5369 if (arg->getStringAttribute(
"style")) {
5370 t = arg->getStringAttribute(
"style");
5371 }
else if (autoCreate) {
5373 argInitObject = std::make_unique<TH1D>(
GetName(),
GetTitle(), 1, 0, 1);
5374 initObject = argInitObject.get();
5380 std::shared_ptr<TStyle>
style;
5382 if (!
gROOT->GetStyle(t)) {
5383 if ((
style = getObject<TStyle>(t.
Data()))) {
5393 if (
auto x =
dynamic_cast<TAttLine *
>(initObject))
5395 if (
auto x =
dynamic_cast<TAttFill *
>(initObject))
5397 if (
auto x =
dynamic_cast<TAttMarker *
>(initObject))
5405 if (arg && !arg->getStringAttribute(
"style")) {
5406 arg->setStringAttribute(
"style",
style->GetName());
5412std::shared_ptr<TObject>
xRooNode::acquire(
const std::shared_ptr<TObject> &arg,
bool checkFactory,
bool mustBeNew)
5417 return fParent->acquire(arg, checkFactory, mustBeNew);
5421 if (_ws && (
get() == _ws || _ws->arg(
GetName()) || (arg && strcmp(arg->GetName(),
GetName()) == 0))) {
5424 if (
auto a =
dynamic_cast<RooAbsArg *
>(arg.get());
a) {
5425 auto out_arg = _ws->arg(
a->GetName());
5426 TString aName = arg->GetName();
5428 while (out_arg && mustBeNew) {
5430 out_arg = _ws->arg(
a->GetName());
5432 if (aName !=
a->GetName())
5433 Warning(
"acquire",
"Renaming to %s",
a->GetName());
5437 if (
auto res = _ws->factory(arg->GetName()); res) {
5444 Info(
"acquire",
"A copy of %s has been added to workspace %s",
a->GetName(), _ws->GetName());
5450 std::set<std::string> setNames;
5453 setNames.insert(aa.first);
5456 for (
auto &aa : setNames)
5458 out_arg = _ws->arg(
a->GetName());
5459 if (
GETWS(out_arg) != _ws) {
5460 out_arg->setWorkspace(*_ws);
5466 out_arg->leafNodeServerList(&leafs);
5467 std::unique_ptr<RooAbsCollection> globals(leafs.
selectByAttrib(
"global",
true));
5468 for (
auto &aa : *globals) {
5469 if (!
globs->contains(*aa)) {
5476 return std::shared_ptr<TObject>(out_arg, [](
TObject *) {});
5477 }
else if (
auto a2 =
dynamic_cast<RooAbsData *
>(arg.get()); a2) {
5483 return std::shared_ptr<TObject>(_ws->embeddedData(arg->GetName()), [](
TObject *) {});
5484 }
else if (arg->InheritsFrom(
"TNamed")) {
5488 out_arg = fr->
Clone();
5493 TString aName = arg->GetName();
5494 out_arg = _ws->genobj(arg->GetName());
5496 while (aNamed && out_arg && mustBeNew) {
5498 out_arg = _ws->genobj(aNamed->
GetName());
5501 if (aName != arg->GetName()) {
5502 Warning(
"acquire",
"Renaming to %s", arg->GetName());
5504 if (_ws->import(*arg,
false )) {
5508 out_arg = _ws->genobj(arg->GetName());
5513 return std::shared_ptr<TObject>(out_arg, [](
TObject *) {});
5520 auto out =
fProvider->getObject(arg->GetName(), arg->ClassName());
5524 auto _owned =
find(
".memory");
5526 _owned = emplace_back(std::make_shared<xRooNode>(
".memory",
nullptr, *
this));
5531 for (
auto &
r : *_owned) {
5532 if (strcmp(
r->GetName(), arg->GetName()) == 0 && strcmp(
r->get()->ClassName(), arg->ClassName()) == 0) {
5538 std::cout <<
GetName() <<
" taking over " << arg->ClassName() <<
"::" << arg->GetName() << std::endl;
5540 return _owned->emplace_back(std::make_shared<xRooNode>(arg->GetName(), arg, *
this))->fComp;
5568 auto _deps =
vars();
5580 auto a = get<RooAbsArg>();
5582 throw std::runtime_error(
"Cannot SetXaxis of non-arg");
5584 auto _x = acquire<RooRealVar>(
name, title, low, high);
5585 _x->setBinning(binning,
a->
GetName());
5586 _x->getBinning(
a->GetName()).SetTitle(title);
5587 if (_x->getBinningNames().size() == 2) {
5589 _x->setBinning(_x->getBinning(
a->GetName()));
5594 if (_x->getMax() < high)
5596 if (_x->getMin() > low)
5600 if (!_deps.find(
name) && get<RooAbsPdf>()) {
5602 _x->setAttribute(
"obs");
5605 a->setStringAttribute(
"xvar", _x->GetName());
5606 a->setStringAttribute(
"binning",
a->GetName());
5625 return find(
name,
false) !=
nullptr;
5630 std::string partname = (
name.find(
'/') != std::string::npos) ?
name.substr(0,
name.find(
'/')) :
name;
5632 : get<RooSimultaneous>();
5633 std::string extra = (_s) ? _s->indexCat().GetName() :
"";
5634 for (
auto &
child : *
this) {
5636 (_obj &&
name == _obj->GetName()) || (_obj && partname == _obj->GetName()) ||
5637 (!extra.empty() && ((extra +
"=" +
name) ==
child->GetName() ||
5638 (extra +
"=" + partname) ==
child->GetName()))) {
5642 return child->at(
name.substr(partname.length() + 1));
5646 if (partname.find(
'.') != 0) {
5650 for (
auto &child2 :
x.browse()) {
5651 if (
auto _obj = child2->get();
name == child2->GetName() || partname == child2->GetName() ||
5652 (_obj &&
name == _obj->GetName()) ||
5653 (_obj && partname == _obj->GetName())) {
5656 if (partname !=
name &&
name != child2->GetName()) {
5657 return child2->at(
name.substr(partname.length() + 1));
5667 auto child2 =
at(s.Atoi());
5668 if (partname !=
name) {
5669 return child2->at(
name.substr(partname.length() + 1));
5674 if (get<RooWorkspace>() &&
name !=
".memory") {
5676 auto out = std::make_shared<xRooNode>(obj, *
this);
5687 std::string partname = (
name.find(
'/') != std::string::npos) ?
name.substr(0,
name.find(
'/')) :
name;
5690 : get<RooSimultaneous>();
5691 std::string extra = (_s) ? _s->indexCat().GetName() :
"";
5692 std::shared_ptr<xRooNode> folderNode;
5693 for (
auto &
child : *
this) {
5696 ((extra +
"=" +
name) ==
child->GetName() || (extra +
"=" + partname) ==
child->GetName()))) {
5699 return child->operator[](
name.substr(partname.length() + 1));
5705 for (
auto &child2 :
x.browse()) {
5706 if (
name == child2->GetName() || partname == child2->GetName()) {
5708 if (partname !=
name &&
name != child2->GetName()) {
5709 return child2->operator[](
name.substr(partname.length() + 1));
5715 if (
child->fFolder == (std::string(
"!") + partname)) {
5717 folderNode = std::make_shared<xRooNode>(
child->fFolder.c_str(),
nullptr, *
this);
5718 folderNode->push_back(
child);
5722 if (partname !=
name) {
5723 return folderNode->operator[](
name.substr(partname.length() + 1));
5729 auto child2 =
at(s.Atoi());
5730 if (partname !=
name) {
5731 return child2->operator[](
name.substr(partname.length() + 1));
5735 auto out = std::make_shared<xRooNode>(partname.c_str(),
nullptr, *
this);
5737 if (get<RooWorkspace>() && partname ==
"pdfs") {
5738 out->SetName(
"!pdfs");
5740 if (partname !=
name) {
5741 return out->operator[](
name.substr(partname.length() + 1));
5749 for (
auto o : *
gROOT->GetListOfBrowsers()) {
5751 if (!
b || !
b->GetBrowserImp())
5758 if (!
b->GetBrowserImp())
5774 for (
auto o : *
gROOT->GetListOfBrowsers()) {
5776 if (!
b || !
b->GetBrowserImp())
5783 if (
b->GetBrowserImp()) {
5789 if (
auto item =
GETLISTTREE(_b)->FindItemByObj(_root,
const_cast<xRooNode *
>(
this)); item) {
5800 if (
auto a = get<RooAbsArg>();
a)
5801 a->setStringAttribute(
"alias",
name);
5802 for (
auto o : *
gROOT->GetListOfBrowsers()) {
5803 if (
auto b =
dynamic_cast<TBrowser *
>(o);
b) {
5805 item->SetText(
name);
5813 if (
auto o = (get<TNamed>()); o) {
5828 auto findByObj = [&](
const std::shared_ptr<xRooNode> &
n) {
5829 std::vector<std::shared_ptr<xRooNode>> &nn = *
this;
5830 for (
auto &
c : nn) {
5831 if (
c->get() ==
n->get() && strcmp(
n->GetName(),
c->GetName()) == 0)
5834 return std::shared_ptr<xRooNode>(
nullptr);
5837 auto appendChildren = [&](
const xRooNode &
n) {
5839 const std::vector<std::shared_ptr<xRooNode>> &nn(
n);
5840 for (
auto &
c : nn) {
5841 if (
auto existing = findByObj(
c); existing) {
5843 existing->fFolder =
c->fFolder;
5853 const std::vector<std::shared_ptr<xRooNode>> &nn2(*
this);
5854 for (
auto &
c : nn2) {
5855 if (strlen(
c->GetName()) > 0 && (
c->GetName()[0] ==
'.')) {
5859 if (strcmp(
c->GetName(),
"!.pars") == 0) {
5870 size_t addedChildren = 0;
5874 if (get<RooWorkspace>()) {
5875 addedChildren += appendChildren(
datasets());
5889 addedChildren += appendChildren(
components());
5890 if (!get<RooWorkspace>())
5891 addedChildren += appendChildren(
factors());
5893 auto _coefs =
coefs();
5894 if (_coefs.get() && strcmp(_coefs->GetName(),
"1") != 0 && strcmp(_coefs->GetName(),
"ONE") != 0) {
5895 if (_coefs.size() == 1 && _coefs.get<
RooAddition>()) {
5896 if (strcmp(_coefs.at(0)->GetName(),
"1") != 0 &&
5897 strcmp(_coefs.at(0)->GetName(),
"ONE") != 0) {
5898 auto coef = std::make_shared<xRooNode>(
".coef", *_coefs.at(0)->get(), *
this);
5899 if (
auto existing = findByObj(coef); existing) {
5901 existing->fFolder = _coefs.at(0)->fFolder;
5907 if (
auto existing =
find(_coefs.GetName()); existing) {
5909 existing->fFolder = _coefs.fFolder;
5911 emplace_back(std::make_shared<xRooNode>(_coefs));
5915 addedChildren += appendChildren(
variations());
5916 if (get<ParamHistFunc>() || get<RooSimultaneous>())
5917 addedChildren += appendChildren(
bins());
5918 if (get<RooAbsData>())
5919 addedChildren += appendChildren(
obs());
5922 if (
auto arg = get<RooAbsArg>(); arg && addedChildren == 0) {
5923 for (
int i = 0; i < arg->numProxies(); i++) {
5924 auto _proxy = arg->getProxy(i);
5926 auto c = std::make_shared<xRooNode>(
TString::Format(
".%s", _proxy->name()), *(
a->absArg()), *
this);
5927 if (
auto existing = findByObj(
c); existing) {
5929 existing->fFolder =
c->fFolder;
5934 for (
auto &
child : *
this) {
5935 if (strcmp(
child->GetName(),
c->GetName()) == 0) {
5942 for (
auto a2 : *s) {
5943 auto c = std::make_shared<xRooNode>(*a2, *
this);
5944 if (arg->numProxies() != 1) {
5945 c->fFolder = std::string(
"!.") +
5948 if (
auto existing = findByObj(
c); existing) {
5950 existing->fFolder =
c->fFolder;
5966 }
else if (
auto ir = get<RooStats::HypoTestInverterResult>()) {
5970 if (strcmp(
c->GetName(),
".memory") == 0 &&
c->get<
xRooHypoSpace>()) {
5978 fBrowsables.emplace_back(std::make_shared<xRooNode>(
".memory", std::make_shared<xRooHypoSpace>(ir), *
this));
5985 for (
auto a : _axes) {
5986 if (
a != _axes.first())
5989 TString::Format(
"%s=%g",
a->GetName(), hp.coords->getRealValue(
a->GetName(), ir->GetXValue(i)));
5991 auto hpn = emplace_back(std::make_shared<xRooNode>(coordString, hp.hypoTestResult, hs));
5993 hpn->fBrowsables.emplace_back(std::make_shared<xRooNode>(
5999 std::vector<std::shared_ptr<xRooNode>> &nn = *
this;
6000 for (
auto &
c : nn) {
6010 }
else if (get<RooStats::HypoTestResult>()) {
6023 std::make_shared<xRooNLLVar::xRooHypoPoint>(std::dynamic_pointer_cast<RooStats::HypoTestResult>(
fComp));
6024 fBrowsables.emplace_back(std::make_shared<xRooNode>(
".memory", shp, *
this));
6030 if (
auto fit = hp->
ufit()) {
6031 fits.emplace_back(std::make_shared<xRooNode>(fit, *
this))->TNamed::SetName(
"ufit");
6034 fits.emplace_back(std::make_shared<xRooNode>(fit, *
this))->TNamed::SetName(
"cfit_null");
6037 fits.emplace_back(std::make_shared<xRooNode>(fit, *
this))->TNamed::SetName(
"cfit_alt");
6039 if (
auto fit = hp->
gfit()) {
6040 fits.emplace_back(std::make_shared<xRooNode>(fit, *
this))->TNamed::SetName(
"gfit");
6042 if (
auto asi = hp->
asimov()) {
6043 auto asiP = fits.emplace_back(std::make_shared<xRooNode>(
6044 asi->hypoTestResult ? asi->hypoTestResult : std::make_shared<RooStats::HypoTestResult>(asi->result()),
6046 asiP->TNamed::SetName(
"asimov");
6047 asiP->fBrowsables.emplace_back(std::make_shared<xRooNode>(
".memory", asi, asiP));
6049 appendChildren(fits);
6053 auto it = std::vector<std::shared_ptr<xRooNode>>
::begin();
6054 while (it != std::vector<std::shared_ptr<xRooNode>>
::end()) {
6055 if (it->get()->fTimes == 0) {
6056 for (
auto o : *
gROOT->GetListOfBrowsers()) {
6058 if (
b &&
b->GetBrowserImp()) {
6067 if (
auto item =
GETLISTTREE(_b)->FindItemByObj(_root,
this); item) {
6105 xRooNode out(
".obs", std::make_shared<RooArgList>(), *
this);
6107 for (
auto o :
vars()) {
6110 out.emplace_back(o);
6121 xRooNode out(
".globs", std::make_shared<RooArgList>(), *
this);
6123 for (
auto o :
obs()) {
6126 out.emplace_back(o);
6137 xRooNode out(
".robs", std::make_shared<RooArgList>(), *
this);
6139 for (
auto o :
obs()) {
6142 out.emplace_back(o);
6157 xRooNode out(
".pars", std::make_shared<RooArgList>(), *
this);
6159 for (
auto o :
vars()) {
6162 out.emplace_back(o);
6173 xRooNode out(
".consts", std::make_shared<RooArgList>(), *
this);
6175 for (
auto o :
pars()) {
6178 out.emplace_back(o);
6190 xRooNode out(
".floats", std::make_shared<RooArgList>(), *
this);
6192 for (
auto o :
pars()) {
6195 out.emplace_back(o);
6207 xRooNode out(
".poi", std::make_shared<RooArgList>(), *
this);
6209 for (
auto o :
pars()) {
6212 out.emplace_back(o);
6224 xRooNode out(
".np", std::make_shared<RooArgList>(), *
this);
6226 for (
auto o :
pars()) {
6228 (!o->get<
RooAbsArg>()->getAttribute(
"Constant") && !o->get<
RooAbsArg>()->getAttribute(
"poi") &&
6231 out.emplace_back(o);
6242 xRooNode out(
".pp", std::make_shared<RooArgList>(), *
this);
6244 for (
auto o :
pars()) {
6248 out.emplace_back(o);
6259 xRooNode out(
".vars", std::make_shared<RooArgList>(), *
this);
6261 if (
auto coll = get<RooAbsCollection>(); coll) {
6262 for (
auto &
x : *
this) {
6263 for (
auto &
y :
x->vars()) {
6269 if (
auto p = get<RooAbsArg>();
p) {
6275 p->leafNodeServerList(&allLeaves);
6276 for (
auto &
c : allLeaves) {
6278 if (!
c->getAttribute(
"global")) {
6280 out.emplace_back(std::make_shared<xRooNode>(*
c, *
this));
6282 if (
c->getAttribute(
"global")) {
6283 _globs.emplace_back(std::make_shared<xRooNode>(*
c, *
this));
6284 _globs.back()->fFolder =
"!globs";
6285 }
else if (
c->getAttribute(
"obs")) {
6286 out.back()->fFolder =
"!robs";
6287 }
else if (
c->getAttribute(
"poi")) {
6288 out.back()->fFolder =
"!poi";
6289 }
else if (
c->getAttribute(
"np") ||
6291 out.back()->fFolder =
"!np";
6293 out.back()->fFolder =
"!floats";
6295 out.back()->fFolder =
"!pp";
6299 for (
auto g : _globs) {
6301 out.emplace_back(
g);
6303 }
else if (
auto p2 = get<RooAbsData>(); p2) {
6304 for (
auto a : *p2->get()) {
6305 a->setAttribute(
"obs");
6306 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
6309 if (
auto _dglobs = p2->getGlobalObservables()) {
6310 for (
auto &
a : *_dglobs) {
6311 a->setAttribute(
"obs");
6312 a->setAttribute(
"global");
6313 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
6318 a->setAttribute(
"obs");
6319 a->setAttribute(
"global");
6320 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
6323 }
else if (
auto _ws =
ws(); _ws) {
6325 for (
auto a : *_globs2) {
6326 a->setAttribute(
"obs");
6327 a->setAttribute(
"global");
6328 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
6332 for (
auto &_g : _gl->second) {
6333 auto _clone = std::shared_ptr<RooAbsArg>(
dynamic_cast<RooAbsArg *
>(_g->Clone(_g->GetName())));
6334 if (
auto v = std::dynamic_pointer_cast<RooAbsRealLValue>(_clone);
v && _g->getStringAttribute(
"nominal"))
6335 v->setVal(
TString(_g->getStringAttribute(
"nominal")).
Atof());
6336 out.emplace_back(std::make_shared<xRooNode>(_clone, *
this));
6344 for (
auto &_g : *_globs3) {
6345 auto _clone = std::shared_ptr<RooAbsArg>(
dynamic_cast<RooAbsArg *
>(_g->Clone(_g->GetName())));
6346 if (
auto v = std::dynamic_pointer_cast<RooAbsRealLValue>(_clone);
v && _g->getStringAttribute(
"nominal"))
6347 v->setVal(
TString(_g->getStringAttribute(
"nominal")).
Atof());
6348 out.emplace_back(std::make_shared<xRooNode>(_clone, *
this));
6353 }
else if (
auto w = get<RooWorkspace>();
w) {
6354 for (
auto a :
w->components()) {
6357 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
6366 xRooNode out(
".components",
nullptr, *
this);
6368 if (
auto p = get<RooAddPdf>();
p) {
6370 std::set<RooAbsArg *> donePdfs;
6371 for (
auto &o :
p->pdfList()) {
6372 if (donePdfs.count(o))
6374 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
6377 }
else if (
auto p2 = get<RooRealSumPdf>(); p2) {
6391 std::set<RooAbsArg *> doneFuncs;
6392 for (
auto &o : p2->funcList()) {
6393 if (doneFuncs.count(o))
6395 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
6396 doneFuncs.insert(o);
6398 }
else if (
auto p3 = get<RooAddition>(); p3) {
6399 for (
auto &o : p3->list()) {
6400 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
6402 }
else if (
auto p4 = get<RooAbsCollection>(); p4) {
6403 for (
auto &
a : *p4) {
6404 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
6406 }
else if (
auto p5 = get<RooWorkspace>(); p5) {
6407 for (
auto &o : p5->components()) {
6410 bool hasClients =
false;
6411 for (
auto &
c : o->clients()) {
6412 if (!
c->InheritsFrom(
"RooRealIntegral") && p5 ==
GETWS(
c)) {
6419 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
6420 if (o->InheritsFrom(
"RooAbsPdf")) {
6421 out.back()->fFolder =
"!pdfs";
6423 out.back()->fFolder =
"!scratch";
6426 for (
auto &o : p5->allGenericObjects()) {
6430 s = s(0, s.
Index(
';'));
6431 if (
auto _pdf = out.
find(s.
Data()); _pdf) {
6433 out.emplace_back(std::make_shared<xRooNode>(fr->GetName(), *fr, _pdf));
6440 out.emplace_back(std::make_shared<xRooNode>(fr->GetName(), *fr, *
this));
6442 out.back()->fFolder =
"!fits";
6444 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
6445 if (strcmp(out.back()->get()->
ClassName(),
"TStyle") == 0) {
6446 out.back()->fFolder =
"!styles";
6447 }
else if (strcmp(out.back()->get()->
ClassName(),
"RooStats::HypoTestInverterResult") == 0) {
6448 out.back()->fFolder =
"!scans";
6449 }
else if (strcmp(out.back()->get()->
ClassName(),
"RooStats::ModelConfig") == 0) {
6450 out.back()->fFolder =
"!models";
6452 out.back()->fFolder =
"!objects";
6459 if (k.find(
"CACHE_") == 0)
6461 out.emplace_back(std::make_shared<xRooNode>(k.c_str(),
v, *
this));
6462 out.back()->fFolder =
"!sets";
6468 while ((snap = iter->Next())) {
6469 out.emplace_back(std::make_shared<xRooNode>(*snap, *
this));
6470 out.back()->fFolder =
"!snapshots";
6472 }
else if (
auto mc = get<RooStats::ModelConfig>()) {
6475 out.emplace_back(std::make_shared<xRooNode>(
".pdf", *mc->GetPdf(), *
this));
6477 if (mc->GetExternalConstraints()) {
6478 out.emplace_back(std::make_shared<xRooNode>(
".extCons", *mc->GetExternalConstraints(), *
this));
6484 out.emplace_back(
c);
6491 out.emplace_back(
c);
6505 xRooNode out(
".bins",
nullptr, *
this);
6507 if (
auto p = get<RooSimultaneous>();
p) {
6508 std::map<int, std::shared_ptr<xRooNode>> cats;
6509 for (
auto &
c :
p->indexCat()) {
6510 auto pp =
p->getPdf(
c.first.c_str());
6516 for (
auto &[
_,
n] : cats)
6517 out.emplace_back(
n);
6518 }
else if (
auto phf = get<ParamHistFunc>(); phf) {
6520#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
6521 auto &pSet = phf->_paramSet;
6523 auto &pSet = phf->paramList();
6525 for (
auto par : pSet) {
6526 out.emplace_back(std::make_shared<xRooNode>(*par, *
this));
6527 out.back()->fBinNumber = i;
6530 }
else if (
auto ax =
GetXaxis(); ax) {
6531 for (
int i = 1; i <= ax->GetNbins(); i++) {
6533 std::vector<RooAbsArg *> _factors;
6537 for (
auto &ss :
f->bins()[i - 1]->factors())
6538 _factors.push_back(ss->get<
RooAbsArg>());
6540 _factors.push_back(
f->bins()[i - 1]->get<
RooAbsArg>());
6544 out.emplace_back(std::make_shared<xRooNode>(
6545 TString::Format(
"%g<=%s<%g", ax->GetBinLowEdge(i), ax->GetParent()->GetName(), ax->GetBinLowEdge(i + 1)),
6546 _factors.empty() ? nullptr
6550 for (
auto f : _factors) {
6551#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
6557 out.back()->fBinNumber = i;
6571 auto parentCoefs =
fParent->coefs(
true);
6582 std::make_shared<RooProduct>(
".recursiveCoefs",
6587 auto mem = out.emplace_back(std::make_shared<xRooNode>(
".memory",
nullptr, *
this));
6588 mem->emplace_back(std::make_shared<xRooNode>(ourCoefs));
6589 mem->emplace_back(std::make_shared<xRooNode>(parentCoefs));
6593 bool isResidual =
false;
6601 if (!parent->fComp) {
6602 while (!parent->fComp && parent->fParent) {
6603 parent = parent->fParent;
6606 parent = parent->fParent;
6612 for (
auto &o :
p->funcList()) {
6614 if (i >=
p->coefList().size()) {
6616 coefs.add(
p->coefList());
6618 coefs.add(*
p->coefList().at(i));
6623 }
else if (
auto p2 = parent->get<
RooAddPdf>(); p2) {
6625 if (p2->coefList().empty()) {
6630 for (
auto &o : p2->pdfList()) {
6632 if (i >= p2->coefList().size()) {
6634 coefs.add(p2->coefList());
6636 coefs.add(*p2->coefList().at(i));
6647 auto coefSum =
coefs.empty()
6650 : std::make_shared<RooAddition>((isResidual) ?
".sumOfCoefs" :
".coefs",
6651 "Coefficients of",
coefs));
6652 xRooNode out(
".coef", coefSum ? std::dynamic_pointer_cast<RooAbsArg>(std::make_shared<RooFormulaVar>(
6653 ".coef",
"1-sum(otherCoefs)",
"1. - @0", *coefSum))
6655 if (coefSum &&
coefs.size() != 1) {
6656 out.emplace_back(std::make_shared<xRooNode>(
".memory",
nullptr, *
this))
6658 std::make_shared<xRooNode>(
".sumOfCoefs", coefSum, out));
6660 if (!
coefs.empty()) {
6664 }
else if (
coefs.size() == 1) {
6666 if (!
coefs.empty()) {
6675 xRooNode out(
".coefs", coefSum, *
this);
6685 xRooNode out(
".factors",
nullptr, *
this);
6687 if (
auto p = get<RooProdPdf>();
p) {
6689 if (
auto a = _main.get<
RooRealSumPdf>();
a && !
a->getStringAttribute(
"alias")) {
6690 a->setStringAttribute(
"alias",
"samples");
6692 a2->setStringAttribute(
"alias",
"components");
6694 int _npdfs =
p->pdfList().size();
6695 for (
auto &o :
p->pdfList()) {
6696 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
6697 if (_npdfs > 5 && o != _main.get() && out.back()->robs().size() == 0)
6698 out.back()->fFolder =
"!constraints";
6700 }
else if (
auto p2 = get<RooProduct>(); p2) {
6701 for (
auto &o : p2->components()) {
6702 if (o->InheritsFrom(
"RooProduct")) {
6704 auto x =
xRooNode(
"tmp", *o, *
this).factors();
6706 out.emplace_back(std::make_shared<xRooNode>(
n->GetName(),
n->fComp, *
this));
6709 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
6712 }
else if (
auto w = get<RooWorkspace>();
w) {
6718 for (
auto a :
w->allFunctions()) {
6719 if (_obs.contains(*
a))
6722 for (
auto c :
a->clients()) {
6724 if (
c->InheritsFrom(
"RooProduct")) {
6730 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
6774 xRooNode out(
".variations",
nullptr, *
this);
6786 if (
auto p2 = get<PiecewiseInterpolation>(); p2) {
6787#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
6788 out.emplace_back(std::make_shared<xRooNode>(
"nominal", p2->_nominal.arg(), *
this));
6790 out.emplace_back(std::make_shared<xRooNode>(
"nominal", *(p2->nominalHist()), *
this));
6792 for (
size_t i = 0; i < p2->paramList().
size(); i++) {
6794 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=1", p2->paramList().at(i)->GetName()),
6795 *p2->highList().at(i), *
this));
6796 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=-1", p2->paramList().at(i)->GetName()),
6797 *p2->lowList().at(i), *
this));
6799 }
else if (
auto p3 = get<RooStats::HistFactory::FlexibleInterpVar>(); p3) {
6800#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
6801 out.emplace_back(std::make_shared<xRooNode>(
"nominal",
RooFit::RooConst(p3->_nominal), *
this));
6802 for (
size_t i = 0; i < p3->_paramList.size(); i++) {
6803 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=1", p3->_paramList.at(i)->GetName()),
6805 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=-1", p3->_paramList.at(i)->GetName()),
6809 out.emplace_back(std::make_shared<xRooNode>(
"nominal",
RooFit::RooConst(p3->nominal()), *
this));
6810 for (
size_t i = 0; i < p3->variables().
size(); i++) {
6811 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=1", p3->variables().at(i)->GetName()),
6813 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=-1", p3->variables().at(i)->GetName()),
6818 }
else if (
auto p4 = get<ParamHistFunc>(); p4) {
6837 for (
auto &k : *
this) {
6846 xRooNode out(
".datasets()",
nullptr, *
this);
6851 if (
auto _ws = get<RooWorkspace>(); _ws) {
6852 for (
auto &
d : _ws->allData()) {
6853 out.emplace_back(std::make_shared<xRooNode>(*
d, *
this));
6854 out.back()->fFolder =
"!datasets";
6856 }
else if (get<RooAbsPdf>() ||
6867 for (
auto _c :
coords()) {
6871 cut +=
TString::Format(
"%s==%d", _cat->GetName(), _cat->getCurrentIndex());
6879 cut +=
TString::Format(
"%s>=%f&&%s<%f", _rv->GetName(), _rv->getMin(_rv->getStringAttribute(
"coordRange")),
6880 _rv->GetName(), _rv->getMax(_rv->getStringAttribute(
"coordRange")));
6885 throw std::runtime_error(
"datasets(): Unsupported coordinate type");
6888 if (
auto s = get<RooSimultaneous>()) {
6890 bool hasMissing =
false;
6892 for (
auto cat : s->indexCat()) {
6893 if (!s->getPdf(cat.first.c_str())) {
6898 extraCut +=
TString::Format(
"%s==%d", s->indexCat().GetName(), cat.second);
6904 cut +=
"(" + extraCut +
")";
6905 cutobs.
add(s->indexCat());
6910 auto a =
dynamic_cast<RooAbsArg *
>(ax->GetParent());
6914 for (
auto &
child : *
this) {
6916 _datasets.push_back(
child);
6918 if (
auto __ws =
ws(); __ws) {
6921 _datasets.push_back(
d);
6925 for (
auto &
d : _datasets) {
6926 if (std::unique_ptr<RooAbsCollection>(
d->obs().argList().selectCommon(_obs))->size() == _obs.
size()) {
6933 out.emplace_back(std::make_shared<xRooNode>(
6938 out.back()->get<
RooAbsData>()->setGlobalObservables(*std::unique_ptr<RooAbsCollection>(
6940 if (
d->get()->TestBit(1 << 20))
6941 out.back()->get()->
SetBit(1 << 20);
6943 out.back()->fBrowsables.emplace_back(std::make_shared<xRooNode>(
".sourceds",
d->fComp, *
this));
6945 out.emplace_back(std::make_shared<xRooNode>(
d->fComp, *
this));
6958 }
else if (
auto mc = get<RooStats::ModelConfig>()) {
6967 xRooNode out(
".parents",
nullptr, *
this);
6968 if (
auto a = get<RooAbsArg>()) {
6969 for (
auto c :
a->clients()) {
6970 out.push_back(std::make_shared<xRooNode>(*
c, *
this));
6978 if (
auto w = get<RooWorkspace>()) {
6979 xRooNode out(
".args",
w->components(), *
this);
6982 }
else if (
auto a = get<RooAbsArg>()) {
6983 xRooNode out(
".args", std::make_shared<RooArgList>(), *
this);
6995 if (
b && strcmp(
b->GetName(),
name) == 0)
7004 if (
auto fr = get<RooFitResult>(); fr) {
7008 if (
auto theData = get<RooDataSet>(); theData) {
7010 TH1 *theHist =
nullptr;
7015 theHist =
dynamic_cast<TH1 *
>(o);
7017 theHist =
static_cast<TH1 *
>(theHist->
Clone());
7028 auto vo =
dynamic_cast<TObject *
>(
v);
7029 if (
v &&
obs().
find(vo->GetName())) {
7033 TString::Format(
"my temp hist;%s", strlen(vo->GetTitle()) ? vo->GetTitle() : vo->GetName()),
7034 cat->numTypes(), 0, cat->numTypes());
7036 std::map<int, std::string> cats;
7037 for (
auto &
c : *cat) {
7038 cats[
c.second] =
c.first;
7040 for (
auto &[
_, label] : cats) {
7044 auto _binning =
v->getBinningPtr(
nullptr);
7045 if (_binning->isUniform()) {
7048 TString::Format(
"my temp hist;%s", strlen(vo->GetTitle()) ? vo->GetTitle() : vo->GetName()),
7049 v->numBins(), _binning->lowBound(), _binning->highBound());
7053 TString::Format(
"my temp hist;%s", strlen(vo->GetTitle()) ? vo->GetTitle() : vo->GetName()),
7054 v->numBins(), _binning->array());
7058 throw std::runtime_error(
"Cannot draw dataset without parent PDF");
7061 theHist = _parentPdf->BuildHistogram(
v,
true);
7067 TH1 *xPos =
static_cast<TH1 *
>(theHist->
Clone(
"xPos"));
7069 TH1 *xPos2 =
static_cast<TH1 *
>(theHist->
Clone(
"xPos2"));
7071 auto nHist = std::unique_ptr<TH1>(
static_cast<TH1 *
>(theHist->
Clone(
"nEntries")));
7076 dataGraph->SetName(
GetName());
7077 dataGraph->SetTitle(strlen(theData->GetTitle()) ? theData->GetTitle() : theData->GetName());
7086 if (
auto w = theData->weightVar();
w &&
w->getStringAttribute(
"fitResult")) {
7089 if (
w->getAttribute(
"expected")) {
7091 dataGraph->SetLineColor(
kBlue);
7094 dataGraph->SetLineColor(
kBlack);
7096 dataGraph->SetMarkerStyle(20);
7097 dataGraph->SetMarkerColor(dataGraph->GetLineColor());
7111 dataGraph->SetTitle(
TString::Format(
"%s = %f", dataGraph->GetTitle(), dataGraph->GetPointX(0)));
7124 auto _pos = pName.
Index(
'=');
7126 int nevent = theData->numEntries();
7127 for (
int i = 0; i < nevent; i++) {
7130 for (
auto _c : _coords) {
7132 if (cat->getIndex() != theData->get()->getCatIndex(cat->GetName())) {
7138 if (!rv->inRange(theData->get()->getRealValue(rv->GetName()), rv->getStringAttribute(
"coordRange"))) {
7146 cat && cat->
getLabel() != pName(_pos + 1, pName.Length())) {
7162 theHist->
Fill((
x) ? xvar->
getVal() : 0.5, theData->weight());
7163 nHist->Fill((
x) ? xvar->
getVal() : 0.5, 1);
7171 for (
int i = 0; i < theHist->
GetNbinsX(); i++) {
7172 if (includeZeros || nHist->GetBinContent(i + 1)) {
7175 dataGraph->SetPoint(dataGraph->GetN(),
7180 xErr = (xErr <= 0) ? 0. : sqrt(xErr);
7183 dataGraph->SetPointError(dataGraph->GetN() - 1, xErr, xErr,
7195 dataGraph->GetHistogram()->GetXaxis()->Set(theHist->
GetNbinsX(), 0, theHist->
GetNbinsX());
7196 for (
int i = 1; i <= theHist->
GetNbinsX(); i++)
7197 dataGraph->GetHistogram()->GetXaxis()->SetBinLabel(i, theHist->
GetXaxis()->
GetBinLabel(i));
7222 auto _styleNode =
styles(dataGraph);
7223 if (
auto _style = _styleNode.get<
TStyle>()) {
7224 *
dynamic_cast<TAttLine *
>(dataGraph) = *_style;
7225 *
dynamic_cast<TAttFill *
>(dataGraph) = *_style;
7226 *
dynamic_cast<TAttMarker *
>(dataGraph) = *_style;
7231 throw std::runtime_error(
"Cannot build graph");
7237 if (
auto _w =
ws(); _w) {
7239 for (
auto o : _w->allGenericObjects()) {
7241 _fr->ResetBit(1 << 20);
7244 res->SetBit(1 << 20);
7246 auto allVars = _w->allVars();
7251 throw std::runtime_error(
"Not supported yet");
7265 throw std::runtime_error(
"Not a RooFitResult");
7271 if (get<RooFitResult>())
7273 if (get<RooAbsData>()) {
7274 if (
auto _fr =
find(
".fitResult"); _fr)
7276#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
7278 if (get<RooDataSet>() && get<RooDataSet>()->weightVar() &&
7279 get<RooDataSet>()->weightVar()->getStringAttribute(
"fitResult")) {
7280 return xRooNode(getObject<const RooFitResult>(get<RooDataSet>()->weightVar()->getStringAttribute(
"fitResult")),
7288 if (sOpt ==
"prefit") {
7295 auto _coefs =
coefs();
7301 std::unique_ptr<RooArgList> _pars(
dynamic_cast<RooArgList *
>(
pars().
argList().selectByAttrib(
"Constant",
false)));
7302 auto fr = std::make_shared<RooFitResult>(
"prefitResult",
"Prefit");
7303 fr->setFinalParList(*_pars);
7304 for (
auto &
p : fr->floatParsFinal()) {
7308 if (
auto s = _v->getStringAttribute(
"nominal"); s)
7311 std::shared_ptr<xRooNode> pConstr;
7312 for (
auto &
c : _constr) {
7315 bool isServer =
true;
7318 for (
auto s :
c->get<
RooAbsArg>()->servers()) {
7319 if (strcmp(s->GetName(),
p->
GetName()) == 0) {
7334 double prefitVal = 0;
7335 double prefitError = 0;
7336 for (
auto &_d : pConstr->vars()) {
7337 if (strcmp(
p->
GetName(), _d->get()->GetName()) == 0)
7341 prefitVal = prefitError;
7342 prefitError = _c->getVal();
7343 }
else if (prefitError == 0) {
7344 prefitError = _d->get<
RooAbsReal>()->getVal();
7350 if (pConstr->get<
RooGaussian>() && pConstr->browse().find(
".sigma")) {
7351 prefitError = pConstr->find(
".sigma")->get<
RooAbsReal>()->getVal();
7357 prefitVal /= prefitError;
7359 prefitError = 1. / sqrt(prefitError);
7361 if (!_v->getStringAttribute(
"nominal"))
7362 _v->setVal(prefitVal);
7363 _v->setError(prefitError);
7372 auto _globs =
globs();
7373 _args.add(_globs.argList());
7374 fr->setConstParList(_args);
7375 std::unique_ptr<RooArgList> _snap(
dynamic_cast<RooArgList *
>(_pars->snapshot()));
7376 for (
auto &
p : *_snap) {
7377 if (
auto atr =
p->getStringAttribute(
"initVal"); atr &&
dynamic_cast<RooRealVar *
>(
p))
7380 fr->setInitParList(*_snap);
7385 if (
auto _w =
ws(); _w) {
7386 auto checkFr = [&](
TObject *o) {
7392 for (
auto p :
pars()) {
7395 if (_fr->floatParsFinal().find(
p->
GetName()) ||
7397 std::abs(_fr->constPars().getRealValue(
p->
GetName(), std::numeric_limits<double>::quiet_NaN()) -
7401 _fr->constPars().getCatIndex(
p->
GetName(), std::numeric_limits<int>().max()))) {
7406 if (!_fr->floatParsFinal().find(
p->
GetName())) {
7409 std::abs(_fr->floatParsFinal().getRealValue(
p->
GetName(),
7410 std::numeric_limits<double>::quiet_NaN()) -
7414 _fr->floatParsFinal().getCatIndex(
p->
GetName(), std::numeric_limits<int>().max()))) {
7423 RooArgList existingFloats(_fr->floatParsFinal());
7424 existingFloats.
remove(newConsts,
true,
true );
7425 auto cov = _fr->reducedCovarianceMatrix(existingFloats);
7426 if (!newFloats.
empty()) {
7428 size_t oldSize = existingFloats.
size();
7429 cov.ResizeTo(oldSize + newFloats.
size(), oldSize + newFloats.
size());
7430 for (
size_t i = 0; i < newFloats.
size(); i++) {
7431 existingFloats.
add(*newFloats.
at(i));
7434 cov(oldSize + i, oldSize + i) = std::pow(
v->getError(), 2);
7438 existingConsts.
remove(newFloats,
true,
true);
7439 existingConsts.
add(newConsts);
7446 auto fr = std::make_shared<RooFitResult>(
TString::Format(
"%s-dirty", _fr->GetName()));
7447 fr->setFinalParList(existingFloats);
7448 fr->setConstParList(existingConsts);
7449 fr->setCovarianceMatrix(cov);
7450 fr->setInitParList(_fr->floatParsInit());
7455 return xRooNode(*_fr, std::make_shared<xRooNode>(*_w, std::make_shared<xRooNode>()));
7460 for (
auto o : _w->allGenericObjects()) {
7461 auto out = checkFr(o);
7466 auto out = checkFr(o);
7473 if (
auto fr = getObject<RooFitResult>(
".fitResult"); fr) {
7479 auto _coefs =
coefs();
7485 std::unique_ptr<RooArgList> _pars(
dynamic_cast<RooArgList *
>(
pars().
argList().selectByAttrib(
"Constant",
false)));
7486 auto fr = std::make_shared<RooFitResult>(
TUUID().AsString());
7488 fr->setFinalParList(*_pars);
7494 for (
int i = 0; i < prevCov->
GetNcols(); i++) {
7495 for (
int j = 0; j < prevCov->
GetNrows(); j++) {
7496 cov(i, j) = (*prevCov)(i, j);
7501 for (
auto &
p : fr->floatParsFinal()) {
7502 if (!prevCov || i >= prevCov->
GetNcols()) {
7504 cov(i, i) = pow(
v->getError(), 2);
7511 int covQualBackup = fr->covQual();
7512 fr->setCovarianceMatrix(cov);
7513 fr->setCovQual(covQualBackup);
7518 auto _globs =
globs();
7519 _args.add(_globs.argList());
7520 fr->setConstParList(_args);
7521 std::unique_ptr<RooArgList> _snap(
dynamic_cast<RooArgList *
>(_pars->snapshot()));
7522 for (
auto &
p : *_snap) {
7523 if (
auto atr =
p->getStringAttribute(
"initVal"); atr &&
dynamic_cast<RooRealVar *
>(
p))
7526 fr->setInitParList(*_snap);
7547 if (!std::isnan(low) && !std::isnan(high) && get<RooRealVar>()) {
7548 if (range && strlen(range)) {
7549 get<RooRealVar>()->setRange(range, low, high);
7551 get<RooRealVar>()->setRange(low, high);
7555 if (
auto o = get<RooAbsArg>(); o)
7556 o->setStringAttribute(
"range", range);
7563 std::string &out =
fRange;
7564 if (
auto o = get<RooAbsArg>(); o && o->getStringAttribute(
"range"))
7565 out = o->getStringAttribute(
"range");
7567 while (out.empty() && _parent) {
7568 if (
auto o = _parent->get<
RooAbsArg>(); o && o->getStringAttribute(
"range"))
7569 out = o->getStringAttribute(
"range");
7570 _parent = _parent->fParent;
7590 for (
auto opt : *defaultOpts) {
7593 for (
auto &i : nllOpts) {
7595 Info(
"nll",
"Overriding NLL Option: %s", o->GetName());
7601 return nll(_data,
l);
7606 if (
auto mc = get<RooStats::ModelConfig>()) {
7610 if (!get<RooAbsPdf>()) {
7612 if (get<RooWorkspace>()) {
7613 std::shared_ptr<xRooNode> mainModel;
7619 throw std::runtime_error(
TString::Format(
"Workspace has multiple models, you must specify which to "
7620 "generate with (found at least %s and %s)",
7621 mainModel->GetName(),
c->GetName()));
7626 return mainModel->generate(fr, expected, seed);
7633 if (get<RooSimultaneous>()) {
7634 std::string selected;
7636 bool hasDeselected =
false;
7637 for (
auto c :
bins()) {
7639 cName = cName(cName.
Index(
'=') + 1, cName.
Length());
7641 hasDeselected =
true;
7643 if (!fromds.empty())
7645 fromds += cName.
Data();
7648 if (!selected.empty())
7650 selected += cName.
Data();
7653 if (hasDeselected) {
7654 std::string dsetName =
"";
7655 if (!fromds.empty()) {
7658 for (
auto &
d : _dsets) {
7659 if (
d->get()->TestBit(1 << 20)) {
7660 dsetName =
d->get()->GetName();
7664 if (dsetName.empty()) {
7665 throw std::runtime_error(
7666 "Need at least one dataset selected (SetChecked) to use for deselected regions");
7670 if (!fromds.empty()) {
7689 auto _globs =
globs();
7690 bool missingGlobs(
false);
7691 for (
auto glob : _globs) {
7692 if (!_fr->constPars().find(*glob->get<
RooAbsArg>())) {
7693 missingGlobs =
true;
7698 std::unique_ptr<RooFitResult> newFr;
7700 newFr = std::make_unique<RooFitResult>(*_fr);
7701 for (
auto glob : _globs) {
7702 if (!newFr->constPars().find(*glob->get<
RooAbsArg>())) {
7710 auto _pars =
pars();
7711 bool missingPars(
false);
7712 for (
auto par : _pars) {
7715 if (!_fr->constPars().find(*par->get<
RooAbsArg>()) && !_fr->floatParsFinal().find(*par->get<
RooAbsArg>())) {
7722 newFr = std::make_unique<RooFitResult>(*_fr);
7723 for (
auto par : _pars) {
7726 if (!newFr->constPars().find(*par->get<
RooAbsArg>()) &&
7727 !newFr->floatParsFinal().find(*par->get<
RooAbsArg>())) {
7744 if (
auto mc = get<RooStats::ModelConfig>()) {
7745 if (mc->GetExternalConstraints()) {
7747 for (
auto o : opts) {
7748 optsWithConstraints.
Add(o->Clone(
nullptr));
7751 return xRooNode(*mc->GetPdf(),
fParent).nll(_data, optsWithConstraints);
7757 if (!get<RooAbsPdf>()) {
7759 if (get<RooWorkspace>()) {
7760 std::shared_ptr<xRooNode> mainPdf, mainModel, otherPdf;
7772 throw std::runtime_error(
TString::Format(
"Workspace has multiple models, you must specify which to "
7773 "build nll with (found at least %s and %s)",
7774 mainModel->GetName(),
c->GetName()));
7779 return mainModel->nll(_data, opts);
7782 throw std::runtime_error(
TString::Format(
"Workspace has multiple pdfs, you must specify which to "
7783 "build nll with (found at least %s and %s)",
7784 mainPdf->GetName(), otherPdf->GetName()));
7786 return mainPdf->nll(_data, opts);
7793 if (get<RooSimultaneous>()) {
7794 std::string selected;
7795 bool hasDeselected =
false;
7796 for (
auto c :
bins()) {
7798 hasDeselected =
true;
7801 cName = cName(cName.Index(
'=') + 1, cName.Length());
7802 if (!selected.empty())
7804 selected += cName.Data();
7814 if (strlen(_data.
GetName()) == 0) {
7817 _d = std::make_shared<xRooNode>(asi.first, *
this);
7820 std::make_shared<xRooNode>(
".globs", std::const_pointer_cast<RooAbsCollection>(asi.second), *_d));
7825 return nll(*_d, opts);
7830 me.push_back(std::make_shared<xRooNode>(_data));
7831 return nll(*me.datasets().at(_data.
GetName()), opts);
7834 auto _globs = _data.
globs();
7847 for (
int i = 0; i < opts.
GetSize(); i++) {
7850 if (strcmp(opts.
At(i)->
GetName(),
"GlobalObservables") == 0) {
7853 _opts->Add(opts.
At(i)->
Clone(
nullptr));
7861 std::dynamic_pointer_cast<RooAbsData>(_data.
fComp), *_opts);
7959 auto rangeName = (_range.empty()) ?
GetRange() : _range;
7960 if (!rangeName.empty()) {
7961 std::vector<TString> patterns;
7963 while (pattern.NextToken()) {
7964 patterns.emplace_back(pattern);
7966 if (
auto s = get<RooSimultaneous>(); s) {
7971 for (
auto &
c :
bins()) {
7973 cName = cName(cName.Index(
'=') + 1, cName.Length());
7974 _cat.setLabel(cName);
7975 bool matchAny =
false;
7976 for (
auto &
p : patterns) {
7978 if (pNoCatName.Contains(
'='))
7979 pNoCatName = pNoCatName(pNoCatName.Index(
'=') + 1, pNoCatName.Length());
7980 if (cName.Contains(
TRegexp(
p,
true)) || cName.Contains(
TRegexp(pNoCatName,
true))) {
7984 if (_cat.hasRange(
p) && _cat.inRange(
p)) {
7989 if ((matchAny && !invert) || (!matchAny && invert)) {
7994 }
else if (
get() && !get<RooAbsCollection>() && !
components().empty()) {
7998 std::vector<TObject *>
funcs;
8000 bool matchAny =
false;
8001 for (
auto &
p : patterns) {
8007 if (!((matchAny && !invert) || (!matchAny && invert)))
8008 funcs.push_back(
c->get());
8012 if (!
funcs.empty()) {
8014 _pdf->setFloor(
false);
8020 }
else if (
auto fr = get<RooFitResult>()) {
8026 for (
auto c : _pars) {
8027 bool matchAny =
false;
8028 for (
auto &
p : patterns) {
8034 if (!((matchAny && !invert) || (!matchAny && invert))) {
8038 _pars.remove(_remPars,
true);
8040 auto _tmp = fr->reducedCovarianceMatrix(_pars);
8041 int covQualBackup = fr->covQual();
8042 fr->setCovarianceMatrix(_tmp);
8043 fr->setCovQual(covQualBackup);
8044 const_cast<RooArgList &
>(fr->floatParsFinal())
8045 .remove(_remPars,
true);
8048 }
else if (!
get() || get<RooAbsCollection>()) {
8053 bool notAllArgs =
false;
8054 bool isVars = (strcmp(
GetName(),
".vars") == 0);
8055 for (
auto c : *this) {
8056 nobs += (
c->fFolder ==
"!robs" ||
c->fFolder ==
"!globs");
8057 bool matchAny =
false;
8058 for (
auto &
p : patterns) {
8060 (isVars &&
p ==
"x" && (
c->fFolder ==
"!robs" ||
c->fFolder ==
"!globs") && nobs == 1)) {
8065 if ((matchAny && !invert) || (!matchAny && invert)) {
8081 return get<RooArgList>() ?
xRooNode(std::make_shared<RooArgList>(),
fParent) : *this;
8090 std::string noName =
"___";
8091 std::string childNames;
8092 for (
auto &
c : *
this) {
8094 if (!childNames.empty())
8096 childNames +=
c->GetName();
8099 if (childNames.empty())
8100 childNames = noName;
8184 return static_cast<RooAbsPdf *
>(intpdf.absArg())->expectedEvents(nset);
8193 return getProjection(&intobs, _normSet, (_normRange.Length() > 0 ? _normRange.Data() :
nullptr), code)->getVal();
8198 RooArgList **pars,
bool asymHi,
bool asymLo,
const std::vector<int> &bins,
8199 const std::function<
void(
int)> &setBin)
8201 const size_t nBins = bins.size();
8202 std::vector<double> out(nBins, 0.);
8209 RooArgList *_pars = (pars) ? *pars :
nullptr;
8214 f.getParameters(&nset, allParamsInAbsReal);
8217 for (
auto *rrvFitRes : static_range_cast<RooRealVar *>(fr.
floatParsFinal())) {
8219 auto rrvInAbsReal =
static_cast<RooRealVar const *
>(allParamsInAbsReal.
find(*rrvFitRes));
8222 if (rrvFitRes->getError() <= std::abs(rrvFitRes->getVal()) * std::numeric_limits<double>::epsilon())
8231 if (std::abs(rrvInAbsReal->getVal() - rrvFitRes->getVal()) > 0.01 * rrvFitRes->getError()) {
8232 std::stringstream errMsg;
8233 errMsg <<
"RooAbsReal::getPropagatedError(): the parameters of the RooAbsReal don't have"
8234 <<
" the same values as in the fit result! The logic of getPropagatedError is broken in this case."
8235 <<
" \n " << rrvInAbsReal->GetName() <<
" : " << rrvInAbsReal->getVal() <<
" vs "
8236 << rrvFitRes->getVal();
8238 throw std::runtime_error(errMsg.str());
8241 _pars->
add(*rrvInAbsReal);
8245 const size_t nPars = _pars->
size();
8255 for (
size_t i = 0; i < nPars; i++) {
8256 for (
size_t j = i; j < nPars; j++) {
8257 C(i, j) = V(i, j) / std::sqrt(V(i, i) * V(j, j));
8263 std::vector<double> nomVals;
8264 if (asymHi || asymLo) {
8265 nomVals.resize(nBins);
8266 for (
size_t k = 0; k < nBins; k++) {
8268 nomVals[k] =
f.getVal(nset);
8274 std::vector<TVectorD> F(nBins,
TVectorD(nPars));
8276 std::vector<double> plusVar(nBins), minusVar(nBins);
8278 double ERROR_FACTOR = 1.;
8279 for (
size_t ivar = 0; ivar < nPars; ivar++) {
8281 auto &rrv =
static_cast<RooRealVar &
>((*_pars)[ivar]);
8284 double cenVal = rrv.
getVal();
8287 if (asymHi || asymLo) {
8288 double errValHi = frrrv->getErrorHi();
8289 rrv.setVal(errValHi > 0 ? std::min(cenVal + errValHi*ERROR_FACTOR, rrv.getMax())
8290 : std::max(cenVal + errValHi*ERROR_FACTOR, rrv.getMin()));
8291 for (
size_t k = 0; k < nBins; k++) {
8293 plusVar[k] =
f.getVal(nset);
8295 double errValLo = frrrv->getErrorLo();
8296 rrv.setVal(errValLo > 0 ? std::min(cenVal + errValLo*ERROR_FACTOR, rrv.getMax())
8297 : std::max(cenVal + errValLo*ERROR_FACTOR, rrv.getMin()));
8298 for (
size_t k = 0; k < nBins; k++) {
8300 minusVar[k] =
f.getVal(nset);
8303 for (
size_t k = 0; k < nBins; k++) {
8304 double hi = plusVar[k];
8305 double lo = minusVar[k];
8308 hi = std::max(plusVar[k], minusVar[k]);
8309 lo = 2 * nomVals[k] -
hi;
8312 lo = std::min(plusVar[k], minusVar[k]);
8313 hi = 2 * nomVals[k] - lo;
8315 F[k][ivar] = (
hi - lo) * 0.5 / ERROR_FACTOR;
8318 double errVal = sqrt(V(ivar, ivar));
8320 rrv.setVal(std::min(cenVal + errVal*ERROR_FACTOR, rrv.getMax()));
8321 for (
size_t k = 0; k < nBins; k++) {
8323 plusVar[k] =
f.getVal(nset);
8326 rrv.setVal(std::max(cenVal - errVal*ERROR_FACTOR, rrv.getMin()));
8327 for (
size_t k = 0; k < nBins; k++) {
8329 minusVar[k] =
f.getVal(nset);
8332 for (
size_t k = 0; k < nBins; k++) {
8333 F[k][ivar] = (plusVar[k] - minusVar[k]) * 0.5 / ERROR_FACTOR;
8344 setBin(bins[nBins - 1]);
8349 for (
size_t k = 0; k < nBins; k++) {
8350 out[k] = std::sqrt(F[k] * (C * F[k]));
8367 fFunc(
"func",
"func", this,
f),
8368 fCoef(
"coef",
"coef", this),
8369 fExpPdf(
"expPdf",
"expPdf", this)
8374 fCoef.setArg(*coef);
8376 if (expPdf && expPdf->canBeExtended() && !(coef &&
dynamic_cast<RooAddPdf *
>(expPdf))) {
8377 fExpPdf.setArg(*expPdf);
8378 }
else if (
auto _p =
dynamic_cast<RooAbsPdf *
>(&
f);
8382 fExpectedEventsMode = expEvMode;
8387 fFunc(
"func", this, other.fFunc),
8388 fCoef(
"coef", this, other.fCoef),
8389 fExpPdf(
"expPdf", this, other.fExpPdf),
8390 fExpectedEventsMode(other.fExpectedEventsMode)
8397 return fFunc->binBoundaries(obs, xlo, xhi);
8402 return (fExpectedEventsMode ? 1. : fFunc) *
8403 ((fExpPdf.absArg()) ?
static_cast<RooAbsPdf *
>(fExpPdf.absArg())->expectedEvents(_normSet) : 1.) *
8404 (fCoef.absArg() ? fCoef : 1.);
8415#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 28, 00)
8416 double oo = getPropagatedError(fr, nset_in);
8417 if (std::isnan(oo)) {
8422 getParameters(&nset_in, allParamsInAbsReal);
8425 for (
auto *rrvFitRes : static_range_cast<RooRealVar *>(fr.
floatParsFinal())) {
8427 auto rrvInAbsReal =
static_cast<RooRealVar const *
>(allParamsInAbsReal.
find(*rrvFitRes));
8431 if (rrvFitRes->namePtr() == namePtr())
8435 if (!rrvFitRes->hasError() ||
8436 rrvFitRes->getError() <= std::abs(rrvFitRes->getVal()) * std::numeric_limits<double>::epsilon())
8445 if (std::abs(rrvInAbsReal->getVal() - rrvFitRes->getVal()) > 0.01 * rrvFitRes->getError()) {
8446 std::stringstream errMsg;
8448 <<
"RooAbsReal::getPropagatedError(): the parameters of the RooAbsReal don't have"
8449 <<
" the same values as in the fit result! The logic of getPropagatedError is broken in this case.";
8451 throw std::runtime_error(errMsg.str());
8454 paramList.
add(*rrvInAbsReal);
8456 if (paramList.
empty())
8459 std::vector<double> plusVar;
8460 std::vector<double> minusVar;
8461 plusVar.reserve(paramList.
size());
8462 minusVar.reserve(paramList.
size());
8468 for (std::size_t ivar = 0; ivar < paramList.
size(); ivar++) {
8470 auto &rrv =
static_cast<RooRealVar &
>(paramList[ivar]);
8472 double cenVal = rrv.
getVal();
8473 double errVal = sqrt(V(ivar, ivar));
8485 rrv.setVal(cenVal + errVal);
8486 plusVar.push_back(getVal(nset_in));
8489 rrv.setVal(cenVal - errVal);
8490 minusVar.push_back(getVal(nset_in));
8491#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
8515 std::vector<double> errVec(paramList.
size());
8516 for (std::size_t i = 0; i < paramList.
size(); i++) {
8517 errVec[i] = std::sqrt(V(i, i));
8518 for (std::size_t j = i; j < paramList.
size(); j++) {
8519 C(i, j) = V(i, j) / std::sqrt(V(i, i) * V(j, j));
8526 for (
unsigned int j = 0; j < plusVar.size(); j++) {
8527 F[j] = (plusVar[j] - minusVar[j]) / 2;
8531 double sum = F * (C * F);
8540 for (
auto *frv : static_range_cast<RooRealVar *>(fr.
floatParsFinal())) {
8541 if (frv->getError() > 1
e-20) {
8542 fpf_stripped.
add(*frv);
8557 std::vector<int> fpf_idx;
8558 for (
Int_t i = 0; i < fpf.
size(); i++) {
8561 paramList.
add(*par);
8562 fpf_idx.push_back(i);
8566 std::vector<double> plusVar, minusVar;
8572 for (
Int_t ivar = 0; ivar < paramList.
size(); ivar++) {
8576 double cenVal = rrv.
getVal();
8577 double errVal = sqrt(V(ivar, ivar));
8580 ((
RooRealVar *)paramList.
at(ivar))->setVal(cenVal + errVal);
8583 plusVar.push_back(cloneFunc->
getVal(nset));
8586 ((
RooRealVar *)paramList.
at(ivar))->setVal(cenVal - errVal);
8589 minusVar.push_back(cloneFunc->
getVal(nset));
8597 std::vector<double> errVec(paramList.
size());
8598 for (
int i = 0; i < paramList.
size(); i++) {
8599 errVec[i] = sqrt(V(i, i));
8600 for (
int j = i; j < paramList.
size(); j++) {
8601 C(i, j) = V(i, j) / sqrt(V(i, i) * V(j, j));
8608 for (
unsigned int j = 0; j < plusVar.size(); j++) {
8609 F[j] = (plusVar[j] - minusVar[j]) / 2;
8613 double sum = F * (C * F);
8627 bool fExpectedEventsMode =
false;
8635 std::cout <<
"Got signal " << signum << std::endl;
8636 if (signum == SIGINT) {
8637 std::cout <<
"Keyboard interrupt while building histogram" << std::endl;
8647 auto _doSterilize = [](
RooAbsArg *obj) {
8650 for (
int i = 0; i < obj->numCaches(); i++) {
8656 p->setNormRange(
p->normRange());
8658#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
8663 p->setProxyNormSet(
nullptr);
8664 p->_lastNSet =
nullptr;
8667 obj->setValueDirty();
8669 if (
auto w = get<RooWorkspace>();
w) {
8671 for (
auto &
c :
w->components()) {
8690 nClients =
a->clients().size();
8691 for (
auto obj :
a->clients()) {
8693 if (
a->clients().size() != nClients) {
8698 }
while (
a->clients().size() != nClients);
8700 func(get<RooAbsArg>());
8705 bool errorsLo,
int nErrorToys)
const
8717 out.
fComp = std::shared_ptr<TH1>(
8718 BuildHistogram(
nullptr, !content, errors, -1, -1, fr, errorsHi, errorsLo, nErrorToys,
nullptr, !stack,
false));
8719 }
else if (
vars.size() == 1) {
8721 out.
fComp = std::shared_ptr<TH1>(
8722 BuildHistogram(
v, !content, errors, 1, 0, fr, errorsHi, errorsLo, nErrorToys,
nullptr, !stack,
true));
8724 throw std::runtime_error(
"multi-dim histo not yet supported");
8736 bool errorsHi,
bool errorsLo,
int nErrorToys,
TH1 *templateHist,
bool nostack,
8737 bool setInterp)
const
8739 auto rar = get<RooAbsReal>();
8751 if (binStart != -1 || binEnd != -1) {
8763 h =
new TH1D(rar->GetName(), rar->GetTitle(), 1, 0, 1);
8764 h->GetXaxis()->SetBinLabel(1, rar->GetName());
8765 h->GetXaxis()->SetTimeFormat(rar->GetName());
8770 bool setTitle =
false;
8775 h =
static_cast<TH1 *
>(templateHist->
Clone(rar->GetName()));
8784 h =
new TH1D(rar->GetName(), rar->GetTitle(), 1, 0, 1);
8787 h->GetXaxis()->SetBinLabel(1, rar->GetName());
8788 h->SetBinContent(1, rar->getVal());
8789 if (
x->getError()) {
8790 h->SetBinError(1,
x->getError());
8791 h->SetFillStyle(3005);
8792 h->SetFillColor(
h->GetLineColor());
8794 h->SetMaximum(
x->hasMax() ?
x->getMax()
8795 : (
h->GetBinContent(1) + std::max(std::abs(
h->GetBinContent(1) * 0.1), 50.)));
8796 h->SetMinimum(
x->hasMin() ?
x->getMin()
8797 : (
h->GetBinContent(1) - std::max(std::abs(
h->GetBinContent(1) * 0.1), 50.)));
8800 h->SetMarkerSize(0);
8801 h->SetMarkerStyle(0);
8806 TString binningName = (_ax && _ax->GetParent() ==
x) ? _ax->GetName() : rar->getStringAttribute(
"binning");
8807 if (binningName ==
"")
8808 binningName = rar->GetName();
8809 if (
x->hasBinning(binningName)) {
8810 if (
x->getBinning(binningName).isUniform()) {
8812 h =
new TH1D(rar->GetName(), rar->GetTitle(),
x->numBins(binningName) <= 0 ? 100 :
x->numBins(binningName),
8813 x->getMin(binningName),
x->getMax(binningName));
8816 h =
new TH1D(rar->GetName(), rar->GetTitle(),
x->numBins(binningName),
x->getBinning(binningName).array());
8818 h->GetXaxis()->SetTitle(
x->getBinning(binningName).GetTitle());
8820 }
else if (
auto _boundaries =
8821 _or_func( (std::list<double> *)(
nullptr),
8822 rar->binBoundaries(*
x, -std::numeric_limits<double>::infinity(),
8823 std::numeric_limits<double>::infinity()));
8825 std::vector<double> _bins;
8826 for (
auto &
b : *_boundaries) {
8827 if (_bins.empty() || std::abs(_bins.back() -
b) > 1
e-5 * _bins.back())
8831 h =
new TH1D(rar->GetName(), rar->GetTitle(), _bins.size() - 1, &_bins[0]);
8833 }
else if (!
x->hasMax() || !
x->hasMin()) {
8836 h =
new TH1D(rar->GetName(), rar->GetTitle(),
v->numBins(),
x->getVal() * 0.2,
x->getVal() * 5);
8839 h =
new TH1D(rar->GetName(), rar->GetTitle(),
v->numBins(),
x->getBinning().array());
8845 h =
new TH1D(rar->GetName(), rar->GetTitle(),
v->numBins(rar->GetName()), 0,
v->numBins(rar->GetName()));
8849 std::map<int, std::string> cats;
8850 for (
auto &
c : *cat) {
8851 cats[
c.second] =
c.first;
8853 for (
auto &[
_, label] : cats) {
8854 h->GetXaxis()->SetBinLabel(i++, label.c_str());
8859 if (
auto o =
dynamic_cast<TObject *
>(
v); o && !setTitle) {
8860 h->GetXaxis()->SetTitle(o->GetTitle());
8864 if (
h->GetXaxis()->IsAlphanumeric()) {
8873 if (
auto s =
styles(
nullptr,
false); s) {
8874 auto _style = s.get<
TStyle>();
8875 static_cast<TAttLine &
>(*h) = *_style;
8876 static_cast<TAttFill &
>(*h) = *_style;
8879 if (strlen(
h->GetXaxis()->GetTitle()) == 0)
8888 if (empty && !errors) {
8894 auto _coefs =
coefs();
8909 if (!
GETDMP(fr, _finalPars)) {
8922 for (
int i = 0; i < prevCov->
GetNcols(); i++) {
8923 for (
int j = 0; j < prevCov->
GetNrows(); j++) {
8924 cov(i, j) = (*prevCov)(i, j);
8930 if (!prevCov || i >= prevCov->
GetNcols()) {
8931 cov(i, i) = pow(
dynamic_cast<RooRealVar *
>(p2)->getError(), 2);
8935 int covQualBackup = fr->
covQual();
8946 int covQualBackup = fr->
covQual();
8954 bool hasErrors =
false;
8972 binEnd =
h->GetNbinsX();
8974 bool needBinWidth =
false;
8977 if (
x && (
p || _coefs.get() || rar->getAttribute(
"density"))) {
8979 needBinWidth =
true;
8983 spdf && spdf->
canBeExtended() && !spdf->getFloor() && !_coefs.get()) {
8995 for (
auto o : _obs) {
9000 rr->setStringAttribute(
"coordRange",
nullptr);
9008 rr->setStringAttribute(
"coordRange",
nullptr);
9018 bool hasRange =
false;
9019 for (
auto o : normSet) {
9021 rr && (rr->getStringAttribute(
"coordRange")) && strlen(rr->getStringAttribute(
"coordRange"))) {
9031 for (
auto pdf :
bins()) {
9034 std::unique_ptr<RooArgSet> projObs{pdf->get<
RooAbsPdf>()->getObservables(*_obs.get<
RooArgList>())};
9038 dynamic_cast<RooAbsPdf *
>(_pdf)->setNormRange(
"coordRange");
9040 newrar->addPdf(*_pdf, pdf->coords()[s->indexCat().GetName()]->get<
RooCategory>()->getLabel());
9044 rar =
p->createProjection(
9048 dynamic_cast<RooAbsPdf *
>(rar)->setNormRange(
"coordRange");
9052 p->setNormRange(
"coordRange");
9057 rar = std::unique_ptr<RooAbsReal>{rar->createIntegral(
9063 std::unique_ptr<RooAbsReal>{rar->createIntegral(*_obs.get<
RooArgList>() )}
9069 bool scaleExpected = (
p &&
p->canBeExtended() && !_coefs.get());
9075 if (!nostack &&
p &&
p->canBeExtended() && _coefs.get()) {
9081 std::unique_ptr<RooArgSet> snap(normSet.
snapshot());
9083 std::vector<double> lapTimes;
9084 bool warned =
false;
9085 if (binStart == -1 && binEnd == -1) {
9090 std::unique_ptr<RooAbsCollection> errorParsSnap;
9100 TString clNameNoNamespace = rar->ClassName();
9101 clNameNoNamespace = clNameNoNamespace(clNameNoNamespace.
Last(
':') + 1, clNameNoNamespace.
Length());
9102 setInterp = (clNameNoNamespace.
Contains(
"Hist") || vvv->
isCategory() || rar->isBinnedDistribution(*vvv) ||
9103 h->GetNbinsX() == 1 || rar->getAttribute(
"BinnedLikelihood") ||
9105 std::unique_ptr<std::list<double>>(rar->binBoundaries(*
dynamic_cast<RooAbsRealLValue *
>(vvv),
9106 -std::numeric_limits<double>::infinity(),
9107 std::numeric_limits<double>::infinity()))))
9116 bool allHist =
true;
9118 TString _clName = s->get()->ClassName();
9119 _clName = _clName(_clName.
Last(
':') + 1, _clName.
Length());
9120 if (!(s->get() && _clName.
Contains(
"Hist"))) {
9138 auto l =
static_cast<TH1 *
>(
h->Clone(
"nominal"));
9141 h->GetListOfFunctions()->Add(
l, (setInterp) ?
"lsame" :
"histsame");
9142 h->SetOption(setInterp ?
"e3" :
"e2");
9145 h->SetMarkerSize(0);
9146 h->SetFillStyle(3005);
9147 h->SetFillColor(
h->GetLineColor());
9150 if (nErrorToys > 0) {
9159 errorPars->
add(*par);
9162 errorParsSnap.reset(errorPars->
snapshot());
9163 auto l =
static_cast<TH1 *
>(
h->Clone(
"toys"));
9166 h->GetListOfFunctions()->Add(
9169 if (errorsLo || errorsHi)
9173 std::vector<int> errorBins;
9174 for (
int toy = 0; toy < (nErrorToys + 1); toy++) {
9190 if (_vv->getError() == 0)
9195 for (
int i = std::max(1, binStart); i <= std::min(
h->GetNbinsX(), binEnd); i++) {
9198 x->setVal(
h->GetBinCenter(i));
9200 cat->setLabel(
h->GetXaxis()->GetBinLabel(i));
9204 if (
x && !
x->inRange(
"coordRange"))
9208 if (!empty || toy > 0) {
9209 r = rar->getVal(
p ? &normSet :
nullptr);
9210#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
9215 if (
r && _coefs.get()) {
9219 r *=
h->GetBinWidth(i);
9221 if (scaleExpected) {
9224 r *= (
p->expectedEvents(normSet));
9227 h->SetBinContent(i,
r);
9233 errorBins.push_back(i);
9237 lapTimes.push_back(timeIt.
RealTime());
9238 double time_estimate =
9239 (lapTimes.size() > 1)
9240 ? (
h->GetNbinsX() * (std::accumulate(lapTimes.begin() + 1, lapTimes.end(), 0.) / (lapTimes.size() - 1)))
9242 if (!warned && (lapTimes.at(0) > 10 || (lapTimes.size() > 2 && time_estimate > 60.))) {
9244 t2.
Add(time_estimate);
9245 Warning(
"BuildHistogram",
"Building this histogram will take until %s", t2.
AsString());
9255 Warning(
"BuildHistogram",
"Skipping errors for remaining bins");
9266 if (errors && !errorBins.empty()) {
9270 std::unique_ptr<RooAbsReal> errFunc;
9274 std::make_unique<PdfWrapper>((oldrar) ? *rar : *
p, _coefs.get<
RooAbsReal>(), !
v, oldrar ?
p :
nullptr);
9278 errFunc = std::make_unique<RooProduct>(
9279 "errorEval",
"errorEval",
9282 const RooArgSet &errNormSet =
p ? normSet : emptyNormSet;
9284 auto setBin = [&](
int i) {
9286 x->setVal(
h->GetBinCenter(i));
9288 cat->setLabel(
h->GetXaxis()->GetBinLabel(i));
9294 bool doAsym = (errorsHi && errorsLo);
9298 *errFunc, *fr, errNormSet, &errorPars, doAsym ?
false : errorsHi, doAsym ? true : errorsLo, errorBins, setBin);
9299 std::vector<double> errHi;
9303#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
9306 p->_normSet =
nullptr;
9310 for (
size_t k = 0; k < errorBins.size(); k++) {
9311 int i = errorBins[k];
9312 double resLo = errLo[k];
9314 resLo *=
h->GetBinWidth(i);
9315 h->SetBinError(i, resLo);
9317 double resHi = errHi[k];
9319 resHi *=
h->GetBinWidth(i);
9322 h->SetBinContent(i,
h->GetBinContent(i) + (resHi - resLo) * 0.5);
9323 h->SetBinError(i, (resHi + resLo) * 0.5);
9336 *errorPars = *errorParsSnap;
9343 if (errorsLo && errorsHi) {
9344 auto nomHist =
static_cast<TH1 *
>(
h->FindObject(
"nominal"));
9347 for (
int i = 1; i <=
h->GetNbinsX(); i++) {
9348 std::vector<double> vals;
9349 vals.reserve(nErrorToys);
9350 for (
int j = 1; j < (nErrorToys + 1); j++) {
9354 double upVal, downVal;
9355 if (errorsLo || errorsHi) {
9356 std::sort(vals.begin(), vals.end());
9360 downVal = 2. *
h->GetBinContent(i) - upVal;
9362 upVal = 2. *
h->GetBinContent(i) - downVal;
9365 upVal =
h->GetBinContent(i) + err;
9366 downVal =
h->GetBinContent(i) - err;
9368 h->SetBinContent(i, (upVal + downVal) * 0.5);
9369 h->SetBinError(i, (upVal - downVal) * 0.5);
9372#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 41, 00)
9387 treeRoot->treeNodeServerList(&evaluatedNodes);
9389 for (
RooAbsArg *node : evaluatedNodes) {
9390 node->setProxyNormSet(
nullptr);
9395 std::vector<RooAbsArg *> extra;
9398 for (
auto _pdf : s->servers()) {
9400 extra.push_back(_pdf);
9403 extra.push_back(rar);
9406 for (
auto a : extra)
9412 if (!
p && !rar->getAttribute(
"density") && !needBinWidth) {
9413 h->GetYaxis()->SetTitle(rar->getStringAttribute(
"units"));
9414 }
else if ((
p &&
p->canBeExtended()) || (!
p && needBinWidth)) {
9415 h->GetYaxis()->SetTitle(
"Events");
9417 h->GetYaxis()->SetTitle(
"Probability Mass");
9419 h->GetYaxis()->SetMaxDigits(3);
9428 auto hCopy =
static_cast<TH1 *
>(
h->Clone(
"copy"));
9432 hCopy->SetStats(
false);
9433 h->GetListOfFunctions()->Add(hCopy,
TString(
h->GetOption()) +
"same");
9434 h->GetListOfFunctions()->Add(hCopy,
"axissame");
9435 TString dOpt = (setInterp) ?
"LF2" :
"";
9441 rarNode =
find(
".pdf").get();
9448 std::map<std::string, int> colorByTitle;
9449 std::set<std::string> allTitles;
9450 bool titleMatchName =
true;
9451 std::map<std::string, TH1 *> histGroups;
9452 std::vector<TH1 *> hhs;
9453 std::set<std::pair<size_t, TH1 *>> ordered_hhs;
9454 std::set<TH1 *> histsWithBadTitles;
9460 if (!rarNode->components().empty()) {
9461 auto comps = rarNode->components()[0];
9462 for (
auto &
c : *comps) {
9463 if (
c->fFolder ==
"!.coeffs" ||
c->fFolder ==
"!.coeffpars")
9467 if (!cms_coefs.
empty()) {
9469 std::shared_ptr<TH1> prevHist(
static_cast<TH1 *
>(
h->Clone()));
9476 std::unique_ptr<RooAbsReal> forig(
9477 dynamic_cast<RooAbsReal *
>(rarNode->components()[0]->get()->
Clone(
"tmpCopy0")));
9478 for (
auto c : cms_coefs) {
9482 forig->redirectServers(
RooArgSet(zero),
false,
true);
9483 std::unique_ptr<RooAbsReal>
f(
dynamic_cast<RooAbsReal *
>(forig->Clone(
"tmpCopy")));
9487 auto hh =
xRooNode(*
f, *
this).BuildHistogram(
v);
9488 hh->SetName(
c->GetName());
9491 if (strlen(hh->GetTitle()) == 0) {
9492 hh->SetTitle(
c->GetName());
9496 hh->SetTitle(
TString(
TString(hh->GetTitle())(idx + 6, strlen(hh->GetTitle()))));
9498 histsWithBadTitles.insert(hh);
9499 }
else if (strcmp(hh->GetName(), hh->GetTitle()) == 0) {
9500 histsWithBadTitles.insert(hh);
9502 titleMatchName &= (
TString(
c->GetName()) == hh->GetTitle() ||
9504 std::shared_ptr<TH1> nextHist(
static_cast<TH1 *
>(hh->Clone()));
9505 hh->Add(prevHist.get(), -1.);
9508 hh->TH1::Reset(
"ICE");
9509 ordered_hhs.insert(std::pair(ordered_hhs.size(), hh));
9510 prevHist = nextHist;
9512 }
else if (get<RooSimultaneous>()) {
9516 for (
auto &chan :
bins()) {
9517 TString chanName(chan->GetName());
9518 chanName = chanName(chanName.
Index(
"=") + 1, chanName.
Length());
9519 auto samps = chan->mainChild();
9522 for (
auto &samp : samps.components()) {
9523 auto hh =
static_cast<TH1 *
>(
h->Clone(samp->GetName()));
9525 hh->SetTitle(samp->GetTitle());
9526 if (strlen(hh->GetTitle()) == 0) {
9527 hh->SetTitle(samp->GetName());
9528 histsWithBadTitles.insert(hh);
9529 }
else if (strcmp(hh->GetName(), hh->GetTitle()) == 0) {
9530 histsWithBadTitles.insert(hh);
9532 hh->SetTitle(
TString(hh->GetTitle())
9533 .ReplaceAll(
TString(chan->get()->GetName()) +
"_",
9535 titleMatchName &= (
TString(samp->GetName()) == hh->GetTitle() ||
9537 hh->SetBinContent(hh->GetXaxis()->FindFixBin(chanName), samp->GetContent());
9538 ordered_hhs.insert(std::pair(ordered_hhs.size(), hh));
9542 for (
auto &samp : rarNode->components()) {
9543 auto hh = samp->BuildHistogram(
9544 v, empty,
false , binStart, binEnd, _fr,
false,
false, 0,
h,
true,
9546 hh->SetName(samp->GetName());
9552 : ordered_hhs.size(),
9554 if (strlen(hh->GetTitle()) == 0) {
9555 hh->SetTitle(samp->GetName());
9556 histsWithBadTitles.insert(hh);
9557 }
else if (strcmp(hh->GetName(), hh->GetTitle()) == 0) {
9558 histsWithBadTitles.insert(hh);
9560 titleMatchName &= (
TString(samp->GetName()) == hh->GetTitle() ||
9566 for (
auto &[
_, hh] : ordered_hhs) {
9571 for (
auto &hh : hhs) {
9572 allTitles.insert(hh->GetTitle());
9577 size_t e = std::min(allTitles.begin()->size(), allTitles.rbegin()->size());
9579 bool goodPrefix =
false;
9580 std::string commonSuffix;
9581 if (titleMatchName && hhs.size() > 1) {
9582 while (ii <
e - 1 && allTitles.begin()->at(ii) == allTitles.rbegin()->at(ii)) {
9584 if (allTitles.begin()->at(ii) ==
'_' || allTitles.begin()->at(ii) ==
' ')
9590 while (!stop && commonSuffix.size() <
size_t(
e - 1)) {
9591 commonSuffix = allTitles.begin()->substr(allTitles.begin()->length() - commonSuffix.length() - 1);
9592 for (
auto &
tt : allTitles) {
9594 commonSuffix = commonSuffix.substr(1);
9600 if (commonSuffix.find(
'_') == std::string::npos) {
9603 commonSuffix = commonSuffix.substr(commonSuffix.find(
'_'));
9612 std::map<std::string, std::string> reducedTitles;
9613 while (reducedTitles.size() != allTitles.size()) {
9615 std::map<std::string, int> titlesMap;
9616 for (
auto &s : allTitles) {
9617 if (reducedTitles.count(s))
9619 titlesMap[s.substr(0, jj)]++;
9621 for (
auto &s : allTitles) {
9622 if (titlesMap[s.substr(0, jj)] == 1 && (jj >= s.length() || s.at(jj) ==
' ' || s.at(jj) ==
'_')) {
9623 reducedTitles[s] = s.substr(0, jj);
9629 for (
auto ritr = hhs.rbegin(); ritr != hhs.rend(); ++ritr) {
9630 if (!histsWithBadTitles.count((*ritr))) {
9633 auto _title = (hhs.size() > 5) ? reducedTitles[(*ritr)->GetTitle()] : (*ritr)->GetTitle();
9634 _title = _title.substr(ii < _title.size() ? ii : 0);
9635 if (!commonSuffix.empty() &&
TString(_title).
EndsWith(commonSuffix.c_str()))
9636 _title = _title.substr(0, _title.length() - commonSuffix.length());
9637 (*ritr)->SetTitle(_title.c_str());
9641 for (
auto &hh : hhs) {
9643 if (histGroups.find(hh->GetTitle()) == histGroups.end()) {
9644 histGroups[hh->GetTitle()] = hh;
9647 histGroups[hh->GetTitle()]->Add(hh);
9652 auto hhMin = (hh->GetMinimum() == 0) ? hh->GetMinimum(1
e-9) : hh->GetMinimum();
9653 if (!stack->
GetHists() &&
h->GetMinimum() > hhMin) {
9655 if (hhMin >= 0 && newMin < 0)
9656 newMin = hhMin * 0.99;
9670 stack->
Add(hh, thisOpt);
9673 h->GetListOfFunctions()->AddFirst(stack,
"noclear same");
9685 for (
auto ho : *ll) {
9686 TH1 *hh =
dynamic_cast<TH1 *
>(ho);
9689 bool createdStyle = (
xRooNode(*hh, *
this).styles(
nullptr,
false).get<
TStyle>() ==
nullptr);
9703 for (
auto ho2 : *ll) {
9704 TH1 *hh2 =
dynamic_cast<TH1 *
>(ho2);
9707 auto _styleNode =
xRooNode(*hh2, *
this).styles(hh2,
false);
9708 auto _style = _styleNode.get<
TStyle>();
9717 auto _styleNode =
xRooNode(*hh, *
this).styles(hh);
9718 if (
auto _style = _styleNode.get<
TStyle>()) {
9719 *
dynamic_cast<TAttLine *
>(hh) = *_style;
9720 *
dynamic_cast<TAttFill *
>(hh) = *_style;
9740 push_back(std::make_shared<xRooNode>(
data));
9748 return std::numeric_limits<double>::quiet_NaN();
9749 return node->GetBinContent(bin);
9755 if (binStart != binEnd || !
fParent) {
9760 std::vector<double> out;
9761 if (get<RooAbsData>()) {
9769 if (binStart == binEnd && binStart == -1) {
9772 for (
int i = 0; i <
g->GetN(); i++)
9773 integral +=
g->GetPointY(i);
9774 out.push_back(integral);
9778 for (
int i = binStart - 1; i <
g->GetN() && (binEnd == 0 || i < binEnd); i++) {
9779 out.push_back(
g->GetPointY(i));
9785 bool doIntegral =
false;
9786 if (binStart == binEnd && binStart == -1) {
9796 binEnd =
h->GetNbinsX();
9800 for (
int i = 1; i <=
h->GetNbinsX(); i++) {
9801 tot +=
h->GetBinContent(i);
9805 for (
int i = binStart; i <= binEnd; i++) {
9806 out.push_back(
h->GetBinContent(i));
9815 if (
auto a = get<RooAbsArg>();
a) {
9817 for (
auto &
l :
a->servers()) {
9837 if (
auto o =
get(); o) {
9846#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
9850 for (
int i = 0; i <
p->fCGnx; i++) {
9851 for (
int j = 0; j <
p->fCGny; j++) {
9852 p->fCollideGrid[i + j *
p->fCGnx] =
true;
9855 p->FillCollideGrid(o);
9859 Int_t nxmax =
p->fCGnx - iw - 1 -
p->fCGnx *
p->GetRightMargin();
9860 Int_t nymax =
p->fCGny - ih - 1 -
p->fCGny *
p->GetTopMargin();
9862 for (
Int_t j = nymax; j >= 0; j--) {
9863 for (
Int_t i = nxmax; i >= 0; i--) {
9864 if (
p->Collide(i, j, iw, ih)) {
9875 return p->PlaceBox(o,
w,
h, xl, yb,
"trw");
9883 gPad->PaintModified();
9889 auto l =
new TPaveText(
gPad->GetLeftMargin() + 0.02, 1. -
gPad->GetTopMargin() - 0.08, 0.6,
9890 1. -
gPad->GetTopMargin() - 0.08);
9891 l->SetBorderSize(0);
9892 if (
l->GetTextSize() == 0)
9900 l->ConvertNDCtoPad();
9906 if (
auto p =
dynamic_cast<TLegend *
>(
gPad->GetPrimitive(
"legend"));
p) {
9909 double w =
p->GetX2NDC() -
p->GetX1NDC();
9910 double h =
p->GetY2NDC() -
p->GetY1NDC();
9912 gPad->PaintModified();
9916 x = std::max(
x, (
gPad->GetLeftMargin() + 0.02));
9917 y = std::max(
y, (
gPad->GetBottomMargin() + 0.02));
9918 x = std::min(
x, (1. -
gPad->GetRightMargin() - 0.02) -
w);
9919 y = std::min(
y, (1. -
gPad->GetTopMargin() - 0.02) -
h);
9920 h = std::min(
h, (1. -
gPad->GetTopMargin() - 0.02) -
y);
9921 w = std::min(
w, (1. -
gPad->GetRightMargin() - 0.02) -
x);
9933 while ((
p !=
p->GetMother()) && (
p =
p->GetMother())) {
9934 if (
auto q =
dynamic_cast<TVirtualPad *
>(
p->GetPrimitive(
"legend"));
q) {
9942 if (
p && strcmp(
p->
GetName(),
"legend") == 0) {
9943 if (
l =
dynamic_cast<TLegend *
>(
p->GetPrimitive(
"legend"));
l || !create)
9947 gPad->GetBottomMargin());
9948 l->SetBorderSize(1);
9952 l =
new TLegend(0.6, 1. -
gPad->GetTopMargin() - 0.08, 0.75, 1. -
gPad->GetTopMargin() - 0.08);
9953 l->SetBorderSize(0);
9955 if (
l->GetTextSize() == 0) {
9963 l->SetName(
"legend");
9965 l->ConvertNDCtoPad();
9972 auto i = s.find(
"\n");
9973 if (i == std::string::npos) {
9976 return std::string(
"#splitline{") + s.substr(0, i) +
"}{" +
formatLegendString(s.substr(i + 1)) +
"}";
9985 for (
auto a : *
l->GetListOfPrimitives()) {
9989 if (
l->GetListOfPrimitives()->GetEntries() > 20)
9994 l->GetListOfPrimitives()->RemoveLast();
9995 l->GetListOfPrimitives()->AddFirst(
e);
9996 if (
auto nObj =
l->GetListOfPrimitives()->GetEntries(); nObj > 0) {
9998 int nn =
l->GetNColumns();
10000 if (nObj > 1 && (nObj % nn) == 1) {
10001 l->SetNColumns(
l->GetNColumns() + 1);
10002 if (
l->GetBorderSize() == 0) {
10003 l->SetX1NDC(
l->GetX2NDC() - 0.15 *
l->GetNColumns());
10006 if (
l->GetBorderSize() == 0) {
10007 l->SetY1NDC(
l->GetY2NDC() - 0.05 *
gPad->GetHNDC() * std::ceil((
double(nObj) /
l->GetNColumns())));
10023 fPad->GetCanvas()->Paint();
10024 fPad->GetCanvas()->Update();
10025#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 30, 00)
10026 fPad->GetCanvas()->ResetUpdated();
10041 if (
gROOT->FromPopUp()) {
10042 gROOT->SetFromPopUp(
false);
10045 }
catch (
const std::exception &
e) {
10048 (
gROOT->GetListOfBrowsers()->At(0))
10051 "Exception",
e.what(),
10054 gROOT->SetFromPopUp(
true);
10063 if (
auto mc = get<RooStats::ModelConfig>()) {
10065 }
else if (
auto ir = get<RooStats::HypoTestInverterResult>()) {
10069 }
else if (get<RooStats::HypoTestResult>()) {
10082 auto _dsets =
fParent->datasets();
10085 for (
auto &
d : _dsets) {
10086 if (
d->get()->TestBit(1 << 20)) {
10087 dsetName =
d->get()->GetName();
10091 auto hs =
fParent->nll(dsetName.
Data()).hypoSpace(get<RooRealVar>()->GetName());
10092 hs.limits(
"cls visualize");
10104 [](
double a,
double b,
double) {
10107 if (
b == 0 &&
a == 0)
10114 [](
double n,
double b,
double sigma) {
10118 t0 = 2. * (((
n == 0) ? 0 :
n * log(
n /
b)) - (
n -
b));
10121 double b_hathat = 0.5 * (
b - sigma2 + sqrt(pow(
b - sigma2, 2) + 4 *
n * sigma2));
10124 t0 = 2. * (((
n == 0) ? 0 :
n * log(
n / b_hathat)) + b_hathat -
n + pow(
b - b_hathat, 2) / (2. * sigma2));
10128 return (
n >=
b) ? sqrt(t0) : -sqrt(t0);
10136 std::vector<double> xPoints;
10139 int _idx = sOpt2.
Index(
"x=");
10140 int _eidx = sOpt2.
Index(
';', _idx);
10141 TString varPart = sOpt(_idx + 2, (_eidx < 0 ? sOpt2.
Length() : _eidx) - (_idx + 2));
10144 if (
auto _idx2 = varPart.
Index(
"("); _idx2 > 0) {
10145 varName = varPart(0, _idx2);
10155 }
else if (ii == 1) {
10157 }
else if (ii == 2) {
10165 for (
double x = min;
x <= max;
x += (max - min) / (nBins - 1)) {
10166 xPoints.push_back(
x);
10168 }
else if (nBins == 1)
10169 xPoints.push_back((min + max) / 2.);
10171 v = getObject<RooAbsLValue>(varName.Data()).get();
10173 throw std::runtime_error(
TString::Format(
"Could not find variable %s", varName.Data()));
10175 if (xPoints.empty() && !
obs().
find(varName.Data()) &&
10178 for (
int i = 0; i <
v->numBins(
GetName()); i++) {
10184 sOpt2 =
TString(sOpt2(0, _idx)) + sOpt2(_idx + 2 + varPart.
Length() + 1, sOpt2.
Length());
10196 }
else if (get<RooAbsPdf>()) {
10198 forceNames = sOpt(sOpt2.
Index(
"force") + 5, sOpt2.
Length());
10199 sOpt = sOpt(0, sOpt2.
Index(
"force"));
10200 sOpt2 = sOpt2(0, sOpt2.
Index(
"force"));
10202 Error(
"Draw",
"Can only compute forces with PDFs");
10206 bool hasOverlay = sOpt2.
Contains(
"overlay");
10210 overlayName = sOpt(sOpt2.
Index(
"overlay") + 7, sOpt2.
Length());
10211 sOpt = sOpt(0, sOpt2.
Index(
"overlay"));
10212 sOpt2 = sOpt2(0, sOpt2.
Index(
"overlay"));
10215 sOpt +=
"auxRatio";
10217 sOpt +=
"auxSignif";
10219 std::string auxPlotTitle;
10230 bool nostack = sOpt.
Contains(
"nostack");
10232 bool hasSame = sOpt.
Contains(
"same");
10234 bool hasGoff = sOpt.
Contains(
"goff");
10236 bool hasFR = sOpt.
Contains(
"pull") && !get<RooFitResult>();
10238 bool hasText = sOpt.
Contains(
"text");
10239 bool hasTexte = sOpt.
Contains(
"texte");
10240 bool hasErrorOpt = sOpt.
Contains(
"e");
10244 }
else if (hasText) {
10247 if (auxPlotTitle ==
"Signif")
10248 hasErrorOpt =
true;
10254 TH1 *hAxis =
nullptr;
10256 auto clearPad = []() {
10258 if (
gPad->GetNumber() == 0) {
10270 if (!hasSame || !pad) {
10281 if (hAxis =
dynamic_cast<TH1 *
>(o); hAxis)
10301 auto adjustYRange = [&](
double min,
double max,
TH1 *hh =
nullptr,
bool symmetrize =
false) {
10309 double ymin = hh->GetMinimum();
10310 double ymax = hh->GetMaximum();
10311 if (hh->GetMaximumStored() == -1111)
10313 if (hh->GetMinimumStored() == -1111) {
10316 }
else if (
ymin < 0) {
10324 if (hh->GetSumw2()) {
10325 double smallestErrDown3 = -std::numeric_limits<double>::infinity();
10326 double smallestErrUp3 = std::numeric_limits<double>::infinity();
10327 for (
int i = 1; i <= hh->GetNbinsX(); i++) {
10328 smallestErrDown3 = std::max(smallestErrDown3, hh->GetBinContent(i) - 3 * hh->GetBinError(i));
10329 smallestErrUp3 = std::min(smallestErrUp3, hh->GetBinContent(i) + 3 * hh->GetBinError(i));
10331 max = std::max(max, smallestErrUp3);
10332 min = std::min(min, smallestErrDown3);
10334 bool change =
false;
10346 double down = hh->GetBinContent(1) -
ymin;
10347 double up =
ymax - hh->GetBinContent(1);
10349 ymax = hh->GetBinContent(1) + down;
10351 ymin = hh->GetBinContent(1) - up;
10354 if (hh == hAxis && pad && !pad->
GetLogy() &&
ymin > 0 && (log10(
ymax) - log10(max)) >= 3) {
10358 if (hh == hAxis && pad &&
ymin == 0 && pad->
GetLogy()) {
10363 hh->SetMinimum(
ymin);
10364 hh->SetMaximum(
ymax);
10365 hh->GetYaxis()->Set(1,
ymin,
ymax);
10366 hh->SetAxisRange(
ymin,
ymax,
"Y");
10372 double ymax = -std::numeric_limits<double>::infinity();
10373 double ymin = std::numeric_limits<double>::infinity();
10374 for (
int i = 0; i <
gr->
GetN(); i++) {
10378 return std::make_pair(
ymin,
ymax);
10381 if (!xPoints.empty()) {
10390 for (
auto &
x : xPoints) {
10401 out->
Draw(
TString(hasSame ?
"L" :
"AL") + (hasErrorOpt ?
"3" :
""));
10422 gPad->GetFrame()->SetFillStyle(1001);
10423 gPad->SetTopMargin(0);
10424 gPad->SetBottomMargin(0);
10425 gPad->SetName(
"pull");
10429 Error(
"Draw",
"Couldn't find pull graph");
10432 pullGraph->SetName(
"nominal");
10436 auto scaleHist =
static_cast<TH1 *
>(pullGraph->FindObject(
"scales"));
10438 throw std::runtime_error(
"Could not find scales in fit result");
10440 for (
auto i = 0; i < pullGraph->GetN(); i++) {
10442 g->
SetName(scaleHist->GetXaxis()->GetBinLabel(i + 1));
10445 Warning(
"Draw",
"Found a non-var in the floatParsFinal list: %s - this shouldn't happen",
g->GetName());
10449 "%s=%g +/- %s [%g,%g]", strlen(_p->GetTitle()) ? _p->GetTitle() : _p->GetName(), _p->getVal(),
10450 _p->hasAsymError() ?
TString::Format(
"(%g,%g)", _p->getAsymErrorHi(), _p->getAsymErrorLo()).
Data()
10452 scaleHist->GetBinContent(i + 1), scaleHist->GetBinError(i + 1)));
10453 g->SetPoint(0, pullGraph->GetPointX(i), pullGraph->GetPointY(i));
10454 g->SetPointEYhigh(0, pullGraph->GetErrorYhigh(i));
10455 g->SetPointEYlow(0, pullGraph->GetErrorYlow(i));
10456 g->SetEditable(
true);
10457 g->SetHighlight(
true);
10458 g->SetMarkerStyle(20);
10459 g->SetMarkerSize(0.5);
10467 _thisClone->AppendPad();
10480 if (
auto _simPdf = get<RooSimultaneous>();
10481 _simPdf && !(
v && strcmp(_simPdf->indexCat().GetName(),
dynamic_cast<TObject *
>(
v)->
GetName()) == 0)) {
10482 auto _channels =
bins();
10484 for (
auto &_v : _channels) {
10485 if (!_v->IsHidden())
10516 int ncols = _simPdf->getStringAttribute(
"ncols") ?
TString(_simPdf->getStringAttribute(
"ncols")).
Atoi() : 0;
10518 dynamic_cast<TPad *
>(pad)->Divide(ncols, std::ceil(
double(_size) / ncols), 1
e-9, 1
e-9);
10520 dynamic_cast<TPad *
>(pad)->DivideSquare(_size, 1
e-9, 1
e-9);
10523 auto _pad = pad->
GetPad(_size);
10526 _pad->SetPad(_pad->GetXlowNDC(), _pad->GetYlowNDC(), 1.0, _pad->GetYlowNDC() + _pad->GetHNDC());
10539 std::vector<TString> chanPatterns;
10540 if (_range && strlen(_range)) {
10543 chanPatterns.emplace_back(pattern);
10546 for (
auto &_v : _channels) {
10547 if (_v->IsHidden())
10553 chanVar.setLabel(cName);
10554 bool inRange = chanPatterns.empty();
10555 for (
auto &
p : chanPatterns) {
10556 if (chanVar.inRange(
p)) {
10564 gPad->SetLeftMargin(std::min(
gPad->GetLeftMargin() * (1. /
gPad->GetWNDC()), 0.3));
10574 if (!
get() || get<RooArgList>()) {
10579 for (
auto &_v : *
this) {
10580 if (_v->IsHidden())
10582 if (strcmp(
GetName(),
".vars") == 0) {
10586 if (strcmp(_v->get()->GetName(),
"1") == 0 || strcmp(_v->get()->GetName(),
"ONE") == 0 ||
10589 if (_v->get()->InheritsFrom(
"RooConstVar"))
10600 dynamic_cast<TPad *
>(pad)->DivideSquare(_size, 1
e-9, 1
e-9);
10603 for (
auto &_v : *
this) {
10604 if (_v->IsHidden())
10606 if (strcmp(
GetName(),
".vars") == 0) {
10610 if (strcmp(_v->get()->GetName(),
"1") == 0 || strcmp(_v->get()->GetName(),
"ONE") == 0 ||
10613 if (_v->get()->InheritsFrom(
"RooConstVar"))
10622 gPad->SetLeftMargin(std::min(
gPad->GetLeftMargin() * (1. /
gPad->GetWNDC()), 0.3));
10637 _mainChild.Draw(opt);
10643 if (
auto fr = get<RooFitResult>(); fr) {
10651 TH2 *hist =
nullptr;
10652 if (numCorrs < fr->correlationMatrix().GetNcols()) {
10654 std::set<std::pair<double, size_t>> maxCorrs;
10656 double maxCorr = 0;
10662 maxCorrs.insert({maxCorr, i});
10664 std::vector<size_t> topN;
10666 for (
auto itr = maxCorrs.rbegin(); itr != maxCorrs.rend(); ++itr) {
10667 topN.push_back(itr->second);
10673 numCorrs, 0, numCorrs, numCorrs, 0, numCorrs);
10674 for (
size_t i = 0; i < topN.size(); i++) {
10677 for (
size_t j = 0; j < topN.size(); j++) {
10700 gPad->SetGrid(1, 1);
10711 std::string poiName;
10714 poiName = sOpt3(sOpt3.
Index(
"breakdown:") + 10, sOpt3.
Length());
10717 if (_poi->empty()) {
10718 throw std::runtime_error(
"No floating poi in the fit");
10719 }
else if (_poi->size() != 1) {
10720 throw std::runtime_error(
"Multiple poi in the fit");
10722 poiName = _poi->first()->GetName();
10726 throw std::runtime_error(
TString::Format(
"Cannot find parameter %s", poiName.c_str()));
10728 std::set<std::string> groups;
10732 }
else if (
p->getStringAttribute(
"group")) {
10733 groups.insert(
p->getStringAttribute(
"group"));
10743 groups.size() + 1);
10746 roundedVal.second *= .1;
10754 for (
auto group : groups) {
10756 double variance = pow(
dynamic_cast<RooRealVar *
>(
poi)->getError(), 2);
10760 }
else if ((
p->getStringAttribute(
"group") &&
group ==
p->getStringAttribute(
"group")) ||
10766 int idx =
pars.index(poiName.c_str());
10768 if (reducedVar > variance) {
10769 Warning(
"Draw",
"breakdown group %s variance bigger than preceding?",
group.c_str());
10775 std::pair(sqrt(variance - reducedVar), roundedVal.second));
10803 out->
SetTitle(
"Fit Result Pulls");
10804 std::vector<TString> graphLabels;
10807 ugraph->
SetTitle(
"Fit Result Pulls");
10808 std::vector<TString> ugraphLabels;
10809 std::map<std::string, double> scale;
10810 std::map<std::string, double>
offset;
10816 if (std::isnan(_v->getErrorHi()) || std::isnan(_v->getErrorLo())) {
10817 Warning(
"Draw",
"%s error is invalid", _v->GetName());
10822 double prefitError = 0;
10823 double prefitVal = 0;
10824 double customScale = 0;
10827 prefitError = ip->getError();
10828 prefitVal = ip->getVal();
10831 std::shared_ptr<xRooNode> pConstr;
10834 if (_vv->hasRange(
"pullScale")) {
10835 customScale = (_vv->getMax(
"pullScale") - _vv->getMin(
"pullScale")) / 2.;
10837 auto _constr =
xRooNode(_vv, *
this).constraints();
10838 for (
auto &
c : _constr) {
10841 bool isServer =
true;
10844 for (
auto s :
c->get<
RooAbsArg>()->servers()) {
10845 if (strcmp(s->GetName(),
p->
GetName()) == 0) {
10866 if (pConstr->get<
RooPoisson>() && pConstr->find(
".x")) {
10867 std::string xName = pConstr->find(
".x")->get()->GetName();
10868 prefitVal = pConstr->find(
".x")->get<
RooAbsReal>()->getVal();
10869 for (
auto &_d : pConstr->vars()) {
10870 if (strcmp(
p->
GetName(), _d->get()->GetName()) == 0)
10872 if (xName == _d->get()->GetName())
10877 if (fr->
constPars().
find(pConstr->find(
".x")->get()->GetName())) {
10882 prefitVal /= prefitError;
10884 prefitError = 1. / sqrt(prefitError);
10885 }
else if (
auto _g = pConstr->get<
RooGaussian>(); _g) {
10887 (pConstr->find(
".sigma")) ? pConstr->find(
".sigma")->get<
RooAbsReal>()->getVal() : prefitError;
10889 (pConstr->find(
".x")) ? pConstr->find(
".x")->get<
RooAbsReal>()->getVal() : 0;
10890 if (pConstr->find(
".x") && fr->
constPars().
find(pConstr->find(
".x")->get()->GetName())) {
10894 if (pConstr->find(
".x") &&
10897 prefitVal = pConstr->find(
".mean")->get<
RooAbsReal>()->getVal();
10898 if (fr->
constPars().
find(pConstr->find(
".mean")->get()->GetName())) {
10906 prefitError = customScale;
10907 if (prefitError == 0) {
10908 Warning(
"Draw",
"failed to determine prefit error of %s, using post-fit error",
p->
GetName());
10909 prefitError = _v->getError();
10911 out->
SetPoint(out->
GetN(), out->
GetN(), (_v->getVal() - prefitVal) / prefitError);
10913 (_v->getErrorHi()) / prefitError);
10914 graphLabels.push_back(
p->
GetName());
10915 scale[
p->
GetName()] = prefitError;
10920 prefitError = customScale;
10921 if (prefitError == 0) {
10923 prefitError = (std::max({_v->getMax() - _v->getVal(), _v->getVal() - _v->getMin(), 4.}) / 4);
10924 ugraph->
SetPoint(ugraph->
GetN(), ugraph->
GetN(), (_v->getVal() - prefitVal) / prefitError);
10925 ugraph->
SetPointError(ugraph->
GetN() - 1, 0, 0, (-_v->getErrorLo()) / prefitError,
10926 (_v->getErrorHi()) / prefitError);
10927 ugraphLabels.push_back(
p->
GetName());
10929 out->
SetPoint(out->
GetN(), out->
GetN(), (_v->getVal() - prefitVal) / prefitError);
10931 (_v->getErrorHi()) / prefitError);
10932 graphLabels.push_back(
p->
GetName());
10934 scale[
p->
GetName()] = prefitError;
10940 prefitError = customScale;
10941 if (prefitError == 0) {
10942 prefitError = (std::max({_v->getMax() - _v->getVal(), _v->getVal() - _v->getMin(), 4.}) / 4);
10944 ugraph->
SetPoint(ugraph->
GetN(), ugraph->
GetN(), (_v->getVal() - prefitVal) / prefitError);
10945 ugraph->
SetPointError(ugraph->
GetN() - 1, 0, 0, (-_v->getErrorLo()) / prefitError,
10946 (_v->getErrorHi()) / prefitError);
10947 ugraphLabels.push_back(
p->
GetName());
10948 scale[
p->
GetName()] = prefitError;
10955 for (
int i = 0; i < ugraph->
GetN(); i++)
10956 ugraph->
SetPointX(i, i + graph->GetN());
10957 int nUnconstrained = ugraph->
GetN();
10960 tmpList.
Add(ugraph);
10961 graph->Merge(&tmpList);
10964 for (
auto &
l : ugraphLabels) {
10965 graphLabels.push_back(
l);
10969 graph->SetMarkerStyle(20);
10970 graph->SetMarkerSize(0.5);
10972 graph->SetMaximum(4);
10973 graph->SetMinimum(-4);
10975 bool doHorizontal =
10978 std::vector<std::pair<double, std::string>>
covariances;
10979 std::string poiName;
10980 double maxImpact = 0;
10984 poiName = sOpt3(sOpt3.
Index(
"impact:") + 7, sOpt3.
Length());
10987 if (_poi->empty()) {
10988 throw std::runtime_error(
"No floating poi in the fit");
10989 }
else if (_poi->size() != 1) {
10990 throw std::runtime_error(
"Multiple poi in the fit");
10992 poiName = _poi->first()->GetName();
10996 throw std::runtime_error(
TString::Format(
"Cannot find parameter %s", poiName.c_str()));
11007 for (
auto &label : graphLabels) {
11013 [&](std::pair<double, std::string> i, std::pair<double, std::string> j) {
11014 return doHorizontal ? (std::abs(i.first) < std::abs(j.first))
11015 : (std::abs(i.first) > std::abs(j.first));
11019 std::vector<TString> sortedLabels;
11020 maxImpact = (doHorizontal) ?
covariances.back().first
11027 c.first *= 4. / (maxImpact * 1.2);
11028 sortedLabels.push_back(
c.second);
11030 for (; i < graphLabels.size(); i++) {
11031 if (graphLabels[i] ==
c.second) {
11035 sortedGraph.
AddPoint(sortedGraph.
GetN(), graph->GetPointY(i));
11036 sortedGraph.
SetPointError(sortedGraph.
GetN() - 1, 0, 0, graph->GetErrorYlow(i), graph->GetErrorYhigh(i));
11041 tmpList2.
Add(&sortedGraph);
11042 graph->Merge(&tmpList2);
11044 graphLabels = sortedLabels;
11045 graph->SetTitle(
"Fit Result Impact");
11050 if (doHorizontal) {
11052 std::max(graph->GetN(), 1) - 0.5);
11054 for (
auto &
l : graphLabels) {
11057 if (!graphLabels.empty())
11061 hist =
new TH2D(
GetName(), fr->
GetTitle(), std::max(graph->GetN(), 1), -0.5, std::max(graph->GetN(), 1) - 0.5,
11064 for (
auto &
l : graphLabels) {
11067 if (!graphLabels.empty())
11075 auto histCopy =
dynamic_cast<TH1 *
>(hist->
Clone(
".axis"));
11078 auto _axis = (doHorizontal ? histCopy->GetYaxis() : histCopy->GetXaxis());
11080 graph->GetHistogram()->GetXaxis()->Set(std::max(graph->GetN(), 1), -0.5, std::max(graph->GetN(), 1) - 0.5);
11081 for (
int ii = 1; ii <= _axis->GetNbins(); ii++) {
11082 graph->GetHistogram()->GetXaxis()->SetBinLabel(ii, _axis->GetBinLabel(ii));
11096 auto oldPad =
gPad;
11097 gPad->Divide(1, 1, 1
e-9, 1
e-9);
11100 if (doHorizontal) {
11101 gPad->SetLeftMargin(0.4);
11103 gPad->SetBottomMargin(0.4);
11106 auto pNamesHist =
dynamic_cast<TH1F *
>(graph->GetHistogram()->Clone(
"scales"));
11107 pNamesHist->
Sumw2();
11108 pNamesHist->SetDirectory(
nullptr);
11110 for (
int ii = 1; ii <= graph->GetN(); ii++) {
11112 pNamesHist->SetBinContent(ii,
offset[_p->GetName()]);
11113 pNamesHist->SetBinError(ii, scale[_p->GetName()]);
11114 _axis->SetBinLabel(ii, strlen(_p->GetTitle()) ? _p->GetTitle() : _p->GetName());
11120 for (
int ii = 2; ii >= 1; ii--) {
11124 pullBox->SetPoint(0, (doHorizontal) ? -ii : -0.5, (doHorizontal) ? -0.5 : 0);
11125 pullBox->SetPoint(1, (doHorizontal) ? ii : (_axis->GetNbins() - 0.5 - nUnconstrained),
11126 (doHorizontal) ? -0.5 : 0);
11127 pullBox->SetPointError(0, 0, (doHorizontal) ? (_axis->GetNbins() - nUnconstrained) : ii);
11128 pullBox->SetPointError(1, 0, (doHorizontal) ? (_axis->GetNbins() - nUnconstrained) : ii);
11132 auto pullLine =
new TGraph;
11133 pullLine->
SetName(
"0sigmaLine");
11135 pullLine->SetPoint(0, -0.5, 0);
11136 pullLine->SetPoint(1, _axis->GetNbins() - 0.5, 0);
11137 pullLine->SetLineStyle(2);
11138 pullLine->SetEditable(
false);
11142 if (nUnconstrained > 0) {
11144 pullLine->
SetName(
"dividerLine");
11146 pullLine->SetPoint(0, graph->GetN() - 0.5 - nUnconstrained, -100);
11147 pullLine->SetPoint(1, graph->GetN() - 0.5 - nUnconstrained, 100);
11148 pullLine->SetLineStyle(2);
11149 pullLine->SetEditable(
false);
11155 new TPaveText(
gPad->GetLeftMargin(), 1. -
gPad->GetTopMargin(), 1. -
gPad->GetRightMargin(), 0.98,
"NDCNB");
11163 std::string covQualTxt;
11165 case -1: covQualTxt =
"Unknown";
break;
11166 case 0: covQualTxt =
"Not calculated";
break;
11167 case 1: covQualTxt =
"Approximate";
break;
11168 case 2: covQualTxt =
"Forced Positive-Definite";
break;
11169 case 3: covQualTxt =
"Accurate";
break;
11174 std::string statusCodes;
11183 gPad->SetTicks(0, 0);
11185 if (doHorizontal) {
11187 if (
int(
gPad->GetCanvas()->GetWh()) < pNamesHist->GetNbinsX() * 15) {
11188 gPad->GetCanvas()->SetCanvasSize(
gPad->GetCanvas()->GetWw(), pNamesHist->GetNbinsX() * 15);
11192 double factor = 475. /
gPad->GetCanvas()->GetWh();
11197 new TGaxis(_axis->GetXmin(), -4, _axis->GetXmin(), 4, -1.2 * maxImpact, 1.2 * maxImpact, 510,
"-S");
11199 if (doHorizontal) {
11221 for (
int tt = 0;
tt < 2;
tt++) {
11222 auto impact =
static_cast<TH1 *
>(
11223 graph->GetHistogram()->Clone(
TString::Format(
"%s_impact+",
tt == 0 ?
"prefit" :
"postfit")));
11225 impact->GetYaxis()->SetTitle(
TString::Format(
"#Delta%s/#sigma", poiName.c_str()));
11226 impact->SetBarWidth(0.9);
11227 impact->SetBarOffset(0.05);
11228 impact->SetLineColor(
kBlack);
11229 impact->SetFillColor(
kAzure - 4);
11230 impact->SetFillStyle(
tt == 0 ? 3013 : 1001);
11232 static_cast<TH1 *
>(impact->Clone(
TString::Format(
"%s_impact-",
tt == 0 ?
"prefit" :
"postfit")));
11234 impact2->SetFillColor(
kCyan);
11235 for (
int ii = 1; ii <= pNamesHist->GetNbinsX(); ii++) {
11237 if (
c.second != pNamesHist->GetXaxis()->GetBinLabel(ii))
11241 impact->SetBinContent(ii, ((
tt == 0 && !vv_init->hasError()) || !
vv->hasError())
11243 :
c.first *
vv->getError() /
vv->getErrorHi() *
11244 (
tt == 0 ? (vv_init->getErrorHi() /
vv->getErrorHi()) : 1.));
11245 impact2->SetBinContent(ii, ((
tt == 0 && !vv_init->hasError()) || !
vv->hasError())
11247 :
c.first *
vv->getError() /
vv->getErrorLo() *
11248 (
tt == 0 ? (vv_init->getErrorLo() /
vv->getErrorLo()) : 1.));
11255 for (
int ii = -1; ii <= 1; ii++) {
11256 auto pullLine =
new TGraph;
11259 pullLine->SetPoint(0, -0.5, ii);
11260 pullLine->SetPoint(1, hist->
GetNbinsY() - 0.5, ii);
11261 pullLine->SetLineStyle(2);
11262 pullLine->SetEditable(
false);
11267 new TLegend(0.02, doHorizontal ? (1. - 0.22 * factor) : 0.02, 0.27, (doHorizontal ? 1. : 0.24));
11277 leg1->
AddEntry(hist->
FindObject(
"prefit_impact+"),
"#theta = #hat{#theta}+#Delta#theta",
"f");
11278 leg1->
AddEntry(hist->
FindObject(
"prefit_impact-"),
"#theta = #hat{#theta}-#Delta#theta",
"f");
11281 leg1->
AddEntry(hist->
FindObject(
"postfit_impact+"),
"#theta = #hat{#theta}+#Delta#theta",
"f");
11282 leg1->
AddEntry(hist->
FindObject(
"postfit_impact-"),
"#theta = #hat{#theta}-#Delta#theta",
"f");
11288 new TPaveText(
gPad->GetLeftMargin(), 1. -
gPad->AbsPixeltoY(14), 1. -
gPad->GetRightMargin(), 1.,
"NDC");
11295 : ((
gPad->AbsPixeltoY(0) -
gPad->AbsPixeltoY(10 / factor)) / (
gPad->GetY2() -
gPad->GetY1())));
11298 title->
AddText(histCopy->GetTitle());
11303 graph->SetEditable(
false);
11304 pNamesHist->SetLineWidth(0);
11305 pNamesHist->SetMarkerSize(0);
11306 pNamesHist->SetMarkerStyle(0);
11307 graph->GetListOfFunctions()->Add(pNamesHist,
"same");
11308 if (doHorizontal) {
11311 for (
int p = 0;
p < graph->GetN();
p++) {
11312 graph->SetPoint(
p, graph->GetPointY(
p), graph->GetPointX(
p));
11313 graph->SetPointError(
p, graph->GetErrorYlow(
p), graph->GetErrorYhigh(
p), graph->GetErrorXlow(
p),
11314 graph->GetErrorXhigh(
p));
11317 if (
f->InheritsFrom(
"TH1")) {
11326 else if (
auto g =
dynamic_cast<TGraph *
>(
f)) {
11327 for (
int p = 0;
p <
g->GetN();
p++) {
11328 g->SetPoint(
p,
g->GetPointY(
p),
g->GetPointX(
p));
11331 }
else if (
auto l =
dynamic_cast<TLine *
>(
f)) {
11334 l->
SetY1(_axis->GetXmax());
11335 l->
SetY2(_axis->GetXmax());
11343 for (
size_t i = 0; i < ugraphLabels.size(); i++) {
11344 int bin = pNamesHist->GetNbinsX() - ugraphLabels.size() + i + 1;
11348 auto x = graph->GetPointX(graph->GetN() - ugraphLabels.size() + i);
11349 auto y = graph->GetPointY(graph->GetN() - ugraphLabels.size() + i) +
11350 graph->GetErrorYhigh(graph->GetN() - ugraphLabels.size() + i);
11354 t->SetTextSize(0.025);
11355 t->SetTextAngle(90);
11356 graph->GetListOfFunctions()->Add(t);
11360 graph->SetName(
"pulls");
11365 histCopy->Draw((sOpt.
Contains(
"impact") && !doHorizontal)
11369 hist->
Draw(
"same");
11381 auto hh =
dynamic_cast<TH1 *
>(histCopy->Clone(
".axiscopy"));
11385 (sOpt.
Contains(
"impact") && !doHorizontal)
11399 bool doneDraw =
false;
11405 for (
auto [catName, catVal] : s->get<
RooSimultaneous>()->indexCat()) {
11406 auto _pad =
dynamic_cast<TPad *
>(
gPad->GetPrimitive(
11414 if (
auto c = s->bins().find(catName)) {
11415 c->push_back(std::make_shared<xRooNode>(*
this));
11416 auto ds =
c->datasets().find(
GetName());
11417 c->resize(
c->size() - 1);
11419 std::cout <<
" no ds " <<
GetName() <<
" - this should never happen!" << std::endl;
11435 if (!s && hasSame) {
11438 bool doneDraw =
false;
11439 for (
auto o : *
gPad->GetListOfPrimitives()) {
11454 auto dataGraph =
BuildGraph(
v,
false, (!s && hasSame) ?
gPad :
nullptr);
11459 dataGraph->SetMarkerSize(dataGraph->GetMarkerSize() *
gPad->GetWNDC());
11464 for (
int i = 0; i < dataGraph->GetN(); i++)
11465 tot += dataGraph->GetPointY(i);
11466 dataGraph->Scale(1. / tot);
11471 dataGraph->Draw(
"Az0p");
11472 addLegendEntry(dataGraph, strlen(dataGraph->GetTitle()) ? dataGraph->GetTitle() :
GetName(),
"pEX0");
11478 bool noPoint =
false;
11481 for (
auto o : *
gPad->GetListOfPrimitives()) {
11482 if (
auto h =
dynamic_cast<TH1 *
>(o);
11483 h && strcmp(
h->GetXaxis()->GetName(),
dynamic_cast<TObject *
>(
v)->
GetName()) == 0) {
11484 dataGraph->SetPointY(0,
h->Interpolate(dataGraph->GetPointX(0)));
11491 if (
auto _pad =
dynamic_cast<TPad *
>(
gPad->FindObject(
"auxPad")); _pad) {
11492 if (
auto h =
dynamic_cast<TH1 *
>(_pad->GetPrimitive(
"auxHist"));
h) {
11495 histName = histName(0, histName.
Index(
'|'));
11496 if (
auto mainHist =
dynamic_cast<TH1 *
>(
gPad->GetPrimitive(histName));
11500 auto ratioGraph =
dynamic_cast<TGraphAsymmErrors *
>(dataGraph->Clone(dataGraph->GetName()));
11502 for (
int i = 0; i < ratioGraph->GetN(); i++) {
11503 double val = ratioGraph->GetPointY(i);
11504 int binNum = mainHist->FindFixBin(ratioGraph->GetPointX(i));
11505 double nom = mainHist->GetBinContent(binNum);
11506 double nomerr = mainHist->GetBinError(binNum);
11508 std::get<0>(
auxFunctions[
h->GetYaxis()->GetTitle()])(ratioGraph->GetPointY(i), nom, nomerr);
11509 double yup = std::get<0>(
auxFunctions[
h->GetYaxis()->GetTitle()])(val + ratioGraph->GetErrorYhigh(i),
11512 double ydown = yval - std::get<0>(
auxFunctions[
h->GetYaxis()->GetTitle()])(
11513 val - ratioGraph->GetErrorYlow(i), nom, nomerr);
11514 if (!std::isnan(yval)) {
11515 ratioGraph->SetPointY(i, yval);
11516 if (!std::isnan(yup))
11517 ratioGraph->SetPointEYhigh(i, yup);
11518 if (!std::isnan(ydown))
11519 ratioGraph->SetPointEYlow(i, ydown);
11524 while (i < ratioGraph->GetN()) {
11525 if (ratioGraph->GetPointY(i) == 0 && ratioGraph->GetErrorYhigh(i) == 0 &&
11526 ratioGraph->GetErrorYlow(i) == 0) {
11527 ratioGraph->RemovePoint(i);
11532 auto _tmpPad =
gPad;
11534 ratioGraph->Draw(
"z0psame");
11535 auto minMax = graphMinMax(ratioGraph);
11536 adjustYRange(minMax.first, minMax.second,
h, std::get<1>(
auxFunctions[
h->GetYaxis()->GetTitle()]));
11542 dataGraph->Draw(
"z0p same");
11543 addLegendEntry((noPoint) ?
nullptr : dataGraph, strlen(dataGraph->GetTitle()) ? dataGraph->GetTitle() :
GetName(),
11544 noPoint ?
"" :
"pEX0");
11547 adjustYRange(minMax.first, minMax.second);
11563 gr->
Draw(hasSame ?
"P" :
"AP");
11567 if (forceNames !=
"") {
11570 bool _drawn =
false;
11571 auto _coords =
coords();
11576 std::vector<double> valuesToDo = {initPar->
getVal()};
11577 if (initPar->hasError() || initPar->hasAsymError()) {
11578 valuesToDo.push_back(initPar->getVal() + initPar->getErrorLo());
11579 valuesToDo.push_back(initPar->getVal() + initPar->getErrorHi());
11582 for (
auto valueToDo : valuesToDo) {
11584 for (
auto &
d : _dsets) {
11585 if (!
d->get()->TestBit(1 << 20))
11589 auto _obs =
d->obs();
11590 auto x = _obs.find((
v) ?
dynamic_cast<TObject *
>(
v)->
GetName() : emptyHist->GetXaxis()->GetName());
11591 auto _nll =
nll(
d);
11594 for (
int i = 0; i < nevent; i++) {
11596 bool _skip =
false;
11597 for (
const auto &_c : _coords) {
11599 if (cat->getIndex() != theData->get()->getCatIndex(cat->GetName())) {
11609 auto val = _nll.pars()->getRealValue(initPar->GetName());
11611 _nll.pars()->setRealValue(initPar->GetName(), valueToDo);
11612 auto nllVal = _nll.getEntryVal(i);
11613 _nll.pars()->setRealValue(initPar->GetName(), initPar->getVal());
11614 auto nllVal2 = _nll.getEntryVal(i);
11615 _nll.pars()->setRealValue(initPar->GetName(), val);
11621 auto val = _nll.pars()->getRealValue(initPar->GetName());
11623 _nll.pars()->setRealValue(initPar->GetName(), valueToDo);
11624 auto _extTerm = _nll.extendedTermVal();
11625 _nll.pars()->setRealValue(initPar->GetName(), initPar->getVal());
11626 auto _extTerm2 = _nll.extendedTermVal();
11627 _nll.pars()->setRealValue(initPar->GetName(), val);
11628 for (
int i = 1; i <= emptyHist->GetNbinsX(); i++) {
11629 emptyHist->SetBinContent(i,
11630 emptyHist->GetBinContent(i) + (_extTerm2 - _extTerm) / emptyHist->GetNbinsX());
11631 emptyHist->SetBinError(i, 0);
11633 emptyHist->GetYaxis()->SetTitle(
"log (L(#theta)/L(#theta_{0}))");
11634 emptyHist->SetTitle(
TString::Format(
"#theta = %g", (ii > 1) ? valueToDo : val));
11636 emptyHist->SetLineColor(
kBlack);
11638 emptyHist->SetLineColor(
kRed);
11639 }
else if (ii == 3) {
11640 emptyHist->SetLineColor(
kBlue);
11642 emptyHist->Draw(_drawn ?
"same" :
"");
11649 auto rar = get<RooAbsReal>();
11659 rarNode =
find(
".pdf").get();
11664 if (!nostack && !hasOverlay &&
11674 auto h =
BuildHistogram(
v,
false, hasErrorOpt, 1, 0,
"",
false,
false, 0,
nullptr, nostack,
true );
11685 v = getObject<RooAbsLValue>(
h->GetXaxis()->IsAlphanumeric() ?
h->GetXaxis()->GetTimeFormatOnly()
11686 :
h->GetXaxis()->GetName())
11689 if (
h->GetXaxis()->IsAlphanumeric()) {
11697 if (rar->InheritsFrom(
"RooAbsPdf") && !(rar->InheritsFrom(
"RooRealSumPdf") || rar->InheritsFrom(
"RooAddPdf") ||
11698 rar->InheritsFrom(
"RooSimultaneous"))) {
11701 rar->leafNodeServerList(&s);
11708 for (
auto _p : s) {
11715 ss +=
TString::Format(
"%s=%g", strlen(_p->GetTitle()) ? _p->GetTitle() : _p->GetName(), _v->getVal());
11716 if (_v->hasError()) {
11727 gPad->SetGrid(0, 0);
11729 gPad->SetGrid(1, 1);
11734 h->SetFillStyle(0);
11783 gROOT->SetEditHistograms(
true);
11785 gROOT->SetEditHistograms(
false);
11799 bool hasError(
false);
11800 for (
int i = 0; i <
h->GetSumw2N(); i++) {
11801 if (
h->GetSumw2()->At(i)) {
11812 if (!hasSame &&
h->GetYaxis()->GetTitleFont() % 10 == 2) {
11813 h->GetYaxis()->SetTitleOffset(1.);
11816 TH1 *errHist =
nullptr;
11821 if (rar->getAttribute(
"Logy")) {
11830 auto _hist = (errHist) ? errHist :
h;
11831 auto hCopy = (errHist) ?
nullptr :
dynamic_cast<TH1 *
>(
h->Clone());
11835 hCopy->SetDirectory(
nullptr);
11837 _hist->GetListOfFunctions()->Add(node);
11838 _hist->GetListOfFunctions()->Add(
new TExec(
11841 "gROOT->SetEditHistograms(true);auto h = dynamic_cast<TH1*>(gPad->GetPrimitive(\"%s\")); if(h) { double "
11842 "range= h->GetMaximum()-h->GetMinimum(); if(auto n "
11843 "= dynamic_cast<xRooNode*>(h->GetListOfFunctions()->FindObject(\"%s\")); n && "
11844 "n->TestBit(TObject::kNotDeleted) && n->get<RooRealVar>()->getVal() != h->GetBinContent(1)) {"
11845 "h->SetBinContent(1, "
11846 "TString::Format(\"%%.2g\",int(h->GetBinContent(1)/(range*0.01))*range*0.01).Atof());n->SetContent( "
11847 "h->GetBinContent(1) ); for(auto pp : *h->GetListOfFunctions()) if(auto hh = "
11848 "dynamic_cast<TH1*>(pp))hh->SetBinContent(1,h->GetBinContent(1));} if(h->GetBinContent(1)==0.) "
11849 "h->SetBinContent(1,range*0.005); gPad->Modified();gPad->Update(); }",
11850 _hist->GetName(), node->GetName())));
11856 hCopy->SetFillStyle(0);
11857 _hist->GetListOfFunctions()->Add(hCopy,
"TEXT HIST same");
11860 _hist->SetStats(
false);
11867 bool overlayExisted =
false;
11870 if (
auto existing =
dynamic_cast<TH1 *
>(
gPad->GetPrimitive(
h->GetName())); existing) {
11875 overlayExisted =
true;
11877 TString oldStyle = (rar && rar->getStringAttribute(
"style")) ? rar->getStringAttribute(
"style") :
"";
11878 h->SetTitle(overlayName);
11907 rar->setStringAttribute(
"style", oldStyle ==
"" ?
nullptr : oldStyle.
Data());
11908 if (
auto _style = _styleNode.get<
TStyle>()) {
11913 h->Draw(dOpt ==
"LF2" ?
"e3" : dOpt);
11936 if (
auto stack =
dynamic_cast<THStack *
>(
h->FindObject(
"stack"))) {
11938 TObjLink *lnk = stack->GetHists()->FirstLink();
11943 if (lnk == stack->GetHists()->FirstLink() &&
h->GetMinimum() > hhMin) {
11945 if (hhMin >= 0 && newMin < 0)
11946 newMin = hhMin * 0.99;
11947 adjustYRange(newMin,
h->GetMaximum());
12219 }
else if (!overlayExisted) {
12230 errHist->
Draw(dOpt + (dOpt.
Contains(
"LF2") ?
"e3same" :
"e2same"));
12231 double ymax = -std::numeric_limits<double>::infinity();
12232 double ymin = std::numeric_limits<double>::infinity();
12233 for (
int i = 1; i <= errHist->
GetNbinsX(); i++) {
12239 adjustYRange(
h->GetMinimum() * 0.9,
h->GetMaximum() * 1.1);
12242 if ((!auxPlotTitle.empty()) && !hasSame) {
12244 double padFrac = 0.3;
12245 auto _tmpPad =
gPad;
12246 gPad->SetBottomMargin(padFrac);
12247 auto ratioPad =
new TPad(
"auxPad",
"aux plot", 0, 0, 1, padFrac);
12248 ratioPad->SetFillColor(_tmpPad->GetFillColor());
12249 ratioPad->SetNumber(1);
12250 ratioPad->SetBottomMargin(ratioPad->GetBottomMargin() / padFrac);
12251 ratioPad->SetTopMargin(0.04);
12252 ratioPad->SetLeftMargin(
gPad->GetLeftMargin());
12253 ratioPad->SetRightMargin(
gPad->GetRightMargin());
12255 TH1 *ratioHist =
dynamic_cast<TH1 *
>((errHist) ? errHist->
Clone(
"auxHist") :
h->
Clone(
"auxHist"));
12256 ratioHist->
Reset();
12266 auxPlotTitle.c_str()));
12269 ratioPad->SetGridy();
12271 for (
int i = 1; i <= ratioHist->
GetNbinsX(); i++) {
12279 double rHeight = (1. - padFrac) / padFrac;
12287#if ROOT_VERSION_CODE < ROOT_VERSION(6, 26, 00)
12296 auto _h =
dynamic_cast<TH1 *
>(ratioHist->
Clone(
"auxHist_clone"));
12298 _h->SetFillColor(0);
12304 TString::Format(
"auto h1 = (TH1*)%p; auto h2 = (TH1*)%p; if(h2->GetXaxis()->GetFirst() != "
12305 "h1->GetXaxis()->GetFirst() || h1->GetXaxis()->GetLast()!=h2->GetXaxis()->GetLast()) "
12306 "{h2->GetXaxis()->SetRange(h1->GetXaxis()->GetFirst(),h1->GetXaxis()->GetLast());if(gPad) "
12307 "{gPad->GetCanvas()->Paint();gPad->GetCanvas()->Update();}}",
12308 (
void *)ratioHist, (
void *)(
h))));
12309 ratioHist->
Draw((errHist ?
"e2" :
""));
12313 }
else if (
auto ratioPad =
dynamic_cast<TPad *
>(
gPad->GetPrimitive(
"auxPad")); hasSame && ratioPad) {
12317 if (
auto hr =
dynamic_cast<TH1 *
>(ratioPad->GetPrimitive(
"auxHist"));
12319 TString histName = hr->GetTitle();
12321 histName = histName(0, histName.
Index(
'|'));
12323 if (
auto hnom =
dynamic_cast<TH1 *
>(
gPad->GetPrimitive(histName)); hnom) {
12324 h =
dynamic_cast<TH1 *
>(
h->Clone(
h->GetName()));
12327 for (
int i = 1; i <= hnom->GetNbinsX(); i++) {
12328 double val =
h->GetBinContent(i);
12329 double err =
h->GetBinError(i);
12330 h->SetBinContent(i, std::get<0>(
auxFunctions[hr->GetYaxis()->GetTitle()])(
12331 h->GetBinContent(i), hnom->GetBinContent(i), hnom->GetBinError(i)));
12332 h->SetBinError(i, std::get<0>(
auxFunctions[hr->GetYaxis()->GetTitle()])(
12333 val + err, hnom->GetBinContent(i), hnom->GetBinError(i)) -
12334 h->GetBinContent(i));
12336 auto _tmpPad =
gPad;
12339 if (
auto existing =
dynamic_cast<TH1 *
>(ratioPad->GetPrimitive(
h->GetName())); existing) {
12344 overlayExisted =
true;
12351 double ymax = -std::numeric_limits<double>::infinity();
12352 double ymin = std::numeric_limits<double>::infinity();
12353 for (
int i = 1; i <=
h->GetNbinsX(); i++) {
12354 ymax = std::max(
ymax,
h->GetBinContent(i) +
h->GetBinError(i));
12355 ymin = std::min(
ymin,
h->GetBinContent(i) -
h->GetBinError(i));
12384 if (
auto _pdf = get<RooAbsPdf>();
12385 !hasSame && _pdf &&
coefs(
true).empty()) {
12388 for (
auto &
d : _dsets) {
12389 if (
d->get()->TestBit(1 << 20)) {
12410 if (sFilename.
Contains(
".root:")) {
12412 sFilename = sFilename(0, sFilename.
Index(
".root:") + 5);
12415 if (
auto pdf = get<RooAbsPdf>(); pdf) {
12420 auto addedPdf =
ws.Add(*
this);
12425 mc.
SetPdf(addedPdf->GetName());
12435 }
else if (
auto w = get<RooWorkspace>();
w) {
12437 w->import(*
gROOT->GetListOfColors(),
true);
12439 if (sFilename.
EndsWith(
".json")) {
12440#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
12444 Info(
"SaveAs",
"%s saved to %s",
w->GetName(), sFilename.
Data());
12446 Error(
"SaveAs",
"Unable to save to %s", sFilename.
Data());
12449 Error(
"SaveAs",
"json format workspaces only in ROOT 6.26 onwards");
12454#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
12458 for (
auto &
c :
w->components()) {
12459 c->_eocache =
nullptr;
12463#if ROOT_VERSION_CODE < ROOT_VERSION(6, 38, 00)
12464 if (!
w->writeToFile(sFilename, sOpt !=
"update")) {
12466 if (
w->writeToFile(sFilename, sOpt !=
"update")) {
12468 Info(
"SaveAs",
"%s saved to %s",
w->GetName(), sFilename.
Data());
12474 auto dir =
dest->GetDirectory(source->
GetName());
12479 auto key =
dynamic_cast<TKey *
>(k);
12480 const char *classname = key->GetClassName();
12489 if (dir->FindKey(key->GetName()))
12492 if (strcmp(classname,
"ROOT::Fit::FitConfig") == 0) {
12494 dir->WriteObject(fc, key->GetName());
12497 TObject *obj = key->ReadObj();
12499 dir->WriteTObject(obj, key->
GetName());
12506 if (
gROOT->GetListOfFiles()) {
12507 for (
auto key : *
gROOT->GetListOfFiles()) {
12508 if (
auto fitDb =
dynamic_cast<TMemFile *
>(key);
12510 CopyDir(fitDb, std::make_unique<TFile>(sFilename,
"UPDATE").
get());
12511 Info(
"SaveAs",
"Saved %s to %s", fitDb->GetName(), sFilename.
Data());
12516 Error(
"SaveAs",
"Unable to save to %s", sFilename.
Data());
12518#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
12520 for (
auto &
c :
w->components()) {
12521 c->setExpensiveObjectCache(
w->expensiveObjectCache());
12529 auto res =
GetBinErrors(bin, bin, fr, nToys, errorsHi, errorsLo);
12531 return std::numeric_limits<double>::quiet_NaN();
12537 std::vector<double> out;
12538 out.reserve(
size());
12539 for (
auto child : *
this) {
12540 out.push_back(
child->GetContent());
12554 auto rho = _fr->correlationMatrix();
12558 auto _pars =
pars();
12563 for (
int m = 0;
m < rho.GetNrows();
m++) {
12564 auto p_m =
dynamic_cast<RooRealVar *
>(_fr->floatParsFinal().at(
m));
12570 auto tmp = _p->
getVal();
12571 _p->setVal(p_m->getVal() + p_m->getErrorHi());
12573 _p->setVal(p_m->getVal() + p_m->getErrorLo());
12576 for (
int n = 0;
n < rho.GetNrows();
n++) {
12577 auto p_n =
dynamic_cast<RooRealVar *
>(_fr->floatParsFinal().at(
n));
12583 auto tmp2 = _p2->
getVal();
12584 _p2->setVal(p_n->getVal() + p_n->getErrorHi());
12585 auto nu_n = (p_n == p_m) ? nu_m :
contents();
12586 _p2->setVal(p_n->getVal() + p_n->getErrorLo());
12587 auto nu_n2 = (p_n == p_m) ? nu_m2 :
contents();
12589 for (
int i = 0; i < out.
GetNrows(); i++) {
12590 for (
int j = 0; j < out.
GetNrows(); j++) {
12591 out(i, j) += 0.25 * (nu_m[i] - nu_m2[i]) * rho(
m,
n) * (nu_n[j] - nu_n2[j]);
12599std::pair<double, double>
12603 double err = std::numeric_limits<double>::quiet_NaN();
12605 std::unique_ptr<RooAbsCollection> _snap;
12610 _pars = _fr->floatParsFinal();
12611 _pars = _fr->constPars();
12616 auto _coefs =
coefs();
12618 out =
c->getVal(sobs);
12624 p->setNormRange(rangeName);
12625#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 27, 00)
12628 out *=
p->expectedEvents(*_obs.get<
RooArgList>());
12629#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
12631 p->_normSet =
nullptr;
12633 err =
GetBinError(-1, fr, nToys, errorsHi, errorsLo);
12635 p->setNormRange(
nullptr);
12636 }
else if (
auto p2 =
dynamic_cast<RooAbsReal *
>(
get()); p2) {
12638 auto f = std::shared_ptr<RooAbsReal>(
12639 p2->createIntegral(*std::unique_ptr<RooArgSet>(p2->getObservables(*_obs.get<
RooArgList>())),
12643 out *=
f->getVal();
12644 err =
xRooNode(pr, *
this).GetBinError(-1, fr, nToys, errorsHi, errorsLo);
12646 }
else if (get<RooAbsData>()) {
12649 auto ax = (rangeName) ?
GetXaxis() :
nullptr;
12650 auto rv = (ax) ?
dynamic_cast<RooRealVar *
>(ax->GetParent()) :
nullptr;
12651 auto cv = (ax && !rv) ?
dynamic_cast<RooCategory *
>(ax->GetParent()) :
nullptr;
12653 for (
auto &
v : vals) {
12656 if (rv && !rv->inRange(ax->GetBinCenter(i), rangeName))
12658 if (cv && !cv->isStateInRange(rangeName, ax->GetBinLabel(i)))
12665 out = std::numeric_limits<double>::quiet_NaN();
12668 _pars.RooAbsCollection::operator=(*_snap);
12670 return std::make_pair(out, err);
12683 if (binStart != binEnd || !
fParent) {
12689 std::vector<double> out;
12691 auto _hist =
BuildHistogram(
nullptr,
true,
true, binStart, binEnd, _fr, errorHi, errorLo, nToys);
12695 binEnd = _hist->GetNbinsX();
12696 }
else if (binEnd == binStart && binEnd == -1) {
12700 for (
int bin = binStart; bin <= binEnd; bin++) {
12701 out.push_back(((errorLo && !errorHi) ? (-1.) : 1.) *
12702 _hist->GetBinError(bin));
12829std::string cling::printValue(
const XROOFIT_NAMESPACE_NAME::xRooNode *
v)
12832 return "nullptr\n";
12835 size_t left =
v->size();
12836 for (
auto n : *
v) {
12842 out +=
n->GetName();
12843 if (out.length() > 100 && left > 0) {
12849 out = std::string(
Form(
"<%s> %s",
v->get() ?
v->get()->ClassName() :
"nullptr",
v->
GetName())) + out;
12854 return "<nullptr>";
12856 return Form(
"<%s> %s",
v->get() ?
v->get()->ClassName() :
"nullptr",
v->
GetName());
#define ROOT_VERSION(a, b, c)
#define ROOT_VERSION_CODE
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
const char Option_t
Option string (const char)
static void indent(ostringstream &buf, int indent_level)
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
winID h TVirtualViewer3D TVirtualGLPainter p
winID h TVirtualViewer3D vv
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t dest
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t child
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void funcs
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
R__EXTERN TStyle * gStyle
R__EXTERN TSystem * gSystem
TVectorT< Double_t > TVectorD
double GetBinLowEdge(Int_t bin) const override
Return low edge of bin.
double GetBinUpEdge(Int_t bin) const override
Return up edge of bin.
Int_t FindFixBin(double x) const override
Find bin number corresponding to abscissa x
void Set(Int_t nbins, const double *xbins) override
Initialize axis with variable bins.
RooAbsRealLValue * rvar() const
void SetTitle(const char *title) override
Set the title of the TNamed.
void Set(Int_t nbins, double xmin, double xmax) override
Initialize axis with fix bins.
Int_t FindFixBin(const char *label) const override
Find bin number with label.
RooAbsLValue * var() const
const RooAbsBinning * binning() const
void Set(Int_t nbins, const float *xbins) override
Initialize axis with variable bins.
const char * GetTitle() const override
Returns title of object.
double GetBinWidth(Int_t bin) const override
Return bin width.
PadRefresher(TVirtualPad *p)
A class which maps the current values of a RooRealVar (or a set of RooRealVars) to one of a number of...
bool isBinnedDistribution(const RooArgSet &obs) const override
Tests if the distribution is binned. Unless overridden by derived classes, this always returns false.
bool selfNormalized() const override
Shows if a PDF is self-normalized, which means that no attempt is made to add a normalization term.
double getSimplePropagatedError(const RooFitResult &fr, const RooArgSet &nset_in) const
double evaluate() const override
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
TObject * clone(const char *newname) const override
std::list< double > * binBoundaries(RooAbsRealLValue &obs, double xlo, double xhi) const override
Retrieve bin boundaries if this distribution is binned in obs.
PdfWrapper(const PdfWrapper &other, const char *name=nullptr)
PdfWrapper(RooAbsReal &f, RooAbsReal *coef, bool expEvMode=false, RooAbsPdf *expPdf=nullptr)
The PiecewiseInterpolation is a class that can morph distributions into each other,...
static std::shared_ptr< RooLinkedList > createNLLOptions()
static std::pair< std::shared_ptr< RooAbsData >, std::shared_ptr< const RooAbsCollection > > generateFrom(RooAbsPdf &pdf, const RooFitResult &fr, bool expected=false, int seed=0)
static xRooNLLVar createNLL(const std::shared_ptr< RooAbsPdf > pdf, const std::shared_ptr< RooAbsData > data, const RooLinkedList &nllOpts)
static std::pair< double, double > matchPrecision(const std::pair< double, double > &in)
void Draw(Option_t *opt="") override
Default Draw method for all objects.
std::shared_ptr< xRooHypoPoint > asimov(bool readOnly=false)
std::shared_ptr< const RooFitResult > ufit(bool readOnly=false)
std::shared_ptr< const RooFitResult > cfit_null(bool readOnly=false)
std::shared_ptr< const RooFitResult > cfit_alt(bool readOnly=false)
std::shared_ptr< const RooFitResult > gfit()
void Draw(Option_t *opt="") override
Default Draw method for all objects.
This xRooNLLVar object has several special methods, e.g.
xRooHypoSpace hypoSpace(const char *parName, int nPoints, double low, double high, double alt_value=std::numeric_limits< double >::quiet_NaN(), const xRooFit::Asymptotics::PLLType &pllType=xRooFit::Asymptotics::Unknown, int tsType=0)
The xRooNode class is designed to wrap over a TObject and provide functionality to aid with interacti...
void _Add_(const char *name, const char *opt)
TH1 * BuildHistogram(RooAbsLValue *v=nullptr, bool empty=false, bool errors=false, int binStart=1, int binEnd=0, const xRooNode &fr="", bool errorsHi=false, bool errorsLo=false, int nErrorToys=0, TH1 *templateHist=nullptr, bool nostack=true, bool setInterp=false) const
xRooNode filter(const xRooNode &range) const
std::vector< std::shared_ptr< xRooNode > > fBrowsables
xRooNLLVar nll(const xRooNode &_data, std::initializer_list< RooCmdArg > nllOpts) const
xRooNode poi() const
List of parameters of interest: parameters marked as "of interest" These parameters have the "poi" at...
void SetName(const char *name) override
Set the name of the TNamed.
TGListTreeItem * GetTreeItem(TBrowser *b) const
void SetTitle(const char *title) override
Set the title of the TNamed.
xRooNode Multiply(const xRooNode &child, Option_t *opt="")
xRooNode Replace(const xRooNode &node)
bool SetData(const TObject &obj, const xRooNode &data="obsData")
xRooNode datasets() const
xRooNode Remove(const xRooNode &child)
xRooNode globs() const
List of global observables of this node.
xRooNode Add(const xRooNode &child, Option_t *opt="")
xRooNode(const char *type, const char *name, const char *title="")
const char * GetIconName() const override
Returns mime type name of object.
void Draw(Option_t *opt="") override
Default Draw method for all objects.
bool _IsShowVars_() const
TGraph * BuildGraph(RooAbsLValue *v=nullptr, bool includeZeros=false, TVirtualPad *fromPad=nullptr) const
const std::shared_ptr< xRooNode > & at(size_t idx, bool browseResult=true) const
std::string fRange
! only here so can have char* GetRange return so can return nullptr for no range set !...
xRooNode reduced(const std::string &range="", bool invert=false) const
const char * GetNodeType() const
void _fit_(const char *constParValues="", const char *options="GoF")
bool SetBinContent(int bin, double value, const char *par=nullptr, double parVal=1)
std::shared_ptr< xRooNode > operator[](size_t idx)
void Checked(TObject *obj, bool val)
void Print(Option_t *opt="") const override
Print TNamed name and title.
double GetContent() const
std::shared_ptr< T > acquireNew(Args &&...args)
std::shared_ptr< T > acquire2(Args &&...args)
xRooNode components() const
void SaveAs(const char *filename="", Option_t *option="") const override
Save this object in the file specified by filename.
xRooNode bins() const
bins of a channel or sample, or channels of a multi-channel pdf
std::shared_ptr< xRooNode > find(const std::string &name, bool browseResult=true) const
TGListTree * GetListTree(TBrowser *b) const
xRooNode styles(TObject *initObject=nullptr, bool autoCreate=true) const
xRooNode generate(const xRooNode &fr="", bool expected=false, int seed=0)
void Inspect() const override
Dump contents of this object in a graphics canvas.
std::shared_ptr< xRooNode > getBrowsable(const char *name) const
bool SetXaxis(const RooAbsBinning &binning)
double GetBinError(int bin, const xRooNode &fr="", int nToys=0, bool errorsHi=false, bool errorsLo=false) const
RooArgList argList() const
bool SetBinData(int bin, double value, const xRooNode &data="obsData")
void SetHidden(bool set=true)
std::vector< double > GetBinContents(int binStart=1, int binEnd=0) const
xRooNode pp() const
List of prespecified parameters: non-floatable parameters.
double GetError(const xRooNode &fr="", int nToys=0, bool errorsHi=false, bool errorsLo=false) const
xRooNode constraints() const
std::shared_ptr< xRooNode > fProvider
! like a parent but only for use by getObject
std::shared_ptr< TStyle > style(TObject *initObject=nullptr, bool autoCreate=true) const
xRooNode mainChild() const
xRooNode fitResult(const char *opt="") const
std::shared_ptr< TAxis > fXAxis
! appears that if was fXaxis then dialog box for SetXaxis will take as current value
xRooNode coords(bool setVals=true) const
xRooNode Vary(const xRooNode &child)
xRooNode Constrain(const xRooNode &child)
static std::map< std::string, std::tuple< std::function< double(double, double, double)>, bool > > auxFunctions
xRooNode pars() const
List of parameters (non-observables) of this node.
void _SetContent_(double value)
void SetFitResult(const RooFitResult *fr=nullptr)
void _ShowVars_(bool set=true)
xRooNode coefs(bool recurse=false) const
bool IsFolder() const override
Returns kTRUE in case object contains browsable objects (like containers or lists of other objects).
double GetBinData(int bin, const xRooNode &data="obsData")
bool SetBinError(int bin, double value)
void _Vary_(const char *what)
bool SetContents(const TObject &obj)
std::shared_ptr< TObject > fComp
!
std::pair< double, double > IntegralAndError(const xRooNode &fr="", const char *rangeName=nullptr, int nToys=0, bool errorsHi=false, bool errorsLo=false) const
std::vector< double > contents() const
RooWorkspace * ws() const
The RooWorkspace this node belong to, if any.
xRooNode shallowCopy(const std::string &name, std::shared_ptr< xRooNode > parent=nullptr)
void _generate_(const char *name="", bool expected=false)
std::shared_ptr< TObject > getObject(const std::string &name, const std::string &type="") const
xRooNode np() const
List of nuisance parameters: non-constant parameters that are not marked of interest,...
xRooNode Combine(const xRooNode &rhs, bool silent=false)
xRooNode floats() const
List of parameters that are currently non-constant These parameters do not have the "Constant" attrib...
bool contains(const std::string &name) const
double GetBinContent(int bin) const
xRooNode variations() const
std::string GetPath() const
std::vector< double > GetBinErrors(int binStart=1, int binEnd=0, const xRooNode &fr="", int nToys=0, bool errorsHi=false, bool errorsLo=false) const
auto begin() const -> xRooNodeIterator
std::shared_ptr< xRooNode > parentPdf() const
bool SetContent(double value)
void _scan_(const char *what="plr", double nToys=0, const char *xvar="", int nPointsX=0, double lowX=0, double highX=0, const char *constParValues="", const char *options="")
std::shared_ptr< xRooNode > fParent
!
xRooNode robs() const
List of regular observables of this node.
TClass * IsA() const override
xRooNode & operator=(const TObject &o)
auto end() const -> xRooNodeIterator
xRooNode consts() const
List of parameters that are currently constant.
void _SetBinContent_(int bin, double value, const char *par="", double parVal=1)
std::shared_ptr< TObject > acquire(const std::shared_ptr< TObject > &arg, bool checkFactory=false, bool mustBeNew=false)
std::function< xRooNode(xRooNode *) fBrowseOperation)
void _SetAttribute_(const char *name, const char *value=nullptr)
xRooNode histo(const xRooNode &vars="x", const xRooNode &fr="", bool content=true, bool errors=true, bool stack=true, bool errorsHi=false, bool errorsLo=false, int nErrorToys=0) const
void Browse(TBrowser *b=nullptr) override
Browse object. May be overridden for another default action.
xRooNode obs() const
List of observables (global and regular) of this node.
void SetRange(const char *range, double low=std::numeric_limits< double >::quiet_NaN(), double high=std::numeric_limits< double >::quiet_NaN())
static void SetAuxFunction(const char *title, const std::function< double(double, double, double)> &func, bool symmetrize=false)
std::shared_ptr< TObject > convertForAcquisition(xRooNode &acquirer, const char *opt="") const
xRooNode vars() const
List of variables (observables and parameters) of this node.
const char * GetRange() const
TMatrixDSym covariances(const xRooNode &fr="") const
Class describing the configuration of the fit, options and parameter settings using the ROOT::Fit::Pa...
Common abstract base class for objects that represent a value and a "shape" in RooFit.
bool dependsOn(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=nullptr, bool valueOnly=false) const
Test whether we depend on (ie, are served by) any object in the specified collection.
virtual bool isCategory() const
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string 'value' to this object under key 'key'.
RooFit::OwningPtr< RooArgSet > getParameters(const RooAbsData *data, bool stripDisconnected=true) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
RooFit::OwningPtr< RooArgSet > getObservables(const RooArgSet &set, bool valueOnly=true) const
Given a set of possible observables, return the observables that this PDF depends on.
void SetName(const char *name) override
Set the name of the TNamed.
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key 'key'.
bool getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
void setAttribute(const Text_t *name, bool value=true)
Set (default) or clear a named boolean attribute of this object.
TObject * Clone(const char *newname=nullptr) const override
Make a clone of an object using the Streamer facility.
virtual bool isFundamental() const
Is this object a fundamental type that can be added to a dataset? Fundamental-type subclasses overrid...
Abstract base class for RooRealVar binning definitions.
virtual double highBound() const =0
virtual double lowBound() const =0
Abstract base class for objects that represent a discrete value that can be set from the outside,...
A space to attach TBranches.
const char * getLabel() const
Retrieve current label. Use getCurrentLabel() for more clarity.
Abstract container object that can hold multiple RooAbsArg objects.
RooAbsCollection * selectByAttrib(const char *name, bool value) const
Create a subset of the current collection, consisting only of those elements with the specified attri...
double getRealValue(const char *name, double defVal=0.0, bool verbose=false) const
Get value of a RooAbsReal stored in set with given name.
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
RooAbsCollection & assignValueOnly(const RooAbsCollection &other, bool forceIfSizeOne=false)
Sets the value of any argument in our set that also appears in the other set.
RooAbsCollection * snapshot(bool deepCopy=true) const
Take a snap shot of current collection contents.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Int_t index(const RooAbsArg *arg) const
Returns index of given arg, or -1 if arg is not in the collection.
Storage_t::size_type size() const
bool setRealValue(const char *name, double newVal=0.0, bool verbose=false)
Set value of a RooAbsRealLValue stored in set with given name to newVal No error messages are printed...
virtual RooAbsArg * addClone(const RooAbsArg &var, bool silent=false)
Add a clone of the specified argument to list.
bool selectCommon(const RooAbsCollection &refColl, RooAbsCollection &outColl) const
Create a subset of the current collection, consisting only of those elements that are contained as we...
std::string contentsString() const
Return comma separated list of contained object names as STL string.
void setName(const char *name)
RooAbsArg * find(const char *name) const
Find object with given name in list.
Abstract base class for binned and unbinned datasets.
RooFit::OwningPtr< RooAbsData > reduce(const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
Create a reduced copy of this dataset.
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
RooArgSet const * getGlobalObservables() const
Returns snapshot of global observables stored in this data.
Abstract base class for objects that are lvalues, i.e.
virtual std::list< std::string > getBinningNames() const =0
Abstract interface for all probability density functions.
bool canBeExtended() const
If true, PDF can provide extended likelihood term.
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
void setBin(Int_t ibin, const char *rangeName=nullptr) override
Set value to center of bin 'ibin' of binning 'rangeName' (or of default binning if no range is specif...
bool hasRange(const char *name) const override
Check if variable has a binning with given name.
Context to temporarily change the error logging mode as long as the context is alive.
Abstract base class for objects that represent a real value and implements functionality common to al...
bool isSelectedComp() const
If true, the current pdf is a selected component (for use in plotting)
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
virtual void forceNumInt(bool flag=true)
Efficient implementation of a sum of PDFs of the form.
Calculates the sum of a set of RooAbsReal terms, or when constructed with two sets,...
RooArgList is a container object that can hold multiple RooAbsArg objects.
RooAbsArg * at(Int_t idx) const
Return object at given index, or nullptr if index is out of range.
Abstract interface for RooAbsArg proxy classes.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
RooArgSet * selectByAttrib(const char *name, bool value) const
Use RooAbsCollection::selectByAttrib(), but return as RooArgSet.
Implements a RooAbsBinning in terms of an array of boundary values, posing no constraints on the choi...
Object to represent discrete states.
bool defineType(const std::string &label)
Define a state with given name.
Named container for two doubles, two integers two object points and three string pointers that can be...
static const RooCmdArg & none()
Return reference to null argument.
TObject * Clone(const char *newName=nullptr) const override
Make a clone of an object using the Streamer facility.
Represents a constant real-valued object.
Container class to hold N-dimensional binned data.
Container class to hold unbinned data.
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
TMatrixDSym conditionalCovarianceMatrix(const RooArgList ¶ms) const
Return a reduced covariance matrix, which is calculated as.
void setCovQual(Int_t val)
const TMatrixDSym & covarianceMatrix() const
Return covariance matrix.
Int_t statusCodeHistory(UInt_t icycle) const
const RooArgList & floatParsInit() const
Return list of floating parameters before fit.
TMatrixDSym reducedCovarianceMatrix(const RooArgList ¶ms) const
Return a reduced covariance matrix (Note that Vred is a simple sub-matrix of V, row/columns are order...
const RooArgList & randomizePars() const
Generate random perturbations of the final parameters using the covariance matrix.
void setCovarianceMatrix(TMatrixDSym &V)
Store externally provided correlation matrix in this RooFitResult ;.
double edm() const
Return estimated distance to minimum.
const RooArgList & constPars() const
Return list of constant parameters.
const char * statusLabelHistory(UInt_t icycle) const
Int_t covQual() const
Return MINUIT quality code of covariance matrix.
TH2 * correlationHist(const char *name="correlation_matrix") const
Return TH2D of correlation matrix.
const RooArgList & floatParsFinal() const
Return list of floating parameters after fit.
Int_t status() const
Return MINUIT status code.
void setFinalParList(const RooArgList &list)
Fill the list of final values of the floating parameters.
UInt_t numStatusHistory() const
const TMatrixDSym & correlationMatrix() const
Return correlation matrix ;.
double minNll() const
Return minimized -log(L) value.
Implementation of a probability density function that takes a RooArgList of servers and a C++ express...
A real-valued function sampled from a multidimensional histogram.
bool isBinnedDistribution(const RooArgSet &) const override
Tests if the distribution is binned. Unless overridden by derived classes, this always returns false.
Collection class for internal use, storing a collection of RooAbsArg pointers in a doubly linked list...
TObject * At(int index) const
Return object stored in sequential position given by index.
virtual void Add(TObject *arg)
TIterator * MakeIterator(bool forward=true) const
Create a TIterator for this list.
static RooMsgService & instance()
Return reference to singleton instance.
StreamConfig & getStream(Int_t id)
void setGlobalKillBelow(RooFit::MsgLevel level)
RooFit::MsgLevel globalKillBelow() const
Implementation of a RooCacheManager<RooAbsCacheElement> that specializes in the storage of cache elem...
Efficient implementation of a product of PDFs of the form.
Represents the product of a given set of RooAbsReal objects.
A RooAbsPdf implementation that represent a projection of a given input p.d.f and the object returned...
RooProjectedPdf()
Default constructor.
Implements a PDF constructed from a sum of functions:
Variable that can be changed from the outside.
void setVal(double value) override
Set value of variable to 'value'.
void setError(double value)
bool hasError(bool allowZero=true) const
Facilitates simultaneous fitting of multiple PDFs to subsets of a given dataset.
const RooAbsCategoryLValue & indexCat() const
HypoTestResult is a base class for results from hypothesis tests.
< A class that holds configuration information for a model using a workspace as a store
void SetParametersOfInterest(const RooArgSet &set)
Specify parameters of interest.
void SetObservables(const RooArgSet &set)
Specify the observables.
void SetPdf(const RooAbsPdf &pdf)
Set the Pdf, add to the workspace if not already there.
void SetNuisanceParameters(const RooArgSet &set)
Specify the nuisance parameters (parameters that are not POI).
void SetGlobalObservables(const RooArgSet &set)
Specify the global observables.
A RooAbsArg implementing string values.
Persistable container for RooFit projects.
const std::map< std::string, RooArgSet > & sets() const
bool removeSet(const char *name)
Remove a named set from the workspace.
RooFactoryWSTool & factory()
Return instance to factory tool.
bool import(const RooAbsArg &arg, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}, const RooCmdArg &arg9={})
Import a RooAbsArg object, e.g.
const Double_t * GetArray() const
virtual void SetTitleOffset(Float_t offset=1)
Set distance between the axis and the axis title.
virtual Style_t GetTitleFont() const
virtual void SetLabelSize(Float_t size=0.04)
Set size of axis labels.
virtual void SetTitleSize(Float_t size=0.04)
Set size of axis title.
virtual Float_t GetTitleSize() const
virtual void SetTickSize(Float_t size=0.03)
virtual Float_t GetLabelSize() const
virtual Float_t GetTickLength() const
virtual Float_t GetTitleOffset() const
virtual void SetTickLength(Float_t length=0.03)
Set tick mark length.
virtual void SetNdivisions(Int_t n=510, Bool_t optim=kTRUE)
Set the number of divisions for this axis.
Fill Area Attributes class.
virtual Color_t GetFillColor() const
Return the fill area color.
virtual Style_t GetFillStyle() const
Return the fill area style.
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
virtual Color_t GetLineColor() const
Return the line color.
virtual void SetLineColor(Color_t lcolor)
Set the line color.
virtual Size_t GetMarkerSize() const
Return the marker size.
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
virtual void SetTextAlign(Short_t align=11)
Set the text alignment.
virtual Font_t GetTextFont() const
Return the text font.
virtual void SetTextColor(Color_t tcolor=1)
Set the text color.
virtual void SetTextFont(Font_t tfont=62)
Set the text font.
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Class to manage histogram axis.
virtual void LabelsOption(Option_t *option="h")
Set option(s) to draw axis with labels option can be:
virtual void SetBinLabel(Int_t bin, const char *label)
Set label for bin.
Bool_t IsAlphanumeric() const
Bool_t IsVariableBinSize() const
const char * GetTitle() const override
Returns title of object.
TAxis()
Default constructor.
const TArrayD * GetXbins() const
const char * GetBinLabel(Int_t bin) const
Return label for bin.
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x
virtual const char * GetTimeFormatOnly() const
Return only the time format from the string fTimeFormat.
Using a TBrowser one can browse all ROOT objects.
TBrowserImp * GetBrowserImp() const
static TCanvas * MakeDefCanvas()
Static function to build a default canvas.
TClass instances represent classes, structs and namespaces in the ROOT type system.
Longptr_t GetDataMemberOffset(const char *membername) const
return offset for member name.
Bool_t InheritsFrom(const char *cl) const override
Return kTRUE if this class inherits from a class with name "classname".
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
void SetName(const char *name)
virtual Int_t GetEntries() const
virtual void RemoveAll(TCollection *col)
Remove all objects in collection col from this collection.
static Int_t GetColorPalette(Int_t i)
Static function returning the color number i in current palette.
static void InitializeColors()
Initialize colors used by the TCanvas based graphics (via TColor objects).
static Int_t GetNumberOfColors()
Static function returning number of colors in the color palette.
TDirectory::TContext keeps track and restore the current directory.
Describe directory structure in memory.
virtual TDirectory * GetDirectory(const char *namecycle, Bool_t printError=false, const char *funcname="GetDirectory")
Find a directory using apath.
virtual TList * GetListOfKeys() const
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=nullptr)
Set the value of a resource or create a new resource.
TExec is a utility class that can be used to execute a C++ command when some event happens in a pad.
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
Create a dialog for fit function parameter settings.
System file browser, used as TRootBrowser plug-in.
void AddFSDirectory(const char *entry, const char *path=nullptr, Option_t *opt="")
Add file system directory in the list tree.
A list tree is a widget that can contain a number of items arranged in a tree structure.
ROOT GUI Window base class.
virtual void SetTitle(const char *title="")
Change the title of the axis.
virtual void ImportAxisAttributes(TAxis *axis)
Internal method to import TAxis attributes to this TGaxis.
TGraph with asymmetric error bars.
virtual void SetPointEYlow(Int_t i, Double_t eyl)
Set EYlow for point i.
virtual void SetPointError(Double_t exl, Double_t exh, Double_t eyl, Double_t eyh)
Set ex and ey values for point pointed by the mouse.
virtual void SetPointEYhigh(Int_t i, Double_t eyh)
Set EYhigh for point i.
Double_t GetErrorYlow(Int_t i) const override
Get low error on Y.
A TGraphErrors is a TGraph with error bars.
Double_t GetErrorYlow(Int_t bin) const override
It returns the error along Y at point i.
Double_t GetErrorYhigh(Int_t bin) const override
It returns the error along Y at point i.
A TGraph is an object made of two arrays X and Y with npoints each.
virtual void AddPoint(Double_t x, Double_t y)
Append a new point to the graph.
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
void SetName(const char *name="") override
Set graph name.
void Draw(Option_t *chopt="") override
Draw this graph with its current attributes.
virtual TH1F * GetHistogram() const
Returns a pointer to the histogram used to draw the axis Takes into account the two following cases.
virtual Double_t GetPointY(Int_t i) const
Get y value for point i.
void SetTitle(const char *title="") override
Change (i.e.
virtual void SetPointX(Int_t i, Double_t x)
Set x value for point i.
virtual void SetEditable(Bool_t editable=kTRUE)
if editable=kFALSE, the graph cannot be modified with the mouse by default a TGraph is editable
1-D histogram with a double per channel (see TH1 documentation)
1-D histogram with a float per channel (see TH1 documentation)
TH1 is the base class of all histogram classes in ROOT.
virtual void SetDirectory(TDirectory *dir)
By default, when a histogram is created, it is added to the list of histogram objects in the current ...
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
void SetTitle(const char *title) override
Change/set the title.
virtual Int_t GetNbinsY() const
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
@ kNoTitle
Don't draw the histogram title.
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
TObject * FindObject(const char *name) const override
Search object named name in the list of functions.
virtual Int_t GetNbinsX() const
virtual void SetMaximum(Double_t maximum=-1111)
virtual Bool_t Add(TF1 *h1, Double_t c1=1, Option_t *option="")
Performs the operation: this = this + c1*f1 if errors are defined (see TH1::Sumw2),...
virtual void SetBinError(Int_t bin, Double_t error)
Set the bin Error Note that this resets the bin eror option to be of Normal Type and for the non-empt...
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
void Draw(Option_t *option="") override
Draw this histogram with options.
virtual void SetMinimum(Double_t minimum=-1111)
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
TList * GetListOfFunctions() const
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
virtual Bool_t Divide(TF1 *f1, Double_t c1=1)
Performs the operation: this = this/(c1*f1) if errors are defined (see TH1::Sumw2),...
virtual Double_t GetMinimum(Double_t minval=-FLT_MAX) const
Return minimum value larger than minval of bins in the range, unless the value has been overridden by...
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
2-D histogram with a double per channel (see TH1 documentation)
Service class for 2-D histogram classes.
Int_t Fill(Double_t) override
Invalid Fill method.
The Histogram stack class.
virtual void Add(TH1 *h, Option_t *option="")
Add a new histogram to the list.
Book space in a file, create I/O buffers, to fill them, (un)compress them.
To draw Mathematical Formula.
Storage class for one entry of a TLegend.
This class displays a legend box (TPaveText) containing several legend entries.
TLegendEntry * AddEntry(const TObject *obj, const char *label="", Option_t *option="lpf")
Add a new entry to this legend.
void SetNColumns(Int_t nColumns)
Set the number of columns for the legend.
void SetMargin(Float_t margin)
Use the TLine constructor to create a simple line.
virtual void SetY2(Double_t y2)
virtual void SetX2(Double_t x2)
virtual void SetX1(Double_t x1)
virtual void SetY1(Double_t y1)
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
void Add(TObject *obj) override
A TMemFile is like a normal TFile except that it reads and writes only from memory.
A TMultiGraph is a collection of TGraph (or derived) objects.
virtual void Add(TGraph *graph, Option_t *chopt="")
Add a new graph to the list of graphs.
void Draw(Option_t *chopt="") override
Draw this multigraph with its current attributes.
The TNamed class is the base class for all named ROOT classes.
TObject * Clone(const char *newname="") const override
Make a clone of an object using the Streamer facility.
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
const char * GetName() const override
Returns name of object.
const char * GetTitle() const override
Returns title of object.
void Clear(Option_t *option="") override
Set name and title to empty strings ("").
virtual void SetName(const char *name)
Set the name of the TNamed.
virtual void SetNameTitle(const char *name, const char *title)
Set all the TNamed parameters (name and title).
Wrapper around a TObject so it can be stored in a TList.
TObject * GetObject() const
Mother of all ROOT objects.
virtual void Inspect() const
Dump contents of this object in a graphics canvas.
virtual const char * GetName() const
Returns name of object.
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
virtual TObject * Clone(const char *newname="") const
Make a clone of an object using the Streamer facility.
virtual const char * ClassName() const
Returns name of class to which the object belongs.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
virtual TObject * DrawClone(Option_t *option="") const
Draw a clone of this object in the current selected pad with: gROOT->SetSelectedPad(c1).
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
virtual void SaveAs(const char *filename="", Option_t *option="") const
Save this object in the file specified by filename.
virtual void Delete(Option_t *option="")
Delete this object.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
virtual const char * GetTitle() const
Returns title of object.
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
@ kCanDelete
if object in a list can be deleted
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
The most important graphics class in the ROOT system.
TVirtualPad * cd(Int_t subpadnumber=0) override
Set Current pad.
A Pave (see TPave) with text, lines or/and boxes inside.
virtual TText * AddText(Double_t x1, Double_t y1, const char *label)
Add a new Text line to this pavetext at given coordinates.
virtual void SetMargin(Float_t margin=0.05)
virtual void SetY1NDC(Double_t y1)
virtual void ConvertNDCtoPad()
Convert pave coordinates from NDC to Pad coordinates.
virtual void SetName(const char *name="")
virtual void SetBorderSize(Int_t bordersize=4)
Sets the border size of the TPave box and shadow.
virtual void SetY2NDC(Double_t y2)
void SetEntryVal(Int_t, Double_t)
Set the value of a slice.
void SetEntryFillColor(Int_t, Int_t)
Set the color for the slice "i".
void SetRadius(Double_t)
Set the pie chart's radius' value.
void SetEntryLabel(Int_t, const char *text="Slice")
Set slice number "i" label.
void Draw(Option_t *option="l") override
Draw the pie chart.
Regular expression class.
This class creates a ROOT object browser, constituted by three main tabs.
Sequenceable collection abstract base class.
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
void Stop()
Stop the stopwatch.
Provides iteration through tokens of a given string.
Bool_t NextToken()
Get the next token, it is stored in this TString.
Bool_t IsDec() const
Returns true if all characters in string are decimal digits (0-9).
void ToLower()
Change string to lower-case.
Int_t Atoi() const
Return integer value of string.
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Double_t Atof() const
Return floating-point value contained in string.
Bool_t IsFloat() const
Returns kTRUE if string contains a floating point or integer number.
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
const char * Data() const
TString & ReplaceAll(const TString &s1, const TString &s2)
Bool_t IsAlpha() const
Returns true if all characters in string are alphabetic.
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Int_t CountChar(Int_t c) const
Return number of times character c occurs in the string.
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
TStyle objects may be created to define special styles.
void SetPaintTextFormat(const char *format="g")
Int_t GetOptTitle() const
Float_t GetLabelSize(Option_t *axis="X") const
Return label size.
Float_t GetPadRightMargin() const
Style_t GetTitleFont(Option_t *axis="X") const
Return title font.
Bool_t GetHistMinimumZero() const
Float_t GetPadLeftMargin() const
Float_t GetTitleYSize() const
Double_t GetHistTopMargin() const
Float_t GetPadBottomMargin() const
const char * GetPaintTextFormat() const
Float_t GetPadTopMargin() const
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
The TTimeStamp encapsulates seconds and ns since EPOCH.
void Add(const TTimeStamp &offset)
Add "offset" as a delta time.
const char * AsString(const Option_t *option="") const
Return the date & time as a string.
This class defines a UUID (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDent...
const char * AsString() const
Return UUID as string. Copy string immediately since it will be reused.
static TVirtualPadEditor * GetPadEditor(Bool_t load=kTRUE)
Returns the pad editor dialog. Static method.
TVirtualPad is an abstract base class for the Pad and Canvas classes.
virtual void Modified(Bool_t flag=1)=0
virtual TList * GetListOfPrimitives() const =0
virtual void SetPad(const char *name, const char *title, Double_t xlow, Double_t ylow, Double_t xup, Double_t yup, Color_t color=35, Short_t bordersize=5, Short_t bordermode=-1)=0
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
const char * GetName() const override=0
Returns name of object.
virtual TVirtualPad * GetPad(Int_t subpadnumber) const =0
virtual void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0)=0
virtual Int_t GetLogy() const =0
virtual void SetLogy(Int_t value=1)=0
virtual TObject * GetPrimitive(const char *name) const =0
virtual void SetBorderSize(Short_t bordersize)=0
virtual void SetName(const char *name)=0
TClass * IsA() const override
double evaluate() const override
Evaluate projected p.d.f.
TObject * clone(const char *newname) const override
double expectedEvents(const RooArgSet *nset) const override
Return expected number of events to be used in calculation of extended likelihood.
ExtendMode extendMode() const override
Returns ability of PDF to provide extended likelihood terms.
RooCmdArg RecycleConflictNodes(bool flag=true)
RooConstVar & RooConst(double val)
RooCmdArg Embedded(bool flag=true)
RooCmdArg WeightVar(const char *name="weight", bool reinterpretAsWeight=false)
RooCmdArg GlobalObservables(Args_t &&... argsOrArgSet)
RooCmdArg ExternalConstraints(const RooArgSet &constraintPdfs)
RooCmdArg Range(const char *rangeName, bool adjustNorm=true)
double gaussian_cdf(double x, double sigma=1, double x0=0)
Alternative name for same function.
CoordSystem::Scalar get(DisplacementVector2D< CoordSystem, Tag > const &p)
bool EndsWith(std::string_view string, std::string_view suffix)
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
static constexpr auto NumIntegration
Alias of MsgLevel::NumericIntegration for backwards compatibility.
MsgLevel
Verbosity level for RooMsgService::StreamConfig in RooMsgService.
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Double_t ChisquareQuantile(Double_t p, Double_t ndf)
Evaluate the quantiles of the chi-squared probability distribution function.
Double_t StdDev(Long64_t n, const T *a, const Double_t *w=nullptr)
Same as RMS.
std::string GetName(TCppScope_t)
#define BEGIN_XROOFIT_NAMESPACE
#define END_XROOFIT_NAMESPACE
void removeTopic(RooFit::MsgTopic oldTopic)
bool isNaNWithPayload() const
Test if this struct has a float packed into its mantissa.
static float unpackNaN(double val)
If val is NaN and a this NaN has been tagged as containing a payload, unpack the float from the manti...
static uint64_t sum(uint64_t i)
void(* gOldHandlerr)(int)
void addLegendEntry(TObject *o, const char *title, const char *opt)
void buildHistogramInterrupt(int signum)
auto GETACTBROWSER(TRootBrowser *b)
auto & GETWSSNAPSHOTS(RooWorkspace *w)
bool TopRightPlaceBox(TPad *p, TObject *o, double w, double h, double &xl, double &yb)
TPaveText * getPave(const char *name="labels", bool create=true, bool doPaint=false)
std::string formatLegendString(const std::string &s)
auto GETROOTDIR(TGFileBrowser *b)
const xRooNode * runningNode
auto GETLISTTREE(TGFileBrowser *b)
const T & _or_func(const T &a, const T &b)
std::vector< double > new_getPropagatedErrors(const RooAbsReal &f, const RooFitResult &fr, const RooArgSet &nset, RooArgList **pars, bool asymHi, bool asymLo, const std::vector< int > &bins, const std::function< void(int)> &setBin)
TLegend * getLegend(bool create=true, bool doPaint=false)