ATLAS Offline Software
ObjectMetadata.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
6 // Boost include(s):
7 #include <boost/tokenizer.hpp>
8 
9 // Gaudi/Athena include(s):
10 #include "GaudiKernel/System.h"
12 
13 // Local include(s):
15 
17 namespace {
18 
20 
30  bool isPrimitive( const std::type_info& ti ) {
31 
32  if( ( ti == typeid( char* ) ) ||
33  ( ti == typeid( char ) ) ||
34  ( ti == typeid( unsigned char ) ) ||
35  ( ti == typeid( short ) ) ||
36  ( ti == typeid( unsigned short ) ) ||
37  ( ti == typeid( int ) ) ||
38  ( ti == typeid( unsigned int ) ) ||
39  ( ti == typeid( float ) ) ||
40  ( ti == typeid( double ) ) ||
41  ( ti == typeid( long long ) ) ||
42  ( ti == typeid( unsigned long long ) ) ||
43  ( ti == typeid( bool ) ) ) {
44 
45  return true;
46  }
47 
48  return false;
49  }
50 
51 } // namespace
52 
53 namespace D3PD {
54 
55  // Set the value of the constant(s):
57  const char* const ObjectMetadata::STRING_SEPARATOR = "@";
58  const unsigned int ObjectMetadata::SERIALIZER_VERSION = 1;
59  const char* const ObjectMetadata::Variable::STRING_SEPARATOR = "$";
60 
62  : m_variables(), m_name( "" ), m_prefix( "" ),
63  m_container( false ) {
64 
65  }
66 
68  : m_variables( parent.m_variables ), m_name( parent.m_name ),
69  m_prefix( parent.m_prefix ), m_container( parent.m_container ) {
70 
71  }
72 
74  {
75  if (&parent != this) {
76  m_variables = parent.m_variables;
77  m_name = parent.m_name;
78  m_prefix = parent.m_prefix;
79  m_container = parent.m_container;
80  }
81 
82  return *this;
83  }
84 
85  bool ObjectMetadata::operator== ( const ObjectMetadata& rhs ) const {
86 
87  return ( ( name() == rhs.name() ) && ( prefix() == rhs.prefix() ) &&
88  ( container() == rhs.container() ) );
89  }
90 
91  bool ObjectMetadata::operator< ( const ObjectMetadata& rhs ) const {
92 
93  if( prefix() != rhs.prefix() ) {
94  return ( prefix() < rhs.prefix() );
95  } else if( name() != rhs.name() ) {
96  return ( name() < rhs.name() );
97  } else {
98  return ( container() < rhs.container() );
99  }
100  }
101 
110  const std::type_info& ti,
111  void*& /*ptr*/,
112  const std::string& docstring,
113  const void* /*defval*/ ) {
114 
115  // Check that the variable has the correct prefix:
116  if( m_prefix != "" &&
117  !name.starts_with( m_prefix) )
118  {
119  REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "ObjectMetadata" )
120  << "Specified variable name (" << name << ") doesn't have the "
121  << "expected prefix (" << m_prefix << ")";
122  return StatusCode::RECOVERABLE;
123  }
124 
125  // Create a new variable:
126  Variable var;
127 
128  // Remove the prefix from the variable name:
129  var.setName( name.substr( m_prefix.size(), name.npos ) );
130 
131  // Check if it's already amongst the existing variables:
132  if( m_variables.find( var ) != m_variables.end() ) {
133  return StatusCode::SUCCESS;
134  }
135 
136  // Set the type of the variable:
137  var.setType( System::typeinfoName( ti.name() ) );
138 
139  // Set whether the variable is a primitive:
140  var.setPrimitive( isPrimitive( ti ) );
141 
142  // Set the documentation string for the variable:
143  var.setDoc( docstring );
144 
145  // Remember the variable:
146  m_variables.insert( var );
147 
148  return StatusCode::SUCCESS;
149  }
150 
156  StatusCode
157  ObjectMetadata::addDimensionedVariable( const std::string& /*name*/,
158  const std::type_info& /*ti*/,
159  void*& /*ptr*/,
160  const std::string& /*dim*/,
161  const std::string& /*docstring*/,
162  const void* /*defval*/ ) {
163 
164  REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata" )
165  << "addDimensionedVariable(...) not implemented";
166 
167  return StatusCode::FAILURE;
168  }
169 
170  const std::string& ObjectMetadata::name() const {
171 
172  return m_name;
173  }
174 
175  void ObjectMetadata::setName( const std::string& name ) {
176 
177  m_name = name;
178  return;
179  }
180 
191  std::string ObjectMetadata::metadataName ATLAS_NOT_THREAD_SAFE () const {
192 
193  // Variable used to give names to unnamed D3PDObject-s
194  static size_t objectCounter = 0;
195  std::string name = m_name;
196  if (name.empty()) {
197  ++objectCounter;
198  name = "D3PDObject" + std::to_string( objectCounter );
199  }
200  return name + "_" + genSuffix (name, RANDOM_NAME_POSTFIX_LENGTH);
201  }
202 
213  std::string ObjectMetadata::objectName( const std::string& metaName ) {
214 
215  return metaName.substr( 0, metaName.size() -
216  ( RANDOM_NAME_POSTFIX_LENGTH + 1 ) );
217  }
218 
219  const std::string& ObjectMetadata::prefix() const {
220 
221  return m_prefix;
222  }
223 
224  void ObjectMetadata::setPrefix( const std::string& prefix ) {
225 
226  m_prefix = prefix;
227  return;
228  }
229 
231 
232  return m_container;
233  }
234 
235  void ObjectMetadata::setContainer( bool container ) {
236 
238  return;
239  }
240 
249  std::string ObjectMetadata::toString() const {
250 
251  // Save the simple part of the information
252  std::string result =
255  STRING_SEPARATOR + ( m_container ? "1" : "0" );
256 
257  // Save the serialized version of all the variables:
258  std::set< Variable >::const_iterator itr = m_variables.begin();
259  std::set< Variable >::const_iterator end = m_variables.end();
260  for( ; itr != end; ++itr ) {
261  result += STRING_SEPARATOR + itr->toString();
262  }
263 
264  return result;
265  }
266 
276  StatusCode ObjectMetadata::read( const std::string& data ) {
277 
278  //
279  // Tokenize the string using Boost:
280  //
281  boost::char_separator< char > separator( STRING_SEPARATOR, "",
282  boost::keep_empty_tokens );
283  boost::tokenizer< boost::char_separator< char > > tokens( data,
284  separator );
285  boost::tokenizer< boost::char_separator< char > >::const_iterator itr = tokens.begin();
286  boost::tokenizer< boost::char_separator< char > >::const_iterator end = tokens.end();
287 
288  // Check that we didn't reach the last token yet:
289  if( itr == end ) {
290  REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata" )
291  << "The received data can not be parsed successfully: "
292  << data;
293  return StatusCode::FAILURE;
294  }
295 
296  // Check that the metadata was saved using the same version of the
297  // serializer code. Later on we might want to introduce backward
298  // compatibility, but for now this simple check should be enough.
299  if( atoi(itr->c_str()) != SERIALIZER_VERSION ) {
300  REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata" )
301  << "Version mismatch! The metadata was saved with a different "
302  << "serialization version (" << *itr << ") than the code used ("
303  << SERIALIZER_VERSION << ")";
304  return StatusCode::FAILURE;
305  }
306 
307  ++itr;
308 
309  // Check that we didn't reach the last token yet:
310  if( itr == end ) {
311  REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata" )
312  << "The received data can not be parsed successfully: "
313  << data;
314  return StatusCode::FAILURE;
315  }
316 
317  // Extract the prefix from the metadata:
318  m_prefix = *itr; ++itr;
319 
320  // Check that we didn't reach the last token yet:
321  if( itr == end ) {
322  REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata" )
323  << "The received data can not be parsed successfully: "
324  << data;
325  return StatusCode::FAILURE;
326  }
327 
328  // Extract whether this is a container that the variables describe:
329  if( *itr == "0" ) {
330  m_container = false;
331  } else if( *itr == "1" ) {
332  m_container = true;
333  } else {
334  REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata" )
335  << "The received data can not be parsed successfully: "
336  << data;
337  return StatusCode::FAILURE;
338  }
339 
340  ++itr;
341 
342  // Finally, let's extract all the variable metadata:
343  for( ; itr != end; ++itr ) {
344  Variable var;
345  CHECK( var.read( *itr ) );
346  m_variables.insert( var );
347  }
348 
349  return StatusCode::SUCCESS;
350  }
351 
353 
354  // Clear/reset all the variables:
355  m_variables.clear();
356  m_name = "";
357  m_prefix = "";
358  m_container = false;
359 
360  return;
361  }
362 
364 
365  return this->merge( obj );
366  }
367 
376 
377  // Only objects with the same "name" should be merged:
378  if( name() != obj.name() ) {
379  REPORT_MESSAGE_WITH_CONTEXT( MSG::WARNING, "ObjectMetadata" )
380  << "Can't merge object with name \"" << obj.name()
381  << "\" into another object with name \"" << name() << "\"";
382  return *this;
383  }
384 
385  // Now merge all the variable definitions:
386  std::set< Variable >::const_iterator itr = obj.variables().begin();
387  std::set< Variable >::const_iterator end = obj.variables().end();
388  for( ; itr != end; ++itr ) {
389  m_variables.insert( *itr );
390  }
391 
392  return *this;
393  }
394 
406  std::string ObjectMetadata::genSuffix ATLAS_NOT_THREAD_SAFE (const std::string& name,
407  size_t length)
408  {
409 
410  // Count of the number of times a given name was used,
411  // in order to assign them a unique suffix.
412  static std::unordered_map<std::string, size_t> namecount;
413 
414  const size_t count = ++namecount[name];
415  std::ostringstream os;
416  os << std::setw(length) << std::setprecision(length) << std::setfill('0')
417  << count;
418  return os.str();
419  }
420 
421 
423  : m_type( "" ), m_name( "" ), m_doc( "" ), m_primitive( true ) {
424 
425  }
426 
427  const std::string& ObjectMetadata::Variable::type() const {
428 
429  return m_type;
430  }
431 
432  const std::string& ObjectMetadata::Variable::name() const {
433 
434  return m_name;
435  }
436 
437  const std::string& ObjectMetadata::Variable::doc() const {
438 
439  return m_doc;
440  }
441 
443 
444  return m_primitive;
445  }
446 
447  void ObjectMetadata::Variable::setType( const std::string& type ) {
448 
449  m_type = type;
450  return;
451  }
452 
453  void ObjectMetadata::Variable::setName( const std::string& name ) {
454 
455  m_name = name;
456  return;
457  }
458 
459  void ObjectMetadata::Variable::setDoc( const std::string& doc ) {
460 
461  m_doc = doc;
462  return;
463  }
464 
465  void ObjectMetadata::Variable::setPrimitive( bool primitive ) {
466 
467  m_primitive = primitive;
468  return;
469  }
470 
480 
482  m_doc + STRING_SEPARATOR + ( m_primitive ? "1" : "0" );
483  }
484 
496 
497  //
498  // Tokenize the string using Boost:
499  //
500  boost::char_separator< char > separator( STRING_SEPARATOR, "",
501  boost::keep_empty_tokens );
502  boost::tokenizer< boost::char_separator< char > > tokens( data,
503  separator );
504  boost::tokenizer< boost::char_separator< char > >::const_iterator itr = tokens.begin();
505 
506  // Check that we didn't reach the last token yet:
507  if( itr == tokens.end() ) {
508  REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata::Variable" )
509  << "The received data can not be parsed successfully: "
510  << data;
511  return StatusCode::FAILURE;
512  }
513 
514  // Extract the name of the variable:
515  m_name = *itr; ++itr;
516 
517  // Check that we didn't reach the last token yet:
518  if( itr == tokens.end() ) {
519  REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata::Variable" )
520  << "The received data can not be parsed successfully: "
521  << data;
522  return StatusCode::FAILURE;
523  }
524 
525  // Extract the type of the variable:
526  m_type = *itr; ++itr;
527 
528  // Check that we didn't reach the last token yet:
529  if( itr == tokens.end() ) {
530  REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata::Variable" )
531  << "The received data can not be parsed successfully: "
532  << data;
533  return StatusCode::FAILURE;
534  }
535 
536  // Extract the documentation string of the variable:
537  m_doc = *itr; ++itr;
538 
539  // Check that we didn't reach the last token yet:
540  if( itr == tokens.end() ) {
541  REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata::Variable" )
542  << "The received data can not be parsed successfully: "
543  << data;
544  return StatusCode::FAILURE;
545  }
546 
547  // Extract the information of whether this variable is a primitive or not:
548  if( *itr == "0" ) {
549  m_primitive = false;
550  } else if( *itr == "1" ) {
551  m_primitive = true;
552  } else {
553  REPORT_MESSAGE_WITH_CONTEXT( MSG::FATAL, "ObjectMetadata::Variable" )
554  << "The received data can not be parsed successfully: "
555  << data;
556  return StatusCode::FAILURE;
557  }
558 
559  return StatusCode::SUCCESS;
560  }
561 
563 
564  return ( ( name() == var.name() ) &&
565  ( type() == var.type() ) );
566  }
567 
569 
570  if( name() != var.name() ) {
571  return ( name() < var.name() );
572  } else {
573  return ( type() < var.type() );
574  }
575  }
576 
577  const std::set< ObjectMetadata::Variable >& ObjectMetadata::variables() const {
578 
579  return m_variables;
580  }
581 
583  const ObjectMetadata& obj2 ) {
584 
585  ObjectMetadata result( obj1 );
586  return result += obj2;
587  }
588 
589 } // namespace D3PD
D3PD::ObjectMetadata::operator<
bool operator<(const ObjectMetadata &rhs) const
Operator needed to use such objects in ordered STL containers.
Definition: ObjectMetadata.cxx:91
beamspotnt.var
var
Definition: bin/beamspotnt.py:1394
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
D3PD::ObjectMetadata::variables
const std::set< Variable > & variables() const
Function for accessing all the variables of the D3PDObject.
Definition: ObjectMetadata.cxx:577
D3PD::ObjectMetadata::Variable::Variable
Variable()
Default constructor.
Definition: ObjectMetadata.cxx:422
D3PD::ObjectMetadata::addDimensionedVariable
virtual StatusCode addDimensionedVariable(const std::string &name, const std::type_info &ti, void *&ptr, const std::string &dim, const std::string &docstring="", const void *defval=0)
The object doesn't support dimensioned variables at the moment, like most of the D3PDMaker code doesn...
Definition: ObjectMetadata.cxx:157
D3PD::ObjectMetadata::Variable::primitive
bool primitive() const
Flag showing whether the variable is a primitive.
Definition: ObjectMetadata.cxx:442
D3PD::ObjectMetadata::m_variables
std::set< Variable > m_variables
The list of variables created by a D3PDObject.
Definition: ObjectMetadata.h:172
get_generator_info.result
result
Definition: get_generator_info.py:21
D3PD::ObjectMetadata::Variable::operator==
bool operator==(const Variable &var) const
Operator checking the equivalence of two variables.
Definition: ObjectMetadata.cxx:562
D3PD::ObjectMetadata::Variable::type
const std::string & type() const
Type name of the variable.
Definition: ObjectMetadata.cxx:427
python.Constants.FATAL
int FATAL
Definition: Control/AthenaCommon/python/Constants.py:19
D3PD::ObjectMetadata::Variable::read
StatusCode read(const std::string &data)
Read data from a "serialized" string.
Definition: ObjectMetadata.cxx:495
D3PD::ObjectMetadata::m_name
std::string m_name
Name of the D3PDObject that this object describes.
Definition: ObjectMetadata.h:173
D3PD::ObjectMetadata::setName
void setName(const std::string &name)
Set the name of the D3PDObject that this object describes.
Definition: ObjectMetadata.cxx:175
D3PD::ObjectMetadata::Variable::toString
std::string toString() const
Function "serializing" the variable information into a string.
Definition: ObjectMetadata.cxx:479
D3PD::ObjectMetadata::m_prefix
std::string m_prefix
Prefix used by the D3PDObject.
Definition: ObjectMetadata.h:174
ReadCellNoiseFromCoolCompare.obj2
obj2
Definition: ReadCellNoiseFromCoolCompare.py:303
ObjectMetadata.h
D3PD::ObjectMetadata::SERIALIZER_VERSION
static const unsigned int SERIALIZER_VERSION
"Version number" of the serialized information
Definition: ObjectMetadata.h:119
D3PD::isPrimitive
bool isPrimitive(const std::string &type)
This function is used in the code generator to determine from a type name if it's a primitive type or...
Definition: isPrimitive.cxx:24
D3PD::ObjectMetadata::operator+=
ObjectMetadata & operator+=(const ObjectMetadata &obj)
Operator merging the contents of two objects.
Definition: ObjectMetadata.cxx:363
D3PD::ObjectMetadata::setPrefix
void setPrefix(const std::string &prefix)
Set the prefix given to variables in this D3PDObject.
Definition: ObjectMetadata.cxx:224
beamspotman.tokens
tokens
Definition: beamspotman.py:1284
D3PD::ObjectMetadata::container
bool container() const
Get whether the D3PDObject describes a container or not.
Definition: ObjectMetadata.cxx:230
D3PD::ObjectMetadata::read
StatusCode read(const std::string &data)
Function "de-serializing" the stored information from a string.
Definition: ObjectMetadata.cxx:276
D3PD::ObjectMetadata::Variable::setType
void setType(const std::string &type)
Set the type name of the variable.
Definition: ObjectMetadata.cxx:447
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
D3PD::ObjectMetadata::m_container
bool m_container
The D3PDObject describes a container.
Definition: ObjectMetadata.h:175
D3PD::ObjectMetadata::STRING_SEPARATOR
static const char *const STRING_SEPARATOR
Character separating parts of the object's metadata.
Definition: ObjectMetadata.h:111
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
D3PD::ObjectMetadata::ObjectMetadata
ObjectMetadata()
Default constructor.
Definition: ObjectMetadata.cxx:61
m_type
TokenType m_type
the type
Definition: TProperty.cxx:44
D3PD::ObjectMetadata::Variable::STRING_SEPARATOR
static const char *const STRING_SEPARATOR
Character separating parts of the variable's metadata.
Definition: ObjectMetadata.h:160
D3PD
Block filler tool for noisy FEB information.
Definition: InnerDetector/InDetMonitoring/InDetGlobalMonitoring/macros/EnhancedPrimaryVertexMonitoring/TrigD3PD/ChainGroup.h:21
D3PD::ObjectMetadata::merge
ObjectMetadata & merge(const ObjectMetadata &obj)
Function merging the contents of two objects.
Definition: ObjectMetadata.cxx:375
D3PD::operator+
ObjectMetadata operator+(const ObjectMetadata &obj1, const ObjectMetadata &obj2)
Operator for creating the sum of two metadata objects.
Definition: ObjectMetadata.cxx:582
D3PD::ObjectMetadata::operator=
ObjectMetadata & operator=(const ObjectMetadata &parent)
Assignment operator.
Definition: ObjectMetadata.cxx:73
D3PD::ObjectMetadata::Variable::setName
void setName(const std::string &name)
Set the name of the variable.
Definition: ObjectMetadata.cxx:453
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
D3PD::ObjectMetadata::objectName
static std::string objectName(const std::string &metaName)
Get the D3PDObject's name from the name of the metadata object.
Definition: ObjectMetadata.cxx:213
checkCorrelInHIST.prefix
dictionary prefix
Definition: checkCorrelInHIST.py:391
test_pyathena.parent
parent
Definition: test_pyathena.py:15
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
D3PD::ATLAS_NOT_THREAD_SAFE
StatusCode DummyInitAlg::initialize ATLAS_NOT_THREAD_SAFE()
Standard Gaudi initialize method.
Definition: DummyInitAlg.cxx:69
D3PD::ObjectMetadata::clear
void clear()
Function clearing the object.
Definition: ObjectMetadata.cxx:352
D3PD::ObjectMetadata::toString
std::string toString() const
Function "serializing" the stored information into a string.
Definition: ObjectMetadata.cxx:249
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
D3PD::ObjectMetadata::Variable::setDoc
void setDoc(const std::string &doc)
Set the description of the variable.
Definition: ObjectMetadata.cxx:459
D3PD::ObjectMetadata::Variable::operator<
bool operator<(const Variable &var) const
Operator needed to use such objects in STL containers.
Definition: ObjectMetadata.cxx:568
REPORT_MESSAGE_WITH_CONTEXT
#define REPORT_MESSAGE_WITH_CONTEXT(LVL, CONTEXT_NAME)
Report a message, with an explicitly specified context name.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:345
D3PD::ObjectMetadata::Variable::name
const std::string & name() const
Name of the variable without its prefix.
Definition: ObjectMetadata.cxx:432
D3PD::ObjectMetadata::setContainer
void setContainer(bool container)
Set whether the D3PDObject describes a container or not.
Definition: ObjectMetadata.cxx:235
D3PD::ObjectMetadata
D3PD variable metadata handling class.
Definition: ObjectMetadata.h:36
merge_scale_histograms.doc
string doc
Definition: merge_scale_histograms.py:9
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
errorcheck.h
Helpers for checking error return status codes and reporting errors.
D3PD::ObjectMetadata::addVariable
virtual StatusCode addVariable(const std::string &name, const std::type_info &ti, void *&ptr, const std::string &docstring="", const void *defval=0)
This function can be used to save the metadata about a D3PD variable.
Definition: ObjectMetadata.cxx:109
D3PD::ObjectMetadata::prefix
const std::string & prefix() const
Get the prefix given to variables in this D3PDObject.
Definition: ObjectMetadata.cxx:219
D3PD::ObjectMetadata::operator==
bool operator==(const ObjectMetadata &rhs) const
Equality operator.
Definition: ObjectMetadata.cxx:85
D3PD::ObjectMetadata::Variable
Internal class keeping track of a single variable.
Definition: ObjectMetadata.h:131
D3PD::ObjectMetadata::RANDOM_NAME_POSTFIX_LENGTH
static const size_t RANDOM_NAME_POSTFIX_LENGTH
Length of the random string appended to the object name.
Definition: ObjectMetadata.h:109
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
D3PD::ObjectMetadata::Variable::setPrimitive
void setPrimitive(bool primitive)
Set whether the variable is a primitive.
Definition: ObjectMetadata.cxx:465
CxxUtils::atoi
int atoi(std::string_view str)
Helper functions to unpack numbers decoded in string into integers and doubles The strings are requir...
Definition: Control/CxxUtils/Root/StringUtils.cxx:85
python.PyAthena.obj
obj
Definition: PyAthena.py:135
D3PD::ObjectMetadata::Variable::doc
const std::string & doc() const
Description of the variable.
Definition: ObjectMetadata.cxx:437
length
double length(const pvec &v)
Definition: FPGATrackSimLLPDoubletHoughTransformTool.cxx:26
D3PD::ObjectMetadata::name
const std::string & name() const
Get the name of the D3PDObject that this object describes.
Definition: ObjectMetadata.cxx:170