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 <ROOT/RSpan.hxx>
17
18#include <iostream>
19#include <map>
20#include <unordered_map>
21#include <memory>
22#include <stdexcept>
23#include <string>
24#include <vector>
25
26namespace RooFit {
27namespace Detail {
28
29class JSONNode {
30public:
31 template <class Nd>
33 public:
34 class Impl {
35 public:
36 virtual ~Impl() = default;
37 virtual std::unique_ptr<Impl> clone() const = 0;
38 virtual void forward() = 0;
39 virtual void backward() = 0;
40 virtual Nd &current() = 0;
41 virtual bool equal(const Impl &other) const = 0;
42 };
43
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
61 {
62 return !lhs.it->equal(*rhs.it);
63 }
65 {
66 return lhs.it->equal(*rhs.it);
67 }
68
69 private:
70 std::unique_ptr<Impl> it;
71 };
72
75
76 template <class Nd>
79
80 public:
82
83 inline child_iterator_t<Nd> begin() const { return b; }
84 inline child_iterator_t<Nd> end() const { return e; }
85 };
86
87public:
88 virtual void writeJSON(std::ostream &os) const = 0;
89 virtual void writeYML(std::ostream &) const { throw std::runtime_error("YML not supported"); }
90
91public:
92 virtual JSONNode &operator<<(std::string const &s) = 0;
93 inline JSONNode &operator<<(const char *s) { return *this << std::string(s); }
94 virtual JSONNode &operator<<(int i) = 0;
95 virtual JSONNode &operator<<(double d) = 0;
96 virtual JSONNode &operator<<(bool b) = 0;
97 virtual const JSONNode &operator>>(std::string &v) const = 0;
98 virtual JSONNode &operator[](std::string const &k) = 0;
99 virtual const JSONNode &operator[](std::string const &k) const = 0;
100 virtual bool is_container() const = 0;
101 virtual bool is_map() const = 0;
102 virtual bool is_seq() const = 0;
103 virtual bool is_null() const = 0;
104 virtual JSONNode &set_map() = 0;
105 virtual JSONNode &set_seq() = 0;
106 virtual JSONNode &set_null() = 0;
107 virtual void clear() = 0;
108
109 virtual std::string key() const = 0;
110 virtual std::string val() const = 0;
111 virtual int val_int() const { return atoi(this->val().c_str()); }
112 virtual double val_double() const;
113 virtual bool val_bool() const { return atoi(this->val().c_str()); }
114 template <class T>
115 T val_t() const;
116 virtual bool has_key() const = 0;
117 virtual bool has_val() const = 0;
118 virtual bool has_child(std::string const &) const = 0;
119 virtual JSONNode &append_child() = 0;
120 virtual size_t num_children() const = 0;
121
124
125 virtual children_view children();
126 virtual const_children_view children() const;
127 virtual JSONNode &child(size_t pos) = 0;
128 virtual const JSONNode &child(size_t pos) const = 0;
129
130 template <typename Collection>
131 void fill_seq(Collection const &coll)
132 {
133 set_seq();
134 for (auto const &item : coll) {
135 append_child() << item;
136 }
137 }
138
139 template <typename Collection>
140 void fill_seq(Collection const &coll, size_t nmax)
141 {
142 set_seq();
143 size_t n = 0;
144 for (auto const &item : coll) {
145 if (n >= nmax)
146 break;
147 append_child() << item;
148 ++n;
149 }
150 }
151
152 template <typename Collection, typename TransformationFunc>
153 void fill_seq(Collection const &coll, TransformationFunc func)
154 {
155 set_seq();
156 for (auto const &item : coll) {
157 append_child() << func(item);
158 }
159 }
160
161 template <typename Matrix>
162 void fill_mat(Matrix const &mat)
163 {
164 set_seq();
165 for (int i = 0; i < mat.GetNrows(); ++i) {
166 auto &row = append_child();
167 row.set_seq();
168 for (int j = 0; j < mat.GetNcols(); ++j) {
169 row.append_child() << mat(i, j);
170 }
171 }
172 }
173
174 JSONNode const *find(std::string const &key) const
175 {
176 auto &n = *this;
177 return n.has_child(key) ? &n[key] : nullptr;
178 }
179
180 template <typename... Keys_t>
181 JSONNode const *find(std::string const &key, Keys_t const &...keys) const
182 {
183 auto &n = *this;
184 return n.has_child(key) ? n[key].find(keys...) : nullptr;
185 }
186
187 JSONNode &get(std::string const &key)
188 {
189 auto &n = *this;
190 n.set_map();
191 return n[key];
192 }
193
194 template <typename... Keys_t>
195 JSONNode &get(std::string const &key, Keys_t const &...keys)
196 {
197 auto &next = get(key);
198 next.set_map();
199 return next.get(keys...);
200 }
201};
202
203class JSONTree {
204public:
205 virtual ~JSONTree() = default;
206
207 virtual JSONNode &rootnode() = 0;
208
209 static std::unique_ptr<JSONTree> create();
210 static std::unique_ptr<JSONTree> create(std::istream &is);
211 static std::unique_ptr<JSONTree> create(std::string const &str);
212
213 static std::string getBackend();
214 static void setBackend(std::string const &name);
215
216 static bool hasBackend(std::string const &name);
217
218private:
219 // Internally, we store the backend type with an enum to be more memory efficient.
220 enum class Backend { NlohmannJson, Ryml };
221
222 static Backend &getBackendEnum();
223
224 template <typename... Args>
225 static std::unique_ptr<JSONTree> createImpl(Args &&...args);
226};
227
228std::ostream &operator<<(std::ostream &os, RooFit::Detail::JSONNode const &s);
229
230template <class T>
231std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode::children_view const &cv)
232{
233 for (const auto &e : cv) {
234 v.push_back(e.val_t<T>());
235 }
236 return v;
237}
238
239template <class T>
240std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode::const_children_view const &cv)
241{
242 for (const auto &e : cv) {
243 v.push_back(e.val_t<T>());
244 }
245 return v;
246}
247
248template <class T>
249std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode const &n)
250{
251 if (!n.is_seq()) {
252 throw std::runtime_error("node " + n.key() + " is not of sequence type!");
253 }
254 v << n.children();
255 return v;
256}
257
259{
260 n.fill_seq(v);
261 return n;
262}
263
265{
266 n.fill_seq(v);
267 return n;
268}
269
271{
272 n.fill_seq(v);
273 return n;
274}
275
276template <class Key, class T, class Hash, class KeyEqual, class Allocator>
278operator<<(RooFit::Detail::JSONNode &n, const std::unordered_map<Key, T, Hash, KeyEqual, Allocator> &m)
279{
280 n.set_map();
281 for (const auto &it : m) {
282 n[it.first] << it.second;
283 }
284 return n;
285}
286
287template <class Key, class T, class Compare, class Allocator>
288RooFit::Detail::JSONNode &operator<<(RooFit::Detail::JSONNode &n, const std::map<Key, T, Compare, Allocator> &m)
289{
290 n.set_map();
291 for (const auto &it : m) {
292 n[it.first] << it.second;
293 }
294 return n;
295}
296
297template <>
298inline int JSONNode::val_t<int>() const
299{
300 return val_int();
301}
302template <>
303inline double JSONNode::val_t<double>() const
304{
305 return val_double();
306}
307template <>
308inline bool JSONNode::val_t<bool>() const
309{
310 return val_bool();
311}
312template <>
313inline std::string JSONNode::val_t<std::string>() const
314{
315 return val();
316}
317
318} // namespace Detail
319} // namespace RooFit
320
321#endif
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define e(i)
Definition RSha256.hxx:103
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
char name[80]
Definition TGX11.cxx:145
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 double val_double() const
virtual const JSONNode & operator>>(std::string &v) const =0
void fill_seq(Collection const &coll, size_t nmax)
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 JSONNode & set_null()=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
JSONNode const * find(std::string const &key) const
virtual bool is_null() const =0
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
const Int_t n
Definition legend1.C:16
std::ostream & operator<<(std::ostream &os, RooFit::Detail::JSONNode const &s)
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition CodegenImpl.h:72
TMarker m
Definition textangle.C:8