Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:46:49

0001 #ifndef FWCore_Framework_EDLooperBase_h
0002 #define FWCore_Framework_EDLooperBase_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     Framework
0006 // Module:      EDLooperBase
0007 //
0008 /**\class EDLooperBase EDLooperBase.h FWCore/Framework/interface/EDLooperBase.h
0009 
0010  Description: Base class for all looping components
0011 
0012  This abstract class forms the basis of being able to loop through a list of events multiple times. In general the
0013  class EDLooper is more appropriate for looping sequentially over events.
0014 
0015  The class uses a Template Pattern to describe the structure of a loop.  The structure is made up of three phases
0016  1) start of loop
0017    At the start of a new loop the virtual method 'startingNewLoop(unsigned int)' is called.  The integer passed is
0018    the number of loops which have been run in the job starting at index 0.
0019  2) during loop
0020    Each time an event has been processed by all other modules in a job, the method
0021       Status duringLoop(Event const&, EventSetup const&, ProcessingController&)
0022    will be called.  The return value 'Status' can be either kContinue if you want to proceed to the 'next' event or
0023    kStop if you want to stop this particular loop.
0024    The class ProcessingController allows you further control of what is meant by 'next' event.  By default 'next' event
0025    will just be the next event in the normal sequence.  However, for sources which support the feature, you can also use
0026    ProcessingController to make the 'next' event be the 'event before the last processed event' (i.e. go back one) or to
0027    use an EventID to exactly specify what next event you want.  However, if you say to go 'back' one event while the
0028    job is on the first event of the loop or pass an EventID for an event not contained in the source the job will
0029    immediately go to 'end of loop'.
0030    NOTE: if you have no need of controlling exactly what 'next' event should be processed then you should instead inherit
0031    from the subclass EDLooper and us it simplified interface for 'duringLoop'.
0032  3) end of loop
0033    Once all events have been processed or kStop was returned from 'duringLoop' or ProcessingController was told to go to an
0034    'invalid' event then the method
0035       Status endOfLoop(EventSetup const&, unsigned int iCounter)
0036    will be called.  iCounter will be the number of loops which have been run in the job starting at index 0. If kContinue
0037    is returned from endOfLoop then a new loop will begin else if kStop is called then the job will end.
0038 
0039  Like other modules, an EDLooperBase is called for 'beginJob', 'endJob', 'beginRun', 'endRun', 'beginLuminosityBlock' and
0040  'endLuminosityBlock'.
0041 
0042  Additional information and control of a job is possible via the interfaces:
0043  attachTo(ActivityRegistry&) : via the ActivityRegistry you can monitor exactly which modules are being run
0044  scheduleInfo(): returns a ScheduleInfo which you can use to determine what paths are in a job and what
0045     modules are on each path.
0046  moduleChanger(): returns a ModuleChanger instance which can be used to modify the parameters of an EDLooper or EDFilter.
0047     Such modifications can only occur during a call to 'endOfLoop' since the newly changed module can only be properly initialized
0048     at the start of the next loop.
0049 
0050 */
0051 //
0052 // Author:      Chris Jones
0053 // Created:     Mon Aug  9 12:42:17 EDT 2010
0054 //
0055 
0056 #include "DataFormats/Provenance/interface/ModuleDescription.h"
0057 #include "FWCore/Framework/interface/EDConsumerBase.h"
0058 #include "FWCore/Framework/interface/Frameworkfwd.h"
0059 #include "FWCore/ServiceRegistry/interface/ModuleCallingContext.h"
0060 #include "FWCore/Utilities/interface/propagate_const.h"
0061 
0062 #include <set>
0063 #include <memory>
0064 
0065 namespace edm {
0066   namespace eventsetup {
0067     class EventSetupRecordKey;
0068     class EventSetupProvider;
0069   }  // namespace eventsetup
0070   class ExceptionToActionTable;
0071   class ProcessContext;
0072   class ScheduleInfo;
0073   class StreamContext;
0074   class ModuleChanger;
0075   class ProcessingController;
0076   class ActivityRegistry;
0077   class ServiceToken;
0078   class WaitingTaskHolder;
0079 
0080   class EDLooperBase : public EDConsumerBase {
0081   public:
0082     enum Status { kContinue, kStop };
0083 
0084     EDLooperBase();
0085     ~EDLooperBase() noexcept(false) override;
0086 
0087     EDLooperBase(EDLooperBase const&) = delete;             // Disallow copying and moving
0088     EDLooperBase& operator=(EDLooperBase const&) = delete;  // Disallow copying and moving
0089 
0090     void doStartingNewLoop();
0091     Status doDuringLoop(EventPrincipal& eventPrincipal, EventSetupImpl const& es, ProcessingController&, StreamContext*);
0092     Status doEndOfLoop(EventSetupImpl const& es);
0093     void prepareForNextLoop(eventsetup::EventSetupProvider* esp);
0094     void doBeginRun(RunPrincipal&, EventSetupImpl const&, ProcessContext*);
0095     void doEndRun(RunPrincipal&, EventSetupImpl const&, ProcessContext*);
0096     void doBeginLuminosityBlock(LuminosityBlockPrincipal&, EventSetupImpl const&, ProcessContext*);
0097     void doEndLuminosityBlock(LuminosityBlockPrincipal&, EventSetupImpl const&, ProcessContext*);
0098 
0099     void beginOfJob(EventSetupImpl const&);
0100     //This interface is deprecated
0101     virtual void beginOfJob(EventSetup const&);
0102     virtual void beginOfJob();
0103 
0104     virtual void endOfJob();
0105 
0106     void prefetchAsync(WaitingTaskHolder iTask,
0107                        ServiceToken const& token,
0108                        Transition iTrans,
0109                        Principal const& iPrincipal,
0110                        EventSetupImpl const& iImpl) const;
0111 
0112     void esPrefetchAsync(WaitingTaskHolder iTask,
0113                          EventSetupImpl const& iImpl,
0114                          Transition iTrans,
0115                          ServiceToken const& iToken) const;
0116 
0117     ///Override this method if you need to monitor the state of the processing
0118     virtual void attachTo(ActivityRegistry&);
0119 
0120     void setActionTable(ExceptionToActionTable const* actionTable) { act_table_ = actionTable; }
0121 
0122     virtual std::set<eventsetup::EventSetupRecordKey> modifyingRecords() const;
0123 
0124     void copyInfo(ScheduleInfo const&);
0125     void setModuleChanger(ModuleChanger*);
0126 
0127   protected:
0128     ///This only returns a non-zero value during the call to endOfLoop
0129     ModuleChanger* moduleChanger();
0130     ///This returns a non-zero value after the constructor has been called
0131     ScheduleInfo const* scheduleInfo() const;
0132 
0133   private:
0134     /**Called before system starts to loop over the events. The argument is a count of
0135        how many loops have been processed.  For the first time through the events the argument
0136        will be 0.
0137        */
0138     virtual void startingNewLoop(unsigned int) = 0;
0139 
0140     /**Called after all event modules have had a chance to process the Event.
0141        */
0142     virtual Status duringLoop(Event const&, EventSetup const&, ProcessingController&) = 0;
0143 
0144     /**Called after the system has finished one loop over the events. Thar argument is a
0145        count of how many loops have been processed before this loo.  For the first time through
0146        the events the argument will be 0.
0147        */
0148     virtual Status endOfLoop(EventSetup const&, unsigned int iCounter) = 0;
0149 
0150     ///Called after all event modules have processed the begin of a Run
0151     virtual void beginRun(Run const&, EventSetup const&);
0152 
0153     ///Called after all event modules have processed the end of a Run
0154     virtual void endRun(Run const&, EventSetup const&);
0155 
0156     ///Called after all event modules have processed the begin of a LuminosityBlock
0157     virtual void beginLuminosityBlock(LuminosityBlock const&, EventSetup const&);
0158 
0159     ///Called after all event modules have processed the end of a LuminosityBlock
0160     virtual void endLuminosityBlock(LuminosityBlock const&, EventSetup const&);
0161 
0162     void edPrefetchAsync(WaitingTaskHolder iTask, ServiceToken const& token, Principal const& iPrincipal) const;
0163 
0164     unsigned int iCounter_;
0165     ExceptionToActionTable const* act_table_;
0166 
0167     edm::propagate_const<std::unique_ptr<ScheduleInfo>> scheduleInfo_;
0168     edm::propagate_const<ModuleChanger*> moduleChanger_;
0169 
0170     ModuleDescription moduleDescription_;
0171     ModuleCallingContext moduleCallingContext_;
0172   };
0173 }  // namespace edm
0174 
0175 #endif