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 <cstdarg>
7 #include <algorithm>
8 #include <map>
9 // ============================================================================
10 // GaudiKernel
11 // ============================================================================
13 // ============================================================================
14 // GaudiAlg
15 // ============================================================================
16 #include "GaudiAlg/Tuples.h"
17 #include "GaudiAlg/TupleObj.h"
18 // ============================================================================
19 // Boost
20 // ============================================================================
21 #include "boost/integer_traits.hpp"
22 // ============================================================================
30 // ============================================================================
31 
32 namespace {
33 
34  template <typename T> struct tuple_type_ ;
35 
36  template <> struct tuple_type_<typename Tuples::TupleObj::Float>
37  { static constexpr const char* fmt = "F";
38  static constexpr const char* typ = "floats"; };
39  template <> struct tuple_type_<typename Tuples::TupleObj::Double>
40  { static constexpr const char* fmt = "D";
41  static constexpr const char* typ = "doubles"; };
42  template <> struct tuple_type_<typename Tuples::TupleObj::Bool>
43  { static constexpr const char* fmt = "I";
44  static constexpr const char* typ = "bools";};
45  template <> struct tuple_type_<typename Tuples::TupleObj::Char>
46  { static constexpr const char* fmt = "I";
47  static constexpr const char* typ = "chars";};
48  template <> struct tuple_type_<typename Tuples::TupleObj::UChar>
49  { static constexpr const char* fmt = "I";
50  static constexpr const char* typ = "uchars";};
51  template <> struct tuple_type_<typename Tuples::TupleObj::Short>
52  { static constexpr const char* fmt = "I";
53  static constexpr const char* typ = "shorts";};
54  template <> struct tuple_type_<typename Tuples::TupleObj::UShort>
55  { static constexpr const char* fmt = "I";
56  static constexpr const char* typ = "ushorts";};
57  template <> struct tuple_type_<typename Tuples::TupleObj::Int>
58  { static constexpr const char* fmt = "I";
59  static constexpr const char* typ = "ints";};
60  template <> struct tuple_type_<typename Tuples::TupleObj::UInt>
61  { static constexpr const char* fmt = "I";
62  static constexpr const char* typ = "uints";};
63  template <> struct tuple_type_<typename Tuples::TupleObj::LongLong>
64  { static constexpr const char* fmt = "ULL";
65  static constexpr const char* typ = "longlongs";};
66  template <> struct tuple_type_<typename Tuples::TupleObj::ULongLong>
67  { static constexpr const char* fmt = "ULL";
68  static constexpr const char* typ = "ulonglongs";};
69  template <> struct tuple_type_<typename Tuples::TupleObj::Address>
70  { static constexpr const char* fmt = "IOpaqueAddress*" ;
71  static constexpr const char* typ = "addresses";};
72  template <> struct tuple_type_<typename Tuples::TupleObj::FArray>
73  { static constexpr const char* fmt = "FArray";
74  static constexpr const char* typ = "farray";};
75  template <> struct tuple_type_<typename Tuples::TupleObj::FMatrix>
76  { static constexpr const char* fmt = "FMatrix";
77  static constexpr const char* typ = "fmatrix"; };
78 
79  // helper functions to simplify things...
80  template <typename C, typename AddItem>
81  typename C::mapped_type::pointer create_(Tuples::TupleObj* parent, C& container, const std::string& name, AddItem addItem ) {
82  using element_t = typename C::mapped_type::element_type;
83  using map_t = struct tuple_type_<element_t> ;
84  auto item = container.emplace( name , std::make_unique<element_t>() ) ;
85  if (!item.second)
86  { parent->Error ( std::string{map_t::typ} + " ('" + name + "'): item is not inserted" ) ; }
87  StatusCode sc = addItem( name , *(item.first->second) );
88  if ( sc.isFailure() )
89  { parent->Error ( std::string{map_t::typ} + " ('" + name + "'): item is not added", sc ) ; }
90  if ( !parent->addItem(name,map_t::fmt) )
91  { parent->Error ( std::string{map_t::typ} + " ('" + name + "'): item is not unique" ) ; }
92  return item.first->second.get() ;
93  }
94 
95  template <typename C, typename... ExtraArgs>
96  typename C::mapped_type::pointer find_or_create(Tuples::TupleObj* parent, const std::string& name, C& map,
97  ExtraArgs&& ... ea) {
98  using pointer = typename C::mapped_type::pointer;
100  auto found = map.find(name);
101  return found != map.end() ? found->second.get()
102  : create_(parent, map ,name,
103  [&](const std::string& n, reference i)
104  { return parent->tuple()->addItem(n,i, std::forward<ExtraArgs>(ea)...); });
105  }
106 
107  template <typename Container, typename UT, typename ... ExtraArgs>
108  StatusCode column_(Tuples::TupleObj* parent, Container& container, const std::string& name, UT&& value, ExtraArgs&&... ea) {
109  if ( parent->invalid() ) { return Tuples::InvalidTuple ; }
110  auto item = find_or_create( parent, name, container, std::forward<ExtraArgs>(ea)...);
111  if ( !item ) { return Tuples::InvalidColumn ; }
112  *item = std::forward<UT>(value);
113  return StatusCode::SUCCESS ;
114  }
115 }
116 
117 namespace Tuples
118 {
119  namespace Local
120  {
121  class Counter final
122  {
123  public:
124  // constructor
125  Counter ( std::string msg = " Misbalance ")
126  : m_message ( std::move(msg) )
127  {}
128  // destructor
129  ~Counter() { report(); }
130  // make the increment
131  long increment ( const std::string& object ) { return ++m_map[object]; }
132  // make the decrement
133  long decrement ( const std::string& object ) { return --m_map[object]; }
134  // current count
135  long counts ( const std::string& object ) const { return m_map.at(object); }
136  // make a report
137  void report() const
138  {
139  for ( auto& entry : m_map )
140  {
141  if( entry.second != 0 ) std::cout
142  << "Tuples::TupleObj WARNING " << m_message
143  << "'" << entry.first << "' Counts = " << entry.second
144  << std::endl ;
145  }
146  };
147 
148  private:
151  };
152 
158  static Counter s_InstanceCounter{ " Create/Destroy (mis)balance " };
159 
160  }
161 }
162 // ============================================================================
163 // Standard constructor
164 // ============================================================================
166 ( std::string name ,
167  NTuple::Tuple* tuple ,
168  const CLID& clid ,
169  const Tuples::Type type )
170 //
171  : m_name ( std::move(name) )
172  , m_tuple ( tuple )
173  , m_clid ( clid )
174  , m_type ( type )
175 {
176  // make counts
177  Tuples::Local::s_InstanceCounter.increment ( m_name ) ;
178 }
179 // ============================================================================
180 // destructor
181 // ============================================================================
183 {
184  // make counts
185  Tuples::Local::s_InstanceCounter.decrement ( m_name ) ;
186 }
187 // ============================================================================
188 // release the reference to TupleObj
189 // if reference counter becomes zero,
190 // object will be automatically deleted
191 // ============================================================================
193 {
194  // decrease the reference counter
195  if( refCount() > 0 ) { --m_refCount; }
196  // check references -- delete if needed
197  if( 0 == refCount() ) delete this;
198 }
199 // ============================================================================
200 // write a record to NTuple
201 // ============================================================================
203 {
204  if ( invalid() ) { return InvalidTuple ; }
205  return tuple()->write() ;
206 }
207 // ============================================================================
208 namespace
209 {
214  std::vector<std::string> tokenize( const std::string& value ,
215  const std::string& separators = " " )
216  {
218  auto it1 = value.begin() ;
219  auto it2 = value.begin() ;
220  while( value.end() != it1 && value.end() != it2 )
221  {
222  it2 = std::find_first_of( it1 ,
223  value.end () ,
224  separators.begin () ,
225  separators.end () ) ;
226  if( it2 != it1 ) {
227  tokens.emplace_back( value , it1 - value.begin() , it2 - it1 ) ;
228  it1 = it2 ;
229  }
230  else { ++it1 ; }
231  }
232  return tokens;
233  }
234 }
235 // ============================================================================
237 {
238  // check the underlying tuple
239  if ( invalid() ) { return InvalidTuple ; }
240  // decode format string into tokens
241  auto tokens = tokenize( format , " ,;" );
243  va_list valist ;
244  va_start( valist , format ) ;
245  // loop over all tokens
247  for( auto token = tokens.cbegin() ;
248  tokens.cend() != token && status.isSuccess() ; ++token )
249  {
250  double val = va_arg( valist , double );
251  status = column( *token , val );
252  if( status.isFailure() )
253  { Error ( "fill(): Can not add column '" + *token + "' " ) ; }
254  }
255  // mandatory !!!
256  va_end( valist );
257  //
258  return status ;
259 }
260 
261 // ============================================================================
262 // put IOpaqueAddress in NTuple (has sense only for Event tag collection Ntuples)
263 // ============================================================================
265 ( const std::string& name ,
266  IOpaqueAddress* address )
267 {
268  if ( !evtColType () ) { return InvalidOperation ; }
269  if ( !address )
270  { return Error ( "column('" + name +
271  "') IOpaqueAddress* is NULL!" , InvalidObject ) ; }
272  return column_(this, m_addresses, name, address);
273 }
274 
275 // ============================================================================
276 // put IOpaqueAddress in NTuple (has sense only for Event tag collection Ntuples)
277 // ============================================================================
279 ( IOpaqueAddress* address )
280 {
281  return column ( "Address" , address ) ;
282 }
283 
284 // ============================================================================
286  float value )
287 {
288  return column_(this, m_floats,name,value);
289 }
290 // ============================================================================
292  double value )
293 {
294  return column_(this, m_doubles, name,value);
295 }
296 // ============================================================================
298  char value )
299 {
300  return column_(this, m_chars, name, value);
301 }
302 // ============================================================================
304  char value ,
305  char minv ,
306  char maxv )
307 {
308  return column_(this, m_chars, name,value,minv,maxv);
309 }
310 // ============================================================================
312  unsigned char value )
313 {
314  return column_(this, m_uchars, name,value);
315 }
316 // ============================================================================
318  unsigned char value ,
319  unsigned char minv ,
320  unsigned char maxv )
321 {
322  return column_(this, m_uchars, name,value,minv,maxv);
323 }
324 // ============================================================================
326  short value )
327 {
328  return column_(this, m_shorts, name,value);
329 }
330 // ============================================================================
332  const short value ,
333  const short minv ,
334  const short maxv )
335 {
336  return column_(this, m_shorts, name, value, minv, maxv);
337 }
338 // ============================================================================
340  const unsigned short value )
341 {
342  return column_(this, m_ushorts, name, value );
343 }
344 // ============================================================================
346  unsigned short value ,
347  unsigned short minv ,
348  unsigned short maxv )
349 {
350  return column_(this, m_ushorts, name, value, minv, maxv );
351 }
352 // ============================================================================
354  int value )
355 {
356  return column_(this, m_ints, name, value );
357 }
358 // ============================================================================
360  int value ,
361  int minv ,
362  int maxv )
363 {
364  return column_(this, m_ints, name,value,minv,maxv);
365 }
366 // ============================================================================
368  int minv ,
369  int maxv )
370 {
371  return find_or_create( this, name, m_ints, minv, maxv );
372 }
373 // ============================================================================
375  unsigned int value )
376 {
377  return column_(this, m_uints, name,value);
378 }
379 // ============================================================================
381  unsigned int value ,
382  unsigned int minv ,
383  unsigned int maxv )
384 {
385  return column_(this, m_uints, name,value,minv,maxv);
386 }
387 // ============================================================================
389  const long value )
390 {
391  Warning( "'long' has different sizes on 32/64 bit systems. Casting '" +
392  name + "' to 'long long'", StatusCode::SUCCESS ).ignore();
393  return column( name, static_cast<long long>(value) );
394 }
395 // ============================================================================
397  const long value ,
398  const long minv ,
399  const long maxv )
400 {
401  Warning( "'long' has different sizes on 32/64 bit systems. Casting '" +
402  name + "' to 'long long'", StatusCode::SUCCESS ).ignore();
403  return column( name,
404  static_cast<long long>(value),
405  static_cast<long long>(minv),
406  static_cast<long long>(maxv) );
407 }
408 // ============================================================================
410  const unsigned long value )
411 {
412  Warning( "'unsigned long' has different sizes on 32/64 bit systems. Casting '" +
413  name + "' to 'unsigned long long'", StatusCode::SUCCESS ).ignore();
414  return column( name, static_cast<unsigned long long>(value) );
415 }
416 // ============================================================================
418  const unsigned long value ,
419  const unsigned long minv ,
420  const unsigned long maxv )
421 {
422  Warning( "'unsigned long' has different sizes on 32/64 bit systems. Casting '" +
423  name + "' to 'unsigned long long'", StatusCode::SUCCESS ).ignore();
424  return column( name,
425  static_cast<unsigned long long>(value),
426  static_cast<unsigned long long>(minv),
427  static_cast<unsigned long long>(maxv) );
428 }
429 // ============================================================================
431  const long long value )
432 {
433  return column_(this, m_longlongs, name,value);
434 }
435 // ============================================================================
437  long long value ,
438  long long minv ,
439  long long maxv )
440 {
441  return column_(this, m_longlongs, name,value,minv,maxv);
442 }
443 // ============================================================================
445  unsigned long long value )
446 {
447  return column_(this, m_ulonglongs, name,value);
448 }
449 // ============================================================================
451  unsigned long long value ,
452  unsigned long long minv ,
453  unsigned long long maxv )
454 {
455  return column_( this, m_ulonglongs, name,value,minv,maxv);
456 }
457 // ============================================================================
459  bool value )
460 {
461  return column_(this, m_bools, name,value);
462 }
463 // ============================================================================
464 // retrieve (book on demand) array-items for ntuple
465 // ============================================================================
467 ( const std::string& name ,
468  Tuples::TupleObj::Int* length )
469 {
470  // existing array ?
471  auto found = m_farrays.find( name ) ;
472  if( m_farrays.end() != found ) { return found->second.get() ; }
473  return create_(this, m_farrays, name,
474  [&](const std::string& n, FArray& i)
475  { return this->tuple()->addIndexedItem(n,*length,i); });
476 }
477 // ============================================================================
478 // retrieve (book on demand) array-items for ntuple (fixed)
479 // ============================================================================
481 ( const std::string& name ,
482  const Tuples::TupleObj::MIndex& rows )
483 {
484  // existing array ?
485  auto found = m_arraysf.find( name ) ;
486  if( m_arraysf.end() != found ) { return found->second.get() ; }
487  return create_(this, m_arraysf, name,
488  [&](const std::string& n, FArray& i)
489  { return this->tuple()->addItem(n,rows,i); });
490 }
491 // ============================================================================
492 // retrieve (book on demand) matrix-items for ntuple
493 // ============================================================================
496 ( const std::string& name ,
497  Tuples::TupleObj::Int* length ,
498  const Tuples::TupleObj::MIndex& cols )
499 {
500  // existing array ?
501  auto found = m_fmatrices.find( name ) ;
502  if( m_fmatrices.end() != found ) { return found->second.get() ; }
503  return create_(this, m_fmatrices, name,
504  [&](const std::string& n, FMatrix& i)
505  { return this->tuple()->addIndexedItem(n,*length,cols,i); });
506 }
507 // ============================================================================
508 // retrieve (book on demand) matrix-items for ntuple (fixed)
509 // ============================================================================
512 ( const std::string& name ,
513  const Tuples::TupleObj::MIndex& rows ,
514  const Tuples::TupleObj::MIndex& cols )
515 {
516  // existing array ?
517  auto found = m_matricesf.find( name ) ;
518  if( m_matricesf.end() != found ) { return found->second.get() ; }
519  return create_(this, m_matricesf, name,
520  [&](const std::string& n, FMatrix& i)
521  { return this->tuple()->addItem(n,rows,cols,i); });
522 }
523 // ============================================================================
524 // The END
525 // ============================================================================
Int * ints(const std::string &name, int minv, int maxv)
get the column
Definition: TupleObj.cpp:367
virtual StatusCode write()=0
Write record of the NTuple (Shortcut of writeRecord)
const NTuple::Tuple * tuple() const
provide the access to underlying Gaudi N-tuple
Definition: TupleObj.h:1988
void release()
release the reference to TupleObj if reference counter becomes zero, object will be automatically del...
Definition: TupleObj.cpp:192
long decrement(const std::string &object)
Definition: TupleObj.cpp:133
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:119
long counts(const std::string &object) const
Definition: TupleObj.cpp:135
Header file for class TupleObj.
Class acting as a smart pointer holding a N tuple _Item.
Definition: NTuple.h:44
StatusCode fill(const char *format...)
Set the values for several columns simultaneously.
Definition: TupleObj.cpp:236
void report() const
Definition: TupleObj.cpp:137
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:74
StatusCode column(const std::string &name, float value)
Set the value for selected tuple column.
Definition: TupleObj.cpp:285
T endl(T...args)
TupleObj()=delete
delete the default/copy constructor and assignment
STL namespace.
T end(T...args)
unsigned short MIndex
Definition: TupleObj.h:243
std::map< std::string, long > m_map
Definition: TupleObj.cpp:146
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:84
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:743
Counter(std::string msg=" Misbalance ")
Definition: TupleObj.cpp:125
STL class.
bool addItem(std::string name, std::string type)
add the item name into the list of known items
Definition: TupleObj.h:2039
struct GAUDI_API map
Parametrisation class for map-like implementation.
A simple wrapper class over standard Gaudi NTuple::Tuple facility.
Definition: TupleObj.h:196
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
T find_first_of(T...args)
StatusCode write()
write a record to NTuple
Definition: TupleObj.cpp:202
unsigned int CLID
Class ID definition.
Definition: ClassID.h:8
T move(T...args)
Abstract base class which allows the user to interact with the actual N tuple implementation.
Definition: NTuple.h:370
virtual ~TupleObj()
destructor is protected
Definition: TupleObj.cpp:182
FArray * fArray(const std::string &name, Int *item)
get the column
Definition: TupleObj.cpp:467
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:554
FMatrix * fMatrix(const std::string &name, Int *item, const MIndex &cols)
get the column
Definition: TupleObj.cpp:496
bool invalid() const
invalid pointer to tuple ?
Definition: TupleObj.h:2030
Opaque address interface definition.
void ignore() const
Definition: StatusCode.h:106
Class acting as a smart pointer holding a N tuple _Item.
Definition: NTuple.h:42
std::string m_message
Definition: TupleObj.cpp:150
Class acting as a smart pointer holding a N tuple _Item.
Definition: NTuple.h:43
Type
the list of available types for ntuples
Definition: TupleObj.h:79
long increment(const std::string &object)
Definition: TupleObj.cpp:131
TO * reference(FROM *from)
Definition: KeyedObject.cpp:20
General namespace for Tuple properties.
Definition: Maps.h:34
T emplace_back(T...args)