| The Gaudi Framework v32r1 (f65d50dc)

RootTool.h
Go to the documentation of this file.
1 #include <algorithm>
2 /*
3 * Gaudi namespace declaration
4 */
5 namespace Gaudi {
6
16 class RootTool : virtual public RootDataConnection::Tool {
17 public:
19 RootTool( RootDataConnection* con ) { c = con; }
21 TBranch* getBranch( std::string_view section, std::string_view branch_name ) override {
22 std::string n{branch_name};
23 n += '.';
24 for ( int i = 0, m = n.length() - 1; i < m; ++i )
25 if ( !isalnum( n[i] ) ) n[i] = '_';
26 TTree* t = c->getSection( section );
27 TBranch* b = t ? t->GetBranch( n.c_str() ) : nullptr;
28 if ( !b ) b = t ? t->GetBranch( std::string{branch_name}.c_str() ) : nullptr;
29 if ( b ) b->SetAutoDelete( kFALSE );
30 return b;
31 }
33 int loadRefs( std::string_view section, std::string_view cnt, unsigned long entry, RootObjectRefs& refs ) override {
34 TBranch* b = getBranch( section, std::string{cnt} + "#R" );
35 RootObjectRefs* prefs = &refs;
36 if ( b ) {
37 b->SetAddress( &prefs );
38 int nb = b->GetEntry( entry );
39 if ( nb >= 1 ) {
40 const MergeSections& ms = c->mergeSections();
41 if ( !ms.empty() ) {
42 MsgStream& msg = msgSvc();
43 msgSvc() << MSG::VERBOSE;
44 pair<const RootRef*, const ContainerSection*> ls = c->getMergeSection( cnt, entry );
45 if ( ls.first ) {
46 if ( ls.first->dbase >= 0 ) {
47 // Now patch the references and links 'en block' to be efficient
48 // First the leafs from the TES
49 if ( msg.isActive() ) {
50 msg << "Refs: LS [" << entry << "] -> " << ls.first->dbase << "," << ls.first->container << ","
51 << ls.first->link << "," << ls.first->entry << endmsg;
52 }
53 for ( size_t j = 0, n = refs.refs.size(); j < n; ++j ) {
54 RootRef& r = refs.refs[j];
55 if ( r.entry >= 0 && r.dbase >= 0 ) {
56 int db = r.dbase + ls.first->dbase;
57 if ( c->getDb( db ) == c->fid() ) {
58 if ( r.dbase ) r.dbase += ls.first->dbase;
59 if ( r.container ) r.container += ls.first->container;
60 if ( r.link ) r.link += ls.first->link;
61 const string& rc = c->getCont( r.container );
62 auto k = ms.find( rc );
63 if ( k != ms.end() ) {
64 const auto& cs = ( *k ).second;
65 r.entry = ( ls.first->entry >= 0 && ls.first->entry < (int)cs.size() )
66 ? cs[ls.first->entry].start + r.entry
67 : -1;
68 if ( msg.isActive() ) {
69 msg << "Add link [" << r.entry << "," << ls.first->entry << "," << ls.first->container << ","
70 << r.container << "," << r.entry << "] to -> " << rc << endmsg;
71 }
72 } else {
73 msg << MSG::WARNING << c->fid() << " [" << c->getDb( db ) << "] Evt:" << entry
74 << " Invalid link to " << rc << endmsg;
75 msg << MSG::VERBOSE;
76 }
77 }
78 }
79 }
81 std::for_each( std::begin( refs.links ), std::end( refs.links ),
82 [&]( int& i ) { i += ls.first->link; } );
83 }
84 return nb;
85 }
86 return -1;
87 }
88 return nb;
89 }
90 }
91 return -1;
92 }
94 void addParam( ParamMap& c, char* p ) {
95 char* q = strchr( p, '=' );
96 if ( q ) {
97 *q = 0;
98 c.emplace_back( p, ++q );
99 }
100 }
102 void addEntry( StringVec& c, char* val ) { c.push_back( val ); }
104 template <class C, class F>
105 StatusCode readBranch( TTree* t, const char* nam, C& v, F pmf ) {
106 char text[2048];
107 TBranch* b = t->GetBranch( nam );
108 if ( b ) {
109 TLeaf* l = b->GetLeaf( nam );
110 if ( l ) {
111 StatusCode sc = StatusCode::SUCCESS;
112 b->SetAddress( text );
113 msgSvc() << MSG::VERBOSE;
114 for ( Long64_t i = 0, n = b->GetEntries(); i < n; ++i ) {
115 if ( b->GetEntry( i ) > 0 ) {
116 char* p = (char*)l->GetValuePointer();
117 msgSvc() << "Add Value[" << b->GetName() << "]:" << p << endmsg;
118 ( this->*pmf )( v, p );
119 } else {
120 sc = RootDataConnection::Status::ROOT_READ_ERROR;
121 }
122 }
123 return sc;
124 }
125 }
126 msgSvc() << MSG::ERROR << "Failed to read '" << nam << "' table." << endmsg;
127 return RootDataConnection::Status::ROOT_READ_ERROR;
128 }
130 bool get( const string& dsc, pair<string, ContainerSection>& e ) {
131 if ( dsc != "[END-OF-SECTION]" ) {
132 size_t id1 = dsc.find( "[CNT=" );
133 size_t id2 = dsc.find( "[START=" );
134 size_t id3 = dsc.find( "[LEN=" );
135 if ( id1 != string::npos && id2 != string::npos && id3 != string::npos ) {
136 string cnt = dsc.substr( id1 + 5, id2 - 1 - 5 );
137 int section_start = std::stoi( dsc.substr( id2 + 7, id3 - id2 - 8 ) );
138 int section_length = std::stoi( dsc.substr( id3 + 5, dsc.find( "]", id3 + 5 ) - id3 - 5 ) );
139 e.first = cnt;
140 e.second = ContainerSection( section_start, section_length );
141 return true;
142 }
143 }
144 e.first.clear();
145 e.second = ContainerSection( -1, -1 );
146 return false;
147 }
149 void analyzeMergeMap( StringVec& tmp ) {
150 LinkSections& ls = linkSections();
151 MergeSections& ms = mergeSections();
152 pair<string, ContainerSection> e;
153 MsgStream& msg = msgSvc();
154 RootRef r;
155 int cnt = 0;
156 ls.clear();
157 ms.clear();
158 msg << MSG::VERBOSE;
159 r.dbase = r.container = r.link = r.clid = r.svc = r.entry = 0;
160 for ( const auto& i : tmp ) {
161 if ( get( i, e ) ) {
162 msg << "Added Merge Section:" << e.first << endmsg;
163 ms[e.first].push_back( e.second );
164 if ( e.first == "Links" )
165 r.link = e.second.start;
166 else if ( e.first == "Containers" )
167 r.container = e.second.start;
168 else if ( e.first == "Databases" )
169 r.dbase = e.second.start;
170 else if ( e.first == "Params" )
171 r.svc = e.second.start;
172 } else if ( i == "[END-OF-SECTION]" ) {
173 r.entry = cnt;
174 if ( msg.isActive() ) {
175 msg << "Link Section [" << r.entry << "," << ls.size() << "] -> D:" << r.dbase << " C:" << r.container
176 << " L:" << r.link << " P:" << r.svc << endmsg;
177 }
178 ls.push_back( r );
179 cnt++;
180 }
181 }
182 }
184 StatusCode readRefs() override {
185 TTree* t = (TTree*)c->file()->Get( "Sections" );
186 StatusCode sc( StatusCode::SUCCESS, true );
187 StringVec tmp;
188 if ( t && !( sc = readBranch( t, "Sections", tmp, &RootTool::addEntry ) ).isSuccess() )
189 return sc;
190 else if ( refs() ) {
191 analyzeMergeMap( tmp );
192 if ( !( sc = readBranch( refs(), "Databases", dbs(), &RootTool::addEntry ) ).isSuccess() ) return sc;
193 if ( !( sc = readBranch( refs(), "Containers", conts(), &RootTool::addEntry ) ).isSuccess() ) return sc;
194 if ( !( sc = readBranch( refs(), "Links", links(), &RootTool::addEntry ) ).isSuccess() ) return sc;
195 if ( !( sc = readBranch( refs(), "Params", params(), &RootTool::addParam ) ).isSuccess() ) return sc;
196 return sc;
197 }
198 return StatusCode::FAILURE;
199 }
201 string getEntry( const string& c ) { return c; }
203 string getParam( const pair<string, string>& p ) { return p.first + "=" + p.second; }
205 template <class C, class F>
206 StatusCode saveBranch( const char* nam, C& v, F pmf ) {
207 Long64_t i, n;
208 string val, typ = nam;
209 StatusCode sc = StatusCode::SUCCESS;
210 TDirectory::TContext ctxt( c->file() );
211 TBranch* b = refs()->GetBranch( nam );
212 if ( !b ) b = refs()->Branch( nam, 0, ( typ + "/C" ).c_str() );
213 if ( b ) {
214 for ( i = b->GetEntries(), n = Long64_t( v.size() ); i < n; ++i ) {
215 val = ( this->*pmf )( v[size_t( i )] );
216 b->SetAddress( (char*)val.c_str() );
217 msgSvc() << MSG::VERBOSE << "Save Value[" << b->GetName() << "]:" << val << endmsg;
218 if ( b->Fill() < 0 ) sc = StatusCode::FAILURE;
219 }
220 return sc;
221 }
222 return StatusCode::FAILURE;
223 }
225 StatusCode saveRefs() override {
226 if ( refs() ) {
227 if ( !saveBranch( "Databases", dbs(), &RootTool::getEntry ).isSuccess() ) return StatusCode::FAILURE;
228 if ( !saveBranch( "Containers", conts(), &RootTool::getEntry ).isSuccess() ) return StatusCode::FAILURE;
229 if ( !saveBranch( "Links", links(), &RootTool::getEntry ).isSuccess() ) return StatusCode::FAILURE;
230 if ( !saveBranch( "Params", params(), &RootTool::getParam ).isSuccess() ) return StatusCode::FAILURE;
231 return StatusCode::SUCCESS;
232 }
233 return StatusCode::FAILURE;
234 }
235 };
236 } // namespace Gaudi
MsgStream
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
Gaudi::RootTool::readRefs
StatusCode readRefs() override
Read reference tables.
Definition: RootTool.h:184
Gaudi::RootDataConnection::mergeSections
const MergeSections & mergeSections() const
Access merged data section inventory.
Definition: RootDataConnection.h:251
Gaudi::RootDataConnection::Tool::links
StringVec & links() const
Definition: RootDataConnection.h:209
Gaudi::RootTool::getBranch
TBranch * getBranch(std::string_view section, std::string_view branch_name) override
Access data branch by name: Get existing branch in read only mode.
Definition: RootTool.h:21
Gaudi::RootDataConnection::Tool::mergeSections
MergeSections & mergeSections() const
Definition: RootDataConnection.h:215
Gaudi::RootDataConnection::Tool::refs
TTree * refs() const
Definition: RootDataConnection.h:206
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
Gaudi::RootRef::container
int container
Definition: extractEvt.C:36
Gaudi::IDataConnection::fid
const std::string & fid() const
Access file id.
Definition: IIODataManager.h:53
std::end
T end(T... args)
Gaudi::RootDataConnection::Tool::linkSections
LinkSections & linkSections() const
Definition: RootDataConnection.h:214
Gaudi::RootRef::entry
int entry
Definition: extractEvt.C:36
Gaudi::RootDataConnection::Tool::params
ParamMap & params() const
Definition: RootDataConnection.h:210
Gaudi::RootDataConnection::getDb
const std::string & getDb(int which) const
Access database/file name from saved index.
Definition: RootDataConnection.cpp:448
MSG::VERBOSE
Definition: IMessageSvc.h:15
Gaudi::RootTool::getEntry
string getEntry(const string &c)
Helper function to convert string vectors to branch entries.
Definition: RootTool.h:201
std::map< std::string, ContainerSections, std::less<> >
Gaudi::RootObjectRefs
Persistent reference object containing all leafs and links corresponding to a Gaudi DataObject.
Definition: extractEvt.C:71
std::string
STL class.
GaudiPluginService.cpluginsvc.n
n
Definition: cpluginsvc.py:210
Gaudi::RootRef::dbase
int dbase
Data members to define object location in the persistent world.
Definition: extractEvt.C:36
Gaudi::RootRef
Persistent reference object.
Definition: extractEvt.C:34
std::vector::push_back
T push_back(T... args)
Gaudi::RootTool::analyzeMergeMap
void analyzeMergeMap(StringVec &tmp)
Build merge sections from the Sections table entries.
Definition: RootTool.h:149
Gaudi::RootTool
Description:
Definition: RootTool.h:16
Gaudi::RootDataConnection::getCont
const std::string & getCont(int which) const
Access container name from saved index.
Definition: RootDataConnection.h:323
Gaudi::RootTool::saveRefs
StatusCode saveRefs() override
Save/update reference tables.
Definition: RootTool.h:225
Gaudi::RootTool::saveBranch
StatusCode saveBranch(const char *nam, C &v, F pmf)
Helper function to save internal tables.
Definition: RootTool.h:206
Gaudi::RootDataConnection::Tool
Helper class to facilitate an abstraction layer for reading POOL style files with this package.
Definition: RootDataConnection.h:192
Gaudi::RootDataConnection::getSection
TTree * getSection(std::string_view sect, bool create=false)
Access TTree section from section name. The section is created if required.
Definition: RootDataConnection.cpp:357
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
Gaudi::Units::m
constexpr double m
Definition: SystemOfUnits.h:92
IOTest.rc
rc
Definition: IOTest.py:101
Gaudi::RootTool::get
bool get(const string &dsc, pair< string, ContainerSection > &e)
Analyze the Sections table entries.
Definition: RootTool.h:130
Gaudi::RootDataConnection::Tool::dbs
StringVec & dbs() const
Definition: RootDataConnection.h:207
Gaudi::RootDataConnection::Tool::conts
StringVec & conts() const
Definition: RootDataConnection.h:208
Gaudi::RootTool::getParam
string getParam(const pair< string, string > &p)
Helper function to convert parameter vectors to branch entries.
Definition: RootTool.h:203
std::vector::clear
T clear(T... args)
Gaudi::RootDataConnection::getMergeSection
std::pair< const RootRef *, const ContainerSection * > getMergeSection(std::string_view container, int entry) const
Access link section for single container and entry.
Definition: RootDataConnection.cpp:564
Gaudi::RootRef::clid
int clid
Definition: extractEvt.C:36
gaudirun.l
dictionary l
Definition: gaudirun.py:521
Gaudi::RootTool::addParam
void addParam(ParamMap &c, char *p)
Helper function to read params table.
Definition: RootTool.h:94
Gaudi::RootTool::addEntry
void addEntry(StringVec &c, char *val)
Helper function to read string tables.
Definition: RootTool.h:102
Gaudi::RootTool::readBranch
StatusCode readBranch(TTree *t, const char *nam, C &v, F pmf)
Helper function to read internal file tables.
Definition: RootTool.h:105
Gaudi::RootDataConnection::Tool::msgSvc
MsgStream & msgSvc() const
Definition: RootDataConnection.h:211
std::vector::size
T size(T... args)
std::vector< std::pair< std::string, std::string > >
Gaudi::RootDataConnection::Tool::ContainerSection
RootDataConnection::ContainerSection ContainerSection
Definition: RootDataConnection.h:199
Gaudi::RootRef::link
int link
Definition: extractEvt.C:36
std::begin
T begin(T... args)
std::string::c_str
T c_str(T... args)
Gaudi::RootTool::RootTool
RootTool(RootDataConnection *con)
Standard constructor.
Definition: RootTool.h:19
GaudiMP.FdsRegistry.msg
msg
Definition: FdsRegistry.py:8
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:86
MSG::ERROR
Definition: IMessageSvc.h:15
Gaudi::RootDataConnection::Tool::c
RootDataConnection * c
Pointer to containing data connection object.
Definition: RootDataConnection.h:203
Gaudi::RootRef::svc
int svc
Definition: extractEvt.C:36
Gaudi::RootDataConnection::file
TFile * file() const
Direct access to TFile structure.
Definition: RootDataConnection.h:243
MSG::WARNING
Definition: IMessageSvc.h:15
Gaudi::RootTool::loadRefs
int loadRefs(std::string_view section, std::string_view cnt, unsigned long entry, RootObjectRefs &refs) override
Load references object from file.
Definition: RootTool.h:33
std::for_each
T for_each(T... args)
Gaudi::RootDataConnection
Concrete implementation of the IDataConnection interface to access ROOT files.
Definition: RootDataConnection.h:93
std::stoi
T stoi(T... args)
Gaudi::Units::ms
constexpr double ms
Definition: SystemOfUnits.h:134
Gaudi
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192