The Gaudi Framework  v29r0 (ff2e7097)
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  }
161  // propose the tuple ID
162  ID = TupleID( m_nTupleMapID.size() + 1 + nTupleOffSet() );
163  // adjust the proposed ID
164  while ( nTupleExists( ID ) || evtColExists( ID ) ) {
165  ID = TupleID( ID.numeric() + 1 );
166  }
167  } else {
168  // use the title to create a unique literal ID
169  ID = TupleID( this->convertTitleToID( title ) );
170  // Just in case ...
171  while ( nTupleExists( ID ) || evtColExists( ID ) ) {
172  ID = TupleID( ID.idAsString() + "_" );
173  }
174  }
175  // return
176  return nTuple( ID, title, clid );
177 }
178 // ============================================================================
179 
180 // ============================================================================
181 // Access an Event Tag Collection object (book on-demand) with unique identifier
182 // ============================================================================
183 template <class PBASE>
184 Tuples::Tuple GaudiTuples<PBASE>::evtCol( const std::string& title, const CLID& clid ) const
185 {
186  // look up in the table
187  Tuples::TupleObj* tuple = m_evtColMapTitle[title];
188  if ( tuple ) {
189  return Tuple( tuple );
190  } // RETURN
191  // Create the tuple ID
192  TupleID ID;
193  if ( this->useNumericAutoIDs() || title.empty() ) {
194  if ( !this->useNumericAutoIDs() ) {
195  this->Warning(
196  "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for evtCol ID",
198  }
199  // proposed the tuple ID
200  ID = TupleID( m_evtColMapID.size() + 1 + evtColOffSet() );
201  // adjust the proposed ID
202  while ( nTupleExists( ID ) || evtColExists( ID ) ) {
203  ID = TupleID( ID.numeric() + 1 );
204  }
205  } else {
206  // use the title to create a unique literal ID
207  ID = TupleID( this->convertTitleToID( title ) );
208  // Just in case ...
209  while ( nTupleExists( ID ) || evtColExists( ID ) ) {
210  ID = TupleID( ID.idAsString() + "_" );
211  }
212  }
213  // return
214  return evtCol( ID, title, clid );
215 }
216 // ============================================================================
217 
218 // ============================================================================
219 // get N-tuple object ( book on-demand ) with forced ID
220 // ============================================================================
221 template <class PBASE>
222 Tuples::Tuple GaudiTuples<PBASE>::nTuple( const TupleID& ID, const std::string& title1, const CLID& clid ) const
223 {
224  // Check ID
225  if ( ID.undefined() ) {
226  this->Error( "Undefined NTuple ID : Title='" + title1 + "'" );
227  return Tuple( 0 );
228  }
229 
230  // look up in the table
231  Tuples::TupleObj* tuple = m_nTupleMapID[ID];
232  if ( tuple ) {
233  return Tuple( tuple );
234  } // RETURN
235 
236  // convert ID to the string
237  const std::string tID = ID.idAsString();
238 
239  // adjust the NTuple title
240  const std::string title = title1.empty() ? ( "NTuple #" + tID ) : title1;
241 
242  // book new ntuple
243  if ( produceNTuples() ) {
244  // book NTupel
245  NTuple::Tuple* tup = nullptr;
246  if ( ID.numeric() ) {
247  tup = this->ntupleSvc()->book( nTuplePath(), ID.numericID(), clid, title );
248  } else if ( ID.literal() ) {
249  tup = this->ntupleSvc()->book( nTuplePath(), ID.literalID(), clid, title );
250  } else {
251  this->Error( "Undefined NTuple ID" );
252  }
253 
254  // assertion
255  this->Assert( tup, "Could not book the N-Tuple='" + title + "'" );
256  // some printout
257  if ( tup->registry() && this->msgLevel( MSG::DEBUG ) ) {
258  this->debug() << "Booked NTuple '" << title << "' ID=" << tID << "' Path='" << nTuplePath() << "' TS='"
259  << tup->registry()->identifier() << "'" << endmsg;
260  }
261 
262  tuple = createNTuple( title, tup, clid );
263  } else {
264  tuple = createNTuple( title, (NTuple::Tuple*)0, clid );
265  }
266  // increment the reference
267  tuple->addRef();
268  //
269  m_nTupleMapID[ID] = tuple;
270  //
271  tuple->addRef();
272  m_nTupleMapTitle[title] = tuple;
273  // return
274  return Tuple( tuple );
275 }
276 // ============================================================================
277 template <class PBASE>
278 Tuples::Tuple GaudiTuples<PBASE>::evtCol( const TupleID& ID, const std::string& title1, const CLID& clid ) const
279 {
280  // Check ID
281  if ( ID.undefined() ) {
282  this->Error( "Undefined NTuple ID : Title='" + title1 + "'" );
283  return Tuple( 0 );
284  }
285 
286  // look up in the table
287  Tuples::TupleObj* tuple = m_evtColMapID[ID];
288  if ( tuple ) {
289  return Tuple( tuple );
290  } // RETURN
291 
292  // convert ID to the string
293  const std::string tID = ID.idAsString();
294 
295  // adjust the NTuple title
296  const std::string title = title1.empty() ? ( "EvtCol #" + tID ) : title1;
297 
298  // book new ntuple
299  if ( produceEvtCols() ) {
300  // book NTuple
301  NTuple::Tuple* tup = nullptr;
302  if ( ID.numeric() ) {
303  tup = this->evtColSvc()->book( evtColPath(), ID.numericID(), clid, title );
304  } else if ( ID.literal() ) {
305  tup = this->evtColSvc()->book( evtColPath(), ID.literalID(), clid, title );
306  } else {
307  this->Error( "Undefined NTuple ID" );
308  }
309 
310  // assertion
311  this->Assert( tup, "Could not book the EvtCol='" + title + "'" );
312  // some printout
313  if ( tup->registry() && this->msgLevel( MSG::DEBUG ) ) {
314  this->debug() << "Booked EvtCol '" << title << "' ID=" << tID << "' Path='" << evtColPath() << "' TS='"
315  << tup->registry()->identifier() << "'" << endmsg;
316  }
317 
318  tuple = createEvtCol( title, tup, clid );
319  } else {
320  tuple = createEvtCol( title, (NTuple::Tuple*)0, clid );
321  }
322  // increment the reference
323  tuple->addRef();
324  //
325  m_evtColMapID[ID] = tuple;
326  //
327  tuple->addRef();
328  m_evtColMapTitle[title] = tuple;
329  // return
330  return Tuple( tuple );
331 }
332 // ============================================================================
333 // create TupleObj
334 // ============================================================================
335 template <class PBASE>
337  const CLID& clid ) const
338 {
339  return Tuples::createTupleObj( this, "Tuple '" + name + "'", tuple, clid, Tuples::NTUPLE );
340 }
341 // ============================================================================
342 
343 // ============================================================================
344 // create TupleObj for event tag collection
345 // ============================================================================
346 template <class PBASE>
348  const CLID& clid ) const
349 {
350  return Tuples::createTupleObj( this, "EvtCol '" + name + "'", tuple, clid, Tuples::EVTCOL );
351 }
352 // ============================================================================
353 // perform the actual printout of N-tuples
354 // ============================================================================
355 template <class PBASE>
357 {
358 
359  if ( nTupleMapTitle().empty() && nTupleMapID().empty() ) {
360  if ( this->msgLevel( MSG::DEBUG ) ) this->debug() << "No N-Tuples are booked" << endmsg;
361  } else {
362  this->always() << "List of booked N-Tuples in directory "
363  << "\"" << nTuplePath() << "\"" << endmsg;
364  }
365 
366  for ( const auto& entry : ordered( nTupleMapID() ) ) {
367  if ( !entry.second ) {
368  continue;
369  }
370  const NTuple::Tuple* tuple = entry.second->tuple();
371  if ( !tuple ) {
372  this->error() << " NTuple::Tuple* points to NULL" << endmsg;
373  continue;
374  }
375  this->always() << GaudiAlg::PrintTuple::print( tuple, entry.first ) << endmsg;
376  }
377  //
378  return this->nTupleMapID().size();
379 }
380 // ============================================================================
381 // perform the actual printout of Evt Tag Collections
382 // ============================================================================
383 template <class PBASE>
385 {
386  if ( evtColMapTitle().empty() && evtColMapID().empty() ) {
387  this->always() << "No Event Tag Collections are booked" << endmsg;
388  } else {
389  this->always() << "List of booked Event Tag Collections in directory "
390  << "\"" << evtColPath() << "\"" << endmsg;
391  }
392  for ( const auto& entry : ordered( evtColMapID() ) ) {
393  if ( !entry.second ) {
394  continue;
395  }
396  const auto tuple = entry.second->tuple();
397  if ( !tuple ) {
398  this->error() << " NTuple::Tuple* points to NULL" << endmsg;
399  continue;
400  }
401  this->always() << GaudiAlg::PrintTuple::print( tuple, entry.first )
402  << " Items:" << Gaudi::Utils::toString( entry.second->items() ) << endmsg;
403  }
404  //
405  return this->evtColMapID().size();
406 }
407 // ============================================================================
408 // check the existence AND validity of the N-Tuple with the given ID
409 // ============================================================================
410 template <class PBASE>
412 {
413  return m_nTupleMapID.end() != m_nTupleMapID.find( ID );
414 }
415 // ============================================================================
416 // check the existence AND validity of the Event Tag Collection with the given ID
417 // ============================================================================
418 template <class PBASE>
420 {
421  return m_evtColMapID.end() != m_evtColMapID.find( ID );
422 }
423 // ============================================================================
424 // Handle method for changes in the 'NTuplePrint' property
425 // ============================================================================
426 template <class PBASE>
428 {
429  // no action if not yet initialized
430  if ( this->FSMState() < Gaudi::StateMachine::INITIALIZED ) {
431  return;
432  }
433  if ( this->tuplesPrint() ) {
434  this->printTuples();
435  }
436 }
437 // ============================================================================
438 // Handle method for changes in the 'EvtColsPrint' property
439 // ============================================================================
440 template <class PBASE>
442 {
443  // no action if not yet initialized
444  if ( this->FSMState() < Gaudi::StateMachine::INITIALIZED ) {
445  return;
446  }
447  if ( this->evtColsPrint() ) {
448  this->printEvtCols();
449  }
450 }
451 // ============================================================================
452 // get the constructed N-Tuple path
453 // ============================================================================
454 template <class PBASE>
456 {
457  const std::string path = nTupleLUN() + "/" + nTupleTopDir() + nTupleDir();
458  return ( splitNTupleDir() ? dirHbookName( path ) : path );
459 }
460 // ============================================================================
461 // get the constructed Event Tag Collection path
462 // ============================================================================
463 template <class PBASE>
465 {
466  std::string path = evtColLUN() + "/" + evtColTopDir() + evtColDir();
467  return ( splitEvtColDir() ? dirHbookName( path ) : path );
468 }
469 // ============================================================================
470 // The END
471 // ============================================================================
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:86
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:72
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:28
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:1950
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.