Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
TupleObj.cpp
Go to the documentation of this file.
1 // ============================================================================
2 // Include files
3 // ============================================================================
4 // STD & STL
5 // ============================================================================
6 #include <algorithm>
7 #include <cstdarg>
8 #include <map>
9 // ============================================================================
10 // GaudiKernel
11 // ============================================================================
13 // ============================================================================
14 // GaudiAlg
15 // ============================================================================
16 #include "GaudiAlg/TupleObj.h"
17 #include "GaudiAlg/Tuples.h"
18 // ============================================================================
19 // Boost
20 // ============================================================================
21 #include "boost/integer_traits.hpp"
22 // ============================================================================
30 // ============================================================================
31 
32 namespace {
33 
34  template <typename T>
35  struct tuple_type_;
36 
37  template <>
38  struct tuple_type_<typename Tuples::TupleObj::Float> {
39  static constexpr const char* fmt = "F";
40  static constexpr const char* typ = "floats";
41  };
42  template <>
43  struct tuple_type_<typename Tuples::TupleObj::Double> {
44  static constexpr const char* fmt = "D";
45  static constexpr const char* typ = "doubles";
46  };
47  template <>
48  struct tuple_type_<typename Tuples::TupleObj::Bool> {
49  static constexpr const char* fmt = "I";
50  static constexpr const char* typ = "bools";
51  };
52  template <>
53  struct tuple_type_<typename Tuples::TupleObj::Char> {
54  static constexpr const char* fmt = "I";
55  static constexpr const char* typ = "chars";
56  };
57  template <>
58  struct tuple_type_<typename Tuples::TupleObj::UChar> {
59  static constexpr const char* fmt = "I";
60  static constexpr const char* typ = "uchars";
61  };
62  template <>
63  struct tuple_type_<typename Tuples::TupleObj::Short> {
64  static constexpr const char* fmt = "I";
65  static constexpr const char* typ = "shorts";
66  };
67  template <>
68  struct tuple_type_<typename Tuples::TupleObj::UShort> {
69  static constexpr const char* fmt = "I";
70  static constexpr const char* typ = "ushorts";
71  };
72  template <>
73  struct tuple_type_<typename Tuples::TupleObj::Int> {
74  static constexpr const char* fmt = "I";
75  static constexpr const char* typ = "ints";
76  };
77  template <>
78  struct tuple_type_<typename Tuples::TupleObj::UInt> {
79  static constexpr const char* fmt = "I";
80  static constexpr const char* typ = "uints";
81  };
82  template <>
83  struct tuple_type_<typename Tuples::TupleObj::LongLong> {
84  static constexpr const char* fmt = "ULL";
85  static constexpr const char* typ = "longlongs";
86  };
87  template <>
88  struct tuple_type_<typename Tuples::TupleObj::ULongLong> {
89  static constexpr const char* fmt = "ULL";
90  static constexpr const char* typ = "ulonglongs";
91  };
92  template <>
93  struct tuple_type_<typename Tuples::TupleObj::Address> {
94  static constexpr const char* fmt = "IOpaqueAddress*";
95  static constexpr const char* typ = "addresses";
96  };
97  template <>
98  struct tuple_type_<typename Tuples::TupleObj::FArray> {
99  static constexpr const char* fmt = "FArray";
100  static constexpr const char* typ = "farray";
101  };
102  template <>
103  struct tuple_type_<typename Tuples::TupleObj::FMatrix> {
104  static constexpr const char* fmt = "FMatrix";
105  static constexpr const char* typ = "fmatrix";
106  };
107 
108  // helper functions to simplify things...
109  template <typename C, typename AddItem>
110  typename C::mapped_type::pointer create_( Tuples::TupleObj* parent, C& container, const std::string& name,
111  AddItem addItem ) {
112  using element_t = typename C::mapped_type::element_type;
113  using map_t = struct tuple_type_<element_t>;
114  auto item = container.emplace( name, std::make_unique<element_t>() );
115  if ( !item.second ) { parent->Error( std::string{map_t::typ} + " ('" + name + "'): item is not inserted" ); }
116  StatusCode sc = addItem( name, *( item.first->second ) );
117  if ( sc.isFailure() ) { parent->Error( std::string{map_t::typ} + " ('" + name + "'): item is not added", sc ); }
118  if ( !parent->addItem( name, map_t::fmt ) ) {
119  parent->Error( std::string{map_t::typ} + " ('" + name + "'): item is not unique" );
120  }
121  return item.first->second.get();
122  }
123 
124  template <typename C, typename... ExtraArgs>
125  typename C::mapped_type::pointer find_or_create( Tuples::TupleObj* parent, const std::string& name, C& map,
126  ExtraArgs&&... ea ) {
127  using pointer = typename C::mapped_type::pointer;
129  auto found = map.find( name );
130  return found != map.end() ? found->second.get()
131  : create_( parent, map, name, [&]( const std::string& n, reference i ) {
132  return parent->tuple()->addItem( n, i, std::forward<ExtraArgs>( ea )... );
133  } );
134  }
135 
136  template <typename Container, typename UT, typename... ExtraArgs>
137  StatusCode column_( Tuples::TupleObj* parent, Container& container, const std::string& name, UT&& value,
138  ExtraArgs&&... ea ) {
139  if ( parent->invalid() ) return Tuples::ErrorCodes::InvalidTuple;
140  auto item = find_or_create( parent, name, container, std::forward<ExtraArgs>( ea )... );
141  if ( !item ) return Tuples::ErrorCodes::InvalidColumn;
142  *item = std::forward<UT>( value );
143  return StatusCode::SUCCESS;
144  }
145 
146  struct TuplesCategory : StatusCode::Category {
147  const char* name() const override { return "Tuples"; }
148 
149  bool isRecoverable( StatusCode::code_t ) const override { return false; }
150 
151  std::string message( StatusCode::code_t code ) const override {
152  switch ( static_cast<Tuples::ErrorCodes>( code ) ) {
154  return "InvalidTuple";
156  return "InvalidColumn";
158  return "InvalidOperation";
160  return "InvalidObject";
162  return "InvalidItem";
164  return "TruncateValue";
165  default:
166  return StatusCode::default_category().message( code );
167  }
168  }
169  };
170 } // namespace
171 
172 STATUSCODE_ENUM_IMPL( Tuples::ErrorCodes, TuplesCategory )
173 
174 namespace Tuples {
175  namespace Local {
176  class Counter final {
177  public:
178  // constructor
179  Counter( std::string msg = " Misbalance " ) : m_message( std::move( msg ) ) {}
180  // destructor
181  ~Counter() { report(); }
182  // make the increment
183  long increment( const std::string& object ) { return ++m_map[object]; }
184  // make the decrement
185  long decrement( const std::string& object ) { return --m_map[object]; }
186  // current count
187  long counts( const std::string& object ) const { return m_map.at( object ); }
188  // make a report
189  void report() const {
190  for ( auto& entry : m_map ) {
191  if ( entry.second != 0 )
192  std::cout << "Tuples::TupleObj WARNING " << m_message << "'" << entry.first << "' Counts = " << entry.second
193  << std::endl;
194  }
195  };
196 
197  private:
200  };
201 
207  static Counter s_InstanceCounter{" Create/Destroy (mis)balance "};
208  } // namespace Local
209 } // namespace Tuples
210 // ============================================================================
211 // Standard constructor
212 // ============================================================================
214  //
215  : m_name( std::move( name ) ), m_tuple( tuple ), m_clid( clid ), m_type( type ) {
216  // make counts
217  Tuples::Local::s_InstanceCounter.increment( m_name );
218 }
219 // ============================================================================
220 // destructor
221 // ============================================================================
223  // make counts
224  Tuples::Local::s_InstanceCounter.decrement( m_name );
225 }
226 // ============================================================================
227 // write a record to NTuple
228 // ============================================================================
230  if ( invalid() ) return ErrorCodes::InvalidTuple;
231  return tuple()->write();
232 }
233 // ============================================================================
234 namespace {
239  std::vector<std::string> tokenize( const std::string& value, const std::string& separators = " " ) {
241  auto it1 = value.begin();
242  auto it2 = value.begin();
243  while ( value.end() != it1 && value.end() != it2 ) {
244  it2 = std::find_first_of( it1, value.end(), separators.begin(), separators.end() );
245  if ( it2 != it1 ) {
246  tokens.emplace_back( value, it1 - value.begin(), it2 - it1 );
247  it1 = it2;
248  } else {
249  ++it1;
250  }
251  }
252  return tokens;
253  }
254 } // namespace
255 // ============================================================================
257  // check the underlying tuple
258  if ( invalid() ) return ErrorCodes::InvalidTuple;
259  // decode format string into tokens
260  auto tokens = tokenize( format, " ,;" );
262  va_list valist;
263  va_start( valist, format );
264  // loop over all tokens
266  for ( auto token = tokens.cbegin(); tokens.cend() != token && status.isSuccess(); ++token ) {
267  double val = va_arg( valist, double );
268  status = column( *token, val );
269  if ( status.isFailure() ) Error( "fill(): Can not add column '" + *token + "' " );
270  }
271  // mandatory !!!
272  va_end( valist );
273  //
274  return status;
275 }
276 
277 // ============================================================================
278 // put IOpaqueAddress in NTuple (has sense only for Event tag collection Ntuples)
279 // ============================================================================
281  if ( !evtColType() ) return ErrorCodes::InvalidOperation;
282  if ( !address ) return Error( "column('" + name + "') IOpaqueAddress* is NULL!", ErrorCodes::InvalidObject );
283  return column_( this, m_addresses, name, address );
284 }
285 
286 // ============================================================================
287 // put IOpaqueAddress in NTuple (has sense only for Event tag collection Ntuples)
288 // ============================================================================
289 StatusCode Tuples::TupleObj::column( IOpaqueAddress* address ) { return column( "Address", address ); }
290 
291 // ============================================================================
292 StatusCode Tuples::TupleObj::column( const std::string& name, float value ) {
293  return column_( this, m_floats, name, value );
294 }
295 // ============================================================================
296 StatusCode Tuples::TupleObj::column( const std::string& name, double value ) {
297  return column_( this, m_doubles, name, value );
298 }
299 // ============================================================================
300 StatusCode Tuples::TupleObj::column( const std::string& name, char value ) {
301  return column_( this, m_chars, name, value );
302 }
303 // ============================================================================
304 StatusCode Tuples::TupleObj::column( const std::string& name, char value, char minv, char maxv ) {
305  return column_( this, m_chars, name, value, minv, maxv );
306 }
307 // ============================================================================
308 StatusCode Tuples::TupleObj::column( const std::string& name, unsigned char value ) {
309  return column_( this, m_uchars, name, value );
310 }
311 // ============================================================================
312 StatusCode Tuples::TupleObj::column( const std::string& name, unsigned char value, unsigned char minv,
313  unsigned char maxv ) {
314  return column_( this, m_uchars, name, value, minv, maxv );
315 }
316 // ============================================================================
317 StatusCode Tuples::TupleObj::column( const std::string& name, short value ) {
318  return column_( this, m_shorts, name, value );
319 }
320 // ============================================================================
321 StatusCode Tuples::TupleObj::column( const std::string& name, const short value, const short minv, const short maxv ) {
322  return column_( this, m_shorts, name, value, minv, maxv );
323 }
324 // ============================================================================
325 StatusCode Tuples::TupleObj::column( const std::string& name, const unsigned short value ) {
326  return column_( this, m_ushorts, name, value );
327 }
328 // ============================================================================
329 StatusCode Tuples::TupleObj::column( const std::string& name, unsigned short value, unsigned short minv,
330  unsigned short maxv ) {
331  return column_( this, m_ushorts, name, value, minv, maxv );
332 }
333 // ============================================================================
335  return column_( this, m_ints, name, value );
336 }
337 // ============================================================================
338 StatusCode Tuples::TupleObj::column( const std::string& name, int value, int minv, int maxv ) {
339  return column_( this, m_ints, name, value, minv, maxv );
340 }
341 // ============================================================================
342 Tuples::TupleObj::Int* Tuples::TupleObj::ints( const std::string& name, int minv, int maxv ) {
343  return find_or_create( this, name, m_ints, minv, maxv );
344 }
345 // ============================================================================
346 StatusCode Tuples::TupleObj::column( const std::string& name, unsigned int value ) {
347  return column_( this, m_uints, name, value );
348 }
349 // ============================================================================
350 StatusCode Tuples::TupleObj::column( const std::string& name, unsigned int value, unsigned int minv,
351  unsigned int maxv ) {
352  return column_( this, m_uints, name, value, minv, maxv );
353 }
354 // ============================================================================
355 StatusCode Tuples::TupleObj::column( const std::string& name, const long value ) {
356  Warning( "'long' has different sizes on 32/64 bit systems. Casting '" + name + "' to 'long long'",
358  .ignore();
359  return column( name, static_cast<long long>( value ) );
360 }
361 // ============================================================================
362 StatusCode Tuples::TupleObj::column( const std::string& name, const long value, const long minv, const long maxv ) {
363  Warning( "'long' has different sizes on 32/64 bit systems. Casting '" + name + "' to 'long long'",
365  .ignore();
366  return column( name, static_cast<long long>( value ), static_cast<long long>( minv ),
367  static_cast<long long>( maxv ) );
368 }
369 // ============================================================================
370 StatusCode Tuples::TupleObj::column( const std::string& name, const unsigned long value ) {
371  Warning( "'unsigned long' has different sizes on 32/64 bit systems. Casting '" + name + "' to 'unsigned long long'",
373  .ignore();
374  return column( name, static_cast<unsigned long long>( value ) );
375 }
376 // ============================================================================
377 StatusCode Tuples::TupleObj::column( const std::string& name, const unsigned long value, const unsigned long minv,
378  const unsigned long maxv ) {
379  Warning( "'unsigned long' has different sizes on 32/64 bit systems. Casting '" + name + "' to 'unsigned long long'",
381  .ignore();
382  return column( name, static_cast<unsigned long long>( value ), static_cast<unsigned long long>( minv ),
383  static_cast<unsigned long long>( maxv ) );
384 }
385 // ============================================================================
386 StatusCode Tuples::TupleObj::column( const std::string& name, const long long value ) {
387  return column_( this, m_longlongs, name, value );
388 }
389 // ============================================================================
390 StatusCode Tuples::TupleObj::column( const std::string& name, long long value, long long minv, long long maxv ) {
391  return column_( this, m_longlongs, name, value, minv, maxv );
392 }
393 // ============================================================================
394 StatusCode Tuples::TupleObj::column( const std::string& name, unsigned long long value ) {
395  return column_( this, m_ulonglongs, name, value );
396 }
397 // ============================================================================
398 StatusCode Tuples::TupleObj::column( const std::string& name, unsigned long long value, unsigned long long minv,
399  unsigned long long maxv ) {
400  return column_( this, m_ulonglongs, name, value, minv, maxv );
401 }
402 // ============================================================================
403 StatusCode Tuples::TupleObj::column( const std::string& name, bool value ) {
404  return column_( this, m_bools, name, value );
405 }
406 // ============================================================================
407 // retrieve (book on demand) array-items for ntuple
408 // ============================================================================
410  // existing array ?
411  auto found = m_farrays.find( name );
412  if ( m_farrays.end() != found ) return found->second.get();
413  return create_( this, m_farrays, name,
414  [&]( const std::string& n, FArray& i ) { return this->tuple()->addIndexedItem( n, *length, i ); } );
415 }
416 // ============================================================================
417 // retrieve (book on demand) array-items for ntuple (fixed)
418 // ============================================================================
420  // existing array ?
421  auto found = m_arraysf.find( name );
422  if ( m_arraysf.end() != found ) return found->second.get();
423  return create_( this, m_arraysf, name,
424  [&]( const std::string& n, FArray& i ) { return this->tuple()->addItem( n, rows, i ); } );
425 }
426 // ============================================================================
427 // retrieve (book on demand) matrix-items for ntuple
428 // ============================================================================
430  const Tuples::TupleObj::MIndex& cols ) {
431  // existing array ?
432  auto found = m_fmatrices.find( name );
433  if ( m_fmatrices.end() != found ) return found->second.get();
434  return create_( this, m_fmatrices, name, [&]( const std::string& n, FMatrix& i ) {
435  return this->tuple()->addIndexedItem( n, *length, cols, i );
436  } );
437 }
438 // ============================================================================
439 // retrieve (book on demand) matrix-items for ntuple (fixed)
440 // ============================================================================
442  const Tuples::TupleObj::MIndex& cols ) {
443  // existing array ?
444  auto found = m_matricesf.find( name );
445  if ( m_matricesf.end() != found ) return found->second.get();
446  return create_( this, m_matricesf, name,
447  [&]( const std::string& n, FMatrix& i ) { return this->tuple()->addItem( n, rows, cols, i ); } );
448 }
449 // ============================================================================
450 // The END
451 // ============================================================================
Int * ints(const std::string &name, int minv, int maxv)
get the column
Definition: TupleObj.cpp:342
virtual StatusCode write()=0
Write record of the NTuple (Shortcut of writeRecord)
ColumnStorage< FArray > m_arraysf
the actual storage of all &#39;FArray&#39; columns (fixed)
Definition: TupleObj.h:1991
ColumnStorage< Float > m_floats
the actual storage of all &#39;Float&#39; columns
Definition: TupleObj.h:1979
ColumnStorage< Address > m_addresses
the actual storage of all &#39;Address&#39; columns
Definition: TupleObj.h:1985
const NTuple::Tuple * tuple() const
provide the access to underlying Gaudi N-tuple
Definition: TupleObj.h:1852
long decrement(const std::string &object)
Definition: TupleObj.cpp:185
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:109
ColumnStorage< Bool > m_bools
the actual storage of all &#39;bool&#39; columns
Definition: TupleObj.h:1952
bool evtColType() const
Event collection ?
Definition: TupleObj.h:1872
long counts(const std::string &object) const
Definition: TupleObj.cpp:187
Header file for class TupleObj.
Class acting as a smart pointer holding a N tuple _Item.
Definition: NTuple.h:52
StatusCode fill(const char *format...)
Set the values for several columns simultaneously.
Definition: TupleObj.cpp:256
void report() const
Definition: TupleObj.cpp:189
bool isSuccess() const
Definition: StatusCode.h:267
The category assigned to a StatusCode.
Definition: StatusCode.h:63
StatusCode column(const std::string &name, float value)
Set the value for selected tuple column.
Definition: TupleObj.cpp:292
T endl(T...args)
ErrorCodes
Tuple error codes.
Definition: TupleObj.h:92
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
STL namespace.
T end(T...args)
unsigned short MIndex
Definition: TupleObj.h:246
ColumnStorage< LongLong > m_longlongs
the actual storage of all &#39;long long&#39; columns
Definition: TupleObj.h:1973
ColumnStorage< UShort > m_ushorts
the actual storage of all &#39;unsigned int&#39; columns
Definition: TupleObj.h:1964
std::string m_name
name
Definition: TupleObj.h:1933
bool isFailure() const
Definition: StatusCode.h:130
StatusCode addIndexedItem(const std::string &name, Item< INDEX > &index, Array< TYPE > &array, const RANGE low, const RANGE high)
Add an indexed Array of data to a column wise N tuple with a range.
Definition: NTuple.h:660
Counter(std::string msg=" Misbalance ")
Definition: TupleObj.cpp:179
ColumnStorage< UInt > m_uints
the actual storage of all &#39;unsigned int&#39; columns
Definition: TupleObj.h:1970
STL class.
virtual StatusCode Warning(const std::string &msg, const StatusCode sc=StatusCode::FAILURE) const =0
bool addItem(std::string name, std::string type)
add the item name into the list of known items
Definition: TupleObj.h:1887
ColumnStorage< Double > m_doubles
the actual storage of all &#39;Double&#39; columns
Definition: TupleObj.h:1982
ColumnStorage< FMatrix > m_fmatrices
the actual storage of all &#39;FArray&#39; columns
Definition: TupleObj.h:1994
ColumnStorage< ULongLong > m_ulonglongs
the actual storage of all &#39;unsigned long long&#39; columns
Definition: TupleObj.h:1976
struct GAUDI_API map
Parametrisation class for map-like implementation.
A simple wrapper class over standard Gaudi NTuple::Tuple facility.
Definition: TupleObj.h:200
TupleObj(std::string name, NTuple::Tuple *tuple, const CLID &clid=CLID_ColumnWiseTuple, const Tuples::Type type=Tuples::NTUPLE)
Standard constructor.
Definition: TupleObj.cpp:213
#define STATUSCODE_ENUM_IMPL(...)
Assign a category to the StatusCode enum declared with STATUSCODE_ENUM_DECL( ENUM ) ...
Definition: StatusCode.h:248
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
ColumnStorage< Char > m_chars
the actual storage of all &#39;Int&#39; columns
Definition: TupleObj.h:1955
static const Category & default_category() noexcept
Default Gaudi StatusCode category.
Definition: StatusCode.h:263
std::map< std::string, long > m_map
Definition: TupleObj.cpp:195
ColumnStorage< Short > m_shorts
the actual storage of all &#39;Int&#39; columns
Definition: TupleObj.h:1961
T find_first_of(T...args)
StatusCode write()
write a record to NTuple
Definition: TupleObj.cpp:229
ColumnStorage< Int > m_ints
the actual storage of all &#39;Int&#39; columns
Definition: TupleObj.h:1967
unsigned int CLID
Class ID definition.
Definition: ClassID.h:8
Abstract base class which allows the user to interact with the actual N tuple implementation.
Definition: NTuple.h:375
virtual ~TupleObj()
Definition: TupleObj.cpp:222
FArray * fArray(const std::string &name, Int *item)
get the column
Definition: TupleObj.cpp:409
T begin(T...args)
virtual StatusCode Error(const std::string &msg, const StatusCode sc=StatusCode::FAILURE) const =0
ColumnStorage< FMatrix > m_matricesf
the actual storage of all &#39;FMatrix&#39; columns (fixed)
Definition: TupleObj.h:1997
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:153
StatusCode addItem(const std::string &name, Item< TYPE > &itm)
Add a scalar data item a N tuple.
Definition: NTuple.h:503
FMatrix * fMatrix(const std::string &name, Int *item, const MIndex &cols)
get the column
Definition: TupleObj.cpp:429
bool invalid() const
invalid pointer to tuple ?
Definition: TupleObj.h:1878
Opaque address interface definition.
Class acting as a smart pointer holding a N tuple _Item.
Definition: NTuple.h:48
std::string m_message
Definition: TupleObj.cpp:199
Class acting as a smart pointer holding a N tuple _Item.
Definition: NTuple.h:50
Type
the list of available types for ntuples
Definition: TupleObj.h:80
long increment(const std::string &object)
Definition: TupleObj.cpp:183
ColumnStorage< UChar > m_uchars
the actual storage of all &#39;unsigned int&#39; columns
Definition: TupleObj.h:1958
virtual std::string message(code_t code) const
Description for code within this category.
Definition: StatusCode.h:71
unsigned long code_t
type of StatusCode value
Definition: StatusCode.h:52
ColumnStorage< FArray > m_farrays
the actual storage of all &#39;FArray&#39; columns
Definition: TupleObj.h:1988
General namespace for Tuple properties.
Definition: Maps.h:33
T emplace_back(T...args)