00001 #ifndef Framework_EPStates_h
00002 #define Framework_EPStates_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00044
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
00076
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
00084
00085
00086
00087
00088
00089
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