The Gaudi Framework  v29r0 (ff2e7097)
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() ) {
148  return Tuples::InvalidTuple;
149  }
150  auto item = find_or_create( parent, name, container, std::forward<ExtraArgs>( ea )... );
151  if ( !item ) {
152  return Tuples::InvalidColumn;
153  }
154  *item = std::forward<UT>( value );
155  return StatusCode::SUCCESS;
156  }
157 }
158 
159 namespace Tuples
160 {
161  namespace Local
162  {
163  class Counter final
164  {
165  public:
166  // constructor
167  Counter( std::string msg = " Misbalance " ) : m_message( std::move( msg ) ) {}
168  // destructor
169  ~Counter() { report(); }
170  // make the increment
171  long increment( const std::string& object ) { return ++m_map[object]; }
172  // make the decrement
173  long decrement( const std::string& object ) { return --m_map[object]; }
174  // current count
175  long counts( const std::string& object ) const { return m_map.at( object ); }
176  // make a report
177  void report() const
178  {
179  for ( auto& entry : m_map ) {
180  if ( entry.second != 0 )
181  std::cout << "Tuples::TupleObj WARNING " << m_message << "'" << entry.first << "' Counts = " << entry.second
182  << std::endl;
183  }
184  };
185 
186  private:
189  };
190 
196  static Counter s_InstanceCounter{" Create/Destroy (mis)balance "};
197  }
198 }
199 // ============================================================================
200 // Standard constructor
201 // ============================================================================
203  //
204  : m_name( std::move( name ) ),
205  m_tuple( tuple ),
206  m_clid( clid ),
207  m_type( type )
208 {
209  // make counts
210  Tuples::Local::s_InstanceCounter.increment( m_name );
211 }
212 // ============================================================================
213 // destructor
214 // ============================================================================
216 {
217  // make counts
218  Tuples::Local::s_InstanceCounter.decrement( m_name );
219 }
220 // ============================================================================
221 // release the reference to TupleObj
222 // if reference counter becomes zero,
223 // object will be automatically deleted
224 // ============================================================================
226 {
227  // decrease the reference counter
228  if ( refCount() > 0 ) {
229  --m_refCount;
230  }
231  // check references -- delete if needed
232  if ( 0 == refCount() ) delete this;
233 }
234 // ============================================================================
235 // write a record to NTuple
236 // ============================================================================
238 {
239  if ( invalid() ) {
240  return InvalidTuple;
241  }
242  return tuple()->write();
243 }
244 // ============================================================================
245 namespace
246 {
251  std::vector<std::string> tokenize( const std::string& value, const std::string& separators = " " )
252  {
254  auto it1 = value.begin();
255  auto it2 = value.begin();
256  while ( value.end() != it1 && value.end() != it2 ) {
257  it2 = std::find_first_of( it1, value.end(), separators.begin(), separators.end() );
258  if ( it2 != it1 ) {
259  tokens.emplace_back( value, it1 - value.begin(), it2 - it1 );
260  it1 = it2;
261  } else {
262  ++it1;
263  }
264  }
265  return tokens;
266  }
267 }
268 // ============================================================================
270 {
271  // check the underlying tuple
272  if ( invalid() ) {
273  return InvalidTuple;
274  }
275  // decode format string into tokens
276  auto tokens = tokenize( format, " ,;" );
278  va_list valist;
279  va_start( valist, format );
280  // loop over all tokens
282  for ( auto token = tokens.cbegin(); tokens.cend() != token && status.isSuccess(); ++token ) {
283  double val = va_arg( valist, double );
284  status = column( *token, val );
285  if ( status.isFailure() ) {
286  Error( "fill(): Can not add column '" + *token + "' " );
287  }
288  }
289  // mandatory !!!
290  va_end( valist );
291  //
292  return status;
293 }
294 
295 // ============================================================================
296 // put IOpaqueAddress in NTuple (has sense only for Event tag collection Ntuples)
297 // ============================================================================
299 {
300  if ( !evtColType() ) {
301  return InvalidOperation;
302  }
303  if ( !address ) {
304  return Error( "column('" + name + "') IOpaqueAddress* is NULL!", InvalidObject );
305  }
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 ) {
460  return found->second.get();
461  }
462  return create_( this, m_farrays, name,
463  [&]( const std::string& n, FArray& i ) { return this->tuple()->addIndexedItem( n, *length, i ); } );
464 }
465 // ============================================================================
466 // retrieve (book on demand) array-items for ntuple (fixed)
467 // ============================================================================
469 {
470  // existing array ?
471  auto found = m_arraysf.find( name );
472  if ( m_arraysf.end() != found ) {
473  return found->second.get();
474  }
475  return create_( this, m_arraysf, name,
476  [&]( const std::string& n, FArray& i ) { return this->tuple()->addItem( n, rows, i ); } );
477 }
478 // ============================================================================
479 // retrieve (book on demand) matrix-items for ntuple
480 // ============================================================================
482  const Tuples::TupleObj::MIndex& cols )
483 {
484  // existing array ?
485  auto found = m_fmatrices.find( name );
486  if ( m_fmatrices.end() != found ) {
487  return found->second.get();
488  }
489  return create_( this, m_fmatrices, name, [&]( const std::string& n, FMatrix& i ) {
490  return this->tuple()->addIndexedItem( n, *length, cols, i );
491  } );
492 }
493 // ============================================================================
494 // retrieve (book on demand) matrix-items for ntuple (fixed)
495 // ============================================================================
497  const Tuples::TupleObj::MIndex& cols )
498 {
499  // existing array ?
500  auto found = m_matricesf.find( name );
501  if ( m_matricesf.end() != found ) {
502  return found->second.get();
503  }
504  return create_( this, m_matricesf, name,
505  [&]( const std::string& n, FMatrix& i ) { return this->tuple()->addItem( n, rows, cols, i ); } );
506 }
507 // ============================================================================
508 // The END
509 // ============================================================================
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)
UShorts m_ushorts
the actual storage of all &#39;unsigned int&#39; columns
Definition: TupleObj.h:2107
FMatrices m_fmatrices
the actual storage of all &#39;FArray&#39; columns
Definition: TupleObj.h:2137
const NTuple::Tuple * tuple() const
provide the access to underlying Gaudi N-tuple
Definition: TupleObj.h:1935
void release()
release the reference to TupleObj if reference counter becomes zero, object will be automatically del...
Definition: TupleObj.cpp:225
long decrement(const std::string &object)
Definition: TupleObj.cpp:173
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:120
bool evtColType() const
Event collection ?
Definition: TupleObj.h:1971
long counts(const std::string &object) const
Definition: TupleObj.cpp:175
Header file for class TupleObj.
Doubles m_doubles
the actual storage of all &#39;Double&#39; columns
Definition: TupleObj.h:2125
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:269
void report() const
Definition: TupleObj.cpp:177
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:75
StatusCode column(const std::string &name, float value)
Set the value for selected tuple column.
Definition: TupleObj.cpp:315
FMatrices m_matricesf
the actual storage of all &#39;FMatrix&#39; columns (fixed)
Definition: TupleObj.h:2140
T endl(T...args)
TupleObj()=delete
delete the default/copy constructor and assignment
Floats m_floats
the actual storage of all &#39;Float&#39; columns
Definition: TupleObj.h:2122
STL namespace.
FArrays m_farrays
the actual storage of all &#39;FArray&#39; columns
Definition: TupleObj.h:2131
T end(T...args)
size_t m_refCount
reference counter
Definition: TupleObj.h:2092
unsigned short MIndex
Definition: TupleObj.h:246
std::string m_name
name
Definition: TupleObj.h:2080
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
FArrays m_arraysf
the actual storage of all &#39;FArray&#39; columns (fixed)
Definition: TupleObj.h:2134
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:736
Counter(std::string msg=" Misbalance ")
Definition: TupleObj.cpp:167
Bools m_bools
the actual storage of all &#39;bool&#39; columns
Definition: TupleObj.h:2095
STL class.
virtual StatusCode Warning(const std::string &msg, const StatusCode sc=StatusCode::FAILURE) const =0
Chars m_chars
the actual storage of all &#39;Int&#39; columns
Definition: TupleObj.h:2098
bool addItem(std::string name, std::string type)
add the item name into the list of known items
Definition: TupleObj.h:1986
ULongLongs m_ulonglongs
the actual storage of all &#39;ulonglong&#39; columns
Definition: TupleObj.h:2119
iterator end()
Definition: Map.h:134
struct GAUDI_API map
Parametrisation class for map-like implementation.
A simple wrapper class over standard Gaudi NTuple::Tuple facility.
Definition: TupleObj.h:199
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:28
UInts m_uints
the actual storage of all &#39;unsigned int&#39; columns
Definition: TupleObj.h:2113
std::map< std::string, long > m_map
Definition: TupleObj.cpp:184
iterator find(const key_type &key)
Definition: Map.h:151
T find_first_of(T...args)
StatusCode write()
write a record to NTuple
Definition: TupleObj.cpp:237
Ints m_ints
the actual storage of all &#39;Int&#39; columns
Definition: TupleObj.h:2110
unsigned int CLID
Class ID definition.
Definition: ClassID.h:8
LongLongs m_longlongs
the actual storage of all &#39;longlong&#39; columns
Definition: TupleObj.h:2116
unsigned long refCount() const
return the reference counter
Definition: TupleObj.h:1945
Abstract base class which allows the user to interact with the actual N tuple implementation.
Definition: NTuple.h:412
virtual ~TupleObj()
destructor is protected
Definition: TupleObj.cpp:215
Addresses m_addresses
the actual storage of all &#39;Address&#39; columns
Definition: TupleObj.h:2128
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
typename std::tuple_element< N, Tuple >::type element_t
StatusCode addItem(const std::string &name, Item< TYPE > &itm)
Add a scalar data item a N tuple.
Definition: NTuple.h:572
FMatrix * fMatrix(const std::string &name, Int *item, const MIndex &cols)
get the column
Definition: TupleObj.cpp:481
Shorts m_shorts
the actual storage of all &#39;Int&#39; columns
Definition: TupleObj.h:2104
bool invalid() const
invalid pointer to tuple ?
Definition: TupleObj.h:1977
Opaque address interface definition.
void ignore() const
Definition: StatusCode.h:109
Class acting as a smart pointer holding a N tuple _Item.
Definition: NTuple.h:49
std::string m_message
Definition: TupleObj.cpp:188
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:84
long increment(const std::string &object)
Definition: TupleObj.cpp:171
TO * reference(FROM *from)
Definition: KeyedObject.cpp:21
UChars m_uchars
the actual storage of all &#39;unsigned int&#39; columns
Definition: TupleObj.h:2101
General namespace for Tuple properties.
Definition: Maps.h:34
T emplace_back(T...args)