File indexing completed on 2024-04-06 12:19:39
0001 #include "L1Trigger/DemonstratorTools/interface/BoardDataReader.h"
0002
0003 #include <fstream>
0004
0005 #include "L1Trigger/DemonstratorTools/interface/Frame.h"
0006 #include "L1Trigger/DemonstratorTools/interface/utilities.h"
0007
0008 namespace l1t::demo {
0009
0010 BoardDataReader::BoardDataReader(FileFormat format,
0011 const std::vector<std::string>& fileNames,
0012 const size_t framesPerBX,
0013 const size_t tmux,
0014 const size_t emptyFramesAtStart,
0015 const ChannelMap_t& channelMap)
0016 : fileFormat_(format),
0017 fileNames_(fileNames),
0018 framesPerBX_(framesPerBX),
0019 boardTMUX_(tmux),
0020 emptyFramesAtStart_(emptyFramesAtStart),
0021 channelMap_(channelMap),
0022 events_() {
0023
0024
0025
0026 for (const auto& [id, value] : channelMap_) {
0027 const auto& [spec, indices] = value;
0028 if ((spec.tmux % boardTMUX_) != 0)
0029 throw std::runtime_error("Link [" + id.interface + ", " + std::to_string(id.channel) +
0030 "]: Specified TMUX period, " + std::to_string(spec.tmux) +
0031 ", is not a multiple of the board TMUX, " + std::to_string(boardTMUX_));
0032
0033 const size_t tmuxRatio(spec.tmux / boardTMUX_);
0034 if (indices.size() != tmuxRatio)
0035 throw std::runtime_error("Link [" + id.interface + ", " + std::to_string(id.channel) +
0036 "]: Number of channel indices specified, " + std::to_string(indices.size()) +
0037 ", does not match link:board TMUX ratio");
0038 }
0039
0040
0041 for (const auto& path : fileNames_) {
0042 BoardData boardData(read(path, fileFormat_));
0043
0044
0045 for (const auto& [id, value] : channelMap_) {
0046 const auto& [spec, indices] = value;
0047 for (const auto i : indices) {
0048 if (not boardData.has(i))
0049 throw std::runtime_error("Channel " + std::to_string(i) + " was declared but is missing from file '" +
0050 path + "'");
0051 }
0052 }
0053
0054
0055 for (const auto& [id, value] : channelMap) {
0056 const auto& [spec, indices] = value;
0057 for (size_t tmuxIndex = 0; tmuxIndex < indices.size(); tmuxIndex++) {
0058 const auto& chanData = boardData.at(indices.at(tmuxIndex));
0059
0060 const size_t framesBeforeFirstPacket(emptyFramesAtStart_ + tmuxIndex * boardTMUX_ * framesPerBX_ +
0061 spec.offset);
0062 const size_t eventLength(spec.tmux * framesPerBX_);
0063 const size_t packetLength(eventLength - spec.interpacketGap);
0064
0065 for (size_t j = 0; j < framesBeforeFirstPacket; j++) {
0066 if (chanData.at(j).valid)
0067 throw std::runtime_error("Frame " + std::to_string(j) + " on channel " +
0068 std::to_string(indices.at(tmuxIndex)) + " is valid, but first " +
0069 std::to_string(framesBeforeFirstPacket) + "frames should be invalid");
0070 }
0071
0072 for (size_t j = framesBeforeFirstPacket; j < chanData.size(); j++) {
0073 if ((j + (framesPerBX_ * spec.tmux)) >= chanData.size())
0074 continue;
0075
0076 bool expectValid(((j - framesBeforeFirstPacket) % eventLength) < packetLength);
0077 if (expectValid) {
0078 if (not chanData.at(j).valid)
0079 throw std::runtime_error("Frame " + std::to_string(j) + " on channel " +
0080 std::to_string(indices.at(tmuxIndex)) +
0081 " is invalid, but expected valid frame (path='" + path + "')");
0082 } else if (chanData.at(j).valid)
0083 throw std::runtime_error("Frame " + std::to_string(j) + " on channel " +
0084 std::to_string(indices.at(tmuxIndex)) +
0085 " is valid, but expected invalid frame (path='" + path + "')");
0086 }
0087 }
0088 }
0089
0090
0091 bool eventIncomplete(false);
0092 for (size_t eventIndex = 0;; eventIndex++) {
0093 EventData eventData;
0094
0095 for (const auto& [id, value] : channelMap) {
0096 const auto& [spec, indices] = value;
0097 const auto& chanData = boardData.at(indices.at(eventIndex % (spec.tmux / boardTMUX_)));
0098
0099
0100 const size_t framesBeforeEvent(eventIndex * boardTMUX_ * framesPerBX_ + emptyFramesAtStart_ + spec.offset);
0101 const size_t packetLength(spec.tmux * framesPerBX_ - spec.interpacketGap);
0102
0103 if (chanData.size() < (framesBeforeEvent + spec.tmux * framesPerBX_)) {
0104 eventIncomplete = true;
0105 break;
0106 }
0107
0108 std::vector<ap_uint<64>> chanEventData(packetLength);
0109 for (size_t j = 0; j < packetLength; j++)
0110 chanEventData.at(j) = chanData.at(framesBeforeEvent + j).data;
0111 eventData.add(id, chanEventData);
0112 }
0113
0114 if (eventIncomplete)
0115 break;
0116
0117 events_.push_back(eventData);
0118 }
0119 }
0120
0121 eventIt_ = events_.begin();
0122 }
0123
0124 BoardDataReader::BoardDataReader(FileFormat format,
0125 const std::vector<std::string>& fileNames,
0126 const size_t framesPerBX,
0127 const size_t tmux,
0128 const size_t emptyFramesAtStart,
0129 const std::map<LinkId, std::vector<size_t>>& channelMap,
0130 const std::map<std::string, ChannelSpec>& channelSpecs)
0131 : BoardDataReader(format, fileNames, framesPerBX, tmux, emptyFramesAtStart, mergeMaps(channelMap, channelSpecs)) {
0132 }
0133
0134 EventData BoardDataReader::getNextEvent() {
0135 if (eventIt_ == events_.end())
0136 throw std::runtime_error("Board data reader ran out of events");
0137
0138 return *(eventIt_++);
0139 }
0140
0141 BoardDataReader::ChannelMap_t BoardDataReader::mergeMaps(const std::map<LinkId, std::vector<size_t>>& indexMap,
0142 const std::map<std::string, ChannelSpec>& specMap) {
0143 ChannelMap_t channelMap;
0144 for (const auto& x : indexMap)
0145 channelMap.at(x.first) = {specMap.at(x.first.interface), x.second};
0146 return channelMap;
0147 }
0148
0149 }