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