Warning, /include/GaudiAlg/GaudiTuples.icpp is written in an unsupported language. File is not indexed.
0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 * *
0004 * This software is distributed under the terms of the Apache version 2 licence, *
0005 * copied verbatim in the file "LICENSE". *
0006 * *
0007 * In applying this licence, CERN does not waive the privileges and immunities *
0008 * granted to it by virtue of its status as an Intergovernmental Organization *
0009 * or submit itself to any jurisdiction. *
0010 \***********************************************************************************/
0011 // ============================================================================
0012 // Include files
0013 // ============================================================================
0014 // Gaudi
0015 // ============================================================================
0016 #include "GaudiKernel/IRegistry.h"
0017 #include "GaudiKernel/ToStream.h"
0018 // ============================================================================
0019 // GaudiAlg
0020 // ============================================================================
0021 #include "GaudiAlg/GaudiTupleAlg.h"
0022 #include "GaudiAlg/GaudiTuples.h"
0023 #include "GaudiAlg/HbookName.h"
0024 #include "GaudiAlg/Print.h"
0025 #include "GaudiAlg/Tuple.h"
0026 #include "GaudiAlg/TupleDetail.h"
0027 #include "GaudiAlg/TupleObj.h"
0028 // ============================================================================
0029 /* @file GaudiTuples.cpp
0030 *
0031 * Implementation file for class : GaudiTuples
0032 *
0033 * @author Chris Jones Christopher.Rob.Jones@cern.ch
0034 * @author Vanya BELYAEV Ivan.Belyaev@itep.ru
0035 * @date 2005-08-08
0036 */
0037 // ============================================================================
0038 // Disable warning on windows
0039 #ifdef _WIN32
0040 # pragma warning( disable : 4661 ) // incomplete explicit templates
0041 #endif
0042
0043 //=============================================================================
0044 // Initialize ntupling
0045 //=============================================================================
0046 template <class PBASE>
0047 StatusCode GaudiTuples<PBASE>::initialize() {
0048 // initialize base class
0049 const StatusCode sc = PBASE::initialize();
0050 if ( sc.isFailure() ) return sc;
0051
0052 if ( produceNTuples() ) {
0053 // check the existance of service
0054 if ( this->ntupleSvc() == 0 ) { return this->Error( "INTupleSvc* points to NULL!" ); }
0055 // Print ntuple path
0056 this->Print( "The N-Tuple path is set to be '" + nTuplePath() + "'", StatusCode::SUCCESS, MSG::DEBUG ).ignore();
0057 } else {
0058 this->debug() << "Production of N-Tuples is switched OFF" << endmsg;
0059 }
0060
0061 if ( produceEvtCols() ) {
0062 // check the existance of service
0063 if ( 0 == this->evtColSvc() ) { return this->Error( "INTupleSvc* points to NULL!" ); }
0064 // Print EvtCol path
0065 this->Print( "The EventCol path is set to be '" + evtColPath() + "'", StatusCode::SUCCESS, MSG::DEBUG ).ignore();
0066 } else {
0067 this->debug() << "Production of Event Collections is switched OFF" << endmsg;
0068 }
0069
0070 return sc;
0071 }
0072
0073 //=============================================================================
0074 // finalize ntupling
0075 //=============================================================================
0076 template <class PBASE>
0077 StatusCode GaudiTuples<PBASE>::finalize() {
0078 if ( !( m_nTupleMap.empty() && m_evtColMap.empty() ) ) {
0079 const int nNtuples = m_nTupleMap.size();
0080 const int nEvtCols = m_evtColMap.size();
0081 this->always() << "Booked " << nNtuples << " N-Tuples and " << nEvtCols << " Event Tag Collections" << endmsg;
0082 }
0083
0084 if ( produceNTuples() && tuplesPrint() ) printTuples();
0085 if ( produceEvtCols() && evtColsPrint() ) printEvtCols();
0086
0087 // release ntuples and clear the container
0088 m_nTupleMap.clear();
0089
0090 // release ntuples and clear the container
0091 m_evtColMap.clear();
0092
0093 // finalize base class
0094 return PBASE::finalize();
0095 }
0096
0097 // ============================================================================
0098 // get N-tuple object ( book on-demand ) with unique identidier
0099 // ============================================================================
0100 template <class PBASE>
0101 Tuples::Tuple GaudiTuples<PBASE>::nTuple( const std::string& title, const CLID& clid ) const {
0102 // look up in the table
0103 auto& m = nTupleByTitle();
0104 auto tuple = m.find( title );
0105 if ( tuple != m.end() ) return Tuple( tuple->tuple ); // RETURN
0106 // Create the tuple ID
0107 TupleID ID;
0108 if ( this->useNumericAutoIDs() || title.empty() ) {
0109 if ( !this->useNumericAutoIDs() ) {
0110 this->Warning(
0111 "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for nTuple ID",
0112 StatusCode::SUCCESS )
0113 .ignore();
0114 }
0115 // propose the tuple ID
0116 ID = TupleID( m_nTupleMap.size() + 1 + nTupleOffSet() );
0117 // adjust the proposed ID
0118 while ( nTupleExists( ID ) || evtColExists( ID ) ) { ID = TupleID( ID.numeric() + 1 ); }
0119 } else {
0120 // use the title to create a unique literal ID
0121 ID = TupleID( this->convertTitleToID( title ) );
0122 // Just in case ...
0123 while ( nTupleExists( ID ) || evtColExists( ID ) ) { ID = TupleID( ID.idAsString() + "_" ); }
0124 }
0125 // return
0126 return nTuple( ID, title, clid );
0127 }
0128 // ============================================================================
0129
0130 // ============================================================================
0131 // Access an Event Tag Collection object (book on-demand) with unique identifier
0132 // ============================================================================
0133 template <class PBASE>
0134 Tuples::Tuple GaudiTuples<PBASE>::evtCol( const std::string& title, const CLID& clid ) const {
0135 // look up in the table
0136 auto& m = evtColByTitle();
0137 auto tuple = m.find( title );
0138 if ( tuple != m.end() ) return Tuple( tuple->tuple ); // RETURN
0139 // Create the tuple ID
0140 TupleID ID;
0141 if ( this->useNumericAutoIDs() || title.empty() ) {
0142 if ( !this->useNumericAutoIDs() ) {
0143 this->Warning(
0144 "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for evtCol ID",
0145 StatusCode::SUCCESS )
0146 .ignore();
0147 }
0148 // proposed the tuple ID
0149 ID = TupleID( m_evtColMap.size() + 1 + evtColOffSet() );
0150 // adjust the proposed ID
0151 while ( nTupleExists( ID ) || evtColExists( ID ) ) { ID = TupleID( ID.numeric() + 1 ); }
0152 } else {
0153 // use the title to create a unique literal ID
0154 ID = TupleID( this->convertTitleToID( title ) );
0155 // Just in case ...
0156 while ( nTupleExists( ID ) || evtColExists( ID ) ) { ID = TupleID( ID.idAsString() + "_" ); }
0157 }
0158 // return
0159 return evtCol( ID, title, clid );
0160 }
0161 // ============================================================================
0162
0163 // ============================================================================
0164 // get N-tuple object ( book on-demand ) with forced ID
0165 // ============================================================================
0166 template <class PBASE>
0167 Tuples::Tuple GaudiTuples<PBASE>::nTuple( const TupleID& ID, const std::string& title1, const CLID& clid ) const {
0168 // Check ID
0169 if ( ID.undefined() ) {
0170 this->Error( "Undefined NTuple ID : Title='" + title1 + "'" ).ignore();
0171 return Tuple( 0 );
0172 }
0173
0174 // look up in the table
0175 auto& m = nTupleByID();
0176 auto tuple = m.find( ID );
0177 if ( tuple != m.end() ) return Tuple( tuple->tuple ); // RETURN
0178
0179 // convert ID to the string
0180 const std::string tID = ID.idAsString();
0181
0182 // adjust the NTuple title
0183 const std::string title = title1.empty() ? ( "NTuple #" + tID ) : title1;
0184
0185 // book new ntuple
0186 if ( !produceNTuples() ) {
0187 auto r = m_nTupleMap.insert( nTupleMapItem{ title, ID, createNTuple( title, nullptr, clid ) } );
0188 if ( !r.second ) this->Error( "Failure to createNTuple" ).ignore();
0189 return Tuple( r.first->tuple );
0190 }
0191 // book NTupel
0192 NTuple::Tuple* tup = nullptr;
0193 if ( ID.numeric() ) {
0194 tup = this->ntupleSvc()->book( nTuplePath(), ID.numericID(), clid, title );
0195 } else if ( ID.literal() ) {
0196 tup = this->ntupleSvc()->book( nTuplePath(), ID.literalID(), clid, title );
0197 } else {
0198 this->Error( "Undefined NTuple ID" ).ignore();
0199 }
0200
0201 // assertion
0202 this->Assert( tup, "Could not book the N-Tuple='" + title + "'" );
0203 // some printout
0204 if ( tup->registry() && this->msgLevel( MSG::DEBUG ) ) {
0205 this->debug() << "Booked NTuple '" << title << "' ID=" << tID << "' Path='" << nTuplePath() << "' TS='"
0206 << tup->registry()->identifier() << "'" << endmsg;
0207 }
0208
0209 auto r = m_nTupleMap.insert( nTupleMapItem{ title, ID, createNTuple( title, tup, clid ) } );
0210 if ( !r.second ) this->Error( "Failure to createNTuple" ).ignore();
0211 return Tuple( r.first->tuple );
0212 //
0213 }
0214 // ============================================================================
0215 template <class PBASE>
0216 Tuples::Tuple GaudiTuples<PBASE>::evtCol( const TupleID& ID, const std::string& title1, const CLID& clid ) const {
0217 // Check ID
0218 if ( ID.undefined() ) {
0219 this->Error( "Undefined NTuple ID : Title='" + title1 + "'" ).ignore();
0220 return Tuple( 0 );
0221 }
0222
0223 // look up in the table
0224 auto& tuple = evtColByID();
0225 auto i = tuple.find( ID );
0226 if ( i != tuple.end() ) return Tuple( i->tuple ); // RETURN
0227
0228 // convert ID to the string
0229 const std::string tID = ID.idAsString();
0230
0231 // adjust the NTuple title
0232 const std::string title = title1.empty() ? ( "EvtCol #" + tID ) : title1;
0233
0234 // book new ntuple
0235 if ( !produceEvtCols() ) {
0236 auto r = m_evtColMap.insert( nTupleMapItem{ title, ID, createEvtCol( title, nullptr, clid ) } );
0237 if ( !r.second ) this->Error( "Failure to createEvtCol" ).ignore();
0238 return Tuple( r.first->tuple );
0239 }
0240 // book NTuple
0241 NTuple::Tuple* tup = nullptr;
0242 if ( ID.numeric() ) {
0243 tup = this->evtColSvc()->book( evtColPath(), ID.numericID(), clid, title );
0244 } else if ( ID.literal() ) {
0245 tup = this->evtColSvc()->book( evtColPath(), ID.literalID(), clid, title );
0246 } else {
0247 this->Error( "Undefined NTuple ID" ).ignore();
0248 }
0249
0250 // assertion
0251 this->Assert( tup, "Could not book the EvtCol='" + title + "'" );
0252 // some printout
0253 if ( tup->registry() && this->msgLevel( MSG::DEBUG ) ) {
0254 this->debug() << "Booked EvtCol '" << title << "' ID=" << tID << "' Path='" << evtColPath() << "' TS='"
0255 << tup->registry()->identifier() << "'" << endmsg;
0256 }
0257 auto r = m_evtColMap.insert( nTupleMapItem{ title, ID, createEvtCol( title, tup, clid ) } );
0258 if ( !r.second ) this->Error( "Failure to createEvtCol" ).ignore();
0259 return Tuple( r.first->tuple );
0260 }
0261 // ============================================================================
0262 // create TupleObj
0263 // ============================================================================
0264 template <class PBASE>
0265 std::unique_ptr<Tuples::TupleObj> GaudiTuples<PBASE>::createNTuple( const std::string& name, NTuple::Tuple* tuple,
0266 const CLID& clid ) const {
0267 return Tuples::createTupleObj( this, "Tuple '" + name + "'", tuple, clid, Tuples::NTUPLE );
0268 }
0269 // ============================================================================
0270
0271 // ============================================================================
0272 // create TupleObj for event tag collection
0273 // ============================================================================
0274 template <class PBASE>
0275 std::unique_ptr<Tuples::TupleObj> GaudiTuples<PBASE>::createEvtCol( const std::string& name, NTuple::Tuple* tuple,
0276 const CLID& clid ) const {
0277 return Tuples::createTupleObj( this, "EvtCol '" + name + "'", tuple, clid, Tuples::EVTCOL );
0278 }
0279 // ============================================================================
0280 // perform the actual printout of N-tuples
0281 // ============================================================================
0282 template <class PBASE>
0283 long GaudiTuples<PBASE>::printTuples() const {
0284
0285 if ( m_nTupleMap.empty() ) {
0286 if ( this->msgLevel( MSG::DEBUG ) ) this->debug() << "No N-Tuples are booked" << endmsg;
0287 } else {
0288 this->always() << "List of booked N-Tuples in directory "
0289 << "\"" << nTuplePath() << "\"" << endmsg;
0290 }
0291
0292 for ( const auto& entry : this->nTupleOrdered() ) {
0293 if ( !entry.tuple->tuple() ) {
0294 this->error() << " NTuple::Tuple* points to NULL" << endmsg;
0295 continue;
0296 }
0297 this->always() << GaudiAlg::PrintTuple::print( entry.tuple->tuple(), entry.id ) << endmsg;
0298 }
0299 //
0300 return this->m_nTupleMap.size();
0301 }
0302 // ============================================================================
0303 // perform the actual printout of Evt Tag Collections
0304 // ============================================================================
0305 template <class PBASE>
0306 long GaudiTuples<PBASE>::printEvtCols() const {
0307 if ( m_evtColMap.empty() ) {
0308 this->always() << "No Event Tag Collections are booked" << endmsg;
0309 } else {
0310 this->always() << "List of booked Event Tag Collections in directory "
0311 << "\"" << evtColPath() << "\"" << endmsg;
0312 }
0313 for ( const auto& entry : this->evtColOrdered() ) {
0314 if ( !entry.tuple->tuple() ) {
0315 this->error() << " NTuple::Tuple* points to NULL" << endmsg;
0316 continue;
0317 }
0318 this->always() << GaudiAlg::PrintTuple::print( entry.tuple->tuple(), entry.id )
0319 << " Items:" << Gaudi::Utils::toString( entry.tuple->items() ) << endmsg;
0320 }
0321 //
0322 return this->m_evtColMap.size();
0323 }
0324 // ============================================================================
0325 // check the existence AND validity of the N-Tuple with the given ID
0326 // ============================================================================
0327 template <class PBASE>
0328 bool GaudiTuples<PBASE>::nTupleExists( const TupleID& ID ) const {
0329 auto& m = nTupleByID();
0330 return m.find( ID ) != m.end();
0331 }
0332 // ============================================================================
0333 // check the existence AND validity of the Event Tag Collection with the given ID
0334 // ============================================================================
0335 template <class PBASE>
0336 bool GaudiTuples<PBASE>::evtColExists( const TupleID& ID ) const {
0337 auto& m = evtColByID();
0338 return m.find( ID ) != m.end();
0339 }
0340 // ============================================================================
0341 // get the constructed N-Tuple path
0342 // ============================================================================
0343 template <class PBASE>
0344 std::string GaudiTuples<PBASE>::nTuplePath() const {
0345 const std::string path = nTupleLUN() + "/" + nTupleTopDir() + nTupleDir();
0346 return splitNTupleDir() ? dirHbookName( path ) : path;
0347 }
0348 // ============================================================================
0349 // get the constructed Event Tag Collection path
0350 // ============================================================================
0351 template <class PBASE>
0352 std::string GaudiTuples<PBASE>::evtColPath() const {
0353 std::string path = evtColLUN() + "/" + evtColTopDir() + evtColDir();
0354 return splitEvtColDir() ? dirHbookName( path ) : path;
0355 }
0356 // ============================================================================
0357 // The END
0358 // ============================================================================