Skip to content

Commit 9f2631c

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 8e50c5f commit 9f2631c

5 files changed

Lines changed: 73 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
@@ -744,48 +713,22 @@ class RooRealSumFuncStreamer : public RooFit::JSONIO::Exporter {
744713
}
745714
};
746715

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

788-
class RooHistPdfFactory : public RooFit::JSONIO::Importer {
730+
template <class RooArg_t>
731+
class RooHistFactory : public RooFit::JSONIO::Importer {
789732
public:
790733
bool importArg(RooJSONFactoryWSTool *tool, const JSONNode &p) const override
791734
{
@@ -795,7 +738,7 @@ class RooHistPdfFactory : public RooFit::JSONIO::Importer {
795738
}
796739
std::unique_ptr<RooDataHist> dataHist =
797740
RooJSONFactoryWSTool::readBinnedData(p["data"], name, RooJSONFactoryWSTool::readAxes(p["data"]));
798-
tool->wsEmplace<RooHistPdf>(name, *dataHist->get(), *dataHist);
741+
tool->wsEmplace<RooArg_t>(name, *dataHist->get(), *dataHist);
799742
return true;
800743
}
801744
};
@@ -894,17 +837,6 @@ class RooPolynomialStreamer : public RooFit::JSONIO::Exporter {
894837
}
895838
};
896839

897-
class RooLegacyExpPolyStreamer : public RooFit::JSONIO::Exporter {
898-
public:
899-
std::string const &key() const override;
900-
bool exportObject(RooJSONFactoryWSTool *, const RooAbsArg *func, JSONNode &elem) const override
901-
{
902-
elem["type"] << key();
903-
writePolynomialBody(static_cast<const RooLegacyExpPoly *>(func), elem);
904-
return true;
905-
}
906-
};
907-
908840
class RooPoissonStreamer : public RooFit::JSONIO::Exporter {
909841
public:
910842
std::string const &key() const override;
@@ -1249,14 +1181,17 @@ DEFINE_EXPORTER_KEY(RooAddPdfStreamer<RooAddModel>, "mixture_model");
12491181
DEFINE_EXPORTER_KEY(RooBinSamplingPdfStreamer, "binsampling");
12501182
DEFINE_EXPORTER_KEY(RooWrapperPdfStreamer, "density_function_dist");
12511183
DEFINE_EXPORTER_KEY(RooBinWidthFunctionStreamer, "binwidth");
1252-
DEFINE_EXPORTER_KEY(RooLegacyExpPolyStreamer, "legacy_exp_poly_dist");
1184+
template <>
1185+
DEFINE_EXPORTER_KEY(RooPolynomialStreamer<RooLegacyExpPoly>, "legacy_exp_poly_dist");
12531186
DEFINE_EXPORTER_KEY(RooExponentialStreamer, "exponential_dist");
12541187
template <>
12551188
DEFINE_EXPORTER_KEY(RooFormulaArgStreamer<RooFormulaVar>, "generic_function");
12561189
template <>
12571190
DEFINE_EXPORTER_KEY(RooFormulaArgStreamer<RooGenericPdf>, "generic_dist");
1258-
DEFINE_EXPORTER_KEY(RooHistFuncStreamer, "histogram");
1259-
DEFINE_EXPORTER_KEY(RooHistPdfStreamer, "histogram_dist");
1191+
template <>
1192+
DEFINE_EXPORTER_KEY(RooHistStreamer<RooHistFunc>, "histogram");
1193+
template <>
1194+
DEFINE_EXPORTER_KEY(RooHistStreamer<RooHistPdf>, "histogram_dist");
12601195
DEFINE_EXPORTER_KEY(RooLogNormalStreamer, "lognormal_dist");
12611196
DEFINE_EXPORTER_KEY(RooMultiVarGaussianStreamer, "multivariate_normal_dist");
12621197
DEFINE_EXPORTER_KEY(RooPoissonStreamer, "poisson_dist");
@@ -1293,12 +1228,12 @@ STATIC_EXECUTE([]() {
12931228
registerImporter<RooAddModelFactory>("mixture_model", false);
12941229
registerImporter<RooBinSamplingPdfFactory>("binsampling_dist", false);
12951230
registerImporter<RooBinWidthFunctionFactory>("binwidth", false);
1296-
registerImporter<RooLegacyExpPolyFactory>("legacy_exp_poly_dist", false);
1231+
registerImporter<RooPolynomialFactory<RooLegacyExpPoly>>("legacy_exp_poly_dist", false);
12971232
registerImporter<RooExponentialFactory>("exponential_dist", false);
12981233
registerImporter<RooFormulaArgFactory<RooFormulaVar>>("generic_function", false);
12991234
registerImporter<RooFormulaArgFactory<RooGenericPdf>>("generic_dist", false);
1300-
registerImporter<RooHistFuncFactory>("histogram", false);
1301-
registerImporter<RooHistPdfFactory>("histogram_dist", false);
1235+
registerImporter<RooHistFactory<RooHistFunc>>("histogram", false);
1236+
registerImporter<RooHistFactory<RooHistPdf>>("histogram_dist", false);
13021237
registerImporter<RooLogNormalFactory>("lognormal_dist", false);
13031238
registerImporter<RooMultiVarGaussianFactory>("multivariate_normal_dist", false);
13041239
registerImporter<RooPoissonFactory>("poisson_dist", false);
@@ -1321,12 +1256,12 @@ STATIC_EXECUTE([]() {
13211256
registerExporter<RooAddPdfStreamer<RooAddModel>>(RooAddModel::Class(), false);
13221257
registerExporter<RooBinSamplingPdfStreamer>(RooBinSamplingPdf::Class(), false);
13231258
registerExporter<RooBinWidthFunctionStreamer>(RooBinWidthFunction::Class(), false);
1324-
registerExporter<RooLegacyExpPolyStreamer>(RooLegacyExpPoly::Class(), false);
1259+
registerExporter<RooPolynomialStreamer<RooLegacyExpPoly>>(RooLegacyExpPoly::Class(), false);
13251260
registerExporter<RooExponentialStreamer>(RooExponential::Class(), false);
13261261
registerExporter<RooFormulaArgStreamer<RooFormulaVar>>(RooFormulaVar::Class(), false);
13271262
registerExporter<RooFormulaArgStreamer<RooGenericPdf>>(RooGenericPdf::Class(), false);
1328-
registerExporter<RooHistFuncStreamer>(RooHistFunc::Class(), false);
1329-
registerExporter<RooHistPdfStreamer>(RooHistPdf::Class(), false);
1263+
registerExporter<RooHistStreamer<RooHistFunc>>(RooHistFunc::Class(), false);
1264+
registerExporter<RooHistStreamer<RooHistPdf>>(RooHistPdf::Class(), false);
13301265
registerExporter<RooLogNormalStreamer>(RooLognormal::Class(), false);
13311266
registerExporter<RooMultiVarGaussianStreamer>(RooMultiVarGaussian::Class(), false);
13321267
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)