File indexing completed on 2025-06-29 22:57:59
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/RawDataBuffer.h"
0010 #include "EventFilter/Utilities/interface/EvFDaqDirector.h"
0011 #include "EventFilter/Utilities/interface/crc32c.h"
0012 #include "EventFilter/Utilities/plugins/EvFBuildingThrottle.h"
0013 #include "FWCore/Framework/interface/EventForOutput.h"
0014 #include "FWCore/Framework/interface/LuminosityBlockForOutput.h"
0015 #include "FWCore/Framework/interface/one/OutputModule.h"
0016 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0017 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0018 #include "FWCore/ServiceRegistry/interface/ModuleCallingContext.h"
0019 #include "FWCore/ServiceRegistry/interface/Service.h"
0020 #include "FWCore/Utilities/interface/Adler32Calculator.h"
0021 #include "FWCore/Utilities/interface/EDGetToken.h"
0022 #include "IOPool/Streamer/interface/FRDEventMessage.h"
0023
0024 template <class Consumer>
0025 class RawEventOutputModuleForBU : public edm::one::OutputModule<edm::one::WatchRuns, edm::one::WatchLuminosityBlocks> {
0026
0027
0028
0029
0030
0031
0032
0033 public:
0034 explicit RawEventOutputModuleForBU(edm::ParameterSet const& ps);
0035 ~RawEventOutputModuleForBU() override;
0036
0037 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0038
0039 private:
0040 void write(edm::EventForOutput const& e) override;
0041 void beginRun(edm::RunForOutput const&) override;
0042 void endRun(edm::RunForOutput const&) override;
0043 void writeRun(const edm::RunForOutput&) override {}
0044 void writeLuminosityBlock(const edm::LuminosityBlockForOutput&) override {}
0045
0046 void beginLuminosityBlock(edm::LuminosityBlockForOutput const&) override;
0047 void endLuminosityBlock(edm::LuminosityBlockForOutput const&) override;
0048
0049 std::unique_ptr<Consumer> templateConsumer_;
0050 const edm::EDGetTokenT<FEDRawDataCollection> tokenFRD_;
0051 const edm::EDGetTokenT<RawDataBuffer> token_;
0052 const unsigned int numEventsPerFile_;
0053 const unsigned int frdVersion_;
0054 std::string rawProductName_;
0055 unsigned int rawProductType_ = 0;
0056 std::vector<unsigned int> sourceIdList_;
0057 unsigned int totevents_ = 0;
0058 unsigned int index_ = 0;
0059 };
0060
0061 template <class Consumer>
0062 RawEventOutputModuleForBU<Consumer>::RawEventOutputModuleForBU(edm::ParameterSet const& ps)
0063 : edm::one::OutputModuleBase::OutputModuleBase(ps),
0064 edm::one::OutputModule<edm::one::WatchRuns, edm::one::WatchLuminosityBlocks>(ps),
0065 templateConsumer_(new Consumer(ps)),
0066 tokenFRD_(consumes<FEDRawDataCollection>(ps.getParameter<edm::InputTag>("source"))),
0067 token_(consumes<RawDataBuffer>(ps.getParameter<edm::InputTag>("source"))),
0068 numEventsPerFile_(ps.getParameter<unsigned int>("numEventsPerFile")),
0069 frdVersion_(ps.getParameter<unsigned int>("frdVersion")),
0070 rawProductName_(ps.getUntrackedParameter<std::string>("rawProductName")),
0071 sourceIdList_(ps.getUntrackedParameter<std::vector<unsigned int>>("sourceIdList", std::vector<unsigned int>())) {
0072 if (rawProductName_ == "FEDRawDataCollection")
0073 rawProductType_ = 1;
0074 else if (rawProductName_ == "RawDataBuffer")
0075 rawProductType_ = 2;
0076 else
0077 throw cms::Exception("RawEventOutputModuleForBU") << "Unknown raw product specified";
0078 if (frdVersion_ > 0 && frdVersion_ < 5)
0079 throw cms::Exception("RawEventOutputModuleForBU")
0080 << "Generating data with FRD version " << frdVersion_ << " is no longer supported";
0081 else if (frdVersion_ > edm::streamer::FRDHeaderMaxVersion)
0082 throw cms::Exception("RawEventOutputModuleForBU") << "Unknown FRD version " << frdVersion_;
0083 }
0084
0085 template <class Consumer>
0086 RawEventOutputModuleForBU<Consumer>::~RawEventOutputModuleForBU() {}
0087
0088 template <class Consumer>
0089 void RawEventOutputModuleForBU<Consumer>::write(edm::EventForOutput const& e) {
0090
0091
0092 if (totevents_ > 0 && totevents_ % numEventsPerFile_ == 0) {
0093 index_++;
0094 unsigned int ls = e.luminosityBlock();
0095 std::string filename = edm::Service<evf::EvFDaqDirector>()->getOpenRawFilePath(ls, index_);
0096 std::string destinationDir = edm::Service<evf::EvFDaqDirector>()->buBaseRunDir();
0097 int run = edm::Service<evf::EvFDaqDirector>()->getRunNumber();
0098 templateConsumer_->initialize(destinationDir, filename, run, ls);
0099 }
0100 totevents_++;
0101
0102
0103 edm::Handle<FEDRawDataCollection> fedBuffers;
0104 edm::Handle<RawDataBuffer> fedBuffer;
0105
0106 unsigned int usedRawType = 0;
0107 if (rawProductType_ == 1) {
0108 e.getByToken(tokenFRD_, fedBuffers);
0109 usedRawType = 1;
0110 } else if (rawProductType_ == 2) {
0111 e.getByToken(token_, fedBuffer);
0112 usedRawType = 2;
0113 }
0114 assert(usedRawType);
0115
0116
0117 int headerSize = edm::streamer::FRDHeaderVersionSize[frdVersion_];
0118 int expectedSize = headerSize;
0119
0120 int nFeds = FEDNumbering::lastFEDId() + 1;
0121
0122 if (usedRawType == 1) {
0123 if (!sourceIdList_.empty()) {
0124 for (int idx : sourceIdList_) {
0125 auto singleFED = fedBuffers->FEDData(idx);
0126 expectedSize += singleFED.size();
0127 }
0128 } else {
0129 for (int idx = 0; idx < nFeds; ++idx) {
0130 auto singleFED = fedBuffers->FEDData(idx);
0131 expectedSize += singleFED.size();
0132 }
0133 }
0134 } else if (usedRawType == 2) {
0135 if (!sourceIdList_.empty()) {
0136 for (int idx : sourceIdList_) {
0137 auto singleFED = fedBuffer->fragmentData(idx);
0138 expectedSize += singleFED.size();
0139 }
0140 } else {
0141
0142 for (auto it = fedBuffer->map().begin(); it != fedBuffer->map().end(); it++) {
0143 auto singleFED = fedBuffer->fragmentData(it);
0144 expectedSize += singleFED.size();
0145 }
0146 }
0147 }
0148
0149
0150 std::unique_ptr<std::vector<unsigned char>> workBuffer(
0151 std::make_unique<std::vector<unsigned char>>(expectedSize + 256));
0152 uint32_t* bufPtr = (uint32_t*)(workBuffer.get()->data());
0153
0154 if (frdVersion_) {
0155 if (frdVersion_ <= 5) {
0156
0157 *bufPtr++ = (uint32_t)frdVersion_;
0158 } else {
0159
0160 uint16_t flags = 0;
0161 if (!e.eventAuxiliary().isRealData())
0162 flags |= edm::streamer::FRDEVENT_MASK_ISGENDATA;
0163 *(uint16_t*)bufPtr = (uint16_t)(frdVersion_ & 0xffff);
0164 *((uint16_t*)bufPtr + 1) = flags;
0165 bufPtr++;
0166 }
0167 *bufPtr++ = (uint32_t)e.id().run();
0168 *bufPtr++ = (uint32_t)e.luminosityBlock();
0169 *bufPtr++ = (uint32_t)e.id().event();
0170 *bufPtr++ = expectedSize - headerSize;
0171 *bufPtr++ = 0;
0172 }
0173 uint32_t* payloadPtr = bufPtr;
0174 if (usedRawType == 1) {
0175 if (!sourceIdList_.empty()) {
0176 for (int idx : sourceIdList_) {
0177 FEDRawData singleFED = fedBuffers->FEDData(idx);
0178 if (singleFED.size() > 0) {
0179 memcpy(bufPtr, singleFED.data(), singleFED.size());
0180 bufPtr += singleFED.size() / 4;
0181 }
0182 }
0183 } else {
0184 for (int idx = 0; idx < nFeds; ++idx) {
0185 FEDRawData singleFED = fedBuffers->FEDData(idx);
0186 if (singleFED.size() > 0) {
0187 memcpy(bufPtr, singleFED.data(), singleFED.size());
0188 bufPtr += singleFED.size() / 4;
0189 }
0190 }
0191 }
0192 } else if (usedRawType == 2) {
0193 if (!sourceIdList_.empty()) {
0194 for (int idx : sourceIdList_) {
0195 auto singleFED = fedBuffer->fragmentData(idx);
0196 memcpy(bufPtr, &singleFED.data()[0], singleFED.size());
0197 bufPtr += singleFED.size() / 4;
0198 }
0199 } else {
0200 for (auto it = fedBuffer->map().begin(); it != fedBuffer->map().end(); it++) {
0201 auto singleFED = fedBuffer->fragmentData(it);
0202 memcpy(bufPtr, &singleFED.data()[0], singleFED.size());
0203 bufPtr += singleFED.size() / 4;
0204 }
0205 }
0206 }
0207 if (frdVersion_) {
0208
0209 uint32_t crc = 0;
0210 *(payloadPtr - 1) = crc32c(crc, (const unsigned char*)payloadPtr, expectedSize - headerSize);
0211
0212
0213 edm::streamer::FRDEventMsgView msg(workBuffer.get()->data());
0214 templateConsumer_->doOutputEvent(msg);
0215 } else {
0216
0217 templateConsumer_->doOutputEvent((void*)workBuffer.get()->data(), expectedSize);
0218 }
0219 }
0220
0221 template <class Consumer>
0222 void RawEventOutputModuleForBU<Consumer>::beginRun(edm::RunForOutput const&) {
0223
0224 templateConsumer_->start();
0225 }
0226
0227 template <class Consumer>
0228 void RawEventOutputModuleForBU<Consumer>::endRun(edm::RunForOutput const&) {
0229 templateConsumer_->stop();
0230 }
0231
0232 template <class Consumer>
0233 void RawEventOutputModuleForBU<Consumer>::beginLuminosityBlock(edm::LuminosityBlockForOutput const& ls) {
0234 index_ = 0;
0235 std::string filename = edm::Service<evf::EvFDaqDirector>()->getOpenRawFilePath(ls.id().luminosityBlock(), index_);
0236 std::string destinationDir = edm::Service<evf::EvFDaqDirector>()->buBaseRunDir();
0237 int run = edm::Service<evf::EvFDaqDirector>()->getRunNumber();
0238 std::cout << " writing to destination dir " << destinationDir << " name: " << filename << std::endl;
0239 totevents_ = 0;
0240 templateConsumer_->initialize(destinationDir, filename, run, ls.id().luminosityBlock());
0241 }
0242
0243 template <class Consumer>
0244 void RawEventOutputModuleForBU<Consumer>::endLuminosityBlock(edm::LuminosityBlockForOutput const& ls) {
0245
0246 templateConsumer_->endOfLS(ls.id().luminosityBlock());
0247 }
0248
0249 template <class Consumer>
0250 void RawEventOutputModuleForBU<Consumer>::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0251 edm::ParameterSetDescription desc;
0252 desc.add<edm::InputTag>("source", edm::InputTag("rawDataCollector"));
0253 desc.add<unsigned int>("numEventsPerFile", 100);
0254 desc.add<unsigned int>("frdVersion", 6);
0255 desc.addUntracked<std::string>("rawProductName", "FEDRawDataCollection")
0256 ->setComment("FEDRawDataCollection or RawDataBuffer");
0257 desc.addUntracked<std::vector<unsigned int>>("sourceIdList", std::vector<unsigned int>());
0258 Consumer::extendDescription(desc);
0259
0260 descriptions.addWithDefaultLabel(desc);
0261 }
0262
0263 #endif