The Gaudi Framework  v30r0 (c919700c)
GaudiTuples.icpp
Go to the documentation of this file.
1 // ============================================================================
2 // Include files
3 // ============================================================================
4 // Gaudi
5 // ============================================================================
7 #include "GaudiKernel/ToStream.h"
8 // ============================================================================
9 // GaudiAlg
10 // ============================================================================
11 #include "GaudiAlg/GaudiTupleAlg.h"
12 #include "GaudiAlg/GaudiTuples.h"
13 #include "GaudiAlg/HbookName.h"
14 #include "GaudiAlg/Print.h"
15 #include "GaudiAlg/Tuple.h"
16 #include "GaudiAlg/TupleDetail.h"
17 #include "GaudiAlg/TupleObj.h"
18 // ============================================================================
19 /* @file GaudiTuples.cpp
20  *
21  * Implementation file for class : GaudiTuples
22  *
23  * @author Chris Jones Christopher.Rob.Jones@cern.ch
24  * @author Vanya BELYAEV Ivan.Belyaev@itep.ru
25  * @date 2005-08-08
26  */
27 // ============================================================================
28 // Disable warning on windows
29 #ifdef _WIN32
30 #pragma warning( disable : 4661 ) // incomplete explicit templates
31 #endif
32 //=============================================================================
33 // small helper to simplify the code...
34 
35 namespace
36 {
37  constexpr struct releaseAndClear_t {
38  template <typename C>
39  void operator()( C& c ) const
40  {
41  for ( auto& i : c )
42  if ( i.second ) i.second->release();
43  c.clear();
44  }
45  } releaseAndClear{};
46 
47  constexpr struct ordered_t {
48  template <typename C>
50  {
51  return {std::begin( c ), std::end( c )};
52  }
53  } ordered{};
54 }
55 
56 //=============================================================================
57 // Initialize ntupling
58 //=============================================================================
59 template <class PBASE>
61 #ifdef __ICC
62  i_gtInitialize
63 #else
64  initialize
65 #endif
66  ()
67 {
68  // initialize base class
69  const StatusCode sc = PBASE::initialize();
70  if ( sc.isFailure() ) return sc;
71 
72  if ( produceNTuples() ) {
73  // check the existance of service
74  if ( this->ntupleSvc() == 0 ) {
75  return this->Error( "INTupleSvc* points to NULL!" );
76  }
77  // Print ntuple path
78  this->Print( "The N-Tuple path is set to be '" + nTuplePath() + "'", StatusCode( StatusCode::SUCCESS, true ),
79  MSG::DEBUG )
80  .ignore();
81  } else {
82  this->debug() << "Production of N-Tuples is switched OFF" << endmsg;
83  }
84 
85  if ( produceEvtCols() ) {
86  // check the existance of service
87  if ( 0 == this->evtColSvc() ) {
88  return this->Error( "INTupleSvc* points to NULL!" );
89  }
90  // Print EvtCol path
91  this->Print( "The EventCol path is set to be '" + evtColPath() + "'", StatusCode( StatusCode::SUCCESS, true ),
92  MSG::DEBUG )
93  .ignore();
94  } else {
95  this->debug() << "Production of Event Collections is switched OFF" << endmsg;
96  }
97 
98  return sc;
99 }
100 
101 //=============================================================================
102 // finalize ntupling
103 //=============================================================================
104 template <class PBASE>
106 #ifdef __ICC
107  i_gtFinalize
108 #else
109  finalize
110 #endif
111  ()
112 {
113  if ( !( nTupleMapTitle().empty() && nTupleMapID().empty() && evtColMapTitle().empty() && evtColMapID().empty() ) ) {
114  const int nNtuples = nTupleMapID().size();
115  const int nEvtCols = evtColMapID().size();
116  this->always() << "Booked " << nNtuples << " N-Tuples and " << nEvtCols << " Event Tag Collections" << endmsg;
117  }
118 
119  if ( produceNTuples() && tuplesPrint() ) {
120  printTuples();
121  }
122  if ( produceEvtCols() && evtColsPrint() ) {
123  printEvtCols();
124  }
125 
126  // release ntuples and clear the container
127  releaseAndClear( m_nTupleMapTitle );
128 
129  // release ntuples and clear the container
130  releaseAndClear( m_nTupleMapID );
131 
132  // release ntuples and clear the container
133  releaseAndClear( m_evtColMapTitle );
134 
135  // release ntuples and clear the container
136  releaseAndClear( m_evtColMapID );
137 
138  // finalize base class
139  return PBASE::finalize();
140 }
141 
142 // ============================================================================
143 // get N-tuple object ( book on-demand ) with unique identidier
144 // ============================================================================
145 template <class PBASE>
146 Tuples::Tuple GaudiTuples<PBASE>::nTuple( const std::string& title, const CLID& clid ) const
147 {
148  // look up in the table
149  auto* tuple = m_nTupleMapTitle[title];
150  if ( tuple ) {
151  return Tuple( tuple );
152  } // RETURN
153  // Create the tuple ID
154  TupleID ID;
155  if ( this->useNumericAutoIDs() || title.empty() ) {
156  if ( !this->useNumericAutoIDs() ) {
157  this->Warning(
158  "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for nTuple ID",
160  .ignore();
161  }
162  // propose the tuple ID
163  ID = TupleID( m_nTupleMapID.size() + 1 + nTupleOffSet() );
164  // adjust the proposed ID
165  while ( nTupleExists( ID ) || evtColExists( ID ) ) {
166  ID = TupleID( ID.numeric() + 1 );
167  }
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 ) ) {
173  ID = TupleID( ID.idAsString() + "_" );
174  }
175  }
176  // return
177  return nTuple( ID, title, clid );
178 }
179 // ============================================================================
180 
181 // ============================================================================
182 // Access an Event Tag Collection object (book on-demand) with unique identifier
183 // ============================================================================
184 template <class PBASE>
185 Tuples::Tuple GaudiTuples<PBASE>::evtCol( const std::string& title, const CLID& clid ) const
186 {
187  // look up in the table
188  Tuples::TupleObj* tuple = m_evtColMapTitle[title];
189  if ( tuple ) {
190  return Tuple( tuple );
191  } // RETURN
192  // Create the tuple ID
193  TupleID ID;
194  if ( this->useNumericAutoIDs() || title.empty() ) {
195  if ( !this->useNumericAutoIDs() ) {
196  this->Warning(
197  "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for evtCol ID",
199  .ignore();
200  }
201  // proposed the tuple ID
202  ID = TupleID( m_evtColMapID.size() + 1 + evtColOffSet() );
203  // adjust the proposed ID
204  while ( nTupleExists( ID ) || evtColExists( ID ) ) {
205  ID = TupleID( ID.numeric() + 1 );
206  }
207  } else {
208  // use the title to create a unique literal ID
209  ID = TupleID( this->convertTitleToID( title ) );
210  // Just in case ...
211  while ( nTupleExists( ID ) || evtColExists( ID ) ) {
212  ID = TupleID( ID.idAsString() + "_" );
213  }
214  }
215  // return
216  return evtCol( ID, title, clid );
217 }
218 // ============================================================================
219 
220 // ============================================================================
221 // get N-tuple object ( book on-demand ) with forced ID
222 // ============================================================================
223 template <class PBASE>
224 Tuples::Tuple GaudiTuples<PBASE>::nTuple( const TupleID& ID, const std::string& title1, const CLID& clid ) const
225 {
226  // Check ID
227  if ( ID.undefined() ) {
228  this->Error( "Undefined NTuple ID : Title='" + title1 + "'" ).ignore();
229  return Tuple( 0 );
230  }
231 
232  // look up in the table
233  Tuples::TupleObj* tuple = m_nTupleMapID[ID];
234  if ( tuple ) {
235  return Tuple( tuple );
236  } // RETURN
237 
238  // convert ID to the string
239  const std::string tID = ID.idAsString();
240 
241  // adjust the NTuple title
242  const std::string title = title1.empty() ? ( "NTuple #" + tID ) : title1;
243 
244  // book new ntuple
245  if ( produceNTuples() ) {
246  // book NTupel
247  NTuple::Tuple* tup = nullptr;
248  if ( ID.numeric() ) {
249  tup = this->ntupleSvc()->book( nTuplePath(), ID.numericID(), clid, title );
250  } else if ( ID.literal() ) {
251  tup = this->ntupleSvc()->book( nTuplePath(), ID.literalID(), clid, title );
252  } else {
253  this->Error( "Undefined NTuple ID" ).ignore();
254  }
255 
256  // assertion
257  this->Assert( tup, "Could not book the N-Tuple='" + title + "'" );
258  // some printout
259  if ( tup->registry() && this->msgLevel( MSG::DEBUG ) ) {
260  this->debug() << "Booked NTuple '" << title << "' ID=" << tID << "' Path='" << nTuplePath() << "' TS='"
261  << tup->registry()->identifier() << "'" << endmsg;
262  }
263 
264  tuple = createNTuple( title, tup, clid );
265  } else {
266  tuple = createNTuple( title, (NTuple::Tuple*)0, clid );
267  }
268  // increment the reference
269  tuple->addRef();
270  //
271  m_nTupleMapID[ID] = tuple;
272  //
273  tuple->addRef();
274  m_nTupleMapTitle[title] = tuple;
275  // return
276  return Tuple( tuple );
277 }
278 // ============================================================================
279 template <class PBASE>
280 Tuples::Tuple GaudiTuples<PBASE>::evtCol( const TupleID& ID, const std::string& title1, const CLID& clid ) const
281 {
282  // Check ID
283  if ( ID.undefined() ) {
284  this->Error( "Undefined NTuple ID : Title='" + title1 + "'" ).ignore();
285  return Tuple( 0 );
286  }
287 
288  // look up in the table
289  Tuples::TupleObj* tuple = m_evtColMapID[ID];
290  if ( tuple ) {
291  return Tuple( tuple );
292  } // RETURN
293 
294  // convert ID to the string
295  const std::string tID = ID.idAsString();
296 
297  // adjust the NTuple title
298  const std::string title = title1.empty() ? ( "EvtCol #" + tID ) : title1;
299 
300  // book new ntuple
301  if ( produceEvtCols() ) {
302  // book NTuple
303  NTuple::Tuple* tup = nullptr;
304  if ( ID.numeric() ) {
305  tup = this->evtColSvc()->book( evtColPath(), ID.numericID(), clid, title );
306  } else if ( ID.literal() ) {
307  tup = this->evtColSvc()->book( evtColPath(), ID.literalID(), clid, title );
308  } else {
309  this->Error( "Undefined NTuple ID" ).ignore();
310  }
311 
312  // assertion
313  this->Assert( tup, "Could not book the EvtCol='" + title + "'" );
314  // some printout
315  if ( tup->registry() && this->msgLevel( MSG::DEBUG ) ) {
316  this->debug() << "Booked EvtCol '" << title << "' ID=" << tID << "' Path='" << evtColPath() << "' TS='"
317  << tup->registry()->identifier() << "'" << endmsg;
318  }
319 
320  tuple = createEvtCol( title, tup, clid );
321  } else {
322  tuple = createEvtCol( title, (NTuple::Tuple*)0, clid );
323  }
324  // increment the reference
325  tuple->addRef();
326  //
327  m_evtColMapID[ID] = tuple;
328  //
329  tuple->addRef();
330  m_evtColMapTitle[title] = tuple;
331  // return
332  return Tuple( tuple );
333 }
334 // ============================================================================
335 // create TupleObj
336 // ============================================================================
337 template <class PBASE>
339  const CLID& clid ) const
340 {
341  return Tuples::createTupleObj( this, "Tuple '" + name + "'", tuple, clid, Tuples::NTUPLE );
342 }
343 // ============================================================================
344 
345 // ============================================================================
346 // create TupleObj for event tag collection
347 // ============================================================================
348 template <class PBASE>
350  const CLID& clid ) const
351 {
352  return Tuples::createTupleObj( this, "EvtCol '" + name + "'", tuple, clid, Tuples::EVTCOL );
353 }
354 // ============================================================================
355 // perform the actual printout of N-tuples
356 // ============================================================================
357 template <class PBASE>
359 {
360 
361  if ( nTupleMapTitle().empty() && nTupleMapID().empty() ) {
362  if ( this->msgLevel( MSG::DEBUG ) ) this->debug() << "No N-Tuples are booked" << endmsg;
363  } else {
364  this->always() << "List of booked N-Tuples in directory "
365  << "\"" << nTuplePath() << "\"" << endmsg;
366  }
367 
368  for ( const auto& entry : ordered( nTupleMapID() ) ) {
369  if ( !entry.second ) {
370  continue;
371  }
372  const NTuple::Tuple* tuple = entry.second->tuple();
373  if ( !tuple ) {
374  this->error() << " NTuple::Tuple* points to NULL" << endmsg;
375  continue;
376  }
377  this->always() << GaudiAlg::PrintTuple::print( tuple, entry.first ) << endmsg;
378  }
379  //
380  return this->nTupleMapID().size();
381 }
382 // ============================================================================
383 // perform the actual printout of Evt Tag Collections
384 // ============================================================================
385 template <class PBASE>
387 {
388  if ( evtColMapTitle().empty() && evtColMapID().empty() ) {
389  this->always() << "No Event Tag Collections are booked" << endmsg;
390  } else {
391  this->always() << "List of booked Event Tag Collections in directory "
392  << "\"" << evtColPath() << "\"" << endmsg;
393  }
394  for ( const auto& entry : ordered( evtColMapID() ) ) {
395  if ( !entry.second ) {
396  continue;
397  }
398  const auto tuple = entry.second->tuple();
399  if ( !tuple ) {
400  this->error() << " NTuple::Tuple* points to NULL" << endmsg;
401  continue;
402  }
403  this->always() << GaudiAlg::PrintTuple::print( tuple, entry.first )
404  << " Items:" << Gaudi::Utils::toString( entry.second->items() ) << endmsg;
405  }
406  //
407  return this->evtColMapID().size();
408 }
409 // ============================================================================
410 // check the existence AND validity of the N-Tuple with the given ID
411 // ============================================================================
412 template <class PBASE>
414 {
415  return m_nTupleMapID.end() != m_nTupleMapID.find( ID );
416 }
417 // ============================================================================
418 // check the existence AND validity of the Event Tag Collection with the given ID
419 // ============================================================================
420 template <class PBASE>
422 {
423  return m_evtColMapID.end() != m_evtColMapID.find( ID );
424 }
425 // ============================================================================
426 // Handle method for changes in the 'NTuplePrint' property
427 // ============================================================================
428 template <class PBASE>
430 {
431  // no action if not yet initialized
432  if ( this->FSMState() < Gaudi::StateMachine::INITIALIZED ) {
433  return;
434  }
435  if ( this->tuplesPrint() ) {
436  this->printTuples();
437  }
438 }
439 // ============================================================================
440 // Handle method for changes in the 'EvtColsPrint' property
441 // ============================================================================
442 template <class PBASE>
444 {
445  // no action if not yet initialized
446  if ( this->FSMState() < Gaudi::StateMachine::INITIALIZED ) {
447  return;
448  }
449  if ( this->evtColsPrint() ) {
450  this->printEvtCols();
451  }
452 }
453 // ============================================================================
454 // get the constructed N-Tuple path
455 // ============================================================================
456 template <class PBASE>
458 {
459  const std::string path = nTupleLUN() + "/" + nTupleTopDir() + nTupleDir();
460  return ( splitNTupleDir() ? dirHbookName( path ) : path );
461 }
462 // ============================================================================
463 // get the constructed Event Tag Collection path
464 // ============================================================================
465 template <class PBASE>
467 {
468  std::string path = evtColLUN() + "/" + evtColTopDir() + evtColDir();
469  return ( splitEvtColDir() ? dirHbookName( path ) : path );
470 }
471 // ============================================================================
472 // The END
473 // ============================================================================
static std::string print(const INTuple *tuple, const GaudiAlg::TupleID &ID)
Definition: Print.cpp:151
T empty(T...args)
bool nTupleExists(const TupleID &ID) const
check the existence AND validity of the N-Tuple with the given ID
virtual 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 &#39;ntupling&#39; methods.
Definition: GaudiTuples.h:39
Header file for class TupleObj.
NumericID numericID() const noexcept
Returns the numerical ID.
Definition: GaudiHistoID.h:74
TupleObj * 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:231
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition: ToStream.h:346
void printNTupleHandler(Gaudi::Details::PropertyBase &)
handler for "NTuplePrint" property
Tuple evtCol(const std::string &title, const CLID &clid=CLID_ColumnWiseTuple) const
Access an Event Tag Collection object (book on-demand) with unique identifier.
T end(T...args)
few useful function to construct names of Hbook histograms and directories functions are imported fro...
STL class.
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:61
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:73
STL class.
void printEvtColHandler(Gaudi::Details::PropertyBase &)
handler for "EvtColsPrint" property
A simple wrapper class over standard Gaudi NTuple::Tuple facility.
Definition: Tuple.h:117
long printTuples() const
perform the actual printout of N-tuples
virtual const id_type & identifier() const =0
Full identifier (or key)
A simple wrapper class over standard Gaudi NTuple::Tuple facility.
Definition: TupleObj.h:199
long printEvtCols() const
perform the actual printout of Event Tag Collections
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
Tuple nTuple(const std::string &title, const CLID &clid=CLID_ColumnWiseTuple) const
Access an N-Tuple object (book on-demand) with unique identifier.
bool literal() const noexcept
Is this ID numeric.
Definition: GaudiHistoID.h:68
GaudiAlg::ID TupleID
the actual type for N-Tuple identifier (HBOOK-style)
Definition: TupleID.h:23
collection of useful utilities to print certain objects (currently used for implementation in class G...
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
Definition: Property.h:32
unsigned int CLID
Class ID definition.
Definition: ClassID.h:8
bool evtColExists(const TupleID &ID) const
check the existence AND validity of the Event Tag Collection with the given ID
unsigned long addRef()
add the reference to TupleObj
Definition: TupleObj.h:1964
Collection of few &#39;technical&#39; methods for instantiation of tuples.
Abstract base class which allows the user to interact with the actual N tuple implementation.
Definition: NTuple.h:412
virtual 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
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
T begin(T...args)
std::string nTuplePath() const
get the constructed N-Tuple path
const LiteralID & literalID() const noexcept
Returns the ID as a LiteralID.
Definition: GaudiHistoID.h:72
GAUDI_API LiteralID idAsString() const
Return ID as string, for both numeric and literal IDs.
bool numeric() const noexcept
Is this ID numeric.
Definition: GaudiHistoID.h:66
implementation of various functions for streaming.
bool undefined() const noexcept
Is this ID undefined.
Definition: GaudiHistoID.h:70
ID class for Histogram and Ntuples.
Definition: GaudiHistoID.h:44
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
Header file for class : Tuple.