The Gaudi Framework  master (37c0b60a)
RCWNTupleCnv.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #define ROOTHISTCNV_RCWNTUPLECNV_CPP
12 
13 // Include files
14 #include <GaudiKernel/INTupleSvc.h>
15 #include <GaudiKernel/MsgStream.h>
16 #include <GaudiKernel/NTuple.h>
17 
18 // Compiler include files
19 #include <cstdio>
20 #include <cstring>
21 #include <list>
22 #include <type_traits>
23 #include <utility>
24 #include <vector>
25 
26 #include "RCWNTupleCnv.h"
27 
28 #include <TLeafD.h>
29 #include <TLeafF.h>
30 #include <TLeafI.h>
31 #include <TTree.h>
32 
33 namespace {
34  template <typename T>
35  size_t saveItem( char* target, const NTuple::_Data<T>& src ) {
36  static_assert( std::is_trivially_copyable_v<T>, "T must be trivally copyable" );
37  std::memcpy( target, src.buffer(), sizeof( T ) * src.length() );
38  return sizeof( T ) * src.length();
39  }
40 
41  template <typename T>
42  size_t loadItem( const char* src, NTuple::_Data<T>& target ) {
43  static_assert( std::is_trivially_copyable_v<T>, "T must be trivally copyable" );
44  std::memcpy( const_cast<void*>( target.buffer() ), src, sizeof( T ) * target.length() );
45  return sizeof( T ) * target.length();
46  }
47 
48  template <typename POD>
49  decltype( auto ) downcast_item( const INTupleItem& i ) {
50  return dynamic_cast<const NTuple::_Data<POD>&>( i );
51  }
52  template <typename POD>
53  decltype( auto ) downcast_item( INTupleItem& i ) {
54  return dynamic_cast<NTuple::_Data<POD>&>( i );
55  }
56  template <typename POD, typename T>
57  void downcast_item( T&& ) = delete;
58 
59  template <typename Item, typename F>
60  decltype( auto ) visit( Item& i, F&& f ) {
61  switch ( i.type() ) {
62  case DataTypeInfo::INT:
63  return f( downcast_item<int>( i ) );
64  case DataTypeInfo::CHAR:
65  return f( downcast_item<char>( i ) );
67  return f( downcast_item<short>( i ) );
68  case DataTypeInfo::LONG:
69  return f( downcast_item<long>( i ) );
71  return f( downcast_item<long long>( i ) );
73  return f( downcast_item<unsigned char>( i ) );
75  return f( downcast_item<unsigned short>( i ) );
76  case DataTypeInfo::UINT:
77  return f( downcast_item<unsigned int>( i ) );
79  return f( downcast_item<unsigned long>( i ) );
81  return f( downcast_item<unsigned long long>( i ) );
83  return f( downcast_item<double>( i ) );
85  return f( downcast_item<float>( i ) );
86  case DataTypeInfo::BOOL:
87  return f( downcast_item<bool>( i ) );
88  }
89  throw std::runtime_error( "RCWNTupleCnv::visit: unknown INTupleItem::type()" );
90  }
91 
92  //-----------------------------------------------------------------------------
93  template <class T>
94  void analyzeItem( const std::string& typ, const NTuple::_Data<T>* it, std::string& desc, std::string& block_name,
95  std::string& var_name, long& lowerRange, long& upperRange, long& size )
96  //-----------------------------------------------------------------------------
97  {
98 
99  RootHistCnv::parseName( it->name(), block_name, var_name );
100 
101  // long item_size = (sizeof(T) < 4) ? 4 : sizeof(T);
102  long item_size = sizeof( T );
103  long dimension = it->length();
104  long ndim = it->ndim() - 1;
105  desc += var_name;
106  if ( it->hasIndex() || it->length() > 1 ) { desc += '['; }
107  if ( it->hasIndex() ) {
108  std::string ind_blk, ind_var;
109  RootHistCnv::parseName( it->index(), ind_blk, ind_var );
110  if ( ind_blk != block_name ) {
111  std::cerr << "ERROR: Index for CWNT variable " << ind_var << " is in a different block: " << ind_blk
112  << std::endl;
113  }
114  desc += ind_var;
115  } else if ( it->dim( ndim ) > 1 ) {
116  desc += std::to_string( it->dim( ndim ) );
117  }
118 
119  for ( int i = ndim - 1; i >= 0; i-- ) {
120  desc += "][";
121  desc += std::to_string( it->dim( i ) );
122  }
123  if ( it->hasIndex() || it->length() > 1 ) { desc += ']'; }
124 
125  // 0 and -1 are used to mark that the range is not defined
126  lowerRange = 0;
127  upperRange = -1;
128  if constexpr ( std::is_integral_v<T> ) {
129  // An explicit range makes sense only for integral types so we check only in that case if it is defined.
130  // Note that later a range is only taken into account for int32_t.
131  if ( it->range().lower() != it->range().min() && it->range().upper() != it->range().max() ) {
132  lowerRange = it->range().lower();
133  upperRange = it->range().upper();
134  }
135  }
136 
137  desc += typ;
138  size += item_size * dimension;
139  }
140 } // namespace
141 
142 //-----------------------------------------------------------------------------
144 //-----------------------------------------------------------------------------
145 {
146  MsgStream log( msgSvc(), "RCWNTupleCnv" );
147  rtree = new TTree( desc.c_str(), nt->title().c_str() );
148  log << MSG::VERBOSE << "created tree id: " << rtree->GetName() << " title: " << nt->title() << " desc: " << desc
149  << endmsg;
150 
151  // Loop over the items
152 
153  std::string block_name, var_name;
154  long lowerRange, upperRange;
155  long size = 0;
156  long cursize, oldsize = 0;
157  std::vector<std::string> item_fullname;
158  // std::vector<long> item_size,item_size2;
159  std::vector<long> item_buf_pos, item_buf_len, item_buf_end;
160  std::vector<long> item_range_lower, item_range_upper;
162 
163  for ( const auto& i : nt->items() ) {
164  std::string item;
165 
166  visit( *i, [&]( const auto& data ) {
167  analyzeItem( this->rootVarType( data.type() ), &data, item, block_name, var_name, lowerRange, upperRange, size );
168  } );
169 
170  item_name.emplace_back( block_name, item );
171  cursize = size - oldsize;
172 
173  log << MSG::VERBOSE << "item: " << item << " type " << i->type() << " blk: " << block_name << " var: " << var_name
174  << " rng: " << lowerRange << " " << upperRange << " sz: " << size << " " << cursize
175  << " buf_pos: " << size - cursize << endmsg;
176 
177  item_fullname.push_back( var_name );
178  item_buf_pos.push_back( size - cursize );
179  item_buf_len.push_back( cursize );
180  item_buf_end.push_back( size );
181  item_range_lower.push_back( lowerRange );
182  item_range_upper.push_back( upperRange );
183 
184  oldsize = size;
185  }
186 
187  // Make a new buffer, and tell the ntuple where it is
188  char* buff = nt->setBuffer( new char[size] );
189 
190  log << MSG::VERBOSE << "Created buffer size: " << size << " at " << (void*)buff << endmsg;
191 
192  // Zero out the buffer to make ROOT happy
193  std::fill_n( buff, size, 0 );
194 
195  char* buf_pos = buff;
196 
197  auto end = item_name.cend();
198 
199  // Loop over items, creating a new branch for each one;
200  unsigned int i_item = 0;
201 
202  Gaudi::Property<int> basket_size( "BasketSize", 32000 );
203  m_ntupleSvc.as<IProperty>()->getProperty( &basket_size ).ignore();
204 
205  for ( auto itr = item_name.cbegin(); itr != end; ++itr, ++i_item ) {
206 
207  buf_pos = buff + item_buf_pos[i_item];
208 
209  // log << MSG::WARNING << "adding TBranch " << i_item << " "
210  // << item_fullname[i_item]
211  // << " format: " << itr->second.c_str() << " at "
212  // << (void*) buf_pos << " (" << (void*) buff << "+"
213  // << (void*)item_buf_pos[i_item] << ")"
214  // << endmsg;
215 
216 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 15, 0 )
217  auto br = new TBranch( rtree,
218 #else
219  TBranch* br = new TBranch(
220 #endif
221  item_fullname[i_item].c_str(), buf_pos, itr->second.c_str(), basket_size );
222  if ( itr->first != "AUTO_BLK" ) {
223  std::string title = itr->first;
224  title = itr->first + "::" + br->GetTitle();
225  br->SetTitle( title.c_str() );
226  }
227 
228  log << MSG::DEBUG << "adding TBranch " << br->GetTitle() << " at " << (void*)buf_pos << endmsg;
229 
230  // for index items with a limited range. Must be a TLeafI!
231  if ( item_range_lower[i_item] < item_range_upper[i_item] ) {
232  // log << MSG::VERBOSE << "\"" << item_fullname[i_item]
233  // << "\" is range limited " << item_range_lower[i_item] << " "
234  // << item_range_upper[i_item] << endmsg;
235  TLeafI* index = nullptr;
236  TObject* tobj = br->GetListOfLeaves()->FindObject( item_fullname[i_item].c_str() );
237  if ( tobj->IsA()->InheritsFrom( "TLeafI" ) ) {
238  index = dynamic_cast<TLeafI*>( tobj );
239 
240  if ( index ) {
241  index->SetMaximum( item_range_upper[i_item] );
242  // FIXME -- add for next version of ROOT
243  // index->SetMinimum( item_range_lower[i_item] );
244  } else {
245  log << MSG::ERROR << "Could dynamic cast to TLeafI: " << item_fullname[i_item] << endmsg;
246  }
247  }
248  }
249 
250  rtree->GetListOfBranches()->Add( br );
251  }
252 
253  log << MSG::INFO << "Booked TTree with ID: " << desc << " \"" << nt->title() << "\" in directory " << getDirectory()
254  << endmsg;
255 
256  return StatusCode::SUCCESS;
257 }
258 
259 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
260 
261 //-----------------------------------------------------------------------------
263 //-----------------------------------------------------------------------------
264 {
265  // Fill the tree;
266  const auto& items = nt->items();
267  std::accumulate( begin( items ), end( items ), nt->buffer(), []( char* dest, const INTupleItem* i ) {
268  return dest + visit( *i, [dest]( const auto& item ) { return saveItem( dest, item ); } );
269  } );
270 
271  rtree->Fill();
272  nt->reset();
273  return StatusCode::SUCCESS;
274 }
275 
276 //-----------------------------------------------------------------------------
277 StatusCode RootHistCnv::RCWNTupleCnv::readData( TTree* rtree, INTuple* ntup, long ievt )
278 //-----------------------------------------------------------------------------
279 {
280  if ( ievt >= rtree->GetEntries() ) {
281  MsgStream log( msgSvc(), "RCWNTupleCnv::readData" );
282  log << MSG::ERROR << "no more entries in tree to read. max: " << rtree->GetEntries() << " current: " << ievt
283  << endmsg;
284  return StatusCode::FAILURE;
285  }
286 
287  rtree->GetEvent( ievt );
288  ievt++;
289 
290  // copy data from ntup->buffer() to ntup->items()->buffer()
291  auto& items = ntup->items();
292  std::accumulate( begin( items ), end( items ), const_cast<const char*>( ntup->buffer() ),
293  []( const char* src, INTupleItem* i ) {
294  return src + visit( *i, [src]( auto& item ) { return loadItem( src, item ); } );
295  } );
296 
297  return StatusCode::SUCCESS;
298 }
299 
300 //-----------------------------------------------------------------------------
302 //-----------------------------------------------------------------------------
303 {
304  MsgStream log( msgSvc(), "RCWNTupleCnv::load" );
305 
306  StatusCode status;
307 
308  NTuple::Tuple* pObj = nullptr;
309 
310  std::string title = tree->GetTitle();
311  log << MSG::VERBOSE << "loading CWNT " << title << " at: " << tree << endmsg;
312 
313  status = m_ntupleSvc->create( CLID_ColumnWiseTuple, title, pObj );
314  INTuple* ntup = dynamic_cast<INTuple*>( pObj );
315  if ( !ntup ) { log << MSG::ERROR << "cannot dynamic cast to INTuple" << endmsg; }
316 
317  INTupleItem* item = nullptr;
318 
319  std::string itemName, indexName, item_type, itemTitle, blockName;
320  // long numEnt, numVar;
321  long size, totsize = 0;
323 
324  // numEnt = (int)tree->GetEntries();
325  // numVar = tree->GetNbranches();
326 
327  // loop over all branches (==leaves)
328  TObjArray* lbr = tree->GetListOfBranches();
329  TIter bitr( lbr );
330  while ( TObject* tobjb = bitr() ) {
331 
332  TBranch* br = (TBranch*)tobjb;
333  itemTitle = br->GetTitle();
334 
335  int ipos = itemTitle.find( "::" );
336  if ( ipos >= 0 ) {
337  blockName = itemTitle.substr( 0, ipos );
338  } else {
339  blockName = "";
340  }
341 
342  TObjArray* lf = br->GetListOfLeaves();
343 
344  TIter litr( lf );
345  while ( TObject* tobj = litr() ) {
346 
347  bool hasRange = false;
348  int indexRange = 0;
349  int itemSize;
350  item = nullptr;
351 
352  TLeaf* tl = dynamic_cast<TLeaf*>( tobj );
353  if ( !tl ) {
354  log << MSG::ERROR << "cannot dynamic cast to TLeaf" << endmsg;
355  return StatusCode::FAILURE;
356  }
357  itemName = tl->GetName();
358 
359  if ( blockName != "" ) {
360  log << MSG::DEBUG << "loading NTuple item " << blockName << "/" << itemName;
361  } else {
362  log << MSG::DEBUG << "loading NTuple item " << itemName;
363  }
364 
365  int arraySize{ 0 };
366  TLeaf* indexLeaf = tl->GetLeafCounter( arraySize );
367 
368  if ( arraySize == 0 ) { log << MSG::ERROR << "TLeaf counter size = 0. This should not happen!" << endmsg; }
369 
370  if ( indexLeaf ) {
371  // index Arrays and Matrices
372 
373  indexName = indexLeaf->GetName();
374  indexRange = indexLeaf->GetMaximum();
375  itemSize = indexRange * tl->GetLenType() * arraySize;
376 
377  log << "[" << indexName;
378 
379  // Just for Matrices
380  if ( arraySize != 1 ) { log << "][" << arraySize; }
381  log << "]";
382 
383  } else {
384  itemSize = tl->GetLenType() * arraySize;
385 
386  indexName = "";
387 
388  if ( arraySize == 1 ) {
389  // Simple items
390  } else {
391  // Arrays of constant size
392  log << "[" << arraySize << "]";
393  }
394  }
395 
396  log << endmsg;
397 
398  size = itemSize;
399  totsize += size;
400 
401  hasRange = tl->IsRange();
402 
403  itemList.emplace_back( tl, itemSize );
404 
405  // Integer
406  if ( tobj->IsA()->InheritsFrom( "TLeafI" ) ) {
407 
408  TLeafI* tli = dynamic_cast<TLeafI*>( tobj );
409  if ( tli ) {
410  if ( tli->IsUnsigned() ) {
411  unsigned long min = 0, max = 0;
412  if ( hasRange ) {
413  min = tli->GetMinimum();
414  max = tli->GetMaximum();
415  }
416 
417  item = createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup, hasRange );
418  } else {
419  long min = 0, max = 0;
420  if ( hasRange ) {
421  min = tli->GetMinimum();
422  max = tli->GetMaximum();
423  }
424 
425  item = createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup, hasRange );
426  }
427  } else {
428  log << MSG::ERROR << "cannot dynamic cast to TLeafI" << endmsg;
429  }
430 
431  // Float
432  } else if ( tobj->IsA()->InheritsFrom( "TLeafF" ) ) {
433  float min = 0., max = 0.;
434 
435  TLeafF* tlf = dynamic_cast<TLeafF*>( tobj );
436  if ( tlf ) {
437  if ( hasRange ) {
438  min = float( tlf->GetMinimum() );
439  max = float( tlf->GetMaximum() );
440  }
441  } else {
442  log << MSG::ERROR << "cannot dynamic cast to TLeafF" << endmsg;
443  }
444 
445  item = createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup, hasRange );
446 
447  // Double
448  } else if ( tobj->IsA()->InheritsFrom( "TLeafD" ) ) {
449  double min = 0., max = 0.;
450 
451  TLeafD* tld = dynamic_cast<TLeafD*>( tobj );
452  if ( tld ) {
453  if ( hasRange ) {
454  min = tld->GetMinimum();
455  max = tld->GetMaximum();
456  }
457  } else {
458  log << MSG::ERROR << "cannot dynamic cast to TLeafD" << endmsg;
459  }
460 
461  item = createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup, hasRange );
462 
463  } else {
464  log << MSG::ERROR << "Uknown data type" << endmsg;
465  }
466 
467  if ( item ) {
468  ntup->add( item ).ignore();
469  } else {
470  log << MSG::ERROR << "Unable to create ntuple item \"" << itemName << "\"" << endmsg;
471  }
472 
473  } // end litr
474  } // end bitr
475 
476  log << MSG::DEBUG << "Total buffer size of NTuple: " << totsize << " Bytes." << endmsg;
477 
478  char* buf = ntup->setBuffer( new char[totsize] );
479  char* bufpos = buf;
480 
481  int ts = 0;
482  for ( const auto& iitr : itemList ) {
483  TLeaf* leaf = iitr.first;
484  int isize = iitr.second;
485 
486  log << MSG::VERBOSE << "setting TBranch " << leaf->GetBranch()->GetName() << " buffer at " << (void*)bufpos
487  << endmsg;
488 
489  leaf->GetBranch()->SetAddress( (void*)bufpos );
490 
491  // //testing
492  // if (leaf->IsA()->InheritsFrom("TLeafI")) {
493  // for (int ievt=0; ievt<5; ievt++) {
494  // leaf->GetBranch()->GetEvent(ievt);
495  // int *idat = (int*)bufpos;
496  // log << MSG::WARNING << leaf->GetName() << ": " << ievt << " "
497  // << *idat << endmsg;
498 
499  // }
500  // }
501 
502  ts += isize;
503 
504  bufpos += isize;
505  }
506 
507  if ( totsize != ts ) { log << MSG::ERROR << "buffer size mismatch: " << ts << " " << totsize << endmsg; }
508 
509  refpObject = ntup;
510 
511  return StatusCode::SUCCESS;
512 }
513 
514 // Instantiation of a static factory class used by clients to create
515 // instances of this service
MSG::DEBUG
@ DEBUG
Definition: IMessageSvc.h:25
NTuple::_Data::range
virtual const ItemRange & range() const =0
Access the range if specified.
RCWNTupleCnv.h
std::string
STL class.
details::size
constexpr auto size(const T &, Args &&...) noexcept
Definition: AnyDataWrapper.h:23
Gaudi.Configuration.log
log
Definition: Configuration.py:28
RootHistCnv::createNTupleItem
INTupleItem * createNTupleItem(const std::string &itemName, const std::string &blockName, const std::string &indexName, int indexRange, int arraySize, TYP min, TYP max, INTuple *ntup, bool hasRange)
Add an item of a given type to the N tuple.
Definition: RNTupleCnv.cpp:265
MSG::INFO
@ INFO
Definition: IMessageSvc.h:25
std::vector< std::string >
std::string::find
T find(T... args)
DECLARE_CONVERTER
#define DECLARE_CONVERTER(x)
Definition: Converter.h:163
DataTypeInfo::USHORT
@ USHORT
Definition: DataTypeInfo.h:36
INTuple::buffer
virtual const char * buffer() const =0
Access data buffer (CONST)
AvalancheSchedulerErrorTest.msgSvc
msgSvc
Definition: AvalancheSchedulerErrorTest.py:80
DataTypeInfo::ULONG
@ ULONG
Definition: DataTypeInfo.h:38
RootHistCnv::RCWNTupleCnv::writeData
StatusCode writeData(TTree *rtree, INTuple *pObject) override
Write N tuple data.
Definition: RCWNTupleCnv.cpp:262
std::vector::push_back
T push_back(T... args)
INTuple::setBuffer
virtual char * setBuffer(char *buff)=0
Attach data buffer.
DataTypeInfo::LONG
@ LONG
Definition: DataTypeInfo.h:42
NTuple::_Data
Abstract class describing basic data in an Ntuple.
Definition: NTuple.h:48
IProperty
Definition: IProperty.h:33
compareOutputFiles.target
target
Definition: compareOutputFiles.py:489
DataTypeInfo::DOUBLE
@ DOUBLE
Definition: DataTypeInfo.h:45
INTuple::items
virtual ItemContainer & items()=0
Access item container.
Gaudi::Utils::begin
AttribStringParser::Iterator begin(const AttribStringParser &parser)
Definition: AttribStringParser.h:136
StatusCode
Definition: StatusCode.h:65
DataTypeInfo::SHORT
@ SHORT
Definition: DataTypeInfo.h:40
std::cerr
RootHistCnv::parseName
bool parseName(const std::string &full, std::string &blk, std::string &var)
Definition: RNTupleCnv.cpp:240
compareRootHistos.ts
ts
Definition: compareRootHistos.py:488
RootHistCnv::RCWNTupleCnv
Definition: RCWNTupleCnv.h:30
std::string::c_str
T c_str(T... args)
std::to_string
T to_string(T... args)
NTuple.h
RootHistCnv::RNTupleCnv::m_ntupleSvc
SmartIF< INTupleSvc > m_ntupleSvc
Reference to N tuple service.
Definition: RNTupleCnv.h:64
INTuple
Definition: INTuple.h:91
std::runtime_error
STL class.
std::accumulate
T accumulate(T... args)
INTuple::add
virtual StatusCode add(INTupleItem *item)=0
Add an item row to the N tuple.
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
INTupleItem
Definition: INTuple.h:37
MsgStream
Definition: MsgStream.h:33
StatusCode::ignore
const StatusCode & ignore() const
Allow discarding a StatusCode without warning.
Definition: StatusCode.h:139
DataTypeInfo::FLOAT
@ FLOAT
Definition: DataTypeInfo.h:44
gaudirun.dest
dest
Definition: gaudirun.py:224
SmartIF::as
SmartIF< IFace > as() const
return a new SmartIF instance to another interface
Definition: SmartIF.h:117
std::string::substr
T substr(T... args)
std::vector::emplace_back
T emplace_back(T... args)
DataTypeInfo::UCHAR
@ UCHAR
Definition: DataTypeInfo.h:35
DataTypeInfo::UINT
@ UINT
Definition: DataTypeInfo.h:37
MSG::VERBOSE
@ VERBOSE
Definition: IMessageSvc.h:25
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
std::endl
T endl(T... args)
DataTypeInfo::BOOL
@ BOOL
Definition: DataTypeInfo.h:43
RootHistCnv::RCWNTupleCnv::readData
StatusCode readData(TTree *rtree, INTuple *pObject, long ievt) override
Read N tuple data.
Definition: RCWNTupleCnv.cpp:277
NTuple::Tuple
Abstract base class which allows the user to interact with the actual N tuple implementation.
Definition: NTuple.h:388
std::vector::cbegin
T cbegin(T... args)
MSG::ERROR
@ ERROR
Definition: IMessageSvc.h:25
INTuple::title
virtual const std::string & title() const =0
Object title.
DataTypeInfo::ULONGLONG
@ ULONGLONG
Definition: DataTypeInfo.h:55
GaudiPartProp.decorators.Item
Item
Definition: decorators.py:306
std::memcpy
T memcpy(T... args)
DataTypeInfo::LONGLONG
@ LONGLONG
Definition: DataTypeInfo.h:54
std::vector::cend
T cend(T... args)
IOTest.end
end
Definition: IOTest.py:125
Converter::msgSvc
SmartIF< IMessageSvc > & msgSvc() const
Retrieve pointer to message service.
Definition: Converter.cpp:105
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
getProperty
const char *PyHelper() getProperty(IInterface *p, char *name)
Definition: Bootstrap.cpp:251
RootHistCnv::RNTupleCnv::rootVarType
virtual std::string rootVarType(int)
Return ROOT type info:
Definition: RNTupleCnv.cpp:204
RootHistCnv::RCWNTupleCnv::load
StatusCode load(TTree *tree, INTuple *&refpObject) override
Create the transient representation of an object.
Definition: RCWNTupleCnv.cpp:301
RootHistCnv::RCWNTupleCnv::book
StatusCode book(const std::string &desc, INTuple *pObject, TTree *&tree) override
Book the N tuple.
Definition: RCWNTupleCnv.cpp:143
std::fill_n
T fill_n(T... args)
Gaudi::Property< int >
DataTypeInfo::INT
@ INT
Definition: DataTypeInfo.h:41
INTupleSvc.h
DataTypeInfo::CHAR
@ CHAR
Definition: DataTypeInfo.h:39
MsgStream.h
Gaudi::ParticleProperties::index
size_t index(const Gaudi::ParticleProperty *property, const Gaudi::Interfaces::IParticlePropertySvc *service)
helper utility for mapping of Gaudi::ParticleProperty object into non-negative integral sequential id...
Definition: IParticlePropertySvc.cpp:39