CMS 3D CMS Logo

EPStates.h

Go to the documentation of this file.
00001 #ifndef Framework_EPStates_h
00002 #define Framework_EPStates_h
00003 
00004 /*
00005 $Id: EPStates.h,v 1.8 2008/08/04 20:00:45 wdd Exp $
00006 
00007 The state machine that controls the processing of runs, luminosity
00008 blocks, events, and loops is implemented using the boost statechart
00009 library and the states and events defined here.  This machine is
00010 used by the EventProcessor.
00011 
00012 Original Authors: W. David Dagenhart, Marc Paterno
00013 */
00014 
00015 #include "boost/statechart/event.hpp"
00016 #include "boost/statechart/state_machine.hpp"
00017 #include <boost/statechart/state.hpp>
00018 #include <boost/statechart/transition.hpp>
00019 #include <boost/mpl/list.hpp>
00020 #include <boost/statechart/custom_reaction.hpp>
00021 #include <vector>
00022 #include <set>
00023 
00024 namespace sc = boost::statechart;
00025 namespace mpl = boost::mpl;
00026 
00027 namespace edm {
00028   class IEventProcessor;
00029 }
00030 
00031 namespace statemachine {
00032 
00033   enum FileMode { NOMERGE, MERGE, FULLLUMIMERGE, FULLMERGE };
00034   int const INVALID_RUN = 0;
00035   int const INVALID_LUMI = 0;
00036 
00037   // Define the classes representing the "boost statechart events".
00038   // There are six of them.
00039 
00040   class Run : public sc::event<Run> {
00041   public:
00042     Run(int id);
00043     int id() const;
00044   private:
00045     int id_;
00046   };
00047 
00048   class Lumi : public sc::event<Lumi> {
00049   public:
00050     Lumi(int id);
00051     int id() const;
00052   private:
00053     int id_;
00054   };
00055 
00056   // It is slightly confusing that this one refers to 
00057   // both physics event and a boost statechart event ...
00058   class Event : public sc::event<Event> { };
00059 
00060   class File : public sc::event<File> {};
00061   class Stop : public sc::event<Stop> {};
00062   class Restart : public sc::event<Restart> {};
00063 
00064   // Now define the machine and the states.
00065   // For all these classes, the first template argument
00066   // to the base class is the derived class.  The second
00067   // argument is the parent state or if it is a top level
00068   // state the Machine.  If there is a third template
00069   // argument it is the substate that is entered
00070   // by default on entry.
00071 
00072   class Starting;
00073 
00074   class Machine : public sc::state_machine<Machine, Starting>
00075   {
00076   public:
00077     Machine(edm::IEventProcessor* ep,
00078             FileMode fileMode,
00079             bool handleEmptyRuns,
00080             bool handleEmptyLumis);
00081 
00082     edm::IEventProcessor& ep() const;
00083     FileMode fileMode() const;
00084     bool handleEmptyRuns() const;
00085     bool handleEmptyLumis() const;
00086 
00087     void startingNewLoop(File const& file);
00088     void startingNewLoop(Stop const& stop);
00089     void rewindAndPrepareForNextLoop(Restart const& restart);
00090 
00091   private:
00092 
00093     edm::IEventProcessor* ep_;
00094     FileMode fileMode_;
00095     bool handleEmptyRuns_;
00096     bool handleEmptyLumis_;
00097   };
00098 
00099   class Error;
00100   class HandleFiles;
00101   class EndingLoop;
00102 
00103   class Starting : public sc::state<Starting, Machine>
00104   {
00105   public:
00106     Starting(my_context ctx);
00107     ~Starting();
00108     
00109     typedef mpl::list<
00110       sc::transition<Event, Error>,
00111       sc::transition<Lumi, Error>,
00112       sc::transition<Run, Error>,
00113       sc::transition<File, HandleFiles, Machine, &Machine::startingNewLoop>,
00114       sc::transition<Stop, EndingLoop, Machine, &Machine::startingNewLoop>,
00115       sc::transition<Restart, Error> > reactions;
00116   };
00117 
00118   class FirstFile;
00119 
00120   class HandleFiles : public sc::state<HandleFiles, Machine, FirstFile>
00121   {
00122   public:
00123     HandleFiles(my_context ctx);
00124     void exit();
00125     ~HandleFiles();
00126  
00127     typedef mpl::list<
00128       sc::transition<Event, Error>,
00129       sc::transition<Lumi, Error>,
00130       sc::transition<Run, Error>,
00131       sc::transition<File, Error>,
00132       sc::transition<Stop, EndingLoop>,
00133       sc::transition<Restart, Error> > reactions;
00134 
00135     void closeFiles();
00136     void goToNewInputFile();
00137     bool shouldWeCloseOutput();
00138   private:
00139     edm::IEventProcessor & ep_;
00140     bool exitCalled_;
00141   };
00142 
00143   class EndingLoop : public sc::state<EndingLoop, Machine>
00144   {
00145   public:
00146     EndingLoop(my_context ctx);
00147     ~EndingLoop();
00148     typedef mpl::list<
00149       sc::transition<Restart, Starting, Machine, &Machine::rewindAndPrepareForNextLoop>,
00150       sc::custom_reaction<Stop> > reactions;
00151 
00152     sc::result react(Stop const&);
00153   private:
00154     edm::IEventProcessor & ep_;
00155   };
00156 
00157   class Error : public sc::state<Error, Machine>
00158   {
00159   public:
00160     Error(my_context ctx);
00161     ~Error();
00162     typedef sc::transition<Stop, EndingLoop> reactions;
00163   private:
00164     edm::IEventProcessor & ep_;
00165   };
00166 
00167   class HandleRuns;
00168 
00169   class FirstFile : public sc::state<FirstFile, HandleFiles>
00170   {
00171   public:
00172     FirstFile(my_context ctx);
00173     ~FirstFile();
00174     
00175     typedef mpl::list<
00176       sc::transition<Run, HandleRuns>,
00177       sc::custom_reaction<File> > reactions;
00178 
00179     sc::result react(File const& file);
00180     void openFiles();
00181   private:
00182     edm::IEventProcessor & ep_;
00183   };
00184 
00185   class HandleNewInputFile1 : public sc::state<HandleNewInputFile1, HandleFiles>
00186   {
00187   public:
00188     HandleNewInputFile1(my_context ctx);
00189     ~HandleNewInputFile1();
00190 
00191     typedef mpl::list<
00192       sc::transition<Run, HandleRuns>,
00193       sc::custom_reaction<File> > reactions;
00194 
00195     sc::result react(File const& file);
00196   };
00197 
00198   class NewInputAndOutputFiles : public sc::state<NewInputAndOutputFiles, HandleFiles>
00199   {
00200   public:
00201     NewInputAndOutputFiles(my_context ctx);
00202     ~NewInputAndOutputFiles();
00203 
00204     typedef mpl::list<
00205       sc::transition<Run, HandleRuns>,
00206       sc::custom_reaction<File> > reactions;
00207 
00208     sc::result react(File const& file);
00209 
00210   private:
00211 
00212     void goToNewInputAndOutputFiles();
00213 
00214     edm::IEventProcessor & ep_;
00215   };
00216 
00217   class NewRun;
00218 
00219   class HandleRuns : public sc::state<HandleRuns, HandleFiles, NewRun>
00220   {
00221   public:
00222     HandleRuns(my_context ctx);
00223     void exit();
00224     ~HandleRuns();
00225 
00226     typedef sc::transition<File, NewInputAndOutputFiles> reactions;
00227 
00228     bool beginRunCalled() const;
00229     int currentRun() const;
00230     bool runException() const;
00231     void setupCurrentRun();
00232     void beginRun(int run);
00233     void endRun(int run);
00234     void finalizeRun(Run const&);
00235     void finalizeRun();
00236     void beginRunIfNotDoneAlready();
00237   private:
00238     edm::IEventProcessor & ep_;
00239     bool exitCalled_;
00240     bool beginRunCalled_;
00241     int currentRun_;
00242     std::set<int> previousRuns_;
00243     bool runException_;
00244   };
00245 
00246   class HandleLumis;
00247 
00248   class NewRun : public sc::state<NewRun, HandleRuns>
00249   {
00250   public:
00251     NewRun(my_context ctx);
00252     ~NewRun();
00253 
00254     typedef mpl::list<
00255       sc::transition<Lumi, HandleLumis>,
00256       sc::transition<Run, NewRun, HandleRuns, &HandleRuns::finalizeRun>,
00257       sc::custom_reaction<File> > reactions;
00258 
00259     sc::result react(File const& file);
00260   };
00261 
00262   class ContinueRun1;
00263 
00264   class HandleNewInputFile2 : public sc::state<HandleNewInputFile2, HandleRuns>
00265   {
00266   public:
00267     HandleNewInputFile2(my_context ctx);
00268     ~HandleNewInputFile2();
00269     bool checkInvariant();
00270 
00271     typedef mpl::list<
00272       sc::custom_reaction<Run>,
00273       sc::custom_reaction<File> > reactions;
00274 
00275     sc::result react(Run const& run);
00276     sc::result react(File const& file);
00277   };
00278 
00279   class ContinueRun1 : public sc::state<ContinueRun1, HandleRuns>
00280   {
00281   public:
00282     ContinueRun1(my_context ctx);
00283     ~ContinueRun1();
00284     bool checkInvariant();
00285 
00286     typedef mpl::list<
00287       sc::transition<Run, NewRun, HandleRuns, &HandleRuns::finalizeRun>,
00288       sc::custom_reaction<File>,
00289       sc::transition<Lumi, HandleLumis> > reactions;
00290 
00291     sc::result react(File const& file);
00292   private:
00293     edm::IEventProcessor & ep_;
00294   }; 
00295 
00296   class FirstLumi;
00297 
00298   class HandleLumis : public sc::state<HandleLumis, HandleRuns, FirstLumi>
00299   {
00300   public:
00301     typedef std::pair<int, int> LumiID;
00302     HandleLumis(my_context ctx);
00303     void exit();
00304     ~HandleLumis();
00305     bool checkInvariant();
00306 
00307     LumiID currentLumi() const;
00308     bool currentLumiEmpty() const;
00309     std::vector<LumiID> const& unhandledLumis() const;
00310     void setupCurrentLumi();
00311     void finalizeAllLumis();
00312     void finalizeLumi();
00313     void finalizeOutstandingLumis();
00314     void markLumiNonEmpty();
00315 
00316     typedef sc::transition<Run, NewRun, HandleRuns, &HandleRuns::finalizeRun> reactions;
00317 
00318   private:
00319     edm::IEventProcessor & ep_;
00320     bool exitCalled_;
00321     bool currentLumiEmpty_;
00322     LumiID currentLumi_;
00323     std::set<LumiID> previousLumis_;
00324     std::vector<LumiID> unhandledLumis_;
00325     bool lumiException_;
00326   };
00327 
00328   class HandleEvent;
00329   class AnotherLumi;
00330 
00331   class FirstLumi : public sc::state<FirstLumi, HandleLumis>
00332   {
00333   public:
00334     FirstLumi(my_context ctx);
00335     ~FirstLumi();
00336     bool checkInvariant();
00337 
00338     typedef mpl::list<
00339       sc::transition<Event, HandleEvent>,
00340       sc::transition<Lumi, AnotherLumi>,
00341       sc::custom_reaction<File> > reactions;
00342 
00343     sc::result react(File const& file);
00344   };
00345 
00346   class AnotherLumi : public sc::state<AnotherLumi, HandleLumis>
00347   {
00348   public:
00349     AnotherLumi(my_context ctx);
00350     ~AnotherLumi();
00351     bool checkInvariant();
00352 
00353     typedef mpl::list<
00354       sc::transition<Event, HandleEvent>,
00355       sc::transition<Lumi, AnotherLumi>,
00356       sc::custom_reaction<File> > reactions;
00357 
00358     sc::result react(File const& file);
00359   };
00360 
00361   class HandleEvent : public sc::state<HandleEvent, HandleLumis>
00362   {
00363   public:
00364     HandleEvent(my_context ctx);
00365     ~HandleEvent();
00366     bool checkInvariant();
00367 
00368     typedef mpl::list<
00369       sc::transition<Event, HandleEvent>,
00370       sc::transition<Lumi, AnotherLumi>,
00371       sc::custom_reaction<File> > reactions;
00372 
00373     sc::result react(File const& file);
00374     void readAndProcessEvent();
00375     void markNonEmpty();
00376   private:
00377     edm::IEventProcessor & ep_;
00378   };
00379 
00380   class HandleNewInputFile3 : public sc::state<HandleNewInputFile3, HandleLumis>
00381   {
00382   public:
00383     HandleNewInputFile3(my_context ctx);
00384     ~HandleNewInputFile3();
00385     bool checkInvariant();
00386 
00387     typedef mpl::list<
00388       sc::custom_reaction<Run>,
00389       sc::custom_reaction<File> > reactions;
00390 
00391     sc::result react(Run const& run);
00392     sc::result react(File const& file);
00393   };
00394 
00395   class ContinueRun2 : public sc::state<ContinueRun2, HandleLumis>
00396   {
00397   public:
00398     ContinueRun2(my_context ctx);
00399     ~ContinueRun2();
00400     bool checkInvariant();
00401 
00402     typedef mpl::list<
00403       sc::custom_reaction<Lumi>,
00404       sc::custom_reaction<File> > reactions;
00405 
00406     sc::result react(Lumi const& lumi);
00407     sc::result react(File const& file);
00408   private:
00409     edm::IEventProcessor & ep_;
00410   };
00411 
00412   class ContinueLumi : public sc::state<ContinueLumi, HandleLumis>
00413   {
00414   public:
00415     ContinueLumi(my_context ctx);
00416     ~ContinueLumi();
00417     bool checkInvariant();
00418 
00419     typedef mpl::list<
00420       sc::transition<Event, HandleEvent>,
00421       sc::transition<Lumi, AnotherLumi>,
00422       sc::custom_reaction<File> > reactions;
00423 
00424     sc::result react(File const& file);
00425   private:
00426     edm::IEventProcessor & ep_;
00427   };
00428 }
00429 
00430 #endif

Generated on Tue Jun 9 17:35:53 2009 for CMSSW by  doxygen 1.5.4