Project
Loading...
Searching...
No Matches
PayloadEncoderImpl.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_PAYLOAD_ENCODER_IMPL_H
13#define O2_MCH_RAW_PAYLOAD_ENCODER_IMPL_H
14
15#include "Assertions.h"
16#include "GBTEncoder.h"
21#include "MakeArray.h"
22#include <algorithm>
23#include <cassert>
24#include <cstdlib>
25#include <fmt/format.h>
26#include <functional>
27#include <gsl/span>
28#include <iostream>
29#include <map>
30#include <memory>
31#include <optional>
32#include <set>
33#include <stdexcept>
34#include <vector>
36#include "NofBits.h"
37#include "Framework/Logger.h"
38
39namespace o2::mch::raw
40{
41
45
46template <typename FORMAT, typename CHARGESUM, int VERSION>
48{
49 public:
51
53 const std::vector<SampaCluster>& data) override;
54
55 void startHeartbeatFrame(uint32_t orbit, uint16_t bunchCrossing) override;
56
57 size_t moveToBuffer(std::vector<std::byte>& buffer) override;
58
59 void addHeartbeatHeaders(const std::set<DsElecId>& dsids) override;
60
62
63 private:
64 void closeHeartbeatFrame(uint32_t orbit, uint16_t bunchCrossing);
65 void gbts2buffer(uint32_t orbit, uint16_t bunchCrossing);
66 std::unique_ptr<ElementaryEncoder>& assertGBT(uint16_t solarId);
67
68 private:
69 uint32_t mOrbit;
70 uint16_t mBunchCrossing;
71 std::vector<std::byte> mBuffer;
72 std::map<uint16_t, std::unique_ptr<ElementaryEncoder>> mGBTs;
73 bool mFirstHBFrame;
74 Solar2FeeLinkMapper mSolar2FeeLink;
75};
76
77template <typename FORMAT, typename CHARGESUM, int VERSION>
79 : mOrbit{},
80 mBunchCrossing{},
81 mBuffer{},
82 mGBTs{},
83 mFirstHBFrame{true},
84 mSolar2FeeLink{solar2feelink}
85{
86}
87
88template <typename FORMAT, typename CHARGESUM, int VERSION>
89std::unique_ptr<typename PayloadEncoderImpl<FORMAT, CHARGESUM, VERSION>::ElementaryEncoder>&
91{
92 auto gbt = mGBTs.find(solarId);
93 if (gbt == mGBTs.end()) {
94 auto f = mSolar2FeeLink(solarId);
95 if (!f.has_value()) {
96 throw std::invalid_argument(fmt::format("Could not get fee,link for solarId={}\n", solarId));
97 }
98 mGBTs.emplace(solarId, std::make_unique<ElementaryEncoder>(f->linkId()));
99 gbt = mGBTs.find(solarId);
100 }
101 return gbt->second;
102}
103
104template <typename FORMAT, typename CHARGESUM, int VERSION>
106{
107 auto solarId = dsId.solarId();
108 auto& gbt = assertGBT(solarId);
109 impl::assertNofBits("dualSampaChannelId", dsChId, 6);
110 gbt->addChannelData(dsId.elinkGroupId(), dsId.elinkIndexInGroup(), dsChId, data);
111}
112
113template <typename FORMAT, typename CHARGESUM, int VERSION>
114void PayloadEncoderImpl<FORMAT, CHARGESUM, VERSION>::gbts2buffer(uint32_t orbit, uint16_t bunchCrossing)
115{
116 // append to our own buffer all the words buffers from all our gbts,
117 // prepending each one with a corresponding payload header
118
119 for (auto& p : mGBTs) {
120 auto& gbt = p.second;
121 std::vector<std::byte> gbtBuffer;
122 gbt->moveToBuffer(gbtBuffer);
123 if (gbtBuffer.empty()) {
124 continue;
125 }
126 assert(gbtBuffer.size() % 4 == 0);
127 DataBlockHeader header{orbit, bunchCrossing, p.first, gbtBuffer.size()};
128 appendDataBlockHeader(mBuffer, header);
129 mBuffer.insert(mBuffer.end(), gbtBuffer.begin(), gbtBuffer.end());
130 }
131}
132
133template <typename FORMAT, typename CHARGESUM, int VERSION>
135{
136 closeHeartbeatFrame(mOrbit, mBunchCrossing);
137 buffer.insert(buffer.end(), mBuffer.begin(), mBuffer.end());
138 auto s = mBuffer.size();
139 mBuffer.clear();
140 return s;
141}
142
143template <typename FORMAT, typename CHARGESUM, int VERSION>
145{
146 gbts2buffer(orbit, bunchCrossing);
147}
148
149template <typename FORMAT, typename CHARGESUM, int VERSION>
151{
152 impl::assertIsInRange("bunchCrossing", bunchCrossing, 0, 0xFFF);
153 // build a buffer with the _previous_ (orbit,bx)
154 if (!mFirstHBFrame) {
155 closeHeartbeatFrame(mOrbit, mBunchCrossing);
156 }
157 mFirstHBFrame = false;
158 // then save the (orbit,bx) for next time
159 mOrbit = orbit;
160 mBunchCrossing = bunchCrossing;
161}
162
167template <typename FORMAT, typename CHARGESUM, int VERSION>
169{
170 if (dsids.empty()) {
171 return;
172 }
173 // get first orbit of the TF
175 auto sampaBXCount = sampaBunchCrossingCounter(firstIR.orbit, firstIR.bc, firstIR.orbit);
176 for (auto dsElecId : dsids) {
177 auto solarId = dsElecId.solarId();
178 auto& gbt = assertGBT(solarId);
179 gbt->addHeartbeat(dsElecId.elinkGroupId(), dsElecId.elinkIndexInGroup(), sampaBXCount);
180 }
181}
182} // namespace o2::mch::raw
183#endif
uint64_t orbit
Definition RawEventData.h:6
constexpr uint16_t solarId() const
solarId is an identifier that uniquely identify a solar board
Definition DsElecId.h:50
constexpr uint8_t elinkIndexInGroup() const
Definition DsElecId.h:30
constexpr uint8_t elinkGroupId() const
Definition DsElecId.h:37
A GBTEncoder manages 40 ElinkEncoder to encode the data of one GBT.
Definition GBTEncoder.h:44
(Default) implementation of Encoder
size_t moveToBuffer(std::vector< std::byte > &buffer) override
void startHeartbeatFrame(uint32_t orbit, uint16_t bunchCrossing) override
PayloadEncoderImpl(Solar2FeeLinkMapper solar2feelink)
void addChannelData(DsElecId dsId, DualSampaChannelId dsChId, const std::vector< SampaCluster > &data) override
void addHeartbeatHeaders(const std::set< DsElecId > &dsids) override
A PayloadEncoder builds MCH raw data (payload part only)
GLuint buffer
Definition glcorearb.h:655
GLdouble f
Definition glcorearb.h:310
GLboolean * data
Definition glcorearb.h:298
void assertNofBits(std::string_view msg, T value, int n)
Definition NofBits.h:29
int assertIsInRange(std::string what, uint64_t value, uint64_t min, uint64_t max)
Definition Assertions.h:20
uint20_t sampaBunchCrossingCounter(uint32_t orbit, uint16_t bc, uint32_t firstOrbit)
void appendDataBlockHeader(std::vector< std::byte > &outBuffer, DataBlockHeader header)
Convert the header into bytes.
Definition DataBlock.cxx:17
uint6_t DualSampaChannelId
Definition DataFormats.h:65
std::function< std::optional< FeeLinkId >(uint16_t solarId)> Solar2FeeLinkMapper
From solarId to (feeId,linkId)
Definition Mapper.h:57
IR getFirstSampledTFIR() const
get TF and HB (abs) for this IR
Definition HBFUtils.h:74