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