| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

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 // ============================================================================
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 19:58:14 2011 for GaudiAlg by doxygen 1.4.7