Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
JSONInterface.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 RooFit_Detail_JSONInterface_h
14#define RooFit_Detail_JSONInterface_h
15
16#include <iostream>
17#include <memory>
18#include <stdexcept>
19#include <string>
20#include <vector>
21
22namespace RooFit {
23namespace Detail {
24
25class JSONNode {
26public:
27 template <class Nd>
29 public:
30 class Impl {
31 public:
32 virtual ~Impl() = default;
33 virtual std::unique_ptr<Impl> clone() const = 0;
34 virtual void forward() = 0;
35 virtual void backward() = 0;
36 virtual Nd &current() = 0;
37 virtual bool equal(const Impl &other) const = 0;
38 };
39
40 private:
41 std::unique_ptr<Impl> it;
42
43 public:
44 child_iterator_t(std::unique_ptr<Impl> impl) : it(std::move(impl)) {}
45 child_iterator_t(const child_iterator_t &other) : it(std::move(other.it->clone())) {}
46
48 {
49 it->forward();
50 return *this;
51 }
53 {
54 it->backward();
55 return *this;
56 }
57 Nd &operator*() const { return it->current(); }
58 Nd &operator->() const { return it->current(); }
59
60 friend bool operator!=(child_iterator_t const &lhs, child_iterator_t const &rhs)
61 {
62 return !lhs.it->equal(*rhs.it);
63 }
64 friend bool operator==(child_iterator_t const &lhs, child_iterator_t const &rhs)
65 {
66 return lhs.it->equal(*rhs.it);
67 }
68 };
69
72
73 template <class Nd>
76
77 public:
78 inline children_view_t(child_iterator_t<Nd> const &b_, child_iterator_t<Nd> const &e_) : b(b_), e(e_) {}
79
80 inline child_iterator_t<Nd> begin() const { return b; }
81 inline child_iterator_t<Nd> end() const { return e; }
82 };
83
84public:
85 virtual void writeJSON(std::ostream &os) const = 0;
86 virtual void writeYML(std::ostream &) const { throw std::runtime_error("YML not supported"); }
87
88public:
89 virtual JSONNode &operator<<(std::string const &s) = 0;
90 inline JSONNode &operator<<(const char *s) { return *this << std::string(s); }
91 virtual JSONNode &operator<<(int i) = 0;
92 virtual JSONNode &operator<<(double d) = 0;
93 virtual JSONNode &operator<<(bool b) = 0;
94 virtual const JSONNode &operator>>(std::string &v) const = 0;
95 virtual JSONNode &operator[](std::string const &k) = 0;
96 virtual const JSONNode &operator[](std::string const &k) const = 0;
97 virtual bool is_container() const = 0;
98 virtual bool is_map() const = 0;
99 virtual bool is_seq() const = 0;
100 virtual JSONNode &set_map() = 0;
101 virtual JSONNode &set_seq() = 0;
102 virtual void clear() = 0;
103
104 virtual std::string key() const = 0;
105 virtual std::string val() const = 0;
106 virtual int val_int() const { return atoi(this->val().c_str()); }
107 virtual double val_double() const { return std::stod(this->val()); }
108 virtual bool val_bool() const { return atoi(this->val().c_str()); }
109 template <class T>
110 T val_t() const;
111 virtual bool has_key() const = 0;
112 virtual bool has_val() const = 0;
113 virtual bool has_child(std::string const &) const = 0;
114 virtual JSONNode &append_child() = 0;
115 virtual size_t num_children() const = 0;
116
119
120 virtual children_view children();
121 virtual const_children_view children() const;
122 virtual JSONNode &child(size_t pos) = 0;
123 virtual const JSONNode &child(size_t pos) const = 0;
124
125 template <typename Collection>
126 void fill_seq(Collection const &coll)
127 {
128 set_seq();
129 for (auto const &item : coll) {
130 append_child() << item;
131 }
132 }
133
134 template <typename Collection, typename TransformationFunc>
135 void fill_seq(Collection const &coll, TransformationFunc func)
136 {
137 set_seq();
138 for (auto const &item : coll) {
139 append_child() << func(item);
140 }
141 }
142
143 template <typename Matrix>
144 void fill_mat(Matrix const &mat)
145 {
146 set_seq();
147 for (int i = 0; i < mat.GetNrows(); ++i) {
148 auto &row = append_child();
149 row.set_seq();
150 for (int j = 0; j < mat.GetNcols(); ++j) {
151 row.append_child() << mat(i, j);
152 }
153 }
154 }
155
156 JSONNode const *find(std::string const &key) const
157 {
158 auto &n = *this;
159 return n.has_child(key) ? &n[key] : nullptr;
160 }
161
162 template <typename... Keys_t>
163 JSONNode const *find(std::string const &key, Keys_t const &...keys) const
164 {
165 auto &n = *this;
166 return n.has_child(key) ? n[key].find(keys...) : nullptr;
167 }
168
169 JSONNode &get(std::string const &key)
170 {
171 auto &n = *this;
172 n.set_map();
173 return n[key];
174 }
175
176 template <typename... Keys_t>
177 JSONNode &get(std::string const &key, Keys_t const &...keys)
178 {
179 auto &next = get(key);
180 next.set_map();
181 return next.get(keys...);
182 }
183};
184
185class JSONTree {
186public:
187 virtual ~JSONTree() = default;
188
189 virtual JSONNode &rootnode() = 0;
190
191 static std::unique_ptr<JSONTree> create();
192 static std::unique_ptr<JSONTree> create(std::istream &is);
193 static std::unique_ptr<JSONTree> create(std::string const &str);
194
195 static std::string getBackend();
196 static void setBackend(std::string const &name);
197
198 static bool hasBackend(std::string const &name);
199
200private:
201 // Internally, we store the backend type with an enum to be more memory efficient.
202 enum class Backend { NlohmannJson, Ryml };
203
204 static Backend &getBackendEnum();
205
206 template <typename... Args>
207 static std::unique_ptr<JSONTree> createImpl(Args &&...args);
208};
209
210std::ostream &operator<<(std::ostream &os, RooFit::Detail::JSONNode const &s);
211
212template <class T>
213std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode::children_view const &cv)
214{
215 for (const auto &e : cv) {
216 v.push_back(e.val_t<T>());
217 }
218 return v;
219}
220
221template <class T>
222std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode::const_children_view const &cv)
223{
224 for (const auto &e : cv) {
225 v.push_back(e.val_t<T>());
226 }
227 return v;
228}
229
230template <class T>
231std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode const &n)
232{
233 if (!n.is_seq()) {
234 throw std::runtime_error("node " + n.key() + " is not of sequence type!");
235 }
236 v << n.children();
237 return v;
238}
239
240template <>
241inline int JSONNode::val_t<int>() const
242{
243 return val_int();
244}
245template <>
246inline double JSONNode::val_t<double>() const
247{
248 return val_double();
249}
250template <>
251inline bool JSONNode::val_t<bool>() const
252{
253 return val_bool();
254}
255template <>
256inline std::string JSONNode::val_t<std::string>() const
257{
258 return val();
259}
260
261} // namespace Detail
262} // namespace RooFit
263
264#endif
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define e(i)
Definition RSha256.hxx:103
TBuffer & operator<<(TBuffer &buf, const Tmpl *obj)
Definition TBuffer.h:399
char name[80]
Definition TGX11.cxx:110
virtual std::unique_ptr< Impl > clone() const =0
virtual bool equal(const Impl &other) const =0
child_iterator_t(std::unique_ptr< Impl > impl)
child_iterator_t(const child_iterator_t &other)
friend bool operator==(child_iterator_t const &lhs, child_iterator_t const &rhs)
friend bool operator!=(child_iterator_t const &lhs, child_iterator_t const &rhs)
child_iterator_t< Nd > begin() const
children_view_t(child_iterator_t< Nd > const &b_, child_iterator_t< Nd > const &e_)
child_iterator_t< Nd > end() const
virtual JSONNode & operator<<(std::string const &s)=0
virtual bool val_bool() const
JSONNode & get(std::string const &key)
virtual std::string val() const =0
virtual const JSONNode & operator>>(std::string &v) const =0
JSONNode & get(std::string const &key, Keys_t const &...keys)
void fill_seq(Collection const &coll)
virtual JSONNode & set_map()=0
virtual JSONNode & append_child()=0
JSONNode const * find(std::string const &key, Keys_t const &...keys) const
virtual JSONNode & operator<<(double d)=0
virtual void clear()=0
virtual children_view children()
virtual size_t num_children() const =0
virtual JSONNode & child(size_t pos)=0
virtual JSONNode & set_seq()=0
virtual bool is_container() const =0
virtual void writeJSON(std::ostream &os) const =0
virtual bool is_seq() const =0
virtual const JSONNode & operator[](std::string const &k) const =0
virtual JSONNode & operator<<(bool b)=0
virtual void writeYML(std::ostream &) const
virtual bool is_map() const =0
virtual bool has_child(std::string const &) const =0
virtual std::string key() const =0
JSONNode & operator<<(const char *s)
void fill_seq(Collection const &coll, TransformationFunc func)
virtual JSONNode & operator[](std::string const &k)=0
void fill_mat(Matrix const &mat)
virtual bool has_key() const =0
virtual const JSONNode & child(size_t pos) const =0
virtual double val_double() const
JSONNode const * find(std::string const &key) const
virtual bool has_val() const =0
virtual int val_int() const
virtual JSONNode & operator<<(int i)=0
static void setBackend(std::string const &name)
Set the library that serves as the backend for the JSON interface.
static Backend & getBackendEnum()
static std::unique_ptr< JSONTree > create()
static bool hasBackend(std::string const &name)
Check if ROOT was compiled with support for a certain JSON backend library.
static std::string getBackend()
Returns the name of the library that serves as the backend for the JSON interface,...
static std::unique_ptr< JSONTree > createImpl(Args &&...args)
virtual ~JSONTree()=default
virtual JSONNode & rootnode()=0
Int_t GetNrows() const
Int_t GetNcols() const
const Int_t n
Definition legend1.C:16
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition Common.h:18