Gaudi Framework, version v24r2

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

Generated at Wed Dec 4 2013 14:33:12 for Gaudi Framework, version v24r2 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004