The Gaudi Framework  master (ba5b4fb7)
Loading...
Searching...
No Matches
RootEvtSelector.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2026 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\***********************************************************************************/
12#include <GaudiKernel/ClassID.h>
18#include <RootCnv/RootCnvSvc.h>
21#include <TBranch.h>
22#include <vector>
23
24// Forward declarations
25class TBranch;
26
27/*
28 * Gaudi namespace declaration
29 */
30namespace Gaudi {
31
41 public:
43 typedef std::vector<std::string> Files;
44
45 private:
51 Files::const_iterator m_fiter;
53 long m_entry;
55 TBranch* m_branch;
57 std::string m_fid;
58
59 public:
62 : m_sel( s ), m_fiter( m_files.begin() ), m_entry( -1 ), m_branch( nullptr ) {}
63
64 const Files& files() const { return m_files; }
66 void setFiles( const Files& f ) {
67 m_files = f;
68 m_fiter = m_files.begin();
69 }
70
71 void* identifier() const override { return const_cast<RootEvtSelector*>( m_sel ); }
73 Files::const_iterator fileIterator() const { return m_fiter; }
75 void setFileIterator( Files::const_iterator i ) { m_fiter = i; }
77 long entry() const { return m_entry; }
79 void setEntry( long e ) { m_entry = e; }
81 void setFID( const std::string& fid ) { m_fid = fid; }
83 const std::string& fid() const { return m_fid; }
85 TBranch* branch() const { return m_branch; }
87 void setBranch( TBranch* b ) { m_branch = b; }
88 };
89} // namespace Gaudi
90
91using namespace Gaudi;
92using namespace std;
93
94// Helper method to issue error messages
95StatusCode RootEvtSelector::error( const string& msg ) const {
96 MsgStream log( msgSvc(), name() );
97 log << MSG::ERROR << msg << endmsg;
99}
100
101// IService implementation: Db event selector override
103 // Initialize base class
105 if ( !status.isSuccess() ) { return error( "Error initializing base class Service!" ); }
106
108 if ( !ipers ) { return error( "Unable to locate IPersistencySvc interface of " + m_persName ); }
109 IConversionSvc* cnvSvc = nullptr;
111 status = ipers->getService( itm.name(), cnvSvc );
112 if ( !status.isSuccess() ) {
113 status = ipers->getService( itm.type(), cnvSvc );
114 if ( !status.isSuccess() ) {
115 return error( "Unable to locate IConversionSvc interface of database type " + m_cnvSvcName );
116 }
117 }
118 m_dbMgr = dynamic_cast<RootCnvSvc*>( cnvSvc );
119 if ( !m_dbMgr ) {
120 cnvSvc->release();
121 return error( "Unable to localize service:" + m_cnvSvcName );
122 }
123 m_dbMgr->addRef();
124
125 // Get DataSvc
126 auto eds = serviceLocator()->service<IDataManagerSvc>( "EventDataSvc" );
127 if ( !eds ) { return error( "Unable to localize service EventDataSvc" ); }
128 m_rootCLID = eds->rootCLID();
129 m_rootName = eds->rootName();
130 MsgStream log( msgSvc(), name() );
131 log << MSG::DEBUG << "Selection root:" << m_rootName << " CLID:" << m_rootCLID << endmsg;
132 return status;
133}
134
135// IService implementation: Service finalization
137 // Initialize base class
138 if ( m_dbMgr ) m_dbMgr->release();
139 m_dbMgr = nullptr; // release
140 return Service::finalize();
141}
142
143// Create a new event loop context
144StatusCode RootEvtSelector::createContext( Context*& refpCtxt ) const {
145 refpCtxt = new RootEvtSelectorContext( this );
146 return StatusCode::SUCCESS;
147}
148
149// Access last item in the iteration
150StatusCode RootEvtSelector::last( Context& /*refContext*/ ) const { return StatusCode::FAILURE; }
151
152// Get next iteration item from the event loop context
153StatusCode RootEvtSelector::next( Context& ctxt ) const {
154 RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>( &ctxt );
155 if ( pCtxt ) {
156 TBranch* b = pCtxt->branch();
157 if ( !b ) {
158 auto fileit = pCtxt->fileIterator();
159 pCtxt->setBranch( nullptr );
160 pCtxt->setEntry( -1 );
161 if ( fileit != pCtxt->files().end() ) {
162 RootDataConnection* con = nullptr;
163 string in = *fileit;
164 StatusCode sc = m_dbMgr->connectDatabase( in, IDataConnection::READ, &con );
165 if ( sc.isSuccess() ) {
166 string section = m_rootName[0] == '/' ? m_rootName.substr( 1 ) : m_rootName;
167 b = con->getBranch( section, m_rootName );
168 if ( b ) {
169 pCtxt->setFID( con->fid() );
170 pCtxt->setBranch( b );
171 return next( ctxt );
172 }
173 }
174 m_dbMgr->disconnect( in ).ignore();
175 pCtxt->setFileIterator( ++fileit );
176 return next( ctxt );
177 }
178 return StatusCode::FAILURE;
179 }
180 long ent = pCtxt->entry();
181 Long64_t nent = b->GetEntries();
182 if ( nent > ( ent + 1 ) ) {
183 pCtxt->setEntry( ++ent );
184 return StatusCode::SUCCESS;
185 }
186 auto fit = pCtxt->fileIterator();
187 pCtxt->setFileIterator( ++fit );
188 pCtxt->setEntry( -1 );
189 pCtxt->setBranch( nullptr );
190 pCtxt->setFID( "" );
191 return next( ctxt );
192 }
193 return StatusCode::FAILURE;
194}
195
196// Get next iteration item from the event loop context
197StatusCode RootEvtSelector::next( Context& ctxt, int jump ) const {
198 if ( jump > 0 ) {
199 for ( int i = 0; i < jump; ++i ) {
200 StatusCode status = next( ctxt );
201 if ( !status.isSuccess() ) { return status; }
202 }
203 return StatusCode::SUCCESS;
204 }
205 return StatusCode::FAILURE;
206}
207
208// Get previous iteration item from the event loop context
209StatusCode RootEvtSelector::previous( Context& /* ctxt */ ) const {
210 return error( "EventSelector Iterator, operator -- not supported " );
211}
212
213// Get previous iteration item from the event loop context
214StatusCode RootEvtSelector::previous( Context& ctxt, int jump ) const {
215 if ( jump > 0 ) {
216 for ( int i = 0; i < jump; ++i ) {
217 StatusCode status = previous( ctxt );
218 if ( !status.isSuccess() ) { return status; }
219 }
220 return StatusCode::SUCCESS;
221 }
222 return StatusCode::FAILURE;
223}
224
225// Rewind the dataset
226StatusCode RootEvtSelector::rewind( Context& ctxt ) const {
227 RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>( &ctxt );
228 if ( pCtxt ) {
229 auto fileit = pCtxt->fileIterator();
230 if ( fileit != pCtxt->files().end() ) {
231 string input = *fileit;
232 m_dbMgr->disconnect( input ).ignore();
233 }
234 pCtxt->setFID( "" );
235 pCtxt->setEntry( -1 );
236 pCtxt->setBranch( nullptr );
237 pCtxt->setFileIterator( pCtxt->files().begin() );
238 return StatusCode::SUCCESS;
239 }
240 return StatusCode::FAILURE;
241}
242
243// Create new Opaque address corresponding to the current record
244StatusCode RootEvtSelector::createAddress( const Context& ctxt, IOpaqueAddress*& pAddr ) const {
245 const RootEvtSelectorContext* pctxt = dynamic_cast<const RootEvtSelectorContext*>( &ctxt );
246 if ( pctxt ) {
247 long ent = pctxt->entry();
248 if ( ent >= 0 ) {
249 auto fileit = pctxt->fileIterator();
250 if ( fileit != pctxt->files().end() ) {
251 const string par[2] = { pctxt->fid(), m_rootName };
252 const unsigned long ipar[2] = { 0, (unsigned long)ent };
253 return m_dbMgr->createAddress( m_dbMgr->repSvcType(), m_rootCLID, &par[0], &ipar[0], pAddr );
254 }
255 }
256 }
257 pAddr = nullptr;
258 return StatusCode::FAILURE;
259}
260
261// Release existing event iteration context
263 RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>( ctxt );
264 if ( pCtxt ) {
265 delete pCtxt;
266 return StatusCode::SUCCESS;
267 }
268 return StatusCode::FAILURE;
269}
270
271// Will set a new criteria for the selection of the next list of events and will change
272// the state of the context in a way to point to the new list.
273StatusCode RootEvtSelector::resetCriteria( const string& criteria, Context& context ) const {
274 MsgStream log( msgSvc(), name() );
275 RootEvtSelectorContext* ctxt = dynamic_cast<RootEvtSelectorContext*>( &context );
276 string db, typ, item, sel, stmt, aut, addr;
277 if ( ctxt ) {
278 if ( criteria.compare( 0, 5, "FILE " ) == 0 ) {
279 // The format for the criteria is:
280 // FILE filename1, filename2 ...
281 db = criteria.substr( 5 );
282 } else {
284 for ( auto attrib : Parser( criteria ) ) {
285 string tmp = attrib.tag.substr( 0, 3 );
286 if ( tmp == "DAT" ) {
287 db = std::move( attrib.value );
288 } else if ( tmp == "OPT" ) {
289 if ( attrib.value.compare( 0, 3, "REA" ) != 0 ) {
290 log << MSG::ERROR << "Option:\"" << attrib.value << "\" not valid" << endmsg;
291 return StatusCode::FAILURE;
292 }
293 } else if ( tmp == "TYP" ) {
294 typ = std::move( attrib.value );
295 } else if ( tmp == "ADD" ) {
296 item = std::move( attrib.value );
297 } else if ( tmp == "SEL" ) {
298 sel = std::move( attrib.value );
299 } else if ( tmp == "FUN" ) {
300 stmt = std::move( attrib.value );
301 } else if ( tmp == "AUT" ) {
302 aut = std::move( attrib.value );
303 } else if ( tmp == "COL" ) {
304 addr = std::move( attrib.value );
305 }
306 }
307 }
308 // It's now time to parse the criteria for the event selection
309 // The format for the criteria is:
310 // FILE filename1, filename2 ...
311 // JOBID number1-number2, number3, ...
313 string rest = db;
314 files.clear();
315 while ( true ) {
316 int ipos = rest.find_first_not_of( " ," );
317 if ( ipos == -1 ) break;
318 rest = rest.substr( ipos, string::npos ); // remove blanks before
319 int lpos = rest.find_first_of( " ," ); // locate next blank
320
321 files.push_back( rest.substr( 0, lpos == -1 ? string::npos : lpos ) ); // insert in list
322 if ( lpos == -1 ) break;
323 rest = rest.substr( lpos, string::npos ); // get the rest
324 }
325 ctxt->setFiles( files );
326 ctxt->setFileIterator( ctxt->files().begin() );
327 return StatusCode::SUCCESS;
328 }
329 return error( "Invalid iteration context." );
330}
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
const SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
MsgStream & msg() const
shortcut for the method msgStream(MSG::INFO)
const std::string & fid() const
Access file id.
Description:
Definition RootCnvSvc.h:61
Concrete implementation of the IDataConnection interface to access ROOT files.
TBranch * getBranch(std::string_view section, std::string_view branch_name)
Access data branch by name: Get existing branch in read only mode.
ROOT specific event selector context.
TBranch * m_branch
Reference to the top level branch (typically /Event) used to iterate.
Files::const_iterator fileIterator() const
Access to the file iterator.
long entry() const
Access to the current event entry number.
Files m_files
The file container managed by this context.
long m_entry
Current entry of current file.
const Files & files() const
Access to the file container.
void * identifier() const override
Context identifier.
TBranch * branch() const
Access to the top level branch (typically /Event) used to iterate.
const std::string & fid() const
Access connection fid.
void setFiles(const Files &f)
Set the file container.
std::string m_fid
Connection fid.
void setEntry(long e)
Set current event entry number.
Files::const_iterator m_fiter
The iterator to the.
void setFileIterator(Files::const_iterator i)
Set file iterator.
void setFID(const std::string &fid)
Set connection FID.
const RootEvtSelector * m_sel
Reference to the hosting event selector instance.
void setBranch(TBranch *b)
Set the top level branch (typically /Event) used to iterate.
RootEvtSelectorContext(const RootEvtSelector *s)
Standard constructor with initialization.
std::vector< std::string > Files
Definition of the file container.
Concrete event selector implementation to access ROOT files.
StatusCode rewind(Context &refCtxt) const override
Rewind the dataset.
StatusCode resetCriteria(const std::string &cr, Context &c) const override
Will set a new criteria for the selection of the next list of events and will change the state of the...
StatusCode releaseContext(Context *&refCtxt) const override
Release existing event iteration context.
CLID m_rootCLID
Class id of root node to create opaque address.
StatusCode next(Context &refCtxt) const override
Get next iteration item from the event loop context.
StatusCode initialize() override
IService implementation: Db event selector override.
StatusCode error(const std::string &msg) const
Helper method to issue error messages.
StatusCode createContext(Context *&refpCtxt) const override
Create a new event loop context.
StatusCode createAddress(const Context &refCtxt, IOpaqueAddress *&) const override
Create new Opaque address corresponding to the current record.
StatusCode previous(Context &refCtxt) const override
Get previous iteration item from the event loop context.
StatusCode last(Context &refContext) const override
Access last item in the iteration.
StatusCode finalize() override
IService implementation: Service finalization.
Gaudi::Property< std::string > m_persName
std::string m_cnvSvcName
Property; Name of the concversion service used to create opaque addresses.
std::string m_rootName
Property: Name of the ROOT entry name.
RootCnvSvc * m_dbMgr
Reference to the corresponding conversion service.
Parse attribute strings allowing iteration over the various attributes.
Helper class to parse a string of format "type/name".
const std::string & type() const
const std::string & name() const
virtual unsigned long release() const =0
Release Interface instance.
Opaque address interface definition.
Data persistency service interface.
virtual SmartIF< IService > & service(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true)=0
Returns a smart pointer to a service.
Definition of the MsgStream class used to transmit messages.
Definition MsgStream.h:29
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition Service.cpp:336
StatusCode finalize() override
Definition Service.cpp:223
const std::string & name() const override
Retrieve name of the service.
Definition Service.cpp:333
StatusCode initialize() override
Definition Service.cpp:118
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
bool isSuccess() const
Definition StatusCode.h:314
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition __init__.py:1
@ DEBUG
Definition IMessageSvc.h:22
@ ERROR
Definition IMessageSvc.h:22
STL namespace.