Project
Loading...
Searching...
No Matches
PageDecoder.cxx
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#include "BareGBTDecoder.h"
18#include <iostream>
19
20namespace o2::mch::raw
21{
22namespace impl
23{
24
25template <typename FORMAT, typename CHARGESUM, int VERSION = 0>
27
28 using type = struct PayloadDecoderImplReturnType {
29 void process(uint32_t, gsl::span<const std::byte>);
30 };
31
32 type operator()(const FeeLinkId& feeLinkId, DecodedDataHandlers decodedDataHandlers, FeeLink2SolarMapper fee2solar);
33};
34
35template <typename CHARGESUM, int VERSION>
36struct PayloadDecoderImpl<UserLogicFormat, CHARGESUM, VERSION> {
38
39 type operator()(const FeeLinkId& feeLinkId, DecodedDataHandlers decodedDataHandlers, FeeLink2SolarMapper fee2solar)
40 {
41 return std::move(UserLogicEndpointDecoder<CHARGESUM, VERSION>(feeLinkId.feeId(), fee2solar, decodedDataHandlers));
42 }
43};
44
45template <typename CHARGESUM>
46struct PayloadDecoderImpl<BareFormat, CHARGESUM, 0> {
48
49 type operator()(const FeeLinkId& feeLinkId, DecodedDataHandlers decodedDataHandlers, FeeLink2SolarMapper fee2solar)
50 {
51 auto solarId = fee2solar(feeLinkId);
52 if (!solarId.has_value()) {
53 throw std::logic_error(fmt::format("{} could not get solarId from feelinkid={}\n", __PRETTY_FUNCTION__, asString(feeLinkId)));
54 }
55 return std::move(BareGBTDecoder<CHARGESUM>(solarId.value(), decodedDataHandlers));
56 }
57};
58
59template <typename FORMAT, typename CHARGESUM, int VERSION = 0>
61{
62 public:
63 PageDecoderImpl(DecodedDataHandlers decodedDataHandlers, FeeLink2SolarMapper fee2solar) : mDecodedDataHandlers{decodedDataHandlers},
64 mFee2SolarMapper(fee2solar)
65 {
66 }
67
68 void operator()(Page page)
69 {
70 const void* rdhP = reinterpret_cast<const void*>(page.data());
71 if (!o2::raw::RDHUtils::checkRDH(rdhP, true)) {
72 throw std::invalid_argument("page does not start with a valid RDH");
73 }
74
75 auto feeId = o2::raw::RDHUtils::getFEEID(rdhP);
76 auto linkId = o2::raw::RDHUtils::getLinkID(rdhP);
77 FEEID f{feeId};
78 FeeLinkId feeLinkId(f.id, linkId);
79
80 auto p = mPayloadDecoders.find(feeLinkId);
81 if (p == mPayloadDecoders.end()) {
82 mPayloadDecoders.emplace(feeLinkId, PayloadDecoderImpl<FORMAT, CHARGESUM, VERSION>()(feeLinkId, mDecodedDataHandlers, mFee2SolarMapper));
83 p = mPayloadDecoders.find(feeLinkId);
84 }
85
86 uint32_t orbit = o2::raw::RDHUtils::getHeartBeatOrbit(rdhP);
87 auto rdhSize = o2::raw::RDHUtils::getHeaderSize(rdhP);
88 auto payloadSize = o2::raw::RDHUtils::getMemorySize(rdhP) - rdhSize;
89 // skip empty payloads, otherwise the orbit jumps are not correctly detected
90 if (payloadSize > 0) {
91 p->second.process(orbit, page.subspan(rdhSize, payloadSize));
92 }
93 }
94
95 private:
96 DecodedDataHandlers mDecodedDataHandlers;
97 FeeLink2SolarMapper mFee2SolarMapper;
98 std::map<FeeLinkId, typename PayloadDecoderImpl<FORMAT, CHARGESUM, VERSION>::type> mPayloadDecoders;
99};
100
101} // namespace impl
102
104{
105 const void* rdhP = reinterpret_cast<const void*>(rdhBuffer.data());
106 bool ok = o2::raw::RDHUtils::checkRDH(rdhP, true);
107 if (!ok) {
108 throw std::invalid_argument("rdhBuffer does not point to a valid RDH !");
109 }
110 auto linkId = o2::raw::RDHUtils::getLinkID(rdhP);
111 auto feeId = o2::raw::RDHUtils::getFEEID(rdhP);
112 FEEID f{feeId};
113 if (linkId == 15) {
114 if (f.ulFormatVersion != 0 && f.ulFormatVersion != 1) {
115 throw std::logic_error(fmt::format("ulFormatVersion {} is unknown", static_cast<int>(f.ulFormatVersion)));
116 }
117 if (f.chargeSum) {
118 if (f.ulFormatVersion == 0) {
119 return impl::PageDecoderImpl<UserLogicFormat, ChargeSumMode, 0>(decodedDataHandlers, fee2solar);
120 } else if (f.ulFormatVersion == 1) {
121 return impl::PageDecoderImpl<UserLogicFormat, ChargeSumMode, 1>(decodedDataHandlers, fee2solar);
122 }
123 } else {
124 if (f.ulFormatVersion == 0) {
125 return impl::PageDecoderImpl<UserLogicFormat, SampleMode, 0>(decodedDataHandlers, fee2solar);
126 } else if (f.ulFormatVersion == 1) {
127 return impl::PageDecoderImpl<UserLogicFormat, SampleMode, 1>(decodedDataHandlers, fee2solar);
128 }
129 }
130 } else {
131 if (f.chargeSum) {
132 return impl::PageDecoderImpl<BareFormat, ChargeSumMode>(decodedDataHandlers, fee2solar);
133 } else {
134 return impl::PageDecoderImpl<BareFormat, SampleMode>(decodedDataHandlers, fee2solar);
135 }
136 }
137 return nullptr;
138}
139
141{
143 return createPageDecoder(rdhBuffer, decodedDataHandlers, fee2solar);
144}
145
147{
148 DecodedDataHandlers handlers;
149 handlers.sampaChannelHandler = channelHandler;
150 return createPageDecoder(rdhBuffer, handlers);
151}
152
154{
155 DecodedDataHandlers handlers;
156 handlers.sampaChannelHandler = channelHandler;
157 return createPageDecoder(rdhBuffer, handlers, fee2solar);
158}
159
161{
162 return [](RawBuffer buffer, PageDecoder pageDecoder) {
163 size_t pos{0};
164 const void* rdhP = reinterpret_cast<const void*>(buffer.data());
165 bool ok = o2::raw::RDHUtils::checkRDH(rdhP, true);
166 if (!ok) {
167 throw std::invalid_argument("buffer does not start with a valid RDH !");
168 }
169 auto rdhSize = o2::raw::RDHUtils::getHeaderSize(rdhP);
170 while (pos < buffer.size_bytes() - rdhSize) {
171 const void* rdhP = reinterpret_cast<const void*>(buffer.data() + pos);
172 bool ok = o2::raw::RDHUtils::checkRDH(rdhP, true);
173 if (!ok) {
174 throw std::invalid_argument(fmt::format("buffer at pos {} does not point to a valid RDH !", pos));
175 }
176 auto payloadSize = o2::raw::RDHUtils::getMemorySize(rdhP) - rdhSize;
177 pageDecoder(buffer.subspan(pos, rdhSize + payloadSize));
178 pos += o2::raw::RDHUtils::getOffsetToNext(rdhP);
179 }
180 };
181}
182
183} // namespace o2::mch::raw
uint64_t orbit
Definition RawEventData.h:6
uint16_t pos
Definition RawData.h:3
A BareGBTDecoder groups 40 ElinkDecoder objects.
uint16_t feeId() const
Definition FeeLinkId.h:26
A UserLogicEndpointDecoder groups 12 x (40 UserLogicElinkDecoder objects)
PageDecoderImpl(DecodedDataHandlers decodedDataHandlers, FeeLink2SolarMapper fee2solar)
GLuint buffer
Definition glcorearb.h:655
GLdouble f
Definition glcorearb.h:310
gsl::span< const std::byte > RawBuffer
Definition PageDecoder.h:30
PageParser createPageParser()
std::function< std::optional< uint16_t >(FeeLinkId)> createFeeLink2SolarMapper< ElectronicMapperGenerated >()
std::function< void(Page buffer)> PageDecoder
Definition PageDecoder.h:28
gsl::span< const std::byte > Page
Definition PageDecoder.h:25
std::function< void(DsElecId dsId, DualSampaChannelId channel, SampaCluster)> SampaChannelHandler
std::function< std::optional< uint16_t >(FeeLinkId id)> FeeLink2SolarMapper
From (feeId,linkId) to solarId.
Definition Mapper.h:52
PageDecoder createPageDecoder(RawBuffer rdhBuffer, DecodedDataHandlers decodedDataHandlers)
will be called for each decoded Sampa packet and in case of decoding errors
std::string asString(const SampaCluster &sc)
std::function< void(RawBuffer buffer, PageDecoder pageDecoder)> PageParser
Definition PageDecoder.h:63
type operator()(const FeeLinkId &feeLinkId, DecodedDataHandlers decodedDataHandlers, FeeLink2SolarMapper fee2solar)
type operator()(const FeeLinkId &feeLinkId, DecodedDataHandlers decodedDataHandlers, FeeLink2SolarMapper fee2solar)
PayloadDecoderImplReturnType { void process(uint32_t, gsl::span< const std::byte >) type
type operator()(const FeeLinkId &feeLinkId, DecodedDataHandlers decodedDataHandlers, FeeLink2SolarMapper fee2solar)
static bool checkRDH(const RDHv4 &rdh, bool verbose=true, bool checkZeros=false)
Definition RDHUtils.cxx:133