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"
19#include "TROOT.h"
20
21
22namespace D3PD {
23
24
35AuxDataFillerTool::Var::Var (const std::string& the_name,
36 const std::string& the_docstring,
37 const std::vector<std::string>& the_labels,
38 const std::vector<std::string>& the_label_classes,
39 const std::string& the_defstring,
40 bool the_has_default)
41 : name (the_name),
42 docstring (the_docstring),
43 has_default (the_has_default),
44 ptr (0)
45{
47
48 std::string firstName;
50 ti = 0;
51 assert (the_labels.size() == the_label_classes.size());
52 for (size_t i = 0; i < the_labels.size(); i++) {
53 SG::auxid_t auxid = reg.findAuxID (the_labels[i], the_label_classes[i]);
54 if (auxid != SG::null_auxid) {
55 accessors.emplace_back (the_labels[i], the_label_classes[i]);
56
57 std::string name = the_label_classes[i] + "::" + the_labels[i];
58 if (!label.empty())
59 label += ",";
60 label += name;
61
62 // Find the type of the variable.
63 if (ti == 0) {
64 ti = reg.getType (auxid);
65 type.init (reg.getTypeName (auxid));
66 firstName = std::move(name);
67 firstId = auxid;
68 }
69 else {
70 if (ti != reg.getType (auxid)) {
71 std::string errstr = "Inconsistent types for aux data: " +
72 firstName + " (" + reg.getTypeName (firstId) +") vs " +
73 name + " (" + reg.getTypeName (auxid) + ")";
74 throw std::runtime_error (errstr);
75 }
76 }
77 }
78 }
79
80 if (the_has_default && !the_defstring.empty()) {
81 defobj = RootUtils::Type::unique_ptr (type.create(), type);
82 type.fromString (defobj.get(), the_defstring);
83 }
84}
85
86
94{
95 for (const auto& a : accessors) {
96 if (a.isAvailable(p))
97 return a(p);
98 }
99 return 0;
100}
101
102
110 const std::string& name,
111 const IInterface* parent)
112 : BlockFillerTool<SG::AuxElement> (type, name, parent)
113{
114 declareProperty ("AuxPrefix", m_auxprefix,
115 "Prefix to add to aux data names.");
116
117 declareProperty ("Vars", m_varString,
118 "Specify variables to fill. "
119 "Each is of the form VAR[=AUXVAR][<DEF][#DOCSTRING].\n"
120 "VAR is the D3PD variable name. "
121 "AUXVAR is the aux data item name. It may contain a class "
122 "name before a ::. If omitted, it defaults to VAR. "
123 "It may also be a comma-separated string of variable "
124 "names; the first one found to be present will be used. "
125 "If the < is present, then it is not an error for this "
126 "variable to be missing. If not empty, DEF specifies the "
127 "default value to use (works only for basic types). "
128 "DEF may be preceded with a type name: `TYPE: DEF' to "
129 "specify a type in the case the type of this aux variable "
130 "is unknown. "
131 "An optional documentation string may be given after a #.");
132}
133
134
142
143
148{
149 CHECK( parseVars() );
150 for (auto& v : m_vars) {
151 std::string docstring = "[AuxData: ";
152 docstring += v->label;
153 docstring += "] ";
154 docstring += v->docstring;
155 CHECK( addVariable (v->name, *v->ti, v->ptr, docstring, v->defobj.get()) );
156 }
157 return StatusCode::SUCCESS;
158}
159
160
170{
171 for (auto& v : m_vars) {
172 const void* aux = v->access(p);
173 if (aux)
174 v->type.assign (v->ptr, aux);
175 else if (!v->has_default) {
176 // Trigger an exception.
177 v->accessors[0](p);
178 }
179 }
180
181 return StatusCode::SUCCESS;
182}
183
184
189{
190 for (std::string name : m_varString) {
191 std::string docstring;
192 std::string::size_type ipos = name.find ('#');
193 if (ipos != std::string::npos) {
194 docstring = name.substr (ipos+1, std::string::npos);
195 name.resize(ipos);
196 }
197
198 std::string defstring;
199 bool has_default = false;
200 ipos = name.find ('<');
201 if (ipos != std::string::npos) {
202 defstring = name.substr (ipos+1, std::string::npos);
203 name.erase (ipos, std::string::npos);
204 has_default = true;
205 }
206
207 std::string label = name;
208 ipos = name.find ('=');
209 if (ipos != std::string::npos) {
210 name.erase (ipos, std::string::npos);
211 label.erase (0, ipos+1);
212 }
213
214 std::vector<std::string> labels = CxxUtils::tokenize(label, ',');
215 std::vector<std::string> label_classes;
216 for (std::string& l : labels) {
217 std::string label_class;
218 ipos = l.find ("::");
219 if (ipos != std::string::npos) {
220 label_class = l.substr (0, ipos);
221 l.erase (0, ipos+2);
222 }
224 l = m_auxprefix + l;
225 label_class = CxxUtils::trimWhiteSpaces(label_class);
226 label_classes.push_back (std::move(label_class));
227 }
228
229 name = CxxUtils::trimWhiteSpaces(name);
230 docstring = CxxUtils::trimWhiteSpaces(docstring);
231 defstring = CxxUtils::trimWhiteSpaces(defstring);
232
233 // If a type was given in the default field, make sure this variable
234 // name has been registered.
235 if (!defstring.empty()) {
236 ipos = defstring.find (':');
237 if (ipos != std::string::npos) {
238 std::string typname = defstring.substr (0, ipos);
239 typname = CxxUtils::trimWhiteSpaces(typname);
240 defstring.erase (0, ipos+1);
241
242 RootUtils::Type typ (typname);
244 const std::type_info* ti = typ.getTypeInfo();
245 if (ti) {
246 for (size_t i = 0; i < labels.size(); i++){
247 auto auxid = reg.getAuxID (*ti, labels[i], label_classes[i]);
248 if (auxid == SG::null_auxid){
249 REPORT_MESSAGE(MSG::WARNING)
250 <<"AuxDataFillerTool::parseVars: auxid is invalid for "<<labels[i]<<"\n";
251 }
252 }
253 }
254 }
255 }
256
257 try {
258 m_vars.push_back (std::make_unique<Var>
259 (name, docstring, labels, label_classes,
260 defstring, has_default));
261 }
262 catch (const std::runtime_error& e) {
263 REPORT_MESSAGE(MSG::ERROR)
264 << "Can't find aux data item(s) " << label
265 << " [" << e.what() << "]";
266 return StatusCode::FAILURE;
267 }
268
269 if (m_vars.back()->accessors.empty()) {
270 REPORT_MESSAGE(MSG::ERROR)
271 << "Can't find aux data item(s) " << label;
272 return StatusCode::FAILURE;
273 }
274 }
275 return StatusCode::SUCCESS;
276}
277
278
279} // 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
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
std::string_view trimWhiteSpaces(std::string_view str) noexcept
Removes all trailing and starting whitespaces from a string.
std::vector< std::string > tokenize(std::string_view the_str, std::string_view delimiters)
Splits the string into smaller substrings.
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
AuxElement(SG::AuxVectorData *container, size_t index)
Base class for elements of a container that can have aux data.
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.