File indexing completed on 2025-09-18 09:31:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef RooFitHS3_RooJSONFactoryWSTool_h
0014 #define RooFitHS3_RooJSONFactoryWSTool_h
0015
0016 #include <RooFit/Detail/JSONInterface.h>
0017
0018 #include <RooArgList.h>
0019 #include <RooArgSet.h>
0020 #include <RooGlobalFunc.h>
0021 #include <RooWorkspace.h>
0022
0023 #include <map>
0024 #include <stdexcept>
0025 #include <set>
0026
0027 namespace RooFit {
0028 namespace JSONIO {
0029 namespace Detail {
0030 class Domains;
0031 }
0032 }
0033 }
0034 namespace RooStats {
0035 class ModelConfig;
0036 }
0037
0038 class RooJSONFactoryWSTool {
0039 public:
0040 static constexpr bool useListsInsteadOfDicts = true;
0041 static bool allowExportInvalidNames;
0042
0043 struct CombinedData {
0044 std::string name;
0045 std::map<std::string, std::string> components;
0046 };
0047
0048 RooJSONFactoryWSTool(RooWorkspace &ws);
0049
0050 ~RooJSONFactoryWSTool();
0051
0052 static std::string name(const RooFit::Detail::JSONNode &n);
0053 static bool isValidName(const std::string &str);
0054 static bool testValidName(const std::string &str, bool forcError);
0055
0056 static RooFit::Detail::JSONNode &appendNamedChild(RooFit::Detail::JSONNode &node, std::string const &name);
0057 static RooFit::Detail::JSONNode const *findNamedChild(RooFit::Detail::JSONNode const &node, std::string const &name);
0058
0059 static void fillSeq(RooFit::Detail::JSONNode &node, RooAbsCollection const &coll, size_t nMax = -1);
0060
0061 template <class T>
0062 T *request(const std::string &objname, const std::string &requestAuthor)
0063 {
0064 if (T *out = requestImpl<T>(objname)) {
0065 return out;
0066 }
0067 throw DependencyMissingError(requestAuthor, objname, T::Class()->GetName());
0068 }
0069
0070 template <class T>
0071 T *requestArg(const RooFit::Detail::JSONNode &node, const std::string &key)
0072 {
0073 std::string requestAuthor(RooJSONFactoryWSTool::name(node));
0074 if (!node.has_child(key)) {
0075 RooJSONFactoryWSTool::error("no \"" + key + "\" given in \"" + requestAuthor + "\"");
0076 }
0077 return request<T>(node[key].val(), requestAuthor);
0078 }
0079
0080 template <class T, class Coll_t>
0081 Coll_t requestCollection(const RooFit::Detail::JSONNode &node, const std::string &seqName)
0082 {
0083 std::string requestAuthor(RooJSONFactoryWSTool::name(node));
0084 if (!node.has_child(seqName)) {
0085 RooJSONFactoryWSTool::error("no \"" + seqName + "\" given in \"" + requestAuthor + "\"");
0086 }
0087 if (!node[seqName].is_seq()) {
0088 RooJSONFactoryWSTool::error("\"" + seqName + "\" in \"" + requestAuthor + "\" is not a sequence");
0089 }
0090
0091 Coll_t out;
0092 for (const auto &elem : node[seqName].children()) {
0093 out.add(*request<T>(elem.val(), requestAuthor));
0094 }
0095 return out;
0096 }
0097
0098 template <class T>
0099 RooArgSet requestArgSet(const RooFit::Detail::JSONNode &node, const std::string &seqName)
0100 {
0101 return requestCollection<T, RooArgSet>(node, seqName);
0102 }
0103
0104 template <class T>
0105 RooArgList requestArgList(const RooFit::Detail::JSONNode &node, const std::string &seqName)
0106 {
0107 return requestCollection<T, RooArgList>(node, seqName);
0108 }
0109
0110 RooWorkspace *workspace() { return &_workspace; }
0111
0112 template <class Obj_t>
0113 Obj_t &wsImport(Obj_t const &obj)
0114 {
0115 _workspace.import(obj, RooFit::RecycleConflictNodes(true), RooFit::Silence(true));
0116 return *static_cast<Obj_t *>(_workspace.obj(obj.GetName()));
0117 }
0118
0119 template <class Obj_t, typename... Args_t>
0120 Obj_t &wsEmplace(RooStringView name, Args_t &&...args)
0121 {
0122 return wsImport(Obj_t(name.c_str(), name.c_str(), std::forward<Args_t>(args)...));
0123 }
0124
0125 [[noreturn]] static void error(const char *s);
0126 [[noreturn]] inline static void error(const std::string &s) { error(s.c_str()); }
0127 static std::ostream &warning(const std::string &s);
0128
0129 static RooArgSet readAxes(const RooFit::Detail::JSONNode &node);
0130 static std::unique_ptr<RooDataHist>
0131 readBinnedData(const RooFit::Detail::JSONNode &n, const std::string &namecomp, RooArgSet const &vars);
0132
0133 bool importJSON(std::string const &filename);
0134 bool importYML(std::string const &filename);
0135 bool importJSON(std::istream &os);
0136 bool importYML(std::istream &os);
0137 bool exportJSON(std::string const &fileName);
0138 bool exportYML(std::string const &fileName);
0139 bool exportJSON(std::ostream &os);
0140 bool exportYML(std::ostream &os);
0141
0142 std::string exportJSONtoString();
0143 std::string exportYMLtoString();
0144 bool importJSONfromString(const std::string &s);
0145 bool importYMLfromString(const std::string &s);
0146 void importJSONElement(const std::string &name, const std::string &jsonString);
0147 void importVariableElement(const RooFit::Detail::JSONNode &n);
0148
0149 void importFunction(const RooFit::Detail::JSONNode &n, bool importAllDependants);
0150 void importFunction(const std::string &jsonString, bool importAllDependants);
0151
0152 static std::unique_ptr<RooFit::Detail::JSONTree> createNewJSONTree();
0153
0154 static RooFit::Detail::JSONNode &makeVariablesNode(RooFit::Detail::JSONNode &rootNode);
0155
0156
0157 class DependencyMissingError : public std::exception {
0158 std::string _parent, _child, _class, _message;
0159
0160 public:
0161 DependencyMissingError(const std::string &p, const std::string &c, const std::string &classname)
0162 : _parent(p), _child(c), _class(classname)
0163 {
0164 _message = "object '" + _parent + "' is missing dependency '" + _child + "' of type '" + _class + "'";
0165 };
0166 const std::string &parent() const { return _parent; }
0167 const std::string &child() const { return _child; }
0168 const std::string &classname() const { return _class; }
0169 const char *what() const noexcept override { return _message.c_str(); }
0170 };
0171
0172 template <typename... Keys_t>
0173 static RooFit::Detail::JSONNode &getRooFitInternal(RooFit::Detail::JSONNode &node, Keys_t const &...keys)
0174 {
0175 return node.get("misc", "ROOT_internal", keys...);
0176 }
0177
0178 static void
0179 exportHisto(RooArgSet const &vars, std::size_t n, double const *contents, RooFit::Detail::JSONNode &output);
0180
0181 static void exportArray(std::size_t n, double const *contents, RooFit::Detail::JSONNode &output);
0182
0183 void exportCategory(RooAbsCategory const &cat, RooFit::Detail::JSONNode &node);
0184
0185 void queueExport(RooAbsArg const &arg) { _serversToExport.push_back(&arg); }
0186 void queueExportTemporary(RooAbsArg *arg)
0187 {
0188 _serversToExport.push_back(arg);
0189 _serversToDelete.push_back(arg);
0190 }
0191
0192 std::string exportTransformed(const RooAbsReal *original, const std::string &suffix, const std::string &formula);
0193
0194 void setAttribute(const std::string &obj, const std::string &attrib);
0195 bool hasAttribute(const std::string &obj, const std::string &attrib);
0196 std::string getStringAttribute(const std::string &obj, const std::string &attrib);
0197 void setStringAttribute(const std::string &obj, const std::string &attrib, const std::string &value);
0198
0199 private:
0200 template <class T>
0201 T *requestImpl(const std::string &objname);
0202
0203 void exportObject(RooAbsArg const &func, std::set<std::string> &exportedObjectNames);
0204
0205
0206 template <class T>
0207 void exportObjects(T const &args, std::set<std::string> &exportedObjectNames)
0208 {
0209 RooArgSet argSet;
0210 for (RooAbsArg const *arg : args) {
0211 argSet.add(*arg);
0212 }
0213 argSet.sort();
0214 for (RooAbsArg *arg : argSet) {
0215 exportObject(*arg, exportedObjectNames);
0216 }
0217 }
0218
0219 void exportData(RooAbsData const &data);
0220 RooJSONFactoryWSTool::CombinedData exportCombinedData(RooAbsData const &data);
0221
0222 void importAllNodes(const RooFit::Detail::JSONNode &n);
0223
0224 void importVariable(const RooFit::Detail::JSONNode &n);
0225 void importDependants(const RooFit::Detail::JSONNode &n);
0226
0227 void exportVariable(const RooAbsArg *v, RooFit::Detail::JSONNode &n);
0228 void exportVariables(const RooArgSet &allElems, RooFit::Detail::JSONNode &n);
0229
0230 void exportAllObjects(RooFit::Detail::JSONNode &n);
0231
0232 void exportModelConfig(RooFit::Detail::JSONNode &rootnode, RooStats::ModelConfig const &mc,
0233 const std::vector<RooJSONFactoryWSTool::CombinedData> &d);
0234
0235 void exportSingleModelConfig(RooFit::Detail::JSONNode &rootnode, RooStats::ModelConfig const &mc,
0236 std::string const &analysisName,
0237 std::map<std::string, std::string> const *dataComponents);
0238
0239
0240 const RooFit::Detail::JSONNode *_rootnodeInput = nullptr;
0241 const RooFit::Detail::JSONNode *_attributesNode = nullptr;
0242 RooFit::Detail::JSONNode *_rootnodeOutput = nullptr;
0243 RooFit::Detail::JSONNode *_varsNode = nullptr;
0244 RooWorkspace &_workspace;
0245
0246
0247 std::unique_ptr<RooFit::JSONIO::Detail::Domains> _domains;
0248 std::vector<RooAbsArg const *> _serversToExport;
0249 std::vector<RooAbsArg const *> _serversToDelete;
0250 };
0251 #endif