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 "Compression.h"
29 #include "TTreePerfStats.h"
30 
31 // C/C++ include files
32 #include <stdexcept>
33 
34 using namespace Gaudi;
35 using namespace std;
36 typedef const string& CSTR;
37 
38 static string s_empty;
39 static string s_local = "<localDB>";
40 
41 #ifdef __POOL_COMPATIBILITY
42 #include "PoolTool.h"
43 #endif
44 #include "RootTool.h"
45 
46 static int s_compressionLevel = ROOT::CompressionSettings(ROOT::kLZMA,6);
47 
48 static bool match_wild(const char *str, const char *pat) {
49  //
50  // Credits: Code from Alessandro Felice Cantatore.
51  //
52  static char table[256];
53  static bool first = true;
54  const char *s, *p;
55  bool star = false;
56  if ( first ) {
57  for (int i = 0; i < 256; ++i) table[i] = char(i);
58  first = false;
59  }
60 loopStart:
61  for (s = str, p = pat; *s; ++s, ++p) {
62  switch (*p) {
63  case '?':
64  if (*s == '.') goto starCheck;
65  break;
66  case '*':
67  star = true;
68  str = s, pat = p;
69  do { ++pat; } while (*pat == '*');
70  if (!*pat) return true;
71  goto loopStart;
72  default:
73  if ( *(table+*s) != *(table+*p) )
74  goto starCheck;
75  break;
76  } /* endswitch */
77  } /* endfor */
78  while (*p == '*') ++p;
79  return (!*p);
80 
81 starCheck:
82  if (!star) return false;
83  str++;
84  goto loopStart;
85 }
86 
88 RootConnectionSetup::RootConnectionSetup() : refCount(1), m_msgSvc(0), m_incidentSvc(0)
89 {
90 }
91 
95  m_incidentSvc = 0;
96  deletePtr(m_msgSvc);
97 }
98 
100 long RootConnectionSetup::setCompression(const std::string& compression) {
101  int res = 0, level = ROOT::CompressionSettings(ROOT::kLZMA,6);
102  size_t idx = compression.find(':');
103  if ( idx != string::npos ) {
104  string alg = compression.substr(0,idx);
105  ROOT::ECompressionAlgorithm alg_code = ROOT::kUseGlobalSetting;
106  if ( strcasecmp(alg.c_str(),"ZLIB") == 0 )
107  alg_code = ROOT::kZLIB;
108  else if ( strcasecmp(alg.c_str(),"LZMA") == 0 )
109  alg_code = ROOT::kLZMA;
110  else
111  throw runtime_error("ERROR: request to set unknown ROOT compression algorithm:"+alg);
112  res = ::sscanf(compression.c_str()+idx+1,"%d",&level);
113  if ( res == 1 ) {
114  s_compressionLevel = ROOT::CompressionSettings(alg_code,level);
115  return StatusCode::SUCCESS;
116  }
117  throw runtime_error("ERROR: request to set unknown ROOT compression level:"+compression.substr(idx+1));
118  }
119  else if ( 1==::sscanf(compression.c_str(),"%d",&level) ) {
120  s_compressionLevel = level;
121  return StatusCode::SUCCESS;
122  }
123  throw runtime_error("ERROR: request to set unknown ROOT compression mechanism:"+compression);
124 }
125 
128  return s_compressionLevel;
129 }
130 
133  ++refCount;
134 }
135 
138  int tmp = --refCount;
139  if ( tmp <= 0 ) {
140  delete this;
141  }
142 }
143 
146  MsgStream* tmp = m_msgSvc;
147  m_msgSvc = m;
148  deletePtr(tmp);
149 }
150 
154  m_incidentSvc = s;
156  if ( tmp ) tmp->release();
157 }
158 
161  : IDataConnection(owner,fname), m_setup(setup), m_statistics(0), m_tool(0)
162 { // 01234567890123456789012345678901234567890
163  // Check if FID: A82A3BD8-7ECB-DC11-8DC0-000423D950B0
164  if ( fname.length() == 36 && fname[8]=='-'&&fname[13]=='-'&&fname[18]=='-'&&fname[23]=='-' ) {
165  m_name = "FID:"+fname;
166  }
167  m_setup->addRef();
168  m_age = 0;
169  m_file = 0;
170  m_refs = 0;
171  addClient(owner);
172 }
173 
176  m_setup->release();
177  releasePtr(m_tool);
178 }
179 
182  m_clients.insert(client);
183 }
184 
187  Clients::iterator i=m_clients.find(client);
188  if ( i != m_clients.end() ) m_clients.erase(i);
189  return m_clients.size();
190 }
191 
193 bool RootDataConnection::lookupClient(const IInterface* client) const {
194  Clients::const_iterator i=m_clients.find(client);
195  return i != m_clients.end();
196 }
197 
199 void RootDataConnection::badWriteError(const string& msg) const {
200  msgSvc() << MSG::ERROR << "File:" << fid() << "Failed action:" << msg << endmsg;
201 }
202 
205  if ( m_statistics ) {
206  m_statistics->Print();
207  if ( !statisticsFile.empty() )
208  m_statistics->SaveAs(statisticsFile.c_str());
209  deletePtr(m_statistics);
210  }
211 }
212 
215  if ( 0 == m_statistics ) {
216  TTree* t=getSection(section,false);
217  if ( t ) {
218  m_statistics = new TTreePerfStats((section+"_ioperf").c_str(),t);
219  return;
220  }
221  msgSvc() << MSG::WARNING << "Failed to enable perfstats for tree:" << section << endmsg;
222  return;
223  }
224  msgSvc() << MSG::INFO << "Perfstats are ALREADY ENABLED." << endmsg;
225 }
226 
229  releasePtr(m_tool);
230  if ( !m_refs ) m_refs = (TTree*)m_file->Get("Refs");
231  if ( m_refs )
232  m_tool = new RootTool(this);
233 #ifdef __POOL_COMPATIBILITY
234  else if ( m_file->Get("##Links") != 0 )
235  m_tool = new PoolTool(this);
236 #endif
237  return m_tool;
238 }
239 
242  m_file = TFile::Open(m_pfn.c_str());
243  if ( m_file && !m_file->IsZombie() ) {
245  msgSvc() << MSG::DEBUG << "Opened file " << m_pfn << " in mode READ. [" << m_fid << "]" << endmsg << MSG::DEBUG;
246  if ( msgSvc().isActive() ) m_file->ls();
247  msgSvc() << MSG::VERBOSE;
248  if ( msgSvc().isActive() ) m_file->Print();
249  if ( makeTool() ) {
250  sc = m_tool->readRefs();
251  sc.ignore();
252  if ( sc.getCode() == ROOT_READ_ERROR ) {
253  IIncidentSvc* inc = m_setup->incidentSvc();
254  if ( inc ) {
256  }
257  }
258  }
259  if ( sc.isSuccess() ) {
260  bool need_fid = m_fid == m_pfn;
261  string fid = m_fid;
262  m_mergeFIDs.clear();
263  for(size_t i=0, n=m_params.size(); i<n; ++i) {
264  if ( m_params[i].first == "FID" ) {
265  m_mergeFIDs.push_back(m_params[i].second);
266  if ( m_params[i].second != m_fid ) {
267  msgSvc() << MSG::DEBUG << "Check FID param:" << m_params[i].second << endmsg;
268  //if ( m_fid == m_pfn ) {
269  m_fid = m_params[i].second;
270  //}
271  }
272  }
273  }
274  if ( !need_fid && fid != m_fid ) {
275  msgSvc() << MSG::ERROR << "FID mismatch:" << fid << "(Catalog) != " << m_fid << "(file)" << endmsg
276  << "for PFN:" << m_pfn << endmsg;
277  return StatusCode::FAILURE;
278  }
279  msgSvc() << MSG::DEBUG << "Using FID " << m_fid << " from params table...." << endmsg
280  << "for PFN:" << m_pfn << endmsg;
281  return sc;
282  }
283  }
284  else if ( m_file ) {
285  deletePtr(m_file);
286  }
287  return StatusCode::FAILURE;
288 }
289 
292  int compress = RootConnectionSetup::compression();
293  msgSvc() << MSG::DEBUG;
294  switch(typ) {
295  case CREATE:
296  resetAge();
297  m_file = TFile::Open(m_pfn.c_str(),"CREATE","Root event data",compress);
298  m_refs = new TTree("Refs","Root reference data");
299  msgSvc() << "Opened file " << m_pfn << " in mode CREATE. [" << m_fid << "]" << endmsg;
300  m_params.push_back(make_pair("PFN",m_pfn));
301  if ( m_fid != m_pfn ) {
302  m_params.push_back(make_pair("FID",m_fid));
303  }
304  makeTool();
305  break;
306  case RECREATE:
307  resetAge();
308  m_file = TFile::Open(m_pfn.c_str(),"RECREATE","Root event data",compress);
309  msgSvc() << "Opened file " << m_pfn << " in mode RECREATE. [" << m_fid << "]" << endmsg;
310  m_refs = new TTree("Refs","Root reference data");
311  m_params.push_back(make_pair("PFN",m_pfn));
312  if ( m_fid != m_pfn ) {
313  m_params.push_back(make_pair("FID",m_fid));
314  }
315  makeTool();
316  break;
317  case UPDATE:
318  resetAge();
319  m_file = TFile::Open(m_pfn.c_str(),"UPDATE","Root event data",compress);
320  msgSvc() << "Opened file " << m_pfn << " in mode UPDATE. [" << m_fid << "]" << endmsg;
321  if ( m_file && !m_file->IsZombie() ) {
322  if ( makeTool() ) {
324  sc.ignore();
325  if ( sc.getCode() == ROOT_READ_ERROR ) {
326  IIncidentSvc* inc = m_setup->incidentSvc();
327  if ( inc ) {
329  }
330  }
331  return sc;
332  }
333  TDirectory::TContext ctxt(m_file);
334  m_refs = new TTree("Refs","Root reference data");
335  makeTool();
336  return StatusCode::SUCCESS;
337  }
338  break;
339  default:
340  m_refs = 0;
341  m_file = 0;
342  return StatusCode::FAILURE;
343  }
345 }
346 
349  if ( m_file ) {
350  if ( !m_file->IsZombie() ) {
351  if ( m_file->IsWritable() ) {
352  msgSvc() << MSG::DEBUG;
353  TDirectory::TContext ctxt(m_file);
354  if ( m_refs ) {
355  if ( !m_tool->saveRefs().isSuccess() ) badWriteError("Saving References");
356  if ( m_refs->Write() < 0 ) badWriteError("Write Reference branch");
357  }
358  for(Sections::iterator i=m_sections.begin(); i!= m_sections.end();++i) {
359  if ( (*i).second ) {
360  if ( (*i).second->Write() < 0 ) badWriteError("Write section:"+(*i).first);
361  msgSvc() << "Disconnect section " << (*i).first << " " << (*i).second->GetName() << endmsg;
362  }
363  }
364  m_sections.clear();
365  }
366  msgSvc() << MSG::DEBUG;
367  if ( msgSvc().isActive() ) m_file->ls();
368  msgSvc() << MSG::VERBOSE;
369  if ( msgSvc().isActive() ) m_file->Print();
370  m_file->Close();
371  }
372  msgSvc() << MSG::DEBUG << "Disconnected file " << m_pfn << " " << m_file->GetName() << endmsg;
373  deletePtr(m_file);
374  releasePtr(m_tool);
375  }
376  return StatusCode::SUCCESS;
377 }
378 
380 TTree* RootDataConnection::getSection(CSTR section, bool create) {
381  TTree* t = m_sections[section];
382  if ( !t ) {
383  t = (TTree*)m_file->Get(section.c_str());
384  if ( !t && create ) {
385  TDirectory::TContext ctxt(m_file);
386  t = new TTree(section.c_str(),"Root data for Gaudi");
387  }
388  if ( t ) {
389  int cacheSize = m_setup->cacheSize;
390  if ( create ) {
391  //t->SetAutoFlush(100);
392  }
393  if ( section == m_setup->loadSection && cacheSize>-2 ) {
394  MsgStream& msg = msgSvc();
395  int learnEntries = m_setup->learnEntries;
396  t->SetCacheSize(cacheSize);
397  t->SetCacheLearnEntries(learnEntries);
398  msg << MSG::DEBUG;
399  if ( create ) {
400  msg << "Tree:" << section << "Setting up tree cache:" << cacheSize << endmsg;
401  }
402  else {
403  const StringVec& vB = m_setup->vetoBranches;
404  const StringVec& cB = m_setup->cacheBranches;
405  msg << "Tree:" << section << " Setting up tree cache:" << cacheSize << " Add all branches." << endmsg;
406  msg << "Tree:" << section << " Learn for " << learnEntries << " entries." << endmsg;
407 
408  if ( cB.size()==0 && vB.size()== 0 ) {
409  msg << "Adding (default) all branches to tree cache." << endmsg;
410  t->AddBranchToCache("*",kTRUE);
411  }
412  if ( cB.size()==1 && cB[0]=="*" ) {
413  msg << "Adding all branches to tree cache according to option \"CacheBranches\"." << endmsg;
414  t->AddBranchToCache("*",kTRUE);
415  }
416  else {
417  StringVec::const_iterator i;
418  for(TIter it(t->GetListOfBranches()); it.Next(); ) {
419  const char* n = ((TNamed*)(*it))->GetName();
420  bool add = false, veto = false;
421  for(i=cB.begin(); i != cB.end();++i) {
422  if ( !match_wild(n,(*i).c_str()) ) continue;
423  add = true;
424  break;
425  }
426  for(i=vB.begin(); !add && i!=vB.end();++i) {
427  if ( !match_wild(n,(*i).c_str()) ) continue;
428  veto = true;
429  break;
430  }
431  if ( add && !veto ) {
432  msg << "Add " << n << " to branch cache." << endmsg;
433  t->AddBranchToCache(n,kTRUE);
434  }
435  else {
436  msg << "Do not cache branch " << n << endmsg;
437  }
438  }
439  }
440  }
441  }
442  m_sections[section] = t;
443  }
444  }
445  return t;
446 }
447 
449 TBranch* RootDataConnection::getBranch(CSTR section, CSTR branch_name, TClass* cl, void* ptr, int buff_siz, int split_lvl) {
450  string n = branch_name+".";
451  for(int i=0, m=n.length()-1; i<m; ++i) if ( !isalnum(n[i]) ) n[i]='_';
452  TTree* t = getSection(section,true);
453  TBranch* b = t->GetBranch(n.c_str());
454  if ( !b && cl && m_file->IsWritable() ) {
455  b = t->Branch(n.c_str(),cl->GetName(),(void*)(ptr ? &ptr : 0),buff_siz,split_lvl);
456  }
457  if ( !b ) {
458  b = t->GetBranch(branch_name.c_str());
459  }
460  if ( b ) {
461  b->SetAutoDelete(kFALSE);
462  }
463  return b;
464 }
465 
468  int cnt = 0;
469  StringVec::iterator ip;
470  for(ip=m_links.begin();ip!=m_links.end();++ip,++cnt) {
471  if( (*ip) == p ) return cnt;
472  }
473  m_links.push_back(p);
474  return m_links.size()-1;
475 }
476 
479  if ( (which>=0) && (size_t(which)<m_dbs.size()) ) {
480  if ( *(m_dbs.begin()+which) == s_local ) return m_fid;
481  return *(m_dbs.begin()+which);
482  }
483  return s_empty;
484 }
485 
488  return s_empty;
489 }
490 
492 pair<int,unsigned long>
493 RootDataConnection::saveObj(CSTR section, CSTR cnt, TClass* cl, DataObject* pObj, int buff_siz, int split_lvl,bool fill) {
494  DataObjectPush push(pObj);
495  return save(section,cnt,cl,pObj,buff_siz,split_lvl,fill);
496 }
497 
499 pair<int,unsigned long>
500 RootDataConnection::save(CSTR section, CSTR cnt, TClass* cl, void* pObj, int buff_siz, int split_lvl, bool fill_missing) {
501  split_lvl = 0;
502  TBranch* b = getBranch(section, cnt, cl, (void*)(pObj ? &pObj : 0),buff_siz,split_lvl);
503  if ( b ) {
504  Long64_t evt = b->GetEntries();
505  //msgSvc() << MSG::DEBUG << cnt.c_str() << " Obj:" << (void*)pObj
506  // << " Split:" << split_lvl << " Buffer size:" << buff_siz << endl;
507  if ( fill_missing ) {
508  Long64_t num, nevt = b->GetTree()->GetEntries();
509  if ( nevt > evt ) {
510  b->SetAddress(0);
511  num = nevt - evt;
512  while( num > 0 ) { b->Fill(); --num; }
513  msgSvc() << MSG::DEBUG << "Added " << long(nevt-evt)
514  << " / Tree: " << nevt << " / Branch: " << b->GetEntries()+1
515  << " NULL entries to:" << cnt << endmsg;
516  evt = b->GetEntries();
517  }
518  }
519  b->SetAddress(&pObj);
520  return make_pair(b->Fill(),(unsigned long)evt);
521  }
522  else if ( 0 != pObj ) {
523  msgSvc() << MSG::ERROR << "Failed to access branch " << m_name << "/" << cnt << endmsg;
524  }
525  return make_pair(-1,~0);
526 }
527 
529 int RootDataConnection::loadObj(CSTR section, CSTR cnt, unsigned long entry, DataObject*& pObj) {
530  TBranch* b = getBranch(section,cnt);
531  if ( b ) {
532  TClass* cl = gROOT->GetClass(b->GetClassName(),kTRUE);
533  if ( cl ) {
534  int nb = -1;
535  pObj = (DataObject*)cl->New();
536  {
537  DataObjectPush push(pObj);
538  b->SetAddress(&pObj);
539  if ( section == m_setup->loadSection ) {
540  TTree* t = b->GetTree();
541  if ( Long64_t(entry) != t->GetReadEntry() ) {
542  t->LoadTree(Long64_t(entry));
543  }
544  }
545  nb = b->GetEntry(entry);
546  msgSvc() << MSG::VERBOSE;
547  if ( msgSvc().isActive() ) {
548  msgSvc() << "Load [" << entry << "] --> " << section
549  << ":" << cnt << " " << nb << " bytes."
550  << endmsg;
551  }
552  if ( nb < 0 ) { // This is definitely an error...ROOT says if reads fail, -1 is issued.
553  IIncidentSvc* inc = m_setup->incidentSvc();
554  if ( inc ) {
556  }
557  }
558  else if ( nb == 0 && pObj->clID() == CLID_DataObject) {
559  TFile* f = b->GetFile();
560  int vsn = f->GetVersion();
561  if ( vsn < 52400 ) {
562  // For Gaudi v21r5 (ROOT 5.24.00b) DataObject::m_version was not written!
563  // Still this call be well be successful.
564  nb = 1;
565  }
566  else if ( vsn>1000000 && (vsn%1000000)<52400 ) {
567  // dto. Some POOL files have for unknown reasons a version
568  // not according to ROOT standards. Hack this explicitly.
569  nb = 1;
570  }
571  }
572  if ( nb < 0 ) {
573  delete pObj;
574  pObj = 0;
575  }
576  }
577  return nb;
578  }
579  }
580  return -1;
581 }
582 
584 int RootDataConnection::loadRefs(const std::string& section, const std::string& cnt,
585  unsigned long entry, RootObjectRefs& refs)
586 {
587  int nbytes = m_tool->loadRefs(section,cnt,entry,refs);
588  if ( nbytes < 0 ) {
589  // This is definitely an error:
590  // -- Either branch not preesent at all or
591  // -- ROOT I/O error, which issues -1
592  IIncidentSvc* inc = m_setup->incidentSvc();
593  if ( inc ) {
595  }
596  }
597  return nbytes;
598 }
599 
601 pair<const RootRef*,const RootDataConnection::ContainerSection*>
602 RootDataConnection::getMergeSection(const string& container, int entry) const {
603  //size_t idx = cont.find('/',1);
604  //string container = cont[0]=='/' ? cont.substr(1,idx==string::npos?idx:idx-1) : cont;
605  MergeSections::const_iterator i=m_mergeSects.find(container);
606  if ( i != m_mergeSects.end() ) {
607  size_t cnt = 0;
608  const ContainerSections& s = (*i).second;
609  for(ContainerSections::const_iterator j=s.begin(); j != s.end(); ++j,++cnt) {
610  const ContainerSection& c = *j;
611  if ( entry >= c.start && entry < (c.start+c.length) ) {
612  if ( m_linkSects.size() > cnt ) {
613  if ( msgSvc().isActive() ) {
614  msgSvc() << MSG::VERBOSE << "MergeSection for:" << container
615  << " [" << entry << "]" << endmsg
616  << "FID:" << m_fid << " -> PFN:" << m_pfn << endmsg;
617  }
618  return make_pair(&(m_linkSects[cnt]), &c);
619  }
620  }
621  }
622  }
623  msgSvc() << MSG::DEBUG << "Return INVALID MergeSection for:" << container
624  << " [" << entry << "]" << endmsg
625  << "FID:" << m_fid << " -> PFN:" << m_pfn << endmsg;
626  return make_pair((const RootRef*)0,(const ContainerSection*)0);
627 }
628 
631  IOpaqueAddress* pA = pR->address();
632  makeRef(pR->name(),pA->clID(),pA->svcType(),pA->par()[0],pA->par()[1],-1,ref);
633 }
634 
636 void RootDataConnection::makeRef(CSTR name, long clid, int tech, CSTR dbase, CSTR cnt, int entry, RootRef& ref) {
637  string db(dbase);
638  int cdb=-1, ccnt=-1, clnk=-1;
639  StringVec::iterator idb, icnt, ilnk;
640  if ( db == m_fid ) {
641  db = s_local;
642  }
643  ref.entry = entry;
644  if ( !db.empty() ) {
645  for(cdb=0,idb=m_dbs.begin(); idb!=m_dbs.end();++idb,++cdb)
646  if( (*idb) == db ) break;
647  if ( idb == m_dbs.end() ) {
648  cdb = m_dbs.size();
649  m_dbs.push_back(db);
650  }
651  }
652  if ( !cnt.empty() ) {
653  for(ccnt=0,icnt=m_conts.begin(); icnt!=m_conts.end();++icnt,++ccnt)
654  if( (*icnt) == cnt ) break;
655  if ( icnt == m_conts.end() ) {
656  ccnt = m_conts.size();
657  m_conts.push_back(cnt);
658  }
659  }
660  if ( !name.empty() ) {
661  for(clnk=0,ilnk=m_links.begin(); ilnk!=m_links.end();++ilnk,++clnk)
662  if( (*ilnk) == name ) break;
663  if ( ilnk == m_links.end() ) {
664  clnk = m_links.size();
665  m_links.push_back(name);
666  }
667  }
668  ref.dbase = cdb;
669  ref.container = ccnt;
670  ref.link = clnk;
671  ref.clid = clid;
672  ref.svc = tech;
673  if ( ref.svc == POOL_ROOT_StorageType ||
674  ref.svc == POOL_ROOTKEY_StorageType ||
675  ref.svc == POOL_ROOTTREE_StorageType ) {
676  ref.svc = ROOT_StorageType;
677  }
678 }
679 
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:79
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:62
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:127
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
std
AIDA -> ROTO converter.
Definition: GaudiAlgs.py:73
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:94
This is a number of static methods for bootstrapping the Gaudi framework.
Definition: Bootstrap.h:15
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:243
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.