Skip to content

Commit b763ff1

Browse files
committed
[RF][HS3] Reduce code duplication in RooFit HS3
Refactor the HS3 serialization code to remove duplicated logic without any change in behavior. All hs3, histfactory and JSON tests still pass. JSONFactories_RooFitCore.cxx: - Drop RooLegacyExpPolyFactory; it was identical to the existing RooPolynomialFactory<RooLegacyExpPoly>, which is now registered directly. - Drop RooLegacyExpPolyStreamer; it was identical to RooPolynomialStreamer<RooLegacyExpPoly>. - Merge RooHistFuncStreamer/RooHistPdfStreamer into RooHistStreamer<T> and RooHistFuncFactory/RooHistPdfFactory into RooHistFactory<T>; each pair differed only by the concrete RooFit type. RooJSONFactoryWSTool.cxx: - Remove fillSeqSanitizedName, which had no callers anywhere in ROOT. - Factor the "make a valid name but refuse to change the first character" block (exportCategory, exportCombinedData) into makeValidNameOrError(). - Collapse the repeated ofstream/ifstream open-and-error boilerplate in exportJSON/exportYML/importJSON/importYML. error() is [[noreturn]], so the trailing 'return false' statements were dead code. JSONFactories_HistFactory.cxx: - Remove a redundant mid-file block of #includes (<regex> was already included; the others were already used earlier in the translation unit). JSONIO.cxx: - Deduplicate removeImporters/removeExporters and printImporters/ printExporters into shared templated helpers.
1 parent d75a72f commit b763ff1

5 files changed

Lines changed: 72 additions & 186 deletions

File tree

roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ class RooJSONFactoryWSTool {
6363
static RooFit::Detail::JSONNode const *findNamedChild(RooFit::Detail::JSONNode const &node, std::string const &name);
6464

6565
static void fillSeq(RooFit::Detail::JSONNode &node, RooAbsCollection const &coll, size_t nMax = -1);
66-
static void fillSeqSanitizedName(RooFit::Detail::JSONNode &node, RooAbsCollection const &coll, size_t nMax = -1);
6766

6867
template <class T>
6968
T *request(const std::string &objname, const std::string &requestAuthor)

roofit/hs3/src/JSONFactories_HistFactory.cxx

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -765,12 +765,6 @@ std::vector<std::string> splitTopLevelProduct(const std::string &expr)
765765
return parts;
766766
}
767767

