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