Gaudi Framework, version v23r5

Home   Generated: Wed Nov 28 2012
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
RootNTupleCnv.cpp
Go to the documentation of this file.
1 // $Id: RootNTupleCnv.cpp,v 1.13 2010-09-27 15:43:53 frankb Exp $
2 //------------------------------------------------------------------------------
3 //
4 // Implementation of class : RootNTupleCnv
5 //
6 // Author : Markus Frank
7 //
8 //------------------------------------------------------------------------------
9 
10 #define ALLOW_ALL_TYPES
11 // Include files
12 #include "RootCnv/RootRefs.h"
13 #include "RootCnv/RootAddress.h"
14 #include "RootCnv/RootNTupleCnv.h"
16 
17 #include "GaudiKernel/NTuple.h"
18 #include "GaudiKernel/SmartIF.h"
19 #include "GaudiKernel/SmartRef.h"
20 #include "GaudiKernel/INTupleSvc.h"
21 #include "GaudiKernel/IRegistry.h"
25 
26 // ROOT include files
27 #include "TROOT.h"
28 #include "TTree.h"
29 #include "TBranch.h"
30 #include "Reflex/Reflex.h"
31 
32 #include <limits>
33 #include <memory>
34 
35 #define S_OK StatusCode::SUCCESS
36 #define S_FAIL StatusCode::FAILURE
37 
38 using namespace Gaudi;
39 using namespace std;
40 
41 static inline istream& loadLong(istream& is) {
42  long i;
43  is >> i;
44  return is;
45 }
46 static inline istream& operator>>(istream& is, IOpaqueAddress*& /*pObj*/)
47 { return loadLong(is); }
48 
49 #if 0
50 static inline istream& operator>>(istream& is, SmartRef<DataObject>& /*pObj*/)
51 { return loadLong(is); }
52 static inline istream& operator>>(istream& is, SmartRef<ContainedObject>& /*pObj*/)
53 { return loadLong(is); }
54 static inline istream& operator>>(istream& is, string& /*pObj*/)
55 { return loadLong(is); }
56 #endif
57 
58 template<class TYP> static
59 StatusCode createItem ( TTree* tree, INTuple* tuple, istream& is,const string& name,bool add,const TYP& null) {
60  string idxName;
61  long len, ndim, dim[4], hasIdx, idxLow, idxLen;
62  long dim1 = 1, dim2 = 1;
63  INTupleItem* it = 0;
64  char c;
65  is >> len >> c
66  >> ndim >> c
67  >> hasIdx >> c;
68  if ( hasIdx ) {
69  getline(is, idxName, ';') >> idxLow >> c >> idxLen >> c;
70  }
71  for ( int i = 0; i < ndim; i++ )
72  is >> dim[i] >> c;
73 
74  TYP low = null, high = null;
75  is >> low >> c >> high >> c;
76  is >> c;
77  switch( ndim )
78  {
79  case 0:
80  it = NTuple::_Item<TYP>::create (tuple, name, typeid(TYP), low, high, null);
81  break;
82  case 1:
83  dim1 = (hasIdx) ? idxLen : dim[0];
84  it = NTuple::_Array<TYP>::create (tuple,
85  name,
86  typeid(TYP),
87  idxName,
88  dim1,
89  low,
90  high,
91  null);
92  break;
93  case 2:
94  dim1 = (hasIdx) ? idxLen : dim[0];
95  dim2 = (hasIdx) ? dim[0] : dim[1];
96  it = NTuple::_Matrix<TYP>::create ( tuple,
97  name,
98  typeid(TYP),
99  idxName,
100  dim1,
101  dim2,
102  low,
103  high,
104  null);
105  break;
106  default:
107  return S_FAIL;
108  }
109  if ( add ) {
110  TBranch* b = tree->GetBranch(it->name().c_str());
111  if ( b ) {
112  b->SetAddress((void*)it->buffer());
113  }
114  else {
115  //return StatusCode::SUCCESS;
116  return tuple->add(it);
117  }
118  }
119  return tuple->add(it);
120 }
121 
122 template <class T> static inline void putRange(ostream& os, NTuple::_Data<T>* it) {
123  const NTuple::Range<T>& x = it->range();
124  os << x.lower() << ';' << x.upper() << ';';
125 }
126 
127 static inline string _tr(const string& s) {
128  string local = s;
129  char* p = (char*)local.c_str();
130  if ( strncmp(p,"<local>",7)==0 ) p += 7;
131  for(;*p;++p)
132  if ( !isalnum(*p) ) *p = '_';
133  return local;
134 }
135 
136 // Converter overrides: Update the references of an updated transient object.
138 RootNTupleCnv::createObj(IOpaqueAddress* pAddr, DataObject*& refpObject) {
139  StatusCode status = S_FAIL;
140  RootDataConnection* con = 0;
141  IRegistry* pRegistry = pAddr->registry();
142  RootAddress* rpA = dynamic_cast<RootAddress*>(pAddr);
143  string path = fileName(pRegistry);
144  string cntName = containerName(pRegistry);
145  string* par = const_cast<string*>(pAddr->par());
146  status = m_dbMgr->connectDatabase(path,IDataConnection::READ,&con);
147  if ( status.isSuccess() ) {
148  string par_val, par_guid;
149  TBranch* b = con->getBranch("##Descriptors","GaudiStatisticsDescription");
150  if ( b ) {
153  b->SetAddress(&ptr);
154  for(Long64_t i=0, nent = b->GetEntries(); i<nent; ++i) {
155  int nb = b->GetEntry(i);
156  if ( nb > 1 ) {
157  if ( ptr->container == cntName ) {
158  par_val = ptr->description;
159  break;
160  }
161  }
162  }
163  }
164  par[2] = _tr(cntName);
165  TTree* tree = con->getSection(par[2]);
166  if ( 0 == tree ) {
167  return makeError("Failed to access N-Tuple tree:"+cntName);
168  }
169  if ( !par_val.empty() ) {
170  SmartIF<INTupleSvc> ntupleSvc(dataProvider());
171  if ( ntupleSvc.isValid() ) {
172  char c;
173  CLID clid;
174  int siz, typ;
175  string title;
176  NTuple::Tuple* nt = 0;
177  istringstream is(par_val);
178  getline(is, title, ';') >> clid >> c >> siz >> c;
179  status = ntupleSvc->create(clid, title, nt);
180  for ( int j = 0; j < siz && status.isSuccess(); j++ ) {
181  is >> c;
182  getline(is, title, ';') >> typ >> c;
183  switch ( typ )
184  {
185  case DataTypeInfo::UCHAR:
186  status = createItem(tree, nt, is, title, true, (unsigned char)0);
187  break;
189  status = createItem(tree, nt, is, title, true, (unsigned short)0);
190  break;
191  case DataTypeInfo::UINT:
192  status = createItem(tree, nt, is, title, true, (unsigned int)0);
193  break;
194  case DataTypeInfo::ULONG:
195  status = createItem(tree, nt, is, title, true, (unsigned long)0);
196  break;
197  case DataTypeInfo::CHAR:
198  status = createItem(tree, nt, is, title, true, char(0));
199  break;
200  case DataTypeInfo::SHORT:
201  status = createItem(tree, nt, is, title, true, short(0));
202  break;
203  case DataTypeInfo::INT:
204  status = createItem(tree, nt, is, title, true, int(0));
205  break;
206  case DataTypeInfo::LONG:
207  status = createItem(tree, nt, is, title, true, long(0));
208  break;
209  case DataTypeInfo::BOOL:
210  status = createItem(tree, nt, is, title, true, false);
211  break;
212  case DataTypeInfo::FLOAT:
213  status = createItem(tree, nt, is, title, true, float(0.0));
214  break;
216  status = createItem(tree, nt, is, title, true, double(0.0));
217  break;
218  /*
219  case DataTypeInfo::NTCHAR:
220  case DataTypeInfo::LONG_NTCHAR:
221  status =
222  createItem(tree, nt, is, title, true, (char*)0);
223  break;
224  case DataTypeInfo::STRING:
225  case DataTypeInfo::LONG_STRING:
226  status =
227  createItem(tree, nt, is, title, true, string(""));
228  break;
229  */
231  status = createItem(tree, nt, is, title, false, (IOpaqueAddress*)0);
232  break;
234  status = createItem(tree, nt, is, title, true, (void*)0);
235  break;
237  default:
238  status = S_FAIL;
239  break;
240  }
241  if ( !status.isSuccess() ) {
242  log() << MSG::FATAL
243  << "Error connecting (Unknown) column:" << j << endmsg
244  << par_val << endmsg;
245  return makeError("createObj[NTuple]> Cannot determine column!");
246  }
247  }
248  if ( status.isSuccess() ) {
249  unsigned long* ipar = const_cast<unsigned long*>(rpA->ipar());
250  log() << MSG::DEBUG << "Created N-tuple with description:"
251  << par_val << endl;
252  ipar[0] = (unsigned long)con;
253  ipar[1] = ~0x0UL;
254  rpA->section = tree;
255  refpObject = nt;
256  }
257  else {
258  refpObject = 0;
259  if ( nt ) nt->release();
260  }
261  }
262  }
263  }
264  return status;
265 }
266 
267 // Update the transient object: NTuples end here when reading records
268 StatusCode RootNTupleCnv::updateObj(IOpaqueAddress* pAddr, DataObject* pObj) {
269  INTuple* tupl = dynamic_cast<INTuple*>(pObj);
270  RootAddress* rpA = dynamic_cast<RootAddress*>(pAddr);
271  if ( 0 != tupl && 0 != rpA ) {
272  RootDataConnection* con = (RootDataConnection*)rpA->ipar()[0];
273  if ( con ) {
274  TTree* tree = rpA->section;
275  if ( tree ) {
276  con->resetAge();
277  if ( con->tool()->refs() )
278  return i__updateObjRoot(rpA,tupl,tree,con);
279 #ifdef __POOL_COMPATIBILITY
280  // POOL compatibility mode:
281  return i__updateObjPool(rpA,tupl,tree,con);
282 #else
283  return makeError("Failed to access reference branch for data tree:"+rpA->par()[1]);
284 #endif
285  }
286  return makeError("Failed to access data tree:"+pAddr->par()[1]);
287  }
288  return makeError("updateObj> Failed to access data source!");
289  }
290  return makeError("updateObj> Invalid Tuple reference.");
291 }
292 
293 // Update the transient object: NTuples end here when reading records
294 StatusCode RootNTupleCnv::i__updateObjRoot(RootAddress* rpA, INTuple* tupl, TTree* tree, RootDataConnection* con) {
295  typedef INTuple::ItemContainer Cont;
296  const string* par = rpA->par();
297  unsigned long* ipar = const_cast<unsigned long*>(rpA->ipar());
298  ++ipar[1];
299  if ( Long64_t(ipar[1]) <= tree->GetEntries() ) {
300  GenericAddress* pA = 0;
301  Cont& it = tupl->items();
302  size_t k, n = it.size();
303  vector<RootRef*> paddr(n);
304  vector<RootRef> addr(n);
305  for(k = 0; k < n; ++k) {
306  Cont::value_type j = it[k];
307  switch( j->type() )
308  {
310  paddr[k] = &addr[k];
311  tree->SetBranchAddress(j->name().c_str(),&paddr[k]);
312  break;
313  default:
314  break;
315  }
316  }
317 
318  ULong64_t last = (ULong64_t)tree->GetEntries();
319  ISelectStatement* sel = tupl->selector();
320  if ( sel ) {
321  string criteria = (sel && (sel->type() & ISelectStatement::STRING))
322  ? sel->criteria() : string("");
323  if ( !(criteria.length() == 0 || criteria == "*") ) {
324  if ( rpA->select == 0 ) {
325  log() << MSG::DEBUG << "Selection criteria: " << criteria << " " << ipar[1] << endmsg;
326  rpA->select = new TTreeFormula(tree->GetName(),criteria.c_str(), tree);
327  }
328  rpA->select->SetTree(tree);
329  for( ; ipar[1] < last; ++ipar[1]) { // loop on all selected entries
330  tree->LoadTree(ipar[1]);
331  rpA->select->GetNdata();
332  if ( fabs(rpA->select->EvalInstance(0)) > std::numeric_limits<float>::epsilon() ) {
333  break;
334  }
335  log() << MSG::DEBUG << par[0] << "/" << par[1] << " SKIP Entry: " << ipar[1] << endmsg;
336  }
337  }
338  }
339  if ( ipar[1] < last ) {
340  unsigned long entry = ipar[1];
341  if ( tree->GetEntry(entry) > 1 ) {
342  RootRef *r = 0;
343  string *spar = 0;
344  for(k = 0; k < n; ++k) {
345  Cont::value_type j = it[k];
346  switch( j->type() )
347  {
349  r = paddr[k];
350  pA = (*(GenericAddress**)j->buffer());
351  if ( pA ) { // Fill only if item is connected!
352  spar = (string*)pA->par();
353  ipar = (unsigned long*)pA->ipar();
354  log() << MSG::DEBUG;
356  if ( ls.first ) {
357  if ( ls.first->dbase >= 0 ) {
358  // Now patch the references and links 'en block' to be efficient
359  // First the leafs from the TES
360 
361  r->dbase += ls.first->dbase;
362  r->container += ls.first->container;
363  r->link += ls.first->link;
364 
365  if ( log().isActive() ) {
366  log() << "Refs: LS [" << entry << "] -> "
367  << ls.first->dbase << "," << ls.first->container
368  << "," << ls.first->link
369  << "," << ls.first->entry
370  << " DB:" << con->getDb(r->dbase)
371  << endmsg;
372  }
373  }
374  }
375  spar[0] = con->getDb(r->dbase);
376  spar[1] = con->getCont(r->container);
377  spar[2] = con->getLink(r->link);
378  ipar[0] = 0;
379  ipar[1] = r->entry;
380  pA->setClID(r->clid);
381  pA->setSvcType(r->svc);
382  break;
383  }
384  break;
385  default:
386  break;
387  }
388  }
389  return StatusCode::SUCCESS;
390  }
391  log() << MSG::ERROR << "Failed to read data from NTuple tree." << endmsg;
392  return StatusCode::FAILURE;
393  }
394  log() << MSG::INFO << "End of input Ntuple." << endmsg;
395  return StatusCode::FAILURE;
396  }
397  return StatusCode::FAILURE;
398 }
399 
401 StatusCode RootNTupleCnv::createRep(DataObject* pObj, IOpaqueAddress*& pAddr) {
402  IRegistry* pRegistry = pObj->registry();
403  if ( 0 != pRegistry ) {
404  pAddr = pRegistry->address();
405  if ( 0 != pAddr ) {
406  return S_OK;
407  }
408 
409  RootDataConnection* con = 0;
410  string path = fileName(pRegistry);
411  string cntName = containerName(pRegistry);
412  string secName = cntName.c_str();
413  const INTuple* nt = dynamic_cast<const INTuple*>(pObj);
414  StatusCode status = m_dbMgr->connectDatabase(path, IDataConnection::UPDATE, &con);
415  if ( !status.isSuccess() ) {
416  return makeError("Failed to access Tuple file:"+path);
417  }
418  TTree* tree = con->getSection(_tr(secName),true);
419  if ( 0 != nt ) {
420  const INTuple::ItemContainer& items = nt->items();
421  ostringstream os;
422  size_t item_no;
423  string desc;
424  os << nt->title()<<';'<<pObj->clID()<<';'<<items.size()<< ';';
425  map<string,TBranch*> branches;
426  TBranch* b = 0;
427  for(item_no = 0; item_no < items.size(); ++item_no ) {
428  INTupleItem* it = items[item_no];
429  if ( it->hasIndex() ) {
430  INTupleItem* itm = it->indexItem();
431  const string& n = itm->name();
432  switch( itm->type() )
433  {
434  case DataTypeInfo::UCHAR:
435  desc = n+"/b";
436  b = tree->Branch(n.c_str(),(void*)itm->buffer(),desc.c_str());
437  break;
439  desc = n+"/s";
440  b = tree->Branch(n.c_str(),(void*)itm->buffer(),desc.c_str());
441  break;
442  case DataTypeInfo::UINT:
443  desc = n+"/i";
444  b = tree->Branch(n.c_str(),(void*)itm->buffer(),desc.c_str());
445  break;
446  case DataTypeInfo::ULONG:
447  desc = n+"/l";
448  b = tree->Branch(n.c_str(),(void*)itm->buffer(),desc.c_str());
449  break;
450  case DataTypeInfo::CHAR:
451  desc = n+"/B";
452  b = tree->Branch(n.c_str(),(void*)itm->buffer(),desc.c_str());
453  break;
454  case DataTypeInfo::SHORT:
455  desc = n+"/S";
456  b = tree->Branch(n.c_str(),(void*)itm->buffer(),desc.c_str());
457  break;
458  case DataTypeInfo::INT:
459  desc = n+"/I";
460  b = tree->Branch(n.c_str(),(void*)itm->buffer(),desc.c_str());
461  break;
462  case DataTypeInfo::LONG:
463  desc = n+"/L";
464  b = tree->Branch(n.c_str(),(void*)itm->buffer(),desc.c_str());
465  break;
466  default:
467  return makeError("Column "+it->index()+" is not a valid index column!");
468  }
469  branches[n] = b;
470  }
471  }
472  for(item_no = 0; item_no < items.size(); ++item_no ) {
473  INTupleItem* it = items[item_no];
474  const string& n = it->name();
475  os << '{'
476  << n << ';'
477  << it->type() << ';'
478  << it->length() << ';'
479  << it->ndim() << ';'
480  << it->hasIndex() << ';';
481  if ( it->hasIndex() ) {
482  os << it->index() << ';';
483  INTupleItem* itm = it->indexItem();
484  switch( itm->type() )
485  {
486  case DataTypeInfo::UCHAR:
487  putRange(os, dynamic_cast<NTuple::_Data<unsigned char>*>(itm));
488  break;
490  putRange(os, dynamic_cast<NTuple::_Data<unsigned short>*>(itm));
491  break;
492  case DataTypeInfo::UINT:
493  putRange(os, dynamic_cast<NTuple::_Data<unsigned int>*>(itm));
494  break;
495  case DataTypeInfo::ULONG:
496  putRange(os, dynamic_cast<NTuple::_Data<unsigned long>*>(itm));
497  break;
498  case DataTypeInfo::CHAR:
499  putRange(os, dynamic_cast<NTuple::_Data<char>*>(itm));
500  break;
501  case DataTypeInfo::SHORT:
502  putRange(os, dynamic_cast<NTuple::_Data<short>*>(itm));
503  break;
504  case DataTypeInfo::INT:
505  putRange(os, dynamic_cast<NTuple::_Data<int>*>(itm));
506  break;
507  case DataTypeInfo::LONG:
508  putRange(os, dynamic_cast<NTuple::_Data<long>*>(itm));
509  break;
510  default:
511  return makeError("NTuple:"+pRegistry->name()+" Column "+it->index()+
512  " is not a valid index column!");
513  }
514  }
515  for ( long k = 0; k < it->ndim(); k++ ) {
516  os << it->dim(k) << ';';
517  }
518  desc = n;
519  TClass* cl = 0;
520  switch(it->type())
521  {
523  desc = "/C";
524  os << 0 << ';' << 0 << ';';
525  break;
527  desc = "/C";
528  os << 0 << ';' << 0 << ';';
529  break;
531  if ( it->length() == 1 ) {
532  desc = System::typeinfoName(typeid(RootRef));
533  os << 0 << ';' << 0 << ';';
534  cl = gROOT->GetClass(desc.c_str(),kTRUE);
535  }
536  break;
538  if ( it->length() == 1 ) {
539  ROOT::Reflex::Type typ = ROOT::Reflex::Type::ByName(it->typeName());
540  desc = typ.Name(ROOT::Reflex::SCOPED);
541  os << 0 << ';' << 0 << ';';
542  cl = gROOT->GetClass(desc.c_str(),kTRUE);
543  }
544  break;
545  case DataTypeInfo::UCHAR:
546  desc = "/b";
547  putRange(os, dynamic_cast<NTuple::_Data<unsigned char>*>(it));
548  break;
550  desc = "/s";
551  putRange(os, dynamic_cast<NTuple::_Data<unsigned short>*>(it));
552  break;
553  case DataTypeInfo::UINT:
554  desc = "/i";
555  putRange(os, dynamic_cast<NTuple::_Data<unsigned int>*>(it));
556  break;
557  case DataTypeInfo::ULONG:
558  desc = "/l";
559  putRange(os, dynamic_cast<NTuple::_Data<unsigned long>*>(it));
560  break;
561  case DataTypeInfo::CHAR:
562  desc = "/B";
563  putRange(os, dynamic_cast<NTuple::_Data<char>*>(it));
564  break;
565  case DataTypeInfo::SHORT:
566  desc = "/S";
567  putRange(os, dynamic_cast<NTuple::_Data<short>*>(it));
568  break;
569  case DataTypeInfo::INT:
570  desc = "/I";
571  putRange(os, dynamic_cast<NTuple::_Data<int>*>(it));
572  break;
573  case DataTypeInfo::LONG:
574  desc = "/L";
575  putRange(os, dynamic_cast<NTuple::_Data<long>*>(it));
576  break;
577  case DataTypeInfo::BOOL:
578  desc = "/b";
579  putRange(os, dynamic_cast<NTuple::_Data<bool>*>(it));
580  break;
581  case DataTypeInfo::FLOAT:
582  desc = "/F";
583  putRange(os, dynamic_cast<NTuple::_Data<float>*>(it));
584  break;
586  desc = "/D";
587  putRange(os, dynamic_cast<NTuple::_Data<double>*>(it));
588  break;
590  default:
591  return makeError("Create item[FAIL]: "+it->name());
592  }
593  os << '}';
594  if ( branches.find(n) == branches.end() ) {
595  string tmp;
596  char text[32];
597  switch(it->ndim())
598  {
599  case 0:
600  desc = n+desc;
601  break;
602  case 2:
603  sprintf(text,"[%ld]",it->dim(0));
604  tmp = text;
605  case 1:
606  if ( it->hasIndex() ) {
607  INTupleItem* itm = it->indexItem();
608  desc = n + tmp + "[" + itm->name() + "]" + desc;
609  }
610  else {
611  sprintf(text,"[%ld]",it->dim(0));
612  desc = n + tmp + text + desc;
613  }
614  }
615  log() << MSG::DEBUG << "Create branch:" << n << " Desc:" << desc
616  << " of type:" << it->type() << endmsg;
617  switch(it->type())
618  {
620  branches[n] = tree->Branch(n.c_str(),cl->GetName(),(void*)it->buffer());
621  break;
623  branches[n] = tree->Branch(n.c_str(),cl->GetName(),(void*)it->buffer());
624  break;
625  default:
626  branches[n] = tree->Branch(n.c_str(),(void*)it->buffer(),desc.c_str());
627  break;
628  }
629  }
630  }
631 
632  log() << MSG::DEBUG << "Save description:" << path << " -> " << cntName << endmsg
633  << os.str() << endmsg;
634  status = saveDescription(path,cntName,os.str(),"",pObj->clID());
635  if ( status.isSuccess() ) {
636  status = m_dbMgr->commitOutput(path, true);
637  if ( status.isSuccess() ) {
638  string spar[] = { path, cntName};
639  unsigned long ipar[] = { (unsigned long)con, ~0x0 };
640  status = m_dbMgr->createAddress(repSvcType(),pObj->clID(),spar,ipar,pAddr);
641  if ( status.isSuccess() ) {
642  RootAddress* rpA = dynamic_cast<RootAddress*>(pAddr);
643  ((unsigned long*)rpA->ipar())[0] = (unsigned long)con;
644  rpA->section = tree;
645  }
646  else {
647  pAddr->release();
648  pAddr = 0;
649  }
650  }
651  }
652  return status;
653  }
654  }
655  return S_FAIL;
656 }
657 
658 // Resolve the references of the converted object.
659 StatusCode RootNTupleCnv::fillRepRefs(IOpaqueAddress* pAddr, DataObject* pObj) {
660  typedef INTuple::ItemContainer Cont;
661  INTuple* tupl = dynamic_cast<INTuple*>(pObj);
662  IRegistry* pReg = pObj->registry();
663  RootAddress* rpA = dynamic_cast<RootAddress*>(pAddr);
664  if ( tupl && pReg && rpA ) {
665  string cntName = containerName(pReg);
666  unsigned long* ipar = const_cast<unsigned long*>(pAddr->ipar());
667  RootDataConnection* con = (RootDataConnection*)rpA->ipar()[0];
668  if ( con ) {
669  TTree* tree = rpA->section;
670  if ( tree ) {
671  Cont& it = tupl->items();
672  size_t k, n = it.size();
673  vector<RootRef*> paddr(n);
674  vector<RootRef> addr(n);
675  for(k = 0; k < n; ++k) {
676  IOpaqueAddress* pA = 0;
677  Cont::value_type j = it[k];
678  switch( j->type() )
679  {
681  pA = (*(IOpaqueAddress**)j->buffer());
682  paddr[k] = &addr[k];
683  addr[k].reset();
684  if ( pA ) {
685  con->makeRef(pA->registry(),addr[k]);
686  addr[k].entry = pA->ipar()[1];
687  }
688  tree->SetBranchAddress(j->name().c_str(),&paddr[k]);
689  break;
690  default:
691  break;
692  }
693  }
694  int nb = tree->Fill();
695  if ( nb>1 ) ++ipar[1];
696  for(k = 0; k < n; ++k) it[k]->reset();
698  }
699  return makeError("fillRepRefs> Failed to access data tree:"+cntName);
700  }
701  return makeError("fillRepRefs> Failed to access data source!");
702  }
703  return makeError("fillRepRefs> Invalid Tuple reference.");
704 }
705 
706 #ifdef __POOL_COMPATIBILITY
707 #include "PoolClasses.h"
708 
709 // Compatibility code to access ETCs, which were written using POOL
710 
711 namespace {
712  // Blob I/O helper class
713  class IOBuffer : public StreamBuffer {
714  public:
715  UCharDbArray d;
716  IOBuffer() : StreamBuffer() { }
717  virtual ~IOBuffer() { m_pointer=0; m_length=0; m_buffer=0;}
718  void start() {m_pointer=0; m_buffer=(char*)d.m_buffer; m_length=d.m_size;}
719  };
720 }
721 
722 // Helper to read
723 template <class T> static inline int load(int blob, IOBuffer& s, void* buff) {
724  if ( blob ) {
725  int len;
726  s >> len;
727  s.swapFromBuffer(buff, len*sizeof(T));
728  }
729  return 0;
730 }
731 
732 // Helper to read specialized for strings
733 template <> inline int load<string>(int blob, IOBuffer& s, void* ptr) {
734  if ( blob ) {
735  string* str = (string*)ptr;
736  s >> (*str);
737  }
738  return 0;
739 }
740 
741 // Update the transient object: NTuples end here when reading records
742 StatusCode RootNTupleCnv::i__updateObjPool(RootAddress* rpA, INTuple* tupl, TTree* tree, RootDataConnection* con) {
743  typedef INTuple::ItemContainer Cont;
744  const string* par = rpA->par();
745  unsigned long* ipar = const_cast<unsigned long*>(rpA->ipar());
746  ++ipar[1];
747  if ( Long64_t(ipar[1]) <= tree->GetEntries() ) {
748  Cont& it = tupl->items();
749  size_t k, n = it.size();
750  vector<PoolDbTokenWrap*> paddr(n);
751  vector<PoolDbTokenWrap> addr(n);
752  vector<int> blob_items(n,0);
753  for(k = 0; k < n; ++k) {
754  Cont::value_type j = it[k];
755  switch( j->type() )
756  {
758  paddr[k] = &addr[k];
759  tree->SetBranchAddress(j->name().c_str(),&paddr[k]);
760  break;
761  default:
762  if ( 0 == tree->GetBranch(j->name().c_str()) ) blob_items[k] = 1;
763  break;
764  }
765  }
766  ULong64_t last = (ULong64_t)tree->GetEntries();
767  ISelectStatement* sel = tupl->selector();
768  if ( sel ) {
769  string criteria = (sel && (sel->type() & ISelectStatement::STRING))
770  ? sel->criteria() : string("");
771  if ( !(criteria.length() == 0 || criteria == "*") ) {
772  if ( rpA->select == 0 ) {
773  log() << MSG::DEBUG << "Selection criteria: " << criteria << " " << ipar[1] << endmsg;
774  rpA->select = new TTreeFormula(tree->GetName(),criteria.c_str(), tree);
775  }
776  rpA->select->SetTree(tree);
777  // loop on all selected entries
778  for( ; ipar[1] < last; ++ipar[1]) {
779  tree->LoadTree(ipar[1]);
780  rpA->select->GetNdata();
781  if ( fabs(rpA->select->EvalInstance(0)) > std::numeric_limits<float>::epsilon() ) {
782  break;
783  }
784  log() << MSG::DEBUG << par[0] << "/" << par[1] << " SKIP Entry: " << ipar[1] << endmsg;
785  }
786  }
787  }
788  if ( ipar[1] < last ) {
789  IOBuffer blob;
790  UCharDbArray *pblob = &blob.d;
791  tree->GetBranch("BlobData")->SetAddress(&pblob);
792  if ( tree->GetEntry(ipar[1]) > 1 ) {
793  int sc = 0;
794  blob.start();
795  for(k = 0; k < n; ++k) {
796  Cont::value_type j = it[k];
797  char* buf = (char*)j->buffer();
798  switch( j->type() )
799  {
801  RootRef r = con->tool()->poolRef(addr[k].token.m_oid.first);
802  GenericAddress* pA = (*(GenericAddress**)buf);
803  if ( pA ) { // Fill only if item is connected!
804  string *spar = (string*)pA->par();
805  ipar = (unsigned long*)pA->ipar();
806  spar[0] = con->getDb(r.dbase);
807  spar[1] = con->getCont(r.container);
808  spar[2] = con->getLink(r.link);
809  ipar[0] = 0;
810  ipar[1] = addr[k].token.m_oid.second;
811  if ( r.svc == POOL_ROOT_StorageType ||
814  r.svc = ROOT_StorageType;
815  }
816  pA->setClID(r.clid);
817  pA->setSvcType(r.svc);
818  break;
819  }
820  sc = 11;
821  break;
822  }
823  case DataTypeInfo::UCHAR: sc=load<unsigned char> (blob_items[k],blob,buf); break;
824  case DataTypeInfo::USHORT: sc=load<unsigned short>(blob_items[k],blob,buf); break;
825  case DataTypeInfo::UINT: sc=load<unsigned int> (blob_items[k],blob,buf); break;
826  case DataTypeInfo::ULONG: sc=load<unsigned long> (blob_items[k],blob,buf); break;
827  case DataTypeInfo::CHAR: sc=load<char> (blob_items[k],blob,buf); break;
828  case DataTypeInfo::SHORT: sc=load<short> (blob_items[k],blob,buf); break;
829  case DataTypeInfo::INT: sc=load<int> (blob_items[k],blob,buf); break;
830  case DataTypeInfo::LONG: sc=load<long> (blob_items[k],blob,buf); break;
831  case DataTypeInfo::BOOL: sc=load<bool> (blob_items[k],blob,buf); break;
832  case DataTypeInfo::FLOAT: sc=load<float> (blob_items[k],blob,buf); break;
833  case DataTypeInfo::DOUBLE: sc=load<double> (blob_items[k],blob,buf); break;
834  case DataTypeInfo::STRING: sc=load<string> (blob_items[k],blob,buf); break;
835  case DataTypeInfo::NTCHAR: sc=load<char*> (blob_items[k],blob,buf); break;
836  case DataTypeInfo::POINTER: sc = 0; break;
837  case DataTypeInfo::UNKNOWN: break;
838  default: break;
839  }
840  if ( 0 != sc ) {
841  log() << MSG::DEBUG;
842  switch (sc)
843  {
844  case 10:
845  log() << "CANNOT Set Ntuple token: dynamic_cast<GenericAddress*> is NULL";
846  break;
847  case 11:
848  log() << "CANNOT Set Ntuple token: invalid address buffer";
849  break;
850  }
851  log() << endmsg;
852  }
853  }
854  return StatusCode::SUCCESS;
855  }
856  log() << MSG::ERROR << "Failed to read data from NTuple tree." << endmsg;
857  return StatusCode::FAILURE;
858  }
859  log() << MSG::INFO << "End of input Ntuple." << endmsg;
860  return StatusCode::FAILURE;
861  }
862  return StatusCode::FAILURE;
863 }
864 #endif

Generated at Wed Nov 28 2012 12:17:19 for Gaudi Framework, version v23r5 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004