File indexing completed on 2023-03-17 11:00:29
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
0030
0031
0032
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
0087
0088 edm::Handle<FEDRawDataCollection> fedBuffers;
0089 e.getByToken(token_, fedBuffers);
0090
0091
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
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_;
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;
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
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
0148 uint32_t crc = 0;
0149 *(payloadPtr - 1) = crc32c(crc, (const unsigned char*)payloadPtr, expectedSize - headerSize);
0150 } else if (frdVersion_ >= 3) {
0151
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
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
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
0184 if (!firstLumi_) {
0185 timeval now;
0186 ::gettimeofday(&now, nullptr);
0187
0188
0189
0190
0191
0192 writtenSizeLast = writtensize;
0193 ::gettimeofday(&startOfLastLumi, nullptr);
0194
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
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