Project
Loading...
Searching...
No Matches
UserLogicEndpointDecoder.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#ifndef O2_MCH_RAW_USERLOGIC_ENDPOINT_DECODER_H
13#define O2_MCH_RAW_USERLOGIC_ENDPOINT_DECODER_H
14
15#include <array>
18#include <gsl/span>
19#include <fmt/printf.h>
20#include <fmt/format.h>
21#include "MakeArray.h"
22#include "Assertions.h"
23#include <iostream>
24#include <boost/multiprecision/cpp_int.hpp>
26#include "PayloadDecoder.h"
27#include "Debug.h"
29
30namespace o2::mch::raw
31{
32
36
37template <typename CHARGESUM, int VERSION>
38class UserLogicEndpointDecoder : public PayloadDecoder<UserLogicEndpointDecoder<CHARGESUM, VERSION>>
39{
40 public:
42
47 std::function<std::optional<uint16_t>(FeeLinkId id)> fee2SolarMapper,
48 DecodedDataHandlers decodedDataHandlers);
49
53
59 size_t append(Payload bytes);
61
66
68 void reset();
70
71 private:
72 uint16_t mFeeId;
73 std::function<std::optional<uint16_t>(FeeLinkId id)> mFee2SolarMapper;
74 DecodedDataHandlers mDecodedDataHandlers;
75 std::map<uint16_t, std::array<ElinkDecoder, 40>> mElinkDecoders;
76 int mNofGbtWordsSeens;
77};
78
79using namespace o2::mch::raw;
80using namespace boost::multiprecision;
81
82template <typename CHARGESUM, int VERSION>
84 std::function<std::optional<uint16_t>(FeeLinkId id)> fee2SolarMapper,
85 DecodedDataHandlers decodedDataHandlers)
86 : PayloadDecoder<UserLogicEndpointDecoder<CHARGESUM, VERSION>>(decodedDataHandlers),
87 mFeeId{feeId},
88 mFee2SolarMapper{fee2SolarMapper},
89 mDecodedDataHandlers(decodedDataHandlers),
90 mNofGbtWordsSeens{0}
91{
92}
93
94template <typename CHARGESUM, int VERSION>
96{
97 if (buffer.size() % 8) {
98 throw std::invalid_argument("buffer size should be a multiple of 8");
99 }
100 size_t n{0};
101
102 for (size_t i = 0; i < buffer.size(); i += 8) {
103 uint64_t word = (static_cast<uint64_t>(buffer[i + 0])) |
104 (static_cast<uint64_t>(buffer[i + 1]) << 8) |
105 (static_cast<uint64_t>(buffer[i + 2]) << 16) |
106 (static_cast<uint64_t>(buffer[i + 3]) << 24) |
107 (static_cast<uint64_t>(buffer[i + 4]) << 32) |
108 (static_cast<uint64_t>(buffer[i + 5]) << 40) |
109 (static_cast<uint64_t>(buffer[i + 6]) << 48) |
110 (static_cast<uint64_t>(buffer[i + 7]) << 56);
111
112 if (word == 0xFEEDDEEDFEEDDEED) {
113 continue;
114 }
115
116 ULHeaderWord<VERSION> ulword{word};
117
118 int gbt = ulword.linkID;
119
120 // The User Logic uses the condition gbt=15 to identify special control and diagnostics words
121 // that are generated internally and do not contain data coming from the front-end electronics.
122 if (gbt == 15) {
123 // TODO: the exact format of the UL control words is still being defined and tested,
124 // hence proper decoding will be implemented once the format is finalized.
125 // For the moment we simply avoid throwing an exception when linkID is equal to 15
126 continue;
127 } else {
128 if (gbt < 0 || gbt > 11) {
129 SampaErrorHandler handler = mDecodedDataHandlers.sampaErrorHandler;
130 if (handler) {
131 DsElecId dsId{static_cast<uint16_t>(0), static_cast<uint8_t>(0), static_cast<uint8_t>(0)};
132 handler(dsId, -1, ErrorBadLinkID);
133 continue;
134 } else {
135 throw fmt::format("warning : out-of-range gbt {} word={:08X}\n", gbt, word);
136 }
137 }
138 }
139
140 // Get the corresponding decoders array, or allocate it if does not exist yet
141 auto d = mElinkDecoders.find(gbt);
142 if (d == mElinkDecoders.end()) {
143
144 // Compute the (feeId, linkId) pair...
145 FeeLinkId feeLinkId(mFeeId, gbt);
146 // ... and get the solar from it
147 auto solarId = mFee2SolarMapper(feeLinkId);
148
149 if (!solarId.has_value()) {
150 SampaErrorHandler handler = mDecodedDataHandlers.sampaErrorHandler;
151 if (handler) {
152 DsElecId dsId{static_cast<uint16_t>(0), static_cast<uint8_t>(0), static_cast<uint8_t>(0)};
153 handler(dsId, -1, ErrorUnknownLinkID);
154 continue;
155 } else {
156 throw std::logic_error(fmt::format("{} Could not get solarId from feeLinkId={}\n", __PRETTY_FUNCTION__, asString(feeLinkId)));
157 }
158 }
159
160 mElinkDecoders.emplace(static_cast<uint16_t>(gbt),
161 impl::makeArray<40>([solarId, *this](size_t i) {
162 DsElecId dselec{solarId.value(), static_cast<uint8_t>(i / 5), static_cast<uint8_t>(i % 5)};
163 return ElinkDecoder(dselec, mDecodedDataHandlers);
164 }));
165 d = mElinkDecoders.find(gbt);
166 }
167
168 uint16_t dsid = ulword.dsID;
169 if (dsid > 39) {
170 SampaErrorHandler handler = mDecodedDataHandlers.sampaErrorHandler;
171 if (handler) {
172 DsElecId dsId{static_cast<uint16_t>(0), static_cast<uint8_t>(0), static_cast<uint8_t>(0)};
173 handler(dsId, -1, ErrorBadELinkID);
174 continue;
175 } else {
176 throw fmt::format("warning : out-of-range DS ID {} word={:08X}\n", dsid, word);
177 }
178 }
179
180 int8_t error = ulword.error;
181 bool incomplete = ulword.incomplete > 0;
182 uint64_t data50 = ulword.data;
183
184 d->second.at(dsid).append(data50, error, incomplete);
185 n += 8;
186 }
187 return n;
188}
189
190template <typename CHARGESUM, int VERSION>
192{
193 for (auto& arrays : mElinkDecoders) {
194 for (auto& d : arrays.second) {
195 d.reset();
196 }
197 }
198}
199} // namespace o2::mch::raw
200#endif
unsigned short int uint16_t
int32_t i
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events Show standalone event Run event generator maximum time bin of continuous for triggered for automatic continuous for automatic continuous triggered uint64_t
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events d
char error[CURL_ERROR_SIZE]
size_t bytes
Decoder for MCH Raw Data Format.
A UserLogicEndpointDecoder groups 12 x (40 UserLogicElinkDecoder objects)
size_t append(Payload bytes)
Append the equivalent n 64-bits words bytes size (=n) must be a multiple of 8.
UserLogicEndpointDecoder(uint16_t feeId, std::function< std::optional< uint16_t >(FeeLinkId id)> fee2SolarMapper, DecodedDataHandlers decodedDataHandlers)
GLdouble n
Definition glcorearb.h:1982
std::string asString(const SampaCluster &sc)
std::function< void(DsElecId dsId, int8_t chip, uint32_t error)> SampaErrorHandler