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