GaudiTuples.icpp
Go to the documentation of this file.
1 // ============================================================================
2 // Include files
3 // ============================================================================
4 // Gaudi
5 // ============================================================================
6 #include "GaudiKernel/IRegistry.h"
7 #include "GaudiKernel/ToStream.h"
8 // ============================================================================
9 // GaudiAlg
10 // ============================================================================
11 #include "GaudiAlg/GaudiTuples.h"
12 #include "GaudiAlg/Tuple.h"
13 #include "GaudiAlg/TupleObj.h"
14 #include "GaudiAlg/GaudiTupleAlg.h"
15 #include "GaudiAlg/TupleDetail.h"
16 #include "GaudiAlg/Print.h"
17 #include "GaudiAlg/HbookName.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  constexpr struct releaseAndClear_t {
37  template <typename C> void operator()(C& c) const {
38  for (auto& i : c ) if (i.second) i.second->release();
39  c.clear();
40  }
41  } releaseAndClear {};
42 
43  constexpr struct ordered_t {
44  template <typename C>
45  std::map<typename C::key_type, typename C::mapped_type> operator()(const C& c) const {
46  return { std::begin(c), std::end(c) };
47  }
48  } ordered {};
49 }
50 
51 //=============================================================================
52 // Initialize ntupling
53 //=============================================================================
54 template <class PBASE>
56 #ifdef __ICC
57  i_gtInitialize
58 #else
60 #endif
61  ()
62 {
63  // initialize base class
65  if ( sc.isFailure() ) return sc;
66 
67  if ( produceNTuples() )
68  {
69  // check the existance of service
70  if ( this->ntupleSvc() == 0 )
71  { return this->Error( "INTupleSvc* points to NULL!" ); }
72  // Print ntuple path
73  this->Print( "The N-Tuple path is set to be '" + nTuplePath() + "'",
74  StatusCode(StatusCode::SUCCESS, true) , MSG::DEBUG).ignore();
75  }
76  else
77  { this->debug() << "Production of N-Tuples is switched OFF" << endmsg; }
78 
79  if ( produceEvtCols() )
80  {
81  // check the existance of service
82  if ( 0 == this->evtColSvc() )
83  { return this->Error( "INTupleSvc* points to NULL!" ); }
84  // Print EvtCol path
85  this->Print( "The EventCol path is set to be '" + evtColPath() + "'",
86  StatusCode(StatusCode::SUCCESS, true) , MSG::DEBUG ).ignore();
87  }
88  else
89  { this->debug() << "Production of Event Collections is switched OFF" << endmsg; }
90 
91  return sc;
92 }
93 
94 //=============================================================================
95 // finalize ntupling
96 //=============================================================================
97 template <class PBASE>
99 #ifdef __ICC
100  i_gtFinalize
101 #else
102  finalize
103 #endif
104  ()
105 {
106  if ( !( nTupleMapTitle () . empty () &&
107  nTupleMapID () . empty () &&
108  evtColMapTitle () . empty () &&
109  evtColMapID () . empty ()
110  ) )
111  {
112  const int nNtuples = nTupleMapID () . size () ;
113  const int nEvtCols = evtColMapID () . size ();
114  this->always()
115  << "Booked " << nNtuples << " N-Tuples and " << nEvtCols
116  << " Event Tag Collections" << endmsg ;
117  }
118 
119  if ( produceNTuples () && tuplesPrint () ) { printTuples () ; }
120  if ( produceEvtCols () && evtColsPrint () ) { printEvtCols () ; }
121 
122  // release ntuples and clear the container
123  releaseAndClear(m_nTupleMapTitle);
124 
125  // release ntuples and clear the container
126  releaseAndClear(m_nTupleMapID);
127 
128  // release ntuples and clear the container
129  releaseAndClear(m_evtColMapTitle);
130 
131  // release ntuples and clear the container
132  releaseAndClear(m_evtColMapID);
133 
134  // finalize base class
135  return PBASE::finalize();
136 }
137 
138 // ============================================================================
139 // get N-tuple object ( book on-demand ) with unique identidier
140 // ============================================================================
141 template <class PBASE>
143 ( const std::string& title ,
144  const CLID& clid ) const
145 {
146  // look up in the table
147  auto* tuple = m_nTupleMapTitle[ title ] ;
148  if ( tuple ) { return Tuple( tuple ) ; } // RETURN
149  // Create the tuple ID
150  TupleID ID;
151  if ( this->useNumericAutoIDs() || title.empty() )
152  {
153  if ( ! this->useNumericAutoIDs() )
154  {
155  this -> Warning( "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for nTuple ID",
157  }
158  // propose the tuple ID
159  ID = TupleID ( m_nTupleMapID.size() + 1 + nTupleOffSet() );
160  // adjust the proposed ID
161  while ( nTupleExists(ID) || evtColExists(ID) )
162  { ID = TupleID ( ID.numeric() + 1 ) ; }
163  }
164  else
165  {
166  // use the title to create a unique literal ID
167  ID = TupleID( this->convertTitleToID(title) );
168  // Just in case ...
169  while ( nTupleExists(ID) || evtColExists(ID) )
170  { ID = TupleID(ID.idAsString()+"_"); }
171  }
172  // return
173  return nTuple( ID , title , clid ) ;
174 }
175 // ============================================================================
176 
177 // ============================================================================
178 // Access an Event Tag Collection object (book on-demand) with unique identifier
179 // ============================================================================
180 template <class PBASE>
182 ( const std::string& title ,
183  const CLID& clid ) const
184 {
185  // look up in the table
186  Tuples::TupleObj* tuple = m_evtColMapTitle[ title ] ;
187  if ( tuple ) { return Tuple( tuple ) ; } // RETURN
188  // Create the tuple ID
189  TupleID ID;
190  if ( this->useNumericAutoIDs() || title.empty() )
191  {
192  if ( ! this->useNumericAutoIDs() )
193  {
194  this -> Warning( "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for evtCol ID",
196  }
197  // proposed the tuple ID
198  ID = TupleID ( m_evtColMapID.size() + 1 + evtColOffSet() ) ;
199  // adjust the proposed ID
200  while ( nTupleExists(ID) || evtColExists(ID) )
201  { ID = TupleID ( ID.numeric() + 1 ) ; }
202  }
203  else
204  {
205  // use the title to create a unique literal ID
206  ID = TupleID( this->convertTitleToID(title) );
207  // Just in case ...
208  while ( nTupleExists(ID) || evtColExists(ID) )
209  { ID = TupleID ( ID.idAsString()+"_" ) ; }
210  }
211  // return
212  return evtCol( ID , title , clid ) ;
213 }
214 // ============================================================================
215 
216 // ============================================================================
217 // get N-tuple object ( book on-demand ) with forced ID
218 // ============================================================================
219 template <class PBASE>
221 ( const TupleID& ID ,
222  const std::string& title1 ,
223  const CLID& clid ) const
224 {
225  // Check ID
226  if ( ID.undefined() )
227  { this->Error("Undefined NTuple ID : Title='"+title1+"'"); return Tuple(0); }
228 
229  // look up in the table
230  Tuples::TupleObj * tuple = m_nTupleMapID[ ID ] ;
231  if( tuple ) { return Tuple( tuple ) ; } // RETURN
232 
233  // convert ID to the string
234  const std::string tID = ID.idAsString() ;
235 
236  // adjust the NTuple title
237  const std::string title = title1.empty() ? ( "NTuple #" + tID ) : title1 ;
238 
239  // book new ntuple
240  if( produceNTuples() )
241  {
242  // book NTupel
243  NTuple::Tuple * tup = nullptr;
244  if ( ID.numeric() )
245  {
246  tup = this->ntupleSvc() -> book ( nTuplePath() , ID.numericID() , clid , title );
247  }
248  else if ( ID.literal() )
249  {
250  tup = this->ntupleSvc() -> book ( nTuplePath() , ID.literalID() , clid , title );
251  }
252  else { this->Error( "Undefined NTuple ID" ); }
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
259  << "' Path='" << nTuplePath() << "' TS='"
260  << tup -> registry() -> identifier() << "'" << endmsg; }
261 
262  tuple = createNTuple ( title , tup , clid ) ;
263  }
264  else
265  {
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>
281 ( const TupleID& ID ,
282  const std::string& title1 ,
283  const CLID& clid ) const
284 {
285  // Check ID
286  if ( ID.undefined() )
287  { this->Error("Undefined NTuple ID : Title='"+title1+"'"); return Tuple(0); }
288 
289  // look up in the table
290  Tuples::TupleObj* tuple = m_evtColMapID[ID] ;
291  if ( tuple ) { return Tuple( tuple ) ; } // RETURN
292 
293  // convert ID to the string
294  const std::string tID = ID.idAsString() ;
295 
296  // adjust the NTuple title
297  const std::string title = title1.empty() ? ( "EvtCol #" + tID ) : title1 ;
298 
299  // book new ntuple
300  if( produceEvtCols() )
301  {
302  // book NTuple
303  NTuple::Tuple* tup = nullptr;
304  if ( ID.numeric() )
305  {
306  tup = this->evtColSvc()->book ( evtColPath() , ID.numericID() , clid , title ) ;
307  }
308  else if ( ID.literal() )
309  {
310  tup = this->evtColSvc()->book ( evtColPath() , ID.literalID() , clid , title ) ;
311  }
312  else { this->Error( "Undefined NTuple ID" ); }
313 
314  // assertion
315  this->Assert( tup , "Could not book the EvtCol='" + title + "'" ) ;
316  // some printout
317  if( tup -> registry() && this->msgLevel(MSG::DEBUG) )
318  { this->debug() << "Booked EvtCol '" << title << "' ID=" << tID
319  << "' Path='" << evtColPath() << "' TS='"
320  << tup -> registry() -> identifier() << "'" << endmsg ; }
321 
322  tuple = createEvtCol ( title , tup , clid ) ;
323  }
324  else
325  {
326  tuple = createEvtCol ( title , (NTuple::Tuple*) 0 , clid ) ;
327  }
328  // increment the reference
329  tuple -> addRef();
330  //
331  m_evtColMapID [ ID ] = tuple ;
332  //
333  tuple -> addRef();
334  m_evtColMapTitle[ title ] = tuple ;
335  // return
336  return Tuple( tuple ) ;
337 }
338 // ============================================================================
339 // create TupleObj
340 // ============================================================================
341 template <class PBASE>
343 ( const std::string& name ,
344  NTuple::Tuple* tuple ,
345  const CLID& clid ) const
346 {
348  ( this , "Tuple '" + name + "'" , tuple , clid , Tuples::NTUPLE ) ;
349 }
350 // ============================================================================
351 
352 // ============================================================================
353 // create TupleObj for event tag collection
354 // ============================================================================
355 template <class PBASE>
357 ( const std::string& name ,
358  NTuple::Tuple* tuple ,
359  const CLID& clid ) const
360 {
362  ( this , "EvtCol '" + name + "'" , tuple , clid , Tuples::EVTCOL ) ;
363 }
364 // ============================================================================
365 // perform the actual printout of N-tuples
366 // ============================================================================
367 template <class PBASE>
369 {
370 
371  if ( nTupleMapTitle().empty() && nTupleMapID().empty() )
372  { if (this->msgLevel(MSG::DEBUG)) this->debug() << "No N-Tuples are booked" << endmsg ; }
373  else
374  { this->always() << "List of booked N-Tuples in directory "
375  << "\"" << nTuplePath() << "\"" << endmsg ; }
376 
377  for ( const auto& entry : ordered(nTupleMapID()) )
378  {
379  if ( !entry.second ) { continue ; }
380  const NTuple::Tuple* tuple = entry.second->tuple() ;
381  if ( !tuple )
382  { this->error() << " NTuple::Tuple* points to NULL" << endmsg ; continue ; }
383  this->always() << GaudiAlg::PrintTuple::print ( tuple , entry.first ) << endmsg ;
384  }
385  //
386  return this->nTupleMapID().size() ;
387 }
388 // ============================================================================
389 // perform the actual printout of Evt Tag Collections
390 // ============================================================================
391 template <class PBASE>
393 {
394  if ( evtColMapTitle().empty() && evtColMapID().empty() )
395  { this->always() << "No Event Tag Collections are booked" << endmsg ; }
396  else
397  { this->always() << "List of booked Event Tag Collections in directory "
398  << "\"" << evtColPath() << "\"" << endmsg ; }
399  for ( const auto& entry : ordered( evtColMapID() ) )
400  {
401  if ( !entry.second ) { continue ; }
402  const auto tuple = entry.second->tuple() ;
403  if ( !tuple )
404  { this->error() << " NTuple::Tuple* points to NULL" << endmsg ; continue ; }
405  this->always() << GaudiAlg::PrintTuple::print ( tuple , entry.first )
406  << " Items:"
407  << Gaudi::Utils::toString ( entry.second->items() ) << endmsg ;
408  }
409  //
410  return this->evtColMapID().size() ;
411 }
412 // ============================================================================
413 // check the existence AND validity of the N-Tuple with the given ID
414 // ============================================================================
415 template <class PBASE>
417 {
418  return m_nTupleMapID.end() != m_nTupleMapID.find ( ID ) ;
419 }
420 // ============================================================================
421 // check the existence AND validity of the Event Tag Collection with the given ID
422 // ============================================================================
423 template <class PBASE>
425 {
426  return m_evtColMapID.end() != m_evtColMapID.find ( ID ) ;
427 }
428 // ============================================================================
429 // Handle method for changes in the 'NTuplePrint' property
430 // ============================================================================
431 template <class PBASE>
433 {
434  // no action if not yet initialized
435  if ( this -> FSMState() < Gaudi::StateMachine::INITIALIZED ) { return ; }
436  if ( this -> tuplesPrint() ) { this -> printTuples () ; }
437 }
438 // ============================================================================
439 // Handle method for changes in the 'EvtColsPrint' property
440 // ============================================================================
441 template <class PBASE>
443 {
444  // no action if not yet initialized
445  if ( this -> FSMState() < Gaudi::StateMachine::INITIALIZED ) { return ; }
446  if ( this -> evtColsPrint() ) { this -> printEvtCols () ; }
447 }
448 // ============================================================================
449 // get the constructed N-Tuple path
450 // ============================================================================
451 template <class PBASE>
453 {
454  const std::string path = nTupleLUN() + "/" + nTupleTopDir() + nTupleDir();
455  return ( splitNTupleDir() ? dirHbookName( path ) : path ) ;
456 }
457 // ============================================================================
458 // get the constructed Event Tag Collection path
459 // ============================================================================
460 template <class PBASE>
462 {
463  std::string path = evtColLUN() + "/" + evtColTopDir() + evtColDir();
464  return ( splitEvtColDir() ? dirHbookName( path ) : path );
465 }
466 // ============================================================================
467 // The END
468 // ============================================================================
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:242
static std::string print(const INTuple *tuple, const GaudiAlg::TupleID &ID)
Definition: Print.cpp:168
tuple c
Definition: gaudirun.py:392
def initialize()
Definition: AnalysisTest.py:12
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 'ntupling' methods.
Definition: GaudiTuples.h:37
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition: ToStream.h:400
list path
Definition: __init__.py:15
Tuple evtCol(const std::string &title, const CLID &clid=CLID_ColumnWiseTuple) const
Access an Event Tag Collection object (book on-demand) with unique identifier.
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
A simple wrapper class over standard Gaudi NTuple::Tuple facility.
Definition: Tuple.h:116
void printEvtColHandler(Property &)
handler for "EvtColsPrint" property
NumericID numericID() const
Returns the numerical ID.
Definition: GaudiHistoID.h:72
long printTuples() const
perform the actual printout of N-tuples
A simple wrapper class over standard Gaudi NTuple::Tuple facility.
Definition: TupleObj.h:190
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
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.
const LiteralID & literalID() const
Returns the ID as a LiteralID.
Definition: GaudiHistoID.h:70
GaudiAlg::ID TupleID
the actual type for N-Tuple identifier (HBOOK-style)
Definition: TupleID.h:23
def nTuple
Retrieve (book-on-demand) 'Smart'-N-tuple object.
Definition: TupleUtils.py:66
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
Abstract base class which allows the user to interact with the actual N tuple implementation.
Definition: NTuple.h:370
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
Property base class allowing Property* collections to be "homogeneous".
Definition: Property.h:38
bool undefined() const
Is this ID undefined.
Definition: GaudiHistoID.h:68
std::string nTuplePath() const
get the constructed N-Tuple path
GAUDI_API LiteralID idAsString() const
Return ID as string, for both numeric and literal IDs.
bool literal() const
Is this ID numeric.
Definition: GaudiHistoID.h:66
void printNTupleHandler(Property &)
handler for "NTuplePrint" property
list i
Definition: ana.py:128
GAUDI_API AIDA::IHistogram1D * book(IHistogramSvc *svc, const std::string &path, const Gaudi::Histo1DDef &hist)
helper function to book 1D-histogram
Definition: HistoDef.cpp:127
ID class for Histogram and Ntuples.
Definition: GaudiHistoID.h:44
bool numeric() const
Is this ID numeric.
Definition: GaudiHistoID.h:64