Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-03-19 23:41:16

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   typedef unsigned int uint32;
0028   /**
0029    * Consumers are suppose to provide:
0030    *   void doOutputEvent(const FRDEventMsgView& msg)
0031    *   void start()
0032    *   void stop()
0033    */
0034 
0035 public:
0036   explicit RawEventOutputModuleForBU(edm::ParameterSet const& ps);
0037   ~RawEventOutputModuleForBU() override;
0038 
0039   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0040 
0041 private:
0042   void write(edm::EventForOutput const& e) override;
0043   void beginRun(edm::RunForOutput const&) override;
0044   void endRun(edm::RunForOutput const&) override;
0045   void writeRun(const edm::RunForOutput&) override {}
0046   void writeLuminosityBlock(const edm::LuminosityBlockForOutput&) override {}
0047 
0048   void beginLuminosityBlock(edm::LuminosityBlockForOutput const&) override;
0049   void endLuminosityBlock(edm::LuminosityBlockForOutput const&) override;
0050 
0051   std::unique_ptr<Consumer> templateConsumer_;
0052   const edm::EDGetTokenT<FEDRawDataCollection> token_;
0053   const unsigned int numEventsPerFile_;
0054   const unsigned int frdVersion_;
0055   unsigned long long totsize = 0LL;
0056   unsigned long long writtensize = 0LL;
0057   unsigned long long writtenSizeLast = 0LL;
0058   unsigned int totevents = 0;
0059   unsigned int index_ = 0;
0060   timeval startOfLastLumi;
0061   bool firstLumi_ = true;
0062 };
0063 
0064 template <class Consumer>
0065 RawEventOutputModuleForBU<Consumer>::RawEventOutputModuleForBU(edm::ParameterSet const& ps)
0066     : edm::one::OutputModuleBase::OutputModuleBase(ps),
0067       edm::one::OutputModule<edm::one::WatchRuns, edm::one::WatchLuminosityBlocks>(ps),
0068       templateConsumer_(new Consumer(ps)),
0069       token_(consumes<FEDRawDataCollection>(ps.getParameter<edm::InputTag>("source"))),
0070       numEventsPerFile_(ps.getParameter<unsigned int>("numEventsPerFile")),
0071       frdVersion_(ps.getParameter<unsigned int>("frdVersion")) {}
0072 
0073 template <class Consumer>
0074 RawEventOutputModuleForBU<Consumer>::~RawEventOutputModuleForBU() {}
0075 
0076 template <class Consumer>
0077 void RawEventOutputModuleForBU<Consumer>::write(edm::EventForOutput const& e) {
0078   unsigned int ls = e.luminosityBlock();
0079   if (totevents > 0 && totevents % numEventsPerFile_ == 0) {
0080     index_++;
0081     std::string filename = edm::Service<evf::EvFDaqDirector>()->getOpenRawFilePath(ls, index_);
0082     std::string destinationDir = edm::Service<evf::EvFDaqDirector>()->buBaseRunDir();
0083     templateConsumer_->initialize(destinationDir, filename, ls);
0084   }
0085   totevents++;
0086   // serialize the FEDRawDataCollection into the format that we expect for
0087   // FRDEventMsgView objects (may be better ways to do this)
0088   edm::Handle<FEDRawDataCollection> fedBuffers;
0089   e.getByToken(token_, fedBuffers);
0090 
0091   // determine the expected size of the FRDEvent IN BYTES !!!!!
0092   assert(frdVersion_ <= FRDHeaderMaxVersion);
0093   int headerSize = FRDHeaderVersionSize[frdVersion_];
0094   int expectedSize = headerSize;
0095   int nFeds = frdVersion_ < 3 ? 1024 : FEDNumbering::lastFEDId() + 1;
0096 
0097   for (int idx = 0; idx < nFeds; ++idx) {
0098     FEDRawData singleFED = fedBuffers->FEDData(idx);
0099     expectedSize += singleFED.size();
0100   }
0101 
0102   totsize += expectedSize;
0103   // build the FRDEvent into a temporary buffer
0104   std::unique_ptr<std::vector<unsigned char>> workBuffer(
0105       std::make_unique<std::vector<unsigned char>>(expectedSize + 256));
0106   uint32* bufPtr = (uint32*)(workBuffer.get()->data());
0107   if (frdVersion_ <= 5) {
0108     *bufPtr++ = (uint32)frdVersion_;  // version number only
0109   } else {
0110     uint16 flags = 0;
0111     if (!e.eventAuxiliary().isRealData())
0112       flags |= FRDEVENT_MASK_ISGENDATA;
0113     *(uint16*)bufPtr = (uint16)(frdVersion_ & 0xffff);
0114     *((uint16*)bufPtr + 1) = flags;
0115     bufPtr++;
0116   }
0117   *bufPtr++ = (uint32)e.id().run();
0118   *bufPtr++ = (uint32)e.luminosityBlock();
0119   *bufPtr++ = (uint32)e.id().event();
0120   if (frdVersion_ == 4)
0121     *bufPtr++ = 0;  //64-bit event id high part
0122 
0123   if (frdVersion_ < 3) {
0124     uint32 fedsize[1024];
0125     for (int idx = 0; idx < 1024; ++idx) {
0126       FEDRawData singleFED = fedBuffers->FEDData(idx);
0127       fedsize[idx] = singleFED.size();
0128       //std::cout << "fed size " << singleFED.size()<< std::endl;
0129     }
0130     memcpy(bufPtr, fedsize, 1024 * sizeof(uint32));
0131     bufPtr += 1024;
0132   } else {
0133     *bufPtr++ = expectedSize - headerSize;
0134     *bufPtr++ = 0;
0135     if (frdVersion_ <= 4)
0136       *bufPtr++ = 0;
0137   }
0138   uint32* payloadPtr = bufPtr;
0139   for (int idx = 0; idx < nFeds; ++idx) {
0140     FEDRawData singleFED = fedBuffers->FEDData(idx);
0141     if (singleFED.size() > 0) {
0142       memcpy(bufPtr, singleFED.data(), singleFED.size());
0143       bufPtr += singleFED.size() / 4;
0144     }
0145   }
0146   if (frdVersion_ > 4) {
0147     //crc32c checksum
0148     uint32_t crc = 0;
0149     *(payloadPtr - 1) = crc32c(crc, (const unsigned char*)payloadPtr, expectedSize - headerSize);
0150   } else if (frdVersion_ >= 3) {
0151     //adler32 checksum
0152     uint32 adlera = 1;
0153     uint32 adlerb = 0;
0154     cms::Adler32((const char*)payloadPtr, expectedSize - headerSize, adlera, adlerb);
0155     *(payloadPtr - 1) = (adlerb << 16) | adlera;
0156   }
0157 
0158   // create the FRDEventMsgView and use the template consumer to write it out
0159   FRDEventMsgView msg(workBuffer.get()->data());
0160   writtensize += msg.size();
0161 
0162   templateConsumer_->doOutputEvent(msg);
0163 }
0164 
0165 template <class Consumer>
0166 void RawEventOutputModuleForBU<Consumer>::beginRun(edm::RunForOutput const&) {
0167   // edm::Service<evf::EvFDaqDirector>()->updateBuLock(1);
0168   templateConsumer_->start();
0169 }
0170 
0171 template <class Consumer>
0172 void RawEventOutputModuleForBU<Consumer>::endRun(edm::RunForOutput const&) {
0173   templateConsumer_->stop();
0174 }
0175 
0176 template <class Consumer>
0177 void RawEventOutputModuleForBU<Consumer>::beginLuminosityBlock(edm::LuminosityBlockForOutput const& ls) {
0178   index_ = 0;
0179   std::string filename = edm::Service<evf::EvFDaqDirector>()->getOpenRawFilePath(ls.id().luminosityBlock(), index_);
0180   std::string destinationDir = edm::Service<evf::EvFDaqDirector>()->buBaseRunDir();
0181   std::cout << " writing to destination dir " << destinationDir << " name: " << filename << std::endl;
0182   templateConsumer_->initialize(destinationDir, filename, ls.id().luminosityBlock());
0183   //edm::Service<evf::EvFDaqDirector>()->updateBuLock(ls.id().luminosityBlock()+1);
0184   if (!firstLumi_) {
0185     timeval now;
0186     ::gettimeofday(&now, nullptr);
0187     //long long elapsedusec = (now.tv_sec - startOfLastLumi.tv_sec)*1000000+now.tv_usec-startOfLastLumi.tv_usec;
0188     /*     std::cout << "(now.tv_sec - startOfLastLumi.tv_sec) " << now.tv_sec <<"-" << startOfLastLumi.tv_sec */
0189     /*        <<" (now.tv_usec-startOfLastLumi.tv_usec) " << now.tv_usec << "-" << startOfLastLumi.tv_usec << std::endl; */
0190     /*     std::cout << "elapsedusec " << elapsedusec << "  totevents " << totevents << "  size (GB)" << writtensize  */
0191     /*        << "  rate " << (writtensize-writtenSizeLast)/elapsedusec << " MB/s" <<std::endl; */
0192     writtenSizeLast = writtensize;
0193     ::gettimeofday(&startOfLastLumi, nullptr);
0194     //edm::Service<evf::EvFDaqDirector>()->writeLsStatisticsBU(ls.id().luminosityBlock(), totevents, totsize, elapsedusec);
0195   } else
0196     ::gettimeofday(&startOfLastLumi, nullptr);
0197   totevents = 0;
0198   totsize = 0LL;
0199   firstLumi_ = false;
0200 }
0201 
0202 template <class Consumer>
0203 void RawEventOutputModuleForBU<Consumer>::endLuminosityBlock(edm::LuminosityBlockForOutput const& ls) {
0204   //  templateConsumer_->touchlock(ls.id().luminosityBlock(),basedir);
0205   templateConsumer_->endOfLS(ls.id().luminosityBlock());
0206 }
0207 
0208 template <class Consumer>
0209 void RawEventOutputModuleForBU<Consumer>::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0210   edm::ParameterSetDescription desc;
0211   desc.add<edm::InputTag>("source", edm::InputTag("rawDataCollector"));
0212   desc.add<unsigned int>("numEventsPerFile", 100);
0213   desc.add<unsigned int>("frdVersion", 6);
0214   Consumer::extendDescription(desc);
0215 
0216   descriptions.addWithDefaultLabel(desc);
0217 }
0218 
0219 #endif  // IOPool_Streamer_interface_RawEventOutputModuleForBU_h