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>
135 void fill_seq(Collection const &coll, size_t nmax)
136 {
137 set_seq();
138 size_t n = 0;
139 for (auto const &item : coll) {
140 if (n >= nmax)
141 break;
142 append_child() << item;
143 ++n;
144 }
145 }
146
147 template <typename Collection, typename TransformationFunc>
148 void fill_seq(Collection const &coll, TransformationFunc func)
149 {
150 set_seq();
151 for (auto const &item : coll) {
152 append_child() << func(item);
153 }
154 }
155
156 template <typename Matrix>
157 void fill_mat(Matrix const &mat)
158 {
159 set_seq();
160 for (int i = 0; i < mat.GetNrows(); ++i) {
161 auto &row = append_child();
162 row.set_seq();
163 for (int j = 0; j < mat.GetNcols(); ++j) {
164 row.append_child() << mat(i, j);
165 }
166 }
167 }
168
169 JSONNode const *find(std::string const &key) const
170 {
171 auto &n = *this;
172 return n.has_child(key) ? &n[key] : nullptr;
173 }
174
175 template <typename... Keys_t>
176 JSONNode const *find(std::string const &key, Keys_t const &...keys) const
177 {
178 auto &n = *this;
179 return n.has_child(key) ? n[key].find(keys...) : nullptr;
180 }
181
182 JSONNode &get(std::string const &key)
183 {
184 auto &n = *this;
185 n.set_map();
186 return n[key];
187 }
188
189 template <typename... Keys_t>
190 JSONNode &get(std::string const &key, Keys_t const &...keys)
191 {
192 auto &next = get(key);
193 next.set_map();
194 return next.get(keys...);
195 }
196};
197
198class JSONTree {
199public:
200 virtual ~JSONTree() = default;
201
202 virtual JSONNode &rootnode() = 0;
203
204 static std::unique_ptr<JSONTree> create();
205 static std::unique_ptr<JSONTree> create(std::istream &is);
206 static std::unique_ptr<JSONTree> create(std::string const &str);
207
208 static std::string getBackend();
209 static void setBackend(std::string const &name);
210
211 static bool hasBackend(std::string const &name);
212
213private:
214 // Internally, we store the backend type with an enum to be more memory efficient.
215 enum class Backend { NlohmannJson, Ryml };
216
217 static Backend &getBackendEnum();
218
219 template <typename... Args>
220 static std::unique_ptr<JSONTree> createImpl(Args &&...args);
221};
222
223std::ostream &operator<<(std::ostream &os, RooFit::Detail::JSONNode const &s);
224
225template <class T>
226std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode::children_view const &cv)
227{
228 for (const auto &e : cv) {
229 v.push_back(e.val_t<T>());
230 }
231 return v;
232}
233
234template <class T>
235std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode::const_children_view const &cv)
236{
237 for (const auto &e : cv) {
238 v.push_back(e.val_t<T>());
239 }
240 return v;
241}
242
243template <class T>
244std::vector<T> &operator<<(std::vector<T> &v, RooFit::Detail::JSONNode const &n)
245{
246 if (!n.is_seq()) {
247 throw std::runtime_error("node " + n.key() + " is not of sequence type!");
248 }
249 v << n.children();
250 return v;
251}
252
253template <>
254inline int JSONNode::val_t<int>() const
255{
256 return val_int();
257}
258template <>
259inline double JSONNode::val_t<double>() const
260{
261 return val_double();
262}
263template <>
264inline bool JSONNode::val_t<bool>() const
265{
266 return val_bool();
267}
268template <>
269inline std::string JSONNode::val_t<std::string>() const
270{
271 return val();
272}
273
274} // namespace Detail
275} // namespace RooFit
276
277#endif
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define e(i)
Definition RSha256.hxx:103
TObject * clone(const char *newname) const override
Definition RooChi2Var.h:9
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
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 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 JSONIO.h:26