Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-31 04:19:30

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