The Gaudi Framework  v30r3 (a5ef0a68)
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 //=============================================================================
34 // Initialize ntupling
35 //=============================================================================
36 template <class PBASE>
38 #ifdef __ICC
39  i_gtInitialize
40 #else
41  initialize
42 #endif
43  ()
44 {
45  // initialize base class
46  const StatusCode sc = PBASE::initialize();
47  if ( sc.isFailure() ) return sc;
48 
49  if ( produceNTuples() ) {
50  // check the existance of service
51  if ( this->ntupleSvc() == 0 ) {
52  return this->Error( "INTupleSvc* points to NULL!" );
53  }
54  // Print ntuple path
55  this->Print( "The N-Tuple path is set to be '" + nTuplePath() + "'", StatusCode( StatusCode::SUCCESS, true ),
56  MSG::DEBUG )
57  .ignore();
58  } else {
59  this->debug() << "Production of N-Tuples is switched OFF" << endmsg;
60  }
61 
62  if ( produceEvtCols() ) {
63  // check the existance of service
64  if ( 0 == this->evtColSvc() ) {
65  return this->Error( "INTupleSvc* points to NULL!" );
66  }
67  // Print EvtCol path
68  this->Print( "The EventCol path is set to be '" + evtColPath() + "'", StatusCode( StatusCode::SUCCESS, true ),
69  MSG::DEBUG )
70  .ignore();
71  } else {
72  this->debug() << "Production of Event Collections is switched OFF" << endmsg;
73  }
74 
75  return sc;
76 }
77 
78 //=============================================================================
79 // finalize ntupling
80 //=============================================================================
81 template <class PBASE>
83 #ifdef __ICC
84  i_gtFinalize
85 #else
86  finalize
87 #endif
88  ()
89 {
90  if ( !( m_nTupleMap.empty() && m_evtColMap.empty() ) ) {
91  const int nNtuples = m_nTupleMap.size();
92  const int nEvtCols = m_evtColMap.size();
93  this->always() << "Booked " << nNtuples << " N-Tuples and " << nEvtCols << " Event Tag Collections" << endmsg;
94  }
95 
96  if ( produceNTuples() && tuplesPrint() ) printTuples();
97  if ( produceEvtCols() && evtColsPrint() ) printEvtCols();
98 
99  // release ntuples and clear the container
100  m_nTupleMap.clear();
101 
102  // release ntuples and clear the container
103  m_evtColMap.clear();
104 
105  // finalize base class
106  return PBASE::finalize();
107 }
108 
109 // ============================================================================
110 // get N-tuple object ( book on-demand ) with unique identidier
111 // ============================================================================
112 template <class PBASE>
113 Tuples::Tuple GaudiTuples<PBASE>::nTuple( const std::string& title, const CLID& clid ) const
114 {
115  // look up in the table
116  auto& m = nTupleByTitle();
117  auto tuple = m.find( title );
118  if ( tuple != m.end() ) return Tuple( tuple->tuple ); // RETURN
119  // Create the tuple ID
120  TupleID ID;
121  if ( this->useNumericAutoIDs() || title.empty() ) {
122  if ( !this->useNumericAutoIDs() ) {
123  this->Warning(
124  "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for nTuple ID",
126  .ignore();
127  }
128  // propose the tuple ID
129  ID = TupleID( m_nTupleMap.size() + 1 + nTupleOffSet() );
130  // adjust the proposed ID
131  while ( nTupleExists( ID ) || evtColExists( ID ) ) {
132  ID = TupleID( ID.numeric() + 1 );
133  }
134  } else {
135  // use the title to create a unique literal ID
136  ID = TupleID( this->convertTitleToID( title ) );
137  // Just in case ...
138  while ( nTupleExists( ID ) || evtColExists( ID ) ) {
139  ID = TupleID( ID.idAsString() + "_" );
140  }
141  }
142  // return
143  return nTuple( ID, title, clid );
144 }
145 // ============================================================================
146 
147 // ============================================================================
148 // Access an Event Tag Collection object (book on-demand) with unique identifier
149 // ============================================================================
150 template <class PBASE>
151 Tuples::Tuple GaudiTuples<PBASE>::evtCol( const std::string& title, const CLID& clid ) const
152 {
153  // look up in the table
154  auto& m = evtColByTitle();
155  auto tuple = m.find( title );
156  if ( tuple != m.end() ) return Tuple( tuple->tuple ); // RETURN
157  // Create the tuple ID
158  TupleID ID;
159  if ( this->useNumericAutoIDs() || title.empty() ) {
160  if ( !this->useNumericAutoIDs() ) {
161  this->Warning(
162  "Cannot generate automatic literal ID from an empty title ! Using numeric ID instead for evtCol ID",
164  .ignore();
165  }
166  // proposed the tuple ID
167  ID = TupleID( m_evtColMap.size() + 1 + evtColOffSet() );
168  // adjust the proposed ID
169  while ( nTupleExists( ID ) || evtColExists( ID ) ) {
170  ID = TupleID( ID.numeric() + 1 );
171  }
172  } else {
173  // use the title to create a unique literal ID
174  ID = TupleID( this->convertTitleToID( title ) );
175  // Just in case ...
176  while ( nTupleExists( ID ) || evtColExists( ID ) ) {
177  ID = TupleID( ID.idAsString() + "_" );
178  }
179  }
180  // return
181  return evtCol( ID, title, clid );
182 }
183 // ============================================================================
184 
185 // ============================================================================
186 // get N-tuple object ( book on-demand ) with forced ID
187 // ============================================================================
188 template <class PBASE>
189 Tuples::Tuple GaudiTuples<PBASE>::nTuple( const TupleID& ID, const std::string& title1, const CLID& clid ) const
190 {
191  // Check ID
192  if ( ID.undefined() ) {
193  this->Error( "Undefined NTuple ID : Title='" + title1 + "'" ).ignore();
194  return Tuple( 0 );
195  }
196 
197  // look up in the table
198  auto& m = nTupleByID();
199  auto tuple = m.find( ID );
200  if ( tuple != m.end() ) return Tuple( tuple->tuple ); // RETURN
201 
202  // convert ID to the string
203  const std::string tID = ID.idAsString();
204 
205  // adjust the NTuple title
206  const std::string title = title1.empty() ? ( "NTuple #" + tID ) : title1;
207 
208  // book new ntuple
209  if ( !produceNTuples() ) {
210  auto r = m_nTupleMap.insert( nTupleMapItem{title, ID, createNTuple( title, nullptr, clid )} );
211  if ( !r.second ) this->Error( "Failure to createNTuple" ).ignore();
212  return Tuple( r.first->tuple );
213  }
214  // book NTupel
215  NTuple::Tuple* tup = nullptr;
216  if ( ID.numeric() ) {
217  tup = this->ntupleSvc()->book( nTuplePath(), ID.numericID(), clid, title );
218  } else if ( ID.literal() ) {
219  tup = this->ntupleSvc()->book( nTuplePath(), ID.literalID(), clid, title );
220  } else {
221  this->Error( "Undefined NTuple ID" ).ignore();
222  }
223 
224  // assertion
225  this->Assert( tup, "Could not book the N-Tuple='" + title + "'" );
226  // some printout
227  if ( tup->registry() && this->msgLevel( MSG::DEBUG ) ) {
228  this->debug() << "Booked NTuple '" << title << "' ID=" << tID << "' Path='" << nTuplePath() << "' TS='"
229  << tup->registry()->identifier() << "'" << endmsg;
230  }
231 
232  auto r = m_nTupleMap.insert( nTupleMapItem{title, ID, createNTuple( title, tup, clid )} );
233  if ( !r.second ) this->Error( "Failure to createNTuple" ).ignore();
234  return Tuple( r.first->tuple );
235  //
236 }
237 // ============================================================================
238 template <class PBASE>
239 Tuples::Tuple GaudiTuples<PBASE>::evtCol( const TupleID& ID, const std::string& title1, const CLID& clid ) const
240 {
241  // Check ID
242  if ( ID.undefined() ) {
243  this->Error( "Undefined NTuple ID : Title='" + title1 + "'" ).ignore();
244  return Tuple( 0 );
245  }
246 
247  // look up in the table
248  auto& tuple = evtColByID();
249  auto i = tuple.find( ID );
250  if ( i != tuple.end() ) return Tuple( i->tuple ); // RETURN
251 
252  // convert ID to the string
253  const std::string tID = ID.idAsString();
254 
255  // adjust the NTuple title
256  const std::string title = title1.empty() ? ( "EvtCol #" + tID ) : title1;
257 
258  // book new ntuple
259  if ( !produceEvtCols() ) {
260  auto r = m_evtColMap.insert( nTupleMapItem{title, ID, createEvtCol( title, nullptr, clid )} );
261  if ( !r.second ) this->Error( "Failure to createEvtCol" ).ignore();
262  return Tuple( r.first->tuple );
263  }
264  // book NTuple
265  NTuple::Tuple* tup = nullptr;
266  if ( ID.numeric() ) {
267  tup = this->evtColSvc()->book( evtColPath(), ID.numericID(), clid, title );
268  } else if ( ID.literal() ) {
269  tup = this->evtColSvc()->book( evtColPath(), ID.literalID(), clid, title );
270  } else {
271  this->Error( "Undefined NTuple ID" ).ignore();
272  }
273 
274  // assertion
275  this->Assert( tup, "Could not book the EvtCol='" + title + "'" );
276  // some printout
277  if ( tup->registry() && this->msgLevel( MSG::DEBUG ) ) {
278  this->debug() << "Booked EvtCol '" << title << "' ID=" << tID << "' Path='" << evtColPath() << "' TS='"
279  << tup->registry()->identifier() << "'" << endmsg;
280  }
281  auto r = m_evtColMap.insert( nTupleMapItem{title, ID, createEvtCol( title, tup, clid )} );
282  if ( !r.second ) this->Error( "Failure to createEvtCol" ).ignore();
283  return Tuple( r.first->tuple );
284 }
285 // ============================================================================
286 // create TupleObj
287 // ============================================================================
288 template <class PBASE>
290  const CLID& clid ) const
291 {
292  return Tuples::createTupleObj( this, "Tuple '" + name + "'", tuple, clid, Tuples::NTUPLE );
293 }
294 // ============================================================================
295 
296 // ============================================================================
297 // create TupleObj for event tag collection
298 // ============================================================================
299 template <class PBASE>
301  const CLID& clid ) const
302 {
303  return Tuples::createTupleObj( this, "EvtCol '" + name + "'", tuple, clid, Tuples::EVTCOL );
304 }
305 // ============================================================================
306 // perform the actual printout of N-tuples
307 // ============================================================================
308 template <class PBASE>
310 {
311 
312  if ( m_nTupleMap.empty() ) {
313  if ( this->msgLevel( MSG::DEBUG ) ) this->debug() << "No N-Tuples are booked" << endmsg;
314  } else {
315  this->always() << "List of booked N-Tuples in directory "
316  << "\"" << nTuplePath() << "\"" << endmsg;
317  }
318 
319  for ( const auto& entry : this->nTupleOrdered() ) {
320  if ( !entry.tuple->tuple() ) {
321  this->error() << " NTuple::Tuple* points to NULL" << endmsg;
322  continue;
323  }
324  this->always() << GaudiAlg::PrintTuple::print( entry.tuple->tuple(), entry.id ) << endmsg;
325  }
326  //
327  return this->m_nTupleMap.size();
328 }
329 // ============================================================================
330 // perform the actual printout of Evt Tag Collections
331 // ============================================================================
332 template <class PBASE>
334 {
335  if ( m_evtColMap.empty() ) {
336  this->always() << "No Event Tag Collections are booked" << endmsg;
337  } else {
338  this->always() << "List of booked Event Tag Collections in directory "
339  << "\"" << evtColPath() << "\"" << endmsg;
340  }
341  for ( const auto& entry : this->evtColOrdered() ) {
342  if ( !entry.tuple->tuple() ) {
343  this->error() << " NTuple::Tuple* points to NULL" << endmsg;
344  continue;
345  }
346  this->always() << GaudiAlg::PrintTuple::print( entry.tuple->tuple(), entry.id )
347  << " Items:" << Gaudi::Utils::toString( entry.tuple->items() ) << endmsg;
348  }
349  //
350  return this->m_evtColMap.size();
351 }
352 // ============================================================================
353 // check the existence AND validity of the N-Tuple with the given ID
354 // ============================================================================
355 template <class PBASE>
357 {
358  auto& m = nTupleByID();
359  return m.find( ID ) != m.end();
360 }
361 // ============================================================================
362 // check the existence AND validity of the Event Tag Collection with the given ID
363 // ============================================================================
364 template <class PBASE>
366 {
367  auto& m = evtColByID();
368  return m.find( ID ) != m.end();
369 }
370 // ============================================================================
371 // Handle method for changes in the 'NTuplePrint' property
372 // ============================================================================
373 template <class PBASE>
375 {
376  // no action if not yet initialized
377  if ( this->FSMState() < Gaudi::StateMachine::INITIALIZED ) return;
378  if ( this->tuplesPrint() ) this->printTuples();
379 }
380 // ============================================================================
381 // Handle method for changes in the 'EvtColsPrint' property
382 // ============================================================================
383 template <class PBASE>
385 {
386  // no action if not yet initialized
387  if ( this->FSMState() < Gaudi::StateMachine::INITIALIZED ) return;
388  if ( this->evtColsPrint() ) this->printEvtCols();
389 }
390 // ============================================================================
391 // get the constructed N-Tuple path
392 // ============================================================================
393 template <class PBASE>
395 {
396  const std::string path = nTupleLUN() + "/" + nTupleTopDir() + nTupleDir();
397  return splitNTupleDir() ? dirHbookName( path ) : path;
398 }
399 // ============================================================================
400 // get the constructed Event Tag Collection path
401 // ============================================================================
402 template <class PBASE>
404 {
405  std::string path = evtColLUN() + "/" + evtColTopDir() + evtColDir();
406  return splitEvtColDir() ? dirHbookName( path ) : path;
407 }
408 // ============================================================================
409 // The END
410 // ============================================================================
static std::string print(const INTuple *tuple, const GaudiAlg::TupleID &ID)
Definition: Print.cpp:153
T empty(T...args)
bool nTupleExists(const TupleID &ID) const
check the existence AND validity of the N-Tuple with the given ID
Templated base class providing common &#39;ntupling&#39; methods.
Definition: GaudiTuples.h:43
Header file for class TupleObj.
NumericID numericID() const noexcept
Returns the numerical ID.
Definition: GaudiHistoID.h:74
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition: ToStream.h:356
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.
few useful function to construct names of Hbook histograms and directories functions are imported fro...
bool isFailure() const
Definition: StatusCode.h:139
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)
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:51
constexpr double m
Definition: SystemOfUnits.h:94
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
virtual std::unique_ptr< Tuples::TupleObj > createEvtCol(const std::string &name, NTuple::Tuple *tuple, const CLID &clid) const
create TupleObj for event tag collection
bool evtColExists(const TupleID &ID) const
check the existence AND validity of the Event Tag Collection with the given ID
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
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:407
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:226
T insert(T...args)
std::string evtColPath() const
get the constructed Event Tag Collection path
STL class.
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.
virtual std::unique_ptr< Tuples::TupleObj > createNTuple(const std::string &name, NTuple::Tuple *tuple, const CLID &clid) const
create TupleObj