ATLAS Offline Software
AuxDataFillerTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // $Id$
14 #include "AuxDataFillerTool.h"
18 #include "boost/algorithm/string/trim.hpp"
19 #include "boost/algorithm/string/split.hpp"
20 #include "TROOT.h"
21 
22 
23 namespace D3PD {
24 
25 
36 AuxDataFillerTool::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;
50  SG::auxid_t firstId = SG::null_auxid;
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 = 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()) {
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 
140 {
142 }
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  }
226  l = m_auxprefix + l;
227  boost::algorithm::trim (label_class);
228  label_classes.push_back (label_class);
229  }
230 
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  reg.getAuxID (*ti, labels[i], label_classes[i]);
250  }
251  }
252  }
253 
254  try {
255  m_vars.push_back (std::make_unique<Var>
256  (name, docstring, labels, label_classes,
257  defstring, has_default));
258  }
259  catch (const std::runtime_error& e) {
260  REPORT_MESSAGE(MSG::ERROR)
261  << "Can't find aux data item(s) " << label
262  << " [" << e.what() << "]";
263  return StatusCode::FAILURE;
264  }
265 
266  if (m_vars.back()->accessors.empty()) {
267  REPORT_MESSAGE(MSG::ERROR)
268  << "Can't find aux data item(s) " << label;
269  return StatusCode::FAILURE;
270  }
271  }
272  return StatusCode::SUCCESS;
273 }
274 
275 
276 } // namespace D3PD
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
RootUtils::Type::init
void init(const std::string &typname)
Initialize from a type name.
Definition: Type.cxx:154
SG
Forward declaration.
Definition: CaloCellPacker_400_500.h:32
SG::AuxTypeRegistry::instance
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Definition: AuxTypeRegistry.cxx:640
SG::AuxTypeRegistry::findAuxID
SG::auxid_t findAuxID(const std::string &name, const std::string &clsname="") const
Look up a name -> auxid_t mapping.
Definition: AuxTypeRegistry.cxx:757
SG::AuxElement
Base class for elements of a container that can have aux data.
Definition: AuxElement.h:472
PlotCalibFromCool.label
label
Definition: PlotCalibFromCool.py:78
initialize
void initialize()
Definition: run_EoverP.cxx:894
RootUtils::Type::getTypeInfo
const std::type_info * getTypeInfo() const
Return the type_info for the described type.
Definition: Type.cxx:366
D3PD::AuxDataFillerTool::Var::accessors
std::vector< SG::AuxElement::TypelessConstAccessor > accessors
Aux data accessor(s) for the item.
Definition: AuxDataFillerTool.h:128
D3PD::AuxDataFillerTool::Var::label
std::string label
Name of the aux data item(s).
Definition: AuxDataFillerTool.h:134
D3PD::AuxDataFillerTool::m_vars
std::vector< std::unique_ptr< Var > > m_vars
Parsed list of variables.
Definition: AuxDataFillerTool.h:139
D3PD::AuxDataFillerTool::parseVars
StatusCode parseVars()
Parse the variables property and fill m_vars.
Definition: AuxDataFillerTool.cxx:189
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
D3PD::AddVariable::addVariable
virtual StatusCode addVariable(const std::string &name, const std::type_info &ti, void *&ptr, const std::string &docstring="", const void *defval=0)
Add a variable to the tuple.
Definition: AddVariable.cxx:85
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
SG::AuxTypeRegistry
Handle mappings between names and auxid_t.
Definition: AuxTypeRegistry.h:61
D3PD::AuxDataFillerTool::Var::access
const void * access(const SG::AuxElement &p) const
Try to retrieve an aux data item from p.
Definition: AuxDataFillerTool.cxx:94
SG::auxid_t
size_t auxid_t
Identifier for a particular aux data item.
Definition: AuxTypes.h:27
SG::AuxTypeRegistry::getType
const std::type_info * getType(SG::auxid_t auxid) const
Return the type of an aux data item.
Definition: AuxTypeRegistry.cxx:909
D3PD
Block filler tool for noisy FEB information.
Definition: CaloCellDetailsFillerTool.cxx:29
beamspotnt.labels
list labels
Definition: bin/beamspotnt.py:1447
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
SG::AuxTypeRegistry::getTypeName
std::string getTypeName(SG::auxid_t auxid) const
Return the type name of an aux data item.
Definition: AuxTypeRegistry.cxx:924
lumiFormat.i
int i
Definition: lumiFormat.py:85
D3PD::AuxDataFillerTool::fill
virtual StatusCode fill(const SG::AuxElement &p)
Fill one block — type-safe version.
Definition: AuxDataFillerTool.cxx:170
AuxDataFillerTool.h
Copy aux data to D3PD.
D3PD::AuxDataFillerTool::Var::Var
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.
Definition: AuxDataFillerTool.cxx:36
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
D3PD::AuxDataFillerTool::Var::name
std::string name
Name of the variable.
Definition: AuxDataFillerTool.h:109
D3PD::AuxDataFillerTool::Var::ti
const std::type_info * ti
Type of the variable, as type_info.
Definition: AuxDataFillerTool.h:125
D3PD::AuxDataFillerTool::AuxDataFillerTool
AuxDataFillerTool(const std::string &type, const std::string &name, const IInterface *parent)
Standard Gaudi tool constructor.
Definition: AuxDataFillerTool.cxx:110
test_pyathena.parent
parent
Definition: test_pyathena.py:15
D3PD::AuxDataFillerTool::Var::defobj
RootUtils::Type::unique_ptr defobj
If present, a default object instance to use if the aux variable is not present.
Definition: AuxDataFillerTool.h:116
D3PD::BlockFillerTool
Type-safe wrapper for block filler tools.
Definition: BlockFillerTool.h:68
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
RootUtils::Type::fromString
void fromString(void *p, const std::string &s) const
Initialize an object from a string.
Definition: Type.cxx:601
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
errorcheck.h
Helpers for checking error return status codes and reporting errors.
REPORT_MESSAGE
#define REPORT_MESSAGE(LVL)
Report a message.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:365
python.PyAthena.v
v
Definition: PyAthena.py:154
RootUtils::Type::unique_ptr
std::unique_ptr< void, Deleter > unique_ptr
A std::unique_ptr type referencing a generic pointer.
Definition: Type.h:344
a
TList * a
Definition: liststreamerinfos.cxx:10
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
D3PD::AuxDataFillerTool::book
virtual StatusCode book()
Book variables for this block.
Definition: AuxDataFillerTool.cxx:148
AuxTypeRegistry.h
Handle mappings between names and auxid_t.
RootUtils::Type
Wrapper for ROOT types.
Definition: Type.h:40
GRLStrUtil::trim
void trim(std::string &input)
Definition: StrUtil.cxx:12
RootUtils::Type::create
void * create() const
Create an instance of the object.
Definition: Type.cxx:296
D3PD::AuxDataFillerTool::m_varString
std::vector< std::string > m_varString
Property: Specify variables to fill.
Definition: AuxDataFillerTool.h:76
xAODRootTest.accessors
dictionary accessors
Definition: xAODRootTest.py:73
D3PD::AuxDataFillerTool::m_auxprefix
std::string m_auxprefix
Property: Prefix to add to aux data names.
Definition: AuxDataFillerTool.h:72
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
D3PD::AuxDataFillerTool::initialize
virtual StatusCode initialize()
Standard Gaudi initialize method.
Definition: AuxDataFillerTool.cxx:139
AuxElement.h
Base class for elements of a container that can have aux data.
SG::AuxTypeRegistry::getAuxID
SG::auxid_t getAuxID(const std::string &name, const std::string &clsname="", const Flags flags=Flags::None, const SG::auxid_t linkedVariable=SG::null_auxid)
Look up a name -> auxid_t mapping.
D3PD::AuxDataFillerTool::Var::type
RootUtils::Type type
Type of the item.
Definition: AuxDataFillerTool.h:122