The Gaudi Framework  v38r1p1 (ae26267b)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
GaudiTuples.icpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 // ============================================================================
12 // Include files
13 // ============================================================================
14 // Gaudi
15 // ============================================================================
16 #include "GaudiKernel/IRegistry.h"
17 #include "GaudiKernel/ToStream.h"
18 // ============================================================================
19 // GaudiAlg
20 // ============================================================================
21 #include "GaudiAlg/GaudiTupleAlg.h"
22 #include "GaudiAlg/GaudiTuples.h"
23 #include "GaudiAlg/HbookName.h"
24 #include "GaudiAlg/Print.h"
25 #include "GaudiAlg/Tuple.h"
26 #include "GaudiAlg/TupleDetail.h"
27 #include "GaudiAlg/TupleObj.h"
28 // ============================================================================
29 /* @file GaudiTuples.cpp
30  *
31  * Implementation file for class : GaudiTuples
32  *
33  * @author Chris Jones Christopher.Rob.Jones@cern.ch
34  * @author Vanya BELYAEV Ivan.Belyaev@itep.ru
35  * @date 2005-08-08
36  */
37 // ============================================================================
38 // Disable warning on windows
39 #ifdef _WIN32
40 # pragma warning( disable : 4661 ) // incomplete explicit templates
41 #endif
42 
43 //=============================================================================
44 // Initialize ntupling
45 //=============================================================================
46 template <class PBASE>
48  // initialize base class
49  const StatusCode sc = PBASE::initialize();
50  if ( sc.isFailure() ) return sc;
51 
52  if ( produceNTuples() ) {
53  // check the existance of service
54  if ( this->ntupleSvc() == 0 ) { return this->Error( "INTupleSvc* points to NULL!" ); }
55  // Print ntuple path
56  this->Print( "The N-Tuple path is set to be '" + nTuplePath() + "'", StatusCode::SUCCESS, MSG::DEBUG ).ignore();
57  } else {
58  this->debug() << "Production of N-Tuples is switched OFF" << endmsg;
59  }
60 
61  if ( produceEvtCols() ) {
62  // check the existance of service
63  if ( 0 == this->evtColSvc() ) { return this->Error( "INTupleSvc* points to NULL!" ); }
64  // Print EvtCol path
65  this->Print( "The EventCol path is set to be '" + evtColPath() + "'", StatusCode::SUCCESS, MSG::DEBUG ).ignore();
66  } else {
67  this->debug() << "Production of Event Collections is switched OFF" << endmsg;
68  }
69 
70  return sc;
71 }
72 
73 //=============================================================================
74 // finalize ntupling
75 //=============================================================================
76 template <class PBASE>
78  if ( !( m_nTupleMap.empty() && m_evtColMap.empty() ) ) {
79  const int nNtuples = m_nTupleMap.size();
80  const int nEvtCols = m_evtColMap.size();
81  this->always() << "Booked " << nNtuples << " N-Tuples and " << nEvtCols << " Event Tag Collections" << endmsg;
82  }
83 
84  if ( produceNTuples() && tuplesPrint() ) printTuples();
85  if ( produceEvtCols() && evtColsPrint() ) printEvtCols();
86 
87  // release ntuples and clear the container
88  m_nTupleMap.clear();
89 
90  // release ntuples and clear the container
91  m_evtColMap.clear();
92 
93  // finalize base class
94  return PBASE::finalize();
95 }
96 
97 // ============================================================================
98 // get N-tuple object ( book on-demand ) with unique identidier
99 // ============================================================================
100 template <class PBASE>
101 Tuples::Tuple GaudiTuples<PBASE>::nTuple( const std::string& title, const CLID& clid ) const {
102  // look up in the table
103  auto& m = nTupleByTitle();
104  auto tuple = m.find( title );
105  if ( tuple != m.end() ) return Tuple( tuple->tuple ); // RETURN
106  // Create the tuple ID
107  TupleID ID;
108  if ( this->useNumericAutoIDs() || title.empty() ) {
109  if ( !this->useNumericAutoIDs() ) {
110  this->Warning(
111  "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for nTuple ID",
113  .ignore();
114  }
115  // propose the tuple ID
116  ID = TupleID( m_nTupleMap.size() + 1 + nTupleOffSet() );
117  // adjust the proposed ID
118  while ( nTupleExists( ID ) || evtColExists( ID ) ) { ID = TupleID( ID.numeric() + 1 ); }
119  } else {
120  // use the title to create a unique literal ID
121  ID = TupleID( this->convertTitleToID( title ) );
122  // Just in case ...
123  while ( nTupleExists( ID ) || evtColExists( ID ) ) { ID = TupleID( ID.idAsString() + "_" ); }
124  }
125  // return
126  return nTuple( ID, title, clid );
127 }
128 // ============================================================================
129 
130 // ============================================================================
131 // Access an Event Tag Collection object (book on-demand) with unique identifier
132 // ============================================================================
133 template <class PBASE>
134 Tuples::Tuple GaudiTuples<PBASE>::evtCol( const std::string& title, const CLID& clid ) const {
135  // look up in the table
136  auto& m = evtColByTitle();
137  auto tuple = m.find( title );
138  if ( tuple != m.end() ) return Tuple( tuple->tuple ); // RETURN
139  // Create the tuple ID
140  TupleID ID;
141  if ( this->useNumericAutoIDs() || title.empty() ) {
142  if ( !this->useNumericAutoIDs() ) {
143  this->Warning(
144  "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for evtCol ID",
146  .ignore();
147  }
148  // proposed the tuple ID
149  ID = TupleID( m_evtColMap.size() + 1 + evtColOffSet() );
150  // adjust the proposed ID
151  while ( nTupleExists( ID ) || evtColExists( ID ) ) { ID = TupleID( ID.numeric() + 1 ); }
152  } else {
153  // use the title to create a unique literal ID
154  ID = TupleID( this->convertTitleToID( title ) );
155  // Just in case ...
156  while ( nTupleExists( ID ) || evtColExists( ID ) ) { ID = TupleID( ID.idAsString() + "_" ); }
157  }
158  // return
159  return evtCol( ID, title, clid );
160 }
161 // ============================================================================
162 
163 // ============================================================================
164 // get N-tuple object ( book on-demand ) with forced ID
165 // ============================================================================
166 template <class PBASE>
167 Tuples::Tuple GaudiTuples<PBASE>::nTuple( const TupleID& ID, const std::string& title1, const CLID& clid ) const {
168  // Check ID
169  if ( ID.undefined() ) {
170  this->Error( "Undefined NTuple ID : Title='" + title1 + "'" ).ignore();
171  return Tuple( 0 );
172  }
173 
174  // look up in the table
175  auto& m = nTupleByID();
176  auto tuple = m.find( ID );
177  if ( tuple != m.end() ) return Tuple( tuple->tuple ); // RETURN
178 
179  // convert ID to the string
180  const std::string tID = ID.idAsString();
181 
182  // adjust the NTuple title
183  const std::string title = title1.empty() ? ( "NTuple #" + tID ) : title1;
184 
185  // book new ntuple
186  if ( !produceNTuples() ) {
187  auto r = m_nTupleMap.insert( nTupleMapItem{ title, ID, createNTuple( title, nullptr, clid ) } );
188  if ( !r.second ) this->Error( "Failure to createNTuple" ).ignore();
189  return Tuple( r.first->tuple );
190  }
191  // book NTupel
192  NTuple::Tuple* tup = nullptr;
193  if ( ID.numeric() ) {
194  tup = this->ntupleSvc()->book( nTuplePath(), ID.numericID(), clid, title );
195  } else if ( ID.literal() ) {
196  tup = this->ntupleSvc()->book( nTuplePath(), ID.literalID(), clid, title );
197  } else {
198  this->Error( "Undefined NTuple ID" ).ignore();
199  }
200 
201  // assertion
202  this->Assert( tup, "Could not book the N-Tuple='" + title + "'" );
203  // some printout
204  if ( tup->registry() && this->msgLevel( MSG::DEBUG ) ) {
205  this->debug() << "Booked NTuple '" << title << "' ID=" << tID << "' Path='" << nTuplePath() << "' TS='"
206  << tup->registry()->identifier() << "'" << endmsg;
207  }
208 
209  auto r = m_nTupleMap.insert( nTupleMapItem{ title, ID, createNTuple( title, tup, clid ) } );
210  if ( !r.second ) this->Error( "Failure to createNTuple" ).ignore();
211  return Tuple( r.first->tuple );
212  //
213 }
214 // ============================================================================
215 template <class PBASE>
216 Tuples::Tuple GaudiTuples<PBASE>::evtCol( const TupleID& ID, const std::string& title1, const CLID& clid ) const {
217  // Check ID
218  if ( ID.undefined() ) {
219  this->Error( "Undefined NTuple ID : Title='" + title1 + "'" ).ignore();
220  return Tuple( 0 );
221  }
222 
223  // look up in the table
224  auto& tuple = evtColByID();
225  auto i = tuple.find( ID );
226  if ( i != tuple.end() ) return Tuple( i->tuple ); // RETURN
227 
228  // convert ID to the string
229  const std::string tID = ID.idAsString();
230 
231  // adjust the NTuple title
232  const std::string title = title1.empty() ? ( "EvtCol #" + tID ) : title1;
233 
234  // book new ntuple
235  if ( !produceEvtCols() ) {
236  auto r = m_evtColMap.insert( nTupleMapItem{ title, ID, createEvtCol( title, nullptr, clid ) } );
237  if ( !r.second ) this->Error( "Failure to createEvtCol" ).ignore();
238  return Tuple( r.first->tuple );
239  }
240  // book NTuple
241  NTuple::Tuple* tup = nullptr;
242  if ( ID.numeric() ) {
243  tup = this->evtColSvc()->book( evtColPath(), ID.numericID(), clid, title );
244  } else if ( ID.literal() ) {
245  tup = this->evtColSvc()->book( evtColPath(), ID.literalID(), clid, title );
246  } else {
247  this->Error( "Undefined NTuple ID" ).ignore();
248  }
249 
250  // assertion
251  this->Assert( tup, "Could not book the EvtCol='" + title + "'" );
252  // some printout
253  if ( tup->registry() && this->msgLevel( MSG::DEBUG ) ) {
254  this->debug() << "Booked EvtCol '" << title << "' ID=" << tID << "' Path='" << evtColPath() << "' TS='"
255  << tup->registry()->identifier() << "'" << endmsg;
256  }
257  auto r = m_evtColMap.insert( nTupleMapItem{ title, ID, createEvtCol( title, tup, clid ) } );
258  if ( !r.second ) this->Error( "Failure to createEvtCol" ).ignore();
259  return Tuple( r.first->tuple );
260 }
261 // ============================================================================
262 // create TupleObj
263 // ============================================================================
264 template <class PBASE>
266  const CLID& clid ) const {
267  return Tuples::createTupleObj( this, "Tuple '" + name + "'", tuple, clid, Tuples::NTUPLE );
268 }
269 // ============================================================================
270 
271 // ============================================================================
272 // create TupleObj for event tag collection
273 // ============================================================================
274 template <class PBASE>
276  const CLID& clid ) const {
277  return Tuples::createTupleObj( this, "EvtCol '" + name + "'", tuple, clid, Tuples::EVTCOL );
278 }
279 // ============================================================================
280 // perform the actual printout of N-tuples
281 // ============================================================================
282 template <class PBASE>
284 
285  if ( m_nTupleMap.empty() ) {
286  if ( this->msgLevel( MSG::DEBUG ) ) this->debug() << "No N-Tuples are booked" << endmsg;
287  } else {
288  this->always() << "List of booked N-Tuples in directory "
289  << "\"" << nTuplePath() << "\"" << endmsg;
290  }
291 
292  for ( const auto& entry : this->nTupleOrdered() ) {
293  if ( !entry.tuple->tuple() ) {
294  this->error() << " NTuple::Tuple* points to NULL" << endmsg;
295  continue;
296  }
297  this->always() << GaudiAlg::PrintTuple::print( entry.tuple->tuple(), entry.id ) << endmsg;
298  }
299  //
300  return this->m_nTupleMap.size();
301 }
302 // ============================================================================
303 // perform the actual printout of Evt Tag Collections
304 // ============================================================================
305 template <class PBASE>
307  if ( m_evtColMap.empty() ) {
308  this->always() << "No Event Tag Collections are booked" << endmsg;
309  } else {
310  this->always() << "List of booked Event Tag Collections in directory "
311  << "\"" << evtColPath() << "\"" << endmsg;
312  }
313  for ( const auto& entry : this->evtColOrdered() ) {
314  if ( !entry.tuple->tuple() ) {
315  this->error() << " NTuple::Tuple* points to NULL" << endmsg;
316  continue;
317  }
318  this->always() << GaudiAlg::PrintTuple::print( entry.tuple->tuple(), entry.id )
319  << " Items:" << Gaudi::Utils::toString( entry.tuple->items() ) << endmsg;
320  }
321  //
322  return this->m_evtColMap.size();
323 }
324 // ============================================================================
325 // check the existence AND validity of the N-Tuple with the given ID
326 // ============================================================================
327 template <class PBASE>
328 bool GaudiTuples<PBASE>::nTupleExists( const TupleID& ID ) const {
329  auto& m = nTupleByID();
330  return m.find( ID ) != m.end();
331 }
332 // ============================================================================
333 // check the existence AND validity of the Event Tag Collection with the given ID
334 // ============================================================================
335 template <class PBASE>
336 bool GaudiTuples<PBASE>::evtColExists( const TupleID& ID ) const {
337  auto& m = evtColByID();
338  return m.find( ID ) != m.end();
339 }
340 // ============================================================================
341 // get the constructed N-Tuple path
342 // ============================================================================
343 template <class PBASE>
345  const std::string path = nTupleLUN() + "/" + nTupleTopDir() + nTupleDir();
346  return splitNTupleDir() ? dirHbookName( path ) : path;
347 }
348 // ============================================================================
349 // get the constructed Event Tag Collection path
350 // ============================================================================
351 template <class PBASE>
353  std::string path = evtColLUN() + "/" + evtColTopDir() + evtColDir();
354  return splitEvtColDir() ? dirHbookName( path ) : path;
355 }
356 // ============================================================================
357 // The END
358 // ============================================================================
MSG::DEBUG
@ DEBUG
Definition: IMessageSvc.h:25
GaudiAlg.TupleUtils.nTuple
def nTuple(dirpath, ID, ID2=None, topdir=None, LUN="FILE1")
Definition: TupleUtils.py:84
Tuple.h
std::string
STL class.
GaudiAlg::ID
Definition: GaudiHistoID.h:53
GaudiAlg.HistoUtils.path
path
Definition: HistoUtils.py:960
Tuples::EVTCOL
@ EVTCOL
Definition: TupleObj.h:93
GaudiAlg.Algs.Tuple
Tuple
Definition: Algs.py:1173
HbookName.h
GaudiAlg::ID::numericID
NumericID numericID() const noexcept
Returns the numerical ID.
Definition: GaudiHistoID.h:82
ToStream.h
TupleDetail.h
GaudiTuples::createEvtCol
virtual std::unique_ptr< Tuples::TupleObj > createEvtCol(const std::string &name, NTuple::Tuple *tuple, const CLID &clid) const
create TupleObj for event tag collection
Definition: GaudiTuples.icpp:275
Tuples::NTUPLE
@ NTUPLE
Definition: TupleObj.h:92
GaudiTupleAlg.h
StatusCode
Definition: StatusCode.h:65
GaudiAlg::PrintTuple::print
static std::string print(const INTuple *tuple, const GaudiAlg::TupleID &ID)
Definition: Print.cpp:111
Gaudi::Units::m
constexpr double m
Definition: SystemOfUnits.h:108
TupleObj.h
GaudiTuples::printEvtCols
long printEvtCols() const
perform the actual printout of Event Tag Collections
Definition: GaudiTuples.icpp:306
GaudiTuples::finalize
StatusCode finalize() override
standard finalization method
Definition: GaudiTuples.icpp:77
GaudiAlg::ID::undefined
bool undefined() const noexcept
Is this ID undefined.
Definition: GaudiHistoID.h:78
GaudiTuples.h
Tuples::Tuple
A simple wrapper class over standard Gaudi NTuple::Tuple facility.
Definition: Tuple.h:126
GaudiTuples::createNTuple
virtual std::unique_ptr< Tuples::TupleObj > createNTuple(const std::string &name, NTuple::Tuple *tuple, const CLID &clid) const
create TupleObj
Definition: GaudiTuples.icpp:265
GaudiTuples::evtCol
Tuple evtCol(const std::string &title, const CLID &clid=CLID_ColumnWiseTuple) const
Access an Event Tag Collection object (book on-demand) with unique identifier.
Definition: GaudiTuples.icpp:134
CLID
unsigned int CLID
Class ID definition.
Definition: ClassID.h:18
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:203
Tuples::TupleID
GaudiAlg::ID TupleID
the actual type for N-Tuple identifier (HBOOK-style)
Definition: TupleID.h:32
Tuples::createTupleObj
auto createTupleObj(const OWNER *owner, const std::string &name, NTuple::Tuple *tuple, const CLID &clid=CLID_ColumnWiseTuple, const Tuples::Type type=Tuples::NTUPLE)
Templated helper functions allow to avoid heavy semantics of dealing with explicit type of class Tupl...
Definition: TupleDetail.h:222
IRegistry.h
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:129
Gaudi::Utils::toString
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition: ToStream.h:354
Print.h
GaudiTuples::evtColExists
bool evtColExists(const TupleID &ID) const
check the existence AND validity of the Event Tag Collection with the given ID
Definition: GaudiTuples.icpp:336
ConditionsStallTest.name
name
Definition: ConditionsStallTest.py:76
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
NTuple::Tuple
Abstract base class which allows the user to interact with the actual N tuple implementation.
Definition: NTuple.h:387
GaudiTuples::nTuple
Tuple nTuple(const std::string &title, const CLID &clid=CLID_ColumnWiseTuple) const
Access an N-Tuple object (book on-demand) with unique identifier.
Definition: GaudiTuples.icpp:101
GaudiTuples::printTuples
long printTuples() const
perform the actual printout of N-tuples
Definition: GaudiTuples.icpp:283
GaudiTuples::evtColPath
std::string evtColPath() const
get the constructed Event Tag Collection path
Definition: GaudiTuples.icpp:352
IRegistry::identifier
virtual const id_type & identifier() const =0
Full identifier (or key)
GaudiTuples::nTuplePath
std::string nTuplePath() const
get the constructed N-Tuple path
Definition: GaudiTuples.icpp:344
std::string::empty
T empty(T... args)
GaudiTuples::initialize
StatusCode initialize() override
standard initialization method
Definition: GaudiTuples.icpp:47
GaudiAlg::ID::literalID
const LiteralID & literalID() const noexcept
Returns the ID as a LiteralID.
Definition: GaudiHistoID.h:80
std::unique_ptr
STL class.
GaudiAlg::ID::idAsString
GAUDI_API LiteralID idAsString() const
Return ID as string, for both numeric and literal IDs.
Definition: GaudiHistoID.cpp:30
DataObject::registry
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:82
GaudiAlg::ID::numeric
bool numeric() const noexcept
Is this ID numeric.
Definition: GaudiHistoID.h:74
GaudiTuples::nTupleExists
bool nTupleExists(const TupleID &ID) const
check the existence AND validity of the N-Tuple with the given ID
Definition: GaudiTuples.icpp:328
GaudiAlg::ID::literal
bool literal() const noexcept
Is this ID numeric.
Definition: GaudiHistoID.h:76