Skip to content

Commit 8a1fb82

Browse files
committed
[RF][HS3] Add Workspace => JSON => Workspace => JSON check to tests
Make sure that objects in a list are always exported to JOSN alphabeticall, so the JSON 1 vs. JSON 2 comparision doesn't fail.
1 parent abc5385 commit 8a1fb82

File tree

3 files changed

+45
-17
lines changed

3 files changed

+45
-17
lines changed

roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,20 @@ class RooJSONFactoryWSTool {
194194

195195
void exportObject(RooAbsArg const &func, std::set<std::string> &exportedObjectNames);
196196

197+
// To export multiple objects sorted alphabetically
198+
template <class T>
199+
void exportObjects(T const &args, std::set<std::string> &exportedObjectNames)
200+
{
201+
RooArgSet argSet;
202+
for (RooAbsArg const *arg : args) {
203+
argSet.add(*arg);
204+
}
205+
argSet.sort();
206+
for (RooAbsArg *arg : argSet) {
207+
exportObject(*arg, exportedObjectNames);
208+
}
209+
}
210+
197211
void exportData(RooAbsData const &data);
198212
RooJSONFactoryWSTool::CombinedData exportCombinedData(RooAbsData const &data);
199213

roofit/hs3/src/RooJSONFactoryWSTool.cxx

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -606,8 +606,7 @@ void importAnalysis(const JSONNode &rootnode, const JSONNode &analysisNode, cons
606606
std::vector<std::string> nllDistNames = valsToStringVec((*nllNode)["distributions"]);
607607
RooArgSet extConstraints;
608608
for (auto &nameNode : (*nllNode)["aux_distributions"].children()) {
609-
RooAbsArg *extConstraint = workspace.arg(nameNode.val());
610-
if (extConstraint) {
609+
if (RooAbsArg *extConstraint = workspace.arg(nameNode.val())) {
611610
extConstraints.add(*extConstraint);
612611
}
613612
}
@@ -989,9 +988,7 @@ void RooJSONFactoryWSTool::exportObject(RooAbsArg const &func, std::set<std::str
989988
if (auto simPdf = dynamic_cast<RooSimultaneous const *>(&func)) {
990989
// RooSimultaneous is not used in the HS3 standard, we only export the
991990
// dependents and some ROOT internal information.
992-
for (RooAbsArg *s : func.servers()) {
993-
this->exportObject(*s, exportedObjectNames);
994-
}
991+
exportObjects(func.servers(), exportedObjectNames);
995992

996993
std::vector<std::string> channelNames;
997994
for (auto const &item : simPdf->indexCat()) {
@@ -1040,13 +1037,9 @@ void RooJSONFactoryWSTool::exportObject(RooAbsArg const &func, std::set<std::str
10401037
continue;
10411038
}
10421039
if (exp->autoExportDependants()) {
1043-
for (RooAbsArg *s : func.servers()) {
1044-
this->exportObject(*s, exportedObjectNames);
1045-
}
1040+
exportObjects(func.servers(), exportedObjectNames);
10461041
} else {
1047-
for (RooAbsArg const *s : _serversToExport) {
1048-
this->exportObject(*s, exportedObjectNames);
1049-
}
1042+
exportObjects(_serversToExport, exportedObjectNames);
10501043
}
10511044
return;
10521045
}
@@ -1758,9 +1751,7 @@ void RooJSONFactoryWSTool::exportAllObjects(JSONNode &n)
17581751
}
17591752
sortByName(allpdfs);
17601753
std::set<std::string> exportedObjectNames;
1761-
for (RooAbsPdf *p : allpdfs) {
1762-
this->exportObject(*p, exportedObjectNames);
1763-
}
1754+
exportObjects(allpdfs, exportedObjectNames);
17641755

17651756
// export attributes of all objects
17661757
for (RooAbsArg *arg : _workspace.components()) {

roofit/hs3/test/testRooFitHS3.cxx

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
namespace {
3030

3131
// If the JSON files should be written out for debugging purpose.
32-
const bool writeJsonFiles = true;
32+
const bool writeJsonFiles = false;
3333

3434
// Validate the JSON IO for a given RooAbsReal in a RooWorkspace. The workspace
3535
// will be written out and read back, and then the values of the old and new
@@ -39,10 +39,33 @@ int validate(RooWorkspace &ws1, std::string const &argName, bool exact = true)
3939
{
4040
RooWorkspace ws2;
4141

42+
const std::string json1 = RooJSONFactoryWSTool{ws1}.exportJSONtoString();
43+
RooJSONFactoryWSTool{ws2}.importJSONfromString(json1);
44+
45+
// Export the re-imported workspace back to JSON, and compare the first JSON
46+
// with the second one. They should be identical.
47+
const std::string json2 = RooJSONFactoryWSTool{ws2}.exportJSONtoString();
48+
EXPECT_EQ(json2, json1) << argName;
49+
4250
if (writeJsonFiles) {
43-
RooJSONFactoryWSTool{ws1}.exportJSON(argName + ".json");
51+
RooJSONFactoryWSTool{ws1}.exportJSON(argName + "_1.json");
52+
RooJSONFactoryWSTool{ws2}.exportJSON(argName + "_2.json");
53+
}
54+
55+
// It would be nice to do a similar closure check for the original and for
56+
// the re-imported workspace. However, there is no way to compare workspaces
57+
// for equality. But we can still check that the objects in the workspace
58+
// have at least the same name.
59+
RooArgSet comps1 = ws1.components();
60+
RooArgSet comps2 = ws2.components();
61+
EXPECT_EQ(comps2.size(), comps1.size());
62+
63+
comps1.sort();
64+
comps2.sort();
65+
66+
for (std::size_t i = 0; i < comps1.size(); ++i) {
67+
EXPECT_STREQ(comps1[i]->GetName(), comps2[i]->GetName());
4468
}
45-
RooJSONFactoryWSTool{ws2}.importJSONfromString(RooJSONFactoryWSTool{ws1}.exportJSONtoString());
4669

4770
RooRealVar &x1 = *ws1.var("x");
4871
RooRealVar &x2 = *ws2.var("x");

0 commit comments

Comments
 (0)