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