Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:27

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