PoolTool.h
Go to the documentation of this file.
1 #include "RootCnv/PoolClasses.h"
2 /*
3 * Gaudi namespace declaration
4 */
5 namespace Gaudi {
6 
7 
17  class PoolTool : virtual public RootDataConnection::Tool {
19  std::vector<Gaudi::RootRef> m_poolLinks;
20 
21  public:
23  PoolTool(RootDataConnection* con) { c = con; }
24 
26  string _treeName(string t) {
27  std::replace(std::begin(t),std::end(t),'/','_');
28  return t;
29  }
30 
31  virtual RootRef poolRef(size_t i) const { return m_poolLinks[i]; }
32 
34  virtual int loadRefs(CSTR /* section */, CSTR cnt, unsigned long entry, RootObjectRefs& refs) {
35  TTree* t = sections()[cnt];
36  if ( !t ) {
37  t = (TTree*)c->file()->Get(_treeName(cnt).c_str());
38  }
39  if ( t ) {
40  TBranch* b1 = t->GetBranch("Links");
41  TBranch* b2 = t->GetBranch("Refs");
42  MsgStream& msg = msgSvc();
43  if ( b1 && b2 ) {
44  LinkManager lm, *plm = &lm;
45  PoolDbLinkManager mgr, *pmgr = &mgr;
46  b1->SetAutoDelete(kFALSE);
47  b2->SetAutoDelete(kFALSE);
48  b1->SetAddress(&plm);
49  b2->SetAddress(&pmgr);
50  int nb1 = b1->GetEvent(entry);
51  int nb2 = b2->GetEvent(entry);
52  if ( nb1>1 && nb2>1 ) {
53  size_t ref_size = mgr.references().size();
54  refs.refs.resize(ref_size);
55  msg << MSG::VERBOSE;
56  for(size_t j = 0; j < ref_size; ++j) {
57  const pair<int, int>& oid = mgr.references()[j]->m_oid;
58  string loc = mgr.links()[j].substr(1);
59  RootRef& r = refs.refs[j];
60  if ( oid.first>=0 ) {
61  r = m_poolLinks[oid.first];
62  r.entry = oid.second;
63  r.link = c->makeLink(loc);
64  msg << "Add leaf:" << oid.first << "->" << loc << " from " << c->getDb(r.dbase)
65  << "#" << c->getCont(r.container)
66  << " Link:" << c->getLink(r.link)
67  << " CLID:" << hex << r.clid
68  << " Typ:" << hex << int(r.svc)
69  << " Ent:" << dec << r.entry << endl;
70  }
71  }
72  for(int i = 0, n=lm.size(); i < n; ++i) {
73  LinkManager::Link* lnk = lm.link(i);
74  int link_id = c->makeLink(lnk->path());
75  msg << "Add Link:" << lnk->path() << endl;
76  refs.links.push_back(link_id);
77  }
78  return nb1 + nb2;
79  }
80  }
81  msg << MSG::ERROR << "Failed to access POOL Ref/Link branches:" << cnt
82  << " [" << _treeName(cnt) << "]" << endmsg;
83  t->Print();
84  }
85  return -1;
86  }
87 
89  virtual TBranch* getBranch(CSTR /* section */, CSTR branch_name) {
90  TTree* t = sections()[branch_name];
91  if ( t ) {
92  return (TBranch*)t->GetListOfBranches()->At(0);
93  }
94  string tname = _treeName(branch_name);
95  t = (TTree*)c->file()->Get(tname.c_str()); // c->getSection(tname);
96  if ( t ) {
97  TBranch* b = (TBranch*)t->GetListOfBranches()->At(0);
98  if ( b ) {
99  sections()[branch_name] = t;
100  return b;
101  }
102  msgSvc() << MSG::ERROR << "Failed to access POOL branch:"
103  << branch_name << " [" << tname << "]" << endmsg;
104  t->Print();
105  }
106  return nullptr;
107  }
108 
111 
114  int i;
115  char text[2048];
116  msgSvc() << MSG::VERBOSE;
117 
118  // First read ##Params
119  TTree* t = (TTree*)c->file()->Get("##Params");
120  if ( !t ) return StatusCode::FAILURE;
121  TBranch* b = t->GetBranch("db_string");
122  if ( !b ) return StatusCode::FAILURE;
123  for(i=0,b->SetAddress(text); i < b->GetEntries(); ++i) {
124  b->GetEvent(i);
125  char* id1 = strstr(text,"[NAME=");
126  char* id2 = strstr(text,"[VALUE=");
127  if ( id1 && id2 ) {
128  id1 += 6;
129  id2 += 7;
130  char* id11 = strstr(id1, "]");
131  char* id22 = strstr(id2, "]");
132  if ( id11 && id22 ) {
133  *id11 = 0;
134  *id22 = 0;
135  params().emplace_back(id1,id2);
136  msgSvc() << "Param:" << id1 << "=" << id2 << "." << endmsg;
137  }
138  }
139  }
140 
141  // Read ##Links
142  t = (TTree*)c->file()->Get("##Links");
143  if ( !t ) return StatusCode::FAILURE;
144  b = t->GetBranch("db_string");
145  if ( !b ) return StatusCode::FAILURE;
146  m_poolLinks.resize((size_t)b->GetEntries()+2); // Take into account the ##Links and ##Shapes entry of POOL!
147  for(i=0,b->SetAddress(text); i < b->GetEntries(); ++i) {
148  b->GetEvent(i);
149  std::string db, container;
150  int clid = 1, technology = 0, ipar[2] = {-1,-1};
151  for(char* p1 = (char*)text; p1; p1 = ::strchr(++p1,'[')) {
152  char* p2 = ::strchr(p1, '=');
153  char* p3 = ::strchr(p1, ']');
154  if ( p2 && p3 ) {
155  if ( ::strncmp("[DB=", p1, 4) == 0 ) {
156  *p3 = 0;
157  db = p1+4;
158  }
159  else if ( ::strncmp("[CNT=", p1, 5) == 0 ) {
160  *p3 = 0;
161  container = p1+5;
162  }
163  else if ( ::strncmp("[OID=", p1, 5) == 0 ) {
164  *p3 = 0;
165  ::sscanf(p1+5,"%08X,%08X",(unsigned int*)&ipar[0],(unsigned int*)&ipar[1]);
166  }
167  else if ( ::strncmp("[CLID=", p1, 6) == 0 ) {
168  *p3 = 0;
169  ::sscanf(p1+6,"%08X",(unsigned int*)&clid);
170  }
171  else if ( ::strncmp("[TECH=", p1, 6) == 0 ) {
172  *p3 = 0;
173  ::sscanf(p1+6,"%08X",(unsigned int*)&technology);
174  }
175  else {
176  *p3 = *p2 = 0;
177  }
178  *p3 = ']';
179  *p2 = '=';
180  }
181  }
182  c->makeRef("",clid,technology,db,container,-1,m_poolLinks[i+2]);
183  RootRef& r = m_poolLinks[i];
184  msgSvc() << "Add link[" << i << "]:" << db << container << " [" << r.dbase << "," << r.container << "] "
185  << " tech:" << hex << setw(8) << r.svc << " CLID:" << setw(8) << r.clid << dec << endmsg;
186  }
187  return StatusCode::SUCCESS;
188  }
189  };
190 }
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
TFile * file() const
Direct access to TFile structure.
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::vector< Gaudi::RootRef > m_poolLinks
Image of the POOL ##Links table.
Definition: PoolTool.h:19
virtual StatusCode saveRefs()
Save references section when closing data file (NOT SUPPORTED)
Definition: PoolTool.h:110
const std::string & getLink(int which) const
Access link name from saved index.
std::vector< int > links
The links of the link manager.
Definition: RootRefs.h:73
Persistent reference object containing all leafs and links corresponding to a Gaudi DataObject...
Definition: RootRefs.h:71
StatusCode readRefs()
Internal helper to read reference tables ##Params and ##Links.
Definition: PoolTool.h:113
int dbase
Data members to define object location in the persistent world.
Definition: RootRefs.h:32
Persistent reference object.
Definition: RootRefs.h:30
PoolTool(RootDataConnection *con)
Standard constructor.
Definition: PoolTool.h:23
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
void makeRef(IRegistry *pA, RootRef &ref)
Create reference object from registry entry.
const std::string CSTR
virtual RootRef poolRef(size_t i) const
Internal overload to facilitate the access to POOL files.
Definition: PoolTool.h:31
const std::string & getCont(int which) const
Access container name from saved index.
virtual TBranch * getBranch(CSTR, CSTR branch_name)
Access data branch by name: Get existing branch in read only mode.
Definition: PoolTool.h:89
virtual int loadRefs(CSTR, CSTR cnt, unsigned long entry, RootObjectRefs &refs)
Load references object from file.
Definition: PoolTool.h:34
string _treeName(string t)
Convert TES object identifier to ROOT tree name.
Definition: PoolTool.h:26
int makeLink(const std::string &p)
Convert path string to path index.
RootDataConnection * c
Pointer to containing data connection object.
list i
Definition: ana.py:128
Concrete implementation of the IDataConnection interface to access ROOT files.
std::vector< RootRef > refs
The references corresponding to the next layer of items in the data store.
Definition: RootRefs.h:75
Helper functions to set/get the application return code.
Definition: __init__.py:1