ATLAS Offline Software
DataStructure.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include <iostream>
7 
8 #define BOOST_BIND_GLOBAL_PLACEHOLDERS // Needed to silence Boost pragma message
9 #include "boost/property_tree/json_parser.hpp"
10 
12 {}
13 
14 
17 {}
18 
19 TrigConf::DataStructure::DataStructure(const std::string & name, const ptree & data) :
20  m_initialized(true),
21  m_dataPtr(&data),
22  m_name(name)
23 {}
24 
25 
27  m_initialized(true),
28  m_dataSPtr(std::make_shared<ptree>(std::move(data)))
29 {}
30 
32  m_initialized(true),
33  m_dataSPtr(std::make_shared<ptree>(std::move(data))),
34  m_name(name)
35 {}
36 
37 
38 void
40 {
41  clear();
42  m_initialized = true;
43  m_dataSPtr.reset();
44  m_dataPtr = &data;
45  update();
46 }
47 
48 
49 void
51 {
52  clear();
53  m_initialized = true;
54  m_dataSPtr = std::make_shared<ptree>(std::move(data));
55  m_dataPtr = nullptr;
56  update();
57 }
58 
59 void TrigConf::DataStructure::setName(const std::string& n) {
60  m_name = n;
61 }
62 
63 
64 void
66 {
67  m_initialized = false;
68  m_dataSPtr = nullptr;
69  m_dataPtr = nullptr;
70 }
71 
72 
73 bool
75  return data().empty(); // just a key->value pair, no children
76 }
77 
78 
79 std::string
81  const std::string value = data().get_value<std::string>();
82  return value;
83 }
84 
85 bool
86 TrigConf::DataStructure::hasAttribute(const std::string & key) const {
87  const auto & child = data().get_child_optional( key );
88  if( ! bool(child) ) // key does not exist
89  return false;
90  return child.get().empty(); // if empty then it is an attribute, otherwise a child note
91 }
92 
93 bool
94 TrigConf::DataStructure::isNull(const std::string & key) const {
95  auto child = data().get_child_optional( key );
96  if( ! child ) {
97  return false;
98  }
99  return child->get_value<std::string>() == "null";
100 }
101 
102 
103 std::string
105  return "DataStructure";
106 }
107 
108 const std::string &
110  return m_name;
111 }
112 
113 bool
114 TrigConf::DataStructure::hasChild(const std::string & path) const {
115  const auto & child = data().get_child_optional( path );
116  return bool(child);
117 }
118 
119 
120 std::string
121 TrigConf::DataStructure::operator[](const std::string & key) const
122 {
123  const auto & obj = data().get_child(key);
124  // check if the key points to a plain string value
125  if ( !obj.empty() ) {
126  if ( obj.front().first.empty() ) {
127  throw std::runtime_error(className() + "#" + name() + ": structure '" + key + "' is not a simple attribute but a list [], it needs to be accessed via getList(\"" + key + "\") -> vector<DataStructure>");
128  } else {
129  throw std::runtime_error(className() + "#" + name() + ": structure '" + key + "' is not a simple attribute but an object {}, it needs to be accessed via getObject(\"" + key + "\") -> DataStructure");
130  }
131  }
132  return obj.data();
133 }
134 
135 const std::string &
136 TrigConf::DataStructure::getAttribute(const std::string & key, bool ignoreIfMissing, const std::string & def) const
137 {
138  const auto & obj = data().get_child_optional(key);
139  if( !obj ) {
140  if( ignoreIfMissing ) {
141  return def;
142  } else {
143  throw std::runtime_error(className() + "#" + name() + ": structure '" + key + "' does not exist" );
144  }
145  }
146  // check if the key points to a plain string value
147  if ( !obj.get().empty() ) {
148  if ( obj.get().front().first.empty() ) {
149  throw std::runtime_error(className() + "#" + name() + ": structure '" + key + "' is not a simple attribute but a list [], it needs to be accessed via getList(\"" + key + "\") -> vector<DataStructure>");
150  } else {
151  throw std::runtime_error(className() + "#" + name() + ": structure '" + key + "' is not a simple attribute but an object {}, it needs to be accessed via getObject(\"" + key + "\") -> DataStructure");
152  }
153  }
154  return obj.get().data();
155 }
156 
157 std::vector<TrigConf::DataStructure>
158 TrigConf::DataStructure::getList(const std::string & pathToChild, bool ignoreIfMissing) const
159 {
160  std::vector<TrigConf::DataStructure> childList;
161  const auto & list = data().get_child_optional(pathToChild);
162  if( ! list ) {
163  if ( ignoreIfMissing ) {
164  return childList;
165  } else {
166  throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' does not exist.");
167  }
168  }
169 
170  // check if the pathToChild points to a list
171 
172  // this check is not complete, because boost::ptree can not
173  // distinguish between and empty list and an empty string. In both cases
174  // the value is empty and there are no children
175 
176  if ( list.get().empty() ) {
177  if ( list.get().get_value<std::string>() != "" ) {
178  // if the value is not empty, then it is for sure an attribute ("key" : "value")
179  throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' is not a list [] but a simple attribute, it needs to be accessed via [\"" + pathToChild + "\"] -> string");
180  }
181  // else: if the value is empty, we can not say for sure and will not
182  // give this debugging hint (an empty list will be returned
183  } else if ( ! list.get().front().first.empty() ) {
184  throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' is not a list [] but an object {}, it needs to be accessed via getObject(\"" + pathToChild + "\") -> DataStructure");
185  }
186 
187  childList.reserve(list.get().size());
188 
189  for( auto & childData : list.get() )
190  childList.emplace_back( childData.second );
191 
192  return childList;
193 }
194 
195 
196 std::optional<std::vector<TrigConf::DataStructure> >
197 TrigConf::DataStructure::getList_optional(const std::string & pathToChild) const
198 {
199  if(data().find(pathToChild) == data().not_found()) {
200  return std::nullopt;
201  }
202  return std::optional<std::vector<TrigConf::DataStructure> >(getList(pathToChild));
203 }
204 
205 
207 TrigConf::DataStructure::getObject(const std::string & pathToChild, bool ignoreIfMissing) const
208 {
209  const auto & obj = data().get_child_optional(pathToChild);
210  if( ! obj ) {
211  if ( ignoreIfMissing ) {
212  return DataStructure();
213  } else {
214  throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' does not exist.");
215  }
216  }
217  // check if the pathToChild is an attribute
218  if( obj.get().get_value<std::string>() != "" ) {
219  throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' is not an object {} but a simple attribute, it needs to be accessed via [\"" + pathToChild + "\"] -> string");
220  }
221  // check if the pathToChild points to a list
222  if ( obj.get().front().first.empty() ) {
223  throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' is not an object {} but a list [], it needs to be accessed via getList(\"" + pathToChild + "\") -> vector<DataStructure>");
224  }
225  return { obj.get() };
226 }
227 
228 
229 std::optional<TrigConf::DataStructure>
230 TrigConf::DataStructure::getObject_optional(const std::string & pathToChild) const
231 {
232 
233  if(const auto & obj = data().get_child_optional(pathToChild)) {
234  // check if the pathToChild is an attribute
235  if( obj.get().get_value<std::string>() != "" ) {
236  throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' is not an object {} but a simple attribute, it needs to be accessed via [\"" + pathToChild + "\"] -> string");
237  }
238  // check if the pathToChild points to a list
239  if ( obj.get().front().first.empty() ) {
240  throw std::runtime_error(className() + "#" + name() + ": structure '" + pathToChild + "' is not an object {} but a list [], it needs to be accessed via getList(\"" + pathToChild + "\") -> vector<DataStructure>");
241  }
242  return std::optional<TrigConf::DataStructure>(obj.get());
243  }
244  return std::nullopt;
245 }
246 
247 
248 
249 std::vector<std::string>
251 {
252  std::vector<std::string> keys;
253  if ( ! data().empty() &&
254  ! data().front().first.empty() )
255  {
256  keys.reserve(data().size());
257  for( auto & entry : data() ) {
258  keys.push_back(entry.first);
259  }
260  }
261  return keys;
262 }
263 
264 void
266 {
267  boost::property_tree::json_parser::write_json( os, data() );
268 }
269 
270 
271 void
272 TrigConf::DataStructure::print(std::ostream & os) const
273 {
274  printElement("", data(), 0, os);
275  os << std::endl;
276 }
277 
278 void
279 TrigConf::DataStructure::printElement(const std::string& key, const ptree & data, uint level, std::ostream & os)
280 {
281  constexpr char del = '"';
282 
283  const std::string value = data.get_value<std::string>();
284 
285  if( data.empty() ) { // no children, so just a key->value pair
286  uint n(4*level); while(n--) os << " ";
287  os << del << key << del << ": " << del << value << del;
288  return;
289  }
290 
291 
292  bool isArray ( data.begin()->first.empty() ); // dictionaries have keys, arrays don't
293  { uint n(4*level); while(n--) os << " "; }
294  if ( ! key.empty() )
295  os << del << key << del << ": ";
296  os << (isArray ? "[" : "{") << std::endl;
297 
298  size_t childCounter = data.size();
299  for( const boost::property_tree::ptree::value_type & x : data ) {
300  printElement(x.first, x.second, level + 1, os);
301  if( --childCounter ) os << ",";
302  os << std::endl;
303  }
304  { uint n(4*level); while(n--) os << " "; }
305  os << (isArray ? "]" : "}");
306 
307 }
TrigConf::DataStructure::getObject
DataStructure getObject(const std::string &pathToChild, bool ignoreIfMissing=false) const
Access to configuration object.
Definition: DataStructure.cxx:207
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:128
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
TrigConf::DataStructure::getObject_optional
std::optional< TrigConf::DataStructure > getObject_optional(const std::string &pathToChild) const
Definition: DataStructure.cxx:230
TrigConf::DataStructure::printElement
static void printElement(const std::string &key, const ptree &data, uint level=0, std::ostream &os=std::cout)
Static function to print a ptree object.
Definition: DataStructure.cxx:279
TrigConf::DataStructure::setName
void setName(const std::string &n)
Setting the configuration element name.
Definition: DataStructure.cxx:59
TrigConf::DataStructure::getAttribute
T getAttribute(const std::string &key, bool ignoreIfMissing=false, const T &def=T()) const
Access to simple attribute.
Definition: DataStructure.h:152
athena.value
value
Definition: athena.py:124
TrigConf::DataStructure::getKeys
std::vector< std::string > getKeys() const
Access to the keys of an DataStructure which presents a dictionary.
Definition: DataStructure.cxx:250
TrigConf::DataStructure::name
virtual const std::string & name() const final
Definition: DataStructure.cxx:109
x
#define x
empty
bool empty(TH1 *h)
Definition: computils.cxx:294
TrigConf::DataStructure::setData
void setData(const ptree &data)
Setting the configuration data.
Definition: DataStructure.cxx:39
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
JetTagCalibConfig.className
string className
Definition: JetTagCalibConfig.py:36
TrigConf::DataStructure::hasChild
bool hasChild(const std::string &path) const
Check if child exists.
Definition: DataStructure.cxx:114
uint
unsigned int uint
Definition: LArOFPhaseFill.cxx:20
TrigConf::DataStructure::operator[]
std::string operator[](const std::string &key) const
Access to simple attribute.
Definition: DataStructure.cxx:121
beamspotman.n
n
Definition: beamspotman.py:731
TrigConf::DataStructure::className
virtual std::string className() const
A string that is the name of the class.
Definition: DataStructure.cxx:104
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
TrigConf::name
Definition: HLTChainList.h:35
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
TrigConf::DataStructure::getList_optional
std::optional< std::vector< DataStructure > > getList_optional(const std::string &pathToChild) const
Definition: DataStructure.cxx:197
TrigConf::DataStructure::getList
std::vector< DataStructure > getList(const std::string &pathToChild, bool ignoreIfMissing=false) const
Access to array structure.
Definition: DataStructure.cxx:158
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
TrigConf::DataStructure::printRaw
void printRaw(std::ostream &os=std::cout) const
Definition: DataStructure.cxx:265
TrigConf::DataStructure
Base class for Trigger configuration data and wrapper around underlying representation.
Definition: DataStructure.h:37
TrigConf::DataStructure::getValue
std::string getValue() const
Access to simple content.
Definition: DataStructure.cxx:80
TrigConf::DataStructure::isNull
bool isNull(const std::string &key) const
Check if an attribute is null.
Definition: DataStructure.cxx:94
VKalVrtAthena::varHolder_detail::clear
void clear(T &var)
Definition: NtupleVars.h:48
DeMoScan.first
bool first
Definition: DeMoScan.py:536
TrigConf::DataStructure::clear
virtual void clear()
Clearing the configuration data.
Definition: DataStructure.cxx:65
TrigConf::DataStructure::print
virtual void print(std::ostream &os=std::cout) const
Definition: DataStructure.cxx:272
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:798
python.PyAthena.obj
obj
Definition: PyAthena.py:132
DataStructure.h
TrigConf::DataStructure::DataStructure
DataStructure()
Default constructor, leading to an uninitialized configuration object.
Definition: DataStructure.cxx:11
TrigConf::DataStructure::isValue
bool isValue() const
Check for attribute.
Definition: DataStructure.cxx:74
xAOD::bool
setBGCode setTAP setLVL2ErrorBits bool
Definition: TrigDecision_v1.cxx:60
TrigConf::DataStructure::ptree
boost::property_tree::ptree ptree
Definition: DataStructure.h:40
printElement
int printElement(GeoElement *&p_element)
Definition: RDBMaterialManager.cxx:60
WriteBchToCool.update
update
Definition: WriteBchToCool.py:67
TrigConf::DataStructure::hasAttribute
bool hasAttribute(const std::string &key) const
Check for attribute.
Definition: DataStructure.cxx:86
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37