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 (
gROOT->GetListOfBrowsers()->At(0))
4256 if (_nll.fOpts->find(
"GoF")) {
4257 gofResult =
TString::Format(
"GoF p-value = %g (mainTerm = %g)\n", fr->constPars().getRealValue(
".pgof"),
4258 fr->constPars().getRealValue(
".mainterm_pgof"));
4260 if (fr->status() != 0) {
4262 TString::Format(
"%s\nData = %s\nFit Status Code = %d\nCov Quality = %d\n%s-------------%s",
4263 fr->GetName(), dsetName.
Data(), fr->status(), fr->covQual(), gofResult.
Data(),
4264 statusCodes.
Data()),
4266 }
else if (fr->covQual() != 3 && _nll.fitConfig()->ParabErrors()) {
4267 new TGMsgBox(
gClient->GetRoot(),
w,
"Fit Finished with Bad Covariance Quality",
4268 TString::Format(
"%s\nData = %s\nFit Status Code = %d\nCov Quality = %d\n%s-------------%s",
4269 fr->GetName(), dsetName.
Data(), fr->status(), fr->covQual(), gofResult.
Data(),
4270 statusCodes.
Data()),
4274 TString::Format(
"%s\nData = %s\nFit Status Code = %d\nCov Quality = %d\n%s-------------%s",
4275 fr->GetName(), dsetName.
Data(), fr->status(), fr->covQual(), gofResult.
Data(),
4276 statusCodes.
Data()));
4279 for (
auto a : *
gROOT->GetListOfBrowsers()) {
4290 if (
auto bi =
dynamic_cast<TRootBrowser *
>(
b->GetBrowserImp())) {
4291 if (
auto fb =
dynamic_cast<TGFileBrowser *
>(bi->GetActBrowser())) {
4292 fb->DoubleClicked(
p, 0);
4293 if (
auto first =
p->GetFirstChild()) {
4295 if (first->IsOpen() &&
TString(first->GetText()) ==
"fits") {
4296 fb->DoubleClicked(first, 0);
4298 }
while ((first = first->GetNextSibling()));
4308 }
catch (
const std::exception &
e) {
4311 (
gROOT->GetListOfBrowsers()->At(0))
4321 datasets().
Add(datasetName, expected ?
"asimov" :
"toy");
4324 for (
auto a : *
gROOT->GetListOfBrowsers()) {
4335 if (
auto bi =
dynamic_cast<TRootBrowser *
>(
b->GetBrowserImp())) {
4336 if (
auto fb =
dynamic_cast<TGFileBrowser *
>(bi->GetActBrowser())) {
4337 fb->DoubleClicked(
p, 0);
4338 if (
auto first =
p->GetFirstChild()) {
4340 if (first->IsOpen() &&
TString(first->GetText()) ==
"datasets") {
4341 fb->DoubleClicked(first, 0);
4343 }
while ((first = first->GetNextSibling()));
4353 }
catch (
const std::exception &
e) {
4356 (
gROOT->GetListOfBrowsers()->At(0))
4359 "Exception",
e.what(),
4365 double highX ,
const char *constParValues,
4366 const char *options)
4375 for (
auto &
d : _dsets) {
4376 if (
d->get()->TestBit(1 << 20)) {
4377 dsetName =
d->get()->GetName();
4381 auto _pars =
pars();
4382 std::unique_ptr<RooAbsCollection> snap(_pars.argList().snapshot());
4385 auto idx = pattern.
Index(
'=');
4388 (idx == -1) ? std::numeric_limits<double>::quiet_NaN() :
TString(pattern(idx + 1, pattern.
Length())).
Atof();
4389 bool foundArg =
false;
4390 for (
auto par : _pars.argList()) {
4393 par->setAttribute(
"Constant",
true);
4394 if (!std::isnan(val)) {
4400 throw std::runtime_error(std::string(
"Unrecognised parameter: ") + pat.
Data());
4408 auto idx = pattern2.
Index(
'=');
4411 if (
auto o = defaultOpts->FindObject(pat)) {
4412 defaultOpts->Remove(o);
4416 val.
IsAlpha() ? val :
nullptr));
4427 hs.SetTitle(sWhat +
" scan" + ((dsetName !=
"") ?
TString::Format(
" [data=%s]", dsetName.
Data()) :
""));
4428 int scanStatus = hs.scan(sWhat +
" visualize", nBinsX, lowX, highX);
4429 if (scanStatus != 0) {
4432 (
gROOT->GetListOfBrowsers()->At(0))
4435 "Scan Finished with Bad Status Code",
4436 TString::Format(
"%s\nData = %s\nScan Status Code = %d", hs.GetName(), dsetName.
Data(), scanStatus),
4440 if (
auto res = hs.result())
4444 _pars.argList() = *snap;
4447 for (
auto a : *
gROOT->GetListOfBrowsers()) {
4458 if (
auto bi =
dynamic_cast<TRootBrowser *
>(
b->GetBrowserImp())) {
4459 if (
auto fb =
dynamic_cast<TGFileBrowser *
>(bi->GetActBrowser())) {
4460 fb->DoubleClicked(
p, 0);
4461 if (
auto first =
p->GetFirstChild()) {
4463 if (first->IsOpen() &&
TString(first->GetText()) ==
"scans") {
4464 fb->DoubleClicked(first, 0);
4466 }
while ((first = first->GetNextSibling()));
4477 }
catch (
const std::exception &
e) {
4480 (
gROOT->GetListOfBrowsers()->At(0))
4491 }
catch (
const std::exception &
e) {
4500#if ROOT_VERSION_CODE > ROOT_VERSION(6, 29, 00)
4505 for (
auto a : *
this) {
4512 for (
auto c :
args) {
4518 f.SetParName(i,
c->GetName());
4520 f.SetParLimits(i,
v->getMin(),
v->getMax());
4521 if (
v->isConstant())
4522 f.FixParameter(i,
v->getVal());
4524 f.SetParameter(i,
v->getVal());
4525 f.SetParError(i,
v->getError());
4536 (
gROOT->GetListOfBrowsers()->At(0))
4542 for (i = 0; i <
f.GetNpar(); i++) {
4548 f.GetParLimits(i, low, high);
4550 v->setConstant(low);
4552 v->setRange(low, high);
4562 throw std::runtime_error(
"Failed to SetContent");
4563 }
catch (
const std::exception &
e) {
4577 std::shared_ptr<TH1D>
h;
4578 auto _b =
dynamic_cast<Axis2 *
>(ax)->binning();
4579 if (_b->isUniform()) {
4586 h->SetOption(
"nostyle");
4587 h->GetXaxis()->SetName(
TString::Format(
"%s;%s", ax->GetParent()->GetName(), ax->GetName()));
4595 if (get<RooProduct>()) {
4599 if (get<RooAbsData>()) {
4600 if (
auto _data = get<RooDataSet>(); _data) {
4601 auto _ax = (bin) ?
GetXaxis() :
nullptr;
4603 throw std::runtime_error(
"Cannot determine binning to fill data");
4605 if (_ax && _ax->GetNbins() < bin) {
4606 throw std::out_of_range(
TString::Format(
"%s range %s only has %d bins", _ax->GetParent()->GetName(),
4607 _ax->GetName(), _ax->GetNbins()));
4613 for (
auto _c :
coords()) {
4617 cut +=
TString::Format(
"%s==%d", _cat->GetName(), _cat->getCurrentIndex());
4624 TString::Format(
"%s>=%f&&%s<%f", _rv->GetName(), _rv->getMin(_rv->getStringAttribute(
"coordRange")),
4625 _rv->GetName(), _rv->getMax(_rv->getStringAttribute(
"coordRange")));
4628 throw std::runtime_error(
"SetBinContent of data: Unsupported coordinate type");
4637 cut2 =
TString::Format(
"%s >= %f && %s < %f", _ax->GetParent()->GetName(), _ax->GetBinLowEdge(bin),
4638 _ax->GetParent()->GetName(), _ax->GetBinUpEdge(bin));
4670 l.remove(*_data->get(),
true,
true);
4675 _data->addColumn(*
x);
4685 for (
auto &o :
obs) {
4687 if (
auto dv =
dynamic_cast<RooRealVar *
>(_data->get()->find(
v->GetName())); dv) {
4688 if (
v->getMin() < dv->getMin())
4689 dv->setMin(
v->getMin());
4690 if (
v->getMax() > dv->getMax())
4691 dv->setMax(
v->getMax());
4694 if (
auto dc =
dynamic_cast<RooCategory *
>(_data->get()->find(
c->GetName())); dc) {
4695 if (!dc->hasLabel(
c->getCurrentLabel())) {
4696 dc->defineType(
c->getCurrentLabel(),
c->getCurrentIndex());
4705 if (
auto _nentries = std::unique_ptr<RooAbsData>(_data->reduce(cutFormula))->numEntries();
4706 _nentries != _ax->GetNbins()) {
4709 if (_nentries > 0) {
4710 Info(
"SetBinContent",
"Binning %s in channel: %s",
GetName(), cut.
Data());
4711 auto _reduced = std::unique_ptr<RooAbsData>(_data->reduce(icutFormula));
4713 for (
int j = 0; j < _reduced->numEntries(); j++) {
4714 auto _obs = _reduced->get(j);
4715 _data->add(*_obs, _reduced->weight());
4718 for (
int i = 1; i <= _ax->GetNbins(); i++) {
4722 dynamic_cast<RooAbsLValue *
>(_ax->GetParent())->setBin(i - 1, _ax->GetName());
4723 _data->add(
obs, _contents.
at(i - 1));
4728 if (std::unique_ptr<RooAbsData>(_data->reduce(cutFormula2))->numEntries() > 0) {
4729 auto _reduced = std::unique_ptr<RooAbsData>(_data->reduce(icutFormula2));
4731 for (
int j = 0; j < _reduced->numEntries(); j++) {
4732 auto _obs = _reduced->get(j);
4733 _data->add(*_obs, _reduced->weight());
4737 dynamic_cast<RooAbsLValue *
>(_ax->GetParent())->setBin(bin - 1, _ax->GetName());
4740 return bb->SetBinContent(bin,
value, par, parVal);
4743 }
else if (get<RooDataHist>()) {
4744 throw std::runtime_error(
"RooDataHist not supported yet");
4748 if (
auto _varies =
variations(); !_varies.empty() || (par && strlen(par))) {
4749 if (!par || strlen(par) == 0) {
4750 return _varies[
"nominal"]->SetBinContent(bin,
value, par, parVal);
4751 }
else if (
auto it = _varies.find(
Form(
"%s=%g", par, parVal)); it) {
4752 return it->SetBinContent(bin,
value);
4764 if (!par || strlen(par) == 0) {
4777 if (strcmp(
c->GetName(),
Form(
"%g",
c->getVal())) == 0) {
4780#if ROOT_VERSION_CODE < ROOT_VERSION(6, 24, 00)
4793 auto bin_pars =
f->dataHist().get(bin - 1);
4794 if (
f->getAttribute(
"density")) {
4795 value /=
f->dataHist().binVolume(*bin_pars);
4797 f->dataHist().set(*bin_pars,
value);
4800 if (
auto otherfName =
f->getStringAttribute(
"symmetrized_by"); otherfName) {
4802 f->setStringAttribute(
"symmetrized_by",
nullptr);
4803 if (
auto x = getObject<RooAbsArg>(otherfName);
x) {
4804 x->setStringAttribute(
"symmetrizes",
nullptr);
4805 x->setStringAttribute(
"symmetrize_nominal",
nullptr);
4807 }
else if (
auto otherfName2 =
f->getStringAttribute(
"symmetrizes"); otherfName2) {
4808 auto nomf = getObject<RooHistFunc>(
f->getStringAttribute(
"symmetrize_nominal"));
4809 auto otherf = getObject<RooHistFunc>(otherfName2);
4810 if (nomf && otherf) {
4811 otherf->dataHist().set(*bin_pars, 2 * nomf->dataHist().weight(bin - 1) -
value);
4812 otherf->setValueDirty();
4819 f2->setNominal(
value);
4828 push_back(std::make_shared<xRooNode>(
data));
4835 return node->SetBinContent(bin,
value);
4842 push_back(std::make_shared<xRooNode>(
data));
4849 return node->SetContents(obj);
4856 if (get<RooProduct>()) {
4860 if (
auto _varies =
variations(); !_varies.empty()) {
4861 return _varies[
"nominal"]->SetBinError(bin,
value);
4876 while (_prodParent && !_prodParent->get<
RooProduct>() && !_prodParent->get<
RooAbsPdf>()) {
4878 _prodParent.reset();
4881 _prodParent = _prodParent->fParent;
4884 (_prodParent && !_prodParent->get<
RooAbsPdf>()) ? _prodParent->factors().find(
"statFactor") :
nullptr;
4885 auto f_stat = (_f_stat) ? _f_stat->get<
ParamHistFunc>() :
nullptr;
4886 if (_f_stat && _f_stat->get() && !f_stat) {
4887 throw std::runtime_error(
"stat factor must be a paramhistfunc");
4896 for (
auto &
p :
xRooNode(
"tmp", *
f, std::shared_ptr<xRooNode>(
nullptr)).vars()) {
4901 auto h = std::unique_ptr<TH1>(
f->dataHist().createHistogram(parNames
4908 h->SetName(
"statFactor");
4910 h->SetOption(
"blankshape");
4913 auto toMultiply =
this;
4917 f_stat =
dynamic_cast<ParamHistFunc *
>(toMultiply->Multiply(*h).get());
4919 throw std::runtime_error(
"Failed creating stat shapeFactor");
4925 TString prefix =
f->getStringAttribute(
"statPrefix");
4926 if (
value && prefix ==
"") {
4930 while (_p && !(_p->get()->InheritsFrom(
"RooRealSumPdf") || _p->get()->InheritsFrom(
"RooAddPdf") ||
4931 _p->get()->InheritsFrom(
"RooWorkspace") || _p->get()->InheritsFrom(
"RooAddition"))) {
4936 auto newVar = (
value == 0) ? getObject<RooRealVar>(
"1")
4937 : acquire<RooRealVar>(
Form(
"%s_bin%d", prefix.
Data(), bin),
4938 Form(
"#gamma^{%s}_{%d}", prefix.
Data(), bin), 1);
4939#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
4944 auto var =
dynamic_cast<RooRealVar *
>(&pSet[bin - 1]);
4946 if (newVar.get() != var) {
4950 for (std::size_t i = 0; i < pSet.
size(); i++) {
4951 if (
int(i) != bin - 1) {
4952 all.
add(*pSet.
at(i));
4963 if (strcmp(rrv->GetName(),
"1") != 0) {
4964 TString origName = (
f->getStringAttribute(
"origName")) ?
f->getStringAttribute(
"origName") :
GetName();
4966 auto bin_pars =
f->dataHist().get(bin - 1);
4967 auto _binContent =
f->dataHist().weight(bin - 1);
4968 if (
f->getAttribute(
"density")) {
4969 _binContent *=
f->dataHist().binVolume(*bin_pars);
4974 for (
auto &[s, sv] : rrv->stringAttributes()) {
4975 if (s.find(
"sumw_") == 0) {
4977 }
else if (s.find(
"sumw2_") == 0) {
4981 if (sumw2 && sumw2 != std::numeric_limits<double>::infinity()) {
4982 double tau = pow(sumw, 2) / sumw2;
4983 rrv->setError((tau < 1
e-15) ? 1e15 : ( 1. / sqrt(tau)));
4984 rrv->setConstant(
false);
4986 auto _constr =
v.constraints();
4988 if (_constr.empty()) {
4989 rrv->setStringAttribute(
"boundConstraint", _constr.Add(
"poisson").get()->GetName());
4991 auto _glob = _constr.at(0)->obs().at(0)->get<
RooRealVar>();
4994 double _min = tau * (1. - 5. * sqrt(1. / tau));
4995 double _max = tau * (1. + 5. * sqrt(1. / tau));
4996 _glob->setRange(_min, _max);
4998 _constr.at(0)->pp().at(0)->SetBinContent(0, tau);
4999 rrv->setStringAttribute(
"boundConstraint", _constr.at(0)->get()->GetName());
5001 rrv->setRange(std::max((1. - 5. * sqrt(1. / tau)), 1
e-15), 1. + 5. * sqrt(1. / tau));
5004 if (
auto _constr =
v.constraints(); !_constr.empty()) {
5005 v.constraints().Remove(*_constr.at(0));
5010 rrv->setConstant(sumw2 == 0);
5022 auto res =
find(
name, browseResult);
5024 throw std::out_of_range(
name +
" does not exist");
5033 if (
auto _w = get<RooWorkspace>(); _w)
5035 if (
auto a = get<RooAbsArg>();
a &&
GETWS(
a)) {
5046 xRooNode out(
".constraints",
nullptr, *
this);
5049 getConstraint = [&](
const xRooNode &
n,
RooAbsArg &par, std::set<RooAbsPdf *> ignore) {
5051 if (ignore.count(_pdf))
5053 ignore.insert(_pdf);
5059 for (
auto &
c :
n.bins()) {
5060 if (
auto oo = getConstraint(*
c, par, ignore); oo) {
5070 for (
auto p : _ws->allPdfs()) {
5071 if (ignore.count(
static_cast<RooAbsPdf *
>(
p)))
5073 if (
p->dependsOn(par)) {
5074 out.emplace_back(std::make_shared<xRooNode>(par.GetName(), *
p, *
this));
5080 return getConstraint(*
n.fParent, par, ignore);
5082 for (
auto p : o->pdfList()) {
5083 if (ignore.count(
static_cast<RooAbsPdf *
>(
p)))
5085 if (
p->dependsOn(par)) {
5086 out.emplace_back(std::make_shared<xRooNode>(par.GetName(), *
p, *
this));
5092 for (
auto &
p :
vars()) {
5096 if (
v->getAttribute(
"Constant") &&
v != get<RooAbsReal>())
5098 if (
v->getAttribute(
"obs"))
5100 getConstraint(*
this, *
v, {get<RooAbsPdf>()});
5108 auto it = out.std::vector<std::shared_ptr<xRooNode>>
::begin();
5109 while (it != out.std::vector<std::shared_ptr<xRooNode>>
::end()) {
5110 bool removeIt =
false;
5111 for (
auto &
c : out) {
5112 if (
c.get() == it->get())
5116 std::set<std::string> parNames;
5117 std::string _cName =
c->GetName();
5119 parNames.insert(_cName.substr(0, _cName.find(
';')));
5120 _cName = _cName.substr(_cName.find(
';') + 1);
5121 }
while (_cName.find(
';') != std::string::npos);
5122 parNames.insert(_cName);
5123 _cName = it->get()->GetName();
5125 parNames.insert(_cName.substr(0, _cName.find(
';')));
5126 _cName = _cName.substr(_cName.find(
';') + 1);
5127 }
while (_cName.find(
';') != std::string::npos);
5128 parNames.insert(_cName);
5130 for (
auto &
x : parNames) {
5131 if (!_cName.empty())
5135 c->TNamed::SetName(_cName.c_str());
5148 if (get<RooAbsArg>() && get<RooAbsArg>()->isFundamental()) {
5149 for (
auto &o : out) {
5150 o->TNamed::SetName(o->get()->GetName());
5164 sName =
TString(
"factory:") + sName;
5168 if (
auto h = get<TH1>();
h) {
5170 std::map<std::string, std::string> stringAttrs;
5172 auto pos = sOpt2.
Index(
"=");
5173 auto start = sOpt2.
Index(
";") + 1;
5179 stringAttrs[sOpt2(start, pos - start)] = sOpt2(pos + 1,
end - pos - 1);
5185 origName = origName(1, origName.
Length());
5188 newObjName(1, newObjName.
Length());
5195 TString varName =
h->GetXaxis()->GetName();
5196 std::string binningName = newObjName.
Data();
5197 if (
auto pos = varName.
Index(
';'); pos != -1) {
5198 binningName = varName(pos + 1, varName.
Length());
5199 varName = varName(0, pos);
5202 if (varName ==
"xaxis" &&
5204 if (
auto ax = acquirer.
GetXaxis(); ax) {
5205 varName = ax->GetParent()->GetName();
5207 binningName = ax->GetName();
5208 }
else if (acquirer.
obs().size() == 1)
5209 varName = acquirer.
obs().
at(0)->get()->GetName();
5211 auto x = acquirer.
acquire<
RooRealVar>(varName,
h->GetXaxis()->GetTitle(),
h->GetXaxis()->GetXmin(),
5212 h->GetXaxis()->GetXmax());
5213 if (
x->getMin() >
h->GetXaxis()->GetXmin())
5214 x->setMin(
h->GetXaxis()->GetXmin());
5215 if (
x->getMax() <
h->GetXaxis()->GetXmax())
5216 x->setMax(
h->GetXaxis()->GetXmax());
5217 if (!
x->hasBinning(binningName.c_str())) {
5218 if (
h->GetXaxis()->IsVariableBinSize()) {
5219 x->setBinning(
RooBinning(
h->GetNbinsX(),
h->GetXaxis()->GetXbins()->GetArray()), binningName.c_str());
5222 RooUniformBinning(
h->GetXaxis()->GetXmin(),
h->GetXaxis()->GetXmax(),
h->GetXaxis()->GetNbins()),
5223 binningName.c_str());
5225 x->getBinning(binningName.c_str()).
SetTitle(
h->GetXaxis()->GetTitle());
5226 if (
x->getBinningNames().size() == 2) {
5228 x->setBinning(
x->getBinning(binningName.c_str()));
5232 if (
x->getBinning(binningName.c_str()).numBins() !=
h->GetNbinsX()) {
5233 throw std::runtime_error(
5234 TString::Format(
"binning mismatch for binning %s of %s", binningName.c_str(),
x->GetName()));
5238 std::shared_ptr<RooAbsArg> _f;
5244 for (
auto &[k,
v] : stringAttrs) {
5245 _f->setStringAttribute(k.c_str(),
v.c_str());
5247 x->setAttribute(
"obs",
true);
5248 }
else if (sOpt2.
Contains(
"shape")) {
5250 for (
int i = 0; i <
x->getBinning(binningName.c_str()).numBins(); i++) {
5251 std::shared_ptr<RooAbsArg> arg;
5252 if (sOpt2.
Contains(
"blankshape")) {
5257 }
else if (
h->GetMinimumStored() != -1111 ||
h->GetMaximumStored() != -1111) {
5260 h->GetBinContent(i + 1),
h->GetMinimumStored(),
5261 h->GetMaximumStored());
5265 h->GetBinContent(i + 1));
5272 auto tmp =
dynamic_cast<RooAbsBinning *
>(
x->getBinningPtr(
nullptr)->Clone());
5273 x->setBinning(
x->getBinning(binningName.c_str()));
5275#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
5276 dynamic_cast<ParamHistFunc *
>(_f.get())->_paramSet.setName(
"paramSet");
5279 .setName(
"paramSet");
5281 x->setBinning(*tmp);
5283 for (
auto &[k,
v] : stringAttrs) {
5284 _f->setStringAttribute(k.c_str(),
v.c_str());
5288 binningName.c_str() );
5290 throw std::runtime_error(
"Couldn't make data hist");
5295 f->setAttribute(
"autodensity");
5298 for (
auto &[k,
v] : stringAttrs) {
5299 _f->setStringAttribute(k.c_str(),
v.c_str());
5303 _f->setStringAttribute(
"xvar",
x->GetName());
5304 _f->setStringAttribute(
"binning", binningName.c_str());
5305 if (strcmp(_f->GetName(), origName.
Data()) && !_f->getStringAttribute(
"alias"))
5306 _f->setStringAttribute(
"alias", origName);
5309 xRooNode tmp(
h->GetName(), _f, acquirer);
5311 _f = std::dynamic_pointer_cast<RooAbsArg>(tmp.
fComp);
5314 _f->setStringAttribute(
"xvar",
x->GetName());
5315 _f->setStringAttribute(
"binning", binningName.c_str());
5318 if (strcmp(_f->GetName(), origName.
Data()) && !_f->getStringAttribute(
"alias"))
5319 _f->setStringAttribute(
"alias", origName);
5339 return std::dynamic_pointer_cast<TStyle>(
styles(initObject, autoCreate).
fComp);
5346 auto arg = get<RooAbsArg>();
5347 if (!initObject && !arg && !
gROOT->GetStyle(t)) {
5351 std::unique_ptr<TObject> argInitObject;
5356 if (arg->getStringAttribute(
"style")) {
5357 t = arg->getStringAttribute(
"style");
5358 }
else if (autoCreate) {
5360 argInitObject = std::make_unique<TH1D>(
GetName(),
GetTitle(), 1, 0, 1);
5361 initObject = argInitObject.get();
5367 std::shared_ptr<TStyle>
style;
5369 if (!
gROOT->GetStyle(t)) {
5370 if ((
style = getObject<TStyle>(t.
Data()))) {
5380 if (
auto x =
dynamic_cast<TAttLine *
>(initObject))
5382 if (
auto x =
dynamic_cast<TAttFill *
>(initObject))
5384 if (
auto x =
dynamic_cast<TAttMarker *
>(initObject))
5392 if (arg && !arg->getStringAttribute(
"style")) {
5393 arg->setStringAttribute(
"style",
style->GetName());
5399std::shared_ptr<TObject>
xRooNode::acquire(
const std::shared_ptr<TObject> &arg,
bool checkFactory,
bool mustBeNew)
5404 return fParent->acquire(arg, checkFactory, mustBeNew);
5408 if (_ws && (
get() == _ws || _ws->arg(
GetName()) || (arg && strcmp(arg->GetName(),
GetName()) == 0))) {
5411 if (
auto a =
dynamic_cast<RooAbsArg *
>(arg.get());
a) {
5412 auto out_arg = _ws->arg(
a->GetName());
5413 TString aName = arg->GetName();
5415 while (out_arg && mustBeNew) {
5417 out_arg = _ws->arg(
a->GetName());
5419 if (aName !=
a->GetName())
5420 Warning(
"acquire",
"Renaming to %s",
a->GetName());
5424 if (
auto res = _ws->factory(arg->GetName()); res) {
5431 Info(
"acquire",
"A copy of %s has been added to workspace %s",
a->GetName(), _ws->GetName());
5437 std::set<std::string> setNames;
5440 setNames.insert(aa.first);
5443 for (
auto &aa : setNames)
5445 out_arg = _ws->arg(
a->GetName());
5446 if (
GETWS(out_arg) != _ws) {
5447 out_arg->setWorkspace(*_ws);
5453 out_arg->leafNodeServerList(&leafs);
5454 std::unique_ptr<RooAbsCollection> globals(leafs.
selectByAttrib(
"global",
true));
5455 for (
auto &aa : *globals) {
5456 if (!
globs->contains(*aa)) {
5463 return std::shared_ptr<TObject>(out_arg, [](
TObject *) {});
5464 }
else if (
auto a2 =
dynamic_cast<RooAbsData *
>(arg.get()); a2) {
5470 return std::shared_ptr<TObject>(_ws->embeddedData(arg->GetName()), [](
TObject *) {});
5471 }
else if (arg->InheritsFrom(
"TNamed")) {
5475 out_arg = fr->
Clone();
5480 TString aName = arg->GetName();
5481 out_arg = _ws->genobj(arg->GetName());
5483 while (aNamed && out_arg && mustBeNew) {
5485 out_arg = _ws->genobj(aNamed->
GetName());
5488 if (aName != arg->GetName()) {
5489 Warning(
"acquire",
"Renaming to %s", arg->GetName());
5491 if (_ws->import(*arg,
false )) {
5495 out_arg = _ws->genobj(arg->GetName());
5500 return std::shared_ptr<TObject>(out_arg, [](
TObject *) {});
5507 auto out =
fProvider->getObject(arg->GetName(), arg->ClassName());
5511 auto _owned =
find(
".memory");
5513 _owned = emplace_back(std::make_shared<xRooNode>(
".memory",
nullptr, *
this));
5518 for (
auto &
r : *_owned) {
5519 if (strcmp(
r->GetName(), arg->GetName()) == 0 && strcmp(
r->get()->ClassName(), arg->ClassName()) == 0) {
5525 std::cout <<
GetName() <<
" taking over " << arg->ClassName() <<
"::" << arg->GetName() << std::endl;
5527 return _owned->emplace_back(std::make_shared<xRooNode>(arg->GetName(), arg, *
this))->fComp;
5555 auto _deps =
vars();
5567 auto a = get<RooAbsArg>();
5569 throw std::runtime_error(
"Cannot SetXaxis of non-arg");
5571 auto _x = acquire<RooRealVar>(
name, title, low, high);
5572 _x->setBinning(binning,
a->
GetName());
5573 _x->getBinning(
a->GetName()).SetTitle(title);
5574 if (_x->getBinningNames().size() == 2) {
5576 _x->setBinning(_x->getBinning(
a->GetName()));
5581 if (_x->getMax() < high)
5583 if (_x->getMin() > low)
5587 if (!_deps.find(
name) && get<RooAbsPdf>()) {
5589 _x->setAttribute(
"obs");
5592 a->setStringAttribute(
"xvar", _x->GetName());
5593 a->setStringAttribute(
"binning",
a->GetName());
5612 return find(
name,
false) !=
nullptr;
5617 std::string partname = (
name.find(
'/') != std::string::npos) ?
name.substr(0,
name.find(
'/')) :
name;
5619 : get<RooSimultaneous>();
5620 std::string extra = (_s) ? _s->indexCat().GetName() :
"";
5621 for (
auto &
child : *
this) {
5623 (_obj &&
name == _obj->GetName()) || (_obj && partname == _obj->GetName()) ||
5624 (!extra.empty() && ((extra +
"=" +
name) ==
child->GetName() ||
5625 (extra +
"=" + partname) ==
child->GetName()))) {
5629 return child->at(
name.substr(partname.length() + 1));
5633 if (partname.find(
'.') != 0) {
5637 for (
auto &child2 :
x.browse()) {
5638 if (
auto _obj = child2->get();
name == child2->GetName() || partname == child2->GetName() ||
5639 (_obj &&
name == _obj->GetName()) ||
5640 (_obj && partname == _obj->GetName())) {
5643 if (partname !=
name &&
name != child2->GetName()) {
5644 return child2->at(
name.substr(partname.length() + 1));
5654 auto child2 =
at(s.Atoi());
5655 if (partname !=
name) {
5656 return child2->at(
name.substr(partname.length() + 1));
5661 if (get<RooWorkspace>() &&
name !=
".memory") {
5663 auto out = std::make_shared<xRooNode>(obj, *
this);
5674 std::string partname = (
name.find(
'/') != std::string::npos) ?
name.substr(0,
name.find(
'/')) :
name;
5677 : get<RooSimultaneous>();
5678 std::string extra = (_s) ? _s->indexCat().GetName() :
"";
5679 std::shared_ptr<xRooNode> folderNode;
5680 for (
auto &
child : *
this) {
5683 ((extra +
"=" +
name) ==
child->GetName() || (extra +
"=" + partname) ==
child->GetName()))) {
5686 return child->operator[](
name.substr(partname.length() + 1));
5692 for (
auto &child2 :
x.browse()) {
5693 if (
name == child2->GetName() || partname == child2->GetName()) {
5695 if (partname !=
name &&
name != child2->GetName()) {
5696 return child2->operator[](
name.substr(partname.length() + 1));
5702 if (
child->fFolder == (std::string(
"!") + partname)) {
5704 folderNode = std::make_shared<xRooNode>(
child->fFolder.c_str(),
nullptr, *
this);
5705 folderNode->push_back(
child);
5709 if (partname !=
name) {
5710 return folderNode->operator[](
name.substr(partname.length() + 1));
5716 auto child2 =
at(s.Atoi());
5717 if (partname !=
name) {
5718 return child2->operator[](
name.substr(partname.length() + 1));
5722 auto out = std::make_shared<xRooNode>(partname.c_str(),
nullptr, *
this);
5724 if (get<RooWorkspace>() && partname ==
"pdfs") {
5725 out->SetName(
"!pdfs");
5727 if (partname !=
name) {
5728 return out->operator[](
name.substr(partname.length() + 1));
5736 for (
auto o : *
gROOT->GetListOfBrowsers()) {
5738 if (!
b || !
b->GetBrowserImp())
5745 if (!
b->GetBrowserImp())
5761 for (
auto o : *
gROOT->GetListOfBrowsers()) {
5763 if (!
b || !
b->GetBrowserImp())
5770 if (
b->GetBrowserImp()) {
5776 if (
auto item =
GETLISTTREE(_b)->FindItemByObj(_root,
const_cast<xRooNode *
>(
this)); item) {
5787 if (
auto a = get<RooAbsArg>();
a)
5788 a->setStringAttribute(
"alias",
name);
5789 for (
auto o : *
gROOT->GetListOfBrowsers()) {
5790 if (
auto b =
dynamic_cast<TBrowser *
>(o);
b) {
5792 item->SetText(
name);
5800 if (
auto o = (get<TNamed>()); o) {
5815 auto findByObj = [&](
const std::shared_ptr<xRooNode> &
n) {
5816 std::vector<std::shared_ptr<xRooNode>> &nn = *
this;
5817 for (
auto &
c : nn) {
5818 if (
c->get() ==
n->get() && strcmp(
n->GetName(),
c->GetName()) == 0)
5821 return std::shared_ptr<xRooNode>(
nullptr);
5824 auto appendChildren = [&](
const xRooNode &
n) {
5826 const std::vector<std::shared_ptr<xRooNode>> &nn(
n);
5827 for (
auto &
c : nn) {
5828 if (
auto existing = findByObj(
c); existing) {
5830 existing->fFolder =
c->fFolder;
5840 const std::vector<std::shared_ptr<xRooNode>> &nn2(*
this);
5841 for (
auto &
c : nn2) {
5842 if (strlen(
c->GetName()) > 0 && (
c->GetName()[0] ==
'.')) {
5846 if (strcmp(
c->GetName(),
"!.pars") == 0) {
5857 size_t addedChildren = 0;
5861 if (get<RooWorkspace>()) {
5862 addedChildren += appendChildren(
datasets());
5876 addedChildren += appendChildren(
components());
5877 if (!get<RooWorkspace>())
5878 addedChildren += appendChildren(
factors());
5880 auto _coefs =
coefs();
5881 if (_coefs.get() && strcmp(_coefs->GetName(),
"1") != 0 && strcmp(_coefs->GetName(),
"ONE") != 0) {
5882 if (_coefs.size() == 1 && _coefs.get<
RooAddition>()) {
5883 if (strcmp(_coefs.at(0)->GetName(),
"1") != 0 &&
5884 strcmp(_coefs.at(0)->GetName(),
"ONE") != 0) {
5885 auto coef = std::make_shared<xRooNode>(
".coef", *_coefs.at(0)->get(), *
this);
5886 if (
auto existing = findByObj(coef); existing) {
5888 existing->fFolder = _coefs.at(0)->fFolder;
5894 if (
auto existing =
find(_coefs.GetName()); existing) {
5896 existing->fFolder = _coefs.fFolder;
5898 emplace_back(std::make_shared<xRooNode>(_coefs));
5902 addedChildren += appendChildren(
variations());
5903 if (get<ParamHistFunc>() || get<RooSimultaneous>())
5904 addedChildren += appendChildren(
bins());
5905 if (get<RooAbsData>())
5906 addedChildren += appendChildren(
obs());
5909 if (
auto arg = get<RooAbsArg>(); arg && addedChildren == 0) {
5910 for (
int i = 0; i < arg->numProxies(); i++) {
5911 auto _proxy = arg->getProxy(i);
5913 auto c = std::make_shared<xRooNode>(
TString::Format(
".%s", _proxy->name()), *(
a->absArg()), *
this);
5914 if (
auto existing = findByObj(
c); existing) {
5916 existing->fFolder =
c->fFolder;
5921 for (
auto &
child : *
this) {
5922 if (strcmp(
child->GetName(),
c->GetName()) == 0) {
5929 for (
auto a2 : *s) {
5930 auto c = std::make_shared<xRooNode>(*a2, *
this);
5931 if (arg->numProxies() != 1) {
5932 c->fFolder = std::string(
"!.") +
5935 if (
auto existing = findByObj(
c); existing) {
5937 existing->fFolder =
c->fFolder;
5953 }
else if (
auto ir = get<RooStats::HypoTestInverterResult>()) {
5957 if (strcmp(
c->GetName(),
".memory") == 0 &&
c->get<
xRooHypoSpace>()) {
5965 fBrowsables.emplace_back(std::make_shared<xRooNode>(
".memory", std::make_shared<xRooHypoSpace>(ir), *
this));
5972 for (
auto a : _axes) {
5973 if (
a != _axes.first())
5976 TString::Format(
"%s=%g",
a->GetName(), hp.coords->getRealValue(
a->GetName(), ir->GetXValue(i)));
5978 auto hpn = emplace_back(std::make_shared<xRooNode>(coordString, hp.hypoTestResult, hs));
5980 hpn->fBrowsables.emplace_back(std::make_shared<xRooNode>(
5986 std::vector<std::shared_ptr<xRooNode>> &nn = *
this;
5987 for (
auto &
c : nn) {
5997 }
else if (get<RooStats::HypoTestResult>()) {
6010 std::make_shared<xRooNLLVar::xRooHypoPoint>(std::dynamic_pointer_cast<RooStats::HypoTestResult>(
fComp));
6011 fBrowsables.emplace_back(std::make_shared<xRooNode>(
".memory", shp, *
this));
6017 if (
auto fit = hp->
ufit()) {
6018 fits.emplace_back(std::make_shared<xRooNode>(fit, *
this))->TNamed::SetName(
"ufit");
6021 fits.emplace_back(std::make_shared<xRooNode>(fit, *
this))->TNamed::SetName(
"cfit_null");
6024 fits.emplace_back(std::make_shared<xRooNode>(fit, *
this))->TNamed::SetName(
"cfit_alt");
6026 if (
auto fit = hp->
gfit()) {
6027 fits.emplace_back(std::make_shared<xRooNode>(fit, *
this))->TNamed::SetName(
"gfit");
6029 if (
auto asi = hp->
asimov()) {
6030 auto asiP = fits.emplace_back(std::make_shared<xRooNode>(
6031 asi->hypoTestResult ? asi->hypoTestResult : std::make_shared<RooStats::HypoTestResult>(asi->result()),
6033 asiP->TNamed::SetName(
"asimov");
6034 asiP->fBrowsables.emplace_back(std::make_shared<xRooNode>(
".memory", asi, asiP));
6036 appendChildren(fits);
6040 auto it = std::vector<std::shared_ptr<xRooNode>>
::begin();
6041 while (it != std::vector<std::shared_ptr<xRooNode>>
::end()) {
6042 if (it->get()->fTimes == 0) {
6043 for (
auto o : *
gROOT->GetListOfBrowsers()) {
6045 if (
b &&
b->GetBrowserImp()) {
6054 if (
auto item =
GETLISTTREE(_b)->FindItemByObj(_root,
this); item) {
6092 xRooNode out(
".obs", std::make_shared<RooArgList>(), *
this);
6094 for (
auto o :
vars()) {
6097 out.emplace_back(o);
6108 xRooNode out(
".globs", std::make_shared<RooArgList>(), *
this);
6110 for (
auto o :
obs()) {
6113 out.emplace_back(o);
6124 xRooNode out(
".robs", std::make_shared<RooArgList>(), *
this);
6126 for (
auto o :
obs()) {
6129 out.emplace_back(o);
6144 xRooNode out(
".pars", std::make_shared<RooArgList>(), *
this);
6146 for (
auto o :
vars()) {
6149 out.emplace_back(o);
6160 xRooNode out(
".consts", std::make_shared<RooArgList>(), *
this);
6162 for (
auto o :
pars()) {
6165 out.emplace_back(o);
6177 xRooNode out(
".floats", std::make_shared<RooArgList>(), *
this);
6179 for (
auto o :
pars()) {
6182 out.emplace_back(o);
6194 xRooNode out(
".poi", std::make_shared<RooArgList>(), *
this);
6196 for (
auto o :
pars()) {
6199 out.emplace_back(o);
6211 xRooNode out(
".np", std::make_shared<RooArgList>(), *
this);
6213 for (
auto o :
pars()) {
6215 (!o->get<
RooAbsArg>()->getAttribute(
"Constant") && !o->get<
RooAbsArg>()->getAttribute(
"poi") &&
6218 out.emplace_back(o);
6229 xRooNode out(
".pp", std::make_shared<RooArgList>(), *
this);
6231 for (
auto o :
pars()) {
6235 out.emplace_back(o);
6246 xRooNode out(
".vars", std::make_shared<RooArgList>(), *
this);
6248 if (
auto coll = get<RooAbsCollection>(); coll) {
6249 for (
auto &
x : *
this) {
6250 for (
auto &
y :
x->vars()) {
6256 if (
auto p = get<RooAbsArg>();
p) {
6262 p->leafNodeServerList(&allLeaves);
6263 for (
auto &
c : allLeaves) {
6265 if (!
c->getAttribute(
"global")) {
6267 out.emplace_back(std::make_shared<xRooNode>(*
c, *
this));
6269 if (
c->getAttribute(
"global")) {
6270 _globs.emplace_back(std::make_shared<xRooNode>(*
c, *
this));
6271 _globs.back()->fFolder =
"!globs";
6272 }
else if (
c->getAttribute(
"obs")) {
6273 out.back()->fFolder =
"!robs";
6274 }
else if (
c->getAttribute(
"poi")) {
6275 out.back()->fFolder =
"!poi";
6276 }
else if (
c->getAttribute(
"np") ||
6278 out.back()->fFolder =
"!np";
6280 out.back()->fFolder =
"!floats";
6282 out.back()->fFolder =
"!pp";
6286 for (
auto g : _globs) {
6288 out.emplace_back(
g);
6290 }
else if (
auto p2 = get<RooAbsData>(); p2) {
6291 for (
auto a : *p2->get()) {
6292 a->setAttribute(
"obs");
6293 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
6296 if (
auto _dglobs = p2->getGlobalObservables()) {
6297 for (
auto &
a : *_dglobs) {
6298 a->setAttribute(
"obs");
6299 a->setAttribute(
"global");
6300 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
6305 a->setAttribute(
"obs");
6306 a->setAttribute(
"global");
6307 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
6310 }
else if (
auto _ws =
ws(); _ws) {
6312 for (
auto a : *_globs2) {
6313 a->setAttribute(
"obs");
6314 a->setAttribute(
"global");
6315 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
6319 for (
auto &_g : _gl->second) {
6320 auto _clone = std::shared_ptr<RooAbsArg>(
dynamic_cast<RooAbsArg *
>(_g->Clone(_g->GetName())));
6321 if (
auto v = std::dynamic_pointer_cast<RooAbsRealLValue>(_clone);
v && _g->getStringAttribute(
"nominal"))
6322 v->setVal(
TString(_g->getStringAttribute(
"nominal")).
Atof());
6323 out.emplace_back(std::make_shared<xRooNode>(_clone, *
this));
6331 for (
auto &_g : *_globs3) {
6332 auto _clone = std::shared_ptr<RooAbsArg>(
dynamic_cast<RooAbsArg *
>(_g->Clone(_g->GetName())));
6333 if (
auto v = std::dynamic_pointer_cast<RooAbsRealLValue>(_clone);
v && _g->getStringAttribute(
"nominal"))
6334 v->setVal(
TString(_g->getStringAttribute(
"nominal")).
Atof());
6335 out.emplace_back(std::make_shared<xRooNode>(_clone, *
this));
6340 }
else if (
auto w = get<RooWorkspace>();
w) {
6341 for (
auto a :
w->components()) {
6344 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
6353 xRooNode out(
".components",
nullptr, *
this);
6355 if (
auto p = get<RooAddPdf>();
p) {
6357 std::set<RooAbsArg *> donePdfs;
6358 for (
auto &o :
p->pdfList()) {
6359 if (donePdfs.count(o))
6361 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
6364 }
else if (
auto p2 = get<RooRealSumPdf>(); p2) {
6378 std::set<RooAbsArg *> doneFuncs;
6379 for (
auto &o : p2->funcList()) {
6380 if (doneFuncs.count(o))
6382 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
6383 doneFuncs.insert(o);
6385 }
else if (
auto p3 = get<RooAddition>(); p3) {
6386 for (
auto &o : p3->list()) {
6387 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
6389 }
else if (
auto p4 = get<RooAbsCollection>(); p4) {
6390 for (
auto &
a : *p4) {
6391 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
6393 }
else if (
auto p5 = get<RooWorkspace>(); p5) {
6394 for (
auto &o : p5->components()) {
6397 bool hasClients =
false;
6398 for (
auto &
c : o->clients()) {
6399 if (!
c->InheritsFrom(
"RooRealIntegral") && p5 ==
GETWS(
c)) {
6406 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
6407 if (o->InheritsFrom(
"RooAbsPdf")) {
6408 out.back()->fFolder =
"!pdfs";
6410 out.back()->fFolder =
"!scratch";
6413 for (
auto &o : p5->allGenericObjects()) {
6417 s = s(0, s.
Index(
';'));
6418 if (
auto _pdf = out.
find(s.
Data()); _pdf) {
6420 out.emplace_back(std::make_shared<xRooNode>(fr->GetName(), *fr, _pdf));
6427 out.emplace_back(std::make_shared<xRooNode>(fr->GetName(), *fr, *
this));
6429 out.back()->fFolder =
"!fits";
6431 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
6432 if (strcmp(out.back()->get()->
ClassName(),
"TStyle") == 0) {
6433 out.back()->fFolder =
"!styles";
6434 }
else if (strcmp(out.back()->get()->
ClassName(),
"RooStats::HypoTestInverterResult") == 0) {
6435 out.back()->fFolder =
"!scans";
6436 }
else if (strcmp(out.back()->get()->
ClassName(),
"RooStats::ModelConfig") == 0) {
6437 out.back()->fFolder =
"!models";
6439 out.back()->fFolder =
"!objects";
6446 if (k.find(
"CACHE_") == 0)
6448 out.emplace_back(std::make_shared<xRooNode>(k.c_str(),
v, *
this));
6449 out.back()->fFolder =
"!sets";
6455 while ((snap = iter->Next())) {
6456 out.emplace_back(std::make_shared<xRooNode>(*snap, *
this));
6457 out.back()->fFolder =
"!snapshots";
6459 }
else if (
auto mc = get<RooStats::ModelConfig>()) {
6462 out.emplace_back(std::make_shared<xRooNode>(
".pdf", *mc->GetPdf(), *
this));
6464 if (mc->GetExternalConstraints()) {
6465 out.emplace_back(std::make_shared<xRooNode>(
".extCons", *mc->GetExternalConstraints(), *
this));
6471 out.emplace_back(
c);
6478 out.emplace_back(
c);
6492 xRooNode out(
".bins",
nullptr, *
this);
6494 if (
auto p = get<RooSimultaneous>();
p) {
6495 std::map<int, std::shared_ptr<xRooNode>> cats;
6496 for (
auto &
c :
p->indexCat()) {
6497 auto pp =
p->getPdf(
c.first.c_str());
6503 for (
auto &[
_,
n] : cats)
6504 out.emplace_back(
n);
6505 }
else if (
auto phf = get<ParamHistFunc>(); phf) {
6507#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
6508 auto &pSet = phf->_paramSet;
6510 auto &pSet = phf->paramList();
6512 for (
auto par : pSet) {
6513 out.emplace_back(std::make_shared<xRooNode>(*par, *
this));
6514 out.back()->fBinNumber = i;
6517 }
else if (
auto ax =
GetXaxis(); ax) {
6518 for (
int i = 1; i <= ax->GetNbins(); i++) {
6520 std::vector<RooAbsArg *> _factors;
6524 for (
auto &ss :
f->bins()[i - 1]->factors())
6525 _factors.push_back(ss->get<
RooAbsArg>());
6527 _factors.push_back(
f->bins()[i - 1]->get<
RooAbsArg>());
6531 out.emplace_back(std::make_shared<xRooNode>(
6532 TString::Format(
"%g<=%s<%g", ax->GetBinLowEdge(i), ax->GetParent()->GetName(), ax->GetBinLowEdge(i + 1)),
6533 _factors.empty() ? nullptr
6537 for (
auto f : _factors) {
6538#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
6544 out.back()->fBinNumber = i;
6558 auto parentCoefs =
fParent->coefs(
true);
6569 std::make_shared<RooProduct>(
".recursiveCoefs",
6574 auto mem = out.emplace_back(std::make_shared<xRooNode>(
".memory",
nullptr, *
this));
6575 mem->emplace_back(std::make_shared<xRooNode>(ourCoefs));
6576 mem->emplace_back(std::make_shared<xRooNode>(parentCoefs));
6580 bool isResidual =
false;
6588 if (!parent->fComp) {
6589 while (!parent->fComp && parent->fParent) {
6590 parent = parent->fParent;
6593 parent = parent->fParent;
6599 for (
auto &o :
p->funcList()) {
6601 if (i >=
p->coefList().size()) {
6603 coefs.add(
p->coefList());
6605 coefs.add(*
p->coefList().at(i));
6610 }
else if (
auto p2 = parent->get<
RooAddPdf>(); p2) {
6612 if (p2->coefList().empty()) {
6617 for (
auto &o : p2->pdfList()) {
6619 if (i >= p2->coefList().size()) {
6621 coefs.add(p2->coefList());
6623 coefs.add(*p2->coefList().at(i));
6634 auto coefSum =
coefs.empty()
6637 : std::make_shared<RooAddition>((isResidual) ?
".sumOfCoefs" :
".coefs",
6638 "Coefficients of",
coefs));
6639 xRooNode out(
".coef", coefSum ? std::dynamic_pointer_cast<RooAbsArg>(std::make_shared<RooFormulaVar>(
6640 ".coef",
"1-sum(otherCoefs)",
"1. - @0", *coefSum))
6642 if (coefSum &&
coefs.size() != 1) {
6643 out.emplace_back(std::make_shared<xRooNode>(
".memory",
nullptr, *
this))
6645 std::make_shared<xRooNode>(
".sumOfCoefs", coefSum, out));
6647 if (!
coefs.empty()) {
6651 }
else if (
coefs.size() == 1) {
6653 if (!
coefs.empty()) {
6662 xRooNode out(
".coefs", coefSum, *
this);
6672 xRooNode out(
".factors",
nullptr, *
this);
6674 if (
auto p = get<RooProdPdf>();
p) {
6676 if (
auto a = _main.get<
RooRealSumPdf>();
a && !
a->getStringAttribute(
"alias")) {
6677 a->setStringAttribute(
"alias",
"samples");
6679 a2->setStringAttribute(
"alias",
"components");
6681 int _npdfs =
p->pdfList().size();
6682 for (
auto &o :
p->pdfList()) {
6683 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
6684 if (_npdfs > 5 && o != _main.get() && out.back()->robs().size() == 0)
6685 out.back()->fFolder =
"!constraints";
6687 }
else if (
auto p2 = get<RooProduct>(); p2) {
6688 for (
auto &o : p2->components()) {
6689 if (o->InheritsFrom(
"RooProduct")) {
6691 auto x =
xRooNode(
"tmp", *o, *
this).factors();
6693 out.emplace_back(std::make_shared<xRooNode>(
n->GetName(),
n->fComp, *
this));
6696 out.emplace_back(std::make_shared<xRooNode>(*o, *
this));
6699 }
else if (
auto w = get<RooWorkspace>();
w) {
6705 for (
auto a :
w->allFunctions()) {
6706 if (_obs.contains(*
a))
6709 for (
auto c :
a->clients()) {
6711 if (
c->InheritsFrom(
"RooProduct")) {
6717 out.emplace_back(std::make_shared<xRooNode>(*
a, *
this));
6761 xRooNode out(
".variations",
nullptr, *
this);
6773 if (
auto p2 = get<PiecewiseInterpolation>(); p2) {
6774#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
6775 out.emplace_back(std::make_shared<xRooNode>(
"nominal", p2->_nominal.arg(), *
this));
6777 out.emplace_back(std::make_shared<xRooNode>(
"nominal", *(p2->nominalHist()), *
this));
6779 for (
size_t i = 0; i < p2->paramList().
size(); i++) {
6781 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=1", p2->paramList().at(i)->GetName()),
6782 *p2->highList().at(i), *
this));
6783 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=-1", p2->paramList().at(i)->GetName()),
6784 *p2->lowList().at(i), *
this));
6786 }
else if (
auto p3 = get<RooStats::HistFactory::FlexibleInterpVar>(); p3) {
6787#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
6788 out.emplace_back(std::make_shared<xRooNode>(
"nominal",
RooFit::RooConst(p3->_nominal), *
this));
6789 for (
size_t i = 0; i < p3->_paramList.size(); i++) {
6790 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=1", p3->_paramList.at(i)->GetName()),
6792 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=-1", p3->_paramList.at(i)->GetName()),
6796 out.emplace_back(std::make_shared<xRooNode>(
"nominal",
RooFit::RooConst(p3->nominal()), *
this));
6797 for (
size_t i = 0; i < p3->variables().
size(); i++) {
6798 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=1", p3->variables().at(i)->GetName()),
6800 out.emplace_back(std::make_shared<xRooNode>(
TString::Format(
"%s=-1", p3->variables().at(i)->GetName()),
6805 }
else if (
auto p4 = get<ParamHistFunc>(); p4) {
6824 for (
auto &k : *
this) {
6833 xRooNode out(
".datasets()",
nullptr, *
this);
6838 if (
auto _ws = get<RooWorkspace>(); _ws) {
6839 for (
auto &
d : _ws->allData()) {
6840 out.emplace_back(std::make_shared<xRooNode>(*
d, *
this));
6841 out.back()->fFolder =
"!datasets";
6843 }
else if (get<RooAbsPdf>() ||
6854 for (
auto _c :
coords()) {
6858 cut +=
TString::Format(
"%s==%d", _cat->GetName(), _cat->getCurrentIndex());
6866 cut +=
TString::Format(
"%s>=%f&&%s<%f", _rv->GetName(), _rv->getMin(_rv->getStringAttribute(
"coordRange")),
6867 _rv->GetName(), _rv->getMax(_rv->getStringAttribute(
"coordRange")));
6872 throw std::runtime_error(
"datasets(): Unsupported coordinate type");
6875 if (
auto s = get<RooSimultaneous>()) {
6877 bool hasMissing =
false;
6879 for (
auto cat : s->indexCat()) {
6880 if (!s->getPdf(cat.first.c_str())) {
6885 extraCut +=
TString::Format(
"%s==%d", s->indexCat().GetName(), cat.second);
6891 cut +=
"(" + extraCut +
")";
6892 cutobs.
add(s->indexCat());
6897 auto a =
dynamic_cast<RooAbsArg *
>(ax->GetParent());
6901 for (
auto &
child : *
this) {
6903 _datasets.push_back(
child);
6905 if (
auto __ws =
ws(); __ws) {
6908 _datasets.push_back(
d);
6912 for (
auto &
d : _datasets) {
6913 if (std::unique_ptr<RooAbsCollection>(
d->obs().argList().selectCommon(_obs))->size() == _obs.
size()) {
6920 out.emplace_back(std::make_shared<xRooNode>(
6925 out.back()->get<
RooAbsData>()->setGlobalObservables(*std::unique_ptr<RooAbsCollection>(
6927 if (
d->get()->TestBit(1 << 20))
6928 out.back()->get()->
SetBit(1 << 20);
6930 out.back()->fBrowsables.emplace_back(std::make_shared<xRooNode>(
".sourceds",
d->fComp, *
this));
6932 out.emplace_back(std::make_shared<xRooNode>(
d->fComp, *
this));
6945 }
else if (
auto mc = get<RooStats::ModelConfig>()) {
6954 xRooNode out(
".parents",
nullptr, *
this);
6955 if (
auto a = get<RooAbsArg>()) {
6956 for (
auto c :
a->clients()) {
6957 out.push_back(std::make_shared<xRooNode>(*
c, *
this));
6965 if (
auto w = get<RooWorkspace>()) {
6966 xRooNode out(
".args",
w->components(), *
this);
6969 }
else if (
auto a = get<RooAbsArg>()) {
6970 xRooNode out(
".args", std::make_shared<RooArgList>(), *
this);
6982 if (
b && strcmp(
b->GetName(),
name) == 0)
6991 if (
auto fr = get<RooFitResult>(); fr) {
6995 if (
auto theData = get<RooDataSet>(); theData) {
6997 TH1 *theHist =
nullptr;
7002 theHist =
dynamic_cast<TH1 *
>(o);
7004 theHist =
static_cast<TH1 *
>(theHist->
Clone());
7015 auto vo =
dynamic_cast<TObject *
>(
v);
7016 if (
v &&
obs().
find(vo->GetName())) {
7020 TString::Format(
"my temp hist;%s", strlen(vo->GetTitle()) ? vo->GetTitle() : vo->GetName()),
7021 cat->numTypes(), 0, cat->numTypes());
7023 std::map<int, std::string> cats;
7024 for (
auto &
c : *cat) {
7025 cats[
c.second] =
c.first;
7027 for (
auto &[
_, label] : cats) {
7031 auto _binning =
v->getBinningPtr(
nullptr);
7032 if (_binning->isUniform()) {
7035 TString::Format(
"my temp hist;%s", strlen(vo->GetTitle()) ? vo->GetTitle() : vo->GetName()),
7036 v->numBins(), _binning->lowBound(), _binning->highBound());
7040 TString::Format(
"my temp hist;%s", strlen(vo->GetTitle()) ? vo->GetTitle() : vo->GetName()),
7041 v->numBins(), _binning->array());
7045 throw std::runtime_error(
"Cannot draw dataset without parent PDF");
7048 theHist = _parentPdf->BuildHistogram(
v,
true);
7054 TH1 *xPos =
static_cast<TH1 *
>(theHist->
Clone(
"xPos"));
7056 TH1 *xPos2 =
static_cast<TH1 *
>(theHist->
Clone(
"xPos2"));
7058 auto nHist = std::unique_ptr<TH1>(
static_cast<TH1 *
>(theHist->
Clone(
"nEntries")));
7063 dataGraph->SetName(
GetName());
7064 dataGraph->SetTitle(strlen(theData->GetTitle()) ? theData->GetTitle() : theData->GetName());
7073 if (
auto w = theData->weightVar();
w &&
w->getStringAttribute(
"fitResult")) {
7076 if (
w->getAttribute(
"expected")) {
7078 dataGraph->SetLineColor(
kBlue);
7081 dataGraph->SetLineColor(
kBlack);
7083 dataGraph->SetMarkerStyle(20);
7084 dataGraph->SetMarkerColor(dataGraph->GetLineColor());
7098 dataGraph->SetTitle(
TString::Format(
"%s = %f", dataGraph->GetTitle(), dataGraph->GetPointX(0)));
7111 auto _pos = pName.
Index(
'=');
7113 int nevent = theData->numEntries();
7114 for (
int i = 0; i < nevent; i++) {
7117 for (
auto _c : _coords) {
7119 if (cat->getIndex() != theData->get()->getCatIndex(cat->GetName())) {
7125 if (!rv->inRange(theData->get()->getRealValue(rv->GetName()), rv->getStringAttribute(
"coordRange"))) {
7133 cat && cat->
getLabel() != pName(_pos + 1, pName.Length())) {
7149 theHist->
Fill((
x) ? xvar->
getVal() : 0.5, theData->weight());
7150 nHist->Fill((
x) ? xvar->
getVal() : 0.5, 1);
7158 for (
int i = 0; i < theHist->
GetNbinsX(); i++) {
7159 if (includeZeros || nHist->GetBinContent(i + 1)) {
7162 dataGraph->SetPoint(dataGraph->GetN(),
7167 xErr = (xErr <= 0) ? 0. : sqrt(xErr);
7170 dataGraph->SetPointError(dataGraph->GetN() - 1, xErr, xErr,
7182 dataGraph->GetHistogram()->GetXaxis()->Set(theHist->
GetNbinsX(), 0, theHist->
GetNbinsX());
7183 for (
int i = 1; i <= theHist->
GetNbinsX(); i++)
7184 dataGraph->GetHistogram()->GetXaxis()->SetBinLabel(i, theHist->
GetXaxis()->
GetBinLabel(i));
7209 auto _styleNode =
styles(dataGraph);
7210 if (
auto _style = _styleNode.get<
TStyle>()) {
7211 *
dynamic_cast<TAttLine *
>(dataGraph) = *_style;
7212 *
dynamic_cast<TAttFill *
>(dataGraph) = *_style;
7213 *
dynamic_cast<TAttMarker *
>(dataGraph) = *_style;
7218 throw std::runtime_error(
"Cannot build graph");
7224 if (
auto _w =
ws(); _w) {
7226 for (
auto o : _w->allGenericObjects()) {
7228 _fr->ResetBit(1 << 20);
7231 res->SetBit(1 << 20);
7233 auto allVars = _w->allVars();
7238 throw std::runtime_error(
"Not supported yet");
7252 throw std::runtime_error(
"Not a RooFitResult");
7258 if (get<RooFitResult>())
7260 if (get<RooAbsData>()) {
7261 if (
auto _fr =
find(
".fitResult"); _fr)
7263#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
7265 if (get<RooDataSet>() && get<RooDataSet>()->weightVar() &&
7266 get<RooDataSet>()->weightVar()->getStringAttribute(
"fitResult")) {
7267 return xRooNode(getObject<const RooFitResult>(get<RooDataSet>()->weightVar()->getStringAttribute(
"fitResult")),
7275 if (sOpt ==
"prefit") {
7282 auto _coefs =
coefs();
7288 std::unique_ptr<RooArgList> _pars(
dynamic_cast<RooArgList *
>(
pars().
argList().selectByAttrib(
"Constant",
false)));
7289 auto fr = std::make_shared<RooFitResult>(
"prefitResult",
"Prefit");
7290 fr->setFinalParList(*_pars);
7291 for (
auto &
p : fr->floatParsFinal()) {
7295 if (
auto s = _v->getStringAttribute(
"nominal"); s)
7298 std::shared_ptr<xRooNode> pConstr;
7299 for (
auto &
c : _constr) {
7302 bool isServer =
true;
7305 for (
auto s :
c->get<
RooAbsArg>()->servers()) {
7306 if (strcmp(s->GetName(),
p->
GetName()) == 0) {
7321 double prefitVal = 0;
7322 double prefitError = 0;
7323 for (
auto &_d : pConstr->vars()) {
7324 if (strcmp(
p->
GetName(), _d->get()->GetName()) == 0)
7328 prefitVal = prefitError;
7329 prefitError = _c->getVal();
7330 }
else if (prefitError == 0) {
7331 prefitError = _d->get<
RooAbsReal>()->getVal();
7337 if (pConstr->get<
RooGaussian>() && pConstr->browse().find(
".sigma")) {
7338 prefitError = pConstr->find(
".sigma")->get<
RooAbsReal>()->getVal();
7344 prefitVal /= prefitError;
7346 prefitError = 1. / sqrt(prefitError);
7348 if (!_v->getStringAttribute(
"nominal"))
7349 _v->setVal(prefitVal);
7350 _v->setError(prefitError);
7359 auto _globs =
globs();
7360 _args.add(_globs.argList());
7361 fr->setConstParList(_args);
7362 std::unique_ptr<RooArgList> _snap(
dynamic_cast<RooArgList *
>(_pars->snapshot()));
7363 for (
auto &
p : *_snap) {
7364 if (
auto atr =
p->getStringAttribute(
"initVal"); atr &&
dynamic_cast<RooRealVar *
>(
p))
7367 fr->setInitParList(*_snap);
7372 if (
auto _w =
ws(); _w) {
7373 auto checkFr = [&](
TObject *o) {
7379 for (
auto p :
pars()) {
7382 if (_fr->floatParsFinal().find(
p->
GetName()) ||
7384 std::abs(_fr->constPars().getRealValue(
p->
GetName(), std::numeric_limits<double>::quiet_NaN()) -
7388 _fr->constPars().getCatIndex(
p->
GetName(), std::numeric_limits<int>().max()))) {
7393 if (!_fr->floatParsFinal().find(
p->
GetName())) {
7396 std::abs(_fr->floatParsFinal().getRealValue(
p->
GetName(),
7397 std::numeric_limits<double>::quiet_NaN()) -
7401 _fr->floatParsFinal().getCatIndex(
p->
GetName(), std::numeric_limits<int>().max()))) {
7410 RooArgList existingFloats(_fr->floatParsFinal());
7411 existingFloats.
remove(newConsts,
true,
true );
7412 auto cov = _fr->reducedCovarianceMatrix(existingFloats);
7413 if (!newFloats.
empty()) {
7415 size_t oldSize = existingFloats.
size();
7416 cov.ResizeTo(oldSize + newFloats.
size(), oldSize + newFloats.
size());
7417 for (
size_t i = 0; i < newFloats.
size(); i++) {
7418 existingFloats.
add(*newFloats.
at(i));
7421 cov(oldSize + i, oldSize + i) = std::pow(
v->getError(), 2);
7425 existingConsts.
remove(newFloats,
true,
true);
7426 existingConsts.
add(newConsts);
7433 auto fr = std::make_shared<RooFitResult>(
TString::Format(
"%s-dirty", _fr->GetName()));
7434 fr->setFinalParList(existingFloats);
7435 fr->setConstParList(existingConsts);
7436 fr->setCovarianceMatrix(cov);
7437 fr->setInitParList(_fr->floatParsInit());
7442 return xRooNode(*_fr, std::make_shared<xRooNode>(*_w, std::make_shared<xRooNode>()));
7447 for (
auto o : _w->allGenericObjects()) {
7448 auto out = checkFr(o);
7453 auto out = checkFr(o);
7460 if (
auto fr = getObject<RooFitResult>(
".fitResult"); fr) {
7466 auto _coefs =
coefs();
7472 std::unique_ptr<RooArgList> _pars(
dynamic_cast<RooArgList *
>(
pars().
argList().selectByAttrib(
"Constant",
false)));
7473 auto fr = std::make_shared<RooFitResult>(
TUUID().AsString());
7475 fr->setFinalParList(*_pars);
7481 for (
int i = 0; i < prevCov->
GetNcols(); i++) {
7482 for (
int j = 0; j < prevCov->
GetNrows(); j++) {
7483 cov(i, j) = (*prevCov)(i, j);
7488 for (
auto &
p : fr->floatParsFinal()) {
7489 if (!prevCov || i >= prevCov->
GetNcols()) {
7491 cov(i, i) = pow(
v->getError(), 2);
7498 int covQualBackup = fr->covQual();
7499 fr->setCovarianceMatrix(cov);
7500 fr->setCovQual(covQualBackup);
7505 auto _globs =
globs();
7506 _args.add(_globs.argList());
7507 fr->setConstParList(_args);
7508 std::unique_ptr<RooArgList> _snap(
dynamic_cast<RooArgList *
>(_pars->snapshot()));
7509 for (
auto &
p : *_snap) {
7510 if (
auto atr =
p->getStringAttribute(
"initVal"); atr &&
dynamic_cast<RooRealVar *
>(
p))
7513 fr->setInitParList(*_snap);
7534 if (!std::isnan(low) && !std::isnan(high) && get<RooRealVar>()) {
7535 if (range && strlen(range)) {
7536 get<RooRealVar>()->setRange(range, low, high);
7538 get<RooRealVar>()->setRange(low, high);
7542 if (
auto o = get<RooAbsArg>(); o)
7543 o->setStringAttribute(
"range", range);
7550 std::string &out =
fRange;
7551 if (
auto o = get<RooAbsArg>(); o && o->getStringAttribute(
"range"))
7552 out = o->getStringAttribute(
"range");
7554 while (out.empty() && _parent) {
7555 if (
auto o = _parent->get<
RooAbsArg>(); o && o->getStringAttribute(
"range"))
7556 out = o->getStringAttribute(
"range");
7557 _parent = _parent->fParent;
7577 for (
auto opt : *defaultOpts) {
7580 for (
auto &i : nllOpts) {
7582 Info(
"nll",
"Overriding NLL Option: %s", o->GetName());
7588 return nll(_data,
l);
7593 if (
auto mc = get<RooStats::ModelConfig>()) {
7597 if (!get<RooAbsPdf>()) {
7599 if (get<RooWorkspace>()) {
7600 std::shared_ptr<xRooNode> mainModel;
7606 throw std::runtime_error(
TString::Format(
"Workspace has multiple models, you must specify which to "
7607 "generate with (found at least %s and %s)",
7608 mainModel->GetName(),
c->GetName()));
7613 return mainModel->generate(fr, expected, seed);
7620 if (get<RooSimultaneous>()) {
7621 std::string selected;
7623 bool hasDeselected =
false;
7624 for (
auto c :
bins()) {
7626 cName = cName(cName.
Index(
'=') + 1, cName.
Length());
7628 hasDeselected =
true;
7630 if (!fromds.empty())
7632 fromds += cName.
Data();
7635 if (!selected.empty())
7637 selected += cName.
Data();
7640 if (hasDeselected) {
7641 std::string dsetName =
"";
7642 if (!fromds.empty()) {
7645 for (
auto &
d : _dsets) {
7646 if (
d->get()->TestBit(1 << 20)) {
7647 dsetName =
d->get()->GetName();
7651 if (dsetName.empty()) {
7652 throw std::runtime_error(
7653 "Need at least one dataset selected (SetChecked) to use for deselected regions");
7657 if (!fromds.empty()) {
7676 auto _globs =
globs();
7677 bool missingGlobs(
false);
7678 for (
auto glob : _globs) {
7679 if (!_fr->constPars().find(*glob->get<
RooAbsArg>())) {
7680 missingGlobs =
true;
7685 std::unique_ptr<RooFitResult> newFr;
7687 newFr = std::make_unique<RooFitResult>(*_fr);
7688 for (
auto glob : _globs) {
7689 if (!newFr->constPars().find(*glob->get<
RooAbsArg>())) {
7697 auto _pars =
pars();
7698 bool missingPars(
false);
7699 for (
auto par : _pars) {
7702 if (!_fr->constPars().find(*par->get<
RooAbsArg>()) && !_fr->floatParsFinal().find(*par->get<
RooAbsArg>())) {
7709 newFr = std::make_unique<RooFitResult>(*_fr);
7710 for (
auto par : _pars) {
7713 if (!newFr->constPars().find(*par->get<
RooAbsArg>()) &&
7714 !newFr->floatParsFinal().find(*par->get<
RooAbsArg>())) {
7731 if (
auto mc = get<RooStats::ModelConfig>()) {
7732 if (mc->GetExternalConstraints()) {
7734 for (
auto o : opts) {
7735 optsWithConstraints.
Add(o->Clone(
nullptr));
7738 return xRooNode(*mc->GetPdf(),
fParent).nll(_data, optsWithConstraints);
7744 if (!get<RooAbsPdf>()) {
7746 if (get<RooWorkspace>()) {
7747 std::shared_ptr<xRooNode> mainPdf, mainModel, otherPdf;
7759 throw std::runtime_error(
TString::Format(
"Workspace has multiple models, you must specify which to "
7760 "build nll with (found at least %s and %s)",
7761 mainModel->GetName(),
c->GetName()));
7766 return mainModel->nll(_data, opts);
7769 throw std::runtime_error(
TString::Format(
"Workspace has multiple pdfs, you must specify which to "
7770 "build nll with (found at least %s and %s)",
7771 mainPdf->GetName(), otherPdf->GetName()));
7773 return mainPdf->nll(_data, opts);
7780 if (get<RooSimultaneous>()) {
7781 std::string selected;
7782 bool hasDeselected =
false;
7783 for (
auto c :
bins()) {
7785 hasDeselected =
true;
7788 cName = cName(cName.Index(
'=') + 1, cName.Length());
7789 if (!selected.empty())
7791 selected += cName.Data();
7801 if (strlen(_data.
GetName()) == 0) {
7804 _d = std::make_shared<xRooNode>(asi.first, *
this);
7807 std::make_shared<xRooNode>(
".globs", std::const_pointer_cast<RooAbsCollection>(asi.second), *_d));
7812 return nll(*_d, opts);
7817 me.push_back(std::make_shared<xRooNode>(_data));
7818 return nll(*me.datasets().at(_data.
GetName()), opts);
7821 auto _globs = _data.
globs();
7834 for (
int i = 0; i < opts.
GetSize(); i++) {
7837 if (strcmp(opts.
At(i)->
GetName(),
"GlobalObservables") == 0) {
7840 _opts->Add(opts.
At(i)->
Clone(
nullptr));
7848 std::dynamic_pointer_cast<RooAbsData>(_data.
fComp), *_opts);
7946 auto rangeName = (_range.empty()) ?
GetRange() : _range;
7947 if (!rangeName.empty()) {
7948 std::vector<TString> patterns;
7950 while (pattern.NextToken()) {
7951 patterns.emplace_back(pattern);
7953 if (
auto s = get<RooSimultaneous>(); s) {
7958 for (
auto &
c :
bins()) {
7960 cName = cName(cName.Index(
'=') + 1, cName.Length());
7961 _cat.setLabel(cName);
7962 bool matchAny =
false;
7963 for (
auto &
p : patterns) {
7965 if (pNoCatName.Contains(
'='))
7966 pNoCatName = pNoCatName(pNoCatName.Index(
'=') + 1, pNoCatName.Length());
7967 if (cName.Contains(
TRegexp(
p,
true)) || cName.Contains(
TRegexp(pNoCatName,
true))) {
7971 if (_cat.hasRange(
p) && _cat.inRange(
p)) {
7976 if ((matchAny && !invert) || (!matchAny && invert)) {
7981 }
else if (
get() && !get<RooAbsCollection>() && !
components().empty()) {
7985 std::vector<TObject *>
funcs;
7987 bool matchAny =
false;
7988 for (
auto &
p : patterns) {
7994 if (!((matchAny && !invert) || (!matchAny && invert)))
7995 funcs.push_back(
c->get());
7999 if (!
funcs.empty()) {
8001 _pdf->setFloor(
false);
8007 }
else if (
auto fr = get<RooFitResult>()) {
8013 for (
auto c : _pars) {
8014 bool matchAny =
false;
8015 for (
auto &
p : patterns) {
8021 if (!((matchAny && !invert) || (!matchAny && invert))) {
8025 _pars.remove(_remPars,
true);
8027 auto _tmp = fr->reducedCovarianceMatrix(_pars);
8028 int covQualBackup = fr->covQual();
8029 fr->setCovarianceMatrix(_tmp);
8030 fr->setCovQual(covQualBackup);
8031 const_cast<RooArgList &
>(fr->floatParsFinal())
8032 .remove(_remPars,
true);
8035 }
else if (!
get() || get<RooAbsCollection>()) {
8040 bool notAllArgs =
false;
8041 bool isVars = (strcmp(
GetName(),
".vars") == 0);
8042 for (
auto c : *this) {
8043 nobs += (
c->fFolder ==
"!robs" ||
c->fFolder ==
"!globs");
8044 bool matchAny =
false;
8045 for (
auto &
p : patterns) {
8047 (isVars &&
p ==
"x" && (
c->fFolder ==
"!robs" ||
c->fFolder ==
"!globs") && nobs == 1)) {
8052 if ((matchAny && !invert) || (!matchAny && invert)) {
8068 return get<RooArgList>() ?
xRooNode(std::make_shared<RooArgList>(),
fParent) : *this;
8077 std::string noName =
"___";
8078 std::string childNames;
8079 for (
auto &
c : *
this) {
8081 if (!childNames.empty())
8083 childNames +=
c->GetName();
8086 if (childNames.empty())
8087 childNames = noName;
8171 return static_cast<RooAbsPdf *
>(intpdf.absArg())->expectedEvents(nset);
8180 return getProjection(&intobs, _normSet, (_normRange.Length() > 0 ? _normRange.Data() :
nullptr), code)->getVal();
8185 RooArgList **pars,
bool asymHi,
bool asymLo,
const std::vector<int> &bins,
8186 const std::function<
void(
int)> &setBin)
8188 const size_t nBins = bins.size();
8189 std::vector<double> out(nBins, 0.);
8196 RooArgList *_pars = (pars) ? *pars :
nullptr;
8201 f.getParameters(&nset, allParamsInAbsReal);
8204 for (
auto *rrvFitRes : static_range_cast<RooRealVar *>(fr.
floatParsFinal())) {
8206 auto rrvInAbsReal =
static_cast<RooRealVar const *
>(allParamsInAbsReal.
find(*rrvFitRes));
8209 if (rrvFitRes->getError() <= std::abs(rrvFitRes->getVal()) * std::numeric_limits<double>::epsilon())
8218 if (std::abs(rrvInAbsReal->getVal() - rrvFitRes->getVal()) > 0.01 * rrvFitRes->getError()) {
8219 std::stringstream errMsg;
8220 errMsg <<
"RooAbsReal::getPropagatedError(): the parameters of the RooAbsReal don't have"
8221 <<
" the same values as in the fit result! The logic of getPropagatedError is broken in this case."
8222 <<
" \n " << rrvInAbsReal->GetName() <<
" : " << rrvInAbsReal->getVal() <<
" vs "
8223 << rrvFitRes->getVal();
8225 throw std::runtime_error(errMsg.str());
8228 _pars->
add(*rrvInAbsReal);
8232 const size_t nPars = _pars->
size();
8242 for (
size_t i = 0; i < nPars; i++) {
8243 for (
size_t j = i; j < nPars; j++) {
8244 C(i, j) = V(i, j) / std::sqrt(V(i, i) * V(j, j));
8250 std::vector<double> nomVals;
8251 if (asymHi || asymLo) {
8252 nomVals.resize(nBins);
8253 for (
size_t k = 0; k < nBins; k++) {
8255 nomVals[k] =
f.getVal(nset);
8261 std::vector<TVectorD> F(nBins,
TVectorD(nPars));
8263 std::vector<double> plusVar(nBins), minusVar(nBins);
8265 for (
size_t ivar = 0; ivar < nPars; ivar++) {
8267 auto &rrv =
static_cast<RooRealVar &
>((*_pars)[ivar]);
8270 double cenVal = rrv.
getVal();
8272 if (asymHi || asymLo) {
8273 double errValHi = frrrv->getErrorHi();
8274 rrv.setVal(errValHi > 0 ? std::min(cenVal + errValHi, rrv.getMax())
8275 : std::max(cenVal + errValHi, rrv.getMin()));
8276 for (
size_t k = 0; k < nBins; k++) {
8278 plusVar[k] =
f.getVal(nset);
8280 double errValLo = frrrv->getErrorLo();
8281 rrv.setVal(errValLo > 0 ? std::min(cenVal + errValLo, rrv.getMax())
8282 : std::max(cenVal + errValLo, rrv.getMin()));
8283 for (
size_t k = 0; k < nBins; k++) {
8285 minusVar[k] =
f.getVal(nset);
8288 for (
size_t k = 0; k < nBins; k++) {
8289 double hi = plusVar[k];
8290 double lo = minusVar[k];
8293 hi = std::max(plusVar[k], minusVar[k]);
8294 lo = 2 * nomVals[k] -
hi;
8297 lo = std::min(plusVar[k], minusVar[k]);
8298 hi = 2 * nomVals[k] - lo;
8300 F[k][ivar] = (
hi - lo) * 0.5;
8303 double errVal = sqrt(V(ivar, ivar));
8305 rrv.setVal(std::min(cenVal + errVal, rrv.getMax()));
8306 for (
size_t k = 0; k < nBins; k++) {
8308 plusVar[k] =
f.getVal(nset);
8311 rrv.setVal(std::max(cenVal - errVal, rrv.getMin()));
8312 for (
size_t k = 0; k < nBins; k++) {
8314 minusVar[k] =
f.getVal(nset);
8317 for (
size_t k = 0; k < nBins; k++) {
8318 F[k][ivar] = (plusVar[k] - minusVar[k]) * 0.5;
8329 setBin(bins[nBins - 1]);
8334 for (
size_t k = 0; k < nBins; k++) {
8335 out[k] = std::sqrt(F[k] * (C * F[k]));
8352 fFunc(
"func",
"func", this,
f),
8353 fCoef(
"coef",
"coef", this),
8354 fExpPdf(
"expPdf",
"expPdf", this)
8359 fCoef.setArg(*coef);
8361 if (expPdf && expPdf->canBeExtended() && !(coef &&
dynamic_cast<RooAddPdf *
>(expPdf))) {
8362 fExpPdf.setArg(*expPdf);
8363 }
else if (
auto _p =
dynamic_cast<RooAbsPdf *
>(&
f);
8367 fExpectedEventsMode = expEvMode;
8372 fFunc(
"func", this, other.fFunc),
8373 fCoef(
"coef", this, other.fCoef),
8374 fExpPdf(
"expPdf", this, other.fExpPdf),
8375 fExpectedEventsMode(other.fExpectedEventsMode)
8382 return fFunc->binBoundaries(obs, xlo, xhi);
8387 return (fExpectedEventsMode ? 1. : fFunc) *
8388 ((fExpPdf.absArg()) ?
static_cast<RooAbsPdf *
>(fExpPdf.absArg())->expectedEvents(_normSet) : 1.) *
8389 (fCoef.absArg() ? fCoef : 1.);
8400#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 28, 00)
8401 double oo = getPropagatedError(fr, nset_in);
8402 if (std::isnan(oo)) {
8407 getParameters(&nset_in, allParamsInAbsReal);
8410 for (
auto *rrvFitRes : static_range_cast<RooRealVar *>(fr.
floatParsFinal())) {
8412 auto rrvInAbsReal =
static_cast<RooRealVar const *
>(allParamsInAbsReal.
find(*rrvFitRes));
8416 if (rrvFitRes->namePtr() == namePtr())
8420 if (!rrvFitRes->hasError() ||
8421 rrvFitRes->getError() <= std::abs(rrvFitRes->getVal()) * std::numeric_limits<double>::epsilon())
8430 if (std::abs(rrvInAbsReal->getVal() - rrvFitRes->getVal()) > 0.01 * rrvFitRes->getError()) {
8431 std::stringstream errMsg;
8433 <<
"RooAbsReal::getPropagatedError(): the parameters of the RooAbsReal don't have"
8434 <<
" the same values as in the fit result! The logic of getPropagatedError is broken in this case.";
8436 throw std::runtime_error(errMsg.str());
8439 paramList.
add(*rrvInAbsReal);
8441 if (paramList.
empty())
8444 std::vector<double> plusVar;
8445 std::vector<double> minusVar;
8446 plusVar.reserve(paramList.
size());
8447 minusVar.reserve(paramList.
size());
8453 for (std::size_t ivar = 0; ivar < paramList.
size(); ivar++) {
8455 auto &rrv =
static_cast<RooRealVar &
>(paramList[ivar]);
8457 double cenVal = rrv.
getVal();
8458 double errVal = sqrt(V(ivar, ivar));
8470 rrv.setVal(cenVal + errVal);
8471 plusVar.push_back(getVal(nset_in));
8474 rrv.setVal(cenVal - errVal);
8475 minusVar.push_back(getVal(nset_in));
8476#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
8500 std::vector<double> errVec(paramList.
size());
8501 for (std::size_t i = 0; i < paramList.
size(); i++) {
8502 errVec[i] = std::sqrt(V(i, i));
8503 for (std::size_t j = i; j < paramList.
size(); j++) {
8504 C(i, j) = V(i, j) / std::sqrt(V(i, i) * V(j, j));
8511 for (
unsigned int j = 0; j < plusVar.size(); j++) {
8512 F[j] = (plusVar[j] - minusVar[j]) / 2;
8516 double sum = F * (C * F);
8525 for (
auto *frv : static_range_cast<RooRealVar *>(fr.
floatParsFinal())) {
8526 if (frv->getError() > 1
e-20) {
8527 fpf_stripped.
add(*frv);
8542 std::vector<int> fpf_idx;
8543 for (
Int_t i = 0; i < fpf.
size(); i++) {
8546 paramList.
add(*par);
8547 fpf_idx.push_back(i);
8551 std::vector<double> plusVar, minusVar;
8557 for (
Int_t ivar = 0; ivar < paramList.
size(); ivar++) {
8561 double cenVal = rrv.
getVal();
8562 double errVal = sqrt(V(ivar, ivar));
8565 ((
RooRealVar *)paramList.
at(ivar))->setVal(cenVal + errVal);
8568 plusVar.push_back(cloneFunc->
getVal(nset));
8571 ((
RooRealVar *)paramList.
at(ivar))->setVal(cenVal - errVal);
8574 minusVar.push_back(cloneFunc->
getVal(nset));
8582 std::vector<double> errVec(paramList.
size());
8583 for (
int i = 0; i < paramList.
size(); i++) {
8584 errVec[i] = sqrt(V(i, i));
8585 for (
int j = i; j < paramList.
size(); j++) {
8586 C(i, j) = V(i, j) / sqrt(V(i, i) * V(j, j));
8593 for (
unsigned int j = 0; j < plusVar.size(); j++) {
8594 F[j] = (plusVar[j] - minusVar[j]) / 2;
8598 double sum = F * (C * F);
8612 bool fExpectedEventsMode =
false;
8620 std::cout <<
"Got signal " << signum << std::endl;
8621 if (signum == SIGINT) {
8622 std::cout <<
"Keyboard interrupt while building histogram" << std::endl;
8632 auto _doSterilize = [](
RooAbsArg *obj) {
8635 for (
int i = 0; i < obj->numCaches(); i++) {
8641 p->setNormRange(
p->normRange());
8643#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
8648 p->setProxyNormSet(
nullptr);
8649 p->_lastNSet =
nullptr;
8652 obj->setValueDirty();
8654 if (
auto w = get<RooWorkspace>();
w) {
8656 for (
auto &
c :
w->components()) {
8675 nClients =
a->clients().size();
8676 for (
auto obj :
a->clients()) {
8678 if (
a->clients().size() != nClients) {
8683 }
while (
a->clients().size() != nClients);
8685 func(get<RooAbsArg>());
8690 bool errorsLo,
int nErrorToys)
const
8702 out.
fComp = std::shared_ptr<TH1>(
8703 BuildHistogram(
nullptr, !content, errors, -1, -1, fr, errorsHi, errorsLo, nErrorToys,
nullptr, !stack,
false));
8704 }
else if (
vars.size() == 1) {
8706 out.
fComp = std::shared_ptr<TH1>(
8707 BuildHistogram(
v, !content, errors, 1, 0, fr, errorsHi, errorsLo, nErrorToys,
nullptr, !stack,
true));
8709 throw std::runtime_error(
"multi-dim histo not yet supported");
8721 bool errorsHi,
bool errorsLo,
int nErrorToys,
TH1 *templateHist,
bool nostack,
8722 bool setInterp)
const
8724 auto rar = get<RooAbsReal>();
8736 if (binStart != -1 || binEnd != -1) {
8748 h =
new TH1D(rar->GetName(), rar->GetTitle(), 1, 0, 1);
8749 h->GetXaxis()->SetBinLabel(1, rar->GetName());
8750 h->GetXaxis()->SetTimeFormat(rar->GetName());
8755 bool setTitle =
false;
8760 h =
static_cast<TH1 *
>(templateHist->
Clone(rar->GetName()));
8769 h =
new TH1D(rar->GetName(), rar->GetTitle(), 1, 0, 1);
8772 h->GetXaxis()->SetBinLabel(1, rar->GetName());
8773 h->SetBinContent(1, rar->getVal());
8774 if (
x->getError()) {
8775 h->SetBinError(1,
x->getError());
8776 h->SetFillStyle(3005);
8777 h->SetFillColor(
h->GetLineColor());
8779 h->SetMaximum(
x->hasMax() ?
x->getMax()
8780 : (
h->GetBinContent(1) + std::max(std::abs(
h->GetBinContent(1) * 0.1), 50.)));
8781 h->SetMinimum(
x->hasMin() ?
x->getMin()
8782 : (
h->GetBinContent(1) - std::max(std::abs(
h->GetBinContent(1) * 0.1), 50.)));
8785 h->SetMarkerSize(0);
8786 h->SetMarkerStyle(0);
8791 TString binningName = (_ax && _ax->GetParent() ==
x) ? _ax->GetName() : rar->getStringAttribute(
"binning");
8792 if (binningName ==
"")
8793 binningName = rar->GetName();
8794 if (
x->hasBinning(binningName)) {
8795 if (
x->getBinning(binningName).isUniform()) {
8797 h =
new TH1D(rar->GetName(), rar->GetTitle(),
x->numBins(binningName) <= 0 ? 100 :
x->numBins(binningName),
8798 x->getMin(binningName),
x->getMax(binningName));
8801 h =
new TH1D(rar->GetName(), rar->GetTitle(),
x->numBins(binningName),
x->getBinning(binningName).array());
8803 h->GetXaxis()->SetTitle(
x->getBinning(binningName).GetTitle());
8805 }
else if (
auto _boundaries =
8806 _or_func( (std::list<double> *)(
nullptr),
8807 rar->binBoundaries(*
x, -std::numeric_limits<double>::infinity(),
8808 std::numeric_limits<double>::infinity()));
8810 std::vector<double> _bins;
8811 for (
auto &
b : *_boundaries) {
8812 if (_bins.empty() || std::abs(_bins.back() -
b) > 1
e-5 * _bins.back())
8816 h =
new TH1D(rar->GetName(), rar->GetTitle(), _bins.size() - 1, &_bins[0]);
8818 }
else if (!
x->hasMax() || !
x->hasMin()) {
8821 h =
new TH1D(rar->GetName(), rar->GetTitle(),
v->numBins(),
x->getVal() * 0.2,
x->getVal() * 5);
8824 h =
new TH1D(rar->GetName(), rar->GetTitle(),
v->numBins(),
x->getBinning().array());
8830 h =
new TH1D(rar->GetName(), rar->GetTitle(),
v->numBins(rar->GetName()), 0,
v->numBins(rar->GetName()));
8834 std::map<int, std::string> cats;
8835 for (
auto &
c : *cat) {
8836 cats[
c.second] =
c.first;
8838 for (
auto &[
_, label] : cats) {
8839 h->GetXaxis()->SetBinLabel(i++, label.c_str());
8844 if (
auto o =
dynamic_cast<TObject *
>(
v); o && !setTitle) {
8845 h->GetXaxis()->SetTitle(o->GetTitle());
8849 if (
h->GetXaxis()->IsAlphanumeric()) {
8858 if (
auto s =
styles(
nullptr,
false); s) {
8859 auto _style = s.get<
TStyle>();
8860 static_cast<TAttLine &
>(*h) = *_style;
8861 static_cast<TAttFill &
>(*h) = *_style;
8864 if (strlen(
h->GetXaxis()->GetTitle()) == 0)
8873 if (empty && !errors) {
8879 auto _coefs =
coefs();
8894 if (!
GETDMP(fr, _finalPars)) {
8907 for (
int i = 0; i < prevCov->
GetNcols(); i++) {
8908 for (
int j = 0; j < prevCov->
GetNrows(); j++) {
8909 cov(i, j) = (*prevCov)(i, j);
8915 if (!prevCov || i >= prevCov->
GetNcols()) {
8916 cov(i, i) = pow(
dynamic_cast<RooRealVar *
>(p2)->getError(), 2);
8920 int covQualBackup = fr->
covQual();
8931 int covQualBackup = fr->
covQual();
8939 bool hasErrors =
false;
8957 binEnd =
h->GetNbinsX();
8959 bool needBinWidth =
false;
8962 if (
x && (
p || _coefs.get() || rar->getAttribute(
"density"))) {
8964 needBinWidth =
true;
8968 spdf && spdf->
canBeExtended() && !spdf->getFloor() && !_coefs.get()) {
8980 for (
auto o : _obs) {
8985 rr->setStringAttribute(
"coordRange",
nullptr);
8993 rr->setStringAttribute(
"coordRange",
nullptr);
9003 bool hasRange =
false;
9004 for (
auto o : normSet) {
9006 rr && (rr->getStringAttribute(
"coordRange")) && strlen(rr->getStringAttribute(
"coordRange"))) {
9016 for (
auto pdf :
bins()) {
9019 std::unique_ptr<RooArgSet> projObs{pdf->get<
RooAbsPdf>()->getObservables(*_obs.get<
RooArgList>())};
9023 dynamic_cast<RooAbsPdf *
>(_pdf)->setNormRange(
"coordRange");
9025 newrar->addPdf(*_pdf, pdf->coords()[s->indexCat().GetName()]->get<
RooCategory>()->getLabel());
9029 rar =
p->createProjection(
9033 dynamic_cast<RooAbsPdf *
>(rar)->setNormRange(
"coordRange");
9037 p->setNormRange(
"coordRange");
9042 rar = std::unique_ptr<RooAbsReal>{rar->createIntegral(
9048 std::unique_ptr<RooAbsReal>{rar->createIntegral(*_obs.get<
RooArgList>() )}
9054 bool scaleExpected = (
p &&
p->canBeExtended() && !_coefs.get());
9060 if (!nostack &&
p &&
p->canBeExtended() && _coefs.get()) {
9066 std::unique_ptr<RooArgSet> snap(normSet.
snapshot());
9068 std::vector<double> lapTimes;
9069 bool warned =
false;
9070 if (binStart == -1 && binEnd == -1) {
9075 std::unique_ptr<RooAbsCollection> errorParsSnap;
9085 TString clNameNoNamespace = rar->ClassName();
9086 clNameNoNamespace = clNameNoNamespace(clNameNoNamespace.
Last(
':') + 1, clNameNoNamespace.
Length());
9087 setInterp = (clNameNoNamespace.
Contains(
"Hist") || vvv->
isCategory() || rar->isBinnedDistribution(*vvv) ||
9088 h->GetNbinsX() == 1 || rar->getAttribute(
"BinnedLikelihood") ||
9090 std::unique_ptr<std::list<double>>(rar->binBoundaries(*
dynamic_cast<RooAbsRealLValue *
>(vvv),
9091 -std::numeric_limits<double>::infinity(),
9092 std::numeric_limits<double>::infinity()))))
9101 bool allHist =
true;
9103 TString _clName = s->get()->ClassName();
9104 _clName = _clName(_clName.
Last(
':') + 1, _clName.
Length());
9105 if (!(s->get() && _clName.
Contains(
"Hist"))) {
9123 auto l =
static_cast<TH1 *
>(
h->Clone(
"nominal"));
9126 h->GetListOfFunctions()->Add(
l, (setInterp) ?
"lsame" :
"histsame");
9127 h->SetOption(setInterp ?
"e3" :
"e2");
9130 h->SetMarkerSize(0);
9131 h->SetFillStyle(3005);
9132 h->SetFillColor(
h->GetLineColor());
9135 if (nErrorToys > 0) {
9144 errorPars->
add(*par);
9147 errorParsSnap.reset(errorPars->
snapshot());
9148 auto l =
static_cast<TH1 *
>(
h->Clone(
"toys"));
9151 h->GetListOfFunctions()->Add(
9154 if (errorsLo || errorsHi)
9158 std::vector<int> errorBins;
9159 for (
int toy = 0; toy < (nErrorToys + 1); toy++) {
9175 if (_vv->getError() == 0)
9180 for (
int i = std::max(1, binStart); i <= std::min(
h->GetNbinsX(), binEnd); i++) {
9183 x->setVal(
h->GetBinCenter(i));
9185 cat->setLabel(
h->GetXaxis()->GetBinLabel(i));
9189 if (
x && !
x->inRange(
"coordRange"))
9193 if (!empty || toy > 0) {
9194 r = rar->getVal(
p ? &normSet :
nullptr);
9195#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
9200 if (
r && _coefs.get()) {
9204 r *=
h->GetBinWidth(i);
9206 if (scaleExpected) {
9209 r *= (
p->expectedEvents(normSet));
9212 h->SetBinContent(i,
r);
9218 errorBins.push_back(i);
9222 lapTimes.push_back(timeIt.
RealTime());
9223 double time_estimate =
9224 (lapTimes.size() > 1)
9225 ? (
h->GetNbinsX() * (std::accumulate(lapTimes.begin() + 1, lapTimes.end(), 0.) / (lapTimes.size() - 1)))
9227 if (!warned && (lapTimes.at(0) > 10 || (lapTimes.size() > 2 && time_estimate > 60.))) {
9229 t2.
Add(time_estimate);
9230 Warning(
"BuildHistogram",
"Building this histogram will take until %s", t2.
AsString());
9240 Warning(
"BuildHistogram",
"Skipping errors for remaining bins");
9251 if (errors && !errorBins.empty()) {
9255 std::unique_ptr<RooAbsReal> errFunc;
9259 std::make_unique<PdfWrapper>((oldrar) ? *rar : *
p, _coefs.get<
RooAbsReal>(), !
v, oldrar ?
p :
nullptr);
9263 errFunc = std::make_unique<RooProduct>(
9264 "errorEval",
"errorEval",
9267 const RooArgSet &errNormSet =
p ? normSet : emptyNormSet;
9269 auto setBin = [&](
int i) {
9271 x->setVal(
h->GetBinCenter(i));
9273 cat->setLabel(
h->GetXaxis()->GetBinLabel(i));
9279 bool doAsym = (errorsHi && errorsLo);
9283 *errFunc, *fr, errNormSet, &errorPars, doAsym ?
false : errorsHi, doAsym ? true : errorsLo, errorBins, setBin);
9284 std::vector<double> errHi;
9288#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
9291 p->_normSet =
nullptr;
9295 for (
size_t k = 0; k < errorBins.size(); k++) {
9296 int i = errorBins[k];
9297 double resLo = errLo[k];
9299 resLo *=
h->GetBinWidth(i);
9300 h->SetBinError(i, resLo);
9302 double resHi = errHi[k];
9304 resHi *=
h->GetBinWidth(i);
9307 h->SetBinContent(i,
h->GetBinContent(i) + (resHi - resLo) * 0.5);
9308 h->SetBinError(i, (resHi + resLo) * 0.5);
9321 *errorPars = *errorParsSnap;
9328 if (errorsLo && errorsHi) {
9329 auto nomHist =
static_cast<TH1 *
>(
h->FindObject(
"nominal"));
9332 for (
int i = 1; i <=
h->GetNbinsX(); i++) {
9333 std::vector<double> vals;
9334 vals.reserve(nErrorToys);
9335 for (
int j = 1; j < (nErrorToys + 1); j++) {
9339 double upVal, downVal;
9340 if (errorsLo || errorsHi) {
9341 std::sort(vals.begin(), vals.end());
9345 downVal = 2. *
h->GetBinContent(i) - upVal;
9347 upVal = 2. *
h->GetBinContent(i) - downVal;
9350 upVal =
h->GetBinContent(i) + err;
9351 downVal =
h->GetBinContent(i) - err;
9353 h->SetBinContent(i, (upVal + downVal) * 0.5);
9354 h->SetBinError(i, (upVal - downVal) * 0.5);
9370 treeRoot->treeNodeServerList(&evaluatedNodes);
9372 for (
RooAbsArg *node : evaluatedNodes) {
9373 node->setProxyNormSet(
nullptr);
9378 std::vector<RooAbsArg *> extra;
9381 for (
auto _pdf : s->servers()) {
9383 extra.push_back(_pdf);
9386 extra.push_back(rar);
9389 for (
auto a : extra)
9395 if (!
p && !rar->getAttribute(
"density") && !needBinWidth) {
9396 h->GetYaxis()->SetTitle(rar->getStringAttribute(
"units"));
9397 }
else if ((
p &&
p->canBeExtended()) || (!
p && needBinWidth)) {
9398 h->GetYaxis()->SetTitle(
"Events");
9400 h->GetYaxis()->SetTitle(
"Probability Mass");
9402 h->GetYaxis()->SetMaxDigits(3);
9411 auto hCopy =
static_cast<TH1 *
>(
h->Clone(
"copy"));
9415 hCopy->SetStats(
false);
9416 h->GetListOfFunctions()->Add(hCopy,
TString(
h->GetOption()) +
"same");
9417 h->GetListOfFunctions()->Add(hCopy,
"axissame");
9418 TString dOpt = (setInterp) ?
"LF2" :
"";
9424 rarNode =
find(
".pdf").get();
9431 std::map<std::string, int> colorByTitle;
9432 std::set<std::string> allTitles;
9433 bool titleMatchName =
true;
9434 std::map<std::string, TH1 *> histGroups;
9435 std::vector<TH1 *> hhs;
9436 std::set<std::pair<size_t, TH1 *>> ordered_hhs;
9437 std::set<TH1 *> histsWithBadTitles;
9443 if (!rarNode->components().empty()) {
9444 auto comps = rarNode->components()[0];
9445 for (
auto &
c : *comps) {
9446 if (
c->fFolder ==
"!.coeffs" ||
c->fFolder ==
"!.coeffpars")
9450 if (!cms_coefs.
empty()) {
9452 std::shared_ptr<TH1> prevHist(
static_cast<TH1 *
>(
h->Clone()));
9459 std::unique_ptr<RooAbsReal> forig(
9460 dynamic_cast<RooAbsReal *
>(rarNode->components()[0]->get()->
Clone(
"tmpCopy0")));
9461 for (
auto c : cms_coefs) {
9465 forig->redirectServers(
RooArgSet(zero),
false,
true);
9466 std::unique_ptr<RooAbsReal>
f(
dynamic_cast<RooAbsReal *
>(forig->Clone(
"tmpCopy")));
9470 auto hh =
xRooNode(*
f, *
this).BuildHistogram(
v);
9471 hh->SetName(
c->GetName());
9474 if (strlen(hh->GetTitle()) == 0) {
9475 hh->SetTitle(
c->GetName());
9479 hh->SetTitle(
TString(
TString(hh->GetTitle())(idx + 6, strlen(hh->GetTitle()))));
9481 histsWithBadTitles.insert(hh);
9482 }
else if (strcmp(hh->GetName(), hh->GetTitle()) == 0) {
9483 histsWithBadTitles.insert(hh);
9485 titleMatchName &= (
TString(
c->GetName()) == hh->GetTitle() ||
9487 std::shared_ptr<TH1> nextHist(
static_cast<TH1 *
>(hh->Clone()));
9488 hh->Add(prevHist.get(), -1.);
9491 hh->TH1::Reset(
"ICE");
9492 ordered_hhs.insert(std::pair(ordered_hhs.size(), hh));
9493 prevHist = nextHist;
9495 }
else if (get<RooSimultaneous>()) {
9499 for (
auto &chan :
bins()) {
9500 TString chanName(chan->GetName());
9501 chanName = chanName(chanName.
Index(
"=") + 1, chanName.
Length());
9502 auto samps = chan->mainChild();
9505 for (
auto &samp : samps.components()) {
9506 auto hh =
static_cast<TH1 *
>(
h->Clone(samp->GetName()));
9508 hh->SetTitle(samp->GetTitle());
9509 if (strlen(hh->GetTitle()) == 0) {
9510 hh->SetTitle(samp->GetName());
9511 histsWithBadTitles.insert(hh);
9512 }
else if (strcmp(hh->GetName(), hh->GetTitle()) == 0) {
9513 histsWithBadTitles.insert(hh);
9515 hh->SetTitle(
TString(hh->GetTitle())
9516 .ReplaceAll(
TString(chan->get()->GetName()) +
"_",
9518 titleMatchName &= (
TString(samp->GetName()) == hh->GetTitle() ||
9520 hh->SetBinContent(hh->GetXaxis()->FindFixBin(chanName), samp->GetContent());
9521 ordered_hhs.insert(std::pair(ordered_hhs.size(), hh));
9525 for (
auto &samp : rarNode->components()) {
9526 auto hh = samp->BuildHistogram(
9527 v, empty,
false , binStart, binEnd, _fr,
false,
false, 0,
h,
true,
9529 hh->SetName(samp->GetName());
9535 : ordered_hhs.size(),
9537 if (strlen(hh->GetTitle()) == 0) {
9538 hh->SetTitle(samp->GetName());
9539 histsWithBadTitles.insert(hh);
9540 }
else if (strcmp(hh->GetName(), hh->GetTitle()) == 0) {
9541 histsWithBadTitles.insert(hh);
9543 titleMatchName &= (
TString(samp->GetName()) == hh->GetTitle() ||
9549 for (
auto &[
_, hh] : ordered_hhs) {
9554 for (
auto &hh : hhs) {
9555 allTitles.insert(hh->GetTitle());
9560 size_t e = std::min(allTitles.begin()->size(), allTitles.rbegin()->size());
9562 bool goodPrefix =
false;
9563 std::string commonSuffix;
9564 if (titleMatchName && hhs.size() > 1) {
9565 while (ii <
e - 1 && allTitles.begin()->at(ii) == allTitles.rbegin()->at(ii)) {
9567 if (allTitles.begin()->at(ii) ==
'_' || allTitles.begin()->at(ii) ==
' ')
9573 while (!stop && commonSuffix.size() <
size_t(
e - 1)) {
9574 commonSuffix = allTitles.begin()->substr(allTitles.begin()->length() - commonSuffix.length() - 1);
9575 for (
auto &
tt : allTitles) {
9577 commonSuffix = commonSuffix.substr(1);
9583 if (commonSuffix.find(
'_') == std::string::npos) {
9586 commonSuffix = commonSuffix.substr(commonSuffix.find(
'_'));
9595 std::map<std::string, std::string> reducedTitles;
9596 while (reducedTitles.size() != allTitles.size()) {
9598 std::map<std::string, int> titlesMap;
9599 for (
auto &s : allTitles) {
9600 if (reducedTitles.count(s))
9602 titlesMap[s.substr(0, jj)]++;
9604 for (
auto &s : allTitles) {
9605 if (titlesMap[s.substr(0, jj)] == 1 && (jj >= s.length() || s.at(jj) ==
' ' || s.at(jj) ==
'_')) {
9606 reducedTitles[s] = s.substr(0, jj);
9612 for (
auto ritr = hhs.rbegin(); ritr != hhs.rend(); ++ritr) {
9613 if (!histsWithBadTitles.count((*ritr))) {
9616 auto _title = (hhs.size() > 5) ? reducedTitles[(*ritr)->GetTitle()] : (*ritr)->GetTitle();
9617 _title = _title.substr(ii < _title.size() ? ii : 0);
9618 if (!commonSuffix.empty() &&
TString(_title).
EndsWith(commonSuffix.c_str()))
9619 _title = _title.substr(0, _title.length() - commonSuffix.length());
9620 (*ritr)->SetTitle(_title.c_str());
9624 for (
auto &hh : hhs) {
9626 if (histGroups.find(hh->GetTitle()) == histGroups.end()) {
9627 histGroups[hh->GetTitle()] = hh;
9630 histGroups[hh->GetTitle()]->Add(hh);
9635 auto hhMin = (hh->GetMinimum() == 0) ? hh->GetMinimum(1
e-9) : hh->GetMinimum();
9636 if (!stack->
GetHists() &&
h->GetMinimum() > hhMin) {
9638 if (hhMin >= 0 && newMin < 0)
9639 newMin = hhMin * 0.99;
9653 stack->
Add(hh, thisOpt);
9656 h->GetListOfFunctions()->AddFirst(stack,
"noclear same");
9668 for (
auto ho : *ll) {
9669 TH1 *hh =
dynamic_cast<TH1 *
>(ho);
9672 bool createdStyle = (
xRooNode(*hh, *
this).styles(
nullptr,
false).get<
TStyle>() ==
nullptr);
9686 for (
auto ho2 : *ll) {
9687 TH1 *hh2 =
dynamic_cast<TH1 *
>(ho2);
9690 auto _styleNode =
xRooNode(*hh2, *
this).styles(hh2,
false);
9691 auto _style = _styleNode.get<
TStyle>();
9700 auto _styleNode =
xRooNode(*hh, *
this).styles(hh);
9701 if (
auto _style = _styleNode.get<
TStyle>()) {
9702 *
dynamic_cast<TAttLine *
>(hh) = *_style;
9703 *
dynamic_cast<TAttFill *
>(hh) = *_style;
9723 push_back(std::make_shared<xRooNode>(
data));
9731 return std::numeric_limits<double>::quiet_NaN();
9732 return node->GetBinContent(bin);
9738 if (binStart != binEnd || !
fParent) {
9743 std::vector<double> out;
9744 if (get<RooAbsData>()) {
9752 if (binStart == binEnd && binStart == -1) {
9755 for (
int i = 0; i <
g->GetN(); i++)
9756 integral +=
g->GetPointY(i);
9757 out.push_back(integral);
9761 for (
int i = binStart - 1; i <
g->GetN() && (binEnd == 0 || i < binEnd); i++) {
9762 out.push_back(
g->GetPointY(i));
9768 bool doIntegral =
false;
9769 if (binStart == binEnd && binStart == -1) {
9779 binEnd =
h->GetNbinsX();
9783 for (
int i = 1; i <=
h->GetNbinsX(); i++) {
9784 tot +=
h->GetBinContent(i);
9788 for (
int i = binStart; i <= binEnd; i++) {
9789 out.push_back(
h->GetBinContent(i));
9798 if (
auto a = get<RooAbsArg>();
a) {
9800 for (
auto &
l :
a->servers()) {
9820 if (
auto o =
get(); o) {
9829#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
9833 for (
int i = 0; i <
p->fCGnx; i++) {
9834 for (
int j = 0; j <
p->fCGny; j++) {
9835 p->fCollideGrid[i + j *
p->fCGnx] =
true;
9838 p->FillCollideGrid(o);
9842 Int_t nxmax =
p->fCGnx - iw - 1 -
p->fCGnx *
p->GetRightMargin();
9843 Int_t nymax =
p->fCGny - ih - 1 -
p->fCGny *
p->GetTopMargin();
9845 for (
Int_t j = nymax; j >= 0; j--) {
9846 for (
Int_t i = nxmax; i >= 0; i--) {
9847 if (
p->Collide(i, j, iw, ih)) {
9858 return p->PlaceBox(o,
w,
h, xl, yb,
"trw");
9866 gPad->PaintModified();
9872 auto l =
new TPaveText(
gPad->GetLeftMargin() + 0.02, 1. -
gPad->GetTopMargin() - 0.08, 0.6,
9873 1. -
gPad->GetTopMargin() - 0.08);
9874 l->SetBorderSize(0);
9875 if (
l->GetTextSize() == 0)
9883 l->ConvertNDCtoPad();
9889 if (
auto p =
dynamic_cast<TLegend *
>(
gPad->GetPrimitive(
"legend"));
p) {
9892 double w =
p->GetX2NDC() -
p->GetX1NDC();
9893 double h =
p->GetY2NDC() -
p->GetY1NDC();
9895 gPad->PaintModified();
9899 x = std::max(
x, (
gPad->GetLeftMargin() + 0.02));
9900 y = std::max(
y, (
gPad->GetBottomMargin() + 0.02));
9901 x = std::min(
x, (1. -
gPad->GetRightMargin() - 0.02) -
w);
9902 y = std::min(
y, (1. -
gPad->GetTopMargin() - 0.02) -
h);
9903 h = std::min(
h, (1. -
gPad->GetTopMargin() - 0.02) -
y);
9904 w = std::min(
w, (1. -
gPad->GetRightMargin() - 0.02) -
x);
9916 while ((
p !=
p->GetMother()) && (
p =
p->GetMother())) {
9917 if (
auto q =
dynamic_cast<TVirtualPad *
>(
p->GetPrimitive(
"legend"));
q) {
9925 if (
p && strcmp(
p->
GetName(),
"legend") == 0) {
9926 if (
l =
dynamic_cast<TLegend *
>(
p->GetPrimitive(
"legend"));
l || !create)
9930 gPad->GetBottomMargin());
9931 l->SetBorderSize(1);
9935 l =
new TLegend(0.6, 1. -
gPad->GetTopMargin() - 0.08, 0.75, 1. -
gPad->GetTopMargin() - 0.08);
9936 l->SetBorderSize(0);
9938 if (
l->GetTextSize() == 0) {
9946 l->SetName(
"legend");
9948 l->ConvertNDCtoPad();
9955 auto i = s.find(
"\n");
9956 if (i == std::string::npos) {
9959 return std::string(
"#splitline{") + s.substr(0, i) +
"}{" +
formatLegendString(s.substr(i + 1)) +
"}";
9968 for (
auto a : *
l->GetListOfPrimitives()) {
9972 if (
l->GetListOfPrimitives()->GetEntries() > 20)
9977 l->GetListOfPrimitives()->RemoveLast();
9978 l->GetListOfPrimitives()->AddFirst(
e);
9979 if (
auto nObj =
l->GetListOfPrimitives()->GetEntries(); nObj > 0) {
9981 int nn =
l->GetNColumns();
9983 if (nObj > 1 && (nObj % nn) == 1) {
9984 l->SetNColumns(
l->GetNColumns() + 1);
9985 if (
l->GetBorderSize() == 0) {
9986 l->SetX1NDC(
l->GetX2NDC() - 0.15 *
l->GetNColumns());
9989 if (
l->GetBorderSize() == 0) {
9990 l->SetY1NDC(
l->GetY2NDC() - 0.05 *
gPad->GetHNDC() * std::ceil((
double(nObj) /
l->GetNColumns())));
10006 fPad->GetCanvas()->Paint();
10007 fPad->GetCanvas()->Update();
10008#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 30, 00)
10009 fPad->GetCanvas()->ResetUpdated();
10024 if (
gROOT->FromPopUp()) {
10025 gROOT->SetFromPopUp(
false);
10028 }
catch (
const std::exception &
e) {
10031 (
gROOT->GetListOfBrowsers()->At(0))
10034 "Exception",
e.what(),
10037 gROOT->SetFromPopUp(
true);
10046 if (
auto mc = get<RooStats::ModelConfig>()) {
10048 }
else if (
auto ir = get<RooStats::HypoTestInverterResult>()) {
10052 }
else if (get<RooStats::HypoTestResult>()) {
10065 auto _dsets =
fParent->datasets();
10068 for (
auto &
d : _dsets) {
10069 if (
d->get()->TestBit(1 << 20)) {
10070 dsetName =
d->get()->GetName();
10074 auto hs =
fParent->nll(dsetName.
Data()).hypoSpace(get<RooRealVar>()->GetName());
10075 hs.limits(
"cls visualize");
10087 [](
double a,
double b,
double) {
10090 if (
b == 0 &&
a == 0)
10097 [](
double n,
double b,
double sigma) {
10101 t0 = 2. * (((
n == 0) ? 0 :
n * log(
n /
b)) - (
n -
b));
10104 double b_hathat = 0.5 * (
b - sigma2 + sqrt(pow(
b - sigma2, 2) + 4 *
n * sigma2));
10107 t0 = 2. * (((
n == 0) ? 0 :
n * log(
n / b_hathat)) + b_hathat -
n + pow(
b - b_hathat, 2) / (2. * sigma2));
10111 return (
n >=
b) ? sqrt(t0) : -sqrt(t0);
10119 std::vector<double> xPoints;
10122 int _idx = sOpt2.
Index(
"x=");
10123 int _eidx = sOpt2.
Index(
';', _idx);
10124 TString varPart = sOpt(_idx + 2, (_eidx < 0 ? sOpt2.
Length() : _eidx) - (_idx + 2));
10127 if (
auto _idx2 = varPart.
Index(
"("); _idx2 > 0) {
10128 varName = varPart(0, _idx2);
10138 }
else if (ii == 1) {
10140 }
else if (ii == 2) {
10148 for (
double x = min;
x <= max;
x += (max - min) / (nBins - 1)) {
10149 xPoints.push_back(
x);
10151 }
else if (nBins == 1)
10152 xPoints.push_back((min + max) / 2.);
10154 v = getObject<RooAbsLValue>(varName.Data()).get();
10156 throw std::runtime_error(
TString::Format(
"Could not find variable %s", varName.Data()));
10158 if (xPoints.empty() && !
obs().
find(varName.Data()) &&
10161 for (
int i = 0; i <
v->numBins(
GetName()); i++) {
10167 sOpt2 =
TString(sOpt2(0, _idx)) + sOpt2(_idx + 2 + varPart.
Length() + 1, sOpt2.
Length());
10179 }
else if (get<RooAbsPdf>()) {
10181 forceNames = sOpt(sOpt2.
Index(
"force") + 5, sOpt2.
Length());
10182 sOpt = sOpt(0, sOpt2.
Index(
"force"));
10183 sOpt2 = sOpt2(0, sOpt2.
Index(
"force"));
10185 Error(
"Draw",
"Can only compute forces with PDFs");
10189 bool hasOverlay = sOpt2.
Contains(
"overlay");
10193 overlayName = sOpt(sOpt2.
Index(
"overlay") + 7, sOpt2.
Length());
10194 sOpt = sOpt(0, sOpt2.
Index(
"overlay"));
10195 sOpt2 = sOpt2(0, sOpt2.
Index(
"overlay"));
10198 sOpt +=
"auxRatio";
10200 sOpt +=
"auxSignif";
10202 std::string auxPlotTitle;
10213 bool nostack = sOpt.
Contains(
"nostack");
10215 bool hasSame = sOpt.
Contains(
"same");
10217 bool hasGoff = sOpt.
Contains(
"goff");
10219 bool hasFR = sOpt.
Contains(
"pull") && !get<RooFitResult>();
10221 bool hasText = sOpt.
Contains(
"text");
10222 bool hasTexte = sOpt.
Contains(
"texte");
10223 bool hasErrorOpt = sOpt.
Contains(
"e");
10227 }
else if (hasText) {
10230 if (auxPlotTitle ==
"Signif")
10231 hasErrorOpt =
true;
10237 TH1 *hAxis =
nullptr;
10239 auto clearPad = []() {
10241 if (
gPad->GetNumber() == 0) {
10253 if (!hasSame || !pad) {
10264 if (hAxis =
dynamic_cast<TH1 *
>(o); hAxis)
10284 auto adjustYRange = [&](
double min,
double max,
TH1 *hh =
nullptr,
bool symmetrize =
false) {
10292 double ymin = hh->GetMinimum();
10293 double ymax = hh->GetMaximum();
10294 if (hh->GetMaximumStored() == -1111)
10296 if (hh->GetMinimumStored() == -1111) {
10299 }
else if (
ymin < 0) {
10307 if (hh->GetSumw2()) {
10308 double smallestErrDown3 = -std::numeric_limits<double>::infinity();
10309 double smallestErrUp3 = std::numeric_limits<double>::infinity();
10310 for (
int i = 1; i <= hh->GetNbinsX(); i++) {
10311 smallestErrDown3 = std::max(smallestErrDown3, hh->GetBinContent(i) - 3 * hh->GetBinError(i));
10312 smallestErrUp3 = std::min(smallestErrUp3, hh->GetBinContent(i) + 3 * hh->GetBinError(i));
10314 max = std::max(max, smallestErrUp3);
10315 min = std::min(min, smallestErrDown3);
10317 bool change =
false;
10329 double down = hh->GetBinContent(1) -
ymin;
10330 double up =
ymax - hh->GetBinContent(1);
10332 ymax = hh->GetBinContent(1) + down;
10334 ymin = hh->GetBinContent(1) - up;
10337 if (hh == hAxis && pad && !pad->
GetLogy() &&
ymin > 0 && (log10(
ymax) - log10(max)) >= 3) {
10341 if (hh == hAxis && pad &&
ymin == 0 && pad->
GetLogy()) {
10346 hh->SetMinimum(
ymin);
10347 hh->SetMaximum(
ymax);
10348 hh->GetYaxis()->Set(1,
ymin,
ymax);
10349 hh->SetAxisRange(
ymin,
ymax,
"Y");
10355 double ymax = -std::numeric_limits<double>::infinity();
10356 double ymin = std::numeric_limits<double>::infinity();
10357 for (
int i = 0; i <
gr->
GetN(); i++) {
10361 return std::make_pair(
ymin,
ymax);
10364 if (!xPoints.empty()) {
10373 for (
auto &
x : xPoints) {
10384 out->
Draw(
TString(hasSame ?
"L" :
"AL") + (hasErrorOpt ?
"3" :
""));
10405 gPad->GetFrame()->SetFillStyle(1001);
10406 gPad->SetTopMargin(0);
10407 gPad->SetBottomMargin(0);
10408 gPad->SetName(
"pull");
10412 Error(
"Draw",
"Couldn't find pull graph");
10415 pullGraph->SetName(
"nominal");
10419 auto scaleHist =
static_cast<TH1 *
>(pullGraph->FindObject(
"scales"));
10421 throw std::runtime_error(
"Could not find scales in fit result");
10423 for (
auto i = 0; i < pullGraph->GetN(); i++) {
10425 g->
SetName(scaleHist->GetXaxis()->GetBinLabel(i + 1));
10428 Warning(
"Draw",
"Found a non-var in the floatParsFinal list: %s - this shouldn't happen",
g->GetName());
10432 "%s=%g +/- %s [%g,%g]", strlen(_p->GetTitle()) ? _p->GetTitle() : _p->GetName(), _p->getVal(),
10433 _p->hasAsymError() ?
TString::Format(
"(%g,%g)", _p->getAsymErrorHi(), _p->getAsymErrorLo()).
Data()
10435 scaleHist->GetBinContent(i + 1), scaleHist->GetBinError(i + 1)));
10436 g->SetPoint(0, pullGraph->GetPointX(i), pullGraph->GetPointY(i));
10437 g->SetPointEYhigh(0, pullGraph->GetErrorYhigh(i));
10438 g->SetPointEYlow(0, pullGraph->GetErrorYlow(i));
10439 g->SetEditable(
true);
10440 g->SetHighlight(
true);
10441 g->SetMarkerStyle(20);
10442 g->SetMarkerSize(0.5);
10450 _thisClone->AppendPad();
10463 if (
auto _simPdf = get<RooSimultaneous>();
10464 _simPdf && !(
v && strcmp(_simPdf->indexCat().GetName(),
dynamic_cast<TObject *
>(
v)->
GetName()) == 0)) {
10465 auto _channels =
bins();
10467 for (
auto &_v : _channels) {
10468 if (!_v->IsHidden())
10499 int ncols = _simPdf->getStringAttribute(
"ncols") ?
TString(_simPdf->getStringAttribute(
"ncols")).
Atoi() : 0;
10501 dynamic_cast<TPad *
>(pad)->Divide(ncols, std::ceil(
double(_size) / ncols), 1
e-9, 1
e-9);
10503 dynamic_cast<TPad *
>(pad)->DivideSquare(_size, 1
e-9, 1
e-9);
10506 auto _pad = pad->
GetPad(_size);
10509 _pad->SetPad(_pad->GetXlowNDC(), _pad->GetYlowNDC(), 1.0, _pad->GetYlowNDC() + _pad->GetHNDC());
10522 std::vector<TString> chanPatterns;
10523 if (_range && strlen(_range)) {
10526 chanPatterns.emplace_back(pattern);
10529 for (
auto &_v : _channels) {
10530 if (_v->IsHidden())
10536 chanVar.setLabel(cName);
10537 bool inRange = chanPatterns.empty();
10538 for (
auto &
p : chanPatterns) {
10539 if (chanVar.inRange(
p)) {
10547 gPad->SetLeftMargin(std::min(
gPad->GetLeftMargin() * (1. /
gPad->GetWNDC()), 0.3));
10557 if (!
get() || get<RooArgList>()) {
10562 for (
auto &_v : *
this) {
10563 if (_v->IsHidden())
10565 if (strcmp(
GetName(),
".vars") == 0) {
10569 if (strcmp(_v->get()->GetName(),
"1") == 0 || strcmp(_v->get()->GetName(),
"ONE") == 0 ||
10572 if (_v->get()->InheritsFrom(
"RooConstVar"))
10583 dynamic_cast<TPad *
>(pad)->DivideSquare(_size, 1
e-9, 1
e-9);
10586 for (
auto &_v : *
this) {
10587 if (_v->IsHidden())
10589 if (strcmp(
GetName(),
".vars") == 0) {
10593 if (strcmp(_v->get()->GetName(),
"1") == 0 || strcmp(_v->get()->GetName(),
"ONE") == 0 ||
10596 if (_v->get()->InheritsFrom(
"RooConstVar"))
10605 gPad->SetLeftMargin(std::min(
gPad->GetLeftMargin() * (1. /
gPad->GetWNDC()), 0.3));
10620 _mainChild.Draw(opt);
10626 if (
auto fr = get<RooFitResult>(); fr) {
10634 TH2 *hist =
nullptr;
10635 if (numCorrs < fr->correlationMatrix().GetNcols()) {
10637 std::set<std::pair<double, size_t>> maxCorrs;
10639 double maxCorr = 0;
10645 maxCorrs.insert({maxCorr, i});
10647 std::vector<size_t> topN;
10649 for (
auto itr = maxCorrs.rbegin(); itr != maxCorrs.rend(); ++itr) {
10650 topN.push_back(itr->second);
10656 numCorrs, 0, numCorrs, numCorrs, 0, numCorrs);
10657 for (
size_t i = 0; i < topN.size(); i++) {
10660 for (
size_t j = 0; j < topN.size(); j++) {
10683 gPad->SetGrid(1, 1);
10694 std::string poiName;
10697 poiName = sOpt3(sOpt3.
Index(
"breakdown:") + 10, sOpt3.
Length());
10700 if (_poi->empty()) {
10701 throw std::runtime_error(
"No floating poi in the fit");
10702 }
else if (_poi->size() != 1) {
10703 throw std::runtime_error(
"Multiple poi in the fit");
10705 poiName = _poi->first()->GetName();
10709 throw std::runtime_error(
TString::Format(
"Cannot find parameter %s", poiName.c_str()));
10711 std::set<std::string> groups;
10715 }
else if (
p->getStringAttribute(
"group")) {
10716 groups.insert(
p->getStringAttribute(
"group"));
10726 groups.size() + 1);
10729 roundedVal.second *= .1;
10737 for (
auto group : groups) {
10739 double variance = pow(
dynamic_cast<RooRealVar *
>(
poi)->getError(), 2);
10743 }
else if ((
p->getStringAttribute(
"group") &&
group ==
p->getStringAttribute(
"group")) ||
10749 int idx =
pars.index(poiName.c_str());
10751 if (reducedVar > variance) {
10752 Warning(
"Draw",
"breakdown group %s variance bigger than preceding?",
group.c_str());
10758 std::pair(sqrt(variance - reducedVar), roundedVal.second));
10786 out->
SetTitle(
"Fit Result Pulls");
10787 std::vector<TString> graphLabels;
10790 ugraph->
SetTitle(
"Fit Result Pulls");
10791 std::vector<TString> ugraphLabels;
10792 std::map<std::string, double> scale;
10793 std::map<std::string, double>
offset;
10799 if (std::isnan(_v->getErrorHi()) || std::isnan(_v->getErrorLo())) {
10800 Warning(
"Draw",
"%s error is invalid", _v->GetName());
10805 double prefitError = 0;
10806 double prefitVal = 0;
10807 double customScale = 0;
10810 prefitError = ip->getError();
10811 prefitVal = ip->getVal();
10814 std::shared_ptr<xRooNode> pConstr;
10817 if (_vv->hasRange(
"pullScale")) {
10818 customScale = (_vv->getMax(
"pullScale") - _vv->getMin(
"pullScale")) / 2.;
10820 auto _constr =
xRooNode(_vv, *
this).constraints();
10821 for (
auto &
c : _constr) {
10824 bool isServer =
true;
10827 for (
auto s :
c->get<
RooAbsArg>()->servers()) {
10828 if (strcmp(s->GetName(),
p->
GetName()) == 0) {
10849 if (pConstr->get<
RooPoisson>() && pConstr->find(
".x")) {
10850 std::string xName = pConstr->find(
".x")->get()->GetName();
10851 prefitVal = pConstr->find(
".x")->get<
RooAbsReal>()->getVal();
10852 for (
auto &_d : pConstr->vars()) {
10853 if (strcmp(
p->
GetName(), _d->get()->GetName()) == 0)
10855 if (xName == _d->get()->GetName())
10860 if (fr->
constPars().
find(pConstr->find(
".x")->get()->GetName())) {
10865 prefitVal /= prefitError;
10867 prefitError = 1. / sqrt(prefitError);
10868 }
else if (
auto _g = pConstr->get<
RooGaussian>(); _g) {
10870 (pConstr->find(
".sigma")) ? pConstr->find(
".sigma")->get<
RooAbsReal>()->getVal() : prefitError;
10872 (pConstr->find(
".x")) ? pConstr->find(
".x")->get<
RooAbsReal>()->getVal() : 0;
10873 if (pConstr->find(
".x") && fr->
constPars().
find(pConstr->find(
".x")->get()->GetName())) {
10877 if (pConstr->find(
".x") &&
10880 prefitVal = pConstr->find(
".mean")->get<
RooAbsReal>()->getVal();
10881 if (fr->
constPars().
find(pConstr->find(
".mean")->get()->GetName())) {
10889 prefitError = customScale;
10890 if (prefitError == 0) {
10891 Warning(
"Draw",
"failed to determine prefit error of %s, using post-fit error",
p->
GetName());
10892 prefitError = _v->getError();
10894 out->
SetPoint(out->
GetN(), out->
GetN(), (_v->getVal() - prefitVal) / prefitError);
10896 (_v->getErrorHi()) / prefitError);
10897 graphLabels.push_back(
p->
GetName());
10898 scale[
p->
GetName()] = prefitError;
10903 prefitError = customScale;
10904 if (prefitError == 0) {
10906 prefitError = (std::max({_v->getMax() - _v->getVal(), _v->getVal() - _v->getMin(), 4.}) / 4);
10907 ugraph->
SetPoint(ugraph->
GetN(), ugraph->
GetN(), (_v->getVal() - prefitVal) / prefitError);
10908 ugraph->
SetPointError(ugraph->
GetN() - 1, 0, 0, (-_v->getErrorLo()) / prefitError,
10909 (_v->getErrorHi()) / prefitError);
10910 ugraphLabels.push_back(
p->
GetName());
10912 out->
SetPoint(out->
GetN(), out->
GetN(), (_v->getVal() - prefitVal) / prefitError);
10914 (_v->getErrorHi()) / prefitError);
10915 graphLabels.push_back(
p->
GetName());
10917 scale[
p->
GetName()] = prefitError;
10923 prefitError = customScale;
10924 if (prefitError == 0) {
10925 prefitError = (std::max({_v->getMax() - _v->getVal(), _v->getVal() - _v->getMin(), 4.}) / 4);
10927 ugraph->
SetPoint(ugraph->
GetN(), ugraph->
GetN(), (_v->getVal() - prefitVal) / prefitError);
10928 ugraph->
SetPointError(ugraph->
GetN() - 1, 0, 0, (-_v->getErrorLo()) / prefitError,
10929 (_v->getErrorHi()) / prefitError);
10930 ugraphLabels.push_back(
p->
GetName());
10931 scale[
p->
GetName()] = prefitError;
10938 for (
int i = 0; i < ugraph->
GetN(); i++)
10939 ugraph->
SetPointX(i, i + graph->GetN());
10940 int nUnconstrained = ugraph->
GetN();
10943 tmpList.
Add(ugraph);
10944 graph->Merge(&tmpList);
10947 for (
auto &
l : ugraphLabels) {
10948 graphLabels.push_back(
l);
10952 graph->SetMarkerStyle(20);
10953 graph->SetMarkerSize(0.5);
10955 graph->SetMaximum(4);
10956 graph->SetMinimum(-4);
10958 bool doHorizontal =
10961 std::vector<std::pair<double, std::string>>
covariances;
10962 std::string poiName;
10963 double maxImpact = 0;
10967 poiName = sOpt3(sOpt3.
Index(
"impact:") + 7, sOpt3.
Length());
10970 if (_poi->empty()) {
10971 throw std::runtime_error(
"No floating poi in the fit");
10972 }
else if (_poi->size() != 1) {
10973 throw std::runtime_error(
"Multiple poi in the fit");
10975 poiName = _poi->first()->GetName();
10979 throw std::runtime_error(
TString::Format(
"Cannot find parameter %s", poiName.c_str()));
10990 for (
auto &label : graphLabels) {
10996 [&](std::pair<double, std::string> i, std::pair<double, std::string> j) {
10997 return doHorizontal ? (std::abs(i.first) < std::abs(j.first))
10998 : (std::abs(i.first) > std::abs(j.first));
11002 std::vector<TString> sortedLabels;
11003 maxImpact = (doHorizontal) ?
covariances.back().first
11010 c.first *= 4. / (maxImpact * 1.2);
11011 sortedLabels.push_back(
c.second);
11013 for (; i < graphLabels.size(); i++) {
11014 if (graphLabels[i] ==
c.second) {
11018 sortedGraph.
AddPoint(sortedGraph.
GetN(), graph->GetPointY(i));
11019 sortedGraph.
SetPointError(sortedGraph.
GetN() - 1, 0, 0, graph->GetErrorYlow(i), graph->GetErrorYhigh(i));
11024 tmpList2.
Add(&sortedGraph);
11025 graph->Merge(&tmpList2);
11027 graphLabels = sortedLabels;
11028 graph->SetTitle(
"Fit Result Impact");
11033 if (doHorizontal) {
11035 std::max(graph->GetN(), 1) - 0.5);
11037 for (
auto &
l : graphLabels) {
11040 if (!graphLabels.empty())
11044 hist =
new TH2D(
GetName(), fr->
GetTitle(), std::max(graph->GetN(), 1), -0.5, std::max(graph->GetN(), 1) - 0.5,
11047 for (
auto &
l : graphLabels) {
11050 if (!graphLabels.empty())
11058 auto histCopy =
dynamic_cast<TH1 *
>(hist->
Clone(
".axis"));
11061 auto _axis = (doHorizontal ? histCopy->GetYaxis() : histCopy->GetXaxis());
11063 graph->GetHistogram()->GetXaxis()->Set(std::max(graph->GetN(), 1), -0.5, std::max(graph->GetN(), 1) - 0.5);
11064 for (
int ii = 1; ii <= _axis->GetNbins(); ii++) {
11065 graph->GetHistogram()->GetXaxis()->SetBinLabel(ii, _axis->GetBinLabel(ii));
11079 auto oldPad =
gPad;
11080 gPad->Divide(1, 1, 1
e-9, 1
e-9);
11083 if (doHorizontal) {
11084 gPad->SetLeftMargin(0.4);
11086 gPad->SetBottomMargin(0.4);
11089 auto pNamesHist =
dynamic_cast<TH1F *
>(graph->GetHistogram()->Clone(
"scales"));
11090 pNamesHist->
Sumw2();
11091 pNamesHist->SetDirectory(
nullptr);
11093 for (
int ii = 1; ii <= graph->GetN(); ii++) {
11095 pNamesHist->SetBinContent(ii,
offset[_p->GetName()]);
11096 pNamesHist->SetBinError(ii, scale[_p->GetName()]);
11097 _axis->SetBinLabel(ii, strlen(_p->GetTitle()) ? _p->GetTitle() : _p->GetName());
11103 for (
int ii = 2; ii >= 1; ii--) {
11107 pullBox->SetPoint(0, (doHorizontal) ? -ii : -0.5, (doHorizontal) ? -0.5 : 0);
11108 pullBox->SetPoint(1, (doHorizontal) ? ii : (_axis->GetNbins() - 0.5 - nUnconstrained),
11109 (doHorizontal) ? -0.5 : 0);
11110 pullBox->SetPointError(0, 0, (doHorizontal) ? (_axis->GetNbins() - nUnconstrained) : ii);
11111 pullBox->SetPointError(1, 0, (doHorizontal) ? (_axis->GetNbins() - nUnconstrained) : ii);
11115 auto pullLine =
new TGraph;
11116 pullLine->
SetName(
"0sigmaLine");
11118 pullLine->SetPoint(0, -0.5, 0);
11119 pullLine->SetPoint(1, _axis->GetNbins() - 0.5, 0);
11120 pullLine->SetLineStyle(2);
11121 pullLine->SetEditable(
false);
11125 if (nUnconstrained > 0) {
11127 pullLine->
SetName(
"dividerLine");
11129 pullLine->SetPoint(0, graph->GetN() - 0.5 - nUnconstrained, -100);
11130 pullLine->SetPoint(1, graph->GetN() - 0.5 - nUnconstrained, 100);
11131 pullLine->SetLineStyle(2);
11132 pullLine->SetEditable(
false);
11138 new TPaveText(
gPad->GetLeftMargin(), 1. -
gPad->GetTopMargin(), 1. -
gPad->GetRightMargin(), 0.98,
"NDCNB");
11146 std::string covQualTxt;
11148 case -1: covQualTxt =
"Unknown";
break;
11149 case 0: covQualTxt =
"Not calculated";
break;
11150 case 1: covQualTxt =
"Approximate";
break;
11151 case 2: covQualTxt =
"Forced Positive-Definite";
break;
11152 case 3: covQualTxt =
"Accurate";
break;
11157 std::string statusCodes;
11166 gPad->SetTicks(0, 0);
11168 if (doHorizontal) {
11170 if (
int(
gPad->GetCanvas()->GetWh()) < pNamesHist->GetNbinsX() * 15) {
11171 gPad->GetCanvas()->SetCanvasSize(
gPad->GetCanvas()->GetWw(), pNamesHist->GetNbinsX() * 15);
11175 double factor = 475. /
gPad->GetCanvas()->GetWh();
11180 new TGaxis(_axis->GetXmin(), -4, _axis->GetXmin(), 4, -1.2 * maxImpact, 1.2 * maxImpact, 510,
"-S");
11182 if (doHorizontal) {
11204 for (
int tt = 0;
tt < 2;
tt++) {
11205 auto impact =
static_cast<TH1 *
>(
11206 graph->GetHistogram()->Clone(
TString::Format(
"%s_impact+",
tt == 0 ?
"prefit" :
"postfit")));
11208 impact->GetYaxis()->SetTitle(
TString::Format(
"#Delta%s/#sigma", poiName.c_str()));
11209 impact->SetBarWidth(0.9);
11210 impact->SetBarOffset(0.05);
11211 impact->SetLineColor(
kBlack);
11212 impact->SetFillColor(
kAzure - 4);
11213 impact->SetFillStyle(
tt == 0 ? 3013 : 1001);
11215 static_cast<TH1 *
>(impact->Clone(
TString::Format(
"%s_impact-",
tt == 0 ?
"prefit" :
"postfit")));
11217 impact2->SetFillColor(
kCyan);
11218 for (
int ii = 1; ii <= pNamesHist->GetNbinsX(); ii++) {
11220 if (
c.second != pNamesHist->GetXaxis()->GetBinLabel(ii))
11224 impact->SetBinContent(ii, ((
tt == 0 && !vv_init->hasError()) || !
vv->hasError())
11226 :
c.first *
vv->getError() /
vv->getErrorHi() *
11227 (
tt == 0 ? (vv_init->getErrorHi() /
vv->getErrorHi()) : 1.));
11228 impact2->SetBinContent(ii, ((
tt == 0 && !vv_init->hasError()) || !
vv->hasError())
11230 :
c.first *
vv->getError() /
vv->getErrorLo() *
11231 (
tt == 0 ? (vv_init->getErrorLo() /
vv->getErrorLo()) : 1.));
11238 for (
int ii = -1; ii <= 1; ii++) {
11239 auto pullLine =
new TGraph;
11242 pullLine->SetPoint(0, -0.5, ii);
11243 pullLine->SetPoint(1, hist->
GetNbinsY() - 0.5, ii);
11244 pullLine->SetLineStyle(2);
11245 pullLine->SetEditable(
false);
11250 new TLegend(0.02, doHorizontal ? (1. - 0.22 * factor) : 0.02, 0.27, (doHorizontal ? 1. : 0.24));
11260 leg1->
AddEntry(hist->
FindObject(
"prefit_impact+"),
"#theta = #hat{#theta}+#Delta#theta",
"f");
11261 leg1->
AddEntry(hist->
FindObject(
"prefit_impact-"),
"#theta = #hat{#theta}-#Delta#theta",
"f");
11264 leg1->
AddEntry(hist->
FindObject(
"postfit_impact+"),
"#theta = #hat{#theta}+#Delta#theta",
"f");
11265 leg1->
AddEntry(hist->
FindObject(
"postfit_impact-"),
"#theta = #hat{#theta}-#Delta#theta",
"f");
11271 new TPaveText(
gPad->GetLeftMargin(), 1. -
gPad->AbsPixeltoY(14), 1. -
gPad->GetRightMargin(), 1.,
"NDC");
11278 : ((
gPad->AbsPixeltoY(0) -
gPad->AbsPixeltoY(10 / factor)) / (
gPad->GetY2() -
gPad->GetY1())));
11281 title->
AddText(histCopy->GetTitle());
11286 graph->SetEditable(
false);
11287 pNamesHist->SetLineWidth(0);
11288 pNamesHist->SetMarkerSize(0);
11289 pNamesHist->SetMarkerStyle(0);
11290 graph->GetListOfFunctions()->Add(pNamesHist,
"same");
11291 if (doHorizontal) {
11294 for (
int p = 0;
p < graph->GetN();
p++) {
11295 graph->SetPoint(
p, graph->GetPointY(
p), graph->GetPointX(
p));
11296 graph->SetPointError(
p, graph->GetErrorYlow(
p), graph->GetErrorYhigh(
p), graph->GetErrorXlow(
p),
11297 graph->GetErrorXhigh(
p));
11300 if (
f->InheritsFrom(
"TH1")) {
11309 else if (
auto g =
dynamic_cast<TGraph *
>(
f)) {
11310 for (
int p = 0;
p <
g->GetN();
p++) {
11311 g->SetPoint(
p,
g->GetPointY(
p),
g->GetPointX(
p));
11314 }
else if (
auto l =
dynamic_cast<TLine *
>(
f)) {
11317 l->
SetY1(_axis->GetXmax());
11318 l->
SetY2(_axis->GetXmax());
11326 for (
size_t i = 0; i < ugraphLabels.size(); i++) {
11327 int bin = pNamesHist->GetNbinsX() - ugraphLabels.size() + i + 1;
11331 auto x = graph->GetPointX(graph->GetN() - ugraphLabels.size() + i);
11332 auto y = graph->GetPointY(graph->GetN() - ugraphLabels.size() + i) +
11333 graph->GetErrorYhigh(graph->GetN() - ugraphLabels.size() + i);
11337 t->SetTextSize(0.025);
11338 t->SetTextAngle(90);
11339 graph->GetListOfFunctions()->Add(t);
11343 graph->SetName(
"pulls");
11348 histCopy->Draw((sOpt.
Contains(
"impact") && !doHorizontal)
11352 hist->
Draw(
"same");
11364 auto hh =
dynamic_cast<TH1 *
>(histCopy->Clone(
".axiscopy"));
11368 (sOpt.
Contains(
"impact") && !doHorizontal)
11382 bool doneDraw =
false;
11388 for (
auto [catName, catVal] : s->get<
RooSimultaneous>()->indexCat()) {
11389 auto _pad =
dynamic_cast<TPad *
>(
gPad->GetPrimitive(
11397 if (
auto c = s->bins().find(catName)) {
11398 c->push_back(std::make_shared<xRooNode>(*
this));
11399 auto ds =
c->datasets().find(
GetName());
11400 c->resize(
c->size() - 1);
11402 std::cout <<
" no ds " <<
GetName() <<
" - this should never happen!" << std::endl;
11418 if (!s && hasSame) {
11421 bool doneDraw =
false;
11422 for (
auto o : *
gPad->GetListOfPrimitives()) {
11437 auto dataGraph =
BuildGraph(
v,
false, (!s && hasSame) ?
gPad :
nullptr);
11442 dataGraph->SetMarkerSize(dataGraph->GetMarkerSize() *
gPad->GetWNDC());
11447 for (
int i = 0; i < dataGraph->GetN(); i++)
11448 tot += dataGraph->GetPointY(i);
11449 dataGraph->Scale(1. / tot);
11454 dataGraph->Draw(
"Az0p");
11455 addLegendEntry(dataGraph, strlen(dataGraph->GetTitle()) ? dataGraph->GetTitle() :
GetName(),
"pEX0");
11461 bool noPoint =
false;
11464 for (
auto o : *
gPad->GetListOfPrimitives()) {
11465 if (
auto h =
dynamic_cast<TH1 *
>(o);
11466 h && strcmp(
h->GetXaxis()->GetName(),
dynamic_cast<TObject *
>(
v)->
GetName()) == 0) {
11467 dataGraph->SetPointY(0,
h->Interpolate(dataGraph->GetPointX(0)));
11474 if (
auto _pad =
dynamic_cast<TPad *
>(
gPad->FindObject(
"auxPad")); _pad) {
11475 if (
auto h =
dynamic_cast<TH1 *
>(_pad->GetPrimitive(
"auxHist"));
h) {
11478 histName = histName(0, histName.
Index(
'|'));
11479 if (
auto mainHist =
dynamic_cast<TH1 *
>(
gPad->GetPrimitive(histName));
11483 auto ratioGraph =
dynamic_cast<TGraphAsymmErrors *
>(dataGraph->Clone(dataGraph->GetName()));
11485 for (
int i = 0; i < ratioGraph->GetN(); i++) {
11486 double val = ratioGraph->GetPointY(i);
11487 int binNum = mainHist->FindFixBin(ratioGraph->GetPointX(i));
11488 double nom = mainHist->GetBinContent(binNum);
11489 double nomerr = mainHist->GetBinError(binNum);
11491 std::get<0>(
auxFunctions[
h->GetYaxis()->GetTitle()])(ratioGraph->GetPointY(i), nom, nomerr);
11492 double yup = std::get<0>(
auxFunctions[
h->GetYaxis()->GetTitle()])(val + ratioGraph->GetErrorYhigh(i),
11495 double ydown = yval - std::get<0>(
auxFunctions[
h->GetYaxis()->GetTitle()])(
11496 val - ratioGraph->GetErrorYlow(i), nom, nomerr);
11497 if (!std::isnan(yval)) {
11498 ratioGraph->SetPointY(i, yval);
11499 if (!std::isnan(yup))
11500 ratioGraph->SetPointEYhigh(i, yup);
11501 if (!std::isnan(ydown))
11502 ratioGraph->SetPointEYlow(i, ydown);
11507 while (i < ratioGraph->GetN()) {
11508 if (ratioGraph->GetPointY(i) == 0 && ratioGraph->GetErrorYhigh(i) == 0 &&
11509 ratioGraph->GetErrorYlow(i) == 0) {
11510 ratioGraph->RemovePoint(i);
11515 auto _tmpPad =
gPad;
11517 ratioGraph->Draw(
"z0psame");
11518 auto minMax = graphMinMax(ratioGraph);
11519 adjustYRange(minMax.first, minMax.second,
h, std::get<1>(
auxFunctions[
h->GetYaxis()->GetTitle()]));
11525 dataGraph->Draw(
"z0p same");
11526 addLegendEntry((noPoint) ?
nullptr : dataGraph, strlen(dataGraph->GetTitle()) ? dataGraph->GetTitle() :
GetName(),
11527 noPoint ?
"" :
"pEX0");
11530 adjustYRange(minMax.first, minMax.second);
11546 gr->
Draw(hasSame ?
"P" :
"AP");
11550 if (forceNames !=
"") {
11553 bool _drawn =
false;
11554 auto _coords =
coords();
11559 std::vector<double> valuesToDo = {initPar->
getVal()};
11560 if (initPar->hasError() || initPar->hasAsymError()) {
11561 valuesToDo.push_back(initPar->getVal() + initPar->getErrorLo());
11562 valuesToDo.push_back(initPar->getVal() + initPar->getErrorHi());
11565 for (
auto valueToDo : valuesToDo) {
11567 for (
auto &
d : _dsets) {
11568 if (!
d->get()->TestBit(1 << 20))
11572 auto _obs =
d->obs();
11573 auto x = _obs.find((
v) ?
dynamic_cast<TObject *
>(
v)->
GetName() : emptyHist->GetXaxis()->GetName());
11574 auto _nll =
nll(
d);
11577 for (
int i = 0; i < nevent; i++) {
11579 bool _skip =
false;
11580 for (
const auto &_c : _coords) {
11582 if (cat->getIndex() != theData->get()->getCatIndex(cat->GetName())) {
11592 auto val = _nll.pars()->getRealValue(initPar->GetName());
11594 _nll.pars()->setRealValue(initPar->GetName(), valueToDo);
11595 auto nllVal = _nll.getEntryVal(i);
11596 _nll.pars()->setRealValue(initPar->GetName(), initPar->getVal());
11597 auto nllVal2 = _nll.getEntryVal(i);
11598 _nll.pars()->setRealValue(initPar->GetName(), val);
11604 auto val = _nll.pars()->getRealValue(initPar->GetName());
11606 _nll.pars()->setRealValue(initPar->GetName(), valueToDo);
11607 auto _extTerm = _nll.extendedTermVal();
11608 _nll.pars()->setRealValue(initPar->GetName(), initPar->getVal());
11609 auto _extTerm2 = _nll.extendedTermVal();
11610 _nll.pars()->setRealValue(initPar->GetName(), val);
11611 for (
int i = 1; i <= emptyHist->GetNbinsX(); i++) {
11612 emptyHist->SetBinContent(i,
11613 emptyHist->GetBinContent(i) + (_extTerm2 - _extTerm) / emptyHist->GetNbinsX());
11614 emptyHist->SetBinError(i, 0);
11616 emptyHist->GetYaxis()->SetTitle(
"log (L(#theta)/L(#theta_{0}))");
11617 emptyHist->SetTitle(
TString::Format(
"#theta = %g", (ii > 1) ? valueToDo : val));
11619 emptyHist->SetLineColor(
kBlack);
11621 emptyHist->SetLineColor(
kRed);
11622 }
else if (ii == 3) {
11623 emptyHist->SetLineColor(
kBlue);
11625 emptyHist->Draw(_drawn ?
"same" :
"");
11632 auto rar = get<RooAbsReal>();
11642 rarNode =
find(
".pdf").get();
11647 if (!nostack && !hasOverlay &&
11657 auto h =
BuildHistogram(
v,
false, hasErrorOpt, 1, 0,
"",
false,
false, 0,
nullptr, nostack,
true );
11668 v = getObject<RooAbsLValue>(
h->GetXaxis()->IsAlphanumeric() ?
h->GetXaxis()->GetTimeFormatOnly()
11669 :
h->GetXaxis()->GetName())
11672 if (
h->GetXaxis()->IsAlphanumeric()) {
11680 if (rar->InheritsFrom(
"RooAbsPdf") && !(rar->InheritsFrom(
"RooRealSumPdf") || rar->InheritsFrom(
"RooAddPdf") ||
11681 rar->InheritsFrom(
"RooSimultaneous"))) {
11684 rar->leafNodeServerList(&s);
11691 for (
auto _p : s) {
11698 ss +=
TString::Format(
"%s=%g", strlen(_p->GetTitle()) ? _p->GetTitle() : _p->GetName(), _v->getVal());
11699 if (_v->hasError()) {
11710 gPad->SetGrid(0, 0);
11712 gPad->SetGrid(1, 1);
11717 h->SetFillStyle(0);
11766 gROOT->SetEditHistograms(
true);
11768 gROOT->SetEditHistograms(
false);
11782 bool hasError(
false);
11783 for (
int i = 0; i <
h->GetSumw2N(); i++) {
11784 if (
h->GetSumw2()->At(i)) {
11795 if (!hasSame &&
h->GetYaxis()->GetTitleFont() % 10 == 2) {
11796 h->GetYaxis()->SetTitleOffset(1.);
11799 TH1 *errHist =
nullptr;
11804 if (rar->getAttribute(
"Logy")) {
11813 auto _hist = (errHist) ? errHist :
h;
11814 auto hCopy = (errHist) ?
nullptr :
dynamic_cast<TH1 *
>(
h->Clone());
11818 hCopy->SetDirectory(
nullptr);
11820 _hist->GetListOfFunctions()->Add(node);
11821 _hist->GetListOfFunctions()->Add(
new TExec(
11824 "gROOT->SetEditHistograms(true);auto h = dynamic_cast<TH1*>(gPad->GetPrimitive(\"%s\")); if(h) { double "
11825 "range= h->GetMaximum()-h->GetMinimum(); if(auto n "
11826 "= dynamic_cast<xRooNode*>(h->GetListOfFunctions()->FindObject(\"%s\")); n && "
11827 "n->TestBit(TObject::kNotDeleted) && n->get<RooRealVar>()->getVal() != h->GetBinContent(1)) {"
11828 "h->SetBinContent(1, "
11829 "TString::Format(\"%%.2g\",int(h->GetBinContent(1)/(range*0.01))*range*0.01).Atof());n->SetContent( "
11830 "h->GetBinContent(1) ); for(auto pp : *h->GetListOfFunctions()) if(auto hh = "
11831 "dynamic_cast<TH1*>(pp))hh->SetBinContent(1,h->GetBinContent(1));} if(h->GetBinContent(1)==0.) "
11832 "h->SetBinContent(1,range*0.005); gPad->Modified();gPad->Update(); }",
11833 _hist->GetName(), node->GetName())));
11839 hCopy->SetFillStyle(0);
11840 _hist->GetListOfFunctions()->Add(hCopy,
"TEXT HIST same");
11843 _hist->SetStats(
false);
11850 bool overlayExisted =
false;
11853 if (
auto existing =
dynamic_cast<TH1 *
>(
gPad->GetPrimitive(
h->GetName())); existing) {
11858 overlayExisted =
true;
11860 TString oldStyle = (rar && rar->getStringAttribute(
"style")) ? rar->getStringAttribute(
"style") :
"";
11861 h->SetTitle(overlayName);
11890 rar->setStringAttribute(
"style", oldStyle ==
"" ?
nullptr : oldStyle.
Data());
11891 if (
auto _style = _styleNode.get<
TStyle>()) {
11896 h->Draw(dOpt ==
"LF2" ?
"e3" : dOpt);
11919 if (
auto stack =
dynamic_cast<THStack *
>(
h->FindObject(
"stack"))) {
11921 TObjLink *lnk = stack->GetHists()->FirstLink();
11926 if (lnk == stack->GetHists()->FirstLink() &&
h->GetMinimum() > hhMin) {
11928 if (hhMin >= 0 && newMin < 0)
11929 newMin = hhMin * 0.99;
11930 adjustYRange(newMin,
h->GetMaximum());
12202 }
else if (!overlayExisted) {
12213 errHist->
Draw(dOpt + (dOpt.
Contains(
"LF2") ?
"e3same" :
"e2same"));
12214 double ymax = -std::numeric_limits<double>::infinity();
12215 double ymin = std::numeric_limits<double>::infinity();
12216 for (
int i = 1; i <= errHist->
GetNbinsX(); i++) {
12222 adjustYRange(
h->GetMinimum() * 0.9,
h->GetMaximum() * 1.1);
12225 if ((!auxPlotTitle.empty()) && !hasSame) {
12227 double padFrac = 0.3;
12228 auto _tmpPad =
gPad;
12229 gPad->SetBottomMargin(padFrac);
12230 auto ratioPad =
new TPad(
"auxPad",
"aux plot", 0, 0, 1, padFrac);
12231 ratioPad->SetFillColor(_tmpPad->GetFillColor());
12232 ratioPad->SetNumber(1);
12233 ratioPad->SetBottomMargin(ratioPad->GetBottomMargin() / padFrac);
12234 ratioPad->SetTopMargin(0.04);
12235 ratioPad->SetLeftMargin(
gPad->GetLeftMargin());
12236 ratioPad->SetRightMargin(
gPad->GetRightMargin());
12238 TH1 *ratioHist =
dynamic_cast<TH1 *
>((errHist) ? errHist->
Clone(
"auxHist") :
h->
Clone(
"auxHist"));
12239 ratioHist->
Reset();
12249 auxPlotTitle.c_str()));
12252 ratioPad->SetGridy();
12254 for (
int i = 1; i <= ratioHist->
GetNbinsX(); i++) {
12262 double rHeight = (1. - padFrac) / padFrac;
12270#if ROOT_VERSION_CODE < ROOT_VERSION(6, 26, 00)
12279 auto _h =
dynamic_cast<TH1 *
>(ratioHist->
Clone(
"auxHist_clone"));
12281 _h->SetFillColor(0);
12287 TString::Format(
"auto h1 = (TH1*)%p; auto h2 = (TH1*)%p; if(h2->GetXaxis()->GetFirst() != "
12288 "h1->GetXaxis()->GetFirst() || h1->GetXaxis()->GetLast()!=h2->GetXaxis()->GetLast()) "
12289 "{h2->GetXaxis()->SetRange(h1->GetXaxis()->GetFirst(),h1->GetXaxis()->GetLast());if(gPad) "
12290 "{gPad->GetCanvas()->Paint();gPad->GetCanvas()->Update();}}",
12291 (
void *)ratioHist, (
void *)(
h))));
12292 ratioHist->
Draw((errHist ?
"e2" :
""));
12296 }
else if (
auto ratioPad =
dynamic_cast<TPad *
>(
gPad->GetPrimitive(
"auxPad")); hasSame && ratioPad) {
12300 if (
auto hr =
dynamic_cast<TH1 *
>(ratioPad->GetPrimitive(
"auxHist"));
12302 TString histName = hr->GetTitle();
12304 histName = histName(0, histName.
Index(
'|'));
12306 if (
auto hnom =
dynamic_cast<TH1 *
>(
gPad->GetPrimitive(histName)); hnom) {
12307 h =
dynamic_cast<TH1 *
>(
h->Clone(
h->GetName()));
12310 for (
int i = 1; i <= hnom->GetNbinsX(); i++) {
12311 double val =
h->GetBinContent(i);
12312 double err =
h->GetBinError(i);
12313 h->SetBinContent(i, std::get<0>(
auxFunctions[hr->GetYaxis()->GetTitle()])(
12314 h->GetBinContent(i), hnom->GetBinContent(i), hnom->GetBinError(i)));
12315 h->SetBinError(i, std::get<0>(
auxFunctions[hr->GetYaxis()->GetTitle()])(
12316 val + err, hnom->GetBinContent(i), hnom->GetBinError(i)) -
12317 h->GetBinContent(i));
12319 auto _tmpPad =
gPad;
12322 if (
auto existing =
dynamic_cast<TH1 *
>(ratioPad->GetPrimitive(
h->GetName())); existing) {
12327 overlayExisted =
true;
12334 double ymax = -std::numeric_limits<double>::infinity();
12335 double ymin = std::numeric_limits<double>::infinity();
12336 for (
int i = 1; i <=
h->GetNbinsX(); i++) {
12337 ymax = std::max(
ymax,
h->GetBinContent(i) +
h->GetBinError(i));
12338 ymin = std::min(
ymin,
h->GetBinContent(i) -
h->GetBinError(i));
12367 if (
auto _pdf = get<RooAbsPdf>();
12368 !hasSame && _pdf &&
coefs(
true).empty()) {
12371 for (
auto &
d : _dsets) {
12372 if (
d->get()->TestBit(1 << 20)) {
12393 if (sFilename.
Contains(
".root:")) {
12395 sFilename = sFilename(0, sFilename.
Index(
".root:") + 5);
12398 if (
auto pdf = get<RooAbsPdf>(); pdf) {
12403 auto addedPdf =
ws.Add(*
this);
12408 mc.
SetPdf(addedPdf->GetName());
12418 }
else if (
auto w = get<RooWorkspace>();
w) {
12420 w->import(*
gROOT->GetListOfColors(),
true);
12422 if (sFilename.
EndsWith(
".json")) {
12423#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 26, 00)
12427 Info(
"SaveAs",
"%s saved to %s",
w->GetName(), sFilename.
Data());
12429 Error(
"SaveAs",
"Unable to save to %s", sFilename.
Data());
12432 Error(
"SaveAs",
"json format workspaces only in ROOT 6.26 onwards");
12437#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
12441 for (
auto &
c :
w->components()) {
12442 c->_eocache =
nullptr;
12446#if ROOT_VERSION_CODE < ROOT_VERSION(6, 38, 00)
12447 if (!
w->writeToFile(sFilename, sOpt !=
"update")) {
12449 if (
w->writeToFile(sFilename, sOpt !=
"update")) {
12451 Info(
"SaveAs",
"%s saved to %s",
w->GetName(), sFilename.
Data());
12457 auto dir =
dest->GetDirectory(source->
GetName());
12462 auto key =
dynamic_cast<TKey *
>(k);
12463 const char *classname = key->GetClassName();
12472 if (dir->FindKey(key->GetName()))
12475 if (strcmp(classname,
"ROOT::Fit::FitConfig") == 0) {
12477 dir->WriteObject(fc, key->GetName());
12480 TObject *obj = key->ReadObj();
12482 dir->WriteTObject(obj, key->
GetName());
12489 if (
gROOT->GetListOfFiles()) {
12490 for (
auto key : *
gROOT->GetListOfFiles()) {
12491 if (
auto fitDb =
dynamic_cast<TMemFile *
>(key);
12493 CopyDir(fitDb, std::make_unique<TFile>(sFilename,
"UPDATE").
get());
12494 Info(
"SaveAs",
"Saved %s to %s", fitDb->GetName(), sFilename.
Data());
12499 Error(
"SaveAs",
"Unable to save to %s", sFilename.
Data());
12501#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
12503 for (
auto &
c :
w->components()) {
12504 c->setExpensiveObjectCache(
w->expensiveObjectCache());
12512 auto res =
GetBinErrors(bin, bin, fr, nToys, errorsHi, errorsLo);
12514 return std::numeric_limits<double>::quiet_NaN();
12520 std::vector<double> out;
12521 out.reserve(
size());
12522 for (
auto child : *
this) {
12523 out.push_back(
child->GetContent());
12537 auto rho = _fr->correlationMatrix();
12541 auto _pars =
pars();
12546 for (
int m = 0;
m < rho.GetNrows();
m++) {
12547 auto p_m =
dynamic_cast<RooRealVar *
>(_fr->floatParsFinal().at(
m));
12553 auto tmp = _p->
getVal();
12554 _p->setVal(p_m->getVal() + p_m->getErrorHi());
12556 _p->setVal(p_m->getVal() + p_m->getErrorLo());
12559 for (
int n = 0;
n < rho.GetNrows();
n++) {
12560 auto p_n =
dynamic_cast<RooRealVar *
>(_fr->floatParsFinal().at(
n));
12566 auto tmp2 = _p2->
getVal();
12567 _p2->setVal(p_n->getVal() + p_n->getErrorHi());
12568 auto nu_n = (p_n == p_m) ? nu_m :
contents();
12569 _p2->setVal(p_n->getVal() + p_n->getErrorLo());
12570 auto nu_n2 = (p_n == p_m) ? nu_m2 :
contents();
12572 for (
int i = 0; i < out.
GetNrows(); i++) {
12573 for (
int j = 0; j < out.
GetNrows(); j++) {
12574 out(i, j) += 0.25 * (nu_m[i] - nu_m2[i]) * rho(
m,
n) * (nu_n[j] - nu_n2[j]);
12582std::pair<double, double>
12586 double err = std::numeric_limits<double>::quiet_NaN();
12588 std::unique_ptr<RooAbsCollection> _snap;
12593 _pars = _fr->floatParsFinal();
12594 _pars = _fr->constPars();
12599 auto _coefs =
coefs();
12601 out =
c->getVal(sobs);
12607 p->setNormRange(rangeName);
12608#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 27, 00)
12611 out *=
p->expectedEvents(*_obs.get<
RooArgList>());
12612#if ROOT_VERSION_CODE < ROOT_VERSION(6, 27, 00)
12614 p->_normSet =
nullptr;
12616 err =
GetBinError(-1, fr, nToys, errorsHi, errorsLo);
12618 p->setNormRange(
nullptr);
12619 }
else if (
auto p2 =
dynamic_cast<RooAbsReal *
>(
get()); p2) {
12621 auto f = std::shared_ptr<RooAbsReal>(
12622 p2->createIntegral(*std::unique_ptr<RooArgSet>(p2->getObservables(*_obs.get<
RooArgList>())),
12626 out *=
f->getVal();
12627 err =
xRooNode(pr, *
this).GetBinError(-1, fr, nToys, errorsHi, errorsLo);
12629 }
else if (get<RooAbsData>()) {
12632 auto ax = (rangeName) ?
GetXaxis() :
nullptr;
12633 auto rv = (ax) ?
dynamic_cast<RooRealVar *
>(ax->GetParent()) :
nullptr;
12634 auto cv = (ax && !rv) ?
dynamic_cast<RooCategory *
>(ax->GetParent()) :
nullptr;
12636 for (
auto &
v : vals) {
12639 if (rv && !rv->inRange(ax->GetBinCenter(i), rangeName))
12641 if (cv && !cv->isStateInRange(rangeName, ax->GetBinLabel(i)))
12648 out = std::numeric_limits<double>::quiet_NaN();
12651 _pars.RooAbsCollection::operator=(*_snap);
12653 return std::make_pair(out, err);
12666 if (binStart != binEnd || !
fParent) {
12672 std::vector<double> out;
12674 auto _hist =
BuildHistogram(
nullptr,
true,
true, binStart, binEnd, _fr, errorHi, errorLo, nToys);
12678 binEnd = _hist->GetNbinsX();
12679 }
else if (binEnd == binStart && binEnd == -1) {
12683 for (
int bin = binStart; bin <= binEnd; bin++) {
12684 out.push_back(((errorLo && !errorHi) ? (-1.) : 1.) *
12685 _hist->GetBinError(bin));
12812std::string cling::printValue(
const XROOFIT_NAMESPACE_NAME::xRooNode *
v)
12815 return "nullptr\n";
12818 size_t left =
v->size();
12819 for (
auto n : *
v) {
12825 out +=
n->GetName();
12826 if (out.length() > 100 && left > 0) {
12832 out = std::string(
Form(
"<%s> %s",
v->get() ?
v->get()->ClassName() :
"nullptr",
v->
GetName())) + out;
12837 return "<nullptr>";
12839 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)