The Gaudi Framework  v32r2 (46d42edc)
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 // FIXME - method below generates leak errors with sanitizer
20 //
21 // clang-format off
22 // Direct leak of 176 byte(s) in 1 object(s) allocated from:
23 // #0 0x7f56e2dc2da8 in operator new(unsigned long) /afs/cern.ch/cms/CAF/CMSCOMM/COMM_ECAL/dkonst/GCC/build/contrib/gcc-8.2.0/src/gcc/8.2.0/libsanitizer/lsan/lsan_interceptors.cc:229
24 // #1 0x7f56cb992ae4 in Gaudi::RootCnvSvc::createAddress(long, unsigned int const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const*, unsigned long const*, IOpaqueAddress*&) ../RootCnv/src/RootCnvSvc.cpp:349
25 // #2 0x7f56cb993530 in Gaudi::RootCnvSvc::connectDatabase(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, Gaudi::RootDataConnection**) ../RootCnv/src/RootCnvSvc.cpp:242
26 // #3 0x7f56cb9b5230 in Gaudi::RootEvtSelector::next(IEvtSelector::Context&) const ../RootCnv/src/RootEvtSelector.cpp:168
27 // #4 0x7f56d2e748b3 in EventSelector::next(IEvtSelector::Context&, int) const ../GaudiCoreSvc/src/EventSelector/EventSelector.cpp:188
28 // #5 0x7f56d2e737bf in EventSelector::next(IEvtSelector::Context&) const ../GaudiCoreSvc/src/EventSelector/EventSelector.cpp:177
29 // #6 0x7f56d2e4c68f in EventLoopMgr::getEventRoot(IOpaqueAddress*&) ../GaudiCoreSvc/src/ApplicationMgr/EventLoopMgr.cpp:350
30 // #7 0x7f56d2e4dab5 in EventLoopMgr::nextEvent(int) ../GaudiCoreSvc/src/ApplicationMgr/EventLoopMgr.cpp:307
31 // #8 0x7f56d3fd5a5a in MinimalEventLoopMgr::executeRun(int) ../GaudiKernel/src/Lib/MinimalEventLoopMgr.cpp:296
32 // #9 0x7f56d2e289ac in ApplicationMgr::executeRun(int) ../GaudiCoreSvc/src/ApplicationMgr/ApplicationMgr.cpp:824
33 // #10 0x7f56d3f5a21c in Gaudi::Application::run() ../GaudiKernel/src/Lib/Application.cpp:81
34 // clang-format on
35 //
36 // These leaks are currently suppressed in Gaudi/job/Gaudi-LSan.supp - remove entry there to reactivate
37 
38 /*
39  * Gaudi namespace declaration
40  */
41 namespace Gaudi {
42 
52  public:
55 
56  private:
62  Files::const_iterator m_fiter;
64  long m_entry;
66  TBranch* m_branch;
69 
70  public:
72  RootEvtSelectorContext( const RootEvtSelector* s ) : m_sel( s ), m_entry( -1 ), m_branch( nullptr ) {}
74  const Files& files() const { return m_files; }
76  void setFiles( const Files& f ) {
77  m_files = f;
78  m_fiter = m_files.begin();
79  }
81  void* identifier() const override { return const_cast<RootEvtSelector*>( m_sel ); }
83  Files::const_iterator fileIterator() const { return m_fiter; }
85  void setFileIterator( Files::const_iterator i ) { m_fiter = i; }
87  long entry() const { return m_entry; }
89  void setEntry( long e ) { m_entry = e; }
91  void setFID( const std::string& fid ) { m_fid = fid; }
93  const std::string& fid() const { return m_fid; }
95  TBranch* branch() const { return m_branch; }
97  void setBranch( TBranch* b ) { m_branch = b; }
98  };
99 } // namespace Gaudi
100 #endif // GAUDIROOTCNV_ROOTEVTSELECTORCONTEXT_H
101 
102 // Include files
104 #include "GaudiKernel/ClassID.h"
107 #include "GaudiKernel/ISvcLocator.h"
108 #include "GaudiKernel/MsgStream.h"
110 #include "RootCnv/RootCnvSvc.h"
112 #include "TBranch.h"
113 
114 using namespace Gaudi;
115 using namespace std;
116 
117 // Helper method to issue error messages
118 StatusCode RootEvtSelector::error( const string& msg ) const {
119  MsgStream log( msgSvc(), name() );
120  log << MSG::ERROR << msg << endmsg;
121  return StatusCode::FAILURE;
122 }
123 
124 // IService implementation: Db event selector override
126  // Initialize base class
127  StatusCode status = Service::initialize();
128  if ( !status.isSuccess() ) { return error( "Error initializing base class Service!" ); }
129 
130  auto ipers = serviceLocator()->service<IPersistencySvc>( m_persName );
131  if ( !ipers ) { return error( "Unable to locate IPersistencySvc interface of " + m_persName ); }
132  IConversionSvc* cnvSvc = nullptr;
133  Gaudi::Utils::TypeNameString itm( m_cnvSvcName );
134  status = ipers->getService( itm.name(), cnvSvc );
135  if ( !status.isSuccess() ) {
136  status = ipers->getService( itm.type(), cnvSvc );
137  if ( !status.isSuccess() ) {
138  return error( "Unable to locate IConversionSvc interface of database type " + m_cnvSvcName );
139  }
140  }
141  m_dbMgr = dynamic_cast<RootCnvSvc*>( cnvSvc );
142  if ( !m_dbMgr ) {
143  cnvSvc->release();
144  return error( "Unable to localize service:" + m_cnvSvcName );
145  }
146  m_dbMgr->addRef();
147 
148  // Get DataSvc
149  auto eds = serviceLocator()->service<IDataManagerSvc>( "EventDataSvc" );
150  if ( !eds ) { return error( "Unable to localize service EventDataSvc" ); }
151  m_rootCLID = eds->rootCLID();
152  m_rootName = eds->rootName();
153  MsgStream log( msgSvc(), name() );
154  log << MSG::DEBUG << "Selection root:" << m_rootName << " CLID:" << m_rootCLID << endmsg;
155  return status;
156 }
157 
158 // IService implementation: Service finalization
160  // Initialize base class
161  if ( m_dbMgr ) m_dbMgr->release();
162  m_dbMgr = nullptr; // release
163  return Service::finalize();
164 }
165 
166 // Create a new event loop context
167 StatusCode RootEvtSelector::createContext( Context*& refpCtxt ) const {
168  refpCtxt = new RootEvtSelectorContext( this );
169  return StatusCode::SUCCESS;
170 }
171 
172 // Access last item in the iteration
173 StatusCode RootEvtSelector::last( Context& /*refContext*/ ) const { return StatusCode::FAILURE; }
174 
175 // Get next iteration item from the event loop context
176 StatusCode RootEvtSelector::next( Context& ctxt ) const {
177  RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>( &ctxt );
178  if ( pCtxt ) {
179  TBranch* b = pCtxt->branch();
180  if ( !b ) {
181  auto fileit = pCtxt->fileIterator();
182  pCtxt->setBranch( nullptr );
183  pCtxt->setEntry( -1 );
184  if ( fileit != pCtxt->files().end() ) {
185  RootDataConnection* con = nullptr;
186  string in = *fileit;
187  StatusCode sc = m_dbMgr->connectDatabase( in, IDataConnection::READ, &con );
188  if ( sc.isSuccess() ) {
189  string section = m_rootName[0] == '/' ? m_rootName.substr( 1 ) : m_rootName;
190  b = con->getBranch( section, m_rootName );
191  if ( b ) {
192  pCtxt->setFID( con->fid() );
193  pCtxt->setBranch( b );
194  return next( ctxt );
195  }
196  }
197  m_dbMgr->disconnect( in ).ignore();
198  pCtxt->setFileIterator( ++fileit );
199  return next( ctxt );
200  }
201  return StatusCode::FAILURE;
202  }
203  long ent = pCtxt->entry();
204  Long64_t nent = b->GetEntries();
205  if ( nent > ( ent + 1 ) ) {
206  pCtxt->setEntry( ++ent );
207  return StatusCode::SUCCESS;
208  }
209  auto fit = pCtxt->fileIterator();
210  pCtxt->setFileIterator( ++fit );
211  pCtxt->setEntry( -1 );
212  pCtxt->setBranch( nullptr );
213  pCtxt->setFID( "" );
214  return next( ctxt );
215  }
216  return StatusCode::FAILURE;
217 }
218 
219 // Get next iteration item from the event loop context
220 StatusCode RootEvtSelector::next( Context& ctxt, int jump ) const {
221  if ( jump > 0 ) {
222  for ( int i = 0; i < jump; ++i ) {
223  StatusCode status = next( ctxt );
224  if ( !status.isSuccess() ) { return status; }
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  return error( "EventSelector Iterator, operator -- not supported " );
234 }
235 
236 // Get previous iteration item from the event loop context
237 StatusCode RootEvtSelector::previous( Context& ctxt, int jump ) const {
238  if ( jump > 0 ) {
239  for ( int i = 0; i < jump; ++i ) {
240  StatusCode status = previous( ctxt );
241  if ( !status.isSuccess() ) { return status; }
242  }
243  return StatusCode::SUCCESS;
244  }
245  return StatusCode::FAILURE;
246 }
247 
248 // Rewind the dataset
249 StatusCode RootEvtSelector::rewind( Context& ctxt ) const {
250  RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>( &ctxt );
251  if ( pCtxt ) {
252  auto fileit = pCtxt->fileIterator();
253  if ( fileit != pCtxt->files().end() ) {
254  string input = *fileit;
255  m_dbMgr->disconnect( input ).ignore();
256  }
257  pCtxt->setFID( "" );
258  pCtxt->setEntry( -1 );
259  pCtxt->setBranch( nullptr );
260  pCtxt->setFileIterator( pCtxt->files().begin() );
261  return StatusCode::SUCCESS;
262  }
263  return StatusCode::FAILURE;
264 }
265 
266 // Create new Opaque address corresponding to the current record
267 StatusCode RootEvtSelector::createAddress( const Context& ctxt, IOpaqueAddress*& pAddr ) const {
268  const RootEvtSelectorContext* pctxt = dynamic_cast<const RootEvtSelectorContext*>( &ctxt );
269  if ( pctxt ) {
270  long ent = pctxt->entry();
271  if ( ent >= 0 ) {
272  auto fileit = pctxt->fileIterator();
273  if ( fileit != pctxt->files().end() ) {
274  const string par[2] = {pctxt->fid(), m_rootName};
275  const unsigned long ipar[2] = {0, (unsigned long)ent};
276  return m_dbMgr->createAddress( m_dbMgr->repSvcType(), m_rootCLID, &par[0], &ipar[0], pAddr );
277  }
278  }
279  }
280  pAddr = nullptr;
281  return StatusCode::FAILURE;
282 }
283 
284 // Release existing event iteration context
286  RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>( ctxt );
287  if ( pCtxt ) {
288  delete pCtxt;
289  return StatusCode::SUCCESS;
290  }
291  return StatusCode::FAILURE;
292 }
293 
294 // Will set a new criteria for the selection of the next list of events and will change
295 // the state of the context in a way to point to the new list.
296 StatusCode RootEvtSelector::resetCriteria( const string& criteria, Context& context ) const {
297  MsgStream log( msgSvc(), name() );
298  RootEvtSelectorContext* ctxt = dynamic_cast<RootEvtSelectorContext*>( &context );
299  string db, typ, item, sel, stmt, aut, addr;
300  if ( ctxt ) {
301  if ( criteria.compare( 0, 5, "FILE " ) == 0 ) {
302  // The format for the criteria is:
303  // FILE filename1, filename2 ...
304  db = criteria.substr( 5 );
305  } else {
306  using Parser = Gaudi::Utils::AttribStringParser;
307  for ( auto attrib : Parser( criteria ) ) {
308  string tmp = attrib.tag.substr( 0, 3 );
309  if ( tmp == "DAT" ) {
310  db = std::move( attrib.value );
311  } else if ( tmp == "OPT" ) {
312  if ( attrib.value.compare( 0, 3, "REA" ) != 0 ) {
313  log << MSG::ERROR << "Option:\"" << attrib.value << "\" not valid" << endmsg;
314  return StatusCode::FAILURE;
315  }
316  } else if ( tmp == "TYP" ) {
317  typ = std::move( attrib.value );
318  } else if ( tmp == "ADD" ) {
319  item = std::move( attrib.value );
320  } else if ( tmp == "SEL" ) {
321  sel = std::move( attrib.value );
322  } else if ( tmp == "FUN" ) {
323  stmt = std::move( attrib.value );
324  } else if ( tmp == "AUT" ) {
325  aut = std::move( attrib.value );
326  } else if ( tmp == "COL" ) {
327  addr = std::move( attrib.value );
328  }
329  }
330  }
331  // It's now time to parse the criteria for the event selection
332  // The format for the criteria is:
333  // FILE filename1, filename2 ...
334  // JOBID number1-number2, number3, ...
336  string rest = db;
337  files.clear();
338  while ( true ) {
339  int ipos = rest.find_first_not_of( " ," );
340  if ( ipos == -1 ) break;
341  rest = rest.substr( ipos, string::npos ); // remove blanks before
342  int lpos = rest.find_first_of( " ," ); // locate next blank
343  files.push_back( rest.substr( 0, lpos ) ); // insert in list
344  if ( lpos == -1 ) break;
345  rest = rest.substr( lpos, string::npos ); // get the rest
346  }
347  ctxt->setFiles( files );
348  ctxt->setFileIterator( ctxt->files().begin() );
349  return StatusCode::SUCCESS;
350  }
351  return error( "Invalid iteration context." );
352 }
Parse attribute strings allowing iteration over the various attributes.
StatusCode next(Context &refCtxt) const override
Get next iteration item from the event loop context.
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
StatusCode initialize() override
Definition: Service.cpp:60
TBranch * getBranch(std::string_view section, std::string_view branch_name)
Access data branch by name: Get existing branch in read only mode.
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.
std::string m_fid
Connection fid.
sel
Definition: IOTest.py:94
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
STL namespace.
const std::string & fid() const
Access file id.
StatusCode rewind(Context &refCtxt) const override
Rewind the dataset.
const std::string & type() const
T end(T... args)
StatusCode createContext(Context *&refpCtxt) const override
Create a new event loop context.
StatusCode previous(Context &refCtxt) const override
Get previous iteration item from the event loop context.
Files::const_iterator fileIterator() const
Access to the file iterator.
STL class.
void * identifier() const override
Context identifier.
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".
ROOT specific event selector context.
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...
T next(T... args)
const std::string & name() const
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)
T clear(T... args)
bool isSuccess() const
Definition: StatusCode.h:267
T move(T... args)
const RootEvtSelector * m_sel
Reference to the hosting event selector instance.
void setFiles(const Files &f)
Set the file container.
StatusCode createAddress(const Context &refCtxt, IOpaqueAddress *&) const override
Create new Opaque address corresponding to the current record.
void setBranch(TBranch *b)
Set the top level branch (typically /Event) used to iterate.
Concrete event selector implementation to access ROOT files.
void setEntry(long e)
Set current event entry number.
long entry() const
Access to the current event entry number.
virtual unsigned long release()=0
Release Interface instance.
StatusCode last(Context &refContext) const override
Access last item in the iteration.
T begin(T... args)
void setFID(const std::string &fid)
Set connection FID.
Files::const_iterator m_fiter
The iterator to the.
string s
Definition: gaudirun.py:318
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.
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.
TBranch * branch() const
Access to the top level branch (typically /Event) used to iterate.
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
T compare(T... args)
const std::string & fid() const
Access connection fid.
long m_entry
Current entry of current file.
const Files & files() const
Access to the file container.