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
39template <typename T>
40auto replaceLabels(LabeledArray<T>& input, LabeledArray<T>&& spec)
41{
42 if (!input.getLabelsCols().empty() || !input.getLabelsRows().empty()) {
43 return false;
44 }
45 if (spec.getLabelsCols().empty() == false) {
46 input.replaceLabelsCols(spec.getLabelsCols());
47 }
48 if (spec.getLabelsRows().empty() == false) {
49 input.replaceLabelsRows(spec.getLabelsRows());
50 }
51 return true;
52}
53
55template <typename T, VariantType V>
56boost::property_tree::ptree labeledArrayFromStringToBranch(std::string const& str, Variant const& defaultValue)
57{
58 auto v = fromString<V>(str).template get<LabeledArray<T>>();
59 if (defaultValue.type() == V) {
60 replaceLabels(v, defaultValue.get<LabeledArray<T>>());
61 }
62 return labeledArrayToBranch(std::move(v));
63}
64} // namespace
65void PropertyTreeHelpers::populateDefaults(std::vector<ConfigParamSpec> const& schema,
66 boost::property_tree::ptree& pt,
67 boost::property_tree::ptree& provenance)
68{
69 O2_SIGNPOST_ID_GENERATE(cid, configuration);
70 O2_SIGNPOST_START(configuration, cid, "populateDefaults", "Filling with defaults");
71 for (auto const& spec : schema) {
72 std::string key = spec.name.substr(0, spec.name.find(','));
73 try {
74 if (spec.defaultValue.type() == VariantType::Empty) {
75 continue;
76 }
77 switch (spec.type) {
79 pt.put(key, spec.defaultValue.get<int>());
80 break;
82 pt.put(key, spec.defaultValue.get<int8_t>());
83 break;
85 pt.put(key, spec.defaultValue.get<int16_t>());
86 break;
88 pt.put(key, spec.defaultValue.get<uint8_t>());
89 break;
91 pt.put(key, spec.defaultValue.get<uint16_t>());
92 break;
94 pt.put(key, spec.defaultValue.get<uint32_t>());
95 break;
97 pt.put(key, spec.defaultValue.get<uint64_t>());
98 break;
100 pt.put(key, spec.defaultValue.get<int64_t>());
101 break;
103 pt.put(key, spec.defaultValue.get<float>());
104 break;
106 pt.put(key, spec.defaultValue.get<double>());
107 break;
109 pt.put(key, spec.defaultValue.get<std::string>());
110 break;
111 case VariantType::Bool: {
112 bool value = spec.defaultValue.get<bool>();
113 O2_SIGNPOST_EVENT_EMIT(configuration, cid, "populateDefaults", "Setting %{public}s: %{public}s", key.c_str(), value ? "true" : "false");
114 pt.put(key, value);
115 break;
116 }
118 pt.put_child(key, boost::property_tree::ptree{});
119 break;
121 pt.put_child(key, vectorToBranch(spec.defaultValue.get<int*>(), spec.defaultValue.size()));
122 break;
124 pt.put_child(key, vectorToBranch(spec.defaultValue.get<float*>(), spec.defaultValue.size()));
125 break;
127 pt.put_child(key, vectorToBranch(spec.defaultValue.get<double*>(), spec.defaultValue.size()));
128 break;
130 pt.put_child(key, vectorToBranch(spec.defaultValue.get<bool*>(), spec.defaultValue.size()));
131 break;
133 pt.put_child(key, vectorToBranch(spec.defaultValue.get<std::string*>(), spec.defaultValue.size()));
134 break;
136 pt.put_child(key, array2DToBranch(spec.defaultValue.get<Array2D<int>>()));
137 break;
139 pt.put_child(key, array2DToBranch(spec.defaultValue.get<Array2D<float>>()));
140 break;
142 pt.put_child(key, array2DToBranch(spec.defaultValue.get<Array2D<double>>()));
143 break;
145 pt.put_child(key, labeledArrayToBranch(spec.defaultValue.get<LabeledArray<int>>()));
146 break;
148 pt.put_child(key, labeledArrayToBranch(spec.defaultValue.get<LabeledArray<float>>()));
149 break;
151 pt.put_child(key, labeledArrayToBranch(spec.defaultValue.get<LabeledArray<double>>()));
152 break;
154 pt.put_child(key, labeledArrayToBranch(spec.defaultValue.get<LabeledArray<std::string>>()));
155 break;
158 default:
159 throw runtime_error_f("Unknown variant type", spec.type);
160 }
161 provenance.put(key, "default");
162 } catch (std::runtime_error& re) {
163 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populateDefaults", "Aborting because of runtime_error %{public}s", re.what());
164 throw;
165 } catch (std::exception& e) {
166 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populateDefaults", "Missing option %{public}s (%{public}s)", key.c_str(), e.what());
167 throw std::invalid_argument(std::string("missing option: ") + key + " (" + e.what() + ")");
168 } catch (...) {
169 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populateDefaults", "Aborting because of missing option %{public}s", key.c_str());
170 throw std::invalid_argument(std::string("missing option: ") + key);
171 }
172 }
173 O2_SIGNPOST_END(configuration, cid, "populateDefaults", "Done");
174}
175
176void PropertyTreeHelpers::populate(std::vector<ConfigParamSpec> const& schema,
177 boost::property_tree::ptree& pt,
178 boost::program_options::variables_map const& vmap,
179 boost::property_tree::ptree& provenance)
180{
181 O2_SIGNPOST_ID_GENERATE(cid, configuration);
182 O2_SIGNPOST_START(configuration, cid, "populate", "Filling parameters from variables_map");
183 for (auto const& spec : schema) {
184 // strip short version to get the correct key
185 std::string key = spec.name.substr(0, spec.name.find(','));
186 if (vmap.count(key) == 0) {
187 continue;
188 }
189 try {
190 switch (spec.type) {
191 case VariantType::Int:
192 pt.put(key, vmap[key].as<int>());
193 break;
195 pt.put(key, vmap[key].as<int8_t>());
196 break;
198 pt.put(key, vmap[key].as<int16_t>());
199 break;
201 pt.put(key, vmap[key].as<uint8_t>());
202 break;
204 pt.put(key, vmap[key].as<uint16_t>());
205 break;
207 pt.put(key, vmap[key].as<uint32_t>());
208 break;
210 pt.put(key, vmap[key].as<uint64_t>());
211 break;
213 pt.put(key, vmap[key].as<int64_t>());
214 break;
216 pt.put(key, vmap[key].as<float>());
217 break;
219 pt.put(key, vmap[key].as<double>());
220 break;
222 if (auto const* v = boost::any_cast<std::string>(&vmap[key].value())) {
223 pt.put(key, *v);
224 }
225 break;
226 case VariantType::Bool: {
227 auto v = vmap[key].as<bool>();
228 O2_SIGNPOST_EVENT_EMIT(configuration, cid, "populate", "Setting %{public}s: %{public}s", key.c_str(), v ? "true" : "false");
229 pt.put(key, v);
230 } break;
232 auto v = fromString<VariantType::ArrayInt>(vmap[key].as<std::string>());
233 pt.put_child(key, vectorToBranch<int>(v.get<int*>(), v.size()));
234 } break;
236 auto v = fromString<VariantType::ArrayFloat>(vmap[key].as<std::string>());
237 pt.put_child(key, vectorToBranch<float>(v.get<float*>(), v.size()));
238 } break;
240 auto v = fromString<VariantType::ArrayDouble>(vmap[key].as<std::string>());
241 pt.put_child(key, vectorToBranch<double>(v.get<double*>(), v.size()));
242 } break;
244 // pt.put_child(key, vectorToBranch<bool>(stringToVector<bool>(vmap[key].as<std::string>())));
245 break;
247 auto v = fromString<VariantType::ArrayString>(vmap[key].as<std::string>());
248 pt.put_child(key, vectorToBranch<std::string>(v.get<std::string*>(), v.size()));
249 } break;
251 auto v = fromString<VariantType::Array2DInt>(vmap[key].as<std::string>());
252 pt.put_child(key, array2DToBranch<int>(v.get<Array2D<int>>()));
253 } break;
255 auto v = fromString<VariantType::Array2DFloat>(vmap[key].as<std::string>());
256 pt.put_child(key, array2DToBranch<float>(v.get<Array2D<float>>()));
257 } break;
259 auto v = fromString<VariantType::Array2DDouble>(vmap[key].as<std::string>());
260 pt.put_child(key, array2DToBranch<double>(v.get<Array2D<double>>()));
261 } break;
263 pt.put_child(key, labeledArrayFromStringToBranch<int, VariantType::LabeledArrayInt>(vmap[key].as<std::string>(), spec.defaultValue));
264 break;
266 pt.put_child(key, labeledArrayFromStringToBranch<float, VariantType::LabeledArrayFloat>(vmap[key].as<std::string>(), spec.defaultValue));
267 break;
269 pt.put_child(key, labeledArrayFromStringToBranch<double, VariantType::LabeledArrayDouble>(vmap[key].as<std::string>(), spec.defaultValue));
270 break;
272 pt.put_child(key, labeledArrayFromStringToBranch<std::string, VariantType::LabeledArrayString>(vmap[key].as<std::string>(), spec.defaultValue));
273 break;
275 pt.put_child(key, vmap[key].as<boost::property_tree::ptree>());
276 break;
279 default:
280 throw runtime_error("Unknown variant type");
281 }
282 provenance.put(key, "fairmq");
283 } catch (std::runtime_error& re) {
284 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populate", "Aborting because of runtime_error %{public}s", re.what());
285 throw;
286 } catch (std::exception& e) {
287 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populate", "Missing option %{public}s (%{public}s)", key.c_str(), e.what());
288 throw std::invalid_argument(std::string("missing option: ") + key + " (" + e.what() + ")");
289 } catch (...) {
290 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populate", "Aborting because of missing option %{public}s", key.c_str());
291 throw std::invalid_argument(std::string("missing option: ") + key);
292 }
293 }
294 O2_SIGNPOST_END(configuration, cid, "populate", "Done");
295}
296
297void PropertyTreeHelpers::populate(std::vector<ConfigParamSpec> const& schema,
298 boost::property_tree::ptree& pt,
299 boost::property_tree::ptree const& in,
300 boost::property_tree::ptree& provenance,
301 std::string const& provenanceLabel)
302{
303 O2_SIGNPOST_ID_GENERATE(cid, configuration);
304 O2_SIGNPOST_START(configuration, cid, "populate", "Filling parameters from ptree");
305 for (auto const& spec : schema) {
306 // strip short version to get the correct key
307 std::string key = spec.name.substr(0, spec.name.find(','));
308 auto it = in.get_child_optional(key);
309 if (!it) {
310 it = in.get_child_optional(boost::property_tree::path(key, '/'));
311 }
312 if (!it) {
313 continue;
314 }
315 try {
316 switch (spec.type) {
317 case VariantType::Int:
318 pt.put(key, (*it).get_value<int>());
319 break;
321 pt.put(key, (*it).get_value<int8_t>());
322 break;
324 pt.put(key, (*it).get_value<int16_t>());
325 break;
327 pt.put(key, (*it).get_value<uint8_t>());
328 break;
330 pt.put(key, (*it).get_value<uint16_t>());
331 break;
333 pt.put(key, (*it).get_value<uint32_t>());
334 break;
336 pt.put(key, (*it).get_value<uint64_t>());
337 break;
339 pt.put(key, (*it).get_value<int64_t>());
340 break;
342 pt.put(key, (*it).get_value<float>());
343 break;
345 pt.put(key, (*it).get_value<double>());
346 break;
348 pt.put(key, (*it).get_value<std::string>());
349 break;
350 case VariantType::Bool: {
351 auto v = (*it).get_value<bool>();
352 O2_SIGNPOST_EVENT_EMIT(configuration, cid, "populate", "Setting %{public}s: %{public}s", key.c_str(), v ? "true" : "false");
353 pt.put(key, (*it).get_value<bool>());
354 } break;
364 pt.put_child(key, *it);
365 break;
367 auto v = labeledArrayFromBranch<int>(it.value());
368 if (!replaceLabels(v, spec.defaultValue.get<LabeledArray<int>>())) {
369 pt.put_child(key, *it);
370 } else {
371 pt.put_child(key, labeledArrayToBranch(std::move(v)));
372 }
373 }; break;
375 auto v = labeledArrayFromBranch<float>(it.value());
376 if (!replaceLabels(v, spec.defaultValue.get<LabeledArray<float>>())) {
377 pt.put_child(key, *it);
378 } else {
379 pt.put_child(key, labeledArrayToBranch(std::move(v)));
380 }
381 }; break;
383 auto v = labeledArrayFromBranch<double>(it.value());
384 if (!replaceLabels(v, spec.defaultValue.get<LabeledArray<double>>())) {
385 pt.put_child(key, *it);
386 } else {
387 pt.put_child(key, labeledArrayToBranch(std::move(v)));
388 }
389 }; break;
391 auto v = labeledArrayFromBranch<std::string>(it.value());
392 if (!replaceLabels(v, spec.defaultValue.get<LabeledArray<std::string>>())) {
393 pt.put_child(key, *it);
394 } else {
395 pt.put_child(key, labeledArrayToBranch(std::move(v)));
396 }
397 }; break;
400 default:
401 throw std::runtime_error("Unknown variant type");
402 }
403 provenance.put(key, provenanceLabel);
404 } catch (std::runtime_error& re) {
405 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populate", "Aborting during processing of %{public}s because of runtime_error %{public}s",
406 key.c_str(), re.what());
407 throw;
408 } catch (std::exception& e) {
409 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populate", "Missing option %{public}s (%{public}s)", key.c_str(), e.what());
410 throw std::invalid_argument(std::string("missing option: ") + key + " (" + e.what() + ")");
411 } catch (...) {
412 O2_SIGNPOST_END_WITH_ERROR(configuration, cid, "populate", "Aborting because of missing option %{public}s", key.c_str());
413 throw std::invalid_argument(std::string("missing option: ") + key);
414 }
415 }
416 O2_SIGNPOST_END(configuration, cid, "populate", "Done");
417}
418
419namespace
420{
421void traverseRecursive(const boost::property_tree::ptree& parent,
422 const boost::property_tree::ptree::path_type& childPath,
423 const boost::property_tree::ptree& child,
425{
426 using boost::property_tree::ptree;
427
428 method(parent, childPath, child);
429 for (ptree::const_iterator it = child.begin(); it != child.end(); ++it) {
430 ptree::path_type curPath = childPath / ptree::path_type(it->first);
431 traverseRecursive(parent, curPath, it->second, method);
432 }
433}
434} // namespace
435
436template <>
437void PropertyTreeHelpers::traverse<boost::property_tree::ptree>(const boost::property_tree::ptree& parent, PropertyTreeHelpers::WalkerFunction<boost::property_tree::ptree>& method)
438{
439 traverseRecursive(parent, "", parent, method);
440}
441
442} // namespace o2::framework
std::shared_ptr< arrow::Schema > schema
unsigned short int uint16_t
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events Show standalone event Run event generator maximum time bin of continuous for triggered for automatic continuous for automatic continuous triggered uint64_t
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char e
#define O2_DECLARE_DYNAMIC_LOG(name)
Definition Signpost.h:490
#define O2_SIGNPOST_END(log, id, name, format,...)
Definition Signpost.h:609
#define O2_SIGNPOST_ID_GENERATE(name, log)
Definition Signpost.h:507
#define O2_SIGNPOST_EVENT_EMIT(log, id, name, format,...)
Definition Signpost.h:523
#define O2_SIGNPOST_END_WITH_ERROR(log, id, name, format,...)
Definition Signpost.h:617
#define O2_SIGNPOST_START(log, id, name, format,...)
Definition Signpost.h:603
template o2::framework::LabeledArray< std::string > o2::framework::labeledArrayFromBranch< std::string >(boost::property_tree::ptree const &tree)
StringRef key
const GLdouble * v
Definition glcorearb.h:832
GLsizei const GLfloat * value
Definition glcorearb.h:819
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
RuntimeErrorRef runtime_error(const char *)
boost::property_tree::ptree labeledArrayToBranch(LabeledArray< T > &&array)
boost::property_tree::ptree array2DToBranch(Array2D< T > &&array)
RuntimeErrorRef runtime_error_f(const char *,...)
boost::property_tree::ptree vectorToBranch(T const *values, size_t size)
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