Back to home page

EIC code displayed by LXR

 
 

    


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

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 RooFit_Detail_JSONInterface_h
0014 #define RooFit_Detail_JSONInterface_h
0015 
0016 #include <iostream>
0017 #include <memory>
0018 #include <stdexcept>
0019 #include <string>
0020 #include <vector>
0021 
0022 namespace RooFit {
0023 namespace Detail {
0024 
0025 class JSONNode {
0026 public:
0027    template <class Nd>
0028    class child_iterator_t {
0029    public:
0030       class Impl {
0031       public:
0032          virtual ~Impl() = default;
0033          virtual std::unique_ptr<Impl> clone() const = 0;
0034          virtual void forward() = 0;
0035          virtual void backward() = 0;
0036          virtual Nd &current() = 0;
0037          virtual bool equal(const Impl &other) const = 0;
0038       };
0039 
0040       child_iterator_t(std::unique_ptr<Impl> impl) : it(std::move(impl)) {}
0041       child_iterator_t(const child_iterator_t &other) : it(std::move(other.it->clone())) {}
0042 
0043       child_iterator_t &operator++()
0044       {
0045          it->forward();
0046          return *this;
0047       }
0048       child_iterator_t &operator--()
0049       {
0050          it->backward();
0051          return *this;
0052       }
0053       Nd &operator*() const { return it->current(); }
0054       Nd &operator->() const { return it->current(); }
0055 
0056       friend bool operator!=(child_iterator_t const &lhs, child_iterator_t const &rhs)
0057       {
0058          return !lhs.it->equal(*rhs.it);
0059       }
0060       friend bool operator==(child_iterator_t const &lhs, child_iterator_t const &rhs)
0061       {
0062          return lhs.it->equal(*rhs.it);
0063       }
0064 
0065    private:
0066       std::unique_ptr<Impl> it;
0067    };
0068 
0069    using child_iterator = child_iterator_t<JSONNode>;
0070    using const_child_iterator = child_iterator_t<const JSONNode>;
0071 
0072    template <class Nd>
0073    class children_view_t {
0074       child_iterator_t<Nd> b, e;
0075 
0076    public:
0077       inline children_view_t(child_iterator_t<Nd> const &b_, child_iterator_t<Nd> const &e_) : b(b_), e(e_) {}
0078 
0079       inline child_iterator_t<Nd> begin() const { return b; }
0080       inline child_iterator_t<Nd> end() const { return e; }
0081    };
0082 
0083 public:
0084    virtual void writeJSON(std::ostream &os) const = 0;
0085    virtual void writeYML(std::ostream &) const { throw std::runtime_error("YML not supported"); }
0086 
0087 public:
0088    virtual JSONNode &operator<<(std::string const &s) = 0;
0089    inline JSONNode &operator<<(const char *s) { return *this << std::string(s); }
0090    virtual JSONNode &operator<<(int i) = 0;
0091    virtual JSONNode &operator<<(double d) = 0;
0092    virtual JSONNode &operator<<(bool b) = 0;
0093    virtual const JSONNode &operator>>(std::string &v) const = 0;
0094    virtual JSONNode &operator[](std::string const &k) = 0;
0095    virtual const JSONNode &operator[](std::string const &k) const = 0;
0096    virtual bool is_container() const = 0;
0097    virtual bool is_map() const = 0;
0098    virtual bool is_seq() const = 0;
0099    virtual JSONNode &set_map() = 0;
0100    virtual JSONNode &set_seq() = 0;
0101    virtual void clear() = 0;
0102 
0103    virtual std::string key() const = 0;
0104    virtual std::string val() const = 0;
0105    virtual int val_int() const { return atoi(this->val().c_str()); }
0106    virtual double val_double() const { return std::stod(this->val()); }
0107    virtual bool val_bool() const { return atoi(this->val().c_str()); }
0108    template <class T>
0109    T val_t() const;
0110    virtual bool has_key() const = 0;
0111    virtual bool has_val() const = 0;
0112    virtual bool has_child(std::string const &) const = 0;
0113    virtual JSONNode &append_child() = 0;
0114    virtual size_t num_children() const = 0;
0115 
0116    using children_view = children_view_t<JSONNode>;
0117    using const_children_view = children_view_t<const JSONNode>;
0118 
0119    virtual children_view children();
0120    virtual const_children_view children() const;
0121    virtual JSONNode &child(size_t pos) = 0;
0122    virtual const JSONNode &child(size_t pos) const = 0;
0123 
0124    template <typename Collection>
0125    void fill_seq(Collection const &coll)
0126    {
0127       set_seq();
0128       for (auto const &item : coll) {
0129          append_child() << item;
0130       }
0131    }
0132 
0133    template <typename Collection>
0134    void fill_seq(Collection const &coll, size_t nmax)
0135    {
0136       set_seq();
0137       size_t n = 0;
0138       for (auto const &item : coll) {
0139          if (n >= nmax)
0140             break;
0141          append_child() << item;
0142          ++n;
0143       }
0144    }
0145 
0146    template <typename Collection, typename TransformationFunc>
0147    void fill_seq(Collection const &coll, TransformationFunc func)
0148    {
0149       set_seq();
0150       for (auto const &item : coll) {
0151          append_child() << func(item);
0152       }
0153    }
0154 
0155    template <typename Matrix>
0156    void fill_mat(Matrix const &mat)
0157    {
0158       set_seq();
0159       for (int i = 0; i < mat.GetNrows(); ++i) {
0160          auto &row = append_child();
0161          row.set_seq();
0162          for (int j = 0; j < mat.GetNcols(); ++j) {
0163             row.append_child() << mat(i, j);
0164          }
0165       }
0166    }
0167 
0168    JSONNode const *find(std::string const &key) const
0169    {
0170       auto &n = *this;
0171       return n.has_child(key) ? &n[key] : nullptr;
0172    }
0173 
0174    template <typename... Keys_t>
0175    JSONNode const *find(std::string const &key, Keys_t const &...keys) const
0176    {
0177       auto &n = *this;
0178       return n.has_child(key) ? n[key].find(keys...) : nullptr;
0179    }
0180 
0181    JSONNode &get(std::string const &key)
0182    {
0183       auto &n = *this;
0184       n.set_map();
0185       return n[key];
0186    }
0187 
0188    template <typename... Keys_t>
0189    JSONNode &get(std::string const &key, Keys_t const &...keys)
0190    {
0191       auto &next = get(key);
0192       next.set_map();
0193       return next.get(keys...);
0194    }
0195 };
0196 
0197 class JSONTree {
0198 public:
0199    virtual ~JSONTree() = default;
0200 
0201    virtual JSONNode &rootnode() = 0;
0202 
0203    static std::unique_ptr<JSONTree> create();
0204    static std::unique_ptr<JSONTree> create(std::istream &is);
0205    static std::unique_ptr<JSONTree> create(std::string const &str);
0206 
0207    static std::string getBackend();
0208    static void setBackend(std::string const &name);
0209 
0210    static bool hasBackend(std::string const &name);
0211 
0212 private:
0213    // Internally, we store the backend type with an enum to be more memory efficient.
0214    enum class Backend { NlohmannJson, Ryml };
0215 
0216    static Backend &getBackendEnum();
0217 
0218    template <typename... Args>
0219    static std::unique_ptr<JSONTree> createImpl(Args &&...args);
0220 };
0221 
0222 std::ostream &operator<<(std::ostream &os, RooFit::Detail::JSONNode const &s);
0223 
0224 template <class T>
0225 std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode::children_view const &cv)
0226 {
0227    for (const auto &e : cv) {
0228       v.push_back(e.val_t<T>());
0229    }
0230    return v;
0231 }
0232 
0233 template <class T>
0234 std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode::const_children_view const &cv)
0235 {
0236    for (const auto &e : cv) {
0237       v.push_back(e.val_t<T>());
0238    }
0239    return v;
0240 }
0241 
0242 template <class T>
0243 std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode const &n)
0244 {
0245    if (!n.is_seq()) {
0246       throw std::runtime_error("node " + n.key() + " is not of sequence type!");
0247    }
0248    v << n.children();
0249    return v;
0250 }
0251 
0252 template <>
0253 inline int JSONNode::val_t<int>() const
0254 {
0255    return val_int();
0256 }
0257 template <>
0258 inline double JSONNode::val_t<double>() const
0259 {
0260    return val_double();
0261 }
0262 template <>
0263 inline bool JSONNode::val_t<bool>() const
0264 {
0265    return val_bool();
0266 }
0267 template <>
0268 inline std::string JSONNode::val_t<std::string>() const
0269 {
0270    return val();
0271 }
0272 
0273 } // namespace Detail
0274 } // namespace RooFit
0275 
0276 #endif