CMS 3D CMS Logo

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