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