Project
Loading...
Searching...
No Matches
BareElinkEncoder.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_BARE_ELINK_ENCODER_H
13#define O2_MCH_RAW_BARE_ELINK_ENCODER_H
14
15#include "Assertions.h"
16#include "BitSet.h"
17#include "ElinkEncoder.h"
18#include "EncoderImplHelper.h"
22#include "NofBits.h"
23#include <fmt/format.h>
24#include <fmt/printf.h>
25#include <gsl/span>
26#include <iostream>
27#include <vector>
28
29namespace o2::mch::raw
30{
31
36
37template <typename CHARGESUM>
38class ElinkEncoder<BareFormat, CHARGESUM>
39{
40 public:
48 explicit ElinkEncoder(uint8_t elinkId, int phase = 0);
49
55 void addChannelData(uint8_t chId, const std::vector<SampaCluster>& data);
56
57 void addHeartbeat(uint20_t bunchCrossing);
58
60 void clear();
61
64 void fillWithSync(int upto);
65
67 bool get(int i) const;
68
70 int len() const;
71
73 void resetLocalBunchCrossing();
74
77 uint64_t range(int a, int b) const;
78
79 private:
80 void append(bool value);
81 void append(const SampaCluster& sc);
82 void append10(uint16_t value);
83 void append20(uint32_t value);
84 void append50(uint64_t value);
85 void appendCharges(const SampaCluster& sc);
86 void assertPhase();
87 void assertSync();
88 uint64_t nofSync() const { return mNofSync; }
89
90 private:
91 uint8_t mElinkId; //< Elink id 0..39
92 BitSet mBitSet; //< bitstream
93 uint64_t mNofSync; //< number of sync words seen so far
94 int mSyncIndex; //< at which sync bit position should the next fillWithSync start
95 uint64_t mNofBitSeen; //< total number of bits seen so far
96 int mPhase; //< initial number of bits
97 uint32_t mLocalBunchCrossing; //< bunchcrossing to be used in header
98};
99
100namespace
101{
102const BitSet sync(sampaSync().uint64(), 50);
103}
104
105template <typename CHARGESUM>
107 int phase)
108 : mElinkId(elinkId),
109 mBitSet{},
110 mNofSync{0},
111 mSyncIndex{0},
112 mNofBitSeen{0},
113 mLocalBunchCrossing{0},
114 mPhase{phase}
115{
116 impl::assertIsInRange("elinkId", elinkId, 0, 39);
117
118 // the phase is used to "simulate" a possible different timing alignment between elinks.
119
120 if (phase < 0) {
121 mPhase = static_cast<int>(rand() % 20);
122 }
123
124 for (int i = 0; i < mPhase; i++) {
125 // filling the phase with random bits
126 append(static_cast<bool>(rand() % 2));
127 }
128}
129
130template <typename CHARGESUM>
131void ElinkEncoder<BareFormat, CHARGESUM>::addChannelData(uint8_t chId, const std::vector<SampaCluster>& data)
132{
133 if (data.empty()) {
134 throw std::invalid_argument("cannot add empty data");
135 }
136 assertSync();
137 assertNotMixingClusters<CHARGESUM>(data);
138
139 auto header = impl::buildSampaHeader(mElinkId, chId, data);
140
141 append50(header.uint64());
142
143 for (const auto& s : data) {
144 append(s);
145 }
146}
147
148template <typename CHARGESUM>
150{
151 uint8_t chipAddress = impl::computeChipAddress(mElinkId, 0);
152 SampaHeader sh = sampaHeartbeat(chipAddress, bunchCrossing);
153 append50(sh.uint64());
154}
155
157template <typename CHARGESUM>
159{
160 append10(sc.nofSamples());
161 append10(sc.sampaTime);
162 appendCharges(sc);
163}
164
166template <typename CHARGESUM>
167void ElinkEncoder<BareFormat, CHARGESUM>::append(bool value)
168{
169 mBitSet.append(value);
170 mNofBitSeen++;
171}
172
174template <typename CHARGESUM>
175void ElinkEncoder<BareFormat, CHARGESUM>::append10(uint16_t value)
176{
177 mBitSet.append(value, 10);
178 mNofBitSeen += 10;
179}
180
182template <typename CHARGESUM>
183void ElinkEncoder<BareFormat, CHARGESUM>::append20(uint32_t value)
184{
185 mBitSet.append(value, 20);
186 mNofBitSeen += 20;
187}
188
190template <typename CHARGESUM>
191void ElinkEncoder<BareFormat, CHARGESUM>::append50(uint64_t value)
192{
193 mBitSet.append(value, 50);
194 mNofBitSeen += 50;
195}
196
197template <typename CHARGESUM>
198void ElinkEncoder<BareFormat, CHARGESUM>::assertSync()
199{
200 bool firstSync = (mNofSync == 0);
201
202 // if mSyncIndex is not zero it means
203 // we have a pending sync to finish to transmit
204 // (said otherwise we're not aligned to an expected 50bits mark)
205 bool pendingSync = (mSyncIndex != 0);
206
207 if (firstSync || pendingSync) {
208 for (int i = mSyncIndex; i < 50; i++) {
209 append(sync.get(i));
210 }
211 mSyncIndex = 0;
212 if (firstSync) {
213 mNofSync++;
214 }
215 }
216}
217
218template <typename CHARGESUM>
220{
221 // we are not resetting the global counters mNofSync, mNofBitSeen,
222 // just the bit stream
223 mBitSet.clear();
224}
225
226template <typename CHARGESUM>
228{
229 auto d = upto - len();
230 mSyncIndex = circularAppend(mBitSet, sync, mSyncIndex, d);
231 mNofSync += d / 50;
232 mNofBitSeen += d;
233}
234
235template <typename CHARGESUM>
237{
238 impl::assertIsInRange("i", i, 0, len() - 1);
239 return mBitSet.get(i);
240}
241
242template <typename CHARGESUM>
244{
245 return mBitSet.len();
246}
247
248template <typename CHARGESUM>
250{
251 return mBitSet.subset(a, b).uint64(0, b - a + 1);
252}
253
254template <typename CHARGESUM>
256{
257 mLocalBunchCrossing = mPhase;
258}
259
260} // namespace o2::mch::raw
261
262#endif
uint64_t phase
Definition RawEventData.h:7
#define rand()
unsigned short int uint16_t
unsigned int uint32_t
std::vector< std::string > header
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 s
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
void appendCharges(const SampaCluster &sc)
SampaHeader is the 50-bits header word used in Sampa data transmission protocol.
Definition SampaHeader.h:51
constexpr uint64_t uint64() const
return the header as a 64-bits integer
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLenum GLint * range
Definition glcorearb.h:1899
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLenum GLenum GLsizei len
Definition glcorearb.h:4232
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
uint16_t computeChipAddress(uint8_t elinkId, DualSampaChannelId chId)
SampaHeader buildSampaHeader(uint8_t elinkId, DualSampaChannelId chId, gsl::span< const SampaCluster > data)
int assertIsInRange(std::string what, uint64_t value, uint64_t min, uint64_t max)
Definition Assertions.h:20
SampaHeader sampaHeartbeat(uint8_t elinkId, uint20_t bunchCrossing)
Heartbeat packet.
int circularAppend(BitSet &bs, const BitSet &ringBuffer, int startBit, int n)
Definition BitSet.cxx:421
SampaHeader sampaSync()
The 50-bits Sampa SYNC word.
void append(const char *msg, std::string &to)
Piece of data for one Sampa channel.
uint16_t nofSamples() const
vec clear()