14 std::ostringstream
ss;
15 ss <<
"Scope length " << samplesPerChannel <<
" is too long. " 23 return data_.at(internalFEDChannelNum);
24 }
catch (
const std::out_of_range&) {
25 std::ostringstream
ss;
26 ss <<
"Channel index out of range. (" << uint16_t(internalFEDChannelNum) <<
") " 27 <<
"Index should be in internal numbering scheme (0-95). ";
34 std::ostringstream
ss;
35 ss <<
"Sample value (" << value <<
") is too large. Maximum allowed is 1023. ";
40 }
catch (
const std::out_of_range&) {
41 std::ostringstream
ss;
42 ss <<
"Sample index out of range. " 43 <<
"Requesting sample " << sampleNumber <<
" when channel has only " <<
data_.size() <<
" samples.";
52 uint32_t totalSize = 0;
55 totalSize += channelBuffers[iFE * FEDCH_PER_FEUNIT + iCh].size();
59 totalSize = ((totalSize / 8) + 1) * 8;
62 data_.resize(totalSize);
63 size_t indexInBuffer = 0;
64 feLengths_.reserve(FEUNITS_PER_FED);
67 const size_t lengthAtStartOfFEUnit = indexInBuffer;
70 appendToBuffer(&indexInBuffer,
71 channelBuffers[iFE * FEDCH_PER_FEUNIT + iCh].
begin(),
72 channelBuffers[iFE * FEDCH_PER_FEUNIT + iCh].
end());
75 feLengths_.push_back(indexInBuffer - lengthAtStartOfFEUnit);
77 while (indexInBuffer % 8)
78 appendToBuffer(&indexInBuffer, 0);
93 return feLengths_.at(internalFEUnitNum);
94 }
catch (
const std::out_of_range&) {
95 std::ostringstream
ss;
96 ss <<
"Invalid FE unit number " << internalFEUnitNum <<
". " 97 <<
"Number should be in internal numbering scheme (0-7). ";
105 std::vector<std::vector<uint8_t> > channelBuffers(
FEDCH_PER_FED, std::vector<uint8_t>());
109 fillChannelBuffer(&channelBuffers[iCh], mode, packetCode, data.
channel(iCh), channelsEnabled_[iCh]);
118 const bool channelEnabled)
const {
121 fillRawChannelBuffer(channelBuffer,
PACKET_CODE_SCOPE, data, channelEnabled,
false);
124 switch (packetCode) {
144 fillZeroSuppressedChannelBuffer(channelBuffer, packetCode, data, channelEnabled);
154 fillZeroSuppressedLiteChannelBuffer(channelBuffer, data, channelEnabled, mode);
157 fillPreMixRawChannelBuffer(channelBuffer, data, channelEnabled);
160 std::ostringstream
ss;
161 ss <<
"Invalid readout mode " <<
mode;
168 const uint8_t packetCode,
170 const bool channelEnabled,
171 const bool reorderData)
const {
173 uint16_t channelLength = 0;
174 switch (packetCode) {
176 channelLength = nSamples * 2 + 3;
179 channelLength =
std::ceil(nSamples * 1.25) + 3;
183 channelLength = nSamples * 1 + 3;
186 channelBuffer->reserve(channelLength);
188 channelBuffer->push_back(channelLength & 0xFF);
189 channelBuffer->push_back((channelLength & 0xF00) >> 8);
191 channelBuffer->push_back(packetCode);
193 uint16_t sampleValue_pre = 0;
194 for (uint16_t sampleNumber = 0; sampleNumber <
nSamples; sampleNumber++) {
195 const uint16_t sampleIndex =
197 const uint16_t sampleValue = (channelEnabled ? data.
getSample(sampleIndex) : 0);
198 switch (packetCode) {
200 channelBuffer->push_back(sampleValue & 0xFF);
201 channelBuffer->push_back((sampleValue & 0x300) >> 8);
204 if (sampleNumber % 4 == 0) {
205 channelBuffer->push_back((sampleValue & 0x3FC) >> 2);
206 }
else if (sampleNumber % 4 == 1) {
207 channelBuffer->push_back(((sampleValue_pre & 0x3) << 6) | ((sampleValue & 0x3F0) >> 4));
208 }
else if (sampleNumber % 4 == 2) {
209 channelBuffer->push_back(((sampleValue_pre & 0xF) << 4) | ((sampleValue & 0x3C0) >> 6));
210 }
else if (sampleNumber % 4 == 3) {
211 channelBuffer->push_back(((sampleValue_pre & 0x3F) << 2) | ((sampleValue & 0x300) >> 8));
212 channelBuffer->push_back(sampleValue & 0xFF);
214 sampleValue_pre = sampleValue;
217 channelBuffer->push_back((sampleValue & 0x3FC) >> 2);
220 channelBuffer->push_back((sampleValue & 0x1FE) >> 1);
227 const uint8_t packetCode,
229 const bool channelEnabled)
const {
230 channelBuffer->reserve(50);
232 if (!channelEnabled) {
234 channelBuffer->push_back(7);
235 channelBuffer->push_back(0);
237 channelBuffer->push_back(packetCode);
239 channelBuffer->insert(channelBuffer->end(), 4, 0);
244 channelBuffer->push_back(0xFF);
245 channelBuffer->push_back(0xFF);
247 channelBuffer->push_back(packetCode);
249 const std::pair<uint16_t, uint16_t> medians = data.
getMedians();
250 channelBuffer->push_back(medians.first & 0xFF);
251 channelBuffer->push_back((medians.first & 0x300) >> 8);
252 channelBuffer->push_back(medians.second & 0xFF);
253 channelBuffer->push_back((medians.second & 0x300) >> 8);
257 const uint16_t length = channelBuffer->size();
258 (*channelBuffer)[0] = (length & 0xFF);
259 (*channelBuffer)[1] = ((length & 0x300) >> 8);
264 const bool channelEnabled,
266 channelBuffer->reserve(50);
268 if (!channelEnabled) {
270 channelBuffer->push_back(2);
271 channelBuffer->push_back(0);
276 channelBuffer->push_back(0xFF);
277 channelBuffer->push_back(0xFF);
279 fillClusterData(channelBuffer, 0, data, mode);
281 const uint16_t length = channelBuffer->size();
282 (*channelBuffer)[0] = (length & 0xFF);
283 (*channelBuffer)[1] = ((length & 0x300) >> 8);
288 const bool channelEnabled)
const {
289 channelBuffer->reserve(50);
291 if (!channelEnabled) {
293 channelBuffer->push_back(7);
294 channelBuffer->push_back(0);
298 channelBuffer->insert(channelBuffer->end(), 4, 0);
303 channelBuffer->push_back(0xFF);
304 channelBuffer->push_back(0xFF);
308 const std::pair<uint16_t, uint16_t> medians = data.
getMedians();
309 channelBuffer->push_back(medians.first & 0xFF);
310 channelBuffer->push_back((medians.first & 0x300) >> 8);
311 channelBuffer->push_back(medians.second & 0xFF);
312 channelBuffer->push_back((medians.second & 0x300) >> 8);
314 fillClusterDataPreMixMode(channelBuffer, data);
316 const uint16_t length = channelBuffer->size();
317 (*channelBuffer)[0] = (length & 0xFF);
318 (*channelBuffer)[1] = ((length & 0x300) >> 8);
349 uint16_t clusterSize = 0;
350 std::size_t size_pos = 0;
351 uint16_t adc_pre = 0;
358 if (is10Bit && (clusterSize % 4)) {
359 channelBuffer->push_back(adc_pre);
361 (*channelBuffer)[size_pos] = clusterSize;
365 channelBuffer->push_back(
strip);
366 size_pos = channelBuffer->size();
367 channelBuffer->push_back(0);
370 channelBuffer->push_back(adc & 0xFF);
372 if (clusterSize % 4 == 0) {
373 channelBuffer->push_back((adc & 0x3FC) >> 2);
374 adc_pre = ((adc & 0x3) << 6);
375 }
else if (clusterSize % 4 == 1) {
376 channelBuffer->push_back(adc_pre | ((adc & 0x3F0) >> 4));
377 adc_pre = ((adc & 0xF) << 4);
378 }
else if (clusterSize % 4 == 2) {
379 channelBuffer->push_back(adc_pre | ((adc & 0x3C0) >> 6));
380 adc_pre = ((adc & 0x3F) << 2);
381 }
else if (clusterSize % 4 == 3) {
382 channelBuffer->push_back(adc_pre | ((adc & 0x300) >> 8));
383 channelBuffer->push_back(adc & 0xFF);
388 }
else if (clusterSize) {
389 if (is10Bit && (clusterSize % 4)) {
390 channelBuffer->push_back(adc_pre);
392 (*channelBuffer)[size_pos] = clusterSize;
397 (*channelBuffer)[size_pos] = clusterSize;
398 if (is10Bit && (clusterSize % 4)) {
399 channelBuffer->push_back(adc_pre);
406 uint16_t clusterSize = 0;
414 *(channelBuffer->end() - 2 * clusterSize - 1) = clusterSize;
417 channelBuffer->push_back(
strip);
418 channelBuffer->push_back(0);
420 channelBuffer->push_back(adc & 0xFF);
421 channelBuffer->push_back((adc & 0x0300) >> 8);
426 else if (clusterSize) {
427 *(channelBuffer->end() - 2 * clusterSize - 1) = clusterSize;
432 *(channelBuffer->end() - 2 * clusterSize - 1) = clusterSize;
440 const std::vector<bool>& feUnitsEnabled,
441 const std::vector<bool>& channelsEnabled,
446 : defaultDAQHeader_(l1ID, bxID, 0, evtType),
447 defaultDAQTrailer_(0, 0),
448 defaultTrackerSpecialHeader_(bufferFormat, readoutMode, headerType),
449 defaultFEHeader_(
FEDFEHeader::newFEHeader(headerType)),
450 feUnitsEnabled_(feUnitsEnabled),
451 channelsEnabled_(channelsEnabled) {
453 std::ostringstream
ss;
454 ss <<
"Bad header format: " << headerType;
462 }
catch (
const std::out_of_range&) {
463 std::ostringstream
ss;
464 ss <<
"Invalid FE unit number " << internalFEUnitNumber <<
". Should be in internal numbering scheme (0-7)";
472 }
catch (
const std::out_of_range&) {
473 std::ostringstream
ss;
474 ss <<
"Invalid channel number " << internalFEDChannelNumber <<
". " 475 <<
"Should be in internal numbering scheme (0-95)";
483 }
catch (
const std::out_of_range&) {
484 std::ostringstream
ss;
485 ss <<
"Invalid FE unit number " << internalFEUnitNumber <<
". " 486 <<
"Should be in internal numbering scheme (0-7)";
495 }
catch (
const std::out_of_range&) {
496 std::ostringstream
ss;
497 ss <<
"Invalid channel number " << internalFEDChannelNumber <<
". " 498 <<
"Should be in internal numbering scheme (0-95)";
506 std::ostringstream
ss;
507 ss <<
"Setting FE enable vector with vector which is the wrong size. Size is " << feUnitEnables.size()
517 std::ostringstream
ss;
518 ss <<
"Setting FED channel enable vector with vector which is the wrong size. Size is " << channelEnables.size()
529 uint8_t packetCode)
const {
537 for (uint8_t iFEUnitChannel = 0; iFEUnitChannel <
FEDCH_PER_FEUNIT; iFEUnitChannel++) {
555 fedFeHeader->setFEUnitLength(iFE, payload.
getFELength(iFE));
574 uint8_t* bufferPointer = pointerToStartOfBuffer;
575 memcpy(bufferPointer, daqHeader.
data(), 8);
577 memcpy(bufferPointer, tkSpecialHeader.
data(), 8);
583 memcpy(bufferPointer, updatedDAQTrailer.
data(), 8);
586 updatedDAQTrailer.
setCRC(crc);
587 memcpy(bufferPointer, updatedDAQTrailer.
data(), 8);
590 for (
size_t i = 0;
i < 8;
i++) {
591 bufferPointer[
i] = bufferPointer[
i ^ 4];
static uint8_t physicalOrderForStripInChannel(const uint8_t readoutOrderStripIndexInChannel)
FEDBufferGenerator & setChannelEnables(const std::vector< bool > &channelsEnabled)
void fillClusterDataPreMixMode(std::vector< uint8_t > *channelBuffer, const FEDStripData::ChannelData &data) const
FEDDAQHeader defaultDAQHeader_
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED8_BOTBOT
void setSample(const uint16_t sampleNumber, const uint16_t adcValue)
static const uint8_t PACKET_CODE_SCOPE
FEDBufferPayload(const std::vector< std::vector< uint8_t > > &channelBuffers)
static size_t bufferSizeInBytes(const FEDFEHeader &feHeader, const FEDBufferPayload &payload)
FEDStripData(const std::vector< ChannelData > &data)
uint8_t internalFEDChannelNum(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum)
void fillClusterData(std::vector< uint8_t > *channelBuffer, uint8_t packetCode, const FEDStripData::ChannelData &data, const FEDReadoutMode mode) const
uint16_t calculateFEDBufferCRC(const uint8_t *buffer, const size_t lengthInBytes)
FEDReadoutMode getReadoutMode() const
constexpr int32_t ceil(float num)
void fillZeroSuppressedChannelBuffer(std::vector< uint8_t > *channelBuffer, const uint8_t packetCode, const FEDStripData::ChannelData &data, const bool channelEnabled) const
std::unique_ptr< FEDFEHeader > defaultFEHeader_
uint16_t get10BitSample(const uint16_t sampleNumber) const
FEDDAQTrailer & daqTrailer()
uint8_t get8BitSample(const uint16_t sampleNumber, uint16_t nBotBitsToDrop) const
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED8_TOPBOT
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED10
std::vector< bool > channelsEnabled_
static const uint8_t PACKET_CODE_VIRGIN_RAW10
const uint8_t * data() const
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED
FEDDAQTrailer & setEventLengthIn64BitWords(const uint32_t eventLengthIn64BitWords)
FEDBufferGenerator & setFEUnitEnables(const std::vector< bool > &feUnitsEnabled)
FEDDAQTrailer & setCRC(const uint16_t crc)
void resize(size_t newsize)
std::pair< uint16_t, uint16_t > getMedians() const
static const uint16_t FEUNITS_PER_FED
void fillZeroSuppressedLiteChannelBuffer(std::vector< uint8_t > *channelBuffer, const FEDStripData::ChannelData &data, const bool channelEnabled, const FEDReadoutMode mode) const
const uint8_t * data() const
FEDDAQTrailer defaultDAQTrailer_
uint16_t getFELength(const uint8_t internalFEUnitNum) const
void generateBuffer(FEDRawData *rawDataObject, const FEDStripData &data, uint16_t sourceID, uint8_t packetCode) const
constexpr int adc(sample_type sample)
get the ADC sample (12 bits)
FEDBufferGenerator & setChannelEnable(const uint8_t internalFEDChannelNumber, const bool enabled)
static const uint8_t PACKET_CODE_VIRGIN_RAW8_TOPBOT
void fillChannelBuffer(std::vector< uint8_t > *channelBuffer, FEDReadoutMode mode, uint8_t packetCode, const FEDStripData::ChannelData &data, const bool channelEnabled) const
void fillRawChannelBuffer(std::vector< uint8_t > *channelBuffer, const uint8_t packetCode, const FEDStripData::ChannelData &data, const bool channelEnabled, const bool reorderData) const
FEDBufferGenerator(const uint32_t l1ID=0, const uint16_t bxID=0, const std::vector< bool > &feUnitsEnabled=std::vector< bool >(FEUNITS_PER_FED, true), const std::vector< bool > &channelsEnabled=std::vector< bool >(FEDCH_PER_FED, true), const FEDReadoutMode readoutMode=READOUT_MODE_ZERO_SUPPRESSED, const FEDHeaderType headerType=HEADER_TYPE_FULL_DEBUG, const FEDBufferFormat bufferFormat=BUFFER_FORMAT_OLD_SLINK, const FEDDAQEventType evtType=DAQ_EVENT_TYPE_PHYSICS)
static const uint8_t PACKET_CODE_PROC_RAW
ChannelData & channel(const uint8_t internalFEDChannelNum)
static const uint8_t PACKET_CODE_VIRGIN_RAW8_BOTBOT
static const uint16_t FEDCH_PER_FEUNIT
uint16_t getSample(const uint16_t sampleNumber) const
void fillPreMixRawChannelBuffer(std::vector< uint8_t > *channelBuffer, const FEDStripData::ChannelData &data, const bool channelEnabled) const
FEDBufferGenerator & setFEUnitEnable(const uint8_t internalFEUnitNumber, const bool enabled)
bool getFEUnitEnabled(const uint8_t internalFEUnitNumber) const
char data[epos_bytes_allocation]
std::vector< bool > feUnitsEnabled_
static const uint16_t FEDCH_PER_FED
static const uint16_t STRIPS_PER_APV
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
static void fillBuffer(uint8_t *pointerToStartOfBuffer, const FEDDAQHeader &daqHeader, const FEDDAQTrailer &daqTrailer, const TrackerSpecialHeader &tkSpecialHeader, const FEDFEHeader &feHeader, const FEDBufferPayload &payload)
std::vector< ChannelData > data_
size_t lengthInBytes() const
bool getChannelEnabled(const uint8_t internalFEDChannelNumber) const
static const uint16_t SCOPE_MODE_MAX_SCOPE_LENGTH
TrackerSpecialHeader defaultTrackerSpecialHeader_
FEDBufferPayload createPayload(FEDReadoutMode mode, uint8_t packetCode, const FEDStripData &data) const
FEDDAQHeader & daqHeader()
static const uint8_t PACKET_CODE_VIRGIN_RAW