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