From 356b093acd6d35cebdbe5d7d3474ea403df42af4 Mon Sep 17 00:00:00 2001 From: Phmonski Date: Wed, 5 Nov 2025 12:03:45 +0100 Subject: [PATCH 1/7] Fix Constant Flag in Data axes --- roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h | 4 ++-- roofit/hs3/src/RooJSONFactoryWSTool.cxx | 15 +++++---------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h b/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h index c656d60f73358..349ce96dc87b3 100644 --- a/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h +++ b/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h @@ -229,8 +229,8 @@ class RooJSONFactoryWSTool { void importVariable(const RooFit::Detail::JSONNode &p); void importDependants(const RooFit::Detail::JSONNode &n); - void exportVariable(const RooAbsArg *v, RooFit::Detail::JSONNode &p); - void exportVariables(const RooArgSet &allElems, RooFit::Detail::JSONNode &n); + void exportVariable(const RooAbsArg *v, RooFit::Detail::JSONNode &n, const bool storeConstant=true); + void exportVariables(const RooArgSet &allElems, RooFit::Detail::JSONNode &n, const bool storeConstant=true); void exportAllObjects(RooFit::Detail::JSONNode &n); diff --git a/roofit/hs3/src/RooJSONFactoryWSTool.cxx b/roofit/hs3/src/RooJSONFactoryWSTool.cxx index b41f537d7f01b..5a503823692c4 100644 --- a/roofit/hs3/src/RooJSONFactoryWSTool.cxx +++ b/roofit/hs3/src/RooJSONFactoryWSTool.cxx @@ -965,7 +965,7 @@ RooAbsReal *RooJSONFactoryWSTool::requestImpl(const std::string &obj * @param node The JSONNode to which the variable will be exported. * @return void */ -void RooJSONFactoryWSTool::exportVariable(const RooAbsArg *v, JSONNode &node) +void RooJSONFactoryWSTool::exportVariable(const RooAbsArg *v, JSONNode &node, const bool storeConstant) { auto *cv = dynamic_cast(v); auto *rrv = dynamic_cast(v); @@ -984,7 +984,7 @@ void RooJSONFactoryWSTool::exportVariable(const RooAbsArg *v, JSONNode &node) var["const"] << true; } else if (rrv) { var["value"] << rrv->getVal(); - if (rrv->isConstant()) { + if (rrv->isConstant() && storeConstant) { var["const"] << rrv->isConstant(); } if (rrv->getBins() != 100) { @@ -1004,12 +1004,12 @@ void RooJSONFactoryWSTool::exportVariable(const RooAbsArg *v, JSONNode &node) * @param n The JSONNode to which the variables will be exported. * @return void */ -void RooJSONFactoryWSTool::exportVariables(const RooArgSet &allElems, JSONNode &n) +void RooJSONFactoryWSTool::exportVariables(const RooArgSet &allElems, JSONNode &n, const bool storeConstant) { // export a list of RooRealVar objects n.set_seq(); for (RooAbsArg *arg : allElems) { - exportVariable(arg, n); + exportVariable(arg, n, storeConstant); } } @@ -1554,7 +1554,7 @@ void RooJSONFactoryWSTool::exportData(RooAbsData const &data) // this really is an unbinned dataset output["type"] << "unbinned"; - exportVariables(variables, output["axes"]); + exportVariables(variables, output["axes"], false); auto &coords = output["entries"].set_seq(); std::vector weightVals; bool hasNonUnityWeights = false; @@ -1562,10 +1562,6 @@ void RooJSONFactoryWSTool::exportData(RooAbsData const &data) data.get(i); coords.append_child().fill_seq(variables, [](auto x) { return static_cast(x)->getVal(); }); std::string datasetName = data.GetName(); - /*if (datasetName.find("combData_ZvvH126.5") != std::string::npos) { - file << dynamic_cast(data.get(i)->find("atlas_invMass_PttEtaConvVBFCat1"))->getVal() << - std::endl; - }*/ if (data.isWeighted()) { weightVals.push_back(data.weight()); if (data.weight() != 1.) @@ -1575,7 +1571,6 @@ void RooJSONFactoryWSTool::exportData(RooAbsData const &data) if (data.isWeighted() && hasNonUnityWeights) { output["weights"].fill_seq(weightVals); } - // file.close(); } /** From 5454e38cecc5d38f9303867de5e46ce33c19e0c0 Mon Sep 17 00:00:00 2001 From: Phmonski Date: Fri, 7 Nov 2025 14:47:49 +0100 Subject: [PATCH 2/7] ParamHistFuncs accept custom modifiers --- roofit/hs3/src/JSONFactories_HistFactory.cxx | 11 ++++- roofit/hs3/src/JSONFactories_RooFitCore.cxx | 42 +++++++++++++++++++ roofit/hs3/src/RooFitHS3_wsexportkeys.cxx | 14 +++---- .../src/RooFitHS3_wsfactoryexpressions.cxx | 14 +++---- .../inc/RooFit/Detail/JSONInterface.h | 6 +++ 5 files changed, 72 insertions(+), 15 deletions(-) diff --git a/roofit/hs3/src/JSONFactories_HistFactory.cxx b/roofit/hs3/src/JSONFactories_HistFactory.cxx index 2634b752f3535..23f0f3c5336e9 100644 --- a/roofit/hs3/src/JSONFactories_HistFactory.cxx +++ b/roofit/hs3/src/JSONFactories_HistFactory.cxx @@ -823,6 +823,15 @@ void collectElements(RooArgSet &elems, RooAbsArg *arg) } } +bool allRooRealVar(const RooAbsCollection &list) { + for (auto* var : list) { + if (!dynamic_cast(var)) { + return false; + } + } + return true; +} + struct Sample { std::string name; std::vector hist; @@ -920,7 +929,7 @@ Channel readChannel(RooJSONFactoryWSTool *tool, const std::string &pdfname, cons addNormFactor(par, sample, ws); } else if (auto hf = dynamic_cast(e)) { updateObservables(hf->dataHist()); - } else if (auto phf = dynamic_cast(e)) { + } else if (ParamHistFunc* phf = dynamic_cast(e); phf && allRooRealVar(phf->paramList())) { phfs.push_back(phf); } else if (auto fip = dynamic_cast(e)) { // some (modified) histfactory models have several instances of FlexibleInterpVar diff --git a/roofit/hs3/src/JSONFactories_RooFitCore.cxx b/roofit/hs3/src/JSONFactories_RooFitCore.cxx index 7cc8754df560b..0317c74f524b9 100644 --- a/roofit/hs3/src/JSONFactories_RooFitCore.cxx +++ b/roofit/hs3/src/JSONFactories_RooFitCore.cxx @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -532,6 +533,23 @@ class RooMultiVarGaussianFactory : public RooFit::JSONIO::Importer { } }; +class ParamHistFuncFactory : public RooFit::JSONIO::Importer { +public: + bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override + { + std::string name(RooJSONFactoryWSTool::name(p)); + RooArgList vars = tool->requestArgList(p, "variables"); + std::vector nbins; + nbins << p["nbins"]; + for (size_t i = 0; i < vars.size(); ++i) { + auto *v = dynamic_cast(vars.at(i)); + v->setBins(nbins[i]); + } + tool->wsEmplace(name, vars, tool->requestArgList(p, "parameters")); + return true; + } +}; + /////////////////////////////////////////////////////////////////////////////////////////////////////// // specialized exporter implementations /////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -696,6 +714,7 @@ class RooFormulaArgStreamer : public RooFit::JSONIO::Exporter { expr.ReplaceAll("TMath::Sin", "sin"); expr.ReplaceAll("TMath::Sqrt", "sqrt"); expr.ReplaceAll("TMath::Power", "pow"); + expr.ReplaceAll("TMath::Erf", "erf"); } }; template @@ -952,6 +971,26 @@ class RooExtendPdfStreamer : public RooFit::JSONIO::Exporter { } }; +class ParamHistFuncStreamer : public RooFit::JSONIO::Exporter { +public: + std::string const &key() const override; + bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override + { + auto *pdf = static_cast(func); + elem["type"] << key(); + RooJSONFactoryWSTool::fillSeq(elem["variables"], pdf->dataVars()); + RooJSONFactoryWSTool::fillSeq(elem["parameters"], pdf->paramList()); + std::vector nbins; + for (auto *arg : pdf->dataVars()) { + auto *var = dynamic_cast(arg); + nbins.push_back(var->numBins()); + } + elem["nbins"] << nbins; + + return true; + } +}; + #define DEFINE_EXPORTER_KEY(class_name, name) \ std::string const &class_name::key() const \ { \ @@ -989,6 +1028,7 @@ DEFINE_EXPORTER_KEY(RooRealIntegralStreamer, "integral"); DEFINE_EXPORTER_KEY(RooDerivativeStreamer, "derivative"); DEFINE_EXPORTER_KEY(RooFFTConvPdfStreamer, "fft_conv_pdf"); DEFINE_EXPORTER_KEY(RooExtendPdfStreamer, "extend_pdf"); +DEFINE_EXPORTER_KEY(ParamHistFuncStreamer, "param_hist_func"); /////////////////////////////////////////////////////////////////////////////////////////////////////// // instantiate all importers and exporters @@ -1021,6 +1061,7 @@ STATIC_EXECUTE([]() { registerImporter("derivative", false); registerImporter("fft_conv_pdf", false); registerImporter("extend_pdf", false); + registerImporter("param_hist_func", false); registerExporter>(RooAddPdf::Class(), false); registerExporter>(RooAddModel::Class(), false); @@ -1047,6 +1088,7 @@ STATIC_EXECUTE([]() { registerExporter(RooDerivative::Class(), false); registerExporter(RooFFTConvPdf::Class(), false); registerExporter(RooExtendPdf::Class(), false); + registerExporter(ParamHistFunc::Class(), false); }); } // namespace diff --git a/roofit/hs3/src/RooFitHS3_wsexportkeys.cxx b/roofit/hs3/src/RooFitHS3_wsexportkeys.cxx index dacbf6dbf6456..20423610811ac 100644 --- a/roofit/hs3/src/RooFitHS3_wsexportkeys.cxx +++ b/roofit/hs3/src/RooFitHS3_wsexportkeys.cxx @@ -62,6 +62,13 @@ auto RooFitHS3_wsexportkeys = R"({ "sigmaR": "sigma_R" } }, + "RooEffProd": { + "type": "efficiency_product_pdf_dist", + "proxies": { + "pdf": "pdf", + "eff": "eff" + } + }, "RooGamma": { "type": "gamma_dist", "proxies": { @@ -79,13 +86,6 @@ auto RooFitHS3_wsexportkeys = R"({ "sigma": "sigma" } }, - "ParamHistFunc": { - "type": "step", - "proxies": { - "dataVars": "variables", - "paramSet": "parameters" - } - }, "RooLandau": { "type": "landau_dist", "proxies": { diff --git a/roofit/hs3/src/RooFitHS3_wsfactoryexpressions.cxx b/roofit/hs3/src/RooFitHS3_wsfactoryexpressions.cxx index 62c27a0038fca..6076465bcb8ea 100644 --- a/roofit/hs3/src/RooFitHS3_wsfactoryexpressions.cxx +++ b/roofit/hs3/src/RooFitHS3_wsfactoryexpressions.cxx @@ -43,6 +43,13 @@ auto RooFitHS3_wsfactoryexpressions = R"({ "coefficients" ] }, + "efficiency_product_pdf_dist": { + "class": "RooEffProd", + "arguments": [ + "pdf", + "eff" + ] + }, "gamma_dist": { "class": "RooGamma", "arguments": [ @@ -112,13 +119,6 @@ auto RooFitHS3_wsfactoryexpressions = R"({ "observables" ] }, - "step": { - "class": "ParamHistFunc", - "arguments": [ - "variables", - "parameters" - ] - }, "sum": { "class": "RooAddition", "arguments": [ diff --git a/roofit/jsoninterface/inc/RooFit/Detail/JSONInterface.h b/roofit/jsoninterface/inc/RooFit/Detail/JSONInterface.h index 27b46b9feb51e..245673fcf577f 100644 --- a/roofit/jsoninterface/inc/RooFit/Detail/JSONInterface.h +++ b/roofit/jsoninterface/inc/RooFit/Detail/JSONInterface.h @@ -265,6 +265,12 @@ inline RooFit::Detail::JSONNode &operator<<(RooFit::Detail::JSONNode &n, std::sp return n; } +inline RooFit::Detail::JSONNode &operator<<(RooFit::Detail::JSONNode &n, std::span v) +{ + n.fill_seq(v); + return n; +} + template RooFit::Detail::JSONNode & operator<<(RooFit::Detail::JSONNode &n, const std::unordered_map &m) From 6af113b544dad12f60663cc089edbf3fd6d48c8a Mon Sep 17 00:00:00 2001 From: Phmonski Date: Wed, 12 Nov 2025 18:53:31 +0100 Subject: [PATCH 3/7] Store binning Information with ParamHistFunc --- .../hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h | 4 +- roofit/hs3/src/JSONFactories_RooFitCore.cxx | 95 +++++++++++++++---- roofit/hs3/src/RooJSONFactoryWSTool.cxx | 23 +++-- 3 files changed, 95 insertions(+), 27 deletions(-) diff --git a/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h b/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h index 349ce96dc87b3..d4e10d3ba1dc8 100644 --- a/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h +++ b/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h @@ -229,8 +229,8 @@ class RooJSONFactoryWSTool { void importVariable(const RooFit::Detail::JSONNode &p); void importDependants(const RooFit::Detail::JSONNode &n); - void exportVariable(const RooAbsArg *v, RooFit::Detail::JSONNode &n, const bool storeConstant=true); - void exportVariables(const RooArgSet &allElems, RooFit::Detail::JSONNode &n, const bool storeConstant=true); + void exportVariable(const RooAbsArg *v, RooFit::Detail::JSONNode &n, bool storeConstant, bool storeBins); + void exportVariables(const RooArgSet &allElems, RooFit::Detail::JSONNode &n, bool storeConstant, bool storeBins); void exportAllObjects(RooFit::Detail::JSONNode &n); diff --git a/roofit/hs3/src/JSONFactories_RooFitCore.cxx b/roofit/hs3/src/JSONFactories_RooFitCore.cxx index 0317c74f524b9..eee4f50948b94 100644 --- a/roofit/hs3/src/JSONFactories_RooFitCore.cxx +++ b/roofit/hs3/src/JSONFactories_RooFitCore.cxx @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -538,16 +539,55 @@ class ParamHistFuncFactory : public RooFit::JSONIO::Importer { bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override { std::string name(RooJSONFactoryWSTool::name(p)); - RooArgList vars = tool->requestArgList(p, "variables"); - std::vector nbins; - nbins << p["nbins"]; - for (size_t i = 0; i < vars.size(); ++i) { - auto *v = dynamic_cast(vars.at(i)); - v->setBins(nbins[i]); - } - tool->wsEmplace(name, vars, tool->requestArgList(p, "parameters")); + RooArgList varList = tool->requestArgList(p, "variables"); + tool->wsEmplace(name, readBinning(p, varList), tool->requestArgList(p, "parameters")); return true; } + +private: + RooArgList readBinning(const JSONNode &topNode, const RooArgList &varList) const + { + // Temporary map from variable name → RooRealVar + std::map> varMap; + + // Build variables from JSON + for (const JSONNode &node : topNode["axes"].children()) { + const std::string name = node["name"].val(); + std::unique_ptr obs; + + if (node.has_child("edges")) { + std::vector edges; + for (const auto &bound : node["edges"].children()) { + edges.push_back(bound.val_double()); + } + obs = std::make_unique(name.c_str(), name.c_str(), edges.front(), edges.back()); + RooBinning bins(obs->getMin(), obs->getMax()); + for (auto b : edges) + bins.addBoundary(b); + obs->setBinning(bins); + } else { + obs = std::make_unique(name.c_str(), name.c_str(), node["min"].val_double(), + node["max"].val_double()); + obs->setBins(node["nbins"].val_int()); + } + + varMap[name] = std::move(obs); + } + + // Now build the final list following the order in varList + RooArgList vars; + for (int i = 0; i < varList.getSize(); ++i) { + const auto *refVar = dynamic_cast(varList.at(i)); + if (!refVar) + continue; + + auto it = varMap.find(refVar->GetName()); + if (it != varMap.end()) { + vars.addOwned(std::move(it->second)); // preserve ownership + } + } + return vars; + } }; /////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -980,15 +1020,36 @@ class ParamHistFuncStreamer : public RooFit::JSONIO::Exporter { elem["type"] << key(); RooJSONFactoryWSTool::fillSeq(elem["variables"], pdf->dataVars()); RooJSONFactoryWSTool::fillSeq(elem["parameters"], pdf->paramList()); - std::vector nbins; - for (auto *arg : pdf->dataVars()) { - auto *var = dynamic_cast(arg); - nbins.push_back(var->numBins()); - } - elem["nbins"] << nbins; - + writeBinningInfo(pdf, elem); return true; } + +private: + void writeBinningInfo(const ParamHistFunc *pdf, JSONNode &elem) const + { + auto &observablesNode = elem["axes"].set_seq(); + // axes have to be ordered to get consistent bin indices + for (auto *var : static_range_cast(pdf->dataVars())) { + std::string name = var->GetName(); + RooJSONFactoryWSTool::testValidName(name, false); + JSONNode &obsNode = observablesNode.append_child().set_map(); + obsNode["name"] << name; + if (var->getBinning().isUniform()) { + obsNode["min"] << var->getMin(); + obsNode["max"] << var->getMax(); + obsNode["nbins"] << var->getBins(); + } else { + auto &edges = obsNode["edges"]; + edges.set_seq(); + double val = var->getBinning().binLow(0); + edges.append_child() << val; + for (int i = 0; i < var->getBinning().numBins(); ++i) { + val = var->getBinning().binHigh(i); + edges.append_child() << val; + } + } + } + } }; #define DEFINE_EXPORTER_KEY(class_name, name) \ @@ -1028,7 +1089,7 @@ DEFINE_EXPORTER_KEY(RooRealIntegralStreamer, "integral"); DEFINE_EXPORTER_KEY(RooDerivativeStreamer, "derivative"); DEFINE_EXPORTER_KEY(RooFFTConvPdfStreamer, "fft_conv_pdf"); DEFINE_EXPORTER_KEY(RooExtendPdfStreamer, "extend_pdf"); -DEFINE_EXPORTER_KEY(ParamHistFuncStreamer, "param_hist_func"); +DEFINE_EXPORTER_KEY(ParamHistFuncStreamer, "step"); /////////////////////////////////////////////////////////////////////////////////////////////////////// // instantiate all importers and exporters @@ -1061,7 +1122,7 @@ STATIC_EXECUTE([]() { registerImporter("derivative", false); registerImporter("fft_conv_pdf", false); registerImporter("extend_pdf", false); - registerImporter("param_hist_func", false); + registerImporter("step", false); registerExporter>(RooAddPdf::Class(), false); registerExporter>(RooAddModel::Class(), false); diff --git a/roofit/hs3/src/RooJSONFactoryWSTool.cxx b/roofit/hs3/src/RooJSONFactoryWSTool.cxx index 5a503823692c4..35a86f109dbbd 100644 --- a/roofit/hs3/src/RooJSONFactoryWSTool.cxx +++ b/roofit/hs3/src/RooJSONFactoryWSTool.cxx @@ -965,7 +965,7 @@ RooAbsReal *RooJSONFactoryWSTool::requestImpl(const std::string &obj * @param node The JSONNode to which the variable will be exported. * @return void */ -void RooJSONFactoryWSTool::exportVariable(const RooAbsArg *v, JSONNode &node, const bool storeConstant) +void RooJSONFactoryWSTool::exportVariable(const RooAbsArg *v, JSONNode &node, bool storeConstant, bool storeBins) { auto *cv = dynamic_cast(v); auto *rrv = dynamic_cast(v); @@ -987,7 +987,7 @@ void RooJSONFactoryWSTool::exportVariable(const RooAbsArg *v, JSONNode &node, co if (rrv->isConstant() && storeConstant) { var["const"] << rrv->isConstant(); } - if (rrv->getBins() != 100) { + if (rrv->getBins() != 100 && storeBins) { var["nbins"] << rrv->getBins(); } _domains->readVariable(*rrv); @@ -1004,12 +1004,12 @@ void RooJSONFactoryWSTool::exportVariable(const RooAbsArg *v, JSONNode &node, co * @param n The JSONNode to which the variables will be exported. * @return void */ -void RooJSONFactoryWSTool::exportVariables(const RooArgSet &allElems, JSONNode &n, const bool storeConstant) +void RooJSONFactoryWSTool::exportVariables(const RooArgSet &allElems, JSONNode &n, bool storeConstant, bool storeBins) { // export a list of RooRealVar objects n.set_seq(); for (RooAbsArg *arg : allElems) { - exportVariable(arg, n, storeConstant); + exportVariable(arg, n, storeConstant, storeBins); } } @@ -1070,7 +1070,7 @@ void RooJSONFactoryWSTool::exportObject(RooAbsArg const &func, std::set(&func) || dynamic_cast(&func)) { - exportVariable(&func, *_varsNode); + exportVariable(&func, *_varsNode, true, false); return; } @@ -1554,7 +1554,7 @@ void RooJSONFactoryWSTool::exportData(RooAbsData const &data) // this really is an unbinned dataset output["type"] << "unbinned"; - exportVariables(variables, output["axes"], false); + exportVariables(variables, output["axes"], false, true); auto &coords = output["entries"].set_seq(); std::vector weightVals; bool hasNonUnityWeights = false; @@ -1955,7 +1955,8 @@ void RooJSONFactoryWSTool::exportAllObjects(JSONNode &n) snapshotSorted.sort(); std::string name(snsh->GetName()); if (name != "default_values") { - this->exportVariables(snapshotSorted, appendNamedChild(n["parameter_points"], name)["parameters"]); + this->exportVariables(snapshotSorted, appendNamedChild(n["parameter_points"], name)["parameters"], true, + false); } } _varsNode = nullptr; @@ -2235,8 +2236,14 @@ void RooJSONFactoryWSTool::importAllNodes(const JSONNode &n) combineDatasets(*_rootnodeInput, datasets); for (auto const &d : datasets) { - if (d) + if (d) { _workspace.import(*d); + for (auto const &obs : *d->get()) { + if (auto *rrv = dynamic_cast(obs)) { + _workspace.var(rrv->GetName())->setBinning(rrv->getBinning()); + } + } + } } _rootnodeInput = nullptr; From 05dc57440116b0dfefb5683d4d828b53de24a494 Mon Sep 17 00:00:00 2001 From: Phmonski Date: Wed, 12 Nov 2025 20:34:25 +0100 Subject: [PATCH 4/7] Add Warning to ParamHistFunc Compatibility --- roofit/hs3/src/JSONFactories_RooFitCore.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/roofit/hs3/src/JSONFactories_RooFitCore.cxx b/roofit/hs3/src/JSONFactories_RooFitCore.cxx index eee4f50948b94..7c404c33962aa 100644 --- a/roofit/hs3/src/JSONFactories_RooFitCore.cxx +++ b/roofit/hs3/src/JSONFactories_RooFitCore.cxx @@ -540,6 +540,14 @@ class ParamHistFuncFactory : public RooFit::JSONIO::Importer { { std::string name(RooJSONFactoryWSTool::name(p)); RooArgList varList = tool->requestArgList(p, "variables"); + if (!p.has_child("axes")) { + std::stringstream ss; + ss << "No axes given in '" << name << "'" + << ". Using default binning (uniform; nbins=100). If needed, export the Workspace with a newer Root version that supports histogram binnings(>6.37.01)." << std::endl; + RooJSONFactoryWSTool::warning(ss.str()); + tool->wsEmplace(name, varList, tool->requestArgList(p, "parameters")); + return true; + } tool->wsEmplace(name, readBinning(p, varList), tool->requestArgList(p, "parameters")); return true; } From 74bb92a46b5f1ebc5fb66d25fee63d77d0c5052e Mon Sep 17 00:00:00 2001 From: Phmonski Date: Thu, 13 Nov 2025 12:59:24 +0100 Subject: [PATCH 5/7] clang-format clean-up --- roofit/hs3/src/JSONFactories_HistFactory.cxx | 9 +++++---- roofit/hs3/src/JSONFactories_RooFitCore.cxx | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/roofit/hs3/src/JSONFactories_HistFactory.cxx b/roofit/hs3/src/JSONFactories_HistFactory.cxx index 23f0f3c5336e9..a294050033b16 100644 --- a/roofit/hs3/src/JSONFactories_HistFactory.cxx +++ b/roofit/hs3/src/JSONFactories_HistFactory.cxx @@ -823,9 +823,10 @@ void collectElements(RooArgSet &elems, RooAbsArg *arg) } } -bool allRooRealVar(const RooAbsCollection &list) { - for (auto* var : list) { - if (!dynamic_cast(var)) { +bool allRooRealVar(const RooAbsCollection &list) +{ + for (auto *var : list) { + if (!dynamic_cast(var)) { return false; } } @@ -929,7 +930,7 @@ Channel readChannel(RooJSONFactoryWSTool *tool, const std::string &pdfname, cons addNormFactor(par, sample, ws); } else if (auto hf = dynamic_cast(e)) { updateObservables(hf->dataHist()); - } else if (ParamHistFunc* phf = dynamic_cast(e); phf && allRooRealVar(phf->paramList())) { + } else if (ParamHistFunc *phf = dynamic_cast(e); phf && allRooRealVar(phf->paramList())) { phfs.push_back(phf); } else if (auto fip = dynamic_cast(e)) { // some (modified) histfactory models have several instances of FlexibleInterpVar diff --git a/roofit/hs3/src/JSONFactories_RooFitCore.cxx b/roofit/hs3/src/JSONFactories_RooFitCore.cxx index 7c404c33962aa..57a2e77dfa653 100644 --- a/roofit/hs3/src/JSONFactories_RooFitCore.cxx +++ b/roofit/hs3/src/JSONFactories_RooFitCore.cxx @@ -542,8 +542,9 @@ class ParamHistFuncFactory : public RooFit::JSONIO::Importer { RooArgList varList = tool->requestArgList(p, "variables"); if (!p.has_child("axes")) { std::stringstream ss; - ss << "No axes given in '" << name << "'" - << ". Using default binning (uniform; nbins=100). If needed, export the Workspace with a newer Root version that supports histogram binnings(>6.37.01)." << std::endl; + ss << "No axes given in '" << name << "'" + << ". Using default binning (uniform; nbins=100). If needed, export the Workspace with a newer Root" + << " version that supports histogram binnings(>6.37.01)." << std::endl; RooJSONFactoryWSTool::warning(ss.str()); tool->wsEmplace(name, varList, tool->requestArgList(p, "parameters")); return true; From e4dfa6dd8a7859f7c7764b71dffcd67155cdf42b Mon Sep 17 00:00:00 2001 From: Simon Cello <87865105+Phmonski@users.noreply.github.com> Date: Fri, 14 Nov 2025 09:29:07 +0100 Subject: [PATCH 6/7] Update warning message for histogram binnings version --- roofit/hs3/src/JSONFactories_RooFitCore.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/roofit/hs3/src/JSONFactories_RooFitCore.cxx b/roofit/hs3/src/JSONFactories_RooFitCore.cxx index 57a2e77dfa653..ffd53eb3ebaea 100644 --- a/roofit/hs3/src/JSONFactories_RooFitCore.cxx +++ b/roofit/hs3/src/JSONFactories_RooFitCore.cxx @@ -544,7 +544,7 @@ class ParamHistFuncFactory : public RooFit::JSONIO::Importer { std::stringstream ss; ss << "No axes given in '" << name << "'" << ". Using default binning (uniform; nbins=100). If needed, export the Workspace with a newer Root" - << " version that supports histogram binnings(>6.37.01)." << std::endl; + << " version that supports histogram binnings(v6.38+)." << std::endl; RooJSONFactoryWSTool::warning(ss.str()); tool->wsEmplace(name, varList, tool->requestArgList(p, "parameters")); return true; From a7c2217f98aa2d29352f5fff3528d79908a59cf0 Mon Sep 17 00:00:00 2001 From: Simon Cello <87865105+Phmonski@users.noreply.github.com> Date: Fri, 14 Nov 2025 09:35:45 +0100 Subject: [PATCH 7/7] Update warning message for default binning --- roofit/hs3/src/JSONFactories_RooFitCore.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roofit/hs3/src/JSONFactories_RooFitCore.cxx b/roofit/hs3/src/JSONFactories_RooFitCore.cxx index ffd53eb3ebaea..a149f647ee34b 100644 --- a/roofit/hs3/src/JSONFactories_RooFitCore.cxx +++ b/roofit/hs3/src/JSONFactories_RooFitCore.cxx @@ -543,8 +543,8 @@ class ParamHistFuncFactory : public RooFit::JSONIO::Importer { if (!p.has_child("axes")) { std::stringstream ss; ss << "No axes given in '" << name << "'" - << ". Using default binning (uniform; nbins=100). If needed, export the Workspace with a newer Root" - << " version that supports histogram binnings(v6.38+)." << std::endl; + << ". Using default binning (uniform; nbins=100). If needed, export the Workspace to JSON with a newer " + << "Root version that supports custom ParamHistFunc binnings(>=6.38.00)." << std::endl; RooJSONFactoryWSTool::warning(ss.str()); tool->wsEmplace(name, varList, tool->requestArgList(p, "parameters")); return true;