The Gaudi Framework  v32r0 (3325bb39)
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
13 # include "RootCnv/RootEvtSelector.h"
14 # include <vector>
15 
16 // Forward declarations
17 class TBranch;
18 
19 /*
20  * Gaudi namespace declaration
21  */
22 namespace Gaudi {
23 
33  public:
36 
37  private:
41  Files m_files;
43  Files::const_iterator m_fiter;
45  long m_entry;
47  TBranch* m_branch;
50 
51  public:
53  RootEvtSelectorContext( const RootEvtSelector* s ) : m_sel( s ), m_entry( -1 ), m_branch( nullptr ) {}
55  const Files& files() const { return m_files; }
57  void setFiles( const Files& f ) {
58  m_files = f;
59  m_fiter = m_files.begin();
60  }
62  void* identifier() const override { return const_cast<RootEvtSelector*>( m_sel ); }
64  Files::const_iterator fileIterator() const { return m_fiter; }
66  void setFileIterator( Files::const_iterator i ) { m_fiter = i; }
68  long entry() const { return m_entry; }
70  void setEntry( long e ) { m_entry = e; }
72  void setFID( const std::string& fid ) { m_fid = fid; }
74  const std::string& fid() const { return m_fid; }
76  TBranch* branch() const { return m_branch; }
78  void setBranch( TBranch* b ) { m_branch = b; }
79  };
80 } // namespace Gaudi
81 #endif // GAUDIROOTCNV_ROOTEVTSELECTORCONTEXT_H
82 
83 // Include files
85 #include "GaudiKernel/ClassID.h"
89 #include "GaudiKernel/MsgStream.h"
91 #include "RootCnv/RootCnvSvc.h"
93 #include "TBranch.h"
94 
95 using namespace Gaudi;
96 using namespace std;
97 
98 // Helper method to issue error messages
99 StatusCode RootEvtSelector::error( const string& msg ) const {
100  MsgStream log( msgSvc(), name() );
101  log << MSG::ERROR << msg << endmsg;
102  return StatusCode::FAILURE;
103 }
104 
105 // IService implementation: Db event selector override
107  // Initialize base class
108  StatusCode status = Service::initialize();
109  if ( !status.isSuccess() ) { return error( "Error initializing base class Service!" ); }
110 
111  auto ipers = serviceLocator()->service<IPersistencySvc>( m_persName );
112  if ( !ipers ) { return error( "Unable to locate IPersistencySvc interface of " + m_persName ); }
113  IConversionSvc* cnvSvc = nullptr;
114  Gaudi::Utils::TypeNameString itm( m_cnvSvcName );
115  status = ipers->getService( itm.name(), cnvSvc );
116  if ( !status.isSuccess() ) {
117  status = ipers->getService( itm.type(), cnvSvc );
118  if ( !status.isSuccess() ) {
119  return error( "Unable to locate IConversionSvc interface of database type " + m_cnvSvcName );
120  }
121  }
122  m_dbMgr = dynamic_cast<RootCnvSvc*>( cnvSvc );
123  if ( !m_dbMgr ) {
124  cnvSvc->release();
125  return error( "Unable to localize service:" + m_cnvSvcName );
126  }
127  m_dbMgr->addRef();
128 
129  // Get DataSvc
130  auto eds = serviceLocator()->service<IDataManagerSvc>( "EventDataSvc" );
131  if ( !eds ) { return error( "Unable to localize service EventDataSvc" ); }
132  m_rootCLID = eds->rootCLID();
133  m_rootName = eds->rootName();
134  MsgStream log( msgSvc(), name() );
135  log << MSG::DEBUG << "Selection root:" << m_rootName << " CLID:" << m_rootCLID << endmsg;
136  return status;
137 }
138 
139 // IService implementation: Service finalization
141  // Initialize base class
142  if ( m_dbMgr ) m_dbMgr->release();
143  m_dbMgr = nullptr; // release
144  return Service::finalize();
145 }
146 
147 // Create a new event loop context
148 StatusCode RootEvtSelector::createContext( Context*& refpCtxt ) const {
149  refpCtxt = new RootEvtSelectorContext( this );
150  return StatusCode::SUCCESS;
151 }
152 
153 // Access last item in the iteration
154 StatusCode RootEvtSelector::last( Context& /*refContext*/ ) const { return StatusCode::FAILURE; }
155 
156 // Get next iteration item from the event loop context
157 StatusCode RootEvtSelector::next( Context& ctxt ) const {
158  RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>( &ctxt );
159  if ( pCtxt ) {
160  TBranch* b = pCtxt->branch();
161  if ( !b ) {
162  auto fileit = pCtxt->fileIterator();
163  pCtxt->setBranch( nullptr );
164  pCtxt->setEntry( -1 );
165  if ( fileit != pCtxt->files().end() ) {
166  RootDataConnection* con = nullptr;
167  string in = *fileit;
168  StatusCode sc = m_dbMgr->connectDatabase( in, IDataConnection::READ, &con );
169  if ( sc.isSuccess() ) {
170  string section = m_rootName[0] == '/' ? m_rootName.substr( 1 ) : m_rootName;
171  b = con->getBranch( section, m_rootName );
172  if ( b ) {
173  pCtxt->setFID( con->fid() );
174  pCtxt->setBranch( b );
175  return next( ctxt );
176  }
177  }
178  m_dbMgr->disconnect( in ).ignore();
179  pCtxt->setFileIterator( ++fileit );
180  return next( ctxt );
181  }
182  return StatusCode::FAILURE;
183  }
184  long ent = pCtxt->entry();
185  Long64_t nent = b->GetEntries();
186  if ( nent > ( ent + 1 ) ) {
187  pCtxt->setEntry( ++ent );
188  return StatusCode::SUCCESS;
189  }
190  auto fit = pCtxt->fileIterator();
191  pCtxt->setFileIterator( ++fit );
192  pCtxt->setEntry( -1 );
193  pCtxt->setBranch( nullptr );
194  pCtxt->setFID( "" );
195  return next( ctxt );
196  }
197  return StatusCode::FAILURE;
198 }
199 
200 // Get next iteration item from the event loop context
201 StatusCode RootEvtSelector::next( Context& ctxt, int jump ) const {
202  if ( jump > 0 ) {
203  for ( int i = 0; i < jump; ++i ) {
204  StatusCode status = next( ctxt );
205  if ( !status.isSuccess() ) { return status; }
206  }
207  return StatusCode::SUCCESS;
208  }
209  return StatusCode::FAILURE;
210 }
211 
212 // Get previous iteration item from the event loop context
213 StatusCode RootEvtSelector::previous( Context& /* ctxt */ ) const {
214  return error( "EventSelector Iterator, operator -- not supported " );
215 }
216 
217 // Get previous iteration item from the event loop context
218 StatusCode RootEvtSelector::previous( Context& ctxt, int jump ) const {
219  if ( jump > 0 ) {
220  for ( int i = 0; i < jump; ++i ) {
221  StatusCode status = previous( ctxt );
222  if ( !status.isSuccess() ) { return status; }
223  }
224  return StatusCode::SUCCESS;
225  }
226  return StatusCode::FAILURE;
227 }
228 
229 // Rewind the dataset
230 StatusCode RootEvtSelector::rewind( Context& ctxt ) const {
231  RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>( &ctxt );
232  if ( pCtxt ) {
233  auto fileit = pCtxt->fileIterator();
234  if ( fileit != pCtxt->files().end() ) {
235  string input = *fileit;
236  m_dbMgr->disconnect( input ).ignore();
237  }
238  pCtxt->setFID( "" );
239  pCtxt->setEntry( -1 );
240  pCtxt->setBranch( nullptr );
241  pCtxt->setFileIterator( pCtxt->files().begin() );
242  return StatusCode::SUCCESS;
243  }
244  return StatusCode::FAILURE;
245 }
246 
247 // Create new Opaque address corresponding to the current record
248 StatusCode RootEvtSelector::createAddress( const Context& ctxt, IOpaqueAddress*& pAddr ) const {
249  const RootEvtSelectorContext* pctxt = dynamic_cast<const RootEvtSelectorContext*>( &ctxt );
250  if ( pctxt ) {
251  long ent = pctxt->entry();
252  if ( ent >= 0 ) {
253  auto fileit = pctxt->fileIterator();
254  if ( fileit != pctxt->files().end() ) {
255  const string par[2] = {pctxt->fid(), m_rootName};
256  const unsigned long ipar[2] = {0, (unsigned long)ent};
257  return m_dbMgr->createAddress( m_dbMgr->repSvcType(), m_rootCLID, &par[0], &ipar[0], pAddr );
258  }
259  }
260  }
261  pAddr = nullptr;
262  return StatusCode::FAILURE;
263 }
264 
265 // Release existing event iteration context
267  RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>( ctxt );
268  if ( pCtxt ) {
269  delete pCtxt;
270  return StatusCode::SUCCESS;
271  }
272  return StatusCode::FAILURE;
273 }
274 
275 // Will set a new criteria for the selection of the next list of events and will change
276 // the state of the context in a way to point to the new list.
277 StatusCode RootEvtSelector::resetCriteria( const string& criteria, Context& context ) const {
278  MsgStream log( msgSvc(), name() );
279  RootEvtSelectorContext* ctxt = dynamic_cast<RootEvtSelectorContext*>( &context );
280  string db, typ, item, sel, stmt, aut, addr;
281  if ( ctxt ) {
282  if ( criteria.compare( 0, 5, "FILE " ) == 0 ) {
283  // The format for the criteria is:
284  // FILE filename1, filename2 ...
285  db = criteria.substr( 5 );
286  } else {
287  using Parser = Gaudi::Utils::AttribStringParser;
288  for ( auto attrib : Parser( criteria ) ) {
289  string tmp = attrib.tag.substr( 0, 3 );
290  if ( tmp == "DAT" ) {
291  db = std::move( attrib.value );
292  } else if ( tmp == "OPT" ) {
293  if ( attrib.value.compare( 0, 3, "REA" ) != 0 ) {
294  log << MSG::ERROR << "Option:\"" << attrib.value << "\" not valid" << endmsg;
295  return StatusCode::FAILURE;
296  }
297  } else if ( tmp == "TYP" ) {
298  typ = std::move( attrib.value );
299  } else if ( tmp == "ADD" ) {
300  item = std::move( attrib.value );
301  } else if ( tmp == "SEL" ) {
302  sel = std::move( attrib.value );
303  } else if ( tmp == "FUN" ) {
304  stmt = std::move( attrib.value );
305  } else if ( tmp == "AUT" ) {
306  aut = std::move( attrib.value );
307  } else if ( tmp == "COL" ) {
308  addr = std::move( attrib.value );
309  }
310  }
311  }
312  // It's now time to parse the criteria for the event selection
313  // The format for the criteria is:
314  // FILE filename1, filename2 ...
315  // JOBID number1-number2, number3, ...
317  string rest = db;
318  files.clear();
319  while ( true ) {
320  int ipos = rest.find_first_not_of( " ," );
321  if ( ipos == -1 ) break;
322  rest = rest.substr( ipos, string::npos ); // remove blanks before
323  int lpos = rest.find_first_of( " ," ); // locate next blank
324  files.push_back( rest.substr( 0, lpos ) ); // insert in list
325  if ( lpos == -1 ) break;
326  rest = rest.substr( lpos, string::npos ); // get the rest
327  }
328  ctxt->setFiles( files );
329  ctxt->setFileIterator( ctxt->files().begin() );
330  return StatusCode::SUCCESS;
331  }
332  return error( "Invalid iteration context." );
333 }
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:60
const Files & files() const
Access to the file container.
TBranch * getBranch(std::string_view section, std::string_view branch_name)
Access data branch by name: Get existing branch in read only mode.
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:164
std::vector< std::string > Files
Definition of the file container.
bool isSuccess() const
Definition: StatusCode.h:267
std::string m_fid
Connection fid.
sel
Definition: IOTest.py:93
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
Description:
Definition: RootCnvSvc.h:52
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.
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:50
StatusCode finalize() override
IService implementation: Service finalization.
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:316
constexpr static const auto FAILURE
Definition: StatusCode.h:86
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.
Header file for std:chrono::duration-based Counters.
Definition: __init__.py:1
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
long entry() const
Access to the current event entry number.
T compare(T...args)
long m_entry
Current entry of current file.