Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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.
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.
TBranch * getBranch(boost::string_ref section, boost::string_ref branch_name)
Access data branch by name: Get existing branch in read only mode.
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:312
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.
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:192
long entry() const
Access to the current event entry number.
T compare(T...args)
long m_entry
Current entry of current file.