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