The Gaudi Framework  v30r3 (a5ef0a68)
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 
35  template <typename T>
36  struct tuple_type_;
37 
38  template <>
39  struct tuple_type_<typename Tuples::TupleObj::Float> {
40  static constexpr const char* fmt = "F";
41  static constexpr const char* typ = "floats";
42  };
43  template <>
44  struct tuple_type_<typename Tuples::TupleObj::Double> {
45  static constexpr const char* fmt = "D";
46  static constexpr const char* typ = "doubles";
47  };
48  template <>
49  struct tuple_type_<typename Tuples::TupleObj::Bool> {
50  static constexpr const char* fmt = "I";
51  static constexpr const char* typ = "bools";
52  };
53  template <>
54  struct tuple_type_<typename Tuples::TupleObj::Char> {
55  static constexpr const char* fmt = "I";
56  static constexpr const char* typ = "chars";
57  };
58  template <>
59  struct tuple_type_<typename Tuples::TupleObj::UChar> {
60  static constexpr const char* fmt = "I";
61  static constexpr const char* typ = "uchars";
62  };
63  template <>
64  struct tuple_type_<typename Tuples::TupleObj::Short> {
65  static constexpr const char* fmt = "I";
66  static constexpr const char* typ = "shorts";
67  };
68  template <>
69  struct tuple_type_<typename Tuples::TupleObj::UShort> {
70  static constexpr const char* fmt = "I";
71  static constexpr const char* typ = "ushorts";
72  };
73  template <>
74  struct tuple_type_<typename Tuples::TupleObj::Int> {
75  static constexpr const char* fmt = "I";
76  static constexpr const char* typ = "ints";
77  };
78  template <>
79  struct tuple_type_<typename Tuples::TupleObj::UInt> {
80  static constexpr const char* fmt = "I";
81  static constexpr const char* typ = "uints";
82  };
83  template <>
84  struct tuple_type_<typename Tuples::TupleObj::LongLong> {
85  static constexpr const char* fmt = "ULL";
86  static constexpr const char* typ = "longlongs";
87  };
88  template <>
89  struct tuple_type_<typename Tuples::TupleObj::ULongLong> {
90  static constexpr const char* fmt = "ULL";
91  static constexpr const char* typ = "ulonglongs";
92  };
93  template <>
94  struct tuple_type_<typename Tuples::TupleObj::Address> {
95  static constexpr const char* fmt = "IOpaqueAddress*";
96  static constexpr const char* typ = "addresses";
97  };
98  template <>
99  struct tuple_type_<typename Tuples::TupleObj::FArray> {
100  static constexpr const char* fmt = "FArray";
101  static constexpr const char* typ = "farray";
102  };
103  template <>
104  struct tuple_type_<typename Tuples::TupleObj::FMatrix> {
105  static constexpr const char* fmt = "FMatrix";
106  static constexpr const char* typ = "fmatrix";
107  };
108 
109  // helper functions to simplify things...
110  template <typename C, typename AddItem>
111  typename C::mapped_type::pointer create_( Tuples::TupleObj* parent, C& container, const std::string& name,
112  AddItem addItem )
113  {
114  using element_t = typename C::mapped_type::element_type;
115  using map_t = struct tuple_type_<element_t>;
116  auto item = container.emplace( name, std::make_unique<element_t>() );
117  if ( !item.second ) {
118  parent->Error( std::string{map_t::typ} + " ('" + name + "'): item is not inserted" );
119  }
120  StatusCode sc = addItem( name, *( item.first->second ) );
121  if ( sc.isFailure() ) {
122  parent->Error( std::string{map_t::typ} + " ('" + name + "'): item is not added", sc );
123  }
124  if ( !parent->addItem( name, map_t::fmt ) ) {
125  parent->Error( std::string{map_t::typ} + " ('" + name + "'): item is not unique" );
126  }
127  return item.first->second.get();
128  }
129 
130  template <typename C, typename... ExtraArgs>
131  typename C::mapped_type::pointer find_or_create( Tuples::TupleObj* parent, const std::string& name, C& map,
132  ExtraArgs&&... ea )
133  {
134  using pointer = typename C::mapped_type::pointer;
136  auto found = map.find( name );
137  return found != map.end() ? found->second.get()
138  : create_( parent, map, name, [&]( const std::string& n, reference i ) {
139  return parent->tuple()->addItem( n, i, std::forward<ExtraArgs>( ea )... );
140  } );
141  }
142 
143  template <typename Container, typename UT, typename... ExtraArgs>
144  StatusCode column_( Tuples::TupleObj* parent, Container& container, const std::string& name, UT&& value,
145  ExtraArgs&&... ea )
146  {
147  if ( parent->invalid() ) return Tuples::ErrorCodes::InvalidTuple;
148  auto item = find_or_create( parent, name, container, std::forward<ExtraArgs>( ea )... );
149  if ( !item ) return Tuples::ErrorCodes::InvalidColumn;
150  *item = std::forward<UT>( value );
151  return StatusCode::SUCCESS;
152  }
153 
154  struct TuplesCategory : StatusCode::Category {
155  const char* name() const override { return "Tuples"; }
156 
157  bool isRecoverable( StatusCode::code_t ) const override { return false; }
158 
159  std::string message( StatusCode::code_t code ) const override
160  {
161  switch ( static_cast<Tuples::ErrorCodes>( code ) ) {
163  return "InvalidTuple";
165  return "InvalidColumn";
167  return "InvalidOperation";
169  return "InvalidObject";
171  return "InvalidItem";
173  return "TruncateValue";
174  default:
175  return StatusCode::default_category().message( code );
176  }
177  }
178  };
179 }
180 
181 STATUSCODE_ENUM_IMPL( Tuples::ErrorCodes, TuplesCategory )
182 
183 namespace Tuples
184 {
185  namespace Local
186  {
187  class Counter final
188  {
189  public:
190  // constructor
191  Counter( std::string msg = " Misbalance " ) : m_message( std::move( msg ) ) {}
192  // destructor
193  ~Counter() { report(); }
194  // make the increment
195  long increment( const std::string& object ) { return ++m_map[object]; }
196  // make the decrement
197  long decrement( const std::string& object ) { return --m_map[object]; }
198  // current count
199  long counts( const std::string& object ) const { return m_map.at( object ); }
200  // make a report
201  void report() const
202  {
203  for ( auto& entry : m_map ) {
204  if ( entry.second != 0 )
205  std::cout << "Tuples::TupleObj WARNING " << m_message << "'" << entry.first << "' Counts = " << entry.second
206  << std::endl;
207  }
208  };
209 
210  private:
213  };
214 
220  static Counter s_InstanceCounter{" Create/Destroy (mis)balance "};
221  }
222 }
223 // ============================================================================
224 // Standard constructor
225 // ============================================================================
227  //
228  : m_name( std::move( name ) ),
229  m_tuple( tuple ),
230  m_clid( clid ),
231  m_type( type )
232 {
233  // make counts
234  Tuples::Local::s_InstanceCounter.increment( m_name );
235 }
236 // ============================================================================
237 // destructor
238 // ============================================================================
240 {
241  // make counts
242  Tuples::Local::s_InstanceCounter.decrement( m_name );
243 }
244 // ============================================================================
245 // write a record to NTuple
246 // ============================================================================
248 {
249  if ( invalid() ) return ErrorCodes::InvalidTuple;
250  return tuple()->write();
251 }
252 // ============================================================================
253 namespace
254 {
259  std::vector<std::string> tokenize( const std::string& value, const std::string& separators = " " )
260  {
262  auto it1 = value.begin();
263  auto it2 = value.begin();
264  while ( value.end() != it1 && value.end() != it2 ) {
265  it2 = std::find_first_of( it1, value.end(), separators.begin(), separators.end() );
266  if ( it2 != it1 ) {
267  tokens.emplace_back( value, it1 - value.begin(), it2 - it1 );
268  it1 = it2;
269  } else {
270  ++it1;
271  }
272  }
273  return tokens;
274  }
275 }
276 // ============================================================================
278 {
279  // check the underlying tuple
280  if ( invalid() ) return ErrorCodes::InvalidTuple;
281  // decode format string into tokens
282  auto tokens = tokenize( format, " ,;" );
284  va_list valist;
285  va_start( valist, format );
286  // loop over all tokens
288  for ( auto token = tokens.cbegin(); tokens.cend() != token && status.isSuccess(); ++token ) {
289  double val = va_arg( valist, double );
290  status = column( *token, val );
291  if ( status.isFailure() ) Error( "fill(): Can not add column '" + *token + "' " );
292  }
293  // mandatory !!!
294  va_end( valist );
295  //
296  return status;
297 }
298 
299 // ============================================================================
300 // put IOpaqueAddress in NTuple (has sense only for Event tag collection Ntuples)
301 // ============================================================================
303 {
304  if ( !evtColType() ) return ErrorCodes::InvalidOperation;
305  if ( !address ) return Error( "column('" + name + "') IOpaqueAddress* is NULL!", ErrorCodes::InvalidObject );
306  return column_( this, m_addresses, name, address );
307 }
308 
309 // ============================================================================
310 // put IOpaqueAddress in NTuple (has sense only for Event tag collection Ntuples)
311 // ============================================================================
312 StatusCode Tuples::TupleObj::column( IOpaqueAddress* address ) { return column( "Address", address ); }
313 
314 // ============================================================================
316 {
317  return column_( this, m_floats, name, value );
318 }
319 // ============================================================================
320 StatusCode Tuples::TupleObj::column( const std::string& name, double value )
321 {
322  return column_( this, m_doubles, name, value );
323 }
324 // ============================================================================
326 {
327  return column_( this, m_chars, name, value );
328 }
329 // ============================================================================
330 StatusCode Tuples::TupleObj::column( const std::string& name, char value, char minv, char maxv )
331 {
332  return column_( this, m_chars, name, value, minv, maxv );
333 }
334 // ============================================================================
335 StatusCode Tuples::TupleObj::column( const std::string& name, unsigned char value )
336 {
337  return column_( this, m_uchars, name, value );
338 }
339 // ============================================================================
340 StatusCode Tuples::TupleObj::column( const std::string& name, unsigned char value, unsigned char minv,
341  unsigned char maxv )
342 {
343  return column_( this, m_uchars, name, value, minv, maxv );
344 }
345 // ============================================================================
347 {
348  return column_( this, m_shorts, name, value );
349 }
350 // ============================================================================
351 StatusCode Tuples::TupleObj::column( const std::string& name, const short value, const short minv, const short maxv )
352 {
353  return column_( this, m_shorts, name, value, minv, maxv );
354 }
355 // ============================================================================
356 StatusCode Tuples::TupleObj::column( const std::string& name, const unsigned short value )
357 {
358  return column_( this, m_ushorts, name, value );
359 }
360 // ============================================================================
361 StatusCode Tuples::TupleObj::column( const std::string& name, unsigned short value, unsigned short minv,
362  unsigned short maxv )
363 {
364  return column_( this, m_ushorts, name, value, minv, maxv );
365 }
366 // ============================================================================
368 {
369  return column_( this, m_ints, name, value );
370 }
371 // ============================================================================
372 StatusCode Tuples::TupleObj::column( const std::string& name, int value, int minv, int maxv )
373 {
374  return column_( this, m_ints, name, value, minv, maxv );
375 }
376 // ============================================================================
377 Tuples::TupleObj::Int* Tuples::TupleObj::ints( const std::string& name, int minv, int maxv )
378 {
379  return find_or_create( this, name, m_ints, minv, maxv );
380 }
381 // ============================================================================
382 StatusCode Tuples::TupleObj::column( const std::string& name, unsigned int value )
383 {
384  return column_( this, m_uints, name, value );
385 }
386 // ============================================================================
387 StatusCode Tuples::TupleObj::column( const std::string& name, unsigned int value, unsigned int minv, unsigned int maxv )
388 {
389  return column_( this, m_uints, name, value, minv, maxv );
390 }
391 // ============================================================================
392 StatusCode Tuples::TupleObj::column( const std::string& name, const long value )
393 {
394  Warning( "'long' has different sizes on 32/64 bit systems. Casting '" + name + "' to 'long long'",
396  .ignore();
397  return column( name, static_cast<long long>( value ) );
398 }
399 // ============================================================================
400 StatusCode Tuples::TupleObj::column( const std::string& name, const long value, const long minv, const long maxv )
401 {
402  Warning( "'long' has different sizes on 32/64 bit systems. Casting '" + name + "' to 'long long'",
404  .ignore();
405  return column( name, static_cast<long long>( value ), static_cast<long long>( minv ),
406  static_cast<long long>( maxv ) );
407 }
408 // ============================================================================
409 StatusCode Tuples::TupleObj::column( const std::string& name, const unsigned long value )
410 {
411  Warning( "'unsigned long' has different sizes on 32/64 bit systems. Casting '" + name + "' to 'unsigned long long'",
413  .ignore();
414  return column( name, static_cast<unsigned long long>( value ) );
415 }
416 // ============================================================================
417 StatusCode Tuples::TupleObj::column( const std::string& name, const unsigned long value, const unsigned long minv,
418  const unsigned long maxv )
419 {
420  Warning( "'unsigned long' has different sizes on 32/64 bit systems. Casting '" + name + "' to 'unsigned long long'",
422  .ignore();
423  return column( name, static_cast<unsigned long long>( value ), static_cast<unsigned long long>( minv ),
424  static_cast<unsigned long long>( maxv ) );
425 }
426 // ============================================================================
427 StatusCode Tuples::TupleObj::column( const std::string& name, const long long value )
428 {
429  return column_( this, m_longlongs, name, value );
430 }
431 // ============================================================================
432 StatusCode Tuples::TupleObj::column( const std::string& name, long long value, long long minv, long long maxv )
433 {
434  return column_( this, m_longlongs, name, value, minv, maxv );
435 }
436 // ============================================================================
437 StatusCode Tuples::TupleObj::column( const std::string& name, unsigned long long value )
438 {
439  return column_( this, m_ulonglongs, name, value );
440 }
441 // ============================================================================
442 StatusCode Tuples::TupleObj::column( const std::string& name, unsigned long long value, unsigned long long minv,
443  unsigned long long maxv )
444 {
445  return column_( this, m_ulonglongs, name, value, minv, maxv );
446 }
447 // ============================================================================
449 {
450  return column_( this, m_bools, name, value );
451 }
452 // ============================================================================
453 // retrieve (book on demand) array-items for ntuple
454 // ============================================================================
456 {
457  // existing array ?
458  auto found = m_farrays.find( name );
459  if ( m_farrays.end() != found ) return found->second.get();
460  return create_( this, m_farrays, name,
461  [&]( const std::string& n, FArray& i ) { return this->tuple()->addIndexedItem( n, *length, i ); } );
462 }
463 // ============================================================================
464 // retrieve (book on demand) array-items for ntuple (fixed)
465 // ============================================================================
467 {
468  // existing array ?
469  auto found = m_arraysf.find( name );
470  if ( m_arraysf.end() != found ) return found->second.get();
471  return create_( this, m_arraysf, name,
472  [&]( const std::string& n, FArray& i ) { return this->tuple()->addItem( n, rows, i ); } );
473 }
474 // ============================================================================
475 // retrieve (book on demand) matrix-items for ntuple
476 // ============================================================================
478  const Tuples::TupleObj::MIndex& cols )
479 {
480  // existing array ?
481  auto found = m_fmatrices.find( name );
482  if ( m_fmatrices.end() != found ) return found->second.get();
483  return create_( this, m_fmatrices, name, [&]( const std::string& n, FMatrix& i ) {
484  return this->tuple()->addIndexedItem( n, *length, cols, i );
485  } );
486 }
487 // ============================================================================
488 // retrieve (book on demand) matrix-items for ntuple (fixed)
489 // ============================================================================
491  const Tuples::TupleObj::MIndex& cols )
492 {
493  // existing array ?
494  auto found = m_matricesf.find( name );
495  if ( m_matricesf.end() != found ) return found->second.get();
496  return create_( this, m_matricesf, name,
497  [&]( const std::string& n, FMatrix& i ) { return this->tuple()->addItem( n, rows, cols, i ); } );
498 }
499 // ============================================================================
500 // The END
501 // ============================================================================
Int * ints(const std::string &name, int minv, int maxv)
get the column
Definition: TupleObj.cpp:377
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:2031
ColumnStorage< Float > m_floats
the actual storage of all &#39;Float&#39; columns
Definition: TupleObj.h:2019
ColumnStorage< Address > m_addresses
the actual storage of all &#39;Address&#39; columns
Definition: TupleObj.h:2025
const NTuple::Tuple * tuple() const
provide the access to underlying Gaudi N-tuple
Definition: TupleObj.h:1891
long decrement(const std::string &object)
Definition: TupleObj.cpp:197
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:120
ColumnStorage< Bool > m_bools
the actual storage of all &#39;bool&#39; columns
Definition: TupleObj.h:1992
bool evtColType() const
Event collection ?
Definition: TupleObj.h:1911
long counts(const std::string &object) const
Definition: TupleObj.cpp:199
Header file for class TupleObj.
Class acting as a smart pointer holding a N tuple _Item.
Definition: NTuple.h:53
StatusCode fill(const char *format...)
Set the values for several columns simultaneously.
Definition: TupleObj.cpp:277
void report() const
Definition: TupleObj.cpp:201
bool isSuccess() const
Definition: StatusCode.h:287
The category assigned to a StatusCode.
Definition: StatusCode.h:65
StatusCode column(const std::string &name, float value)
Set the value for selected tuple column.
Definition: TupleObj.cpp:315
T endl(T...args)
ErrorCodes
Tuple error codes.
Definition: TupleObj.h:95
STL namespace.
T end(T...args)
unsigned short MIndex
Definition: TupleObj.h:251
ColumnStorage< LongLong > m_longlongs
the actual storage of all &#39;longlong&#39; columns
Definition: TupleObj.h:2013
ColumnStorage< UShort > m_ushorts
the actual storage of all &#39;unsigned int&#39; columns
Definition: TupleObj.h:2004
std::string m_name
name
Definition: TupleObj.h:1973
bool isFailure() const
Definition: StatusCode.h:139
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:728
Counter(std::string msg=" Misbalance ")
Definition: TupleObj.cpp:191
ColumnStorage< UInt > m_uints
the actual storage of all &#39;unsigned int&#39; columns
Definition: TupleObj.h:2010
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:1926
ColumnStorage< Double > m_doubles
the actual storage of all &#39;Double&#39; columns
Definition: TupleObj.h:2022
ColumnStorage< FMatrix > m_fmatrices
the actual storage of all &#39;FArray&#39; columns
Definition: TupleObj.h:2034
ColumnStorage< ULongLong > m_ulonglongs
the actual storage of all &#39;ulonglong&#39; columns
Definition: TupleObj.h:2016
struct GAUDI_API map
Parametrisation class for map-like implementation.
A simple wrapper class over standard Gaudi NTuple::Tuple facility.
Definition: TupleObj.h:204
TupleObj(std::string name, NTuple::Tuple *tuple, const CLID &clid=CLID_ColumnWiseTuple, const Tuples::Type type=Tuples::NTUPLE)
Standard constructor.
Definition: TupleObj.cpp:226
#define STATUSCODE_ENUM_IMPL(...)
Assign a category to the StatusCode enum declared with STATUSCODE_ENUM_DECL( ENUM ) ...
Definition: StatusCode.h:267
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
ColumnStorage< Char > m_chars
the actual storage of all &#39;Int&#39; columns
Definition: TupleObj.h:1995
static const Category & default_category() noexcept
Default Gaudi StatusCode category.
Definition: StatusCode.h:282
std::map< std::string, long > m_map
Definition: TupleObj.cpp:208
ColumnStorage< Short > m_shorts
the actual storage of all &#39;Int&#39; columns
Definition: TupleObj.h:2001
T find_first_of(T...args)
StatusCode write()
write a record to NTuple
Definition: TupleObj.cpp:247
ColumnStorage< Int > m_ints
the actual storage of all &#39;Int&#39; columns
Definition: TupleObj.h:2007
unsigned int CLID
Class ID definition.
Definition: ClassID.h:8
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
Abstract base class which allows the user to interact with the actual N tuple implementation.
Definition: NTuple.h:407
virtual ~TupleObj()
Definition: TupleObj.cpp:239
FArray * fArray(const std::string &name, Int *item)
get the column
Definition: TupleObj.cpp:455
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:2037
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:165
StatusCode addItem(const std::string &name, Item< TYPE > &itm)
Add a scalar data item a N tuple.
Definition: NTuple.h:564
FMatrix * fMatrix(const std::string &name, Int *item, const MIndex &cols)
get the column
Definition: TupleObj.cpp:477
bool invalid() const
invalid pointer to tuple ?
Definition: TupleObj.h:1917
Opaque address interface definition.
Class acting as a smart pointer holding a N tuple _Item.
Definition: NTuple.h:49
std::string m_message
Definition: TupleObj.cpp:212
Class acting as a smart pointer holding a N tuple _Item.
Definition: NTuple.h:51
Type
the list of available types for ntuples
Definition: TupleObj.h:83
long increment(const std::string &object)
Definition: TupleObj.cpp:195
ColumnStorage< UChar > m_uchars
the actual storage of all &#39;unsigned int&#39; columns
Definition: TupleObj.h:1998
virtual std::string message(code_t code) const
Description for code within this category.
Definition: StatusCode.h:73
unsigned long code_t
type of StatusCode value
Definition: StatusCode.h:54
ColumnStorage< FArray > m_farrays
the actual storage of all &#39;FArray&#39; columns
Definition: TupleObj.h:2028
General namespace for Tuple properties.
Definition: Maps.h:34
T emplace_back(T...args)