The Gaudi Framework  master (37c0b60a)
PoolTool.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #include <GaudiKernel/Incident.h>
12 #include <RootCnv/PoolClasses.h>
13 #include <algorithm>
14 /*
15  * Gaudi namespace declaration
16  */
17 namespace Gaudi {
18 
28  class PoolTool : virtual public RootDataConnection::Tool {
31 
32  public:
34  PoolTool( RootDataConnection* con ) { c = con; }
35 
37  string _treeName( std::string_view sr ) {
38  std::string t{ sr };
39  std::replace( begin( t ), end( t ), '/', '_' );
40  return t;
41  }
42 
43  RootRef poolRef( size_t i ) const override { return m_poolLinks[i]; }
44 
46  int loadRefs( std::string_view /* section */, std::string_view cnt, unsigned long entry,
47  RootObjectRefs& refs ) override {
48  auto ti = sections().find( cnt );
49  TTree* t = ( ti != sections().end() ? ti->second : nullptr );
50  if ( !t ) { t = (TTree*)c->file()->Get( _treeName( cnt ).c_str() ); }
51  if ( t ) {
52  TBranch* b1 = t->GetBranch( "Links" );
53  TBranch* b2 = t->GetBranch( "Refs" );
54  MsgStream& msg = msgSvc();
55  if ( b1 && b2 ) {
56  LinkManager lm, *plm = &lm;
57  PoolDbLinkManager mgr, *pmgr = &mgr;
58  b1->SetAutoDelete( kFALSE );
59  b2->SetAutoDelete( kFALSE );
60  b1->SetAddress( &plm );
61  b2->SetAddress( &pmgr );
62  int nb1 = b1->GetEvent( entry );
63  int nb2 = b2->GetEvent( entry );
64  if ( nb1 > 1 && nb2 > 1 ) {
65  size_t ref_size = mgr.references().size();
66  refs.refs.resize( ref_size );
67  msg << MSG::VERBOSE;
68  for ( size_t j = 0; j < ref_size; ++j ) {
69  const pair<int, int>& oid = mgr.references()[j]->m_oid;
70  string loc = mgr.links()[j].substr( 1 );
71  RootRef& r = refs.refs[j];
72  if ( oid.first >= 0 ) {
73  r = m_poolLinks[oid.first];
74  r.entry = oid.second;
75  r.link = c->makeLink( loc );
76  msg << "Add leaf:" << oid.first << "->" << loc << " from " << c->getDb( r.dbase ) << "#"
77  << c->getCont( r.container ) << " Link:" << c->getLink( r.link ) << " CLID:" << hex << r.clid
78  << " Typ:" << hex << int( r.svc ) << " Ent:" << dec << r.entry << endl;
79  }
80  }
81  for ( int i = 0, n = lm.size(); i < n; ++i ) {
82  const LinkManager::Link* lnk = lm.link( i );
83  int link_id = c->makeLink( lnk->path() );
84  msg << "Add Link:" << lnk->path() << endl;
85  refs.links.push_back( link_id );
86  }
87  return nb1 + nb2;
88  }
89  }
90  msg << MSG::ERROR << "Failed to access POOL Ref/Link branches:" << cnt << " [" << _treeName( cnt ) << "]"
91  << endmsg;
92  t->Print();
93  }
94  return -1;
95  }
96 
98  TBranch* getBranch( std::string_view /* section */, std::string_view branch_name ) override {
99  auto ti = sections().find( branch_name );
100  TTree* t = ( ti != sections().end() ? ti->second : nullptr );
101  if ( t ) { return (TBranch*)t->GetListOfBranches()->At( 0 ); }
102  string tname = _treeName( branch_name );
103  t = (TTree*)c->file()->Get( tname.c_str() ); // c->getSection(tname);
104  if ( t ) {
105  TBranch* b = (TBranch*)t->GetListOfBranches()->At( 0 );
106  if ( b ) {
107  sections()[std::string{ branch_name }] = t;
108  return b;
109  }
110  incidentSvc()->fireIncident( Incident( c->pfn(), IncidentType::CorruptedInputFile ) );
111  msgSvc() << MSG::ERROR << "Failed to access POOL branch:" << branch_name << " [" << tname << "]" << endmsg;
112  t->Print();
113  }
114  return nullptr;
115  }
116 
118  StatusCode saveRefs() override { return StatusCode::FAILURE; }
119 
121  StatusCode readRefs() override {
122  int i;
123  char text[2048];
124  msgSvc() << MSG::VERBOSE;
125 
126  // First read ##Params
127  TTree* t = (TTree*)c->file()->Get( "##Params" );
128  if ( !t ) return StatusCode::FAILURE;
129  TBranch* b = t->GetBranch( "db_string" );
130  if ( !b ) return StatusCode::FAILURE;
131  for ( i = 0, b->SetAddress( text ); i < b->GetEntries(); ++i ) {
132  b->GetEvent( i );
133  char* id1 = strstr( text, "[NAME=" );
134  char* id2 = strstr( text, "[VALUE=" );
135  if ( id1 && id2 ) {
136  id1 += 6;
137  id2 += 7;
138  char* id11 = strstr( id1, "]" );
139  char* id22 = strstr( id2, "]" );
140  if ( id11 && id22 ) {
141  *id11 = 0;
142  *id22 = 0;
143  params().emplace_back( id1, id2 );
144  msgSvc() << "Param:" << id1 << "=" << id2 << "." << endmsg;
145  }
146  }
147  }
148 
149  // Read ##Links
150  t = (TTree*)c->file()->Get( "##Links" );
151  if ( !t ) return StatusCode::FAILURE;
152  b = t->GetBranch( "db_string" );
153  if ( !b ) return StatusCode::FAILURE;
154  m_poolLinks.resize( (size_t)b->GetEntries() + 2 ); // Take into account the ##Links and ##Shapes entry of POOL!
155  for ( i = 0, b->SetAddress( text ); i < b->GetEntries(); ++i ) {
156  b->GetEvent( i );
157  std::string db, container;
158  int clid = 1, technology = 0, ipar[2] = { -1, -1 };
159  for ( char* p1 = (char*)text; p1; p1 = ::strchr( ++p1, '[' ) ) {
160  char* p2 = ::strchr( p1, '=' );
161  char* p3 = ::strchr( p1, ']' );
162  if ( p2 && p3 ) {
163  if ( ::strncmp( "[DB=", p1, 4 ) == 0 ) {
164  *p3 = 0;
165  db = p1 + 4;
166  } else if ( ::strncmp( "[CNT=", p1, 5 ) == 0 ) {
167  *p3 = 0;
168  container = p1 + 5;
169  } else if ( ::strncmp( "[OID=", p1, 5 ) == 0 ) {
170  *p3 = 0;
171  ::sscanf( p1 + 5, "%08X,%08X", (unsigned int*)&ipar[0], (unsigned int*)&ipar[1] );
172  } else if ( ::strncmp( "[CLID=", p1, 6 ) == 0 ) {
173  *p3 = 0;
174  ::sscanf( p1 + 6, "%08X", (unsigned int*)&clid );
175  } else if ( ::strncmp( "[TECH=", p1, 6 ) == 0 ) {
176  *p3 = 0;
177  ::sscanf( p1 + 6, "%08X", (unsigned int*)&technology );
178  } else {
179  *p3 = *p2 = 0;
180  }
181  *p3 = ']';
182  *p2 = '=';
183  }
184  }
185  c->makeRef( "", clid, technology, db, container, -1, m_poolLinks[i + 2] );
186  RootRef& r = m_poolLinks[i];
187  msgSvc() << "Add link[" << i << "]:" << db << container << " [" << r.dbase << "," << r.container << "] "
188  << " tech:" << hex << setw( 8 ) << r.svc << " CLID:" << setw( 8 ) << r.clid << dec << endmsg;
189  }
190  return StatusCode::SUCCESS;
191  }
192  };
193 } // namespace Gaudi
std::vector::resize
T resize(T... args)
MSG::hex
MsgStream & hex(MsgStream &log)
Definition: MsgStream.h:281
std::string
STL class.
Gaudi::RootRef::clid
int clid
Definition: RootRefs.h:42
AlgSequencer.p2
p2
Definition: AlgSequencer.py:30
std::vector< Gaudi::RootRef >
std::map::find
T find(T... args)
std::vector::size
T size(T... args)
Gaudi::RootDataConnection::getLink
const std::string & getLink(int which) const
Access link name from saved index.
Definition: RootDataConnection.h:351
Gaudi::RootRef::dbase
int dbase
Data members to define object location in the persistent world.
Definition: RootRefs.h:42
GaudiMP.FdsRegistry.msg
msg
Definition: FdsRegistry.py:19
Gaudi::RootDataConnection::Tool::msgSvc
MsgStream & msgSvc() const
Definition: RootDataConnection.h:231
Gaudi::RootDataConnection::Tool::c
RootDataConnection * c
Pointer to containing data connection object.
Definition: RootDataConnection.h:223
Gaudi::PoolTool::getBranch
TBranch * getBranch(std::string_view, std::string_view branch_name) override
Access data branch by name: Get existing branch in read only mode.
Definition: PoolTool.h:98
IIncidentSvc::fireIncident
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
Gaudi::PoolTool::loadRefs
int loadRefs(std::string_view, std::string_view cnt, unsigned long entry, RootObjectRefs &refs) override
Load references object from file.
Definition: PoolTool.h:46
Gaudi::RootDataConnection::Tool::incidentSvc
IIncidentSvc * incidentSvc() const
Definition: RootDataConnection.h:232
Gaudi::RootObjectRefs
Definition: RootRefs.h:68
std::replace
T replace(T... args)
Gaudi::RootDataConnection
Definition: RootDataConnection.h:112
Gaudi::PoolTool::m_poolLinks
std::vector< Gaudi::RootRef > m_poolLinks
Image of the POOL ##Links table.
Definition: PoolTool.h:30
bug_34121.t
t
Definition: bug_34121.py:31
Gaudi::PoolTool::readRefs
StatusCode readRefs() override
Internal helper to read reference tables ##Params and ##Links.
Definition: PoolTool.h:121
Gaudi::RootRef::link
int link
Definition: RootRefs.h:42
Gaudi::Utils::begin
AttribStringParser::Iterator begin(const AttribStringParser &parser)
Definition: AttribStringParser.h:136
Gaudi::RootDataConnection::getDb
const std::string & getDb(int which) const
Access database/file name from saved index.
Definition: RootDataConnection.cpp:486
Gaudi::RootRef::svc
int svc
Definition: RootRefs.h:42
CFinViewTest.b2
b2
Definition: CFinViewTest.py:99
StatusCode
Definition: StatusCode.h:65
ProduceConsume.j
j
Definition: ProduceConsume.py:104
Gaudi::RootDataConnection::Tool::sections
Sections & sections() const
Definition: RootDataConnection.h:234
MSG::dec
MsgStream & dec(MsgStream &log)
Definition: MsgStream.h:277
Gaudi::RootDataConnection::getCont
const std::string & getCont(int which) const
Access container name from saved index.
Definition: RootDataConnection.h:346
Gaudi::RootRef::container
int container
Definition: RootRefs.h:42
Gaudi::RootRef
Definition: RootRefs.h:40
AlgSequencer.p1
p1
Definition: AlgSequencer.py:29
GaudiPython.Bindings.nullptr
nullptr
Definition: Bindings.py:87
Gaudi::PoolTool::PoolTool
PoolTool(RootDataConnection *con)
Standard constructor.
Definition: PoolTool.h:34
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
Gaudi::RootDataConnection::makeRef
void makeRef(const IRegistry &pA, RootRef &ref)
Create reference object from registry entry.
Definition: RootDataConnection.cpp:646
Gaudi::RootDataConnection::file
TFile * file() const
Direct access to TFile structure.
Definition: RootDataConnection.h:264
MsgStream
Definition: MsgStream.h:33
Gaudi::PoolTool
Definition: PoolTool.h:28
Gaudi
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition: __init__.py:1
Gaudi::RootRef::entry
int entry
Definition: RootRefs.h:42
cpluginsvc.n
n
Definition: cpluginsvc.py:234
Gaudi::RootDataConnection::makeLink
int makeLink(std::string_view p)
Convert path string to path index.
Definition: RootDataConnection.cpp:478
Gaudi::RootDataConnection::Tool::params
ParamMap & params() const
Definition: RootDataConnection.h:230
std::vector::emplace_back
T emplace_back(T... args)
MSG::VERBOSE
@ VERBOSE
Definition: IMessageSvc.h:25
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
Gaudi::RootDataConnection::Tool::refs
TTree * refs() const
Definition: RootDataConnection.h:226
Gaudi::Units::sr
constexpr double sr
Definition: SystemOfUnits.h:132
MSG::ERROR
@ ERROR
Definition: IMessageSvc.h:25
Gaudi::PoolTool::poolRef
RootRef poolRef(size_t i) const override
Internal overload to facilitate the access to POOL files.
Definition: PoolTool.h:43
CFinViewTest.b1
b1
Definition: CFinViewTest.py:96
std::map::end
T end(T... args)
IOTest.end
end
Definition: IOTest.py:125
Gaudi::IDataConnection::pfn
const std::string & pfn() const
Access physical file name.
Definition: IIODataManager.h:65
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
PoolClasses.h
Incident.h
Incident
Definition: Incident.h:27
Gaudi::PoolTool::saveRefs
StatusCode saveRefs() override
Save references section when closing data file (NOT SUPPORTED)
Definition: PoolTool.h:118
Gaudi::RootDataConnection::Tool
Definition: RootDataConnection.h:212
Gaudi::PoolTool::_treeName
string _treeName(std::string_view sr)
Convert TES object identifier to ROOT tree name.
Definition: PoolTool.h:37