768-
#include <regex>
769-
#include <string>
770-
#include <cctype>
771-
#include <cstdlib>
772-
#include <iostream>
773-
774768
NormSys parseOverallModifierFormula(const std::string &s, RooFormulaVar *formula)
775769
{
776770
static const std::regex pattern(

roofit/hs3/src/JSONFactories_RooFitCore.cxx

Lines changed: 18 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -499,37 +499,6 @@ class RooExponentialFactory : public RooFit::JSONIO::Importer {
499499
}
500500
};
501501

502-
class RooLegacyExpPolyFactory : public RooFit::JSONIO::Importer {
503-
public:
504-
bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
505-
{
506-
std::string name(RooJSONFactoryWSTool::name(p));
507-
if (!p.has_child("coefficients")) {
508-
RooJSONFactoryWSTool::error("no coefficients given in '" + name + "'");
509-
}
510-
RooAbsReal *x = tool->requestArg<RooAbsReal>(p, "x");
511-
RooArgList coefs;
512-
int order = 0;
513-
int lowestOrder = 0;
514-
for (const auto &coef : p["coefficients"].children()) {
515-
// As long as the coefficients match the default coefficients in
516-
// RooFit, we don't have to instantiate RooFit objects but can
517-
// increase the lowestOrder flag.
518-
if (order == 0 && coef.val() == "1.0") {
519-
++lowestOrder;
520-
} else if (coefs.empty() && coef.val() == "0.0") {
521-
++lowestOrder;
522-
} else {
523-
coefs.add(*tool->request<RooAbsReal>(coef.val(), name));
524-
}
525-
++order;
526-
}
527-
528-
tool->wsEmplace<RooLegacyExpPoly>(name, *x, coefs, lowestOrder);
529-
return true;
530-
}
531-
};
532-
533502
class RooMultiVarGaussianFactory : public RooFit::JSONIO::Importer {
534503
public:
535504
bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
@@ -743,48 +712,22 @@ class RooRealSumFuncStreamer : public RooFit::JSONIO::Exporter {
743712
}
744713
};
745714

746-
class RooHistFuncStreamer : public RooFit::JSONIO::Exporter {
747-
public:
748-
std::string const &key() const override;
749-
bool exportObject(RooJSONFactoryWSTool *tool, const RooAbsArg *func, JSONNode &elem) const override
750-
{
751-
const RooHistFunc *hf = static_cast<const RooHistFunc *>(func);
752-
elem["type"] << key();
753-
RooDataHist const &dh = hf->dataHist();
754-
tool->exportHisto(*dh.get(), dh.numEntries(), dh.weightArray(), elem["data"].set_map());
755-
return true;
756-
}
757-
};
758-
759-
class RooHistFuncFactory : public RooFit::JSONIO::Importer {
760-
public:
761-
bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
762-
{
763-
std::string name(RooJSONFactoryWSTool::name(p));
764-
if (!p.has_child("data")) {
765-
RooJSONFactoryWSTool::error("function '" + name + "' is of histogram type, but does not define a 'data' key");
766-
}
767-
std::unique_ptr<RooDataHist> dataHist =
768-
RooJSONFactoryWSTool::readBinnedData(p["data"], name, RooJSONFactoryWSTool::readAxes(p["data"]));
769-
tool->wsEmplace<RooHistFunc>(name, *dataHist->get(), *dataHist);
770-
return true;
771-
}
772-
};
773-
774-
class RooHistPdfStreamer : public RooFit::JSONIO::Exporter {
715+
template <class RooArg_t>
716+
class RooHistStreamer : public RooFit::JSONIO::Exporter {
775717
public:
776718
std::string const &key() const override;
777719
bool exportObject(RooJSONFactoryWSTool *tool, const RooAbsArg *func, JSONNode &elem) const override
778720
{
779-
const RooHistPdf *hf = static_cast<const RooHistPdf *>(func);
721+
const RooArg_t *hf = static_cast<const RooArg_t *>(func);
780722
elem["type"] << key();
781723
RooDataHist const &dh = hf->dataHist();
782724
tool->exportHisto(*dh.get(), dh.numEntries(), dh.weightArray(), elem["data"].set_map());
783725
return true;
784726
}
785727
};
786728

787-
class RooHistPdfFactory : public RooFit::JSONIO::Importer {
729+
template <class RooArg_t>
730+
class RooHistFactory : public RooFit::JSONIO::Importer {
788731
public:
789732
bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
790733
{
@@ -794,7 +737,7 @@ class RooHistPdfFactory : public RooFit::JSONIO::Importer {
794737
}
795738
std::unique_ptr<RooDataHist> dataHist =
796739
RooJSONFactoryWSTool::readBinnedData(p["data"], name, RooJSONFactoryWSTool::readAxes(p["data"]));
797-
tool->wsEmplace<RooHistPdf>(name, *dataHist->get(), *dataHist);
740+
tool->wsEmplace<RooArg_t>(name, *dataHist->get(), *dataHist);
798741
return true;
799742
}
800743
};
@@ -893,17 +836,6 @@ class RooPolynomialStreamer : public RooFit::JSONIO::Exporter {
893836
}
894837
};
895838

896-
class RooLegacyExpPolyStreamer : public RooFit::JSONIO::Exporter {
897-
public:
898-
std::string const &key() const override;
899-
bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
900-
{
901-
elem["type"] << key();
902-
writePolynomialBody(static_cast<const RooLegacyExpPoly *>(func), elem);
903-
return true;
904-
}
905-
};
906-
907839
class RooPoissonStreamer : public RooFit::JSONIO::Exporter {
908840
public:
909841
std::string const &key() const override;
@@ -1248,14 +1180,17 @@ DEFINE_EXPORTER_KEY(RooAddPdfStreamer<RooAddModel>, "mixture_model");
12481180
DEFINE_EXPORTER_KEY(RooBinSamplingPdfStreamer, "binsampling");
12491181
DEFINE_EXPORTER_KEY(RooWrapperPdfStreamer, "density_function_dist");
12501182
DEFINE_EXPORTER_KEY(RooBinWidthFunctionStreamer, "binwidth");
1251-
DEFINE_EXPORTER_KEY(RooLegacyExpPolyStreamer, "legacy_exp_poly_dist");
1183+
template <>
1184+
DEFINE_EXPORTER_KEY(RooPolynomialStreamer<RooLegacyExpPoly>, "legacy_exp_poly_dist");
12521185
DEFINE_EXPORTER_KEY(RooExponentialStreamer, "exponential_dist");
12531186
template <>
12541187
DEFINE_EXPORTER_KEY(RooFormulaArgStreamer<RooFormulaVar>, "generic_function");
12551188
template <>
12561189
DEFINE_EXPORTER_KEY(RooFormulaArgStreamer<RooGenericPdf>, "generic_dist");
1257-
DEFINE_EXPORTER_KEY(RooHistFuncStreamer, "histogram");
1258-
DEFINE_EXPORTER_KEY(RooHistPdfStreamer, "histogram_dist");
1190+
template <>
1191+
DEFINE_EXPORTER_KEY(RooHistStreamer<RooHistFunc>, "histogram");
1192+
template <>
1193+
DEFINE_EXPORTER_KEY(RooHistStreamer<RooHistPdf>, "histogram_dist");
12591194
DEFINE_EXPORTER_KEY(RooLogNormalStreamer, "lognormal_dist");
12601195
DEFINE_EXPORTER_KEY(RooMultiVarGaussianStreamer, "multivariate_normal_dist");
12611196
DEFINE_EXPORTER_KEY(RooPoissonStreamer, "poisson_dist");
@@ -1292,12 +1227,12 @@ STATIC_EXECUTE([]() {
12921227
registerImporter<RooAddModelFactory>("mixture_model", false);
12931228
registerImporter<RooBinSamplingPdfFactory>("binsampling_dist", false);
12941229
registerImporter<RooBinWidthFunctionFactory>("binwidth", false);
1295-
registerImporter<RooLegacyExpPolyFactory>("legacy_exp_poly_dist", false);
1230+
registerImporter<RooPolynomialFactory<RooLegacyExpPoly>>("legacy_exp_poly_dist", false);
12961231
registerImporter<RooExponentialFactory>("exponential_dist", false);
12971232
registerImporter<RooFormulaArgFactory<RooFormulaVar>>("generic_function", false);
12981233
registerImporter<RooFormulaArgFactory<RooGenericPdf>>("generic_dist", false);
1299-
registerImporter<RooHistFuncFactory>("histogram", false);
1300-
registerImporter<RooHistPdfFactory>("histogram_dist", false);
1234+
registerImporter<RooHistFactory<RooHistFunc>>("histogram", false);
1235+
registerImporter<RooHistFactory<RooHistPdf>>("histogram_dist", false);
13011236
registerImporter<RooLogNormalFactory>("lognormal_dist", false);
13021237
registerImporter<RooMultiVarGaussianFactory>("multivariate_normal_dist", false);
13031238
registerImporter<RooPoissonFactory>("poisson_dist", false);
@@ -1320,12 +1255,12 @@ STATIC_EXECUTE([]() {
13201255
registerExporter<RooAddPdfStreamer<RooAddModel>>(RooAddModel::Class(), false);
13211256
registerExporter<RooBinSamplingPdfStreamer>(RooBinSamplingPdf::Class(), false);
13221257
registerExporter<RooBinWidthFunctionStreamer>(RooBinWidthFunction::Class(), false);
1323-
registerExporter<RooLegacyExpPolyStreamer>(RooLegacyExpPoly::Class(), false);
1258+
registerExporter<RooPolynomialStreamer<RooLegacyExpPoly>>(RooLegacyExpPoly::Class(), false);
13241259
registerExporter<RooExponentialStreamer>(RooExponential::Class(), false);
13251260
registerExporter<RooFormulaArgStreamer<RooFormulaVar>>(RooFormulaVar::Class(), false);
13261261
registerExporter<RooFormulaArgStreamer<RooGenericPdf>>(RooGenericPdf::Class(), false);
1327-
registerExporter<RooHistFuncStreamer>(RooHistFunc::Class(), false);
1328-
registerExporter<RooHistPdfStreamer>(RooHistPdf::Class(), false);
1262+
registerExporter<RooHistStreamer<RooHistFunc>>(RooHistFunc::Class(), false);
1263+
registerExporter<RooHistStreamer<RooHistPdf>>(RooHistPdf::Class(), false);
13291264
registerExporter<RooLogNormalStreamer>(RooLognormal::Class(), false);
13301265
registerExporter<RooMultiVarGaussianStreamer>(RooMultiVarGaussian::Class(), false);
13311266
registerExporter<RooPoissonStreamer>(RooPoisson::Class(), false);

roofit/hs3/src/JSONIO.cxx

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -147,26 +147,13 @@ bool registerExporter(const std::string &key, std::unique_ptr<const Exporter> f,
147147
return true;
148148
}
149149

150-
int removeImporters(const std::string &needle)
151-
{
152-
int n = 0;
153-
for (auto &element : importers()) {
154-
for (size_t i = element.second.size(); i > 0; --i) {
155-
auto *imp = element.second[i - 1].get();
156-
std::string name(typeid(*imp).name());
157-
if (name.find(needle) != std::string::npos) {
158-
element.second.erase(element.second.begin() + i - 1);
159-
++n;
160-
}
161-
}
162-
}
163-
return n;
164-
}
150+
namespace {
165151

166-
int removeExporters(const std::string &needle)
152+
template <class Map>
153+
int removeByTypeName(Map &map, const std::string &needle)
167154
{
168155
int n = 0;
169-
for (auto &element : exporters()) {
156+
for (auto &element : map) {
170157
for (size_t i = element.second.size(); i > 0; --i) {
171158
auto *imp = element.second[i - 1].get();
172159
std::string name(typeid(*imp).name());
@@ -179,25 +166,37 @@ int removeExporters(const std::string &needle)
179166
return n;
180167
}
181168

182-
void printImporters()
169+
template <class Map, class KeyPrinter>
170+
void printByTypeName(Map &map, KeyPrinter printKey)
183171
{
184-
for (const auto &x : importers()) {
172+
for (const auto &x : map) {
185173
for (const auto &ePtr : x.second) {
186174
// Passing *e directory to typeid results in clang warnings.
187175
auto const &e = *ePtr;
188-
std::cout << x.first << "\t" << typeid(e).name() << std::endl;
176+
std::cout << printKey(x.first) << "\t" << typeid(e).name() << std::endl;
189177
}
190178
}
191179
}
180+
181+
} // namespace
182+
183+
int removeImporters(const std::string &needle)
184+
{
185+
return removeByTypeName(importers(), needle);
186+
}
187+
188+
int removeExporters(const std::string &needle)
189+
{
190+
return removeByTypeName(exporters(), needle);
191+
}
192+
193+
void printImporters()
194+
{
195+
printByTypeName(importers(), [](auto const &key) { return key; });
196+
}
192197
void printExporters()
193198
{
194-
for (const auto &x : exporters()) {
195-
for (const auto &ePtr : x.second) {
196-
// Passing *e directory to typeid results in clang warnings.
197-
auto const &e = *ePtr;
198-
std::cout << x.first->GetName() << "\t" << typeid(e).name() << std::endl;
199-
}
200-
}
199+
printByTypeName(exporters(), [](auto const &key) { return key->GetName(); });
201200
}
202201

203202
void loadFactoryExpressions(const std::string &fname)

0 commit comments

Comments
 (0)