File indexing completed on 2024-05-31 04:19:30
0001 #include <iostream>
0002 #include <memory>
0003 #include <zlib.h>
0004
0005 #include "IOPool/Streamer/interface/FRDEventMessage.h"
0006 #include "IOPool/Streamer/interface/FRDFileHeader.h"
0007
0008 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0009 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0010 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0011 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0012
0013 #include "DataFormats/TCDS/interface/TCDSRaw.h"
0014
0015 #include "EventFilter/Utilities/interface/GlobalEventNumber.h"
0016
0017 #include "EventFilter/Utilities/plugins/FRDStreamSource.h"
0018 #include "EventFilter/Utilities/interface/crc32c.h"
0019
0020 using namespace edm::streamer;
0021
0022 FRDStreamSource::FRDStreamSource(edm::ParameterSet const& pset, edm::InputSourceDescription const& desc)
0023 : ProducerSourceFromFiles(pset, desc, true),
0024 verifyAdler32_(pset.getUntrackedParameter<bool>("verifyAdler32", true)),
0025 verifyChecksum_(pset.getUntrackedParameter<bool>("verifyChecksum", true)),
0026 useL1EventID_(pset.getUntrackedParameter<bool>("useL1EventID", false)) {
0027 fileNames_ = fileNames(0), itFileName_ = fileNames_.begin();
0028 endFileName_ = fileNames_.end();
0029 openFile(*itFileName_);
0030 produces<FEDRawDataCollection>();
0031 }
0032
0033 bool FRDStreamSource::setRunAndEventInfo(edm::EventID& id,
0034 edm::TimeValue_t& theTime,
0035 edm::EventAuxiliary::ExperimentType& eType) {
0036 if (fin_.peek() == EOF) {
0037 if (++itFileName_ == endFileName_) {
0038 fin_.close();
0039 return false;
0040 }
0041 if (!openFile(*itFileName_)) {
0042 throw cms::Exception("FRDStreamSource::setRunAndEventInfo") << "could not open file " << *itFileName_;
0043 }
0044 }
0045
0046 if (fin_.tellg() == 0) {
0047 constexpr size_t buf_sz = sizeof(FRDFileHeaderIdentifier);
0048 char hdr[sizeof(FRDFileHeader_v2)];
0049 fin_.read(hdr, buf_sz);
0050
0051 if (fin_.gcount() == 0)
0052 throw cms::Exception("FRDStreamSource::setRunAndEventInfo")
0053 << "Unable to read file or empty file" << *itFileName_;
0054 else if (fin_.gcount() < (ssize_t)buf_sz) {
0055
0056 fin_.seekg(0);
0057 } else {
0058 FRDFileHeaderIdentifier* fileId = (FRDFileHeaderIdentifier*)hdr;
0059 uint16_t frd_version = getFRDFileHeaderVersion(fileId->id_, fileId->version_);
0060
0061 if (frd_version == 1) {
0062 constexpr size_t buf_sz_cont = sizeof(FRDFileHeaderContent_v1);
0063 fin_.read(hdr, buf_sz_cont);
0064 FRDFileHeaderContent_v1* fhContent = (FRDFileHeaderContent_v1*)hdr;
0065 if (fin_.gcount() != buf_sz_cont || fhContent->headerSize_ != sizeof(FRDFileHeader_v1))
0066 throw cms::Exception("FRDStreamSource::setRunAndEventInfo")
0067 << "Invalid FRD file header (size mismatch) in file " << *itFileName_;
0068 } else if (frd_version == 2) {
0069 constexpr size_t buf_sz_cont = sizeof(FRDFileHeaderContent_v2);
0070 fin_.read(hdr, buf_sz_cont);
0071 FRDFileHeaderContent_v2* fhContent = (FRDFileHeaderContent_v2*)hdr;
0072 if (fin_.gcount() != buf_sz_cont || fhContent->headerSize_ != sizeof(FRDFileHeader_v2))
0073 throw cms::Exception("FRDStreamSource::setRunAndEventInfo")
0074 << "Invalid FRD file header (size mismatch) in file " << *itFileName_;
0075 } else if (frd_version > 2) {
0076 throw cms::Exception("FRDStreamSource::setRunAndEventInfo") << "Unknown header version " << frd_version;
0077 } else {
0078
0079 fin_.seekg(0, fin_.beg);
0080 }
0081 }
0082 }
0083
0084 if (detectedFRDversion_ == 0) {
0085 fin_.read((char*)&detectedFRDversion_, sizeof(uint16_t));
0086 fin_.read((char*)&flags_, sizeof(uint16_t));
0087 assert(detectedFRDversion_ > 0 && detectedFRDversion_ <= FRDHeaderMaxVersion);
0088 if (buffer_.size() < FRDHeaderVersionSize[detectedFRDversion_])
0089 buffer_.resize(FRDHeaderVersionSize[detectedFRDversion_]);
0090 *((uint32_t*)(&buffer_[0])) = detectedFRDversion_;
0091 fin_.read(&buffer_[0] + sizeof(uint32_t), FRDHeaderVersionSize[detectedFRDversion_] - sizeof(uint32_t));
0092 assert(fin_.gcount() == FRDHeaderVersionSize[detectedFRDversion_] - (unsigned int)(sizeof(uint32_t)));
0093 } else {
0094 if (buffer_.size() < FRDHeaderVersionSize[detectedFRDversion_])
0095 buffer_.resize(FRDHeaderVersionSize[detectedFRDversion_]);
0096 fin_.read(&buffer_[0], FRDHeaderVersionSize[detectedFRDversion_]);
0097 assert(fin_.gcount() == FRDHeaderVersionSize[detectedFRDversion_]);
0098 }
0099
0100 std::unique_ptr<FRDEventMsgView> frdEventMsg(new FRDEventMsgView(&buffer_[0]));
0101 if (useL1EventID_)
0102 id = edm::EventID(frdEventMsg->run(), frdEventMsg->lumi(), frdEventMsg->event());
0103
0104 const uint32_t totalSize = frdEventMsg->size();
0105 if (totalSize > buffer_.size()) {
0106 buffer_.resize(totalSize);
0107 }
0108 if (totalSize > FRDHeaderVersionSize[detectedFRDversion_]) {
0109 fin_.read(&buffer_[0] + FRDHeaderVersionSize[detectedFRDversion_],
0110 totalSize - FRDHeaderVersionSize[detectedFRDversion_]);
0111 if (fin_.gcount() != totalSize - FRDHeaderVersionSize[detectedFRDversion_]) {
0112 throw cms::Exception("FRDStreamSource::setRunAndEventInfo") << "premature end of file " << *itFileName_;
0113 }
0114 frdEventMsg = std::make_unique<FRDEventMsgView>(&buffer_[0]);
0115 }
0116
0117 if (verifyChecksum_ && frdEventMsg->version() >= 5) {
0118 uint32_t crc = 0;
0119 crc = crc32c(crc, (const unsigned char*)frdEventMsg->payload(), frdEventMsg->eventSize());
0120 if (crc != frdEventMsg->crc32c()) {
0121 throw cms::Exception("FRDStreamSource::getNextEvent") << "Found a wrong crc32c checksum: expected 0x" << std::hex
0122 << frdEventMsg->crc32c() << " but calculated 0x" << crc;
0123 }
0124 } else if (verifyAdler32_ && frdEventMsg->version() >= 3) {
0125 uint32_t adler = adler32(0L, Z_NULL, 0);
0126 adler = adler32(adler, (Bytef*)frdEventMsg->payload(), frdEventMsg->eventSize());
0127
0128 if (adler != frdEventMsg->adler32()) {
0129 throw cms::Exception("FRDStreamSource::setRunAndEventInfo")
0130 << "Found a wrong Adler32 checksum: expected 0x" << std::hex << frdEventMsg->adler32() << " but calculated 0x"
0131 << adler;
0132 }
0133 }
0134
0135 rawData_ = std::make_unique<FEDRawDataCollection>();
0136
0137 uint32_t eventSize = frdEventMsg->eventSize();
0138 unsigned char* event = (unsigned char*)frdEventMsg->payload();
0139 bool foundTCDSFED = false;
0140 bool foundGTPFED = false;
0141
0142 while (eventSize > 0) {
0143 assert(eventSize >= FEDTrailer::length);
0144 eventSize -= FEDTrailer::length;
0145 const FEDTrailer fedTrailer(event + eventSize);
0146 const uint32_t fedSize = fedTrailer.fragmentLength() << 3;
0147 assert(eventSize >= fedSize - FEDHeader::length);
0148 eventSize -= (fedSize - FEDHeader::length);
0149 const FEDHeader fedHeader(event + eventSize);
0150 const uint16_t fedId = fedHeader.sourceID();
0151 if (fedId > FEDNumbering::MAXFEDID) {
0152 throw cms::Exception("FedRawDataInputSource::fillFEDRawDataCollection") << "Out of range FED ID : " << fedId;
0153 }
0154 if (fedId == FEDNumbering::MINTCDSuTCAFEDID) {
0155 foundTCDSFED = true;
0156 tcds::Raw_v1 const* tcds = reinterpret_cast<tcds::Raw_v1 const*>(event + eventSize + FEDHeader::length);
0157 id = edm::EventID(frdEventMsg->run(), tcds->header.lumiSection, tcds->header.eventNumber);
0158 eType = static_cast<edm::EventAuxiliary::ExperimentType>(fedHeader.triggerType());
0159 theTime = static_cast<edm::TimeValue_t>(((uint64_t)tcds->bst.gpstimehigh << 32) | tcds->bst.gpstimelow);
0160 }
0161
0162 if (fedId == FEDNumbering::MINTriggerGTPFEDID && !foundTCDSFED) {
0163 foundGTPFED = true;
0164 const bool GTPEvmBoardSense = evf::evtn::evm_board_sense(event + eventSize, fedSize);
0165 if (!useL1EventID_) {
0166 if (GTPEvmBoardSense)
0167 id = edm::EventID(frdEventMsg->run(), frdEventMsg->lumi(), evf::evtn::get(event + eventSize, true));
0168 else
0169 id = edm::EventID(frdEventMsg->run(), frdEventMsg->lumi(), evf::evtn::get(event + eventSize, false));
0170 }
0171
0172 const uint64_t gpsl = evf::evtn::getgpslow(event + eventSize);
0173 const uint64_t gpsh = evf::evtn::getgpshigh(event + eventSize);
0174 theTime = static_cast<edm::TimeValue_t>((gpsh << 32) + gpsl);
0175 }
0176
0177
0178 if (fedId == FEDNumbering::MINTriggerEGTPFEDID && !foundGTPFED && !foundTCDSFED && !useL1EventID_) {
0179 if (evf::evtn::gtpe_board_sense(event + eventSize)) {
0180 id = edm::EventID(frdEventMsg->run(), frdEventMsg->lumi(), evf::evtn::gtpe_get(event + eventSize));
0181 }
0182 }
0183 FEDRawData& fedData = rawData_->FEDData(fedId);
0184 fedData.resize(fedSize);
0185 memcpy(fedData.data(), event + eventSize, fedSize);
0186 }
0187 assert(eventSize == 0);
0188
0189 return true;
0190 }
0191
0192 void FRDStreamSource::produce(edm::Event& e) { e.put(std::move(rawData_)); }
0193
0194 bool FRDStreamSource::openFile(const std::string& fileName) {
0195 std::cout << " open file.. " << fileName << std::endl;
0196 fin_.close();
0197 fin_.clear();
0198 size_t pos = fileName.find(':');
0199 if (pos != std::string::npos) {
0200 std::string prefix = fileName.substr(0, pos);
0201 if (prefix != "file")
0202 return false;
0203 pos++;
0204 } else
0205 pos = 0;
0206
0207 fin_.open(fileName.substr(pos).c_str(), std::ios::in | std::ios::binary);
0208 return fin_.is_open();
0209 }
0210
0211
0212
0213
0214 DEFINE_FWK_INPUT_SOURCE(FRDStreamSource);
0215
0216
0217 using ErrorStreamSource = FRDStreamSource;
0218 DEFINE_FWK_INPUT_SOURCE(ErrorStreamSource);