CMS 3D CMS Logo

SiStripFEDBufferGenerator.cc
Go to the documentation of this file.
3 #include <cstring>
4 #include <stdexcept>
5 #include <cmath>
6 
7 namespace sistrip {
8 
9  //FEDStripData
10 
11  FEDStripData::FEDStripData(bool dataIsAlreadyConvertedTo8Bit, const size_t samplesPerChannel)
12  : data_(FEDCH_PER_FED, ChannelData(dataIsAlreadyConvertedTo8Bit, samplesPerChannel)) {
13  if (samplesPerChannel > SCOPE_MODE_MAX_SCOPE_LENGTH) {
14  std::ostringstream ss;
15  ss << "Scope length " << samplesPerChannel << " is too long. "
16  << "Max scope length is " << SCOPE_MODE_MAX_SCOPE_LENGTH << ".";
17  throw cms::Exception("FEDBufferGenerator") << ss.str();
18  }
19  }
20 
22  try {
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). ";
28  throw cms::Exception("FEDBufferGenerator") << ss.str();
29  }
30  }
31 
32  void FEDStripData::ChannelData::setSample(const uint16_t sampleNumber, const uint16_t value) {
33  if (value > 0x3FF) {
34  std::ostringstream ss;
35  ss << "Sample value (" << value << ") is too large. Maximum allowed is 1023. ";
36  throw cms::Exception("FEDBufferGenerator") << ss.str();
37  }
38  try {
39  data_.at(sampleNumber) = value;
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.";
44  throw cms::Exception("FEDBufferGenerator") << ss.str();
45  }
46  }
47 
48  //FEDBufferPayload
49 
50  FEDBufferPayload::FEDBufferPayload(const std::vector<std::vector<uint8_t> >& channelBuffers) {
51  //calculate size of buffer and allocate enough memory
52  uint32_t totalSize = 0;
53  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
54  for (uint8_t iCh = 0; iCh < FEDCH_PER_FEUNIT; iCh++) {
55  totalSize += channelBuffers[iFE * FEDCH_PER_FEUNIT + iCh].size();
56  }
57  //if it does not finish on a 64Bit word boundary then take into account padding
58  if (totalSize % 8) {
59  totalSize = ((totalSize / 8) + 1) * 8;
60  }
61  }
62  data_.resize(totalSize);
63  size_t indexInBuffer = 0;
64  feLengths_.reserve(FEUNITS_PER_FED);
65  //copy channel data into buffer with padding and update lengths
66  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
67  const size_t lengthAtStartOfFEUnit = indexInBuffer;
68  //insert data for FE unit
69  for (uint8_t iCh = 0; iCh < FEDCH_PER_FEUNIT; iCh++) {
70  appendToBuffer(&indexInBuffer,
71  channelBuffers[iFE * FEDCH_PER_FEUNIT + iCh].begin(),
72  channelBuffers[iFE * FEDCH_PER_FEUNIT + iCh].end());
73  }
74  //store length
75  feLengths_.push_back(indexInBuffer - lengthAtStartOfFEUnit);
76  //add padding
77  while (indexInBuffer % 8)
78  appendToBuffer(&indexInBuffer, 0);
79  }
80  }
81 
82  const uint8_t* FEDBufferPayload::data() const {
83  //vectors are guarenteed to be contiguous
84  if (lengthInBytes())
85  return &data_[0];
86  //return NULL if there is no data yet
87  else
88  return nullptr;
89  }
90 
91  uint16_t FEDBufferPayload::getFELength(const uint8_t internalFEUnitNum) const {
92  try {
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). ";
98  throw cms::Exception("FEDBufferGenerator") << ss.str();
99  }
100  }
101 
103  uint8_t packetCode,
104  const FEDStripData& data) const {
105  std::vector<std::vector<uint8_t> > channelBuffers(FEDCH_PER_FED, std::vector<uint8_t>());
106  for (size_t iCh = 0; iCh < FEDCH_PER_FED; iCh++) {
107  if (!feUnitsEnabled_[iCh / FEDCH_PER_FEUNIT])
108  continue;
109  fillChannelBuffer(&channelBuffers[iCh], mode, packetCode, data.channel(iCh), channelsEnabled_[iCh]);
110  }
111  return FEDBufferPayload(channelBuffers);
112  }
113 
114  void FEDBufferPayloadCreator::fillChannelBuffer(std::vector<uint8_t>* channelBuffer,
116  uint8_t packetCode,
118  const bool channelEnabled) const {
119  switch (mode) {
120  case READOUT_MODE_SCOPE:
121  fillRawChannelBuffer(channelBuffer, PACKET_CODE_SCOPE, data, channelEnabled, false);
122  break;
124  switch (packetCode) {
126  fillRawChannelBuffer(channelBuffer, PACKET_CODE_VIRGIN_RAW, data, channelEnabled, true);
127  break;
129  fillRawChannelBuffer(channelBuffer, PACKET_CODE_VIRGIN_RAW10, data, channelEnabled, true);
130  break;
132  fillRawChannelBuffer(channelBuffer, PACKET_CODE_VIRGIN_RAW8_BOTBOT, data, channelEnabled, true);
133  break;
135  fillRawChannelBuffer(channelBuffer, PACKET_CODE_VIRGIN_RAW8_TOPBOT, data, channelEnabled, true);
136  break;
137  }
138  break;
140  fillRawChannelBuffer(channelBuffer, PACKET_CODE_PROC_RAW, data, channelEnabled, false);
141  break;
143  //case READOUT_MODE_ZERO_SUPPRESSED_CMOVERRIDE:
144  fillZeroSuppressedChannelBuffer(channelBuffer, packetCode, data, channelEnabled);
145  break;
154  fillZeroSuppressedLiteChannelBuffer(channelBuffer, data, channelEnabled, mode);
155  break;
157  fillPreMixRawChannelBuffer(channelBuffer, data, channelEnabled);
158  break;
159  default:
160  std::ostringstream ss;
161  ss << "Invalid readout mode " << mode;
162  throw cms::Exception("FEDBufferGenerator") << ss.str();
163  break;
164  }
165  }
166 
167  void FEDBufferPayloadCreator::fillRawChannelBuffer(std::vector<uint8_t>* channelBuffer,
168  const uint8_t packetCode,
170  const bool channelEnabled,
171  const bool reorderData) const {
172  const uint16_t nSamples = data.size();
173  uint16_t channelLength = 0;
174  switch (packetCode) {
176  channelLength = nSamples * 2 + 3;
177  break;
179  channelLength = std::ceil(nSamples * 1.25) + 3;
180  break;
183  channelLength = nSamples * 1 + 3;
184  break;
185  }
186  channelBuffer->reserve(channelLength);
187  //length (max length is 0xFFF)
188  channelBuffer->push_back(channelLength & 0xFF);
189  channelBuffer->push_back((channelLength & 0xF00) >> 8);
190  //packet code
191  channelBuffer->push_back(packetCode);
192  //channel samples
193  uint16_t sampleValue_pre = 0;
194  for (uint16_t sampleNumber = 0; sampleNumber < nSamples; sampleNumber++) {
195  const uint16_t sampleIndex =
196  (reorderData ? FEDStripOrdering::physicalOrderForStripInChannel(sampleNumber) : sampleNumber);
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);
202  break;
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);
213  }
214  sampleValue_pre = sampleValue;
215  break;
217  channelBuffer->push_back((sampleValue & 0x3FC) >> 2);
218  break;
220  channelBuffer->push_back((sampleValue & 0x1FE) >> 1);
221  break;
222  }
223  }
224  }
225 
226  void FEDBufferPayloadCreator::fillZeroSuppressedChannelBuffer(std::vector<uint8_t>* channelBuffer,
227  const uint8_t packetCode,
229  const bool channelEnabled) const {
230  channelBuffer->reserve(50);
231  //if channel is disabled then create empty channel header and return
232  if (!channelEnabled) {
233  //min length 7
234  channelBuffer->push_back(7);
235  channelBuffer->push_back(0);
236  //packet code
237  channelBuffer->push_back(packetCode);
238  //4 bytes of medians
239  channelBuffer->insert(channelBuffer->end(), 4, 0);
240  return;
241  }
242  //if channel is not empty
243  //add space for channel length
244  channelBuffer->push_back(0xFF);
245  channelBuffer->push_back(0xFF);
246  //packet code
247  channelBuffer->push_back(packetCode);
248  //add medians
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);
254  //clusters
255  fillClusterData(channelBuffer, packetCode, data, READOUT_MODE_ZERO_SUPPRESSED);
256  //set length
257  const uint16_t length = channelBuffer->size();
258  (*channelBuffer)[0] = (length & 0xFF);
259  (*channelBuffer)[1] = ((length & 0x300) >> 8);
260  }
261 
262  void FEDBufferPayloadCreator::fillZeroSuppressedLiteChannelBuffer(std::vector<uint8_t>* channelBuffer,
264  const bool channelEnabled,
265  const FEDReadoutMode mode) const {
266  channelBuffer->reserve(50);
267  //if channel is disabled then create empty channel header and return
268  if (!channelEnabled) {
269  //min length 2
270  channelBuffer->push_back(2);
271  channelBuffer->push_back(0);
272  return;
273  }
274  //if channel is not empty
275  //add space for channel length
276  channelBuffer->push_back(0xFF);
277  channelBuffer->push_back(0xFF);
278  //clusters
279  fillClusterData(channelBuffer, 0, data, mode);
280  //set fibre length
281  const uint16_t length = channelBuffer->size();
282  (*channelBuffer)[0] = (length & 0xFF);
283  (*channelBuffer)[1] = ((length & 0x300) >> 8);
284  }
285 
286  void FEDBufferPayloadCreator::fillPreMixRawChannelBuffer(std::vector<uint8_t>* channelBuffer,
288  const bool channelEnabled) const {
289  channelBuffer->reserve(50);
290  //if channel is disabled then create empty channel header and return
291  if (!channelEnabled) {
292  //min length 7
293  channelBuffer->push_back(7);
294  channelBuffer->push_back(0);
295  //packet code
296  channelBuffer->push_back(PACKET_CODE_ZERO_SUPPRESSED);
297  //4 bytes of medians
298  channelBuffer->insert(channelBuffer->end(), 4, 0);
299  return;
300  }
301  //if channel is not empty
302  //add space for channel length
303  channelBuffer->push_back(0xFF);
304  channelBuffer->push_back(0xFF);
305  //packet code
306  channelBuffer->push_back(PACKET_CODE_ZERO_SUPPRESSED);
307  //add medians
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);
313  //clusters
314  fillClusterDataPreMixMode(channelBuffer, data);
315  //set length
316  const uint16_t length = channelBuffer->size();
317  (*channelBuffer)[0] = (length & 0xFF);
318  (*channelBuffer)[1] = ((length & 0x300) >> 8);
319  }
320 
321  void FEDBufferPayloadCreator::fillClusterData(std::vector<uint8_t>* channelBuffer,
322  uint8_t packetCode,
324  const FEDReadoutMode mode) const {
325  // ZS lite: retrieve "packet code"
326  switch (mode) {
328  packetCode = PACKET_CODE_ZERO_SUPPRESSED;
329  break;
333  break;
337  break;
340  packetCode = PACKET_CODE_ZERO_SUPPRESSED10;
341  break;
342  default:;
343  }
344  const bool is10Bit = (packetCode == PACKET_CODE_ZERO_SUPPRESSED10);
345  const uint16_t bShift = (packetCode == PACKET_CODE_ZERO_SUPPRESSED8_BOTBOT
346  ? 2
347  : (packetCode == PACKET_CODE_ZERO_SUPPRESSED8_TOPBOT ? 1 : 0));
348 
349  uint16_t clusterSize = 0; // counter
350  std::size_t size_pos = 0; // index of cluster size
351  uint16_t adc_pre = 0;
352  const uint16_t nSamples = data.size();
353  for (uint16_t strip = 0; strip < nSamples; ++strip) {
354  const uint16_t adc = is10Bit ? data.get10BitSample(strip) : data.get8BitSample(strip, bShift);
355  if (adc) {
356  if (clusterSize == 0 || strip == STRIPS_PER_APV) {
357  if (clusterSize) {
358  if (is10Bit && (clusterSize % 4)) {
359  channelBuffer->push_back(adc_pre);
360  }
361  (*channelBuffer)[size_pos] = clusterSize;
362  clusterSize = 0;
363  }
364  // cluster header: first strip and size
365  channelBuffer->push_back(strip);
366  size_pos = channelBuffer->size();
367  channelBuffer->push_back(0); // for clustersize
368  }
369  if (!is10Bit) {
370  channelBuffer->push_back(adc & 0xFF);
371  } else {
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);
384  adc_pre = 0;
385  }
386  }
387  ++clusterSize;
388  } else if (clusterSize) {
389  if (is10Bit && (clusterSize % 4)) {
390  channelBuffer->push_back(adc_pre);
391  }
392  (*channelBuffer)[size_pos] = clusterSize;
393  clusterSize = 0;
394  }
395  }
396  if (clusterSize) {
397  (*channelBuffer)[size_pos] = clusterSize;
398  if (is10Bit && (clusterSize % 4)) {
399  channelBuffer->push_back(adc_pre);
400  }
401  }
402  }
403 
404  void FEDBufferPayloadCreator::fillClusterDataPreMixMode(std::vector<uint8_t>* channelBuffer,
405  const FEDStripData::ChannelData& data) const {
406  uint16_t clusterSize = 0;
407  const uint16_t nSamples = data.size();
408  for (uint16_t strip = 0; strip < nSamples; ++strip) {
409  const uint16_t adc = data.get10BitSample(strip);
410 
411  if (adc) {
412  if (clusterSize == 0 || strip == STRIPS_PER_APV) {
413  if (clusterSize) {
414  *(channelBuffer->end() - 2 * clusterSize - 1) = clusterSize;
415  clusterSize = 0;
416  }
417  channelBuffer->push_back(strip);
418  channelBuffer->push_back(0); //clustersize
419  }
420  channelBuffer->push_back(adc & 0xFF);
421  channelBuffer->push_back((adc & 0x0300) >> 8);
422 
423  ++clusterSize;
424  }
425 
426  else if (clusterSize) {
427  *(channelBuffer->end() - 2 * clusterSize - 1) = clusterSize;
428  clusterSize = 0;
429  }
430  }
431  if (clusterSize) {
432  *(channelBuffer->end() - 2 * clusterSize - 1) = clusterSize;
433  }
434  }
435 
436  //FEDBufferGenerator
437 
439  const uint16_t bxID,
440  const std::vector<bool>& feUnitsEnabled,
441  const std::vector<bool>& channelsEnabled,
442  const FEDReadoutMode readoutMode,
443  const FEDHeaderType headerType,
444  const FEDBufferFormat bufferFormat,
445  const FEDDAQEventType evtType)
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) {
452  if (!defaultFEHeader_.get()) {
453  std::ostringstream ss;
454  ss << "Bad header format: " << headerType;
455  throw cms::Exception("FEDBufferGenerator") << ss.str();
456  }
457  }
458 
459  bool FEDBufferGenerator::getFEUnitEnabled(const uint8_t internalFEUnitNumber) const {
460  try {
461  return feUnitsEnabled_.at(internalFEUnitNumber);
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)";
465  throw cms::Exception("FEDBufferGenerator") << ss.str();
466  }
467  }
468 
469  bool FEDBufferGenerator::getChannelEnabled(const uint8_t internalFEDChannelNumber) const {
470  try {
471  return channelsEnabled_.at(internalFEDChannelNumber);
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)";
476  throw cms::Exception("FEDBufferGenerator") << ss.str();
477  }
478  }
479 
480  FEDBufferGenerator& FEDBufferGenerator::setFEUnitEnable(const uint8_t internalFEUnitNumber, const bool enabled) {
481  try {
482  feUnitsEnabled_.at(internalFEUnitNumber) = enabled;
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)";
487  throw cms::Exception("FEDBufferGenerator") << ss.str();
488  }
489  return *this;
490  }
491 
492  FEDBufferGenerator& FEDBufferGenerator::setChannelEnable(const uint8_t internalFEDChannelNumber, const bool enabled) {
493  try {
494  channelsEnabled_.at(internalFEDChannelNumber) = enabled;
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)";
499  throw cms::Exception("FEDBufferGenerator") << ss.str();
500  }
501  return *this;
502  }
503 
504  FEDBufferGenerator& FEDBufferGenerator::setFEUnitEnables(const std::vector<bool>& feUnitEnables) {
505  if (feUnitEnables.size() != FEUNITS_PER_FED) {
506  std::ostringstream ss;
507  ss << "Setting FE enable vector with vector which is the wrong size. Size is " << feUnitEnables.size()
508  << " it must be " << FEUNITS_PER_FED << "." << std::endl;
509  throw cms::Exception("FEDBufferGenerator") << ss.str();
510  }
511  feUnitsEnabled_ = feUnitEnables;
512  return *this;
513  }
514 
515  FEDBufferGenerator& FEDBufferGenerator::setChannelEnables(const std::vector<bool>& channelEnables) {
516  if (channelEnables.size() != FEDCH_PER_FED) {
517  std::ostringstream ss;
518  ss << "Setting FED channel enable vector with vector which is the wrong size. Size is " << channelEnables.size()
519  << " it must be " << FEDCH_PER_FED << "." << std::endl;
520  throw cms::Exception("FEDBufferGenerator") << ss.str();
521  }
522  channelsEnabled_ = channelEnables;
523  return *this;
524  }
525 
527  const FEDStripData& data,
528  uint16_t sourceID,
529  uint8_t packetCode) const {
530  //deal with disabled FE units and channels properly (FE enables, status bits)
532  std::unique_ptr<FEDFEHeader> fedFeHeader(defaultFEHeader_->clone());
533  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
534  const bool enabled = feUnitsEnabled_[iFE];
535  tkSpecialHeader.setFEEnableForFEUnit(iFE, enabled);
536  if (!enabled) {
537  for (uint8_t iFEUnitChannel = 0; iFEUnitChannel < FEDCH_PER_FEUNIT; iFEUnitChannel++) {
538  fedFeHeader->setChannelStatus(iFE, iFEUnitChannel, FEDChannelStatus(0));
539  }
540  }
541  }
542  for (uint8_t iCh = 0; iCh < FEDCH_PER_FED; iCh++) {
543  if (!channelsEnabled_[iCh]) {
544  fedFeHeader->setChannelStatus(iCh, FEDChannelStatus(0));
545  }
546  }
547  //set the source ID
549  daqHeader.setSourceID(sourceID);
550  //build payload
552  const FEDBufferPayload payload = payloadPacker(getReadoutMode(), packetCode, data);
553  //fill FE lengths
554  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
555  fedFeHeader->setFEUnitLength(iFE, payload.getFELength(iFE));
556  }
557  //resize buffer
558  rawDataObject->resize(bufferSizeInBytes(*fedFeHeader, payload));
559  //fill buffer
560  fillBuffer(rawDataObject->data(), daqHeader, defaultDAQTrailer_, tkSpecialHeader, *fedFeHeader, payload);
561  }
562 
563  void FEDBufferGenerator::fillBuffer(uint8_t* pointerToStartOfBuffer,
564  const FEDDAQHeader& daqHeader,
565  const FEDDAQTrailer& daqTrailer,
566  const TrackerSpecialHeader& tkSpecialHeader,
567  const FEDFEHeader& feHeader,
568  const FEDBufferPayload& payload) {
569  //set the length in the DAQ trailer
570  const size_t lengthInBytes = bufferSizeInBytes(feHeader, payload);
571  FEDDAQTrailer updatedDAQTrailer(daqTrailer);
572  updatedDAQTrailer.setEventLengthIn64BitWords(lengthInBytes / 8);
573  //copy pieces into buffer in order
574  uint8_t* bufferPointer = pointerToStartOfBuffer;
575  memcpy(bufferPointer, daqHeader.data(), 8);
576  bufferPointer += 8;
577  memcpy(bufferPointer, tkSpecialHeader.data(), 8);
578  bufferPointer += 8;
579  memcpy(bufferPointer, feHeader.data(), feHeader.lengthInBytes());
580  bufferPointer += feHeader.lengthInBytes();
581  memcpy(bufferPointer, payload.data(), payload.lengthInBytes());
582  bufferPointer += payload.lengthInBytes();
583  memcpy(bufferPointer, updatedDAQTrailer.data(), 8);
584  //update CRC
585  const uint16_t crc = calculateFEDBufferCRC(pointerToStartOfBuffer, lengthInBytes);
586  updatedDAQTrailer.setCRC(crc);
587  memcpy(bufferPointer, updatedDAQTrailer.data(), 8);
588  //word swap if necessary
589  if (tkSpecialHeader.wasSwapped()) {
590  for (size_t i = 0; i < 8; i++) {
591  bufferPointer[i] = bufferPointer[i ^ 4];
592  }
593  }
594  }
595 
596 } // namespace sistrip
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
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
const uint8_t * data() const
constexpr int32_t ceil(float num)
sistrip classes
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
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
static const uint8_t PACKET_CODE_VIRGIN_RAW10
const uint8_t * data() const
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED
TrackerSpecialHeader & setFEEnableForFEUnit(const uint8_t internalFEUnitNum, const bool enabled)
FEDDAQTrailer & setEventLengthIn64BitWords(const uint32_t eventLengthIn64BitWords)
FEDBufferGenerator & setFEUnitEnables(const std::vector< bool > &feUnitsEnabled)
FEDDAQTrailer & setCRC(const uint16_t crc)
void resize(size_t newsize)
Definition: FEDRawData.cc:28
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
uint16_t getFELength(const uint8_t internalFEUnitNum) const
void generateBuffer(FEDRawData *rawDataObject, const FEDStripData &data, uint16_t sourceID, uint8_t packetCode) const
#define end
Definition: vmac.h:39
Definition: value.py:1
constexpr int adc(sample_type sample)
get the ADC sample (12 bits)
virtual const uint8_t * data() const =0
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
FEDDAQHeader & setSourceID(const uint16_t sourceID)
FEDBufferGenerator & setFEUnitEnable(const uint8_t internalFEUnitNumber, const bool enabled)
virtual size_t lengthInBytes() const =0
bool getFEUnitEnabled(const uint8_t internalFEUnitNumber) const
#define begin
Definition: vmac.h:32
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
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.
Definition: FEDRawData.cc:24
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_
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
static const uint8_t PACKET_CODE_VIRGIN_RAW