Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-10-03 05:27:03

0001 /*----------------------------------------------------------------------
0002 ----------------------------------------------------------------------*/
0003 
0004 #include <cerrno>
0005 #include <chrono>
0006 
0007 #include "DataFormats/Provenance/interface/LuminosityBlockAuxiliary.h"
0008 #include "DataFormats/Provenance/interface/RunAuxiliary.h"
0009 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0010 #include "DataFormats/Provenance/interface/ProductResolverIndexHelper.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0012 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0013 #include "FWCore/Framework/interface/EventPrincipal.h"
0014 #include "FWCore/Framework/interface/LuminosityBlock.h"
0015 #include "FWCore/Framework/interface/Run.h"
0016 #include "FWCore/Framework/interface/Event.h"
0017 #include "FWCore/Framework/interface/ExceptionHelpers.h"
0018 #include "FWCore/Sources/interface/IDGeneratorSourceBase.h"
0019 
0020 #include "FWCore/Sources/interface/PuttableSourceBase.h"
0021 
0022 namespace {
0023   void checkFirstLumiForRuns(std::vector<edm::LuminosityBlockID> const& iFirstLumis) {
0024     if (iFirstLumis.empty())
0025       return;
0026 
0027     auto previous = iFirstLumis[0].luminosityBlock();
0028     for (auto it = iFirstLumis.begin() + 1; it != iFirstLumis.end(); ++it) {
0029       if (not(it->luminosityBlock() > previous)) {
0030         throw edm::Exception(edm::errors::Configuration)
0031             << "Incorrect ordering of LuminosityBlock numbers in parameter 'firstLuminosityBlockForEachRun'";
0032       }
0033     }
0034   }
0035 }  // namespace
0036 namespace edm {
0037   //used for defaults
0038   static unsigned long long constexpr kNanoSecPerSec = 1000000000ULL;
0039   static unsigned long long constexpr kAveEventPerSec = 200ULL;
0040 
0041   template <typename BASE>
0042   IDGeneratorSourceBase<BASE>::IDGeneratorSourceBase(ParameterSet const& pset,
0043                                                      InputSourceDescription const& desc,
0044                                                      bool realData)
0045       : BASE(pset, desc),
0046         firstLumiForRuns_(
0047             pset.getUntrackedParameter<std::vector<edm::LuminosityBlockID>>("firstLuminosityBlockForEachRun")),
0048         numberEventsInRun_(pset.getUntrackedParameter<unsigned int>("numberEventsInRun", BASE::remainingEvents())),
0049         numberEventsInLumi_(
0050             pset.getUntrackedParameter<unsigned int>("numberEventsInLuminosityBlock", BASE::remainingEvents())),
0051         presentTime_(pset.getUntrackedParameter<unsigned long long>("firstTime", 1ULL)),  //time in ns
0052         origTime_(presentTime_),
0053         timeBetweenEvents_(
0054             pset.getUntrackedParameter<unsigned long long>("timeBetweenEvents", kNanoSecPerSec / kAveEventPerSec)),
0055         eventCreationDelay_(pset.getUntrackedParameter<unsigned int>("eventCreationDelay", 0)),
0056         numberEventsInThisRun_(0),
0057         numberEventsInThisLumi_(0),
0058         zerothEvent_(pset.existsAs<unsigned int>("firstEvent", false)
0059                          ? pset.getUntrackedParameter<unsigned int>("firstEvent", 1) - 1
0060                          : pset.getUntrackedParameter<unsigned long long>("firstEvent", 1) - 1),
0061         eventID_(pset.getUntrackedParameter<unsigned int>("firstRun", 1),
0062                  pset.getUntrackedParameter<unsigned int>("firstLuminosityBlock", 1),
0063                  zerothEvent_),
0064         origEventID_(eventID_),
0065         isRealData_(realData),
0066         eType_(EventAuxiliary::Undefined) {
0067     BASE::setTimestamp(Timestamp(presentTime_));
0068     checkFirstLumiForRuns(firstLumiForRuns_);
0069     if (not firstLumiForRuns_.empty()) {
0070       numberEventsInRun_ = -1;
0071       eventID_ = EventID(runForLumi(eventID_.luminosityBlock()), eventID_.luminosityBlock(), zerothEvent_);
0072     }
0073   }
0074 
0075   template <typename BASE>
0076   IDGeneratorSourceBase<BASE>::~IDGeneratorSourceBase() noexcept(false) {}
0077 
0078   template <typename BASE>
0079   std::shared_ptr<RunAuxiliary> IDGeneratorSourceBase<BASE>::readRunAuxiliary_() {
0080     Timestamp ts = Timestamp(presentTime_);
0081     BASE::resetNewRun();
0082     return std::make_shared<RunAuxiliary>(eventID_.run(), ts, Timestamp::invalidTimestamp());
0083   }
0084 
0085   template <typename BASE>
0086   std::shared_ptr<LuminosityBlockAuxiliary> IDGeneratorSourceBase<BASE>::readLuminosityBlockAuxiliary_() {
0087     if (BASE::processingMode() == BASE::Runs)
0088       return std::shared_ptr<LuminosityBlockAuxiliary>();
0089     Timestamp ts = Timestamp(presentTime_);
0090     BASE::resetNewLumi();
0091     return std::make_shared<LuminosityBlockAuxiliary>(
0092         eventID_.run(), eventID_.luminosityBlock(), ts, Timestamp::invalidTimestamp());
0093   }
0094 
0095   template <typename BASE>
0096   void IDGeneratorSourceBase<BASE>::skip(int offset) {
0097     EventID oldEventID = eventID_;
0098     for (; offset < 0; ++offset) {
0099       retreatToPrevious(eventID_, presentTime_);
0100     }
0101     for (; offset > 0; --offset) {
0102       advanceToNext(eventID_, presentTime_);
0103     }
0104     if (eventID_.run() != oldEventID.run()) {
0105       // New Run
0106       BASE::setNewRun();
0107       BASE::setNewLumi();
0108     }
0109     if (eventID_.luminosityBlock() != oldEventID.luminosityBlock()) {
0110       // New Lumi
0111       BASE::setNewLumi();
0112     }
0113   }
0114 
0115   template <typename BASE>
0116   void IDGeneratorSourceBase<BASE>::beginJob() {
0117     BASE::beginJob();
0118     // Initialize cannot be called from the constructor, because it is a virtual function
0119     // that needs to be invoked from a derived class if the derived class overrides it.
0120     initialize(eventID_, presentTime_, timeBetweenEvents_);
0121   }
0122 
0123   template <typename BASE>
0124   void IDGeneratorSourceBase<BASE>::initialize(EventID&, TimeValue_t&, TimeValue_t&) {}
0125 
0126   template <typename BASE>
0127   void IDGeneratorSourceBase<BASE>::rewind_() {
0128     presentTime_ = origTime_;
0129     eventID_ = origEventID_;
0130     numberEventsInThisRun_ = 0;
0131     numberEventsInThisLumi_ = 0;
0132     BASE::setNewRun();
0133     BASE::setNewLumi();
0134   }
0135 
0136   template <typename BASE>
0137   typename BASE::ItemTypeInfo IDGeneratorSourceBase<BASE>::getNextItemType() {
0138     if (BASE::state() == BASE::ItemType::IsInvalid) {
0139       return noFiles() ? BASE::ItemType::IsStop : BASE::ItemType::IsFile;
0140     }
0141     if (BASE::newRun()) {
0142       return BASE::ItemType::IsRun;
0143     }
0144     if (BASE::newLumi()) {
0145       return BASE::ItemType::IsLumi;
0146     }
0147     if (BASE::eventCached()) {
0148       return BASE::ItemType::IsEvent;
0149     }
0150     EventID oldEventID = eventID_;
0151     advanceToNext(eventID_, presentTime_);
0152     if (eventCreationDelay_ > 0) {
0153       std::this_thread::sleep_for(std::chrono::microseconds(eventCreationDelay_));
0154     }
0155     size_t index = fileIndex();
0156     bool another = setRunAndEventInfo(eventID_, presentTime_, eType_);
0157     if (!another) {
0158       return BASE::ItemType::IsStop;
0159     }
0160     bool newFile = (fileIndex() > index);
0161     BASE::setEventCached();
0162     if (BASE::newRun() || eventID_.run() != oldEventID.run()) {
0163       // New Run
0164       BASE::setNewRun();
0165       BASE::setNewLumi();
0166       return newFile ? BASE::ItemType::IsFile : BASE::ItemType::IsRun;
0167     }
0168     // Same Run
0169     if (BASE::newLumi() || eventID_.luminosityBlock() != oldEventID.luminosityBlock()) {
0170       // New Lumi
0171       BASE::setNewLumi();
0172       return newFile ? BASE::ItemType::IsFile : BASE::ItemType::IsLumi;
0173     }
0174     return newFile ? BASE::ItemType::IsFile : BASE::ItemType::IsEvent;
0175   }
0176 
0177   template <typename BASE>
0178   void IDGeneratorSourceBase<BASE>::advanceToNext(EventID& eventID, TimeValue_t& time) {
0179     if (numberEventsInRun_ < 1 || numberEventsInThisRun_ < numberEventsInRun_) {
0180       // same run
0181       ++numberEventsInThisRun_;
0182       if (!(numberEventsInLumi_ < 1 || numberEventsInThisLumi_ < numberEventsInLumi_)) {
0183         // new lumi
0184         eventID = eventID.next(eventID.luminosityBlock() + 1);
0185         numberEventsInThisLumi_ = 1;
0186         if (not firstLumiForRuns_.empty()) {
0187           auto run = runForLumi(eventID.luminosityBlock());
0188           if (run != eventID.run()) {
0189             numberEventsInThisRun_ = 1;
0190             eventID = eventID.nextRunFirstEvent(eventID_.luminosityBlock());
0191 
0192             eventID = EventID(run, eventID.luminosityBlock(), eventID.event());
0193           }
0194         }
0195       } else {
0196         eventID = eventID.next(eventID.luminosityBlock());
0197         ++numberEventsInThisLumi_;
0198       }
0199     } else {
0200       // new run
0201       eventID = eventID.nextRunFirstEvent(origEventID_.luminosityBlock());
0202       numberEventsInThisLumi_ = 1;
0203       numberEventsInThisRun_ = 1;
0204     }
0205     time += timeBetweenEvents_;
0206   }
0207 
0208   template <typename BASE>
0209   void IDGeneratorSourceBase<BASE>::retreatToPrevious(EventID& eventID, TimeValue_t& time) {
0210     if (numberEventsInRun_ < 1 || numberEventsInThisRun_ > 0) {
0211       // same run
0212       --numberEventsInThisRun_;
0213       eventID = eventID.previous(eventID.luminosityBlock());
0214       if (!(numberEventsInLumi_ < 1 || numberEventsInThisLumi_ > 0)) {
0215         // new lumi
0216         eventID = eventID.previous(eventID.luminosityBlock() - 1);
0217         numberEventsInThisLumi_ = numberEventsInLumi_;
0218 
0219         if (not firstLumiForRuns_.empty()) {
0220           auto run = runForLumi(eventID.luminosityBlock());
0221           if (run != eventID.run()) {
0222             eventID = eventID.previousRunLastEvent(eventID_.luminosityBlock());
0223 
0224             eventID = EventID(run, eventID.luminosityBlock(), eventID.event());
0225           }
0226         }
0227       } else {
0228         --numberEventsInThisLumi_;
0229       }
0230     } else {
0231       // new run
0232       assert(numberEventsInLumi_ != 0);
0233       eventID = eventID.previousRunLastEvent(origEventID_.luminosityBlock() + numberEventsInRun_ / numberEventsInLumi_);
0234       eventID = EventID(numberEventsInRun_, eventID.luminosityBlock(), eventID.run());
0235       numberEventsInThisLumi_ = numberEventsInLumi_;
0236       numberEventsInThisRun_ = numberEventsInRun_;
0237     }
0238     time -= timeBetweenEvents_;
0239   }
0240 
0241   template <typename BASE>
0242   RunNumber_t IDGeneratorSourceBase<BASE>::runForLumi(LuminosityBlockNumber_t iLumi) const {
0243     auto it = std::find_if(firstLumiForRuns_.rbegin(), firstLumiForRuns_.rend(), [iLumi](auto const& iV) {
0244       return iV.luminosityBlock() <= iLumi;
0245     });
0246     if (it == firstLumiForRuns_.rend()) {
0247       //use first since we are off the end
0248       return firstLumiForRuns_[0].run();
0249     }
0250     return it->run();
0251   }
0252 
0253   template <typename BASE>
0254   bool IDGeneratorSourceBase<BASE>::noFiles() const {
0255     return false;
0256   }
0257 
0258   template <typename BASE>
0259   size_t IDGeneratorSourceBase<BASE>::fileIndex() const {
0260     return 0UL;
0261   }
0262 
0263   template <typename BASE>
0264   void IDGeneratorSourceBase<BASE>::fillDescription(ParameterSetDescription& desc) {
0265     desc.addOptionalUntracked<unsigned int>("numberEventsInRun")
0266         ->setComment("Number of events to generate in each run.");
0267     desc.addOptionalUntracked<unsigned int>("numberEventsInLuminosityBlock")
0268         ->setComment("Number of events to generate in each lumi.");
0269     desc.addUntracked<unsigned long long>("firstTime", 1)->setComment("Time before first event (ns) (for timestamp).");
0270     desc.addUntracked<unsigned long long>("timeBetweenEvents", kNanoSecPerSec / kAveEventPerSec)
0271         ->setComment("Time between consecutive events (ns) (for timestamp).");
0272     desc.addUntracked<unsigned int>("eventCreationDelay", 0)
0273         ->setComment("Real time delay between generation of consecutive events (ms).");
0274 
0275     desc.addNode(edm::ParameterDescription<unsigned int>("firstEvent", 1U, false) xor
0276                  edm::ParameterDescription<unsigned long long>("firstEvent", 1ULL, false))
0277         ->setComment(
0278             "'firstEvent' is an XOR group because it can have type uint32 or uint64, default:1\n"
0279             "Event number of first event to generate.");
0280 
0281     desc.addUntracked<unsigned int>("firstLuminosityBlock", 1)
0282         ->setComment("Luminosity block number of first lumi to generate.");
0283     desc.addUntracked<unsigned int>("firstRun", 1)->setComment("Run number of first run to generate.");
0284     desc.addUntracked<std::vector<edm::LuminosityBlockID>>("firstLuminosityBlockForEachRun", {})
0285         ->setComment(
0286             "When the source makes a new LuminosityBlock, this list is checked to see what Run number should be used. "
0287             "The LuminosityBlock numbers are required to be in ascending order.");
0288     BASE::fillDescription(desc);
0289   }
0290 
0291   template class IDGeneratorSourceBase<PuttableSourceBase>;
0292   template class IDGeneratorSourceBase<InputSource>;
0293 }  // namespace edm