The Gaudi Framework  v36r1 (3e2fb5a8)
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 #ifdef __ICC
49  i_gtInitialize
50 #else
51  initialize
52 #endif
53  () {
54  // initialize base class
55  const StatusCode sc = PBASE::initialize();
56  if ( sc.isFailure() ) return sc;
57 
58  if ( produceNTuples() ) {
59  // check the existance of service
60  if ( this->ntupleSvc() == 0 ) { return this->Error( "INTupleSvc* points to NULL!" ); }
61  // Print ntuple path
62  this->Print( "The N-Tuple path is set to be '" + nTuplePath() + "'", StatusCode::SUCCESS, MSG::DEBUG ).ignore();
63  } else {
64  this->debug() << "Production of N-Tuples is switched OFF" << endmsg;
65  }
66 
67  if ( produceEvtCols() ) {
68  // check the existance of service
69  if ( 0 == this->evtColSvc() ) { return this->Error( "INTupleSvc* points to NULL!" ); }
70  // Print EvtCol path
71  this->Print( "The EventCol path is set to be '" + evtColPath() + "'", StatusCode::SUCCESS, MSG::DEBUG ).ignore();
72  } else {
73  this->debug() << "Production of Event Collections is switched OFF" << endmsg;
74  }
75 
76  return sc;
77 }
78 
79 //=============================================================================
80 // finalize ntupling
81 //=============================================================================
82 template <class PBASE>
84 #ifdef __ICC
85  i_gtFinalize
86 #else
87  finalize
88 #endif
89  () {
90  if ( !( m_nTupleMap.empty() && m_evtColMap.empty() ) ) {
91  const int nNtuples = m_nTupleMap.size();
92  const int nEvtCols = m_evtColMap.size();
93  this->always() << "Booked " << nNtuples << " N-Tuples and " << nEvtCols << " Event Tag Collections" << endmsg;
94  }
95 
96  if ( produceNTuples() && tuplesPrint() ) printTuples();
97  if ( produceEvtCols() && evtColsPrint() ) printEvtCols();
98 
99  // release ntuples and clear the container
100  m_nTupleMap.clear();
101 
102  // release ntuples and clear the container
103  m_evtColMap.clear();
104 
105  // finalize base class
106  return PBASE::finalize();
107 }
108 
109 // ============================================================================
110 // get N-tuple object ( book on-demand ) with unique identidier
111 // ============================================================================
112 template <class PBASE>
113 Tuples::Tuple GaudiTuples<PBASE>::nTuple( const std::string& title, const CLID& clid ) const {
114  // look up in the table
115  auto& m = nTupleByTitle();
116  auto tuple = m.find( title );
117  if ( tuple != m.end() ) return Tuple( tuple->tuple ); // RETURN
118  // Create the tuple ID
119  TupleID ID;
120  if ( this->useNumericAutoIDs() || title.empty() ) {
121  if ( !this->useNumericAutoIDs() ) {
122  this->Warning(
123  "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for nTuple ID",
125  .ignore();
126  }
127  // propose the tuple ID
128  ID = TupleID( m_nTupleMap.size() + 1 + nTupleOffSet() );
129  // adjust the proposed ID
130  while ( nTupleExists( ID ) || evtColExists( ID ) ) { ID = TupleID( ID.numeric() + 1 ); }
131  } else {
132  // use the title to create a unique literal ID
133  ID = TupleID( this->convertTitleToID( title ) );
134  // Just in case ...
135  while ( nTupleExists( ID ) || evtColExists( ID ) ) { ID = TupleID( ID.idAsString() + "_" ); }
136  }
137  // return
138  return nTuple( ID, title, clid );
139 }
140 // ============================================================================
141 
142 // ============================================================================
143 // Access an Event Tag Collection object (book on-demand) with unique identifier
144 // ============================================================================
145 template <class PBASE>
146 Tuples::Tuple GaudiTuples<PBASE>::evtCol( const std::string& title, const CLID& clid ) const {
147  // look up in the table
148  auto& m = evtColByTitle();
149  auto tuple = m.find( title );
150  if ( tuple != m.end() ) return Tuple( tuple->tuple ); // RETURN
151  // Create the tuple ID
152  TupleID ID;
153  if ( this->useNumericAutoIDs() || title.empty() ) {
154  if ( !this->useNumericAutoIDs() ) {
155  this->Warning(
156  "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for evtCol ID",
158  .ignore();
159  }
160  // proposed the tuple ID
161  ID = TupleID( m_evtColMap.size() + 1 + evtColOffSet() );
162  // adjust the proposed ID
163  while ( nTupleExists( ID ) || evtColExists( ID ) ) { ID = TupleID( ID.numeric() + 1 ); }
164  } else {
165  // use the title to create a unique literal ID
166  ID = TupleID( this->convertTitleToID( title ) );
167  // Just in case ...
168  while ( nTupleExists( ID ) || evtColExists( ID ) ) { ID = TupleID( ID.idAsString() + "_" ); }
169  }
170  // return
171  return evtCol( ID, title, clid );
172 }
173 // ============================================================================
174 
175 // ============================================================================
176 // get N-tuple object ( book on-demand ) with forced ID
177 // ============================================================================
178 template <class PBASE>
179 Tuples::Tuple GaudiTuples<PBASE>::nTuple( const TupleID& ID, const std::string& title1, const CLID& clid ) const {
180  // Check ID
181  if ( ID.undefined() ) {
182  this->Error( "Undefined NTuple ID : Title='" + title1 + "'" ).ignore();
183  return Tuple( 0 );
184  }
185 
186  // look up in the table
187  auto& m = nTupleByID();
188  auto tuple = m.find( ID );
189  if ( tuple != m.end() ) return Tuple( tuple->tuple ); // RETURN
190 
191  // convert ID to the string
192  const std::string tID = ID.idAsString();
193 
194  // adjust the NTuple title
195  const std::string title = title1.empty() ? ( "NTuple #" + tID ) : title1;
196 
197  // book new ntuple
198  if ( !produceNTuples() ) {
199  auto r = m_nTupleMap.insert( nTupleMapItem{title, ID, createNTuple( title, nullptr, clid )} );
200  if ( !r.second ) this->Error( "Failure to createNTuple" ).ignore();
201  return Tuple( r.first->tuple );
202  }
203  // book NTupel
204  NTuple::Tuple* tup = nullptr;
205  if ( ID.numeric() ) {
206  tup = this->ntupleSvc()->book( nTuplePath(), ID.numericID(), clid, title );
207  } else if ( ID.literal() ) {
208  tup = this->ntupleSvc()->book( nTuplePath(), ID.literalID(), clid, title );
209  } else {
210  this->Error( "Undefined NTuple ID" ).ignore();
211  }
212 
213  // assertion
214  this->Assert( tup, "Could not book the N-Tuple='" + title + "'" );
215  // some printout
216  if ( tup->registry() && this->msgLevel( MSG::DEBUG ) ) {
217  this->debug() << "Booked NTuple '" << title << "' ID=" << tID << "' Path='" << nTuplePath() << "' TS='"
218  << tup->registry()->identifier() << "'" << endmsg;
219  }
220 
221  auto r = m_nTupleMap.insert( nTupleMapItem{title, ID, createNTuple( title, tup, clid )} );
222  if ( !r.second ) this->Error( "Failure to createNTuple" ).ignore();
223  return Tuple( r.first->tuple );
224  //
225 }
226 // ============================================================================
227 template <class PBASE>
228 Tuples::Tuple GaudiTuples<PBASE>::evtCol( const TupleID& ID, const std::string& title1, const CLID& clid ) const {
229  // Check ID
230  if ( ID.undefined() ) {
231  this->Error( "Undefined NTuple ID : Title='" + title1 + "'" ).ignore();
232  return Tuple( 0 );
233  }
234 
235  // look up in the table
236  auto& tuple = evtColByID();
237  auto i = tuple.find( ID );
238  if ( i != tuple.end() ) return Tuple( i->tuple ); // RETURN
239 
240  // convert ID to the string
241  const std::string tID = ID.idAsString();
242 
243  // adjust the NTuple title
244  const std::string title = title1.empty() ? ( "EvtCol #" + tID ) : title1;
245 
246  // book new ntuple
247  if ( !produceEvtCols() ) {
248  auto r = m_evtColMap.insert( nTupleMapItem{title, ID, createEvtCol( title, nullptr, clid )} );
249  if ( !r.second ) this->Error( "Failure to createEvtCol" ).ignore();
250  return Tuple( r.first->tuple );
251  }
252  // book NTuple
253  NTuple::Tuple* tup = nullptr;
254  if ( ID.numeric() ) {
255  tup = this->evtColSvc()->book( evtColPath(), ID.numericID(), clid, title );
256  } else if ( ID.literal() ) {
257  tup = this->evtColSvc()->book( evtColPath(), ID.literalID(), clid, title );
258  } else {
259  this->Error( "Undefined NTuple ID" ).ignore();
260  }
261 
262  // assertion
263  this->Assert( tup, "Could not book the EvtCol='" + title + "'" );
264  // some printout
265  if ( tup->registry() && this->msgLevel( MSG::DEBUG ) ) {
266  this->debug() << "Booked EvtCol '" << title << "' ID=" << tID << "' Path='" << evtColPath() << "' TS='"
267  << tup->registry()->identifier() << "'" << endmsg;
268  }
269  auto r = m_evtColMap.insert( nTupleMapItem{title, ID, createEvtCol( title, tup, clid )} );
270  if ( !r.second ) this->Error( "Failure to createEvtCol" ).ignore();
271  return Tuple( r.first->tuple );
272 }
273 // ============================================================================
274 // create TupleObj
275 // ============================================================================
276 template <class PBASE>
278  const CLID& clid ) const {
279  return Tuples::createTupleObj( this, "Tuple '" + name + "'", tuple, clid, Tuples::NTUPLE );
280 }
281 // ============================================================================
282 
283 // ============================================================================
284 // create TupleObj for event tag collection
285 // ============================================================================
286 template <class PBASE>
288  const CLID& clid ) const {
289  return Tuples::createTupleObj( this, "EvtCol '" + name + "'", tuple, clid, Tuples::EVTCOL );
290 }
291 // ============================================================================
292 // perform the actual printout of N-tuples
293 // ============================================================================
294 template <class PBASE>
296 
297  if ( m_nTupleMap.empty() ) {
298  if ( this->msgLevel( MSG::DEBUG ) ) this->debug() << "No N-Tuples are booked" << endmsg;
299  } else {
300  this->always() << "List of booked N-Tuples in directory "
301  << "\"" << nTuplePath() << "\"" << endmsg;
302  }
303 
304  for ( const auto& entry : this->nTupleOrdered() ) {
305  if ( !entry.tuple->tuple() ) {
306  this->error() << " NTuple::Tuple* points to NULL" << endmsg;
307  continue;
308  }
309  this->always() << GaudiAlg::PrintTuple::print( entry.tuple->tuple(), entry.id ) << endmsg;
310  }
311  //
312  return this->m_nTupleMap.size();
313 }
314 // ============================================================================
315 // perform the actual printout of Evt Tag Collections
316 // ============================================================================
317 template <class PBASE>
319  if ( m_evtColMap.empty() ) {
320  this->always() << "No Event Tag Collections are booked" << endmsg;
321  } else {
322  this->always() << "List of booked Event Tag Collections in directory "
323  << "\"" << evtColPath() << "\"" << endmsg;
324  }
325  for ( const auto& entry : this->evtColOrdered() ) {
326  if ( !entry.tuple->tuple() ) {
327  this->error() << " NTuple::Tuple* points to NULL" << endmsg;
328  continue;
329  }
330  this->always() << GaudiAlg::PrintTuple::print( entry.tuple->tuple(), entry.id )
331  << " Items:" << Gaudi::Utils::toString( entry.tuple->items() ) << endmsg;
332  }
333  //
334  return this->m_evtColMap.size();
335 }
336 // ============================================================================
337 // check the existence AND validity of the N-Tuple with the given ID
338 // ============================================================================
339 template <class PBASE>
340 bool GaudiTuples<PBASE>::nTupleExists( const TupleID& ID ) const {
341  auto& m = nTupleByID();
342  return m.find( ID ) != m.end();
343 }
344 // ============================================================================
345 // check the existence AND validity of the Event Tag Collection with the given ID
346 // ============================================================================
347 template <class PBASE>
348 bool GaudiTuples<PBASE>::evtColExists( const TupleID& ID ) const {
349  auto& m = evtColByID();
350  return m.find( ID ) != m.end();
351 }
352 // ============================================================================
353 // get the constructed N-Tuple path
354 // ============================================================================
355 template <class PBASE>
357  const std::string path = nTupleLUN() + "/" + nTupleTopDir() + nTupleDir();
358  return splitNTupleDir() ? dirHbookName( path ) : path;
359 }
360 // ============================================================================
361 // get the constructed Event Tag Collection path
362 // ============================================================================
363 template <class PBASE>
365  std::string path = evtColLUN() + "/" + evtColTopDir() + evtColDir();
366  return splitEvtColDir() ? dirHbookName( path ) : path;
367 }
368 // ============================================================================
369 // The END
370 // ============================================================================
MSG::DEBUG
@ DEBUG
Definition: IMessageSvc.h:25
Tuple.h
std::string
STL class.
GaudiAlg::ID
Definition: GaudiHistoID.h:53
GaudiPython.GaudiAlgs.Tuple
Tuple
Definition: GaudiAlgs.py:1175
Tuples::EVTCOL
@ EVTCOL
Definition: TupleObj.h:93
GaudiTuples::nTupleMapItem
Definition: GaudiTuples.h:356
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:287
Tuples::NTUPLE
@ NTUPLE
Definition: TupleObj.h:92
TimingHistograms.name
name
Definition: TimingHistograms.py:23
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
HistoDumpEx.r
r
Definition: HistoDumpEx.py:20
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:318
GaudiPython.HistoUtils.path
path
Definition: HistoUtils.py:943
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:277
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:146
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
GaudiPython.TupleUtils.nTuple
def nTuple(dirpath, ID, ID2=None, topdir=None, LUN='FILE1')
Definition: TupleUtils.py:84
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:142
Gaudi::Utils::toString
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition: ToStream.h:353
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:348
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:113
GaudiTuples::printTuples
long printTuples() const
perform the actual printout of N-tuples
Definition: GaudiTuples.icpp:295
GaudiTuples::evtColPath
std::string evtColPath() const
get the constructed Event Tag Collection path
Definition: GaudiTuples.icpp:364
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:356
std::string::empty
T empty(T... args)
GaudiTuples
Definition: GaudiTuples.h:53
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:340
GaudiAlg::ID::literal
bool literal() const noexcept
Is this ID numeric.
Definition: GaudiHistoID.h:76