Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-01-12 23:41:44

0001 #ifndef IOPool_Streamer_interface_RawEventOutputModuleForBU_h
0002 #define IOPool_Streamer_interface_RawEventOutputModuleForBU_h
0003 
0004 #include <memory>
0005 #include <vector>
0006 
0007 #include "DataFormats/Common/interface/Handle.h"
0008 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0009 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0010 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0011 #include "EventFilter/Utilities/interface/EvFDaqDirector.h"
0012 #include "EventFilter/Utilities/interface/crc32c.h"
0013 #include "EventFilter/Utilities/plugins/EvFBuildingThrottle.h"
0014 #include "FWCore/Framework/interface/EventForOutput.h"
0015 #include "FWCore/Framework/interface/LuminosityBlockForOutput.h"
0016 #include "FWCore/Framework/interface/one/OutputModule.h"
0017 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0018 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0019 #include "FWCore/ServiceRegistry/interface/ModuleCallingContext.h"
0020 #include "FWCore/ServiceRegistry/interface/Service.h"
0021 #include "FWCore/Utilities/interface/Adler32Calculator.h"
0022 #include "FWCore/Utilities/interface/EDGetToken.h"
0023 #include "IOPool/Streamer/interface/FRDEventMessage.h"
0024 
0025 template <class Consumer>
0026 class RawEventOutputModuleForBU : public edm::one::OutputModule<edm::one::WatchRuns, edm::one::WatchLuminosityBlocks> {
0027   /**
0028    * Consumers are suppose to provide:
0029    *   void doOutputEvent(const FRDEventMsgView& msg)
0030    *   void start()
0031    *   void stop()
0032    */
0033 
0034 public:
0035   explicit RawEventOutputModuleForBU(edm::ParameterSet const& ps);
0036   ~RawEventOutputModuleForBU() override;
0037 
0038   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0039 
0040 private:
0041   void write(edm::EventForOutput const& e) override;
0042   void beginRun(edm::RunForOutput const&) override;
0043   void endRun(edm::RunForOutput const&) override;
0044   void writeRun(const edm::RunForOutput&) override {}
0045   void writeLuminosityBlock(const edm::LuminosityBlockForOutput&) override {}
0046 
0047   void beginLuminosityBlock(edm::LuminosityBlockForOutput const&) override;
0048   void endLuminosityBlock(edm::LuminosityBlockForOutput const&) override;
0049 
0050   std::unique_ptr<Consumer> templateConsumer_;
0051   const edm::EDGetTokenT<FEDRawDataCollection> token_;
0052   const unsigned int numEventsPerFile_;
0053   const unsigned int frdVersion_;
0054   std::vector<unsigned int> sourceIdList_;
0055   unsigned int totevents_ = 0;
0056   unsigned int index_ = 0;
0057   bool firstLumi_ = true;
0058 };
0059 
0060 template <class Consumer>
0061 RawEventOutputModuleForBU<Consumer>::RawEventOutputModuleForBU(edm::ParameterSet const& ps)
0062     : edm::one::OutputModuleBase::OutputModuleBase(ps),
0063       edm::one::OutputModule<edm::one::WatchRuns, edm::one::WatchLuminosityBlocks>(ps),
0064       templateConsumer_(new Consumer(ps)),
0065       token_(consumes<FEDRawDataCollection>(ps.getParameter<edm::InputTag>("source"))),
0066       numEventsPerFile_(ps.getParameter<unsigned int>("numEventsPerFile")),
0067       frdVersion_(ps.getParameter<unsigned int>("frdVersion")),
0068       sourceIdList_(ps.getUntrackedParameter<std::vector<unsigned int>>("sourceIdList", std::vector<unsigned int>())) {
0069   if (frdVersion_ > 0 && frdVersion_ < 5)
0070     throw cms::Exception("RawEventOutputModuleForBU")
0071         << "Generating data with FRD version " << frdVersion_ << " is no longer supported";
0072   else if (frdVersion_ > edm::streamer::FRDHeaderMaxVersion)
0073     throw cms::Exception("RawEventOutputModuleForBU") << "Unknown FRD version " << frdVersion_;
0074 }
0075 
0076 template <class Consumer>
0077 RawEventOutputModuleForBU<Consumer>::~RawEventOutputModuleForBU() {}
0078 
0079 template <class Consumer>
0080 void RawEventOutputModuleForBU<Consumer>::write(edm::EventForOutput const& e) {
0081   //using namespace edm::streamer;
0082 
0083   if (totevents_ > 0 && totevents_ % numEventsPerFile_ == 0) {
0084     index_++;
0085     unsigned int ls = e.luminosityBlock();
0086     std::string filename = edm::Service<evf::EvFDaqDirector>()->getOpenRawFilePath(ls, index_);
0087     std::string destinationDir = edm::Service<evf::EvFDaqDirector>()->buBaseRunDir();
0088     int run = edm::Service<evf::EvFDaqDirector>()->getRunNumber();
0089     templateConsumer_->initialize(destinationDir, filename, run, ls);
0090   }
0091   totevents_++;
0092   // serialize the FEDRawDataCollection into the format that we expect for
0093   // FRDEventMsgView objects (may be better ways to do this)
0094   edm::Handle<FEDRawDataCollection> fedBuffers;
0095   e.getByToken(token_, fedBuffers);
0096 
0097   // determine the expected size of the FRDEvent IN bytes
0098   int headerSize = edm::streamer::FRDHeaderVersionSize[frdVersion_];
0099   int expectedSize = headerSize;
0100   int nFeds = FEDNumbering::lastFEDId() + 1;
0101 
0102   if (sourceIdList_.size()) {
0103     for (int idx : sourceIdList_) {
0104       FEDRawData singleFED = fedBuffers->FEDData(idx);
0105       expectedSize += singleFED.size();
0106     }
0107   } else {
0108     for (int idx = 0; idx < nFeds; ++idx) {
0109       FEDRawData singleFED = fedBuffers->FEDData(idx);
0110       expectedSize += singleFED.size();
0111     }
0112   }
0113 
0114   // build the FRDEvent into a temporary buffer
0115   std::unique_ptr<std::vector<unsigned char>> workBuffer(
0116       std::make_unique<std::vector<unsigned char>>(expectedSize + 256));
0117   uint32_t* bufPtr = (uint32_t*)(workBuffer.get()->data());
0118 
0119   if (frdVersion_) {
0120     if (frdVersion_ <= 5) {
0121       //32-bits version field
0122       *bufPtr++ = (uint32_t)frdVersion_;
0123     } else {
0124       //16 bits version and 16 bits flags
0125       uint16_t flags = 0;
0126       if (!e.eventAuxiliary().isRealData())
0127         flags |= edm::streamer::FRDEVENT_MASK_ISGENDATA;
0128       *(uint16_t*)bufPtr = (uint16_t)(frdVersion_ & 0xffff);
0129       *((uint16_t*)bufPtr + 1) = flags;
0130       bufPtr++;
0131     }
0132     *bufPtr++ = (uint32_t)e.id().run();
0133     *bufPtr++ = (uint32_t)e.luminosityBlock();
0134     *bufPtr++ = (uint32_t)e.id().event();
0135     *bufPtr++ = expectedSize - headerSize;
0136     *bufPtr++ = 0;
0137   }
0138   uint32_t* payloadPtr = bufPtr;
0139   if (sourceIdList_.size())
0140     for (int idx : sourceIdList_) {
0141       FEDRawData singleFED = fedBuffers->FEDData(idx);
0142       if (singleFED.size() > 0) {
0143         memcpy(bufPtr, singleFED.data(), singleFED.size());
0144         bufPtr += singleFED.size() / 4;
0145       }
0146     }
0147   else
0148     for (int idx = 0; idx < nFeds; ++idx) {
0149       FEDRawData singleFED = fedBuffers->FEDData(idx);
0150       if (singleFED.size() > 0) {
0151         memcpy(bufPtr, singleFED.data(), singleFED.size());
0152         bufPtr += singleFED.size() / 4;
0153       }
0154     }
0155   if (frdVersion_) {
0156     //crc32c checksum
0157     uint32_t crc = 0;
0158     *(payloadPtr - 1) = crc32c(crc, (const unsigned char*)payloadPtr, expectedSize - headerSize);
0159 
0160     // create the FRDEventMsgView and use the template consumer to write it out
0161     edm::streamer::FRDEventMsgView msg(workBuffer.get()->data());
0162     templateConsumer_->doOutputEvent(msg);
0163   } else {
0164     //write only raw FEDs
0165     templateConsumer_->doOutputEvent((void*)workBuffer.get()->data(), expectedSize);
0166   }
0167 }
0168 
0169 template <class Consumer>
0170 void RawEventOutputModuleForBU<Consumer>::beginRun(edm::RunForOutput const&) {
0171   // edm::Service<evf::EvFDaqDirector>()->updateBuLock(1);
0172   templateConsumer_->start();
0173 }
0174 
0175 template <class Consumer>
0176 void RawEventOutputModuleForBU<Consumer>::endRun(edm::RunForOutput const&) {
0177   templateConsumer_->stop();
0178 }
0179 
0180 template <class Consumer>
0181 void RawEventOutputModuleForBU<Consumer>::beginLuminosityBlock(edm::LuminosityBlockForOutput const& ls) {
0182   index_ = 0;
0183   std::string filename = edm::Service<evf::EvFDaqDirector>()->getOpenRawFilePath(ls.id().luminosityBlock(), index_);
0184   std::string destinationDir = edm::Service<evf::EvFDaqDirector>()->buBaseRunDir();
0185   int run = edm::Service<evf::EvFDaqDirector>()->getRunNumber();
0186   std::cout << " writing to destination dir " << destinationDir << " name: " << filename << std::endl;
0187   templateConsumer_->initialize(destinationDir, filename, run, ls.id().luminosityBlock());
0188   if (!firstLumi_) {
0189     totevents_ = 0;
0190     firstLumi_ = false;
0191   }
0192 }
0193 
0194 template <class Consumer>
0195 void RawEventOutputModuleForBU<Consumer>::endLuminosityBlock(edm::LuminosityBlockForOutput const& ls) {
0196   //  templateConsumer_->touchlock(ls.id().luminosityBlock(),basedir);
0197   templateConsumer_->endOfLS(ls.id().luminosityBlock());
0198 }
0199 
0200 template <class Consumer>
0201 void RawEventOutputModuleForBU<Consumer>::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0202   edm::ParameterSetDescription desc;
0203   desc.add<edm::InputTag>("source", edm::InputTag("rawDataCollector"));
0204   desc.add<unsigned int>("numEventsPerFile", 100);
0205   desc.add<unsigned int>("frdVersion", 6);
0206   desc.addUntracked<std::vector<unsigned int>>("sourceIdList", std::vector<unsigned int>());
0207   Consumer::extendDescription(desc);
0208 
0209   descriptions.addWithDefaultLabel(desc);
0210 }
0211 
0212 #endif  // IOPool_Streamer_interface_RawEventOutputModuleForBU_h