Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooJSONFactoryWSTool.h
Go to the documentation of this file.
1/*
2 * Project: RooFit
3 * Authors:
4 * Carsten D. Burgard, DESY/ATLAS, Dec 2021
5 *
6 * Copyright (c) 2022, CERN
7 *
8 * Redistribution and use in source and binary forms,
9 * with or without modification, are permitted according to the terms
10 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
11 */
12
13#ifndef RooFitHS3_RooJSONFactoryWSTool_h
14#define RooFitHS3_RooJSONFactoryWSTool_h
15
17
18#include <RooArgList.h>
19#include <RooArgSet.h>
20#include <RooGlobalFunc.h>
21#include <RooWorkspace.h>
22
23#include <map>
24#include <stdexcept>
25#include <set>
26#include <vector>
27
29
30namespace RooFit {
31namespace HS3 {
32struct Distribution;
33struct HistFactoryDist;
34struct ParameterPoint;
35struct ParameterValue;
36struct ToolExportState;
37struct ToolImportState;
38template <class Tag>
39struct Ref;
42 std::vector<DistributionRef> channelConstraints);
43} // namespace HS3
44} // namespace RooFit
45namespace RooStats {
46class ModelConfig;
47}
48class RooRealVar;
49
51public:
52 /// Named objects are always stored in lists, as the HS3 standard requires. Kept for backwards compatibility.
53 static constexpr bool useListsInsteadOfDicts = true;
54
55 struct Config {
57 bool allowSanitizeNames = true;
58 /// Identify constant factors of HistFactory samples that are used like the inverse bin width of HistFactory
59 /// before ROOT 6.26 by their structure, and don't write them, since `histfactory_dist` implies them. Turn this
60 /// off if a workspace has such factors that are not meant as bin widths: they are then written as normfactors.
62 };
63
64 static Config &config();
65
66 static RooWorkspace sanitizeWS(const RooWorkspace &ws);
67 static RooWorkspace cleanWS(const RooWorkspace &ws, bool onlyModelConfig = false);
68
69 struct CombinedData {
70 std::string name;
71 std::map<std::string, std::string> components;
72 };
73
75
77
78 static std::string name(const RooFit::Detail::JSONNode &n);
79 static bool isValidName(const std::string &str);
80 static bool testValidName(const std::string &str, bool forcError);
81 static std::string sanitizeName(const std::string str);
83
85 static RooFit::Detail::JSONNode const *findNamedChild(RooFit::Detail::JSONNode const &node, std::string const &name);
86
87 static void fillSeq(RooFit::Detail::JSONNode &node, RooAbsCollection const &coll, size_t nMax = -1);
88
89 template <class T>
90 T *request(const std::string &objname, const std::string &requestAuthor)
91 {
92 if (T *out = requestImpl<T>(objname)) {
93 return out;
94 }
95 throw DependencyMissingError(requestAuthor, objname, T::Class()->GetName());
96 }
97
98 template <class T>
99 T *requestArg(const RooFit::Detail::JSONNode &node, const std::string &key)
100 {
101 std::string requestAuthor(RooJSONFactoryWSTool::name(node));
102 if (!node.has_child(key)) {
103 RooJSONFactoryWSTool::error("no \"" + key + "\" given in \"" + requestAuthor + "\"");
104 }
105 return request<T>(node[key].val(), requestAuthor);
106 }
107
108 template <class T, class Coll_t>
109 Coll_t requestCollection(const RooFit::Detail::JSONNode &node, const std::string &seqName)
110 {
111 std::string requestAuthor(RooJSONFactoryWSTool::name(node));
112 if (!node.has_child(seqName)) {
113 RooJSONFactoryWSTool::error("no \"" + seqName + "\" given in \"" + requestAuthor + "\"");
114 }
115 if (!node[seqName].is_seq()) {
116 RooJSONFactoryWSTool::error("\"" + seqName + "\" in \"" + requestAuthor + "\" is not a sequence");
117 }
118
119 Coll_t out;
120 for (const auto &elem : node[seqName].children()) {
121 out.add(*request<T>(elem.val(), requestAuthor));
122 }
123 return out;
124 }
125
126 template <class T>
127 RooArgSet requestArgSet(const RooFit::Detail::JSONNode &node, const std::string &seqName)
128 {
129 return requestCollection<T, RooArgSet>(node, seqName);
130 }
131
132 template <class T>
133 RooArgList requestArgList(const RooFit::Detail::JSONNode &node, const std::string &seqName)
134 {
135 return requestCollection<T, RooArgList>(node, seqName);
136 }
137
139
140 template <class Obj_t>
141 Obj_t &wsImport(Obj_t const &obj)
142 {
144 return *static_cast<Obj_t *>(_workspace.obj(obj.GetName()));
145 }
146
147 template <class Obj_t, typename... Args_t>
148 Obj_t &wsEmplace(RooStringView name, Args_t &&...args)
149 {
150 return wsImport(Obj_t(name.c_str(), name.c_str(), std::forward<Args_t>(args)...));
151 }
152
153 [[noreturn]] static void error(const char *s);
154 [[noreturn]] inline static void error(const std::string &s) { error(s.c_str()); }
155 static std::ostream &warning(const std::string &s);
156
157 static RooArgSet readAxes(const RooFit::Detail::JSONNode &node);
158 static std::unique_ptr<RooDataHist>
159 readBinnedData(const RooFit::Detail::JSONNode &n, const std::string &namecomp, RooArgSet const &vars);
160
161 bool importJSON(std::string const &filename);
162 bool importJSON(std::istream &os);
163 bool exportJSON(std::string const &fileName);
164 bool exportJSON(std::ostream &os);
165
166 std::string exportJSONtoString();
167 bool importJSONfromString(const std::string &s);
168 void importJSONElement(const std::string &name, const std::string &jsonString);
170
171 void importFunction(const RooFit::Detail::JSONNode &p, bool importAllDependants);
172 void importFunction(const std::string &jsonString, bool importAllDependants);
173
174 static std::unique_ptr<RooFit::Detail::JSONTree> createNewJSONTree();
175
177
178 // error handling helpers
179 class DependencyMissingError : public std::runtime_error {
180 std::string _parent, _child, _class;
181
182 public:
183 DependencyMissingError(const std::string &p, const std::string &c, const std::string &classname)
184 : std::runtime_error("object '" + p + "' is missing dependency '" + c + "' of type '" + classname + "'"),
185 _parent(p),
186 _child(c),
188 {
189 }
190 const std::string &parent() const { return _parent; }
191 const std::string &child() const { return _child; }
192 const std::string &classname() const { return _class; }
193 };
194
195 template <typename... Keys_t>
197 {
198 return node.get("misc", "ROOT_internal", keys...);
199 }
200
201 static void exportAxis(RooFit::Detail::JSONNode &obsNode, RooRealVar const &var);
202
203 static void
204 exportHisto(RooArgSet const &vars, std::size_t n, double const *contents, RooFit::Detail::JSONNode &output);
205
206 static void exportArray(std::size_t n, double const *contents, RooFit::Detail::JSONNode &output);
207
209
210 void queueExport(RooAbsArg const &arg) { _serversToExport.push_back(&arg); }
212 {
213 _serversToExport.push_back(arg);
214 _serversToDelete.push_back(arg);
215 }
216
217 std::string exportTransformed(const RooAbsReal *original, const std::string &suffix, const std::string &formula);
218
219 void setAttribute(const std::string &obj, const std::string &attrib);
220 bool hasAttribute(const std::string &obj, const std::string &attrib);
221 std::string getStringAttribute(const std::string &obj, const std::string &attrib);
222 void setStringAttribute(const std::string &obj, const std::string &attrib, const std::string &value);
223
224 /// The "hs3_version" of the document that is currently being imported, or an empty string outside of an import.
225 std::string const &hs3VersionInput() const { return _hs3VersionInput; }
226
227private:
228 template <class T>
229 T *requestImpl(const std::string &objname);
230 void exportObject(RooAbsArg const &func, std::set<std::string> &exportedObjectNames);
231
232 // To export multiple objects sorted alphabetically
233 template <class T>
234 void exportObjects(T const &args, std::set<std::string> &exportedObjectNames)
235 {
236 RooArgSet argSet;
237 for (RooAbsArg const *arg : args) {
238 argSet.add(*arg);
239 }
240 argSet.sort();
241 for (RooAbsArg *arg : argSet) {
242 exportObject(*arg, exportedObjectNames);
243 }
244 }
245
246 void exportData(RooAbsData const &data);
248
250 void importDistribution(RooFit::HS3::Distribution const &distribution);
251
253 void warnIfFreeWithoutDomain(RooRealVar const &var);
255
256 void exportVariable(const RooAbsArg *v, RooFit::HS3::ParameterPoint &point, bool storeConstant);
257 void exportVariables(const RooArgSet &allElems, RooFit::HS3::ParameterPoint &point, bool storeConstant);
258
260
262 const std::vector<RooJSONFactoryWSTool::CombinedData> &combined,
263 const std::vector<RooAbsData *> &single);
264
265 void exportSingleModelConfig(RooStats::ModelConfig const &mc, std::string const &analysisName,
266 std::map<std::string, std::string> const *dataComponents);
267
269 std::vector<RooFit::HS3::DistributionRef> channelConstraints);
270
271 // member variables
272 std::string _hs3VersionInput;
274
275 // objects to represent intermediate information
276 std::unique_ptr<RooFit::HS3::ToolImportState> _import;
277 std::unique_ptr<RooFit::HS3::ToolExportState> _export;
278 std::vector<RooAbsArg const *> _serversToExport;
279 std::vector<RooAbsArg const *> _serversToDelete;
280
281 // The objects that are currently being imported, innermost last, to detect circular dependencies.
282 std::vector<std::string> _importStack;
283};
284#endif
#define c(i)
Definition RSha256.hxx:101
winID h TVirtualViewer3D TVirtualGLPainter p
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 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 value
char name[80]
Definition TGX11.cxx:142
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:77
A space to attach TBranches.
Abstract container object that can hold multiple RooAbsArg objects.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
void sort(bool reverse=false)
Sort collection using std::sort and name comparison.
Abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:55
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:63
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:22
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
JSONNode & get(std::string const &key)
bool has_child(std::string const &) const
DependencyMissingError(const std::string &p, const std::string &c, const std::string &classname)
When using RooFit, statistical models can be conveniently handled and stored as a RooWorkspace.
static constexpr bool useListsInsteadOfDicts
Named objects are always stored in lists, as the HS3 standard requires. Kept for backwards compatibil...
static void rebuildModelConfigInWorkspace(RooStats::ModelConfig *mc, RooWorkspace &ws)
std::string getStringAttribute(const std::string &obj, const std::string &attrib)
static void fillSeq(RooFit::Detail::JSONNode &node, RooAbsCollection const &coll, size_t nMax=-1)
void exportObjects(T const &args, std::set< std::string > &exportedObjectNames)
void exportCategory(RooAbsCategory const &cat, RooFit::Detail::JSONNode &node)
Export a RooAbsCategory object to a JSONNode.
T * requestArg(const RooFit::Detail::JSONNode &node, const std::string &key)
RooJSONFactoryWSTool(RooWorkspace &ws)
T * request(const std::string &objname, const std::string &requestAuthor)
void exportData(RooAbsData const &data)
bool hasAttribute(const std::string &obj, const std::string &attrib)
bool importJSON(std::string const &filename)
Imports a JSON file from the given filename to the workspace.
Coll_t requestCollection(const RooFit::Detail::JSONNode &node, const std::string &seqName)
Obj_t & wsImport(Obj_t const &obj)
std::vector< std::string > _importStack
static std::unique_ptr< RooDataHist > readBinnedData(const RooFit::Detail::JSONNode &n, const std::string &namecomp, RooArgSet const &vars)
Read binned data from the JSONNode and create a RooDataHist object.
static RooFit::Detail::JSONNode & appendNamedChild(RooFit::Detail::JSONNode &node, std::string const &name)
void importDistribution(RooFit::HS3::Distribution const &distribution)
static RooFit::Detail::JSONNode & getRooFitInternal(RooFit::Detail::JSONNode &node, Keys_t const &...keys)
static void exportArray(std::size_t n, double const *contents, RooFit::Detail::JSONNode &output)
Export an array of doubles to a JSONNode.
static bool testValidName(const std::string &str, bool forcError)
static void exportHisto(RooArgSet const &vars, std::size_t n, double const *contents, RooFit::Detail::JSONNode &output)
Export histogram data to a JSONNode.
void exportModelConfig(RooStats::ModelConfig const &mc, const std::vector< RooJSONFactoryWSTool::CombinedData > &combined, const std::vector< RooAbsData * > &single)
std::vector< RooAbsArg const * > _serversToDelete
void queueExportTemporary(RooAbsArg *arg)
static std::unique_ptr< RooFit::Detail::JSONTree > createNewJSONTree()
Create a new JSON tree with version information.
void queueExport(RooAbsArg const &arg)
std::string const & hs3VersionInput() const
The "hs3_version" of the document that is currently being imported, or an empty string outside of an ...
std::unique_ptr< RooFit::HS3::ToolExportState > _export
RooArgSet requestArgSet(const RooFit::Detail::JSONNode &node, const std::string &seqName)
RooJSONFactoryWSTool::CombinedData exportCombinedData(RooAbsData const &data)
std::string exportJSONtoString()
Export the workspace to a JSON string.
RooArgList requestArgList(const RooFit::Detail::JSONNode &node, const std::string &seqName)
static RooWorkspace cleanWS(const RooWorkspace &ws, bool onlyModelConfig=false)
void exportVariable(const RooAbsArg *v, RooFit::HS3::ParameterPoint &point, bool storeConstant)
std::string exportTransformed(const RooAbsReal *original, const std::string &suffix, const std::string &formula)
static bool isValidName(const std::string &str)
Check if a string is a valid name.
void importVariable(RooFit::HS3::ParameterValue const &p)
T * requestImpl(const std::string &objname)
void importDependants(const RooFit::Detail::JSONNode &n)
static void exportAxis(RooFit::Detail::JSONNode &obsNode, RooRealVar const &var)
Export the name and binning of a RooRealVar to a JSONNode.
void importJSONElement(const std::string &name, const std::string &jsonString)
static RooWorkspace sanitizeWS(const RooWorkspace &ws)
static void error(const char *s)
Writes an error message to the RooFit message service and throws a runtime_error.
void setAttribute(const std::string &obj, const std::string &attrib)
void importFunction(const RooFit::Detail::JSONNode &p, bool importAllDependants)
Import a function from the JSONNode into the workspace.
bool importJSONfromString(const std::string &s)
Import the workspace from a JSON string.
std::unique_ptr< RooFit::HS3::ToolImportState > _import
void exportObject(RooAbsArg const &func, std::set< std::string > &exportedObjectNames)
void exportSingleModelConfig(RooStats::ModelConfig const &mc, std::string const &analysisName, std::map< std::string, std::string > const *dataComponents)
static RooFit::Detail::JSONNode & makeVariablesNode(RooFit::Detail::JSONNode &rootNode)
Obj_t & wsEmplace(RooStringView name, Args_t &&...args)
static std::string sanitizeName(const std::string str)
Cleans up names to the HS3 standard.
static void error(const std::string &s)
void exportVariables(const RooArgSet &allElems, RooFit::HS3::ParameterPoint &point, bool storeConstant)
static std::string name(const RooFit::Detail::JSONNode &n)
void exportAllObjects(RooFit::Detail::JSONNode &n)
bool exportJSON(std::string const &fileName)
Export the workspace to JSON format and write to the specified file.
static RooFit::Detail::JSONNode const * findNamedChild(RooFit::Detail::JSONNode const &node, std::string const &name)
void importAllNodes(RooFit::Detail::JSONNode &n)
void warnIfFreeWithoutDomain(RooRealVar const &var)
void setStringAttribute(const std::string &obj, const std::string &attrib, const std::string &value)
std::vector< RooAbsArg const * > _serversToExport
static std::ostream & warning(const std::string &s)
Writes a warning message to the RooFit message service.
static RooArgSet readAxes(const RooFit::Detail::JSONNode &node)
Read axes from the JSONNode and create a RooArgSet representing them.
void importVariableElement(const RooFit::Detail::JSONNode &n)
Variable that can be changed from the outside.
Definition RooRealVar.h:37
< A class that holds configuration information for a model using a workspace as a store
Definition ModelConfig.h:34
The RooStringView is a wrapper around a C-style string that can also be constructed from a std::strin...
Persistable container for RooFit projects.
TObject * obj(RooStringView name) const
Return any type of object (RooAbsArg, RooAbsData or generic object) with given name)
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.
RooCmdArg RecycleConflictNodes(bool flag=true)
RooCmdArg Silence(bool flag=true)
const Int_t n
Definition legend1.C:16
Types that represent an HS3 document.
void setExportedObject(RooJSONFactoryWSTool &tool, HistFactoryDist dist, std::vector< DistributionRef > channelConstraints)
Called by the exporter of a HistFactory distribution, which is then written by the tool.
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition CodegenImpl.h:73
Namespace for the RooStats classes.
Definition CodegenImpl.h:67
A name that says what it refers to, so that for example a DataRef can't be used as a DomainRef.
Definition HS3Document.h:63
The document that the tool is exporting.
What the tool needs to know about the document that it is importing.
std::map< std::string, std::string > components
bool identifyLegacyBinWidthFactors
Identify constant factors of HistFactory samples that are used like the inverse bin width of HistFact...