ATLAS Offline Software
Loading...
Searching...
No Matches
AuxDataFillerTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// $Id$
12
13
14#include "AuxDataFillerTool.h"
18#include "boost/algorithm/string/trim.hpp"
19#include "boost/algorithm/string/split.hpp"
20#include "TROOT.h"
21
22
23namespace D3PD {
24
25
36AuxDataFillerTool::Var::Var (const std::string& the_name,
37 const std::string& the_docstring,
38 const std::vector<std::string>& the_labels,
39 const std::vector<std::string>& the_label_classes,
40 const std::string& the_defstring,
41 bool the_has_default)
42 : name (the_name),
43 docstring (the_docstring),
44 has_default (the_has_default),
45 ptr (0)
46{
48
49 std::string firstName;
51 ti = 0;
52 assert (the_labels.size() == the_label_classes.size());
53 for (size_t i = 0; i < the_labels.size(); i++) {
54 SG::auxid_t auxid = reg.findAuxID (the_labels[i], the_label_classes[i]);
55 if (auxid != SG::null_auxid) {
56 accessors.emplace_back (the_labels[i], the_label_classes[i]);
57
58 std::string name = the_label_classes[i] + "::" + the_labels[i];
59 if (!label.empty())
60 label += ",";
61 label += name;
62
63 // Find the type of the variable.
64 if (ti == 0) {
65 ti = reg.getType (auxid);
66 type.init (reg.getTypeName (auxid));
67 firstName = std::move(name);
68 firstId = auxid;
69 }
70 else {
71 if (ti != reg.getType (auxid)) {
72 std::string errstr = "Inconsistent types for aux data: " +
73 firstName + " (" + reg.getTypeName (firstId) +") vs " +
74 name + " (" + reg.getTypeName (auxid) + ")";
75 throw std::runtime_error (errstr);
76 }
77 }
78 }
79 }
80
81 if (the_has_default && !the_defstring.empty()) {
82 defobj = RootUtils::Type::unique_ptr (type.create(), type);
83 type.fromString (defobj.get(), the_defstring);
84 }
85}
86
87
95{
96 for (const auto& a : accessors) {
97 if (a.isAvailable(p))
98 return a(p);
99 }
100 return 0;
101}
102
103
111 const std::string& name,
112 const IInterface* parent)
113 : BlockFillerTool<SG::AuxElement> (type, name, parent)
114{
115 declareProperty ("AuxPrefix", m_auxprefix,
116 "Prefix to add to aux data names.");
117
118 declareProperty ("Vars", m_varString,
119 "Specify variables to fill. "
120 "Each is of the form VAR[=AUXVAR][<DEF][#DOCSTRING].\n"
121 "VAR is the D3PD variable name. "
122 "AUXVAR is the aux data item name. It may contain a class "
123 "name before a ::. If omitted, it defaults to VAR. "
124 "It may also be a comma-separated string of variable "
125 "names; the first one found to be present will be used. "
126 "If the < is present, then it is not an error for this "
127 "variable to be missing. If not empty, DEF specifies the "
128 "default value to use (works only for basic types). "
129 "DEF may be preceded with a type name: `TYPE: DEF' to "
130 "specify a type in the case the type of this aux variable "
131 "is unknown. "
132 "An optional documentation string may be given after a #.");
133}
134
135
143
144
149{
150 CHECK( parseVars() );
151 for (auto& v : m_vars) {
152 std::string docstring = "[AuxData: ";
153 docstring += v->label;
154 docstring += "] ";
155 docstring += v->docstring;
156 CHECK( addVariable (v->name, *v->ti, v->ptr, docstring, v->defobj.get()) );
157 }
158 return StatusCode::SUCCESS;
159}
160
161
171{
172 for (auto& v : m_vars) {
173 const void* aux = v->access(p);
174 if (aux)
175 v->type.assign (v->ptr, aux);
176 else if (!v->has_default) {
177 // Trigger an exception.
178 v->accessors[0](p);
179 }
180 }
181
182 return StatusCode::SUCCESS;
183}
184
185
190{
191 for (std::string name : m_varString) {
192 std::string docstring;
193 std::string::size_type ipos = name.find ('#');
194 if (ipos != std::string::npos) {
195 docstring = name.substr (ipos+1, std::string::npos);
196 name.resize(ipos);
197 }
198
199 std::string defstring;
200 bool has_default = false;
201 ipos = name.find ('<');
202 if (ipos != std::string::npos) {
203 defstring = name.substr (ipos+1, std::string::npos);
204 name.erase (ipos, std::string::npos);
205 has_default = true;
206 }
207
208 std::string label = name;
209 ipos = name.find ('=');
210 if (ipos != std::string::npos) {
211 name.erase (ipos, std::string::npos);
212 label.erase (0, ipos+1);
213 }
214
215 std::vector<std::string> labels;
216 boost::algorithm::split (labels, label, boost::algorithm::is_any_of(","));
217 std::vector<std::string> label_classes;
218 for (std::string& l : labels) {
219 std::string label_class;
220 ipos = l.find ("::");
221 if (ipos != std::string::npos) {
222 label_class = l.substr (0, ipos);
223 l.erase (0, ipos+2);
224 }
225 boost::algorithm::trim (l);
226 l = m_auxprefix + l;
227 boost::algorithm::trim (label_class);
228 label_classes.push_back (std::move(label_class));
229 }
230
231 boost::algorithm::trim (name);
232 boost::algorithm::trim (docstring);
233 boost::algorithm::trim (defstring);
234
235 // If a type was given in the default field, make sure this variable
236 // name has been registered.
237 if (!defstring.empty()) {
238 ipos = defstring.find (':');
239 if (ipos != std::string::npos) {
240 std::string typname = defstring.substr (0, ipos);
241 boost::algorithm::trim (typname);
242 defstring.erase (0, ipos+1);
243
244 RootUtils::Type typ (typname);
246 const std::type_info* ti = typ.getTypeInfo();
247 if (ti) {
248 for (size_t i = 0; i < labels.size(); i++){
249 auto auxid = reg.getAuxID (*ti, labels[i], label_classes[i]);
250 if (auxid == SG::null_auxid){
251 REPORT_MESSAGE(MSG::WARNING)
252 <<"AuxDataFillerTool::parseVars: auxid is invalid for "<<labels[i]<<"\n";
253 }
254 }
255 }
256 }
257 }
258
259 try {
260 m_vars.push_back (std::make_unique<Var>
261 (name, docstring, labels, label_classes,
262 defstring, has_default));
263 }
264 catch (const std::runtime_error& e) {
265 REPORT_MESSAGE(MSG::ERROR)
266 << "Can't find aux data item(s) " << label
267 << " [" << e.what() << "]";
268 return StatusCode::FAILURE;
269 }
270
271 if (m_vars.back()->accessors.empty()) {
272 REPORT_MESSAGE(MSG::ERROR)
273 << "Can't find aux data item(s) " << label;
274 return StatusCode::FAILURE;
275 }
276 }
277 return StatusCode::SUCCESS;
278}
279
280
281} // namespace D3PD
Copy aux data to D3PD.
Base class for elements of a container that can have aux data.
Handle mappings between names and auxid_t.
Helpers for checking error return status codes and reporting errors.
#define REPORT_MESSAGE(LVL)
Report a message.
#define CHECK(...)
Evaluate an expression and check for errors.
static Double_t a
virtual StatusCode addVariable(const std::string &name, const std::type_info &ti, void *&ptr, const std::string &docstring="", const void *defval=0)
std::vector< std::string > m_varString
Property: Specify variables to fill.
virtual StatusCode fill(const SG::AuxElement &p)
Fill one block — type-safe version.
virtual StatusCode book()
Book variables for this block.
StatusCode parseVars()
Parse the variables property and fill m_vars.
std::string m_auxprefix
Property: Prefix to add to aux data names.
std::vector< std::unique_ptr< Var > > m_vars
Parsed list of variables.
virtual StatusCode initialize()
Standard Gaudi initialize method.
AuxDataFillerTool(const std::string &type, const std::string &name, const IInterface *parent)
Standard Gaudi tool constructor.
Type-safe wrapper for block filler tools.
Wrapper for ROOT types.
Definition Type.h:40
const std::type_info * getTypeInfo() const
Return the type_info for the described type.
Definition Type.cxx:366
Base class for elements of a container that can have aux data.
Definition AuxElement.h:483
Handle mappings between names and auxid_t.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
std::string label(const std::string &format, int i)
Definition label.h:19
Block filler tool for noisy FEB information.
Forward declaration.
static const auxid_t null_auxid
To signal no aux data item.
Definition AuxTypes.h:30
size_t auxid_t
Identifier for a particular aux data item.
Definition AuxTypes.h:27
const std::type_info * ti
Type of the variable, as type_info.
const void * access(const SG::AuxElement &p) const
Try to retrieve an aux data item from p.
bool has_default
If true, this aux variable can be defaulted.
void * ptr
Pointer passed to ID3PD.
std::vector< SG::AuxElement::TypelessConstAccessor > accessors
Aux data accessor(s) for the item.
RootUtils::Type::unique_ptr defobj
If present, a default object instance to use if the aux variable is not present.
std::string label
Name of the aux data item(s).
Var(const std::string &the_name, const std::string &the_docstring, const std::vector< std::string > &the_labels, const std::vector< std::string > &the_label_classes, const std::string &the_defstring, bool the_has_default)
Constructor.
RootUtils::Type type
Type of the item.
std::string name
Name of the variable.
std::string docstring
Docstring for the variable.