CMS 3D CMS Logo

InputSource.cc

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------
00002 ----------------------------------------------------------------------*/
00003 #include <cassert> 
00004 #include "FWCore/Framework/interface/InputSource.h"
00005 #include "FWCore/Framework/interface/InputSourceDescription.h"
00006 #include "FWCore/Framework/interface/EventPrincipal.h"
00007 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
00008 #include "FWCore/Framework/interface/RunPrincipal.h"
00009 #include "FWCore/Framework/interface/LuminosityBlock.h"
00010 #include "FWCore/Framework/interface/FileBlock.h"
00011 #include "FWCore/Framework/interface/Run.h"
00012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00014 #include "FWCore/Framework/interface/Event.h"
00015 #include "FWCore/ServiceRegistry/interface/Service.h"
00016 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00017 #include "FWCore/Utilities/interface/GlobalIdentifier.h"
00018 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00019 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00020 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
00021 
00022 #include <ctime>
00023 
00024 namespace edm {
00025 
00026   namespace {
00027         int const improbable = -65783927;
00028         std::string const& suffix(int count) {
00029           static std::string const st("st");
00030           static std::string const nd("nd");
00031           static std::string const rd("rd");
00032           static std::string const th("th");
00033           // *0, *4 - *9 use "th".
00034           int lastDigit = count % 10;
00035           if (lastDigit >= 4 || lastDigit == 0) return th;
00036           // *11, *12, or *13 use "th".
00037           if (count % 100 - lastDigit == 10) return th;
00038           return (lastDigit == 1 ? st : (lastDigit == 2 ? nd : rd));
00039         }
00040         struct do_nothing_deleter {
00041           void  operator () (void const*) const {}
00042         };
00043         template <typename T>
00044         boost::shared_ptr<T> createSharedPtrToStatic(T * ptr) {
00045           return  boost::shared_ptr<T>(ptr, do_nothing_deleter());
00046         }
00047   }
00048   InputSource::InputSource(ParameterSet const& pset, InputSourceDescription const& desc) :
00049       ProductRegistryHelper(),
00050       actReg_(desc.actReg_),
00051       maxEvents_(desc.maxEvents_),
00052       remainingEvents_(maxEvents_),
00053       maxLumis_(desc.maxLumis_),
00054       remainingLumis_(maxLumis_),
00055       readCount_(0),
00056       processingMode_(RunsLumisAndEvents),
00057       moduleDescription_(desc.moduleDescription_),
00058       productRegistry_(createSharedPtrToStatic<ProductRegistry const>(desc.productRegistry_)),
00059       primary_(pset.getParameter<std::string>("@module_label") == std::string("@main_input")),
00060       processGUID_(primary_ ? createGlobalIdentifier() : std::string()),
00061       time_(),
00062       doneReadAhead_(false),
00063       state_(IsInvalid),
00064       runPrincipal_(),
00065       lumiPrincipal_() {
00066     // Secondary input sources currently do not have a product registry.
00067     if (primary_) {
00068       assert(desc.productRegistry_ != 0);
00069     }
00070     int maxEventsOldStyle = pset.getUntrackedParameter<int>("maxEvents", improbable);
00071     if (maxEventsOldStyle != improbable) {
00072       throw edm::Exception(edm::errors::Configuration)
00073         << "InputSource::InputSource()\n"
00074         << "The 'maxEvents' parameter for sources is no longer supported.\n"
00075         << "Please use instead the process level parameter set\n"
00076         << "'untracked PSet maxEvents = {untracked int32 input = " << maxEventsOldStyle << "}'\n";
00077     }
00078     std::string const defaultMode("RunsLumisAndEvents");
00079     std::string const runMode("Runs");
00080     std::string const runLumiMode("RunsAndLumis");
00081     std::string processingMode = pset.getUntrackedParameter<std::string>("processingMode", defaultMode);
00082     if (processingMode == runMode) {
00083       processingMode_ = Runs;
00084     } else if (processingMode == runLumiMode) {
00085       processingMode_ = RunsAndLumis;
00086     } else if (processingMode != defaultMode) {
00087       throw edm::Exception(edm::errors::Configuration)
00088         << "InputSource::InputSource()\n"
00089         << "The 'processingMode' parameter for sources has an illegal value '" << processingMode << "'\n"
00090         << "Legal values are '" << defaultMode << "', '" << runLumiMode << "', or '" << runMode << "'.\n";
00091     }
00092   }
00093 
00094   InputSource::~InputSource() {}
00095 
00096   // This next function is to guarantee that "runs only" mode does not return events or lumis,
00097   // and that "runs and lumis only" mode does not return events.
00098   // For input sources that are not random access (e.g. you need to read through the events
00099   // to get to the lumis and runs), this is all that is involved to implement these modes.
00100   // For input sources where events or lumis can be skipped, getNextItemType() should
00101   // implement the skipping internally, so that the performance gain is realized.
00102   // If this is done for a source, the 'if' blocks in this function will never be entered
00103   // for that source.
00104   InputSource::ItemType
00105   InputSource::nextItemType_() {
00106     ItemType itemType = getNextItemType();
00107     if (itemType == IsEvent && processingMode() != RunsLumisAndEvents) {
00108       readEvent_();
00109       return nextItemType_();
00110     }
00111     if (itemType == IsLumi && processingMode() == Runs) {
00112       readLuminosityBlock_();
00113       return nextItemType_();
00114     }
00115     return itemType;
00116   }
00117 
00118   InputSource::ItemType
00119   InputSource::nextItemType() {
00120     if (doneReadAhead_) {
00121       return state_;
00122     }
00123     doneReadAhead_ = true;
00124     ItemType oldState = state_;
00125     if (eventLimitReached()) {
00126       // If the maximum event limit has been reached, stop.
00127       state_ = IsStop;
00128     } else if (lumiLimitReached()) {
00129       // If the maximum lumi limit has been reached, stop
00130       // when reaching a new file, run, or lumi.
00131       if (oldState == IsInvalid || oldState == IsFile || oldState == IsRun || processingMode() != RunsLumisAndEvents) {
00132         state_ = IsStop;
00133       } else {
00134         ItemType newState = nextItemType_();
00135         if (newState == IsEvent) {
00136           assert (processingMode() == RunsLumisAndEvents);
00137           state_ = IsEvent;
00138         } else {
00139           state_ = IsStop;
00140         }
00141       }
00142     } else {
00143       ItemType newState = nextItemType_();
00144       if (newState == IsStop) {
00145         state_ = IsStop;
00146       } else if (newState == IsFile || oldState == IsInvalid) {
00147         state_ = IsFile;
00148       } else if (newState == IsRun || oldState == IsFile) {
00149         RunSourceSentry(*this);
00150         setRunPrincipal(readRun_());
00151         state_ = IsRun;
00152       } else if (newState == IsLumi || oldState == IsRun) {
00153         assert (processingMode() != Runs);
00154         LumiSourceSentry(*this);
00155         setLuminosityBlockPrincipal(readLuminosityBlock_());
00156         state_ = IsLumi;
00157       } else {
00158         assert (processingMode() == RunsLumisAndEvents);
00159         state_ = IsEvent;
00160       }
00161     }
00162     if (state_ == IsStop) {
00163       lumiPrincipal_.reset();
00164       runPrincipal_.reset();
00165     }
00166     return state_;
00167   }
00168 
00169   void
00170   InputSource::doBeginJob(EventSetup const& c) {
00171     beginJob(c);
00172   }
00173 
00174   void
00175   InputSource::doEndJob() {
00176     endJob();
00177   }
00178 
00179   void
00180   InputSource::registerProducts() {
00181     if (!typeLabelList().empty()) {
00182       addToRegistry(typeLabelList().begin(), typeLabelList().end(), moduleDescription(), productRegistryUpdate());
00183     }
00184   }
00185 
00186   // Return a dummy file block.
00187   boost::shared_ptr<FileBlock>
00188   InputSource::readFile() {
00189     assert(doneReadAhead_);
00190     assert(state_ == IsFile);
00191     assert(!limitReached());
00192     doneReadAhead_ = false;
00193     return readFile_();
00194   }
00195 
00196   void
00197   InputSource::closeFile() {
00198     return closeFile_();
00199   }
00200 
00201   // Return a dummy file block.
00202   // This function must be overridden for any input source that reads a file
00203   // containing Products.
00204   boost::shared_ptr<FileBlock>
00205   InputSource::readFile_() {
00206     if (primary()) {
00207       productRegistryUpdate().setProductIDs(1U);
00208     }
00209     return boost::shared_ptr<FileBlock>(new FileBlock);
00210   }
00211 
00212   boost::shared_ptr<RunPrincipal>
00213   InputSource::readRun() {
00214     // Note: For the moment, we do not support saving and restoring the state of the
00215     // random number generator if random numbers are generated during processing of runs
00216     // (e.g. beginRun(), endRun())
00217     assert(doneReadAhead_);
00218     assert(state_ == IsRun);
00219     assert(!limitReached());
00220     doneReadAhead_ = false;
00221     return runPrincipal_;
00222   }
00223 
00224   boost::shared_ptr<LuminosityBlockPrincipal>
00225   InputSource::readLuminosityBlock(boost::shared_ptr<RunPrincipal> rp) {
00226     // Note: For the moment, we do not support saving and restoring the state of the
00227     // random number generator if random numbers are generated during processing of lumi blocks
00228     // (e.g. beginLuminosityBlock(), endLuminosityBlock())
00229     assert(doneReadAhead_);
00230     assert(state_ == IsLumi);
00231     assert(!limitReached());
00232     doneReadAhead_ = false;
00233     --remainingLumis_;
00234     assert(lumiPrincipal_->run() == rp->run());
00235     lumiPrincipal_->setRunPrincipal(rp);
00236     return lumiPrincipal_;
00237   }
00238 
00239   std::auto_ptr<EventPrincipal>
00240   InputSource::readEvent(boost::shared_ptr<LuminosityBlockPrincipal> lbp) {
00241     assert(doneReadAhead_);
00242     assert(state_ == IsEvent);
00243     assert(!eventLimitReached());
00244     doneReadAhead_ = false;
00245 
00246     preRead();
00247     std::auto_ptr<EventPrincipal> result = readEvent_();
00248     assert(lbp->run() == result->run());
00249     assert(lbp->luminosityBlock() == result->luminosityBlock());
00250     result->setLuminosityBlockPrincipal(lbp);
00251     if (result.get() != 0) {
00252       Event event(*result, moduleDescription());
00253       postRead(event);
00254       if (remainingEvents_ > 0) --remainingEvents_;
00255       ++readCount_;
00256       setTimestamp(result->time());
00257       issueReports(result->id(), result->luminosityBlock());
00258     }
00259     return result;
00260   }
00261 
00262   std::auto_ptr<EventPrincipal>
00263   InputSource::readEvent(EventID const& eventID) {
00264 
00265     std::auto_ptr<EventPrincipal> result(0);
00266 
00267     if (!limitReached()) {
00268       preRead();
00269       result = readIt(eventID);
00270       if (result.get() != 0) {
00271         Event event(*result, moduleDescription());
00272         postRead(event);
00273         if (remainingEvents_ > 0) --remainingEvents_;
00274         ++readCount_;
00275         issueReports(result->id(), result->luminosityBlock());
00276       }
00277     }
00278     return result;
00279   }
00280 
00281   void
00282   InputSource::skipEvents(int offset) {
00283     this->skip(offset);
00284   }
00285 
00286   void
00287   InputSource::issueReports(EventID const& eventID, LuminosityBlockNumber_t const& lumi) {
00288     time_t t = time(0);
00289     char ts[] = "dd-Mon-yyyy hh:mm:ss TZN     ";
00290     strftime( ts, strlen(ts)+1, "%d-%b-%Y %H:%M:%S %Z", localtime(&t) );
00291     LogVerbatim("FwkReport") << "Begin processing the " << readCount_
00292                          << suffix(readCount_) << " record. Run " << eventID.run()
00293                          << ", Event " << eventID.event()
00294                                    << ", LumiSection " << lumi<< " at " << ts;
00295       // At some point we may want to initiate checkpointing here
00296   }
00297 
00298   std::auto_ptr<EventPrincipal>
00299   InputSource::readIt(EventID const&) {
00300       throw edm::Exception(edm::errors::LogicError)
00301         << "InputSource::readIt()\n"
00302         << "Random access is not implemented for this type of Input Source\n"
00303         << "Contact a Framework Developer\n";
00304   }
00305 
00306   void
00307   InputSource::setRun(RunNumber_t) {
00308       throw edm::Exception(edm::errors::LogicError)
00309         << "InputSource::setRun()\n"
00310         << "Run number cannot be modified for this type of Input Source\n"
00311         << "Contact a Framework Developer\n";
00312   }
00313 
00314   void
00315   InputSource::setLumi(LuminosityBlockNumber_t) {
00316       throw edm::Exception(edm::errors::LogicError)
00317         << "InputSource::setLumi()\n"
00318         << "Luminosity Block ID  cannot be modified for this type of Input Source\n"
00319         << "Contact a Framework Developer\n";
00320   }
00321 
00322   void
00323   InputSource::skip(int) {
00324       throw edm::Exception(edm::errors::LogicError)
00325         << "InputSource::skip()\n"
00326         << "Random access is not implemented for this type of Input Source\n"
00327         << "Contact a Framework Developer\n";
00328   }
00329 
00330   void
00331   InputSource::rewind_() {
00332       throw edm::Exception(edm::errors::LogicError)
00333         << "InputSource::rewind()\n"
00334         << "Rewind is not implemented for this type of Input Source\n"
00335         << "Contact a Framework Developer\n";
00336   }
00337 
00338   void 
00339   InputSource::preRead() {
00340 
00341     if (primary()) {
00342       Service<RandomNumberGenerator> rng;
00343       if (rng.isAvailable()) {
00344         rng->snapShot();
00345       }
00346     }
00347   }
00348 
00349   void 
00350   InputSource::postRead(Event& event) {
00351 
00352     if (primary()) {
00353       Service<RandomNumberGenerator> rng;
00354       if (rng.isAvailable()) {
00355         rng->restoreState(event);
00356       }
00357     }
00358   }
00359 
00360   void
00361   InputSource::doEndRun(RunPrincipal& rp) {
00362     rp.setEndTime(time_);
00363     Run run(rp, moduleDescription());
00364     endRun(run);
00365     run.commit_();
00366   }
00367 
00368   void
00369   InputSource::doEndLumi(LuminosityBlockPrincipal & lbp) {
00370     lbp.setEndTime(time_);
00371     LuminosityBlock lb(lbp, moduleDescription());
00372     endLuminosityBlock(lb);
00373     lb.commit_();
00374   }
00375 
00376   void 
00377   InputSource::wakeUp_() {}
00378 
00379   void
00380   InputSource::endLuminosityBlock(LuminosityBlock &) {}
00381 
00382   void
00383   InputSource::endRun(Run &) {}
00384 
00385   void
00386   InputSource::beginJob(EventSetup const&) {}
00387 
00388   void
00389   InputSource::endJob() {}
00390 
00391   RunNumber_t
00392   InputSource::run() const {
00393     assert(runPrincipal());
00394     return runPrincipal()->run();
00395   }
00396 
00397   LuminosityBlockNumber_t
00398   InputSource::luminosityBlock() const {
00399     assert(luminosityBlockPrincipal());
00400     return luminosityBlockPrincipal()->luminosityBlock();
00401   }
00402 
00403 
00404   InputSource::SourceSentry::SourceSentry(Sig& pre, Sig& post) : post_(post) {
00405     pre();
00406   }
00407 
00408   InputSource::SourceSentry::~SourceSentry() {
00409     post_();
00410   }
00411 
00412   InputSource::EventSourceSentry::EventSourceSentry(InputSource const& source) :
00413      sentry_(source.actReg()->preSourceSignal_, source.actReg()->postSourceSignal_) {
00414   }
00415 
00416   InputSource::LumiSourceSentry::LumiSourceSentry(InputSource const& source) :
00417      sentry_(source.actReg()->preSourceLumiSignal_, source.actReg()->postSourceLumiSignal_) {
00418   }
00419 
00420   InputSource::RunSourceSentry::RunSourceSentry(InputSource const& source) :
00421      sentry_(source.actReg()->preSourceRunSignal_, source.actReg()->postSourceRunSignal_) {
00422   }
00423 
00424   InputSource::FileOpenSentry::FileOpenSentry(InputSource const& source) :
00425      sentry_(source.actReg()->preOpenFileSignal_, source.actReg()->postOpenFileSignal_) {
00426   }
00427 
00428   InputSource::FileCloseSentry::FileCloseSentry(InputSource const& source) :
00429      sentry_(source.actReg()->preCloseFileSignal_, source.actReg()->postCloseFileSignal_) {
00430   }
00431 }

Generated on Tue Jun 9 17:36:10 2009 for CMSSW by  doxygen 1.5.4