CMS 3D CMS Logo

BoardDataReader.cc
Go to the documentation of this file.
2 
3 #include <fstream>
4 
7 
8 namespace l1t::demo {
9 
11  const std::vector<std::string>& fileNames,
12  const size_t framesPerBX,
13  const size_t tmux,
14  const size_t emptyFramesAtStart,
15  const ChannelMap_t& channelMap)
16  : fileFormat_(format),
17  fileNames_(fileNames),
18  framesPerBX_(framesPerBX),
19  boardTMUX_(tmux),
20  emptyFramesAtStart_(emptyFramesAtStart),
21  channelMap_(channelMap),
22  events_() {
23  // TODO (long term): Move much of this to separate function, and only read files on demand
24 
25  // Verify that channel map/spec is self-consistent
26  for (const auto& [id, value] : channelMap_) {
27  const auto& [spec, indices] = value;
28  if ((spec.tmux % boardTMUX_) != 0)
29  throw std::runtime_error("Link [" + id.interface + ", " + std::to_string(id.channel) +
30  "]: Specified TMUX period, " + std::to_string(spec.tmux) +
31  ", is not a multiple of the board TMUX, " + std::to_string(boardTMUX_));
32 
33  const size_t tmuxRatio(spec.tmux / boardTMUX_);
34  if (indices.size() != tmuxRatio)
35  throw std::runtime_error("Link [" + id.interface + ", " + std::to_string(id.channel) +
36  "]: Number of channel indices specified, " + std::to_string(indices.size()) +
37  ", does not match link:board TMUX ratio");
38  }
39 
40  // Loop over input files
41  for (const auto& path : fileNames_) {
42  BoardData boardData(read(path, fileFormat_));
43 
44  // 1) Verify that all expected channels are present
45  for (const auto& [id, value] : channelMap_) {
46  const auto& [spec, indices] = value;
47  for (const auto i : indices) {
48  if (not boardData.has(i))
49  throw std::runtime_error("Channel " + std::to_string(i) + " was declared but is missing from file '" +
50  path + "'");
51  }
52  }
53 
54  // 2) Verify that packet structure is as expected
55  for (const auto& [id, value] : channelMap) {
56  const auto& [spec, indices] = value;
57  for (size_t tmuxIndex = 0; tmuxIndex < indices.size(); tmuxIndex++) {
58  const auto& chanData = boardData.at(indices.at(tmuxIndex));
59 
60  const size_t framesBeforeFirstPacket(emptyFramesAtStart_ + tmuxIndex * boardTMUX_ * framesPerBX_ +
61  spec.offset);
62  const size_t eventLength(spec.tmux * framesPerBX_);
63  const size_t packetLength(eventLength - spec.interpacketGap);
64 
65  for (size_t j = 0; j < framesBeforeFirstPacket; j++) {
66  if (chanData.at(j).valid)
67  throw std::runtime_error("Frame " + std::to_string(j) + " on channel " +
68  std::to_string(indices.at(tmuxIndex)) + " is valid, but first " +
69  std::to_string(framesBeforeFirstPacket) + "frames should be invalid");
70  }
71 
72  for (size_t j = framesBeforeFirstPacket; j < chanData.size(); j++) {
73  if ((j + (framesPerBX_ * spec.tmux)) >= chanData.size())
74  continue;
75 
76  bool expectValid(((j - framesBeforeFirstPacket) % eventLength) < packetLength);
77 
78  if (expectValid) {
79  if (not chanData.at(j).valid)
80  throw std::runtime_error("Frame " + std::to_string(j) + " on channel " +
81  std::to_string(indices.at(tmuxIndex)) +
82  " is invalid, but expected valid frame");
83  } else if (chanData.at(j).valid)
84  throw std::runtime_error("Frame " + std::to_string(j) + " on channel " +
85  std::to_string(indices.at(tmuxIndex)) + " is valid, but expected invalid frame");
86  }
87  }
88  }
89 
90  // 3) Extract the data for each event
91  bool eventIncomplete(false);
92  for (size_t eventIndex = 0;; eventIndex++) {
93  EventData eventData;
94 
95  for (const auto& [id, value] : channelMap) {
96  const auto& [spec, indices] = value;
97  const auto& chanData = boardData.at(indices.at(eventIndex % (spec.tmux / boardTMUX_)));
98 
99  // Extract the frames for this event
100  const size_t framesBeforeEvent(eventIndex * boardTMUX_ * framesPerBX_ + emptyFramesAtStart_ + spec.offset);
101  const size_t packetLength(spec.tmux * framesPerBX_ - spec.interpacketGap);
102 
103  if (chanData.size() < (framesBeforeEvent + spec.tmux * framesPerBX_)) {
104  eventIncomplete = true;
105  break;
106  }
107 
108  std::vector<ap_uint<64>> chanEventData(packetLength);
109  for (size_t j = 0; j < packetLength; j++)
110  chanEventData.at(j) = chanData.at(framesBeforeEvent + j).data;
111  eventData.add(id, chanEventData);
112  }
113 
114  if (eventIncomplete)
115  break;
116 
117  events_.push_back(eventData);
118  }
119  }
120 
121  eventIt_ = events_.begin();
122  }
123 
125  const std::vector<std::string>& fileNames,
126  const size_t framesPerBX,
127  const size_t tmux,
128  const size_t emptyFramesAtStart,
129  const std::map<LinkId, std::vector<size_t>>& channelMap,
130  const std::map<std::string, ChannelSpec>& channelSpecs)
131  : BoardDataReader(format, fileNames, framesPerBX, tmux, emptyFramesAtStart, mergeMaps(channelMap, channelSpecs)) {
132  }
133 
135  if (eventIt_ == events_.end())
136  throw std::runtime_error("Board data reader ran out of events");
137 
138  return *(eventIt_++);
139  }
140 
142  const std::map<std::string, ChannelSpec>& specMap) {
143  ChannelMap_t channelMap;
144  for (const auto& x : indexMap)
145  channelMap.at(x.first) = {specMap.at(x.first.interface), x.second};
146  return channelMap;
147  }
148 
149 } // namespace l1t::demo
BoardDataReader(FileFormat, const std::vector< std::string > &, const size_t framesPerBX, const size_t tmux, const size_t emptyFramesAtStart, const ChannelMap_t &)
Logical ID for link within any given time slice (e.g. ["tracks", 0] -> ["tracks", 17] for links from ...
Definition: LinkId.h:10
void add(const LinkId &, const std::vector< ap_uint< 64 >> &)
Definition: EventData.cc:14
bool has(size_t) const
Definition: BoardData.cc:41
static std::string to_string(const XMLCh *ch)
static ChannelMap_t mergeMaps(const std::map< LinkId, std::vector< size_t >> &, const std::map< std::string, ChannelSpec > &)
Definition: value.py:1
std::vector< std::string > fileNames_
std::map< LinkId, std::pair< ChannelSpec, std::vector< size_t > > > ChannelMap_t
BoardData read(const std::string &filePath, const FileFormat)
Definition: utilities.cc:98
float x
std::vector< EventData >::const_iterator eventIt_
Class representing information that&#39;s stored in the input or output buffers on a phase-2 board...
Definition: BoardData.h:13
std::vector< EventData > events_
Class representing information phase-2 ATCA I/O data corresponding to a single event, with logical channel IDs (essentially string-uint pairs, e.g. tracks-0 to tracks-17).
Definition: EventData.h:28
Channel & at(size_t)
Definition: BoardData.cc:37