![]() |
|
|
Generated: 8 Jan 2009 |
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 // ============================================================================