| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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