File indexing completed on 2022-10-25 03:22:21
0001 #include "L1Trigger/DemonstratorTools/interface/BoardDataWriter.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 BoardDataWriter::BoardDataWriter(FileFormat format,
0011 const std::string& path,
0012 const size_t framesPerBX,
0013 const size_t tmux,
0014 const size_t maxFramesPerFile,
0015 const ChannelMap_t& channelSpecs)
0016 : fileFormat_(format),
0017 filePathGen_([=](const size_t i) { return path + "_" + std::to_string(i) + ".txt"; }),
0018 framesPerBX_(framesPerBX),
0019 boardTMUX_(tmux),
0020 maxFramesPerFile_(maxFramesPerFile),
0021 maxEventsPerFile_(maxFramesPerFile_),
0022 eventIndex_(0),
0023 pendingEvents_(0),
0024 channelMap_(channelSpecs) {
0025 if (channelMap_.empty())
0026 throw std::runtime_error("BoardDataWriter channel map cannnot be empty");
0027
0028 for (const auto& [id, value] : channelMap_) {
0029 const auto& [spec, indices] = value;
0030 for (const auto i : indices)
0031 boardData_.add(i);
0032
0033 if ((spec.tmux % boardTMUX_) != 0)
0034 throw std::runtime_error("BoardDataWriter, link [" + id.interface + ", " + std::to_string(id.channel) +
0035 "]: Specified TMUX period, " + std::to_string(spec.tmux) +
0036 ", is not a multiple of the board TMUX, " + std::to_string(boardTMUX_));
0037
0038 const size_t tmuxRatio(spec.tmux / boardTMUX_);
0039 if (indices.size() != tmuxRatio)
0040 throw std::runtime_error("BoardDataWriter, link [" + id.interface + ", " + std::to_string(id.channel) +
0041 "]: Number of channel indices specified, " + std::to_string(indices.size()) +
0042 ", does not match link:board TMUX ratio, " + std::to_string(tmuxRatio));
0043
0044 maxEventsPerFile_ = std::min(maxEventsPerFile_,
0045 ((maxFramesPerFile_ - spec.offset) / (framesPerBX_ * boardTMUX_)) - (tmuxRatio - 1));
0046 }
0047
0048 resetBoardData();
0049 }
0050
0051 BoardDataWriter::BoardDataWriter(FileFormat format,
0052 const std::string& path,
0053 const size_t framesPerBX,
0054 const size_t tmux,
0055 const size_t maxFramesPerFile,
0056 const std::map<LinkId, std::vector<size_t>>& channelMap,
0057 const std::map<std::string, ChannelSpec>& channelSpecs)
0058 : BoardDataWriter(format, path, framesPerBX, tmux, maxFramesPerFile, mergeMaps(channelMap, channelSpecs)) {}
0059
0060 void BoardDataWriter::addEvent(const EventData& eventData) {
0061
0062 for (const auto& [id, info] : channelMap_) {
0063 if (not eventData.has(id))
0064 throw std::runtime_error("Event data for link [" + id.interface + ", " + std::to_string(id.channel) +
0065 "] is missing.");
0066 }
0067
0068 for (const auto& [id, channelData] : eventData) {
0069
0070 if (channelMap_.count(id) == 0)
0071 throw std::runtime_error("Event data for link [" + id.interface + ", " + std::to_string(id.channel) +
0072 "] was given to BoardDataWriter, but its structure was not defined");
0073
0074 const auto& [spec, indices] = channelMap_.at(id);
0075 const size_t chanIndex(indices.at(pendingEvents_ % (spec.tmux / boardTMUX_)));
0076
0077
0078 if (channelData.size() > (spec.tmux * framesPerBX_ - spec.interpacketGap))
0079 throw std::runtime_error("Event data for link [" + id.interface + ", " + std::to_string(id.channel) +
0080 "] (TMUX " + std::to_string(spec.tmux) + ", " + std::to_string(spec.interpacketGap) +
0081 " cycles between packets) is too long (" + std::to_string(channelData.size()) +
0082 " 64-bit words)");
0083
0084 if (channelData.empty())
0085 throw std::runtime_error("Event data for link [" + id.interface + ", " + std::to_string(id.channel) +
0086 "] is empty");
0087
0088
0089 boardData_.at(chanIndex).insert(boardData_.at(chanIndex).end(), channelData.begin(), channelData.end());
0090
0091
0092 BoardData::Channel::iterator it(boardData_.at(chanIndex).end() - 1);
0093 it->end = true;
0094 it -= (channelData.size() - 1);
0095 it->start = true;
0096
0097
0098 boardData_.at(chanIndex).insert(
0099 boardData_.at(chanIndex).end(), spec.tmux * framesPerBX_ - channelData.size(), Frame());
0100 }
0101
0102 eventIndex_++;
0103 pendingEvents_++;
0104
0105 if (pendingEvents_ == maxEventsPerFile_)
0106 flush();
0107 }
0108
0109 void BoardDataWriter::flush() {
0110 if (pendingEvents_ == 0)
0111 return;
0112
0113
0114 for (auto& x : boardData_)
0115 x.second.resize(maxFramesPerFile_);
0116
0117
0118 const std::string filePath = filePathGen_(fileNames_.size());
0119 write(boardData_, filePath, fileFormat_);
0120 fileNames_.push_back(filePath);
0121
0122
0123 resetBoardData();
0124 }
0125
0126 BoardDataWriter::ChannelMap_t BoardDataWriter::mergeMaps(const std::map<LinkId, std::vector<size_t>>& indexMap,
0127 const std::map<std::string, ChannelSpec>& specMap) {
0128 ChannelMap_t channelMap;
0129 for (const auto& x : indexMap)
0130 channelMap[x.first] = {specMap.at(x.first.interface), x.second};
0131 return channelMap;
0132 }
0133
0134 void BoardDataWriter::resetBoardData() {
0135 for (auto& x : boardData_)
0136 x.second.clear();
0137
0138 for (const auto& [id, value] : channelMap_) {
0139 const auto& [spec, indices] = value;
0140 for (size_t tmuxIndex = 0; tmuxIndex < indices.size(); tmuxIndex++)
0141 boardData_.at(indices.at(tmuxIndex)).resize(tmuxIndex * boardTMUX_ * framesPerBX_ + spec.offset);
0142 }
0143
0144 pendingEvents_ = 0;
0145 }
0146
0147 }