File indexing completed on 2023-03-17 11:00:31
0001 #include "EventFilter/Utilities/interface/DAQSource.h"
0002 #include "EventFilter/Utilities/interface/DAQSourceModelsFRD.h"
0003
0004 #include <iostream>
0005 #include <sstream>
0006 #include <sys/types.h>
0007 #include <sys/file.h>
0008 #include <sys/time.h>
0009 #include <unistd.h>
0010 #include <vector>
0011
0012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0013
0014 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0015 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0016 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0017
0018 #include "DataFormats/TCDS/interface/TCDSRaw.h"
0019
0020 #include "FWCore/Framework/interface/Event.h"
0021 #include "EventFilter/Utilities/interface/GlobalEventNumber.h"
0022 #include "EventFilter/Utilities/interface/DAQSourceModels.h"
0023 #include "EventFilter/Utilities/interface/DAQSource.h"
0024
0025 #include "EventFilter/Utilities/interface/AuxiliaryMakers.h"
0026
0027 #include "DataFormats/Provenance/interface/EventAuxiliary.h"
0028 #include "DataFormats/Provenance/interface/EventID.h"
0029 #include "DataFormats/Provenance/interface/Timestamp.h"
0030 #include "EventFilter/Utilities/interface/crc32c.h"
0031
0032 void DataModeFRD::readEvent(edm::EventPrincipal& eventPrincipal) {
0033 std::unique_ptr<FEDRawDataCollection> rawData(new FEDRawDataCollection);
0034 bool tcdsInRange;
0035 unsigned char* tcds_pointer = nullptr;
0036 edm::Timestamp tstamp = fillFEDRawDataCollection(*rawData, tcdsInRange, tcds_pointer);
0037
0038 if (daqSource_->useL1EventID()) {
0039 uint32_t L1EventID = event_->event();
0040 edm::EventID eventID = edm::EventID(daqSource_->eventRunNumber(), daqSource_->currentLumiSection(), L1EventID);
0041 edm::EventAuxiliary aux(
0042 eventID, daqSource_->processGUID(), tstamp, event_->isRealData(), edm::EventAuxiliary::PhysicsTrigger);
0043 aux.setProcessHistoryID(daqSource_->processHistoryID());
0044 daqSource_->makeEventWrapper(eventPrincipal, aux);
0045 } else if (tcds_pointer == nullptr) {
0046 uint32_t L1EventID = event_->event();
0047 throw cms::Exception("DAQSource::read") << "No TCDS FED in event with FEDHeader EID -: " << L1EventID;
0048 } else {
0049 const FEDHeader fedHeader(tcds_pointer);
0050 tcds::Raw_v1 const* tcds = reinterpret_cast<tcds::Raw_v1 const*>(tcds_pointer + FEDHeader::length);
0051 edm::EventAuxiliary aux =
0052 evf::evtn::makeEventAuxiliary(tcds,
0053 daqSource_->eventRunNumber(),
0054 daqSource_->currentLumiSection(),
0055 event_->isRealData(),
0056 static_cast<edm::EventAuxiliary::ExperimentType>(fedHeader.triggerType()),
0057 daqSource_->processGUID(),
0058 !daqSource_->fileListLoopMode(),
0059 !tcdsInRange);
0060 aux.setProcessHistoryID(daqSource_->processHistoryID());
0061 daqSource_->makeEventWrapper(eventPrincipal, aux);
0062 }
0063
0064 std::unique_ptr<edm::WrapperBase> edp(new edm::Wrapper<FEDRawDataCollection>(std::move(rawData)));
0065 eventPrincipal.put(
0066 daqProvenanceHelpers_[0]->branchDescription(), std::move(edp), daqProvenanceHelpers_[0]->dummyProvenance());
0067 }
0068
0069 edm::Timestamp DataModeFRD::fillFEDRawDataCollection(FEDRawDataCollection& rawData,
0070 bool& tcdsInRange,
0071 unsigned char*& tcds_pointer) {
0072 edm::TimeValue_t time;
0073 timeval stv;
0074 gettimeofday(&stv, nullptr);
0075 time = stv.tv_sec;
0076 time = (time << 32) + stv.tv_usec;
0077 edm::Timestamp tstamp(time);
0078
0079 uint32_t eventSize = event_->eventSize();
0080 unsigned char* event = (unsigned char*)event_->payload();
0081 tcds_pointer = nullptr;
0082 tcdsInRange = false;
0083 uint16_t selectedTCDSFed = 0;
0084 while (eventSize > 0) {
0085 assert(eventSize >= FEDTrailer::length);
0086 eventSize -= FEDTrailer::length;
0087 const FEDTrailer fedTrailer(event + eventSize);
0088 const uint32_t fedSize = fedTrailer.fragmentLength() << 3;
0089 assert(eventSize >= fedSize - FEDHeader::length);
0090 eventSize -= (fedSize - FEDHeader::length);
0091 const FEDHeader fedHeader(event + eventSize);
0092 const uint16_t fedId = fedHeader.sourceID();
0093 if (fedId > FEDNumbering::MAXFEDID) {
0094 throw cms::Exception("DAQSource::fillFEDRawDataCollection") << "Out of range FED ID : " << fedId;
0095 } else if (fedId >= MINTCDSuTCAFEDID_ && fedId <= MAXTCDSuTCAFEDID_) {
0096 if (!selectedTCDSFed) {
0097 selectedTCDSFed = fedId;
0098 tcds_pointer = event + eventSize;
0099 if (fedId >= FEDNumbering::MINTCDSuTCAFEDID && fedId <= FEDNumbering::MAXTCDSuTCAFEDID) {
0100 tcdsInRange = true;
0101 }
0102 } else
0103 throw cms::Exception("DAQSource::fillFEDRawDataCollection")
0104 << "Second TCDS FED ID " << fedId << " found. First ID: " << selectedTCDSFed;
0105 }
0106
0107 FEDRawData& fedData = rawData.FEDData(fedId);
0108 fedData.resize(fedSize);
0109 memcpy(fedData.data(), event + eventSize, fedSize);
0110 }
0111 assert(eventSize == 0);
0112
0113 return tstamp;
0114 }
0115
0116 std::vector<std::shared_ptr<const edm::DaqProvenanceHelper>>& DataModeFRD::makeDaqProvenanceHelpers() {
0117
0118 daqProvenanceHelpers_.clear();
0119 daqProvenanceHelpers_.emplace_back(std::make_shared<const edm::DaqProvenanceHelper>(
0120 edm::TypeID(typeid(FEDRawDataCollection)), "FEDRawDataCollection", "FEDRawDataCollection", "DAQSource"));
0121 return daqProvenanceHelpers_;
0122 }
0123
0124 bool DataModeFRD::nextEventView() {
0125 if (eventCached_)
0126 return true;
0127 event_ = std::make_unique<FRDEventMsgView>(dataBlockAddr_);
0128 if (event_->size() > dataBlockMax_) {
0129 throw cms::Exception("DAQSource::getNextEvent")
0130 << " event id:" << event_->event() << " lumi:" << event_->lumi() << " run:" << event_->run()
0131 << " of size:" << event_->size() << " bytes does not fit into a chunk of size:" << dataBlockMax_ << " bytes";
0132 }
0133 return true;
0134 }
0135
0136 bool DataModeFRD::checksumValid() {
0137 crc_ = 0;
0138 if (event_->version() >= 5) {
0139 crc_ = crc32c(crc_, (const unsigned char*)event_->payload(), event_->eventSize());
0140 if (crc_ != event_->crc32c())
0141 return false;
0142 }
0143 return true;
0144 }
0145
0146 std::string DataModeFRD::getChecksumError() const {
0147 std::stringstream ss;
0148 ss << "Found a wrong crc32c checksum: expected 0x" << std::hex << event_->crc32c() << " but calculated 0x" << crc_;
0149 return ss.str();
0150 }
0151
0152
0153
0154
0155
0156 void DataModeFRDStriped::makeDirectoryEntries(std::vector<std::string> const& baseDirs, std::string const& runDir) {
0157 std::filesystem::path runDirP(runDir);
0158 for (auto& baseDir : baseDirs) {
0159 std::filesystem::path baseDirP(baseDir);
0160 buPaths_.emplace_back(baseDirP / runDirP);
0161 }
0162 }
0163
0164 void DataModeFRDStriped::readEvent(edm::EventPrincipal& eventPrincipal) {
0165 assert(!events_.empty());
0166 std::unique_ptr<FEDRawDataCollection> rawData(new FEDRawDataCollection);
0167 bool tcdsInRange;
0168 unsigned char* tcds_pointer = nullptr;
0169 edm::Timestamp tstamp = fillFRDCollection(*rawData, tcdsInRange, tcds_pointer);
0170
0171 auto const& event = events_[0];
0172 if (daqSource_->useL1EventID()) {
0173 uint32_t L1EventID = event->event();
0174 edm::EventID eventID = edm::EventID(daqSource_->eventRunNumber(), daqSource_->currentLumiSection(), L1EventID);
0175 edm::EventAuxiliary aux(
0176 eventID, daqSource_->processGUID(), tstamp, event->isRealData(), edm::EventAuxiliary::PhysicsTrigger);
0177 aux.setProcessHistoryID(daqSource_->processHistoryID());
0178 daqSource_->makeEventWrapper(eventPrincipal, aux);
0179 } else if (tcds_pointer == nullptr) {
0180 uint32_t L1EventID = event->event();
0181 throw cms::Exception("DAQSource::read") << "No TCDS FED in event with FEDHeader EID -: " << L1EventID;
0182 } else {
0183 const FEDHeader fedHeader(tcds_pointer);
0184 tcds::Raw_v1 const* tcds = reinterpret_cast<tcds::Raw_v1 const*>(tcds_pointer + FEDHeader::length);
0185 edm::EventAuxiliary aux =
0186 evf::evtn::makeEventAuxiliary(tcds,
0187 daqSource_->eventRunNumber(),
0188 daqSource_->currentLumiSection(),
0189 event->isRealData(),
0190 static_cast<edm::EventAuxiliary::ExperimentType>(fedHeader.triggerType()),
0191 daqSource_->processGUID(),
0192 !daqSource_->fileListLoopMode(),
0193 !tcdsInRange);
0194 aux.setProcessHistoryID(daqSource_->processHistoryID());
0195 daqSource_->makeEventWrapper(eventPrincipal, aux);
0196 }
0197 std::unique_ptr<edm::WrapperBase> edp(new edm::Wrapper<FEDRawDataCollection>(std::move(rawData)));
0198 eventPrincipal.put(
0199 daqProvenanceHelpers_[0]->branchDescription(), std::move(edp), daqProvenanceHelpers_[0]->dummyProvenance());
0200 eventCached_ = false;
0201 }
0202
0203 edm::Timestamp DataModeFRDStriped::fillFRDCollection(FEDRawDataCollection& rawData,
0204 bool& tcdsInRange,
0205 unsigned char*& tcds_pointer) {
0206 edm::TimeValue_t time;
0207 timeval stv;
0208 gettimeofday(&stv, nullptr);
0209 time = stv.tv_sec;
0210 time = (time << 32) + stv.tv_usec;
0211 edm::Timestamp tstamp(time);
0212
0213 tcds_pointer = nullptr;
0214 tcdsInRange = false;
0215 uint16_t selectedTCDSFed = 0;
0216 int selectedTCDSFileIndex = -1;
0217 for (size_t index = 0; index < events_.size(); index++) {
0218 uint32_t eventSize = events_[index]->eventSize();
0219 unsigned char* event = (unsigned char*)events_[index]->payload();
0220 while (eventSize > 0) {
0221 assert(eventSize >= FEDTrailer::length);
0222 eventSize -= FEDTrailer::length;
0223 const FEDTrailer fedTrailer(event + eventSize);
0224 const uint32_t fedSize = fedTrailer.fragmentLength() << 3;
0225 assert(eventSize >= fedSize - FEDHeader::length);
0226 eventSize -= (fedSize - FEDHeader::length);
0227 const FEDHeader fedHeader(event + eventSize);
0228 const uint16_t fedId = fedHeader.sourceID();
0229 if (fedId > FEDNumbering::MAXFEDID) {
0230 throw cms::Exception("DataModeFRDStriped:::fillFRDCollection") << "Out of range FED ID : " << fedId;
0231 } else if (fedId >= MINTCDSuTCAFEDID_ && fedId <= MAXTCDSuTCAFEDID_) {
0232 if (!selectedTCDSFed) {
0233 selectedTCDSFed = fedId;
0234 selectedTCDSFileIndex = index;
0235 tcds_pointer = event + eventSize;
0236 if (fedId >= FEDNumbering::MINTCDSuTCAFEDID && fedId <= FEDNumbering::MAXTCDSuTCAFEDID) {
0237 tcdsInRange = true;
0238 }
0239 } else if (!testing_)
0240 throw cms::Exception("DataModeFRDStriped:::fillFRDCollection")
0241 << "Second TCDS FED ID " << fedId << " found in file " << selectedTCDSFileIndex
0242 << ". First ID: " << selectedTCDSFed << " in file " << index;
0243 }
0244 FEDRawData& fedData = rawData.FEDData(fedId);
0245 fedData.resize(fedSize);
0246 memcpy(fedData.data(), event + eventSize, fedSize);
0247 }
0248 assert(eventSize == 0);
0249 }
0250
0251 return tstamp;
0252 }
0253
0254 std::vector<std::shared_ptr<const edm::DaqProvenanceHelper>>& DataModeFRDStriped::makeDaqProvenanceHelpers() {
0255
0256 daqProvenanceHelpers_.clear();
0257 daqProvenanceHelpers_.emplace_back(std::make_shared<const edm::DaqProvenanceHelper>(
0258 edm::TypeID(typeid(FEDRawDataCollection)), "FEDRawDataCollection", "FEDRawDataCollection", "DAQSource"));
0259 return daqProvenanceHelpers_;
0260 }
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276 bool DataModeFRDStriped::checksumValid() {
0277 bool status = true;
0278 for (size_t i = 0; i < events_.size(); i++) {
0279 uint32_t crc = 0;
0280 auto const& event = events_[i];
0281 if (event->version() >= 5) {
0282 crc = crc32c(crc, (const unsigned char*)event->payload(), event->eventSize());
0283 if (crc != event->crc32c()) {
0284 std::ostringstream ss;
0285 ss << "Found a wrong crc32c checksum at readout index " << i << ": expected 0x" << std::hex << event->crc32c()
0286 << " but calculated 0x" << crc << ". ";
0287 crcMsg_ += ss.str();
0288 status = false;
0289 }
0290 }
0291 }
0292 return status;
0293 }
0294
0295 std::string DataModeFRDStriped::getChecksumError() const { return crcMsg_; }
0296
0297
0298
0299
0300
0301 std::pair<bool, std::vector<std::string>> DataModeFRDStriped::defineAdditionalFiles(std::string const& primaryName,
0302 bool fileListMode) const {
0303 std::vector<std::string> additionalFiles;
0304
0305 if (fileListMode) {
0306
0307 additionalFiles.push_back(primaryName + "_1");
0308 return std::make_pair(true, additionalFiles);
0309 }
0310
0311 auto fullpath = std::filesystem::path(primaryName);
0312 auto fullname = fullpath.filename();
0313
0314 for (size_t i = 1; i < buPaths_.size(); i++) {
0315 std::filesystem::path newPath = buPaths_[i] / fullname;
0316 additionalFiles.push_back(newPath.generic_string());
0317 }
0318 return std::make_pair(true, additionalFiles);
0319 }
0320
0321 bool DataModeFRDStriped::nextEventView() {
0322 blockCompleted_ = false;
0323 if (eventCached_)
0324 return true;
0325 for (unsigned int i = 0; i < events_.size(); i++) {
0326
0327 dataBlockAddrs_[i] += events_[i]->size();
0328 }
0329 return makeEvents();
0330 }
0331
0332 bool DataModeFRDStriped::makeEvents() {
0333 events_.clear();
0334 assert(!blockCompleted_);
0335 for (int i = 0; i < numFiles_; i++) {
0336 if (dataBlockAddrs_[i] >= dataBlockMaxAddrs_[i]) {
0337
0338 assert(dataBlockAddrs_[i] == dataBlockMaxAddrs_[i]);
0339 blockCompleted_ = true;
0340 return false;
0341 } else {
0342 if (blockCompleted_)
0343 throw cms::Exception("DataModeFRDStriped::makeEvents")
0344 << "not all striped blocks were completed at the same time";
0345 }
0346 if (blockCompleted_)
0347 continue;
0348 events_.emplace_back(std::make_unique<FRDEventMsgView>(dataBlockAddrs_[i]));
0349 if (dataBlockAddrs_[i] + events_[i]->size() > dataBlockMaxAddrs_[i])
0350 throw cms::Exception("DAQSource::getNextEvent")
0351 << " event id:" << events_[i]->event() << " lumi:" << events_[i]->lumi() << " run:" << events_[i]->run()
0352 << " of size:" << events_[i]->size() << " bytes does not fit into the buffer or has corrupted header";
0353 }
0354 return !blockCompleted_;
0355 }