Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:29:43

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