Project
Loading...
Searching...
No Matches
PropertyTreeHelpers.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#include "PropertyTreeHelpers.h"
17#include "Framework/Signpost.h"
18
19#include <boost/program_options/variables_map.hpp>
20
21#include <vector>
22#include <string>
23
25
26namespace o2::framework
27{
28namespace
29{
31template <VariantType T>
32inline Variant fromString(std::string const& str)
33{
34 std::stringstream ss;
35 ss.str(str);
36 return VariantJSONHelpers::read<T>(ss);
37}
38} // namespace
39void PropertyTreeHelpers::populateDefaults(std::vector<ConfigParamSpec> const& schema,
40 boost::property_tree::ptree& pt,
41 boost::property_tree::ptree& provenance)
42{
43 O2_SIGNPOST_ID_GENERATE(cid, configuration);
44 O2_SIGNPOST_START(configuration, cid, "populateDefaults", "Filling with defaults");
45 for (auto const& spec : schema) {
46 std::string key = spec.name.substr(0, spec.name.find(','));
47 try {
48 if (spec.defaultValue.type() == VariantType::Empty) {
49 continue;
50 }
51 switch (spec.type) {
53 pt.put(key, spec.defaultValue.get<int>());
54 break;
56 pt.put(key, spec.defaultValue.get<int8_t>());
57 break;
59 pt.put(key, spec.defaultValue.get<int16_t>());
60 break;
62 pt.put(key, spec.defaultValue.get<uint8_t>());
63 break;
65 pt.put(key, spec.defaultValue.get<uint16_t>());
66 break;
68 pt.put(key, spec.defaultValue.get<uint32_t>());
69 break;
71 pt.put(key, spec.defaultValue.get<uint64_t>());
72 break;
74 pt.put(key, spec.defaultValue.get<int64_t>());
75 break;
77 pt.put(key, spec.defaultValue.get<float>());
78 break;
80 pt.put(key, spec.defaultValue.get<double>());
81 break;
83 pt.put(key, spec.defaultValue.get<std::string>());
84 break;
85 case VariantType::Bool: {
86 bool value = spec.defaultValue.get<bool>();
87 O2_SIGNPOST_EVENT_EMIT(configuration, cid, "populateDefaults", "Setting %{public}s: %{public}s", key.c_str(), value ? "true" : "false");
88 pt.put(key, value);
89 break;
90 }
92 pt.put_child(key, boost::property_tree::ptree{});
93 break;
95 pt.put_child(key, vectorToBranch(spec.defaultValue.get<int*>(), spec.defaultValue.size()));
96 break;
98 pt.put_child(key, vectorToBranch(spec.defaultValue.get<float*>(), spec.defaultValue.size()));
99 break;
101 pt.put_child(key, vectorToBranch(spec.defaultValue.get<double*>(), spec.defaultValue.size()));
102 break;
104 pt.put_child(key, vectorToBranch(spec.defaultValue.get<bool*>(), spec.defaultValue.size()));
105 break;
107 pt.put_child(key, vectorToBranch(spec.defaultValue.get<std::string*>(), spec.defaultValue.size()));
108 break;
110 pt.put_child(key, array2DToBranch(spec.defaultValue.get<Array2D<int>>()));
111 break;
113 pt.put_child(key, array2DToBranch(spec.defaultValue.get<Array2D<float>>()));
114 break;
116 pt.put_child(key, array2DToBranch(spec.defaultValue.get<Array2D<double>>()));
117 break;
119 pt.put_child(key, labeledArrayToBranch(spec.defaultValue.get<LabeledArray<int>>()));
120 break;
122 pt.put_child(key, labeledArrayToBranch(spec.defaultValue.get<LabeledArray<float>>()));
123 break;
125 pt.put_child(key, labeledArrayToBranch(spec.defaultValue.get<LabeledArray<double>>()));
126 break;
128 pt.put_child(key, labeledArrayToBranch(spec.defaultValue.get<LabeledArray<std::string>>()));
129 break;
132 default:
133 throw runtime_error_f("Unknown variant type", spec.type);
134 }
135 provenance.put(key, "default");
136 } catch (std::runtime_error& re) {
137 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populateDefaults", "Aborting because of runtime_error %{public}s", re.what());
138 throw;
139 } catch (std::exception& e) {
140 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populateDefaults", "Missing option %{public}s (%{public}s)", key.c_str(), e.what());
141 throw std::invalid_argument(std::string("missing option: ") + key + " (" + e.what() + ")");
142 } catch (...) {
143 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populateDefaults", "Aborting because of missing option %{public}s", key.c_str());
144 throw std::invalid_argument(std::string("missing option: ") + key);
145 }
146 }
147 O2_SIGNPOST_END(configuration, cid, "populateDefaults", "Done");
148}
149
150void PropertyTreeHelpers::populate(std::vector<ConfigParamSpec> const& schema,
151 boost::property_tree::ptree& pt,
152 boost::program_options::variables_map const& vmap,
153 boost::property_tree::ptree& provenance)
154{
155 O2_SIGNPOST_ID_GENERATE(cid, configuration);
156 O2_SIGNPOST_START(configuration, cid, "populate", "Filling parameters from variables_map");
157 for (auto const& spec : schema) {
158 // strip short version to get the correct key
159 std::string key = spec.name.substr(0, spec.name.find(','));
160 if (vmap.count(key) == 0) {
161 continue;
162 }
163 try {
164 switch (spec.type) {
165 case VariantType::Int:
166 pt.put(key, vmap[key].as<int>());
167 break;
169 pt.put(key, vmap[key].as<int8_t>());
170 break;
172 pt.put(key, vmap[key].as<int16_t>());
173 break;
175 pt.put(key, vmap[key].as<uint8_t>());
176 break;
178 pt.put(key, vmap[key].as<uint16_t>());
179 break;
181 pt.put(key, vmap[key].as<uint32_t>());
182 break;
184 pt.put(key, vmap[key].as<uint64_t>());
185 break;
187 pt.put(key, vmap[key].as<int64_t>());
188 break;
190 pt.put(key, vmap[key].as<float>());
191 break;
193 pt.put(key, vmap[key].as<double>());
194 break;
196 if (auto const* v = boost::any_cast<std::string>(&vmap[key].value())) {
197 pt.put(key, *v);
198 }
199 break;
200 case VariantType::Bool: {
201 auto v = vmap[key].as<bool>();
202 O2_SIGNPOST_EVENT_EMIT(configuration, cid, "populate", "Setting %{public}s: %{public}s", key.c_str(), v ? "true" : "false");
203 pt.put(key, v);
204 } break;
206 auto v = fromString<VariantType::ArrayInt>(vmap[key].as<std::string>());
207 pt.put_child(key, vectorToBranch<int>(v.get<int*>(), v.size()));
208 } break;
210 auto v = fromString<VariantType::ArrayFloat>(vmap[key].as<std::string>());
211 pt.put_child(key, vectorToBranch<float>(v.get<float*>(), v.size()));
212 } break;
214 auto v = fromString<VariantType::ArrayDouble>(vmap[key].as<std::string>());
215 pt.put_child(key, vectorToBranch<double>(v.get<double*>(), v.size()));
216 } break;
218 // pt.put_child(key, vectorToBranch<bool>(stringToVector<bool>(vmap[key].as<std::string>())));
219 break;
221 auto v = fromString<VariantType::ArrayString>(vmap[key].as<std::string>());
222 pt.put_child(key, vectorToBranch<std::string>(v.get<std::string*>(), v.size()));
223 } break;
225 auto v = fromString<VariantType::Array2DInt>(vmap[key].as<std::string>());
226 pt.put_child(key, array2DToBranch<int>(v.get<Array2D<int>>()));
227 } break;
229 auto v = fromString<VariantType::Array2DFloat>(vmap[key].as<std::string>());
230 pt.put_child(key, array2DToBranch<float>(v.get<Array2D<float>>()));
231 } break;
233 auto v = fromString<VariantType::Array2DDouble>(vmap[key].as<std::string>());
234 pt.put_child(key, array2DToBranch<double>(v.get<Array2D<double>>()));
235 } break;
237 auto v = fromString<VariantType::LabeledArrayInt>(vmap[key].as<std::string>());
238 pt.put_child(key, labeledArrayToBranch(v.get<LabeledArray<int>>()));
239 } break;
241 auto v = fromString<VariantType::LabeledArrayFloat>(vmap[key].as<std::string>());
242 pt.put_child(key, labeledArrayToBranch(v.get<LabeledArray<float>>()));
243 } break;
245 auto v = fromString<VariantType::LabeledArrayDouble>(vmap[key].as<std::string>());
246 pt.put_child(key, labeledArrayToBranch(v.get<LabeledArray<double>>()));
247 } break;
249 auto v = fromString<VariantType::LabeledArrayString>(vmap[key].as<std::string>());
251 } break;
253 pt.put_child(key, vmap[key].as<boost::property_tree::ptree>());
254 break;
257 default:
258 throw runtime_error("Unknown variant type");
259 }
260 provenance.put(key, "fairmq");
261 } catch (std::runtime_error& re) {
262 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populate", "Aborting because of runtime_error %{public}s", re.what());
263 throw;
264 } catch (std::exception& e) {
265 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populate", "Missing option %{public}s (%{public}s)", key.c_str(), e.what());
266 throw std::invalid_argument(std::string("missing option: ") + key + " (" + e.what() + ")");
267 } catch (...) {
268 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populate", "Aborting because of missing option %{public}s", key.c_str());
269 throw std::invalid_argument(std::string("missing option: ") + key);
270 }
271 }
272 O2_SIGNPOST_END(configuration, cid, "populate", "Done");
273}
274
275template <typename T>
277{
278 if (!input.getLabelsCols().empty() || !input.getLabelsRows().empty()) {
279 return false;
280 }
281 if (spec.getLabelsCols().empty() == false) {
282 input.replaceLabelsCols(spec.getLabelsCols());
283 }
284 if (spec.getLabelsRows().empty() == false) {
285 input.replaceLabelsRows(spec.getLabelsRows());
286 }
287 return true;
288}
289
290void PropertyTreeHelpers::populate(std::vector<ConfigParamSpec> const& schema,
291 boost::property_tree::ptree& pt,
292 boost::property_tree::ptree const& in,
293 boost::property_tree::ptree& provenance,
294 std::string const& provenanceLabel)
295{
296 O2_SIGNPOST_ID_GENERATE(cid, configuration);
297 O2_SIGNPOST_START(configuration, cid, "populate", "Filling parameters from ptree");
298 for (auto const& spec : schema) {
299 // strip short version to get the correct key
300 std::string key = spec.name.substr(0, spec.name.find(','));
301 auto it = in.get_child_optional(key);
302 if (!it) {
303 it = in.get_child_optional(boost::property_tree::path(key, '/'));
304 }
305 if (!it) {
306 continue;
307 }
308 try {
309 switch (spec.type) {
310 case VariantType::Int:
311 pt.put(key, (*it).get_value<int>());
312 break;
314 pt.put(key, (*it).get_value<int8_t>());
315 break;
317 pt.put(key, (*it).get_value<int16_t>());
318 break;
320 pt.put(key, (*it).get_value<uint8_t>());
321 break;
323 pt.put(key, (*it).get_value<uint16_t>());
324 break;
326 pt.put(key, (*it).get_value<uint32_t>());
327 break;
329 pt.put(key, (*it).get_value<uint64_t>());
330 break;
332 pt.put(key, (*it).get_value<int64_t>());
333 break;
335 pt.put(key, (*it).get_value<float>());
336 break;
338 pt.put(key, (*it).get_value<double>());
339 break;
341 pt.put(key, (*it).get_value<std::string>());
342 break;
343 case VariantType::Bool: {
344 auto v = (*it).get_value<bool>();
345 O2_SIGNPOST_EVENT_EMIT(configuration, cid, "populate", "Setting %{public}s: %{public}s", key.c_str(), v ? "true" : "false");
346 pt.put(key, (*it).get_value<bool>());
347 } break;
357 pt.put_child(key, *it);
358 break;
360 auto v = labeledArrayFromBranch<int>(it.value());
361 if (!replaceLabels(v, spec.defaultValue.get<LabeledArray<int>>())) {
362 pt.put_child(key, *it);
363 } else {
364 pt.put_child(key, labeledArrayToBranch(std::move(v)));
365 }
366 }; break;
368 auto v = labeledArrayFromBranch<float>(it.value());
369 if (!replaceLabels(v, spec.defaultValue.get<LabeledArray<float>>())) {
370 pt.put_child(key, *it);
371 } else {
372 pt.put_child(key, labeledArrayToBranch(std::move(v)));
373 }
374 }; break;
376 auto v = labeledArrayFromBranch<double>(it.value());
377 if (!replaceLabels(v, spec.defaultValue.get<LabeledArray<double>>())) {
378 pt.put_child(key, *it);
379 } else {
380 pt.put_child(key, labeledArrayToBranch(std::move(v)));
381 }
382 }; break;
384 auto v = labeledArrayFromBranch<std::string>(it.value());
385 if (!replaceLabels(v, spec.defaultValue.get<LabeledArray<std::string>>())) {
386 pt.put_child(key, *it);
387 } else {
388 pt.put_child(key, labeledArrayToBranch(std::move(v)));
389 }
390 }; break;
393 default:
394 throw std::runtime_error("Unknown variant type");
395 }
396 provenance.put(key, provenanceLabel);
397 } catch (std::runtime_error& re) {
398 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populate", "Aborting during processing of %{public}s because of runtime_error %{public}s",
399 key.c_str(), re.what());
400 throw;
401 } catch (std::exception& e) {
402 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populate", "Missing option %{public}s (%{public}s)", key.c_str(), e.what());
403 throw std::invalid_argument(std::string("missing option: ") + key + " (" + e.what() + ")");
404 } catch (...) {
405 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populate", "Aborting because of missing option %{public}s", key.c_str());
406 throw std::invalid_argument(std::string("missing option: ") + key);
407 }
408 }
409 O2_SIGNPOST_END(configuration, cid, "populate", "Done");
410}
411
412namespace
413{
414void traverseRecursive(const boost::property_tree::ptree& parent,
415 const boost::property_tree::ptree::path_type& childPath,
416 const boost::property_tree::ptree& child,
418{
419 using boost::property_tree::ptree;
420
421 method(parent, childPath, child);
422 for (ptree::const_iterator it = child.begin(); it != child.end(); ++it) {
423 ptree::path_type curPath = childPath / ptree::path_type(it->first);
424 traverseRecursive(parent, curPath, it->second, method);
425 }
426}
427} // namespace
428
429template <>
430void PropertyTreeHelpers::traverse<boost::property_tree::ptree>(const boost::property_tree::ptree& parent, PropertyTreeHelpers::WalkerFunction<boost::property_tree::ptree>& method)
431{
432 traverseRecursive(parent, "", parent, method);
433}
434
435} // namespace o2::framework
#define O2_DECLARE_DYNAMIC_LOG(name)
Definition Signpost.h:489
#define O2_SIGNPOST_END(log, id, name, format,...)
Definition Signpost.h:608
#define O2_SIGNPOST_ID_GENERATE(name, log)
Definition Signpost.h:506
#define O2_SIGNPOST_EVENT_EMIT(log, id, name, format,...)
Definition Signpost.h:522
#define O2_SIGNPOST_END_WITH_ERROR(log, id, name, format,...)
Definition Signpost.h:616
#define O2_SIGNPOST_START(log, id, name, format,...)
Definition Signpost.h:602
template o2::framework::LabeledArray< std::string > o2::framework::labeledArrayFromBranch< std::string >(boost::property_tree::ptree const &tree)
StringRef key
void replaceLabelsRows(std::vector< std::string > const &labels)
Definition Array2D.h:260
void replaceLabelsCols(std::vector< std::string > const &labels)
Definition Array2D.h:265
const GLdouble * v
Definition glcorearb.h:832
GLsizei const GLfloat * value
Definition glcorearb.h:819
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
RuntimeErrorRef runtime_error(const char *)
boost::property_tree::ptree labeledArrayToBranch(LabeledArray< T > &&array)
auto replaceLabels(LabeledArray< T > &input, LabeledArray< T > &&spec)
boost::property_tree::ptree vectorToBranch(T *values, size_t size)
boost::property_tree::ptree array2DToBranch(Array2D< T > &&array)
RuntimeErrorRef runtime_error_f(const char *,...)
auto getLabelsRows() const
Definition Array2D.h:147
auto getLabelsCols() const
Definition Array2D.h:152
static void populate(std::vector< ConfigParamSpec > const &schema, boost::property_tree::ptree &tree, boost::program_options::variables_map const &vmap, boost::property_tree::ptree &provenance)
std::function< void(boost::property_tree::ptree const &, typename T::path_type, boost::property_tree::ptree const &)> WalkerFunction
static void populateDefaults(std::vector< ConfigParamSpec > const &schema, boost::property_tree::ptree &tree, boost::property_tree::ptree &provenance)
const std::string str