CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/FWCore/Framework/src/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.12 2012/10/16 18:25:24 chrjones 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 "DataFormats/Provenance/interface/ProcessHistoryID.h"
00016 #include "DataFormats/Provenance/interface/RunID.h"
00017 #include "DataFormats/Provenance/interface/LuminosityBlockID.h"
00018 
00019 #include "boost/statechart/event.hpp"
00020 #include "boost/statechart/state_machine.hpp"
00021 #include <boost/statechart/state.hpp>
00022 #include <boost/statechart/transition.hpp>
00023 #include <boost/mpl/list.hpp>
00024 #include <boost/statechart/custom_reaction.hpp>
00025 #include <vector>
00026 
00027 namespace sc = boost::statechart;
00028 namespace mpl = boost::mpl;
00029 
00030 namespace edm {
00031   class IEventProcessor;
00032 }
00033 
00034 namespace statemachine {
00035 
00036   enum FileMode { NOMERGE, FULLMERGE };
00037 
00038   enum EmptyRunLumiMode { handleEmptyRunsAndLumis,
00039                           handleEmptyRuns,
00040                           doNotHandleEmptyRunsAndLumis
00041   };
00042 
00043   // Define the classes representing the "boost statechart events".
00044   // There are six of them.
00045 
00046   class Run : public sc::event<Run> {
00047   public:
00048     Run(edm::ProcessHistoryID const& phid, edm::RunNumber_t runNumber);
00049     edm::ProcessHistoryID const& processHistoryID() const { return processHistoryID_; }
00050     edm::RunNumber_t runNumber() const { return runNumber_; }
00051 
00052     bool operator==(Run const& rh) const {
00053       return (runNumber_ == rh.runNumber()) &&
00054              (processHistoryID_ == rh.processHistoryID());
00055     }
00056 
00057     bool operator!=(Run const& rh) const {
00058       return (runNumber_ != rh.runNumber()) ||
00059              (processHistoryID_ != rh.processHistoryID());
00060     }
00061 
00062   private:
00063     edm::ProcessHistoryID processHistoryID_;
00064     edm::RunNumber_t runNumber_;
00065   };
00066 
00067   class Lumi : public sc::event<Lumi> {
00068   public:
00069     Lumi(edm::LuminosityBlockNumber_t id);
00070     edm::LuminosityBlockNumber_t id() const { return id_; }
00071   private:
00072     edm::LuminosityBlockNumber_t id_;
00073   };
00074 
00075   // It is slightly confusing that this one refers to 
00076   // both physics event and a boost statechart event ...
00077   class Event : public sc::event<Event> { };
00078 
00079   class File : public sc::event<File> {};
00080   class Stop : public sc::event<Stop> {};
00081   class Restart : public sc::event<Restart> {};
00082 
00083   // Now define the machine and the states.
00084   // For all these classes, the first template argument
00085   // to the base class is the derived class.  The second
00086   // argument is the parent state or if it is a top level
00087   // state the Machine.  If there is a third template
00088   // argument it is the substate that is entered
00089   // by default on entry.
00090 
00091   class Starting;
00092 
00093   class Machine : public sc::state_machine<Machine, Starting>
00094   {
00095   public:
00096     Machine(edm::IEventProcessor* ep,
00097             FileMode fileMode,
00098             EmptyRunLumiMode emptyRunLumiMode);
00099 
00100     edm::IEventProcessor& ep() const;
00101     FileMode fileMode() const;
00102     EmptyRunLumiMode emptyRunLumiMode() const;
00103 
00104     void startingNewLoop(File const& file);
00105     void startingNewLoop(Stop const& stop);
00106     void rewindAndPrepareForNextLoop(Restart const& restart);
00107 
00108   private:
00109 
00110     edm::IEventProcessor* ep_;
00111     FileMode fileMode_;
00112     EmptyRunLumiMode emptyRunLumiMode_;
00113   };
00114 
00115   class Error;
00116   class HandleFiles;
00117   class EndingLoop;
00118 
00119   class Starting : public sc::state<Starting, Machine>
00120   {
00121   public:
00122     Starting(my_context ctx);
00123     ~Starting();
00124     
00125     typedef mpl::list<
00126       sc::transition<Event, Error>,
00127       sc::transition<Lumi, Error>,
00128       sc::transition<Run, Error>,
00129       sc::transition<File, HandleFiles, Machine, &Machine::startingNewLoop>,
00130       sc::transition<Stop, EndingLoop, Machine, &Machine::startingNewLoop>,
00131       sc::transition<Restart, Error> > reactions;
00132   };
00133 
00134   class FirstFile;
00135 
00136   class HandleFiles : public sc::state<HandleFiles, Machine, FirstFile>
00137   {
00138   public:
00139     HandleFiles(my_context ctx);
00140     void exit();
00141     ~HandleFiles();
00142  
00143     typedef mpl::list<
00144       sc::transition<Event, Error>,
00145       sc::transition<Lumi, Error>,
00146       sc::transition<Run, Error>,
00147       sc::transition<File, Error>,
00148       sc::transition<Stop, EndingLoop>,
00149       sc::transition<Restart, Error> > reactions;
00150 
00151     void closeFiles(bool cleaningUpAfterException);
00152     void goToNewInputFile();
00153     bool shouldWeCloseOutput();
00154   private:
00155     edm::IEventProcessor & ep_;
00156     bool exitCalled_;
00157   };
00158 
00159   class EndingLoop : public sc::state<EndingLoop, Machine>
00160   {
00161   public:
00162     EndingLoop(my_context ctx);
00163     ~EndingLoop();
00164     typedef mpl::list<
00165       sc::transition<Restart, Starting, Machine, &Machine::rewindAndPrepareForNextLoop>,
00166       sc::custom_reaction<Stop> > reactions;
00167 
00168     sc::result react(Stop const&);
00169   private:
00170     edm::IEventProcessor & ep_;
00171   };
00172 
00173   class Error : public sc::state<Error, Machine>
00174   {
00175   public:
00176     Error(my_context ctx);
00177     ~Error();
00178     typedef sc::transition<Stop, EndingLoop> reactions;
00179   private:
00180     edm::IEventProcessor & ep_;
00181   };
00182 
00183   class HandleRuns;
00184 
00185   class FirstFile : public sc::state<FirstFile, HandleFiles>
00186   {
00187   public:
00188     FirstFile(my_context ctx);
00189     ~FirstFile();
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     void openFiles();
00197   private:
00198     edm::IEventProcessor & ep_;
00199   };
00200 
00201   class HandleNewInputFile1 : public sc::state<HandleNewInputFile1, HandleFiles>
00202   {
00203   public:
00204     HandleNewInputFile1(my_context ctx);
00205     ~HandleNewInputFile1();
00206 
00207     typedef mpl::list<
00208       sc::transition<Run, HandleRuns>,
00209       sc::custom_reaction<File> > reactions;
00210 
00211     sc::result react(File const& file);
00212   };
00213 
00214   class NewInputAndOutputFiles : public sc::state<NewInputAndOutputFiles, HandleFiles>
00215   {
00216   public:
00217     NewInputAndOutputFiles(my_context ctx);
00218     ~NewInputAndOutputFiles();
00219 
00220     typedef mpl::list<
00221       sc::transition<Run, HandleRuns>,
00222       sc::custom_reaction<File> > reactions;
00223 
00224     sc::result react(File const& file);
00225 
00226   private:
00227 
00228     void goToNewInputAndOutputFiles();
00229 
00230     edm::IEventProcessor & ep_;
00231   };
00232 
00233   class NewRun;
00234 
00235   class HandleRuns : public sc::state<HandleRuns, HandleFiles, NewRun>
00236   {
00237   public:
00238     HandleRuns(my_context ctx);
00239     void exit();
00240     ~HandleRuns();
00241 
00242     typedef sc::transition<File, NewInputAndOutputFiles> reactions;
00243 
00244     bool beginRunCalled() const;
00245     Run const& currentRun() const;
00246     bool runException() const;
00247     void setupCurrentRun();
00248     void beginRun(Run const& run);
00249     void endRun(Run const& run, bool cleaningUpAfterException);
00250     void finalizeRun(Run const&);
00251     void finalizeRun(bool cleaningUpAfterException);
00252     void beginRunIfNotDoneAlready();
00253   private:
00254     edm::IEventProcessor & ep_;
00255     bool exitCalled_;
00256     bool beginRunCalled_;
00257     Run currentRun_;
00258     bool runException_;
00259   };
00260 
00261   class HandleLumis;
00262 
00263   class NewRun : public sc::state<NewRun, HandleRuns>
00264   {
00265   public:
00266     NewRun(my_context ctx);
00267     ~NewRun();
00268 
00269     typedef mpl::list<
00270       sc::transition<Lumi, HandleLumis>,
00271       sc::custom_reaction<Run>,
00272       sc::custom_reaction<File> > reactions;
00273 
00274     sc::result react(Run const& run);
00275     sc::result react(File const& file);
00276   };
00277 
00278   class ContinueRun1;
00279 
00280   class HandleNewInputFile2 : public sc::state<HandleNewInputFile2, HandleRuns>
00281   {
00282   public:
00283     HandleNewInputFile2(my_context ctx);
00284     ~HandleNewInputFile2();
00285     bool checkInvariant();
00286 
00287     typedef mpl::list<
00288       sc::custom_reaction<Run>,
00289       sc::custom_reaction<File> > reactions;
00290 
00291     sc::result react(Run const& run);
00292     sc::result react(File const& file);
00293   };
00294 
00295   class ContinueRun1 : public sc::state<ContinueRun1, HandleRuns>
00296   {
00297   public:
00298     ContinueRun1(my_context ctx);
00299     ~ContinueRun1();
00300     bool checkInvariant();
00301 
00302     typedef mpl::list<
00303       sc::custom_reaction<Run>,
00304       sc::custom_reaction<File>,
00305       sc::transition<Lumi, HandleLumis> > reactions;
00306 
00307     sc::result react(Run const& run);
00308     sc::result react(File const& file);
00309   private:
00310     edm::IEventProcessor & ep_;
00311   }; 
00312 
00313   class FirstLumi;
00314 
00315   class HandleLumis : public sc::state<HandleLumis, HandleRuns, FirstLumi>
00316   {
00317   public:
00318     class LumiID {
00319     public:
00320       LumiID(edm::ProcessHistoryID const& phid, edm::RunNumber_t run, edm::LuminosityBlockNumber_t lumi);
00321       edm::ProcessHistoryID const& processHistoryID() const { return processHistoryID_; }
00322       edm::RunNumber_t run() const { return run_; }
00323       edm::LuminosityBlockNumber_t lumi() const { return lumi_; }
00324 
00325     private:
00326       edm::ProcessHistoryID processHistoryID_;
00327       edm::RunNumber_t run_;
00328       edm::LuminosityBlockNumber_t lumi_;
00329     };
00330     HandleLumis(my_context ctx);
00331     void exit();
00332     ~HandleLumis();
00333     bool checkInvariant();
00334 
00335     LumiID const& currentLumi() const;
00336     bool currentLumiEmpty() const;
00337     void setupCurrentLumi();
00338     void finalizeLumi(bool cleaningUpAfterException);
00339     void markLumiNonEmpty();
00340 
00341     typedef sc::transition<Run, NewRun, HandleRuns, &HandleRuns::finalizeRun> reactions;
00342 
00343   private:
00344     edm::IEventProcessor & ep_;
00345     bool exitCalled_;
00346     bool currentLumiEmpty_;
00347     LumiID currentLumi_;
00348     bool lumiException_;
00349   };
00350 
00351   class HandleEvent;
00352   class AnotherLumi;
00353 
00354   class FirstLumi : public sc::state<FirstLumi, HandleLumis>
00355   {
00356   public:
00357     FirstLumi(my_context ctx);
00358     ~FirstLumi();
00359     bool checkInvariant();
00360 
00361     typedef mpl::list<
00362       sc::transition<Event, HandleEvent>,
00363       sc::custom_reaction<Lumi>,
00364       sc::custom_reaction<File> > reactions;
00365 
00366     sc::result react(Lumi const& lumi);
00367     sc::result react(File const& file);
00368   };
00369 
00370   class AnotherLumi : public sc::state<AnotherLumi, HandleLumis>
00371   {
00372   public:
00373     AnotherLumi(my_context ctx);
00374     ~AnotherLumi();
00375     bool checkInvariant();
00376 
00377     typedef mpl::list<
00378       sc::transition<Event, HandleEvent>,
00379       sc::custom_reaction<Lumi>,
00380       sc::custom_reaction<File> > reactions;
00381 
00382     sc::result react(Lumi const& lumi);
00383     sc::result react(File const& file);
00384   };
00385 
00386   class HandleEvent : public sc::state<HandleEvent, HandleLumis>
00387   {
00388   public:
00389     HandleEvent(my_context ctx);
00390     ~HandleEvent();
00391     bool checkInvariant();
00392 
00393     typedef mpl::list<
00394       sc::transition<Event, HandleEvent>,
00395       sc::transition<Lumi, AnotherLumi>,
00396       sc::custom_reaction<File> > reactions;
00397 
00398     sc::result react(File const& file);
00399     void readAndProcessEvent();
00400     void markNonEmpty();
00401   private:
00402     edm::IEventProcessor & ep_;
00403   };
00404 
00405   class HandleNewInputFile3 : public sc::state<HandleNewInputFile3, HandleLumis>
00406   {
00407   public:
00408     HandleNewInputFile3(my_context ctx);
00409     ~HandleNewInputFile3();
00410     bool checkInvariant();
00411 
00412     typedef mpl::list<
00413       sc::custom_reaction<Run>,
00414       sc::custom_reaction<File> > reactions;
00415 
00416     sc::result react(Run const& run);
00417     sc::result react(File const& file);
00418   };
00419 
00420   class ContinueRun2 : public sc::state<ContinueRun2, HandleLumis>
00421   {
00422   public:
00423     ContinueRun2(my_context ctx);
00424     ~ContinueRun2();
00425     bool checkInvariant();
00426 
00427     typedef mpl::list<
00428       sc::custom_reaction<Run>,
00429       sc::custom_reaction<Lumi>,
00430       sc::custom_reaction<File> > reactions;
00431 
00432     sc::result react(Run const& run);
00433     sc::result react(Lumi const& lumi);
00434     sc::result react(File const& file);
00435   private:
00436     edm::IEventProcessor & ep_;
00437   };
00438 
00439   class ContinueLumi : public sc::state<ContinueLumi, HandleLumis>
00440   {
00441   public:
00442     ContinueLumi(my_context ctx);
00443     ~ContinueLumi();
00444     bool checkInvariant();
00445 
00446     typedef mpl::list<
00447       sc::transition<Event, HandleEvent>,
00448       sc::custom_reaction<Lumi>,
00449       sc::custom_reaction<File> > reactions;
00450 
00451     sc::result react(Lumi const& lumi);
00452     sc::result react(File const& file);
00453   private:
00454     edm::IEventProcessor & ep_;
00455   };
00456 }
00457 
00458 #endif