The Gaudi Framework  v29r0 (ff2e7097)
RCWNTupleCnv.cpp
Go to the documentation of this file.
1 #define ROOTHISTCNV_RCWNTUPLECNV_CPP
2 
3 #define ALLOW_ALL_TYPES
4 
5 // Include files
8 #include "GaudiKernel/NTuple.h"
9 
10 // Compiler include files
11 #include <cstdio>
12 #include <list>
13 #include <utility> /* std::pair */
14 #include <vector>
15 
16 #include "RCWNTupleCnv.h"
17 
18 #include "TLeafD.h"
19 #include "TLeafF.h"
20 #include "TLeafI.h"
21 #include "TTree.h"
22 
23 #ifdef __ICC
24 // disable icc remark #1572: floating-point equality and inequality comparisons are unreliable
25 // they are intended
26 #pragma warning( disable : 1572 )
27 #endif
28 
29 //-----------------------------------------------------------------------------
30 template <class T>
31 void analyzeItem( std::string typ, const NTuple::_Data<T>* it, std::string& desc, std::string& block_name,
32  std::string& var_name, long& lowerRange, long& upperRange, long& size )
33 //-----------------------------------------------------------------------------
34 {
35 
36  RootHistCnv::parseName( it->name(), block_name, var_name );
37 
38  // long item_size = (sizeof(T) < 4) ? 4 : sizeof(T);
39  long item_size = sizeof( T );
40  long dimension = it->length();
41  long ndim = it->ndim() - 1;
42  desc += var_name;
43  if ( it->hasIndex() || it->length() > 1 ) {
44  desc += '[';
45  }
46  if ( it->hasIndex() ) {
47  std::string ind_blk, ind_var;
48  RootHistCnv::parseName( it->index(), ind_blk, ind_var );
49  if ( ind_blk != block_name ) {
50  std::cerr << "ERROR: Index for CWNT variable " << ind_var << " is in a different block: " << ind_blk << std::endl;
51  }
52  desc += ind_var;
53  } else if ( it->dim( ndim ) > 1 ) {
54  desc += std::to_string( it->dim( ndim ) );
55  }
56 
57  for ( int i = ndim - 1; i >= 0; i-- ) {
58  desc += "][";
59  desc += std::to_string( it->dim( i ) );
60  }
61  if ( it->hasIndex() || it->length() > 1 ) {
62  desc += ']';
63  }
64 
65  if ( it->range().lower() != it->range().min() && it->range().upper() != it->range().max() ) {
66  lowerRange = it->range().lower();
67  upperRange = it->range().upper();
68  } else {
69  lowerRange = 0;
70  upperRange = -1;
71  }
72  desc += typ;
73  size += item_size * dimension;
74 }
75 
76 //-----------------------------------------------------------------------------
78 //-----------------------------------------------------------------------------
79 {
80  MsgStream log( msgSvc(), "RCWNTupleCnv" );
81  rtree = new TTree( desc.c_str(), nt->title().c_str() );
82  log << MSG::VERBOSE << "created tree id: " << rtree->GetName() << " title: " << nt->title() << " desc: " << desc
83  << endmsg;
84 
85  // Loop over the items
86 
87  std::string block_name, var_name;
88  long lowerRange, upperRange;
89  long size = 0;
90  long cursize, oldsize = 0;
91  std::vector<std::string> item_fullname;
92  // std::vector<long> item_size,item_size2;
93  std::vector<long> item_buf_pos, item_buf_len, item_buf_end;
94  std::vector<long> item_range_lower, item_range_upper;
96 
97  for ( const auto& i : nt->items() ) {
98  std::string item;
99 
100  switch ( i->type() ) {
101  case DataTypeInfo::INT: // int
102  analyzeItem( rootVarType( i->type() ), dynamic_cast<const NTuple::_Data<int>*>( i ), item, block_name, var_name,
103  lowerRange, upperRange, size );
104  break;
105  case DataTypeInfo::CHAR: // char
106  analyzeItem( rootVarType( i->type() ), dynamic_cast<const NTuple::_Data<char>*>( i ), item, block_name, var_name,
107  lowerRange, upperRange, size );
108  break;
109  case DataTypeInfo::SHORT: // short
110  analyzeItem( rootVarType( i->type() ), dynamic_cast<const NTuple::_Data<short>*>( i ), item, block_name, var_name,
111  lowerRange, upperRange, size );
112  break;
113  case DataTypeInfo::LONG: // long
114  analyzeItem( rootVarType( i->type() ), dynamic_cast<const NTuple::_Data<long>*>( i ), item, block_name, var_name,
115  lowerRange, upperRange, size );
116  break;
117  case DataTypeInfo::LONGLONG: // long long
118  analyzeItem( rootVarType( i->type() ), dynamic_cast<const NTuple::_Data<long long>*>( i ), item, block_name,
119  var_name, lowerRange, upperRange, size );
120  break;
121  case DataTypeInfo::UCHAR: // unsigned char
122  analyzeItem( rootVarType( i->type() ), dynamic_cast<const NTuple::_Data<unsigned char>*>( i ), item, block_name,
123  var_name, lowerRange, upperRange, size );
124  break;
125  case DataTypeInfo::USHORT: // unsigned short
126  analyzeItem( rootVarType( i->type() ), dynamic_cast<const NTuple::_Data<unsigned short>*>( i ), item, block_name,
127  var_name, lowerRange, upperRange, size );
128  break;
129  case DataTypeInfo::UINT: // unsigned int
130  analyzeItem( rootVarType( i->type() ), dynamic_cast<const NTuple::_Data<unsigned int>*>( i ), item, block_name,
131  var_name, lowerRange, upperRange, size );
132  break;
133  case DataTypeInfo::ULONG: // unsigned long
134  analyzeItem( rootVarType( i->type() ), dynamic_cast<const NTuple::_Data<unsigned long>*>( i ), item, block_name,
135  var_name, lowerRange, upperRange, size );
136  break;
137  case DataTypeInfo::ULONGLONG: // unsigned long long
138  analyzeItem( rootVarType( i->type() ), dynamic_cast<const NTuple::_Data<unsigned long long>*>( i ), item,
139  block_name, var_name, lowerRange, upperRange, size );
140  break;
141  case DataTypeInfo::DOUBLE: // double
142  analyzeItem( rootVarType( i->type() ), dynamic_cast<const NTuple::_Data<double>*>( i ), item, block_name,
143  var_name, lowerRange, upperRange, size );
144  break;
145  case DataTypeInfo::FLOAT: // float
146  analyzeItem( rootVarType( i->type() ), dynamic_cast<const NTuple::_Data<float>*>( i ), item, block_name, var_name,
147  lowerRange, upperRange, size );
148  break;
149  case DataTypeInfo::BOOL: // bool
150  analyzeItem( rootVarType( i->type() ), dynamic_cast<const NTuple::_Data<bool>*>( i ), item, block_name, var_name,
151  lowerRange, upperRange, size );
152  break;
153  default:
154  break;
155  }
156 
157  item_name.emplace_back( block_name, item );
158  cursize = size - oldsize;
159 
160  log << MSG::VERBOSE << "item: " << item << " type " << i->type() << " blk: " << block_name << " var: " << var_name
161  << " rng: " << lowerRange << " " << upperRange << " sz: " << size << " " << cursize
162  << " buf_pos: " << size - cursize << endmsg;
163 
164  item_fullname.push_back( var_name );
165  item_buf_pos.push_back( size - cursize );
166  item_buf_len.push_back( cursize );
167  item_buf_end.push_back( size );
168  item_range_lower.push_back( lowerRange );
169  item_range_upper.push_back( upperRange );
170 
171  oldsize = size;
172  }
173 
174  // Make a new buffer, and tell the ntuple where it is
175  char* buff = nt->setBuffer( new char[size] );
176 
177  log << MSG::VERBOSE << "Created buffer size: " << size << " at " << (void*)buff << endmsg;
178 
179  // Zero out the buffer to make ROOT happy
180  std::fill_n( buff, size, 0 );
181 
182  char* buf_pos = buff;
183 
184  auto end = item_name.cend();
185 
186  // Loop over items, creating a new branch for each one;
187  unsigned int i_item = 0;
188  for ( auto itr = item_name.cbegin(); itr != end; ++itr, ++i_item ) {
189 
190  buf_pos = buff + item_buf_pos[i_item];
191 
192 // log << MSG::WARNING << "adding TBranch " << i_item << " "
193 // << item_fullname[i_item]
194 // << " format: " << itr->second.c_str() << " at "
195 // << (void*) buf_pos << " (" << (void*) buff << "+"
196 // << (void*)item_buf_pos[i_item] << ")"
197 // << endmsg;
198 
199 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 15, 0 )
200  auto br = new TBranch( rtree,
201 #else
202  TBranch* br = new TBranch(
203 #endif
204  item_fullname[i_item].c_str(), buf_pos, itr->second.c_str() );
205 
206  if ( itr->first != "AUTO_BLK" ) {
207  std::string tit = itr->first;
208  tit = itr->first + "::" + br->GetTitle();
209  br->SetTitle( tit.c_str() );
210  }
211 
212  log << MSG::DEBUG << "adding TBranch " << br->GetTitle() << " at " << (void*)buf_pos << endmsg;
213 
214  // for index items with a limited range. Must be a TLeafI!
215  if ( item_range_lower[i_item] < item_range_upper[i_item] ) {
216  // log << MSG::VERBOSE << "\"" << item_fullname[i_item]
217  // << "\" is range limited " << item_range_lower[i_item] << " "
218  // << item_range_upper[i_item] << endmsg;
219  TLeafI* index = nullptr;
220  TObject* tobj = br->GetListOfLeaves()->FindObject( item_fullname[i_item].c_str() );
221  if ( tobj->IsA()->InheritsFrom( "TLeafI" ) ) {
222  index = dynamic_cast<TLeafI*>( tobj );
223 
224  if ( index ) {
225  index->SetMaximum( item_range_upper[i_item] );
226  // FIXME -- add for next version of ROOT
227  // index->SetMinimum( item_range_lower[i_item] );
228  } else {
229  log << MSG::ERROR << "Could dynamic cast to TLeafI: " << item_fullname[i_item] << endmsg;
230  }
231  }
232  }
233 
234  rtree->GetListOfBranches()->Add( br );
235  }
236 
237  log << MSG::INFO << "Booked TTree with ID: " << desc << " \"" << nt->title() << "\" in directory " << getDirectory()
238  << endmsg;
239 
240  return StatusCode::SUCCESS;
241 }
242 
243 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
244 
245 //-----------------------------------------------------------------------------
247 //-----------------------------------------------------------------------------
248 {
249  // Fill the tree;
250  char* tar = nt->buffer();
251  for ( const auto& i : nt->items() ) {
252  switch ( i->type() ) {
253  case DataTypeInfo::BOOL: // bool
254  tar += saveItem( tar, (bool*)i->buffer(), i->length() );
255  break;
256  case DataTypeInfo::CHAR: // char
257  tar += saveItem( tar, (char*)i->buffer(), i->length() );
258  break;
259  case DataTypeInfo::SHORT: // short
260  tar += saveItem( tar, (short*)i->buffer(), i->length() );
261  break;
262  case DataTypeInfo::INT: // int
263  tar += saveItem( tar, (int*)i->buffer(), i->length() );
264  break;
265  case DataTypeInfo::LONG: // long
266  tar += saveItem( tar, (long*)i->buffer(), i->length() );
267  break;
268  case DataTypeInfo::LONGLONG: // long long
269  tar += saveItem( tar, (long long*)i->buffer(), i->length() );
270  break;
271  case DataTypeInfo::UCHAR: // unsigned char
272  tar += saveItem( tar, (unsigned char*)i->buffer(), i->length() );
273  break;
274  case DataTypeInfo::USHORT: // unsigned short
275  tar += saveItem( tar, (unsigned short*)i->buffer(), i->length() );
276  break;
277  case DataTypeInfo::UINT: // unsigned int
278  tar += saveItem( tar, (unsigned int*)i->buffer(), i->length() );
279  break;
280  case DataTypeInfo::ULONG: // unsigned long
281  tar += saveItem( tar, (unsigned long*)i->buffer(), i->length() );
282  break;
283  case DataTypeInfo::ULONGLONG: // unsigned long
284  tar += saveItem( tar, (unsigned long long*)i->buffer(), i->length() );
285  break;
286  case DataTypeInfo::FLOAT: // float
287  tar += saveItem( tar, (float*)i->buffer(), i->length() );
288  break;
289  case DataTypeInfo::DOUBLE: // double
290  tar += saveItem( tar, (double*)i->buffer(), i->length() );
291  break;
292  default:
293  break;
294  }
295  }
296 
297  rtree->Fill();
298  nt->reset();
299  return StatusCode::SUCCESS;
300 }
301 
302 //-----------------------------------------------------------------------------
303 StatusCode RootHistCnv::RCWNTupleCnv::readData( TTree* rtree, INTuple* ntup, long ievt )
304 //-----------------------------------------------------------------------------
305 {
306  MsgStream log( msgSvc(), "RCWNTupleCnv::readData" );
307 
308  if ( ievt >= rtree->GetEntries() ) {
309  log << MSG::ERROR << "no more entries in tree to read. max: " << rtree->GetEntries() << " current: " << ievt
310  << endmsg;
311  return StatusCode::FAILURE;
312  }
313 
314  rtree->GetEvent( ievt );
315 
316  ievt++;
317 
318  // copy data from ntup->buffer() to ntup->items()->buffer()
319 
320  char* src = ntup->buffer();
321  for ( auto& i : ntup->items() ) {
322 
323  switch ( i->type() ) {
324  case DataTypeInfo::BOOL: // bool
325  src += loadItem( src, (bool*)i->buffer(), i->length() );
326  break;
327  case DataTypeInfo::CHAR: // char
328  src += loadItem( src, (char*)i->buffer(), i->length() );
329  break;
330  case DataTypeInfo::SHORT: // short
331  src += loadItem( src, (short*)i->buffer(), i->length() );
332  break;
333  case DataTypeInfo::INT: // short
334  src += loadItem( src, (int*)i->buffer(), i->length() );
335  break;
336  case DataTypeInfo::LONG: // long
337  src += loadItem( src, (long*)i->buffer(), i->length() );
338  break;
339  case DataTypeInfo::LONGLONG: // long long
340  src += loadItem( src, (long long*)i->buffer(), i->length() );
341  break;
342  case DataTypeInfo::UCHAR: // unsigned char
343  src += loadItem( src, (unsigned char*)i->buffer(), i->length() );
344  break;
345  case DataTypeInfo::USHORT: // unsigned short
346  src += loadItem( src, (unsigned short*)i->buffer(), i->length() );
347  break;
348  case DataTypeInfo::UINT: // unsigned short
349  src += loadItem( src, (unsigned int*)i->buffer(), i->length() );
350  break;
351  case DataTypeInfo::ULONG: // unsigned long
352  src += loadItem( src, (unsigned long*)i->buffer(), i->length() );
353  break;
354  case DataTypeInfo::ULONGLONG: // unsigned long long
355  src += loadItem( src, (unsigned long long*)i->buffer(), i->length() );
356  break;
357  case DataTypeInfo::FLOAT: // float
358  src += loadItem( src, (float*)i->buffer(), i->length() );
359  break;
360  case DataTypeInfo::DOUBLE: // unsigned short
361  src += loadItem( src, (double*)i->buffer(), i->length() );
362  break;
363  default:
364  break;
365  }
366  }
367 
368  return StatusCode::SUCCESS;
369 }
370 
371 //-----------------------------------------------------------------------------
373 //-----------------------------------------------------------------------------
374 {
375  MsgStream log( msgSvc(), "RCWNTupleCnv::load" );
376 
377  StatusCode status;
378 
379  NTuple::Tuple* pObj = nullptr;
380 
381  std::string title = tree->GetTitle();
382  log << MSG::VERBOSE << "loading CWNT " << title << " at: " << tree << endmsg;
383 
384  status = m_ntupleSvc->create( CLID_ColumnWiseTuple, title, pObj );
385  INTuple* ntup = dynamic_cast<INTuple*>( pObj );
386 
387  INTupleItem* item = nullptr;
388 
389  std::string itemName, indexName, item_type, itemTitle, blockName;
390  // long numEnt, numVar;
391  long size, totsize = 0;
393 
394  // numEnt = (int)tree->GetEntries();
395  // numVar = tree->GetNbranches();
396 
397  // loop over all branches (==leaves)
398  TObjArray* lbr = tree->GetListOfBranches();
399  TIter bitr( lbr );
400  while ( TObject* tobjb = bitr() ) {
401 
402  TBranch* br = (TBranch*)tobjb;
403  itemTitle = br->GetTitle();
404 
405  int ipos = itemTitle.find( "::" );
406  if ( ipos >= 0 ) {
407  blockName = itemTitle.substr( 0, ipos );
408  } else {
409  blockName = "";
410  }
411 
412  TObjArray* lf = br->GetListOfLeaves();
413 
414  TIter litr( lf );
415  while ( TObject* tobj = litr() ) {
416 
417  bool hasRange = false;
418  int indexRange = 0;
419  int itemSize;
420  item = nullptr;
421 
422  // TLeaf* tl = (TLeaf*)tobj;
423  TLeaf* tl = dynamic_cast<TLeaf*>( tobj );
424  itemName = tl->GetName();
425 
426  // char* buf_pos = (char*)tl->GetValuePointer();
427  // cout << " " << itemName << " " << blockName << " "
428  // << (void*)buf_pos;
429 
430  if ( blockName != "" ) {
431  log << MSG::DEBUG << "loading NTuple item " << blockName << "/" << itemName;
432  } else {
433  log << MSG::DEBUG << "loading NTuple item " << itemName;
434  }
435 
436  int arraySize;
437  TLeaf* indexLeaf = tl->GetLeafCounter( arraySize );
438 
439  if ( arraySize == 0 ) {
440  log << MSG::ERROR << "TLeaf counter size = 0. This should not happen!" << endmsg;
441  }
442 
443  if ( indexLeaf ) {
444  // index Arrays and Matrices
445 
446  indexName = indexLeaf->GetName();
447  // indexRange = tl->GetNdata();
448  indexRange = indexLeaf->GetMaximum();
449  itemSize = indexRange * tl->GetLenType() * arraySize;
450 
451  log << "[" << indexName;
452 
453  // Just for Matrices
454  if ( arraySize != 1 ) {
455  log << "][" << arraySize;
456  }
457  log << "]";
458 
459  } else {
460  itemSize = tl->GetLenType() * arraySize;
461 
462  indexName = "";
463 
464  if ( arraySize == 1 ) {
465  // Simple items
466  } else {
467  // Arrays of constant size
468  log << "[" << arraySize << "]";
469  }
470  }
471 
472  log << endmsg;
473 
474  // cout << " index: " << indexName << endl;
475 
476  // size = tl->GetNdata() * tl->GetLenType();
477  size = itemSize;
478  totsize += size;
479 
480  hasRange = tl->IsRange();
481 
482  itemList.emplace_back( tl, itemSize );
483 
484  // Integer
485  if ( tobj->IsA()->InheritsFrom( "TLeafI" ) ) {
486 
487  TLeafI* tli = dynamic_cast<TLeafI*>( tobj );
488  if ( tli->IsUnsigned() ) {
489  unsigned long min = 0, max = 0;
490  if ( hasRange ) {
491  min = tli->GetMinimum();
492  max = tli->GetMaximum();
493  }
494 
495  item = createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup );
496  } else {
497  long min = 0, max = 0;
498  if ( hasRange ) {
499  min = tli->GetMinimum();
500  max = tli->GetMaximum();
501  }
502 
503  item = createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup );
504  }
505 
506  // Float
507  } else if ( tobj->IsA()->InheritsFrom( "TLeafF" ) ) {
508  float min = 0., max = 0.;
509 
510  TLeafF* tlf = dynamic_cast<TLeafF*>( tobj );
511  if ( hasRange ) {
512  min = float( tlf->GetMinimum() );
513  max = float( tlf->GetMaximum() );
514  }
515 
516  item = createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup );
517 
518  // Double
519  } else if ( tobj->IsA()->InheritsFrom( "TLeafD" ) ) {
520  double min = 0., max = 0.;
521 
522  TLeafD* tld = dynamic_cast<TLeafD*>( tobj );
523  if ( hasRange ) {
524  min = tld->GetMinimum();
525  max = tld->GetMaximum();
526  }
527 
528  item = createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup );
529 
530  } else {
531  log << MSG::ERROR << "Uknown data type" << endmsg;
532  }
533 
534  if ( item ) {
535  ntup->add( item );
536  } else {
537  log << MSG::ERROR << "Unable to create ntuple item \"" << itemName << "\"" << endmsg;
538  }
539 
540  } // end litr
541  } // end bitr
542 
543  log << MSG::DEBUG << "Total buffer size of NTuple: " << totsize << " Bytes." << endmsg;
544 
545  char* buf = ntup->setBuffer( new char[totsize] );
546  char* bufpos = buf;
547 
548  int ts = 0;
549  for ( const auto& iitr : itemList ) {
550  TLeaf* leaf = iitr.first;
551  int isize = iitr.second;
552 
553  log << MSG::VERBOSE << "setting TBranch " << leaf->GetBranch()->GetName() << " buffer at " << (void*)bufpos
554  << endmsg;
555 
556  leaf->GetBranch()->SetAddress( (void*)bufpos );
557 
558  // //testing
559  // if (leaf->IsA()->InheritsFrom("TLeafI")) {
560  // for (int ievt=0; ievt<5; ievt++) {
561  // leaf->GetBranch()->GetEvent(ievt);
562  // int *idat = (int*)bufpos;
563  // log << MSG::WARNING << leaf->GetName() << ": " << ievt << " "
564  // << *idat << endmsg;
565 
566  // }
567  // }
568 
569  ts += isize;
570 
571  bufpos += isize;
572  }
573 
574  if ( totsize != ts ) {
575  log << MSG::ERROR << "buffer size mismatch: " << ts << " " << totsize << endmsg;
576  }
577 
578  refpObject = ntup;
579 
580  return StatusCode::SUCCESS;
581 }
582 
583 // Instantiation of a static factory class used by clients to create
584 // instances of this service
std::string getDirectory()
Definition: RConverter.cpp:153
virtual const std::string & name() const =0
Access _Item name.
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
virtual const ItemRange & range() const =0
Access the range if specified.
bool parseName(const std::string &full, std::string &blk, std::string &var)
Definition: RNTupleCnv.cpp:246
T to_string(T...args)
virtual StatusCode add(INTupleItem *item)=0
Add an item row to the N tuple.
T endl(T...args)
SmartIF< IMessageSvc > & msgSvc() const
Retrieve pointer to message service.
Definition: Converter.cpp:103
T cend(T...args)
Converter of Column-wise NTuple into ROOT format.
Definition: RCWNTupleCnv.h:21
StatusCode book(const std::string &desc, INTuple *pObject, TTree *&tree) override
Book the N tuple.
STL class.
NTuple interface class definition.
Definition: INTuple.h:82
virtual void reset()=0
Reset all entries to their default values.
T push_back(T...args)
virtual long ndim() const =0
Dimension.
NTuple interface class definition.
Definition: INTuple.h:27
virtual long length() const =0
Access the buffer length.
virtual const char * buffer() const =0
Access data buffer (CONST)
virtual StatusCode create(const CLID &typ, const std::string &title, NTuple::Tuple *&refpTuple)=0
Create requested N tuple (Hide constructor)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:28
StatusCode load(TTree *tree, INTuple *&refpObject) override
Create the transient representation of an object.
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:64
Abstract class describing basic data in an Ntuple.
Definition: NTuple.h:39
Abstract base class which allows the user to interact with the actual N tuple implementation.
Definition: NTuple.h:412
StatusCode readData(TTree *rtree, INTuple *pObject, long ievt) override
Read N tuple data.
T find(T...args)
size_t saveItem(char *target, const T *src, size_t len)
Definition: RCWNTupleCnv.h:42
#define DECLARE_NAMESPACE_CONVERTER_FACTORY(n, x)
Definition: Converter.h:177
T cbegin(T...args)
size_t loadItem(char *src, T *tar, size_t len)
Definition: RCWNTupleCnv.h:58
virtual char * setBuffer(char *buff)=0
Attach data buffer.
virtual const std::string & index() const =0
Access the index _Item.
T c_str(T...args)
T fill_n(T...args)
T substr(T...args)
virtual long dim(long i) const =0
Access individual dimensions.
virtual ItemContainer & items()=0
Access item container.
virtual bool hasIndex() const =0
Is the tuple have an index item?
SmartIF< INTupleSvc > m_ntupleSvc
Reference to N tuple service.
Definition: RNTupleCnv.h:60
virtual const std::string & title() const =0
Object title.
void analyzeItem(std::string typ, const NTuple::_Data< T > *it, std::string &desc, std::string &block_name, std::string &var_name, long &lowerRange, long &upperRange, long &size)
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
INTupleItem * createNTupleItem(std::string itemName, std::string blockName, std::string indexName, int indexRange, int arraySize, TYP min, TYP max, INTuple *ntup)
Definition: RNTupleCnv.cpp:273
virtual std::string rootVarType(int)
Return ROOT type info:
Definition: RNTupleCnv.cpp:209
StatusCode writeData(TTree *rtree, INTuple *pObject) override
Write N tuple data.
T emplace_back(T...args)