All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
RootDataConnection.cpp
Go to the documentation of this file.
1 // $Id: RootDataConnection.cpp,v 1.16 2010-09-27 15:43:53 frankb Exp $
2 //====================================================================
3 // RootDataConnection.cpp
4 //--------------------------------------------------------------------
5 //
6 // Author : M.Frank
7 //====================================================================
8 // $Header: /afs/cern.ch/project/cvs/reps/lhcb/Online/RootCnv/src/RootDataConnection.cpp,v 1.16 2010-09-27 15:43:53 frankb Exp $
9 
10 // Framework include files
12 #include "RootUtils.h"
16 #include "GaudiKernel/strcasecmp.h"
17 #include "GaudiKernel/DataObject.h"
18 #include "GaudiKernel/IRegistry.h"
19 #include "GaudiKernel/Incident.h"
20 #include "GaudiKernel/MsgStream.h"
21 // ROOT include files
22 #include "TROOT.h"
23 #include "TFile.h"
24 #include "TTree.h"
25 #include "TLeaf.h"
26 #include "TClass.h"
27 #include "TBranch.h"
28 #include "TTreePerfStats.h"
29 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,33,0)
30 #include "Compression.h"
31 static int s_compressionLevel = ROOT::CompressionSettings(ROOT::kLZMA,6);
32 #else
33 static int s_compressionLevel = 1;
34 #endif
35 
36 // C/C++ include files
37 #include <stdexcept>
38 
39 using namespace Gaudi;
40 using namespace std;
41 typedef const string& CSTR;
42 
43 static string s_empty;
44 static string s_local = "<localDB>";
45 
46 #ifdef __POOL_COMPATIBILITY
47 #include "PoolTool.h"
48 #endif
49 #include "RootTool.h"
50 
51 static bool match_wild(const char *str, const char *pat) {
52  //
53  // Credits: Code from Alessandro Felice Cantatore.
54  //
55  static char table[256];
56  static bool first = true;
57  const char *s, *p;
58  bool star = false;
59  if ( first ) {
60  for (int i = 0; i < 256; ++i) table[i] = char(i);
61  first = false;
62  }
63 loopStart:
64  for (s = str, p = pat; *s; ++s, ++p) {
65  switch (*p) {
66  case '?':
67  if (*s == '.') goto starCheck;
68  break;
69  case '*':
70  star = true;
71  str = s, pat = p;
72  do { ++pat; } while (*pat == '*');
73  if (!*pat) return true;
74  goto loopStart;
75  default:
76  if ( *(table+*s) != *(table+*p) )
77  goto starCheck;
78  break;
79  } /* endswitch */
80  } /* endfor */
81  while (*p == '*') ++p;
82  return (!*p);
83 
84 starCheck:
85  if (!star) return false;
86  str++;
87  goto loopStart;
88 }
89 
91 RootConnectionSetup::RootConnectionSetup() : refCount(1), m_msgSvc(0), m_incidentSvc(0)
92 {
93 }
94 
98  m_incidentSvc = 0;
99  deletePtr(m_msgSvc);
100 }
101 
103 long RootConnectionSetup::setCompression(const std::string& compression) {
104 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,33,0)
105  int res = 0, level = ROOT::CompressionSettings(ROOT::kLZMA,6);
106  size_t idx = compression.find(':');
107  if ( idx != string::npos ) {
108  string alg = compression.substr(0,idx);
109  ROOT::ECompressionAlgorithm alg_code = ROOT::kUseGlobalSetting;
110  if ( strcasecmp(alg.c_str(),"ZLIB") == 0 )
111  alg_code = ROOT::kZLIB;
112  else if ( strcasecmp(alg.c_str(),"LZMA") == 0 )
113  alg_code = ROOT::kLZMA;
114  else
115  throw runtime_error("ERROR: request to set unknown ROOT compression algorithm:"+alg);
116  res = ::sscanf(compression.c_str()+idx+1,"%d",&level);
117  if ( res == 1 ) {
118  s_compressionLevel = ROOT::CompressionSettings(alg_code,level);
119  return StatusCode::SUCCESS;
120  }
121  throw runtime_error("ERROR: request to set unknown ROOT compression level:"+compression.substr(idx+1));
122  }
123  else if ( 1==::sscanf(compression.c_str(),"%d",&level) ) {
124  s_compressionLevel = level;
125  return StatusCode::SUCCESS;
126  }
127  throw runtime_error("ERROR: request to set unknown ROOT compression mechanism:"+compression);
128 #else
129  if ( !compression.empty() ) {}
130  return StatusCode::SUCCESS;
131 #endif
132 }
133 
136  return s_compressionLevel;
137 }
138 
141  ++refCount;
142 }
143 
146  int tmp = --refCount;
147  if ( tmp <= 0 ) {
148  delete this;
149  }
150 }
151 
154  MsgStream* tmp = m_msgSvc;
155  m_msgSvc = m;
156  deletePtr(tmp);
157 }
158 
162  m_incidentSvc = s;
164  if ( tmp ) tmp->release();
165 }
166 
169  : IDataConnection(owner,fname), m_setup(setup), m_statistics(0), m_tool(0)
170 { // 01234567890123456789012345678901234567890
171  // Check if FID: A82A3BD8-7ECB-DC11-8DC0-000423D950B0
172  if ( fname.length() == 36 && fname[8]=='-'&&fname[13]=='-'&&fname[18]=='-'&&fname[23]=='-' ) {
173  m_name = "FID:"+fname;
174  }
175  m_setup->addRef();
176  m_age = 0;
177  m_file = 0;
178  m_refs = 0;
179  addClient(owner);
180 }
181 
184  m_setup->release();
185  releasePtr(m_tool);
186 }
187 
190  m_clients.insert(client);
191 }
192 
195  Clients::iterator i=m_clients.find(client);
196  if ( i != m_clients.end() ) m_clients.erase(i);
197  return m_clients.size();
198 }
199 
201 bool RootDataConnection::lookupClient(const IInterface* client) const {
202  Clients::const_iterator i=m_clients.find(client);
203  return i != m_clients.end();
204 }
205 
207 void RootDataConnection::badWriteError(const string& msg) const {
208  msgSvc() << MSG::ERROR << "File:" << fid() << "Failed action:" << msg << endmsg;
209 }
210 
213  if ( m_statistics ) {
214  m_statistics->Print();
215  if ( !statisticsFile.empty() )
216  m_statistics->SaveAs(statisticsFile.c_str());
217  deletePtr(m_statistics);
218  }
219 }
220 
223  if ( 0 == m_statistics ) {
224  TTree* t=getSection(section,false);
225  if ( t ) {
226  m_statistics = new TTreePerfStats((section+"_ioperf").c_str(),t);
227  return;
228  }
229  msgSvc() << MSG::WARNING << "Failed to enable perfstats for tree:" << section << endmsg;
230  return;
231  }
232  msgSvc() << MSG::INFO << "Perfstats are ALREADY ENABLED." << endmsg;
233 }
234 
237  releasePtr(m_tool);
238  if ( !m_refs ) m_refs = (TTree*)m_file->Get("Refs");
239  if ( m_refs )
240  m_tool = new RootTool(this);
241 #ifdef __POOL_COMPATIBILITY
242  else if ( m_file->Get("##Links") != 0 )
243  m_tool = new PoolTool(this);
244 #endif
245  return m_tool;
246 }
247 
250  m_file = TFile::Open(m_pfn.c_str());
251  if ( m_file && !m_file->IsZombie() ) {
253  msgSvc() << MSG::DEBUG << "Opened file " << m_pfn << " in mode READ. [" << m_fid << "]" << endmsg << MSG::DEBUG;
254  if ( msgSvc().isActive() ) m_file->ls();
255  msgSvc() << MSG::VERBOSE;
256  if ( msgSvc().isActive() ) m_file->Print();
257  if ( makeTool() ) {
258  sc = m_tool->readRefs();
259  sc.ignore();
260 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,33,0)
261  if ( sc.getCode() == ROOT_READ_ERROR ) {
262  IIncidentSvc* inc = m_setup->incidentSvc();
263  if ( inc ) {
265  }
266  }
267 #endif
268  }
269  if ( sc.isSuccess() ) {
270  bool need_fid = m_fid == m_pfn;
271  string fid = m_fid;
272  m_mergeFIDs.clear();
273  for(size_t i=0, n=m_params.size(); i<n; ++i) {
274  if ( m_params[i].first == "FID" ) {
275  m_mergeFIDs.push_back(m_params[i].second);
276  if ( m_params[i].second != m_fid ) {
277  msgSvc() << MSG::DEBUG << "Check FID param:" << m_params[i].second << endmsg;
278  //if ( m_fid == m_pfn ) {
279  m_fid = m_params[i].second;
280  //}
281  }
282  }
283  }
284  if ( !need_fid && fid != m_fid ) {
285  msgSvc() << MSG::ERROR << "FID mismatch:" << fid << "(Catalog) != " << m_fid << "(file)" << endmsg
286  << "for PFN:" << m_pfn << endmsg;
287  return StatusCode::FAILURE;
288  }
289  msgSvc() << MSG::DEBUG << "Using FID " << m_fid << " from params table...." << endmsg
290  << "for PFN:" << m_pfn << endmsg;
291  return sc;
292  }
293  }
294  else if ( m_file ) {
295  deletePtr(m_file);
296  }
297  return StatusCode::FAILURE;
298 }
299 
302  int compress = RootConnectionSetup::compression();
303  msgSvc() << MSG::DEBUG;
304  switch(typ) {
305  case CREATE:
306  resetAge();
307  m_file = TFile::Open(m_pfn.c_str(),"CREATE","Root event data",compress);
308  m_refs = new TTree("Refs","Root reference data");
309  msgSvc() << "Opened file " << m_pfn << " in mode CREATE. [" << m_fid << "]" << endmsg;
310  m_params.push_back(make_pair("PFN",m_pfn));
311  if ( m_fid != m_pfn ) {
312  m_params.push_back(make_pair("FID",m_fid));
313  }
314  makeTool();
315  break;
316  case RECREATE:
317  resetAge();
318  m_file = TFile::Open(m_pfn.c_str(),"RECREATE","Root event data",compress);
319  msgSvc() << "Opened file " << m_pfn << " in mode RECREATE. [" << m_fid << "]" << endmsg;
320  m_refs = new TTree("Refs","Root reference data");
321  m_params.push_back(make_pair("PFN",m_pfn));
322  if ( m_fid != m_pfn ) {
323  m_params.push_back(make_pair("FID",m_fid));
324  }
325  makeTool();
326  break;
327  case UPDATE:
328  resetAge();
329  m_file = TFile::Open(m_pfn.c_str(),"UPDATE","Root event data",compress);
330  msgSvc() << "Opened file " << m_pfn << " in mode UPDATE. [" << m_fid << "]" << endmsg;
331  if ( m_file && !m_file->IsZombie() ) {
332  if ( makeTool() ) {
334  sc.ignore();
335  if ( sc.getCode() == ROOT_READ_ERROR ) {
336 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,33,0)
337  IIncidentSvc* inc = m_setup->incidentSvc();
338  if ( inc ) {
340  }
341 #endif
342  }
343  return sc;
344  }
345  TDirectory::TContext ctxt(m_file);
346  m_refs = new TTree("Refs","Root reference data");
347  makeTool();
348  return StatusCode::SUCCESS;
349  }
350  break;
351  default:
352  m_refs = 0;
353  m_file = 0;
354  return StatusCode::FAILURE;
355  }
357 }
358 
361  if ( m_file ) {
362  if ( !m_file->IsZombie() ) {
363  if ( m_file->IsWritable() ) {
364  msgSvc() << MSG::DEBUG;
365  TDirectory::TContext ctxt(m_file);
366  if ( m_refs ) {
367  if ( !m_tool->saveRefs().isSuccess() ) badWriteError("Saving References");
368  if ( m_refs->Write() < 0 ) badWriteError("Write Reference branch");
369  }
370  for(Sections::iterator i=m_sections.begin(); i!= m_sections.end();++i) {
371  if ( (*i).second ) {
372  if ( (*i).second->Write() < 0 ) badWriteError("Write section:"+(*i).first);
373  msgSvc() << "Disconnect section " << (*i).first << " " << (*i).second->GetName() << endmsg;
374  }
375  }
376  m_sections.clear();
377  }
378  msgSvc() << MSG::DEBUG;
379  if ( msgSvc().isActive() ) m_file->ls();
380  msgSvc() << MSG::VERBOSE;
381  if ( msgSvc().isActive() ) m_file->Print();
382  m_file->Close();
383  }
384  msgSvc() << MSG::DEBUG << "Disconnected file " << m_pfn << " " << m_file->GetName() << endmsg;
385  deletePtr(m_file);
386  releasePtr(m_tool);
387  }
388  return StatusCode::SUCCESS;
389 }
390 
392 TTree* RootDataConnection::getSection(CSTR section, bool create) {
393  TTree* t = m_sections[section];
394  if ( !t ) {
395  t = (TTree*)m_file->Get(section.c_str());
396  if ( !t && create ) {
397  TDirectory::TContext ctxt(m_file);
398  t = new TTree(section.c_str(),"Root data for Gaudi");
399  }
400  if ( t ) {
401  int cacheSize = m_setup->cacheSize;
402  if ( create ) {
403  //t->SetAutoFlush(100);
404  }
405  if ( section == m_setup->loadSection && cacheSize>-2 ) {
406  MsgStream& msg = msgSvc();
407  int learnEntries = m_setup->learnEntries;
408  t->SetCacheSize(cacheSize);
409  t->SetCacheLearnEntries(learnEntries);
410  msg << MSG::DEBUG;
411  if ( create ) {
412  msg << "Tree:" << section << "Setting up tree cache:" << cacheSize << endmsg;
413  }
414  else {
415  const StringVec& vB = m_setup->vetoBranches;
416  const StringVec& cB = m_setup->cacheBranches;
417  msg << "Tree:" << section << " Setting up tree cache:" << cacheSize << " Add all branches." << endmsg;
418  msg << "Tree:" << section << " Learn for " << learnEntries << " entries." << endmsg;
419 
420  if ( cB.size()==0 && vB.size()== 0 ) {
421  msg << "Adding (default) all branches to tree cache." << endmsg;
422  t->AddBranchToCache("*",kTRUE);
423  }
424  if ( cB.size()==1 && cB[0]=="*" ) {
425  msg << "Adding all branches to tree cache according to option \"CacheBranches\"." << endmsg;
426  t->AddBranchToCache("*",kTRUE);
427  }
428  else {
429  StringVec::const_iterator i;
430  for(TIter it(t->GetListOfBranches()); it.Next(); ) {
431  const char* n = ((TNamed*)(*it))->GetName();
432  bool add = false, veto = false;
433  for(i=cB.begin(); i != cB.end();++i) {
434  if ( !match_wild(n,(*i).c_str()) ) continue;
435  add = true;
436  break;
437  }
438  for(i=vB.begin(); !add && i!=vB.end();++i) {
439  if ( !match_wild(n,(*i).c_str()) ) continue;
440  veto = true;
441  break;
442  }
443  if ( add && !veto ) {
444  msg << "Add " << n << " to branch cache." << endmsg;
445  t->AddBranchToCache(n,kTRUE);
446  }
447  else {
448  msg << "Do not cache branch " << n << endmsg;
449  }
450  }
451  }
452  }
453  }
454  m_sections[section] = t;
455  }
456  }
457  return t;
458 }
459 
461 TBranch* RootDataConnection::getBranch(CSTR section, CSTR branch_name, TClass* cl, void* ptr, int buff_siz, int split_lvl) {
462  string n = branch_name+".";
463  for(int i=0, m=n.length()-1; i<m; ++i) if ( !isalnum(n[i]) ) n[i]='_';
464  TTree* t = getSection(section,true);
465  TBranch* b = t->GetBranch(n.c_str());
466  if ( !b && cl && m_file->IsWritable() ) {
467  b = t->Branch(n.c_str(),cl->GetName(),(void*)(ptr ? &ptr : 0),buff_siz,split_lvl);
468  }
469  if ( !b ) {
470  b = t->GetBranch(branch_name.c_str());
471  }
472  if ( b ) {
473  b->SetAutoDelete(kFALSE);
474  }
475  return b;
476 }
477 
480  int cnt = 0;
481  StringVec::iterator ip;
482  for(ip=m_links.begin();ip!=m_links.end();++ip,++cnt) {
483  if( (*ip) == p ) return cnt;
484  }
485  m_links.push_back(p);
486  return m_links.size()-1;
487 }
488 
491  if ( (which>=0) && (size_t(which)<m_dbs.size()) ) {
492  if ( *(m_dbs.begin()+which) == s_local ) return m_fid;
493  return *(m_dbs.begin()+which);
494  }
495  return s_empty;
496 }
497 
500  return s_empty;
501 }
502 
504 pair<int,unsigned long>
505 RootDataConnection::saveObj(CSTR section, CSTR cnt, TClass* cl, DataObject* pObj, int buff_siz, int split_lvl,bool fill) {
506  DataObjectPush push(pObj);
507  return save(section,cnt,cl,pObj,buff_siz,split_lvl,fill);
508 }
509 
511 pair<int,unsigned long>
512 RootDataConnection::save(CSTR section, CSTR cnt, TClass* cl, void* pObj, int buff_siz, int split_lvl, bool fill_missing) {
513  split_lvl = 0;
514  TBranch* b = getBranch(section, cnt, cl, (void*)(pObj ? &pObj : 0),buff_siz,split_lvl);
515  if ( b ) {
516  Long64_t evt = b->GetEntries();
517  //msgSvc() << MSG::DEBUG << cnt.c_str() << " Obj:" << (void*)pObj
518  // << " Split:" << split_lvl << " Buffer size:" << buff_siz << endl;
519  if ( fill_missing ) {
520  Long64_t num, nevt = b->GetTree()->GetEntries();
521  if ( nevt > evt ) {
522  b->SetAddress(0);
523  num = nevt - evt;
524  while( num > 0 ) { b->Fill(); --num; }
525  msgSvc() << MSG::DEBUG << "Added " << long(nevt-evt)
526  << " / Tree: " << nevt << " / Branch: " << b->GetEntries()+1
527  << " NULL entries to:" << cnt << endmsg;
528  evt = b->GetEntries();
529  }
530  }
531  b->SetAddress(&pObj);
532  return make_pair(b->Fill(),(unsigned long)evt);
533  }
534  else if ( 0 != pObj ) {
535  msgSvc() << MSG::ERROR << "Failed to access branch " << m_name << "/" << cnt << endmsg;
536  }
537  return make_pair(-1,~0);
538 }
539 
541 int RootDataConnection::loadObj(CSTR section, CSTR cnt, unsigned long entry, DataObject*& pObj) {
542  TBranch* b = getBranch(section,cnt);
543  if ( b ) {
544  TClass* cl = gROOT->GetClass(b->GetClassName(),kTRUE);
545  if ( cl ) {
546  int nb = -1;
547  pObj = (DataObject*)cl->New();
548  {
549  DataObjectPush push(pObj);
550  b->SetAddress(&pObj);
551  if ( section == m_setup->loadSection ) {
552  TTree* t = b->GetTree();
553  if ( Long64_t(entry) != t->GetReadEntry() ) {
554  t->LoadTree(Long64_t(entry));
555  }
556  }
557  nb = b->GetEntry(entry);
558  msgSvc() << MSG::VERBOSE;
559  if ( msgSvc().isActive() ) {
560  msgSvc() << "Load [" << entry << "] --> " << section
561  << ":" << cnt << " " << nb << " bytes."
562  << endmsg;
563  }
564  if ( nb < 0 ) { // This is definitely an error...ROOT says if reads fail, -1 is issued.
565 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,33,0)
566  IIncidentSvc* inc = m_setup->incidentSvc();
567  if ( inc ) {
569  }
570 #endif
571  }
572  else if ( nb == 0 && pObj->clID() == CLID_DataObject) {
573  TFile* f = b->GetFile();
574  int vsn = f->GetVersion();
575  if ( vsn < 52400 ) {
576  // For Gaudi v21r5 (ROOT 5.24.00b) DataObject::m_version was not written!
577  // Still this call be well be successful.
578  nb = 1;
579  }
580  else if ( vsn>1000000 && (vsn%1000000)<52400 ) {
581  // dto. Some POOL files have for unknown reasons a version
582  // not according to ROOT standards. Hack this explicitly.
583  nb = 1;
584  }
585  }
586  if ( nb < 0 ) {
587  delete pObj;
588  pObj = 0;
589  }
590  }
591  return nb;
592  }
593  }
594  return -1;
595 }
596 
598 int RootDataConnection::loadRefs(const std::string& section, const std::string& cnt,
599  unsigned long entry, RootObjectRefs& refs)
600 {
601  int nbytes = m_tool->loadRefs(section,cnt,entry,refs);
602 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,33,0)
603  if ( nbytes < 0 ) {
604  // This is definitely an error:
605  // -- Either branch not preesent at all or
606  // -- ROOT I/O error, which issues -1
607  IIncidentSvc* inc = m_setup->incidentSvc();
608  if ( inc ) {
610  }
611  }
612 #endif
613  return nbytes;
614 }
615 
617 pair<const RootRef*,const RootDataConnection::ContainerSection*>
618 RootDataConnection::getMergeSection(const string& container, int entry) const {
619  //size_t idx = cont.find('/',1);
620  //string container = cont[0]=='/' ? cont.substr(1,idx==string::npos?idx:idx-1) : cont;
621  MergeSections::const_iterator i=m_mergeSects.find(container);
622  if ( i != m_mergeSects.end() ) {
623  size_t cnt = 0;
624  const ContainerSections& s = (*i).second;
625  for(ContainerSections::const_iterator j=s.begin(); j != s.end(); ++j,++cnt) {
626  const ContainerSection& c = *j;
627  if ( entry >= c.start && entry < (c.start+c.length) ) {
628  if ( m_linkSects.size() > cnt ) {
629  if ( msgSvc().isActive() ) {
630  msgSvc() << MSG::VERBOSE << "MergeSection for:" << container
631  << " [" << entry << "]" << endmsg
632  << "FID:" << m_fid << " -> PFN:" << m_pfn << endmsg;
633  }
634  return make_pair(&(m_linkSects[cnt]), &c);
635  }
636  }
637  }
638  }
639  msgSvc() << MSG::DEBUG << "Return INVALID MergeSection for:" << container
640  << " [" << entry << "]" << endmsg
641  << "FID:" << m_fid << " -> PFN:" << m_pfn << endmsg;
642  return make_pair((const RootRef*)0,(const ContainerSection*)0);
643 }
644 
647  IOpaqueAddress* pA = pR->address();
648  makeRef(pR->name(),pA->clID(),pA->svcType(),pA->par()[0],pA->par()[1],-1,ref);
649 }
650 
652 void RootDataConnection::makeRef(CSTR name, long clid, int tech, CSTR dbase, CSTR cnt, int entry, RootRef& ref) {
653  string db(dbase);
654  int cdb=-1, ccnt=-1, clnk=-1;
655  StringVec::iterator idb, icnt, ilnk;
656  if ( db == m_fid ) {
657  db = s_local;
658  }
659  ref.entry = entry;
660  if ( !db.empty() ) {
661  for(cdb=0,idb=m_dbs.begin(); idb!=m_dbs.end();++idb,++cdb)
662  if( (*idb) == db ) break;
663  if ( idb == m_dbs.end() ) {
664  cdb = m_dbs.size();
665  m_dbs.push_back(db);
666  }
667  }
668  if ( !cnt.empty() ) {
669  for(ccnt=0,icnt=m_conts.begin(); icnt!=m_conts.end();++icnt,++ccnt)
670  if( (*icnt) == cnt ) break;
671  if ( icnt == m_conts.end() ) {
672  ccnt = m_conts.size();
673  m_conts.push_back(cnt);
674  }
675  }
676  if ( !name.empty() ) {
677  for(clnk=0,ilnk=m_links.begin(); ilnk!=m_links.end();++ilnk,++clnk)
678  if( (*ilnk) == name ) break;
679  if ( ilnk == m_links.end() ) {
680  clnk = m_links.size();
681  m_links.push_back(name);
682  }
683  }
684  ref.dbase = cdb;
685  ref.container = ccnt;
686  ref.link = clnk;
687  ref.clid = clid;
688  ref.svc = tech;
689  if ( ref.svc == POOL_ROOT_StorageType ||
690  ref.svc == POOL_ROOTKEY_StorageType ||
691  ref.svc == POOL_ROOTTREE_StorageType ) {
692  ref.svc = ROOT_StorageType;
693  }
694 }
695 
void addClient(const IInterface *client)
Add new client to this data source.
void addRef()
Increase reference count.
bool lookupClient(const IInterface *client) const
Lookup client for this data source.
virtual const std::string * par() const =0
Retrieve String parameters.
MergeSections m_mergeSects
Database section map for merged files.
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
int m_age
Age counter.
const std::string & fid() const
Access file id.
std::vector< ContainerSection > ContainerSections
Definition of container sections to handle merged files.
std::string m_name
Connection name/identifier.
IoType
I/O Connection types.
std::pair< int, unsigned long > saveObj(const std::string &section, const std::string &cnt, TClass *cl, DataObject *pObj, int buff_siz, int split_lvl, bool fill_missing=false)
Save object of a given class to section and container.
unsigned long getCode() const
Get the status code by value.
Definition: StatusCode.h:92
void saveStatistics(const std::string &statisticsFile)
Save TTree access statistics if required.
const std::string & getDb(int which) const
Access database/file name from saved index.
std::string m_fid
File ID of the connection.
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:75
virtual StatusCode saveRefs()=0
Save references section when closing data file.
int loadObj(const std::string &section, const std::string &cnt, unsigned long entry, DataObject *&pObj)
Load object.
TFile * m_file
Reference to ROOT file.
tuple c
Definition: gaudirun.py:341
int refCount
Object refrfence count.
static int compression()
Access to global compression level.
Clients m_clients
Client list.
TTree * getSection(const std::string &sect, bool create=false)
Access TTree section from section name. The section is created if required.
void release()
Decrease reference count.
int start
The start entry of the section.
IIncidentSvc * m_incidentSvc
Reference to incident service.
size_t removeClient(const IInterface *client)
Remove client from this data source.
bool isActive() const
Accessor: is MsgStream active.
Definition: MsgStream.h:128
GAUDI_API void fill(AIDA::IHistogram1D *histo, const double value, const double weight=1.0)
simple function to fill AIDA::IHistogram1D objects
Definition: Fill.cpp:37
virtual const name_type & name() const =0
Name of the directory (or key)
std::vector< std::string > StringVec
Type definition for string maps.
void setMessageSvc(MsgStream *m)
Set message service reference.
virtual int loadRefs(const std::string &section, const std::string &cnt, unsigned long entry, RootObjectRefs &refs)=0
Load references object.
virtual long svcType() const =0
Retrieve service type.
int cacheSize
RootCnvSvc Property: Root data cache size.
const std::string & pfn() const
Access physical file name.
int loadRefs(const std::string &section, const std::string &cnt, unsigned long entry, RootObjectRefs &refs)
Load references object.
Persistent reference object containing all leafs and links corresponding to a Gaudi DataObject...
Definition: RootRefs.h:72
StringVec m_links
Map containing internal links names.
ParamMap m_params
Parameter map for file parameters.
std::string loadSection
RootCnvSvc Property: Root data cache size.
const long POOL_ROOTKEY_StorageType
Definition: ClassID.h:70
const string & CSTR
StringVec m_mergeFIDs
Map containing merge FIDs.
std::string m_pfn
Physical file name of the connection.
int dbase
Data members to define object location in the persistent world.
Definition: RootRefs.h:33
Persistent reference object.
Definition: RootRefs.h:31
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
Description:
Definition: RootTool.h:15
virtual const CLID & clID() const
Retrieve reference to class definition structure.
Definition: DataObject.cpp:58
virtual const CLID & clID() const =0
Retrieve class information from link.
const std::string & name() const
Connection name.
virtual ~RootDataConnection()
Standard destructor.
Helper class to facilitate an abstraction layer for reading POOL style files with this package...
int learnEntries
RootCnvSvc Property: ROOT cache learn entries.
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:30
Definition of the basic interface.
Definition: IInterface.h:160
TBranch * getBranch(const std::string &section, const std::string &branch_name)
Access data branch by name: Get existing branch in read only mode.
void makeRef(IRegistry *pA, RootRef &ref)
Create reference object from registry entry.
StringVec m_conts
Map containing external container names.
const std::string & empty() const
Empty string reference.
list nevt
Definition: ana.py:134
Sections m_sections
Tree sections in TFile.
std::pair< const RootRef *, const ContainerSection * > getMergeSection(const std::string &container, int entry) const
Access link section for single container and entry.
class Gaudi::RootDataConnection::Tool * m_tool
StringVec cacheBranches
Vector of strings with branches to be cached for input files.
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
const std::string CSTR
const long ROOT_StorageType
Definition: ClassID.h:53
def which
Locates an executable in the executables path ($PATH) and returns the full path to it...
Definition: GaudiTest.py:289
const long POOL_ROOT_StorageType
Definition: ClassID.h:69
TTreePerfStats * m_statistics
I/O read statistics from TTree.
RootConnectionSetup()
Standard constructor.
Tool * makeTool()
Create file access tool to encapsulate POOL compatibiliy.
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
StringVec vetoBranches
Vector of strings with branches to NOT be cached for input files.
std::pair< int, unsigned long > save(const std::string &section, const std::string &cnt, TClass *cl, void *pObj, int buff_siz, int split_lvl, bool fill_missing=false)
Save object of a given class to section and container.
virtual unsigned long release()=0
Release Interface instance.
ABC describing basic data connection.
int makeLink(const std::string &p)
Convert path string to path index.
IIncidentSvc * incidentSvc() const
Retrieve incident service.
const long POOL_ROOTTREE_StorageType
Definition: ClassID.h:71
virtual StatusCode disconnect()
Release data stream and release implementation dependent resources.
virtual StatusCode connectRead()
Open data stream in read mode.
LinkSections m_linkSects
Database link sections.
RootDataConnection(const IInterface *own, const std::string &nam, RootConnectionSetup *setup)
Standard constructor.
virtual StatusCode readRefs()=0
Read references section when opening data file.
void resetAge()
Reset age.
Base class for all Incidents (computing events).
Definition: Incident.h:16
MsgStream & msgSvc() const
Allow access to printer service.
RootConnectionSetup * m_setup
Reference to the setup structure.
string s
Definition: gaudirun.py:210
virtual StatusCode connectWrite(IoType typ)
Open data stream in write mode.
static long setCompression(const std::string &compression)
Set the global compression level.
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
Opaque address interface definition.
StringVec m_dbs
Map containing external database file names (fids)
void ignore() const
Definition: StatusCode.h:107
This is a number of static methods for bootstrapping the Gaudi framework.
Definition: Bootstrap.h:14
void setIncidentSvc(IIncidentSvc *m)
Set incident service reference.
void enableStatistics(const std::string &section)
Enable TTreePerStats.
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:31
list i
Definition: ana.py:128
MsgStream * m_msgSvc
Reference to message service.
TTree * m_refs
Pointer to the reference tree.
virtual ~RootConnectionSetup()
Standard destructor.
Internal helper class, which described a TBranch section in a ROOT file.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
const std::string CorruptedInputFile
the input file has shown a corruption
Definition: Incident.h:81
The interface implemented by the IncidentSvc service.
Definition: IIncidentSvc.h:22
void badWriteError(const std::string &msg) const
Error handler when bad write statements occur.