File indexing completed on 2024-05-31 04:19:30
0001 #include "EventFilter/Utilities/plugins/FRDOutputModule.h"
0002
0003
0004 #include <unistd.h>
0005 #include <sys/types.h>
0006 #include <sys/stat.h>
0007 #include <fcntl.h>
0008
0009
0010 #include <cstdio>
0011 #include <fstream>
0012 #include <memory>
0013 #include <vector>
0014
0015 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0016 #include "FWCore/Utilities/interface/EDGetToken.h"
0017 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0018 #include "FWCore/Utilities/interface/Adler32Calculator.h"
0019 #include "DataFormats/Common/interface/Handle.h"
0020 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0021 #include "IOPool/Streamer/interface/FRDEventMessage.h"
0022 #include "IOPool/Streamer/interface/FRDFileHeader.h"
0023 #include "EventFilter/Utilities/interface/crc32c.h"
0024
0025 using namespace edm::streamer;
0026
0027 FRDOutputModule::FRDOutputModule(edm::ParameterSet const& ps)
0028 : edm::one::OutputModuleBase::OutputModuleBase(ps),
0029 edm::one::OutputModule<edm::one::WatchLuminosityBlocks>(ps),
0030 token_(consumes<FEDRawDataCollection>(ps.getParameter<edm::InputTag>("source"))),
0031 frdVersion_(ps.getUntrackedParameter<unsigned int>("frdVersion")),
0032 frdFileVersion_(ps.getUntrackedParameter<unsigned int>("frdFileVersion")),
0033 filePrefix_(ps.getUntrackedParameter<std::string>("filePrefix")),
0034 fileName_(ps.getUntrackedParameter<std::string>("fileName")) {}
0035
0036 FRDOutputModule::~FRDOutputModule() {}
0037
0038 void FRDOutputModule::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0039 edm::ParameterSetDescription desc;
0040 desc.add<edm::InputTag>("source", edm::InputTag("rawDataCollector"));
0041 desc.addUntracked<unsigned int>("frdFileVersion", 1), desc.addUntracked<unsigned int>("frdVersion", 6);
0042 desc.addUntracked<std::string>("filePrefix", "");
0043 desc.addUntracked<std::string>("fileName", "");
0044 descriptions.addWithDefaultLabel(desc);
0045 }
0046
0047 void FRDOutputModule::write(edm::EventForOutput const& e) {
0048
0049
0050 edm::Handle<FEDRawDataCollection> fedBuffers;
0051 e.getByToken(token_, fedBuffers);
0052
0053
0054 assert(frdVersion_ <= FRDHeaderMaxVersion);
0055 int headerSize = FRDHeaderVersionSize[frdVersion_];
0056 int expectedSize = headerSize;
0057 int nFeds = frdVersion_ < 3 ? 1024 : FEDNumbering::lastFEDId() + 1;
0058
0059 for (int idx = 0; idx < nFeds; ++idx) {
0060 FEDRawData singleFED = fedBuffers->FEDData(idx);
0061 expectedSize += singleFED.size();
0062 }
0063
0064
0065 std::unique_ptr<std::vector<unsigned char>> workBuffer(
0066 std::make_unique<std::vector<unsigned char>>(expectedSize + 256));
0067 uint32* bufPtr = (uint32*)(workBuffer.get()->data());
0068 if (frdVersion_ <= 5) {
0069 *bufPtr++ = (uint32)frdVersion_;
0070 } else {
0071 uint16 flags = 0;
0072 if (!e.eventAuxiliary().isRealData())
0073 flags |= FRDEVENT_MASK_ISGENDATA;
0074 *(uint16*)bufPtr = (uint16)(frdVersion_ & 0xffff);
0075 *((uint16*)bufPtr + 1) = flags;
0076 bufPtr++;
0077 }
0078 *bufPtr++ = (uint32)e.id().run();
0079 *bufPtr++ = (uint32)e.luminosityBlock();
0080 *bufPtr++ = (uint32)e.id().event();
0081 if (frdVersion_ == 4)
0082 *bufPtr++ = 0;
0083
0084 if (frdVersion_ < 3) {
0085 uint32 fedsize[1024];
0086 for (int idx = 0; idx < 1024; ++idx) {
0087 FEDRawData singleFED = fedBuffers->FEDData(idx);
0088 fedsize[idx] = singleFED.size();
0089
0090 }
0091 memcpy(bufPtr, fedsize, 1024 * sizeof(uint32));
0092 bufPtr += 1024;
0093 } else {
0094 *bufPtr++ = expectedSize - headerSize;
0095 *bufPtr++ = 0;
0096 if (frdVersion_ <= 4)
0097 *bufPtr++ = 0;
0098 }
0099 uint32* payloadPtr = bufPtr;
0100 for (int idx = 0; idx < nFeds; ++idx) {
0101 FEDRawData singleFED = fedBuffers->FEDData(idx);
0102 if (singleFED.size() > 0) {
0103 memcpy(bufPtr, singleFED.data(), singleFED.size());
0104 bufPtr += singleFED.size() / 4;
0105 }
0106 }
0107 if (frdVersion_ > 4) {
0108
0109 uint32_t crc = 0;
0110 *(payloadPtr - 1) = crc32c(crc, (const unsigned char*)payloadPtr, expectedSize - headerSize);
0111 } else if (frdVersion_ >= 3) {
0112
0113 uint32 adlera = 1;
0114 uint32 adlerb = 0;
0115 cms::Adler32((const char*)payloadPtr, expectedSize - headerSize, adlera, adlerb);
0116 *(payloadPtr - 1) = (adlerb << 16) | adlera;
0117 }
0118
0119
0120 FRDEventMsgView msg(workBuffer.get()->data());
0121
0122
0123 ssize_t retval = ::write(outfd_, (void*)msg.startAddress(), msg.size());
0124
0125 if ((unsigned)retval != msg.size()) {
0126 throw cms::Exception("FRDOutputModule", "write")
0127 << "Error writing FED Raw Data event data to " << fileName_ << ". Possibly the output disk "
0128 << "is full?" << std::endl;
0129 }
0130
0131 perFileEventCount_++;
0132 perFileSize_ += msg.size();
0133 }
0134
0135 void FRDOutputModule::beginLuminosityBlock(edm::LuminosityBlockForOutput const& lumiBlock) {
0136 int ls = lumiBlock.id().luminosityBlock();
0137
0138 if (outfd_ != -1)
0139 finishFileWrite(lumiBlock.run(), ls);
0140
0141 if (fileWritten_)
0142 throw cms::Exception("RawEventFileWriterForBU", "beginLuminosityBlock")
0143 << "Multiple lumisections not supported in the same FRD file!";
0144
0145 std::string fileName;
0146 if (fileName_.empty()) {
0147 std::stringstream ss;
0148 ss << (filePrefix_.empty() ? "" : filePrefix_ + "_") << "run" << std::setfill('0') << std::setw(6)
0149 << lumiBlock.run() << "_ls" << std::setfill('0') << std::setw(4) << ls << "_index000000.raw";
0150 fileName = ss.str();
0151 } else {
0152
0153 fileName = fileName_;
0154 }
0155
0156 outfd_ = open(fileName.c_str(), O_WRONLY | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
0157 ftruncate(outfd_, 0);
0158
0159 if (outfd_ < 0) {
0160 throw cms::Exception("RawEventFileWriterForBU", "beginLuminosityBlock")
0161 << "Error opening FED Raw Data event output file: " << fileName << ": " << strerror(errno) << "\n";
0162 }
0163 edm::LogInfo("RawEventFileWriterForBU") << " Opened " << fileName;
0164
0165 perFileEventCount_ = 0;
0166 perFileSize_ = 0;
0167
0168 adlera_ = 1;
0169 adlerb_ = 0;
0170
0171 if (frdFileVersion_ == 1) {
0172
0173 ftruncate(outfd_, sizeof(FRDFileHeader_v1));
0174 lseek(outfd_, sizeof(FRDFileHeader_v1), SEEK_SET);
0175 perFileSize_ = sizeof(FRDFileHeader_v1);
0176 } else if (frdFileVersion_ == 2) {
0177 ftruncate(outfd_, sizeof(FRDFileHeader_v2));
0178 lseek(outfd_, sizeof(FRDFileHeader_v2), SEEK_SET);
0179 perFileSize_ = sizeof(FRDFileHeader_v2);
0180 } else
0181 throw cms::Exception("RawEventFileWriterForBU", "beginLuminosityBlock")
0182 << "Unsupported FRD version " << frdFileVersion_;
0183 }
0184
0185 void FRDOutputModule::endLuminosityBlock(edm::LuminosityBlockForOutput const& lumiBlock) {
0186 finishFileWrite(lumiBlock.run(), lumiBlock.id().luminosityBlock());
0187 }
0188
0189 void FRDOutputModule::finishFileWrite(unsigned int run, int ls) {
0190 if (outfd_ == -1)
0191 return;
0192
0193 if (frdFileVersion_ == 1) {
0194
0195 lseek(outfd_, 0, SEEK_SET);
0196 FRDFileHeader_v1 frdFileHeader(perFileEventCount_, (uint32_t)ls, perFileSize_);
0197 ::write(outfd_, (char*)&frdFileHeader, sizeof(FRDFileHeader_v1));
0198 } else if (frdFileVersion_ == 2) {
0199 lseek(outfd_, 0, SEEK_SET);
0200 FRDFileHeader_v2 frdFileHeader(0, perFileEventCount_, (uint32_t)run, (uint32_t)ls, perFileSize_);
0201 ::write(outfd_, (char*)&frdFileHeader, sizeof(FRDFileHeader_v2));
0202 }
0203 close(outfd_);
0204 outfd_ = -1;
0205 if (!fileName_.empty())
0206 fileWritten_ = true;
0207
0208 edm::LogInfo("FRDOutputModule") << "closed RAW input file";
0209 }