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/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 // ============================================================================
static std::string print(const INTuple *tuple, const GaudiAlg::TupleID &ID)
Definition: Print.cpp:168
T empty(T...args)
def initialize()
Definition: AnalysisTest.py:12
GAUDI_API AIDA::IHistogram1D * book(IHistogramSvc *svc, const std::string &path, const Gaudi::Histo1DDef &hist)
helper function to book 1D-histogram
Definition: HistoDef.cpp:124
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
Header file for class TupleObj.
tuple c
Definition: gaudirun.py:391
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
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition: ToStream.h:371
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
STL class.
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
def nTuple
Retrieve (book-on-demand) 'Smart'-N-tuple object.
Definition: TupleUtils.py:65
long printTuples() const
perform the actual printout of N-tuples
A simple wrapper class over standard Gaudi NTuple::Tuple facility.
Definition: TupleObj.h:196
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
collection of useful utilities to print certain objects (currently used for implementation in class G...
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
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:370
GAUDI_API std::string path(const AIDA::IBaseHistogram *aida)
get the path in THS for AIDA histogram
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
T begin(T...args)
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
implementation of various functions for streaming.
list i
Definition: ana.py:128
ID class for Histogram and Ntuples.
Definition: GaudiHistoID.h:44
bool numeric() const
Is this ID numeric.
Definition: GaudiHistoID.h:64
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
Header file for class : Tuple.