The Gaudi Framework  v33r1 (b1225454)
EventSelector.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 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 // Include files
18 #include "GaudiKernel/IToolSvc.h"
19 #include "GaudiKernel/Incident.h"
20 #include "GaudiKernel/MsgStream.h"
22 #include "GaudiKernel/SmartIF.h"
23 
24 #include "EventIterator.h"
25 #include "EventSelector.h"
26 #include <climits>
27 
29 
30 StatusCode EventSelector::resetCriteria( const std::string& /* criteria */, Context& /* context */ ) const {
31  return StatusCode::FAILURE;
32 }
33 
34 // Progress report
36  if ( iter ) {
37  long count = iter->numEvent();
38  // Print an message every m_evtPrintFrequency events
39  if ( 0 == iter->context() ) {
40  info() << "End of event input reached." << endmsg;
41  } else if ( iter->numStreamEvent() == -1 ) {
42  // Intial value for this stream
43  } else if ( m_evtPrintFrequency != -1 && ( count % m_evtPrintFrequency == 0 ) ) {
44  always() << "Reading Event record " << count + 1 << ". Record number within stream " << iter->ID() + 1 << ": "
45  << iter->numStreamEvent() + 1 << endmsg;
46  }
47  } else {
48  info() << "End of event input reached." << endmsg;
49  }
50 }
51 
52 // IEvtSelector::first()
55  IDataStreamTool::size_type iter_id = ( m_reconfigure ) ? 0 : iter.ID() + 1;
56  if ( m_reconfigure ) const_cast<EventSelector*>( this )->m_reconfigure = false;
57  if ( shutDown ) {
58  if ( iter.ID() >= 0 && iter.ID() < (long)m_streamtool->size() ) {
60  if ( s->isInitialized() ) {
61  EventSelector* thisPtr = const_cast<EventSelector*>( this );
62  if ( s->selector() && iter.context() ) {
63  Context* ctxt = iter.context();
64  s->selector()->releaseContext( ctxt ).ignore();
65  iter.set( 0, 0 );
66  }
67  status = thisPtr->m_streamtool->finalizeStream( const_cast<EventSelectorDataStream*>( s ) );
68  iter.set( 0, 0 );
69  }
70  }
71  }
72 
73  const EventSelectorDataStream* s = nullptr;
74  status = m_streamtool->getNextStream( s, iter_id );
75 
76  if ( status.isSuccess() ) {
77 
78  if ( s ) {
79  if ( !s->isInitialized() ) {
80  EventSelector* thisPtr = const_cast<EventSelector*>( this );
81  status = thisPtr->m_streamtool->initializeStream( const_cast<EventSelectorDataStream*>( s ) );
82  }
83 
84  if ( status.isSuccess() ) {
85  const IEvtSelector* sel = s->selector();
86  if ( sel ) {
87  Context* ctxt = nullptr;
88  status = sel->createContext( ctxt );
89  if ( status.isSuccess() ) {
90  status = sel->resetCriteria( s->criteria(), *ctxt );
91  if ( status.isSuccess() ) {
92  iter.set( this, iter_id, ctxt, 0 );
93  info() << *s << endmsg;
94  m_incidentSvc->fireIncident( Incident( s->dbName(), IncidentType::BeginInputFile ) );
95  return StatusCode::SUCCESS;
96  }
97  }
98  delete ctxt;
99  }
100  }
101  m_incidentSvc->fireIncident( Incident( s->dbName(), IncidentType::FailInputFile ) );
102  }
103  }
104 
105  iter.set( this, -1, 0, 0 );
106  status.setChecked();
107  // m_incidentSvc->fireIncident(Incident(s->dbName(),IncidentType::FailInputFile));
108  return StatusCode::FAILURE;
109 }
110 
111 // IEvtSelector::first()
114  if ( shutDown ) {
115  if ( iter.ID() >= 0 && iter.ID() < (long)m_streamtool->size() ) {
116  const EventSelectorDataStream* s = m_streamtool->getStream( iter.ID() );
117  if ( s->isInitialized() ) {
118  EventSelector* thisPtr = const_cast<EventSelector*>( this );
119  if ( s->selector() && iter.context() ) {
120  Context* ctxt = iter.context();
121  if ( status = s->selector()->releaseContext( ctxt ); !status ) return status;
122  iter.set( 0, 0 );
123  }
124  status = thisPtr->m_streamtool->finalizeStream( const_cast<EventSelectorDataStream*>( s ) );
125  iter.set( 0, 0 );
126  }
127  }
128  }
129 
130  IDataStreamTool::size_type iter_id = iter.ID() - 1;
131  const EventSelectorDataStream* s = nullptr;
132  status = m_streamtool->getPreviousStream( s, iter_id );
133 
134  if ( status.isSuccess() ) {
135 
136  if ( !s->isInitialized() ) {
137  EventSelector* thisPtr = const_cast<EventSelector*>( this );
138  status = thisPtr->m_streamtool->initializeStream( const_cast<EventSelectorDataStream*>( s ) );
139  }
140  if ( status.isSuccess() ) {
141  const IEvtSelector* sel = s->selector();
142  if ( sel ) {
143  Context* ctxt = nullptr;
144  status = sel->createContext( ctxt );
145  if ( status.isSuccess() ) {
146  status = sel->resetCriteria( s->criteria(), *ctxt );
147  if ( status.isSuccess() ) {
148  iter.set( this, iter_id, ctxt, 0 );
149  info() << *s << endmsg;
150  return StatusCode::SUCCESS;
151  }
152  }
153  }
154  }
155  }
156 
157  iter.set( this, -1, 0, 0 );
158  return StatusCode::FAILURE;
159 }
160 
162 StatusCode EventSelector::createContext( Context*& refpCtxt ) const {
163  // Max event is zero. Return begin = end
164  refpCtxt = nullptr;
165  if ( m_firstEvent < 0 ) {
166  error() << "First Event = " << m_firstEvent << " not valid" << endmsg;
167  error() << "It should be > 0 " << endmsg;
168  return StatusCode::FAILURE; // if failure => iterators = end();
169  }
170  auto ctxt = new EvtSelectorContext( this );
171  refpCtxt = ctxt;
172  ctxt->set( 0, -1, 0, 0 );
173  firstOfNextStream( true, *ctxt ).ignore();
174  long nskip = m_firstEvent;
175  while ( --nskip > 0 ) {
176  StatusCode sc = next( *refpCtxt );
177  if ( sc.isFailure() ) {
178  error() << " createContext() failed to start with event number " << m_firstEvent << endmsg;
179  if ( sc = releaseContext( refpCtxt ); !sc ) return sc;
180  refpCtxt = nullptr;
181  return StatusCode::FAILURE;
182  }
183  }
184  return StatusCode::SUCCESS;
185 }
186 
188 StatusCode EventSelector::next( Context& refCtxt ) const { return next( refCtxt, 1 ); }
189 
191 StatusCode EventSelector::next( Context& refCtxt, int /* jump */ ) const {
192  EvtSelectorContext* pIt = dynamic_cast<EvtSelectorContext*>( &refCtxt );
193  if ( pIt ) {
194  if ( pIt->ID() != -1 ) {
195  const EventSelectorDataStream* s = m_streamtool->getStream( pIt->ID() );
196  Context* it = pIt->context();
197  IEvtSelector* sel = s->selector();
198  if ( it && sel ) { // First exploit the current stream
199  StatusCode sc = sel->next( *it ); // This stream is empty: advance to the next stream
200  if ( !sc.isSuccess() ) {
201  m_incidentSvc->fireIncident( Incident( s->dbName(), IncidentType::EndInputFile ) );
202  sc = firstOfNextStream( true, *pIt );
203  if ( sc.isSuccess() ) sc = next( *pIt );
204  } else {
205  pIt->increaseCounters( false );
206  pIt->set( it, 0 );
207  printEvtInfo( pIt );
208  }
209  return sc;
210  } else if ( m_reconfigure ) {
211  StatusCode sc = firstOfNextStream( false, *pIt );
212  printEvtInfo( pIt );
213  return sc;
214  }
215  } else if ( m_reconfigure ) {
216  StatusCode sc = firstOfNextStream( false, *pIt );
217  printEvtInfo( pIt );
218  return sc;
219  }
220  pIt->increaseCounters( false );
221  }
222  printEvtInfo( pIt );
223  return StatusCode::FAILURE;
224 }
225 
227 StatusCode EventSelector::previous( Context& refCtxt ) const { return previous( refCtxt, 1 ); }
228 
230 StatusCode EventSelector::previous( Context& refCtxt, int jump ) const {
231  EvtSelectorContext* pIt = dynamic_cast<EvtSelectorContext*>( &refCtxt );
232  if ( pIt && jump > 0 ) {
234  for ( int i = 0; i < jump && sc.isSuccess(); ++i ) {
235  const EventSelectorDataStream* s = m_streamtool->getStream( pIt->ID() );
236  Context* it = pIt->context();
237  IEvtSelector* sel = s->selector();
238  if ( it && sel ) { // First exploit the current stream
239  // This stream is empty: advance to the next stream
240  sc = sel->previous( *it ); // This stream is empty: advance to the next stream
241  if ( !sc.isSuccess() ) {
242  sc = lastOfPreviousStream( true, *pIt );
243  } else {
244  pIt->increaseCounters( false );
245  pIt->set( it, 0 );
246  }
247  printEvtInfo( pIt );
248  if ( !sc.isSuccess() ) { return sc; }
249  }
250  pIt->increaseCounters( false );
251  }
252  return sc;
253  }
254  printEvtInfo( pIt );
255  return StatusCode::FAILURE;
256 }
257 
259 StatusCode EventSelector::last( Context& refCtxt ) const {
260  EvtSelectorContext* pIt = dynamic_cast<EvtSelectorContext*>( &refCtxt );
261  if ( pIt ) {}
262  return StatusCode::FAILURE;
263 }
264 
266 StatusCode EventSelector::rewind( Context& refCtxt ) const {
268  EvtSelectorContext* ctxt = dynamic_cast<EvtSelectorContext*>( &refCtxt );
269  if ( ctxt ) {
270  ctxt->set( 0, -1, 0, 0 );
271  if ( sc = firstOfNextStream( true, *ctxt ); !sc ) return sc;
272  long nskip = m_firstEvent;
273  while ( --nskip > 0 ) {
274  sc = next( *ctxt );
275  if ( sc.isFailure() ) { error() << "rewind() failed to start with event number " << m_firstEvent << endmsg; }
276  }
277  }
278  return sc;
279 }
280 
282 StatusCode EventSelector::createAddress( const Context& refCtxt, IOpaqueAddress*& refpAddr ) const {
283  auto cpIt = dynamic_cast<const EvtSelectorContext*>( &refCtxt );
284  auto pIt = const_cast<EvtSelectorContext*>( cpIt );
285  refpAddr = nullptr;
287  if ( pIt ) {
288  auto s = m_streamtool->getStream( pIt->ID() );
289  auto it = pIt->context();
290  auto sel = s->selector();
291  if ( it && sel ) {
292  IOpaqueAddress* pAddr = nullptr;
293  sc = sel->createAddress( *it, pAddr );
294  if ( sc.isSuccess() ) { refpAddr = pAddr; }
295  pIt->set( it, pAddr );
296  }
297  }
298  return sc;
299 }
300 
301 // Release existing event iteration context
302 StatusCode EventSelector::releaseContext( Context*& refCtxt ) const {
304  auto cpIt = dynamic_cast<const EvtSelectorContext*>( refCtxt );
305  std::unique_ptr<EvtSelectorContext> pIt{const_cast<EvtSelectorContext*>( cpIt )};
306  if ( pIt && pIt->ID() >= 0 && pIt->ID() < (long)m_streamtool->size() ) {
307  const auto s = m_streamtool->getStream( pIt->ID() );
308  auto it = pIt->context();
309  auto sel = s->selector();
310  if ( it && sel ) { sc = sel->releaseContext( it ); }
311  }
312  refCtxt = nullptr; // std::unique_ptr always deletes object, so always set to NULL
313  return sc;
314 }
315 
318  // Initialize base class
319  StatusCode status = Service::initialize();
320  if ( !status.isSuccess() ) {
321  error() << "Error initializing base class Service!" << endmsg;
322  return status;
323  }
324  // Get the references to the services that are needed by the ApplicationMgr itself
325  m_incidentSvc = serviceLocator()->service( "IncidentSvc" );
326  if ( !m_incidentSvc ) {
327  fatal() << "Error retrieving IncidentSvc." << endmsg;
328  return StatusCode::FAILURE;
329  }
330  if ( m_evtMax != INT_MAX ) {
331  error() << "EvtMax is an obsolete property of the event selector." << endmsg;
332  error() << "Please set \"ApplicationMgr.EvtMax = " << m_evtMax << ";\" to process the requested number of events."
333  << endmsg;
334  return StatusCode::FAILURE;
335  }
336 
337  m_toolSvc = serviceLocator()->service( "ToolSvc" );
338  if ( !m_toolSvc ) {
339  error() << " Could not locate the Tool Service! " << endmsg;
340  return StatusCode::FAILURE;
341  }
342  // make sure we finalize _prior_ to ToolSvc... we are about to get a
343  // a pointer to a tool which gets finalized and released by the ToolSvc
344  // during ToolSvc::finalize, and we don't want dangling pointers...
346  auto prio = mgr->getPriority( "ToolSvc" );
347  mgr->setPriority( name(), prio + 1 ).ignore();
348 
350 
351  if ( status.isFailure() ) {
352  error() << "Error initializing " << m_streamManager << endmsg;
353  return status;
354  }
355 
356  status = m_streamtool->clear();
357  if ( status.isFailure() ) {
358  // Message already printed by the tool
359  return status;
360  }
361 
363 
365 
366  m_streamID = 0;
367 
368  return status;
369 }
370 
371 // Re-initialize
374  error() << "Cannot reinitialize: service not in state initialized" << endmsg;
375  return StatusCode::FAILURE;
376  }
377 
378  if ( m_streamSpecsLast != m_streamSpecs ) {
379  StatusCode status = m_streamtool->clear();
380  if ( status.isFailure() ) return status;
382  m_reconfigure = true;
384  }
385 
386  return StatusCode::SUCCESS;
387 }
388 
389 //
391 
392  if ( msgLevel( MSG::DEBUG ) ) { debug() << "finalize()" << endmsg; }
393 
394  m_incidentSvc = nullptr;
395 
396  if ( m_streamtool ) {
397  if ( m_toolSvc ) {
399  } else {
400  // It should not be possible to get here
402  }
403  m_streamtool = nullptr;
404  }
405  m_toolSvc.reset();
406 
407  return Service::finalize();
408 }
SmartIF< IIncidentSvc > m_incidentSvc
Reference to the indicent service.
Definition: EventSelector.h:73
StatusCode initialize() override
Definition: Service.cpp:70
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition: Service.cpp:287
virtual StatusCode finalizeStream(EventSelectorDataStream *)=0
virtual StatusCode setPriority(std::string_view name, int pri)=0
StatusCode finalize() override
Definition: Service.cpp:174
Gaudi::StateMachine::State FSMState() const override
Definition: Service.h:62
IEvtSelector::Context * context() const
Access "real" iterator.
Definition: EventIterator.h:80
The Event Selector Interface.
Definition: IEvtSelector.h:28
StatusCode releaseContext(Context *&refCtxt) const override
Release existing event iteration context.
IDataStreamTool * m_streamtool
Definition: EventSelector.h:77
long int m_streamID
Definition: EventSelector.h:69
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
STL namespace.
MsgStream & always() const
shortcut for the method msgStream(MSG::ALWAYS)
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
MSG::Level msgLevel() const
get the cached level (originally extracted from the embedded MsgStream)
StreamSpecs m_streamSpecsLast
Input stream specifiers (last used)
Definition: EventSelector.h:82
#define DECLARE_COMPONENT(type)
virtual StatusCode addStreams(const StreamSpecs &)=0
StatusCode next(Context &refCtxt) const override
Get next iteration item from the event loop context.
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:86
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:284
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
Gaudi::Property< int > m_evtPrintFrequency
Definition: EventSelector.h:92
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
Gaudi::Property< std::string > m_streamManager
Definition: EventSelector.h:93
virtual int getPriority(std::string_view name) const =0
StatusCode rewind(Context &refCtxt) const override
Rewind the dataset.
StatusCode reinitialize() override
Service override: Reinitialize service.
StatusCode previous(Context &refCtxt) const override
Get previous iteration item from the event loop context.
virtual StatusCode clear()=0
Definition of class EventIterator.
Definition: EventIterator.h:42
long numEvent() const
Access counter.
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:61
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...
virtual void printEvtInfo(const EvtSelectorContext *iter) const
Progress report.
virtual EventSelectorDataStream * getStream(size_type)=0
Gaudi::Property< int > m_evtMax
Definition: EventSelector.h:91
StatusCode firstOfNextStream(bool shutDown, EvtSelectorContext &it) const
Retrieve first entry of the next data stream.
StatusCode initialize() override
IService implementation: Db event selector override.
Gaudi::Property< StreamSpecs > m_streamSpecs
Definition: EventSelector.h:89
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
Gaudi::Property< int > m_firstEvent
Definition: EventSelector.h:90
bool isSuccess() const
Definition: StatusCode.h:365
StatusCode finalize() override
IService implementation: Service finalization.
virtual StatusCode getPreviousStream(const EventSelectorDataStream *&, size_type &)=0
SmartIF< IToolSvc > m_toolSvc
Definition: EventSelector.h:75
StatusCode lastOfPreviousStream(bool shutDown, EvtSelectorContext &it) const
Retrieve last entry of the previous data stream.
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:168
virtual unsigned long release()=0
Release Interface instance.
STL class.
void set(const IEvtSelector *sel, IDataStreamTool::size_type id, IEvtSelector::Context *it, IOpaqueAddress *pA)
Set the address of the iterator.
Definition: EventIterator.h:65
StatusCode retrieveTool(std::string_view type, T *&tool, const IInterface *parent=nullptr, bool createIf=true)
Retrieve specified tool sub-type with tool dependent part of the name automatically assigned.
Definition: IToolSvc.h:148
Definition of class EventSelectorDataStream.
Base class for all Incidents (computing events).
Definition: Incident.h:27
string s
Definition: gaudirun.py:328
constexpr static const auto FAILURE
Definition: StatusCode.h:101
virtual IDataStreamTool::size_type ID() const
Stream identifier.
Definition: EventIterator.h:99
long numStreamEvent() const
Access counter within stream.
virtual StatusCode releaseTool(IAlgTool *tool)=0
Release the tool.
IDataStreamTool::size_type increaseCounters(bool reset=false)
Increase counters.
Definition: EventIterator.h:82
Definition of class EventSelector.
Definition: EventSelector.h:63
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:96
StatusCode createAddress(const Context &refCtxt, IOpaqueAddress *&refpAddr) const override
Create new Opaque address corresponding to the current record.
virtual size_type size()=0
virtual StatusCode initializeStream(EventSelectorDataStream *)=0
bool isFailure() const
Definition: StatusCode.h:145
bool m_reconfigure
Reconfigure occurred.
Definition: EventSelector.h:80
Opaque address interface definition.
StatusCode last(Context &c) const override
Access last item in the iteration.
virtual StatusCode getNextStream(const EventSelectorDataStream *&, size_type &)=0
StatusCode createContext(Context *&refpCtxt) const override
Create a new event loop context.
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
const StatusCode & setChecked(bool checked=true) const
Check/uncheck StatusCode.
Definition: StatusCode.h:158
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202