| # Gaudi Framework, version v21r9 |

Home |  | Generated: 3 May 2010

# TupleObj.cpp

Go to the documentation of this file.

    00001 // $Id: TupleObj.cpp,v 1.8 2007/09/28 11:47:29 marcocle Exp $
    00002 // ============================================================================
    00003 // Include files
    00004 // ============================================================================
    00005 // STD & STL
    00006 // ============================================================================
    00007 #include <cstdarg>
    00008 #include <algorithm>
    00009 #include <map>
    00010 // ============================================================================
    00011 // GaudiKernel
    00012 // ============================================================================
    00013 #include "GaudiKernel/GaudiException.h"
    00014 // ============================================================================
    00015 // GaudiAlg
    00016 // ============================================================================
    00017 #include "GaudiAlg/Tuples.h"
    00018 #include "GaudiAlg/TupleObj.h"
    00019 // ============================================================================
    00020 // Boost
    00021 // ============================================================================
    00022 #include  "boost/integer_traits.hpp"
    00023 #include  "boost/static_assert.hpp"
    00024 // ============================================================================
    00032 // ============================================================================
    00033 namespace Tuples
    00034 {
    00035   // Nesessary for Tuples::TupleObj:
    00036   BOOST_STATIC_ASSERT( boost::integer_traits<int>            :: is_specialized ) ;
    00037   BOOST_STATIC_ASSERT( boost::integer_traits<short>          :: is_specialized ) ;
    00038   BOOST_STATIC_ASSERT( boost::integer_traits<unsigned short> :: is_specialized ) ;
    00039   BOOST_STATIC_ASSERT( boost::integer_traits<char>           :: is_specialized ) ;
    00040   BOOST_STATIC_ASSERT( boost::integer_traits<unsigned char>  :: is_specialized ) ;
    00041   BOOST_STATIC_ASSERT( sizeof ( int            ) <= sizeof ( long          ) ) ;
    00042   BOOST_STATIC_ASSERT( sizeof ( int            ) <= sizeof ( unsigned long ) ) ;
    00043   BOOST_STATIC_ASSERT( sizeof ( int            ) <= sizeof ( unsigned int  ) ) ;
    00044   BOOST_STATIC_ASSERT( sizeof ( short          ) <= sizeof ( int           ) ) ;
    00045   BOOST_STATIC_ASSERT( sizeof ( unsigned short ) <= sizeof ( int           ) ) ;
    00046   BOOST_STATIC_ASSERT( sizeof ( char           ) <= sizeof ( int           ) ) ;
    00047   BOOST_STATIC_ASSERT( sizeof ( signed char    ) <= sizeof ( int           ) ) ;
    00048   BOOST_STATIC_ASSERT( sizeof ( unsigned char  ) <= sizeof ( int           ) ) ;
    00049   BOOST_STATIC_ASSERT( boost::integer_traits<int>::const_max   <=
    00050                        boost::integer_traits<long>::const_max    ) ;
    00051   BOOST_STATIC_ASSERT( boost::integer_traits<int>::const_min   >=
    00052                        boost::integer_traits<long>::const_min    ) ;
    00053   BOOST_STATIC_ASSERT( boost::integer_traits<short>::const_max <=
    00054                        boost::integer_traits<int>::const_max    ) ;
    00055   BOOST_STATIC_ASSERT( boost::integer_traits<short>::const_min >=
    00056                        boost::integer_traits<int>::const_min    ) ;
    00057   BOOST_STATIC_ASSERT( boost::integer_traits<unsigned short>::const_max <=
    00058                        (unsigned int) boost::integer_traits<int>::const_max ) ;
    00059   BOOST_STATIC_ASSERT( boost::integer_traits<char>::const_max  <=
    00060                        boost::integer_traits<int>::const_max    ) ;
    00061   BOOST_STATIC_ASSERT( boost::integer_traits<char>::const_min  >=
    00062                        boost::integer_traits<int>::const_min    ) ;
    00063   BOOST_STATIC_ASSERT( boost::integer_traits<unsigned char>::const_max <=
    00064                        (unsigned int) boost::integer_traits<int>::const_max ) ;
    00065   BOOST_STATIC_ASSERT( 31 == boost::integer_traits<int>::digits   ) ;
    00066   BOOST_STATIC_ASSERT( std::numeric_limits<float>::is_specialized ) ;
    00067   //
    00068   namespace Local
    00069   {
    00070     class Counter
    00071     {
    00072     public:
    00073       // constructor
    00074       Counter ( const std::string& msg = " Misbalance ")
    00075         : m_map     ()
    00076         , m_message ( msg )
    00077       {};
    00078       // destructor
    00079       ~Counter() { report() ; m_map.clear() ;}
    00080       // make the increment
    00081       long increment ( const std::string& object ) { return ++m_map[object] ; }
    00082       // make the decrement
    00083       long decrement ( const std::string& object ) { return --m_map[object] ; }
    00084       // current count
    00085       long counts    ( const std::string& object ) { return   m_map[object] ; }
    00086       // make a report
    00087       void report() const
    00088       {
    00089         for ( Map::const_iterator entry = m_map.begin() ;
    00090               m_map.end() != entry ; ++entry )
    00091         {
    00092           if( 0 == entry->second ) { continue ; }
    00093           std::cout << "Tuples::TupleObj WARNING "          << m_message
    00094                     << "'" << entry->first << "' Counts = " << entry->second
    00095                     << std::endl ;
    00096         }
    00097       };
    00098
    00099     private:
    00100       typedef std::map<std::string,long> Map;
    00101       Map         m_map     ;
    00102       std::string m_message ;
    00103     };
    00104
    00110     static Counter s_InstanceCounter ( " Create/Destroy      (mis)balance " ) ;
    00111   }
    00112 }
    00113 // ============================================================================
    00114 // Standard constructor
    00115 // ============================================================================
    00116 Tuples::TupleObj::TupleObj
    00117 ( const std::string&    name  ,
    00118   NTuple::Tuple*        tuple ,
    00119   const CLID&           clid  ,
    00120   const Tuples::Type    type  )
    00121   //
    00122   : m_name     ( name )
    00123   , m_tuple    ( tuple )
    00124   , m_clid     ( clid )
    00125   , m_type     ( type )
    00126   // for error handling
    00127   , m_refCount ( 0 )
    00128   // columns
    00129   , m_ints      ()
    00130   , m_floats    ()
    00131   , m_addresses ()
    00132   , m_farrays   ()
    00133   , m_arraysf   ()
    00134   , m_fmatrices ()
    00135   , m_matricesf ()
    00136   //
    00137   , m_items     ()
    00138 {
    00139   // make counts
    00140   Tuples::Local::s_InstanceCounter.increment ( m_name ) ;
    00141 }
    00142 // ============================================================================
    00143 // destructor
    00144 // ============================================================================
    00145 Tuples::TupleObj::~TupleObj()
    00146 {
    00147   {// delete 'long' columns
    00148     for( Ints::iterator it = m_ints.begin() ;
    00149          m_ints.end() != it ; ++it )
    00150     { if( 0 != it->second ) { delete it->second ; } }
    00151     m_ints.clear() ;
    00152   }
    00153   {// delete 'float' columns
    00154     for( Floats::iterator it = m_floats.begin() ;
    00155          m_floats.end() != it ; ++it )
    00156     { if( 0 != it->second ) { delete it->second ; } }
    00157     m_floats.clear() ;
    00158   }
    00159   {// delete 'fArray' columns
    00160     for( FArrays::iterator it = m_farrays.begin() ;
    00161          m_farrays.end() != it ; ++it )
    00162     { if( 0 != it->second ) { delete it->second ; } }
    00163     m_farrays.clear() ;
    00164   }
    00165   {// delete 'fArray' columns
    00166     for( FArrays::iterator it = m_arraysf.begin() ;
    00167          m_arraysf.end() != it ; ++it )
    00168     { if( 0 != it->second ) { delete it->second ; } }
    00169     m_arraysf.clear() ;
    00170   }
    00171   { // destroy and clean all "addresses"
    00172     for( Addresses::iterator it = m_addresses.begin() ;
    00173          m_addresses.end() != it ; ++it )
    00174     { if( 0 != it->second ) { delete it->second ; } }
    00175     m_addresses.clear();
    00176   }
    00177   { // destroy and clean all "matrices"
    00178     for( FMatrices::iterator it = m_fmatrices.begin() ;
    00179          m_fmatrices.end() != it ; ++it )
    00180     { if( 0 != it->second ) { delete it->second ; } }
    00181     m_fmatrices.clear();
    00182   }
    00183   { // destroy and clean all "matrices" (fixed)
    00184     for( FMatrices::iterator it = m_matricesf.begin() ;
    00185          m_matricesf.end() != it ; ++it )
    00186     { if( 0 != it->second ) { delete it->second ; } }
    00187     m_matricesf.clear();
    00188   }
    00189
    00190   // make counts
    00191   Tuples::Local::s_InstanceCounter.decrement ( m_name ) ;
    00192 }
    00193 // ============================================================================
    00194 // release the reference to TupleObj
    00195 // if reference counter becomes zero,
    00196 // object will be automatically deleted
    00197 // ============================================================================
    00198 void Tuples::TupleObj::release ()
    00199 {
    00200   // decrease the reference counter
    00201   if( 0 < refCount() ) { --m_refCount; }
    00202   // check references
    00203   if( 0 != refCount() ) { return; }
    00204   // delete the object
    00205   delete this  ;
    00206 }
    00207 // ============================================================================
    00208 // write a record to NTuple
    00209 // ============================================================================
    00210 StatusCode Tuples::TupleObj::write ()
    00211 {
    00212   if ( invalid()  ) { return InvalidTuple ; }
    00213   return tuple()->write() ;
    00214 }
    00215 // ============================================================================
    00216 namespace
    00217 {
    00219   typedef std::vector<std::string> Tokens;
    00224   size_t tokenize( const std::string& value            ,
    00225                    Tokens&            tokens           ,
    00226                    const std::string& separators = " " )
    00227   {
    00228     // reset the existing tokens
    00229     tokens.clear();
    00230     if( value       .empty () ) { return tokens.size () ; }
    00231     std::string::const_iterator it1 = value.begin() ;
    00232     std::string::const_iterator it2 = value.begin() ;
    00233     while( value.end() != it1 && value.end() != it2 )
    00234     {
    00235       it2 = std::find_first_of( it1                  ,
    00236                                 value.end         () ,
    00237                                 separators.begin  () ,
    00238                                 separators.end    () ) ;
    00239       if( it2 != it1 )
    00240       {
    00241         std::string aux( value , it1 - value.begin() , it2 - it1 ) ;
    00242         tokens.push_back( aux ) ;
    00243         it1  = it2 ;
    00244       }
    00245       else { ++it1 ; }
    00246
    00247     }
    00248     return tokens.size();
    00249   }
    00250 }
    00251 // ============================================================================
    00252 StatusCode Tuples::TupleObj::fill( const char*  format ... )
    00253 {
    00254   // check the underlying tuple
    00255   if ( invalid()      ) { return InvalidTuple ; }
    00256   // decode format string into tokens
    00257   Tokens tokens ;
    00258   tokenize( format , tokens , " ,;" );
    00259   if ( tokens.empty() ) { return StatusCode::SUCCESS ; }
    00261   va_list valist ;
    00262   va_start( valist , format ) ;
    00263   // loop over all tokens
    00264   StatusCode status = StatusCode::SUCCESS ;
    00265   for( Tokens::const_iterator token = tokens.begin() ;
    00266        tokens.end() != token && status.isSuccess() ; ++token )
    00267   {
    00268     const double val = va_arg( valist , double );
    00269     status = column( *token , val );
    00270     if( status.isFailure() )
    00271     { Error ( " fill(): Can not add column '" + *token + "' " ) ; }
    00272   }
    00273   // mandatory !!!
    00274   va_end( valist );
    00275   //
    00276   return status ;
    00277 }
    00278 // ============================================================================
    00279 // put IOpaqueAddress in NTuple (has sense only for Event tag collection Ntuples)
    00280 // ============================================================================
    00281 StatusCode Tuples::TupleObj::column
    00282 ( const std::string&    name    ,
    00283   IOpaqueAddress*       address )
    00284 {
    00285   if (  invalid    () ) { return InvalidTuple     ; }
    00286   if ( !evtColType () ) { return InvalidOperation ; }
    00287   if ( 0 == address )
    00288   { return Error ( "column('" + name +
    00289                    "') IOpaqueAddress* is NULL!" , InvalidObject ) ; }
    00290   Address* item = addresses( name );
    00291   if ( 0 == item      ) { return InvalidItem      ; }
    00292   *item = address ;
    00293   return StatusCode::SUCCESS ;
    00294 }
    00295 // ============================================================================
    00296 // put IOpaqueAddress in NTuple (has sense only for Event tag collection Ntuples)
    00297 // ============================================================================
    00298 StatusCode Tuples::TupleObj::column
    00299 ( IOpaqueAddress*       address )
    00300 {
    00301   return column ("Address" , address ) ;
    00302 }
    00303 // ============================================================================
    00304 Tuples::TupleObj::Float*   Tuples::TupleObj::floats
    00305 ( const std::string& name )
    00306 {
    00307   Floats::iterator found = m_floats.find( name ) ;
    00308   if ( m_floats.end() != found ) { return found->second ; }
    00309   Float* item = new Float() ;
    00310   m_floats[ name ] = item ;
    00311   const StatusCode sc = tuple()->addItem( name , *item );
    00312   if ( sc.isFailure() )
    00313   { Error ( " floats ('" + name + "'): item is not added",  sc ) ; }
    00314   if ( !addItem ( name , "F" ) )
    00315   { Error ( " floats ('" + name + "'): item is not unique"     ) ; }
    00316   return item ;
    00317 }
    00318 // ============================================================================
    00319 Tuples::TupleObj::Int*   Tuples::TupleObj::ints
    00320 ( const std::string& name )
    00321 {
    00322   Ints::iterator found = m_ints.find( name ) ;
    00323   if( m_ints.end() != found ) { return found->second ; }
    00324   Int* item = new Int() ;
    00325   m_ints[ name ] = item ;
    00326   StatusCode sc = tuple()->addItem( name , *item );
    00327   if( sc.isFailure() )
    00328   { Error ( " ints ('" + name + "'): item is not added",  sc ) ; }
    00329   if ( !addItem ( name , "L" ) )
    00330   { Error ( " ints ('" + name + "'): item is not unique"     ) ; }
    00331   return item ;
    00332 }
    00333 // ============================================================================
    00334 Tuples::TupleObj::Int*   Tuples::TupleObj::ints
    00335 ( const std::string&   name ,
    00336   const int            minv ,
    00337   const int            maxv )
    00338 {
    00339   Ints::iterator found = m_ints.find( name ) ;
    00340   if( m_ints.end() != found ) { return found->second ; }
    00341   Int* item = new Int() ;
    00342   m_ints[ name ] = item ;
    00343   const StatusCode sc = tuple()->addItem( name , *item , minv , maxv );
    00344   if( sc.isFailure() )
    00345   { Error ( " ints ('" + name + "'): item is not added",  sc ) ; }
    00346   if ( !addItem ( name , "L" ) )
    00347   { Error ( " ints ('" + name + "'): item is not unique"     ) ; }
    00348   return item ;
    00349 }
    00350 // ============================================================================
    00351 Tuples::TupleObj::Address* Tuples::TupleObj::addresses
    00352 ( const std::string& name )
    00353 {
    00354   Addresses::iterator found = m_addresses.find( name ) ;
    00355   if( m_addresses.end() != found ) { return found->second ; }
    00356   Address* item = new Address() ;
    00357   m_addresses[ name ] = item ;
    00358   const StatusCode sc = tuple()->addItem( name , *item );
    00359   if( sc.isFailure() )
    00360   { Error ( " addresses ('" + name + "'): item is not added",  sc ) ; }
    00361   if ( !addItem ( name , "IOpaqueAddress*" ) )
    00362   { Error ( " addresses ('" + name + "'): item is not unique"     ) ; }
    00363   return item ;
    00364 }
    00365 // ============================================================================
    00366 // retrieve (book on demand) array-items for ntuple
    00367 // ============================================================================
    00368 Tuples::TupleObj::FArray* Tuples::TupleObj::fArray
    00369 ( const std::string&      name  ,
    00370   Tuples::TupleObj::Int* length )
    00371 {
    00372   // existing array ?
    00373   FArrays::iterator found = m_farrays.find( name ) ;
    00374   if( m_farrays.end() != found ) { return found->second ; }
    00375   // create new array
    00376   FArray* array = new FArray () ;
    00377   m_farrays[ name] =      array    ;
    00378   const StatusCode sc = tuple() -> addIndexedItem( name , *length , *array) ;
    00379   if( sc.isFailure() )
    00380   { Error ( " farray ('" + name + "'): item is not added",  sc ) ; }
    00381   if ( !addItem ( name , "FArray" ) )
    00382   { Error ( " farray ('" + name + "'): item is not unique"     ) ; }
    00383   return array ;
    00384 }
    00385 // ============================================================================
    00386 // retrieve (book on demand) array-items for ntuple (fixed)
    00387 // ============================================================================
    00388 Tuples::TupleObj::FArray* Tuples::TupleObj::fArray
    00389 ( const std::string&              name ,
    00390   const Tuples::TupleObj::MIndex& rows )
    00391 {
    00392   // existing array ?
    00393   FArrays::iterator found = m_arraysf.find( name ) ;
    00394   if( m_arraysf.end() != found ) { return found->second ; }
    00395   // create new array
    00396   FArray* array = new FArray () ;
    00397   m_arraysf[ name] =      array    ;
    00398   const StatusCode sc = tuple() -> addItem ( name , rows , *array) ;
    00399   if( sc.isFailure() )
    00400   { Error ( " array ('" + name + "'): item is not added",  sc ) ; }
    00401   if ( !addItem ( name , "FArray" ) )
    00402   { Error ( " array ('" + name + "'): item is not unique"     ) ; }
    00403   return array ;
    00404 }
    00405 // ============================================================================
    00406 // retrieve (book on demand) matrix-items for ntuple
    00407 // ============================================================================
    00408 Tuples::TupleObj::FMatrix*
    00409 Tuples::TupleObj::fMatrix
    00410 ( const std::string&              name   ,
    00411   Tuples::TupleObj::Int*          length ,
    00412   const Tuples::TupleObj::MIndex& cols   )
    00413 {
    00414   // existing array ?
    00415   FMatrices::iterator found = m_fmatrices.find( name ) ;
    00416   if( m_fmatrices.end() != found ) { return found->second ; }
    00417   // create new array
    00418   FMatrix* matrix = new FMatrix () ;
    00419   m_fmatrices[ name] =  matrix   ;
    00420   const StatusCode sc =
    00421     tuple() -> addIndexedItem( name , *length , cols , *matrix ) ;
    00422   if( sc.isFailure() )
    00423   { Error ( " fmatrix ('" + name + "'): item is not added",  sc ) ; }
    00424   if ( !addItem ( name , "FMatrix" ) )
    00425   { Error ( " fmatrix ('" + name + "'): item is not unique"     ) ; }
    00426   return matrix ;
    00427 }
    00428 // ============================================================================
    00429 // retrieve (book on demand) matrix-items for ntuple (fixed)
    00430 // ============================================================================
    00431 Tuples::TupleObj::FMatrix*
    00432 Tuples::TupleObj::fMatrix
    00433 ( const std::string&              name   ,
    00434   const Tuples::TupleObj::MIndex& rows   ,
    00435   const Tuples::TupleObj::MIndex& cols   )
    00436 {
    00437   // existing array ?
    00438   FMatrices::iterator found = m_matricesf.find( name ) ;
    00439   if( m_matricesf.end() != found ) { return found->second ; }
    00440   // create new array
    00441   FMatrix* matrix = new FMatrix () ;
    00442   m_matricesf[ name] =  matrix   ;
    00443   const StatusCode sc =
    00444     tuple() -> addItem( name , rows , cols , *matrix ) ;
    00445   if( sc.isFailure() )
    00446   { Error ( " matrix ('" + name + "'): item is not added",  sc ) ; }
    00447   if ( !addItem ( name , "FMatrix" ) )
    00448   { Error ( " matrix ('" + name + "'): item is not unique"     ) ; }
    00449   return matrix ;
    00450 }
    00451 // ============================================================================
    00452 // The END
    00453 // ============================================================================