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