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  {
14  if (samplesPerChannel > SCOPE_MODE_MAX_SCOPE_LENGTH) {
15  std::ostringstream ss;
16  ss << "Scope length " << samplesPerChannel << " is too long. "
17  << "Max scope length is " << SCOPE_MODE_MAX_SCOPE_LENGTH << ".";
18  throw cms::Exception("FEDBufferGenerator") << ss.str();
19  }
20  }
21 
23  {
24  try {
25  return data_.at(internalFEDChannelNum);
26  } catch (const std::out_of_range&) {
27  std::ostringstream ss;
28  ss << "Channel index out of range. (" << uint16_t(internalFEDChannelNum) << ") "
29  << "Index should be in internal numbering scheme (0-95). ";
30  throw cms::Exception("FEDBufferGenerator") << ss.str();
31  }
32  }
33 
34  void FEDStripData::ChannelData::setSample(const uint16_t sampleNumber, const uint16_t value)
35  {
36  if (value > 0x3FF) {
37  std::ostringstream ss;
38  ss << "Sample value (" << value << ") is too large. Maximum allowed is 1023. ";
39  throw cms::Exception("FEDBufferGenerator") << ss.str();
40  }
41  try {
42  data_.at(sampleNumber) = value;
43  } catch (const std::out_of_range&) {
44  std::ostringstream ss;
45  ss << "Sample index out of range. "
46  << "Requesting sample " << sampleNumber
47  << " when channel has only " << data_.size() << " samples.";
48  throw cms::Exception("FEDBufferGenerator") << ss.str();
49  }
50  }
51 
52  //FEDBufferPayload
53 
54  FEDBufferPayload::FEDBufferPayload(const std::vector< std::vector<uint8_t> >& channelBuffers)
55  {
56  //calculate size of buffer and allocate enough memory
57  uint32_t totalSize = 0;
58  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
59  for (uint8_t iCh = 0; iCh < FEDCH_PER_FEUNIT; iCh++) {
60  totalSize += channelBuffers[iFE*FEDCH_PER_FEUNIT+iCh].size();
61  }
62  //if it does not finish on a 64Bit word boundary then take into account padding
63  if (totalSize%8) {
64  totalSize = ((totalSize/8) + 1)*8;
65  }
66  }
67  data_.resize(totalSize);
68  size_t indexInBuffer = 0;
69  feLengths_.reserve(FEUNITS_PER_FED);
70  //copy channel data into buffer with padding and update lengths
71  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
72  const size_t lengthAtStartOfFEUnit = indexInBuffer;
73  //insert data for FE unit
74  for (uint8_t iCh = 0; iCh < FEDCH_PER_FEUNIT; iCh++) {
75  appendToBuffer(&indexInBuffer,channelBuffers[iFE*FEDCH_PER_FEUNIT+iCh].begin(),channelBuffers[iFE*FEDCH_PER_FEUNIT+iCh].end());
76  }
77  //store length
78  feLengths_.push_back(indexInBuffer-lengthAtStartOfFEUnit);
79  //add padding
80  while (indexInBuffer % 8) appendToBuffer(&indexInBuffer,0);
81  }
82  }
83 
84  const uint8_t* FEDBufferPayload::data() const
85  {
86  //vectors are guarenteed to be contiguous
87  if (lengthInBytes()) return &data_[0];
88  //return NULL if there is no data yet
89  else return nullptr;
90  }
91 
92  uint16_t FEDBufferPayload::getFELength(const uint8_t internalFEUnitNum) const
93  {
94  try{
95  return feLengths_.at(internalFEUnitNum);
96  } catch (const std::out_of_range&) {
97  std::ostringstream ss;
98  ss << "Invalid FE unit number " << internalFEUnitNum << ". "
99  << "Number should be in internal numbering scheme (0-7). ";
100  throw cms::Exception("FEDBufferGenerator") << ss.str();
101  }
102  }
103 
105  {
106  std::vector< std::vector<uint8_t> > channelBuffers(FEDCH_PER_FED,std::vector<uint8_t>());
107  for (size_t iCh = 0; iCh < FEDCH_PER_FED; iCh++) {
108  if (!feUnitsEnabled_[iCh/FEDCH_PER_FEUNIT]) 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, FEDReadoutMode mode, uint8_t packetCode, const FEDStripData::ChannelData& data, const bool channelEnabled) const
115  {
116  switch (mode) {
117  case READOUT_MODE_SCOPE:
118  fillRawChannelBuffer(channelBuffer,PACKET_CODE_SCOPE,data,channelEnabled,false);
119  break;
121  switch (packetCode) {
123  fillRawChannelBuffer(channelBuffer,PACKET_CODE_VIRGIN_RAW,data,channelEnabled,true);
124  break;
126  fillRawChannelBuffer(channelBuffer,PACKET_CODE_VIRGIN_RAW10,data,channelEnabled,true);
127  break;
129  fillRawChannelBuffer(channelBuffer,PACKET_CODE_VIRGIN_RAW8_BOTBOT,data,channelEnabled,true);
130  break;
132  fillRawChannelBuffer(channelBuffer,PACKET_CODE_VIRGIN_RAW8_TOPBOT,data,channelEnabled,true);
133  break;
134  }
135  break;
137  fillRawChannelBuffer(channelBuffer,PACKET_CODE_PROC_RAW,data,channelEnabled,false);
138  break;
140  //case READOUT_MODE_ZERO_SUPPRESSED_CMOVERRIDE:
141  fillZeroSuppressedChannelBuffer(channelBuffer,packetCode,data,channelEnabled);
142  break;
151  fillZeroSuppressedLiteChannelBuffer(channelBuffer,data,channelEnabled,mode);
152  break;
154  fillPreMixRawChannelBuffer(channelBuffer,data,channelEnabled);
155  break;
156  default:
157  std::ostringstream ss;
158  ss << "Invalid readout mode " << mode;
159  throw cms::Exception("FEDBufferGenerator") << ss.str();
160  break;
161  }
162  }
163 
164  void FEDBufferPayloadCreator::fillRawChannelBuffer(std::vector<uint8_t>* channelBuffer,
165  const uint8_t packetCode,
167  const bool channelEnabled,
168  const bool reorderData) const
169  {
170  const uint16_t nSamples = data.size();
171  uint16_t channelLength = 0;
172  switch (packetCode) {
174  channelLength = nSamples*2 + 3;
175  break;
177  channelLength = std::ceil(nSamples*1.25) + 3;
178  break;
181  channelLength = nSamples*1 + 3;
182  break;
183  }
184  channelBuffer->reserve(channelLength);
185  //length (max length is 0xFFF)
186  channelBuffer->push_back( channelLength & 0xFF );
187  channelBuffer->push_back( (channelLength & 0xF00) >> 8 );
188  //packet code
189  channelBuffer->push_back(packetCode);
190  //channel samples
191  uint16_t sampleValue_pre = 0;
192  for (uint16_t sampleNumber = 0; sampleNumber < nSamples; sampleNumber++) {
193  const uint16_t sampleIndex = ( reorderData ? FEDStripOrdering::physicalOrderForStripInChannel(sampleNumber) : sampleNumber );
194  const uint16_t sampleValue = (channelEnabled ? data.getSample(sampleIndex) : 0);
195  switch (packetCode) {
197  channelBuffer->push_back(sampleValue & 0xFF);
198  channelBuffer->push_back((sampleValue & 0x300) >> 8);
199  break;
201  if (sampleNumber%4==0) {
202  channelBuffer->push_back((sampleValue & 0x3FC) >> 2);
203  }
204  else if (sampleNumber%4==1) {
205  channelBuffer->push_back(((sampleValue_pre & 0x3) << 6) | ((sampleValue & 0x3F0) >> 4));
206  }
207  else if (sampleNumber%4==2) {
208  channelBuffer->push_back(((sampleValue_pre & 0xF) << 4) | ((sampleValue & 0x3C0) >> 6));
209  }
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  {
231  channelBuffer->reserve(50);
232  //if channel is disabled then create empty channel header and return
233  if (!channelEnabled) {
234  //min length 7
235  channelBuffer->push_back(7);
236  channelBuffer->push_back(0);
237  //packet code
238  channelBuffer->push_back(packetCode);
239  //4 bytes of medians
240  channelBuffer->insert(channelBuffer->end(),4,0);
241  return;
242  }
243  //if channel is not empty
244  //add space for channel length
245  channelBuffer->push_back(0xFF);
246  channelBuffer->push_back(0xFF);
247  //packet code
248  channelBuffer->push_back(packetCode);
249  //add medians
250  const std::pair<uint16_t,uint16_t> medians = data.getMedians();
251  channelBuffer->push_back(medians.first & 0xFF);
252  channelBuffer->push_back((medians.first & 0x300) >> 8);
253  channelBuffer->push_back(medians.second & 0xFF);
254  channelBuffer->push_back((medians.second & 0x300) >> 8);
255  //clusters
256  fillClusterData(channelBuffer, packetCode, data, READOUT_MODE_ZERO_SUPPRESSED);
257  //set length
258  const uint16_t length = channelBuffer->size();
259  (*channelBuffer)[0] = (length & 0xFF);
260  (*channelBuffer)[1] = ((length & 0x300) >> 8);
261  }
262 
263  void FEDBufferPayloadCreator::fillZeroSuppressedLiteChannelBuffer(std::vector<uint8_t>* channelBuffer,
265  const bool channelEnabled,
266  const FEDReadoutMode mode) const
267  {
268  channelBuffer->reserve(50);
269  //if channel is disabled then create empty channel header and return
270  if (!channelEnabled) {
271  //min length 2
272  channelBuffer->push_back(2);
273  channelBuffer->push_back(0);
274  return;
275  }
276  //if channel is not empty
277  //add space for channel length
278  channelBuffer->push_back(0xFF);
279  channelBuffer->push_back(0xFF);
280  //clusters
281  fillClusterData(channelBuffer, 0, data, mode);
282  //set fibre length
283  const uint16_t length = channelBuffer->size();
284  (*channelBuffer)[0] = (length & 0xFF);
285  (*channelBuffer)[1] = ((length & 0x300) >> 8);
286  }
287 
288  void FEDBufferPayloadCreator::fillPreMixRawChannelBuffer(std::vector<uint8_t>* channelBuffer,
290  const bool channelEnabled) const
291  {
292  channelBuffer->reserve(50);
293  //if channel is disabled then create empty channel header and return
294  if (!channelEnabled) {
295  //min length 7
296  channelBuffer->push_back(7);
297  channelBuffer->push_back(0);
298  //packet code
299  channelBuffer->push_back(PACKET_CODE_ZERO_SUPPRESSED);
300  //4 bytes of medians
301  channelBuffer->insert(channelBuffer->end(),4,0);
302  return;
303  }
304  //if channel is not empty
305  //add space for channel length
306  channelBuffer->push_back(0xFF); channelBuffer->push_back(0xFF);
307  //packet code
308  channelBuffer->push_back(PACKET_CODE_ZERO_SUPPRESSED);
309  //add medians
310  const std::pair<uint16_t,uint16_t> medians = data.getMedians();
311  channelBuffer->push_back(medians.first & 0xFF);
312  channelBuffer->push_back((medians.first & 0x300) >> 8);
313  channelBuffer->push_back(medians.second & 0xFF);
314  channelBuffer->push_back((medians.second & 0x300) >> 8);
315  //clusters
316  fillClusterDataPreMixMode(channelBuffer,data);
317  //set length
318  const uint16_t length = channelBuffer->size();
319  (*channelBuffer)[0] = (length & 0xFF);
320  (*channelBuffer)[1] = ((length & 0x300) >> 8);
321  }
322 
323  void FEDBufferPayloadCreator::fillClusterData(std::vector<uint8_t>* channelBuffer, uint8_t packetCode, const FEDStripData::ChannelData& data, const FEDReadoutMode mode) const
324  {
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 ? 2
346  : ( packetCode == PACKET_CODE_ZERO_SUPPRESSED8_TOPBOT ? 1 : 0 ) );
347 
348  uint16_t clusterSize = 0; // counter
349  std::size_t size_pos = 0; // index of cluster size
350  uint16_t adc_pre = 0;
351  const uint16_t nSamples = data.size();
352  for( uint16_t strip = 0; strip < nSamples; ++strip) {
353  const uint16_t adc = is10Bit ? data.get10BitSample(strip) : data.get8BitSample(strip, bShift);
354  if (adc) {
355  if ( clusterSize==0 || strip == STRIPS_PER_APV ) {
356  if (clusterSize) {
357  if ( is10Bit && (clusterSize%4) ) { channelBuffer->push_back(adc_pre); }
358  (*channelBuffer)[size_pos] = clusterSize;
359  clusterSize = 0;
360  }
361  // cluster header: first strip and size
362  channelBuffer->push_back(strip);
363  size_pos = channelBuffer->size();
364  channelBuffer->push_back(0); // for clustersize
365  }
366  if ( ! is10Bit ) {
367  channelBuffer->push_back(adc & 0xFF);
368  } else {
369  if (clusterSize%4==0) {
370  channelBuffer->push_back((adc & 0x3FC) >> 2);
371  adc_pre = ((adc & 0x3) << 6);
372  } else if (clusterSize%4==1) {
373  channelBuffer->push_back(adc_pre | ((adc & 0x3F0) >> 4));
374  adc_pre = ((adc & 0xF) << 4);
375  } else if (clusterSize%4==2) {
376  channelBuffer->push_back(adc_pre | ((adc & 0x3C0) >> 6));
377  adc_pre = ((adc & 0x3F) << 2);
378  } else if (clusterSize%4==3) {
379  channelBuffer->push_back(adc_pre | ((adc & 0x300) >> 8));
380  channelBuffer->push_back(adc & 0xFF);
381  adc_pre = 0;
382  }
383  }
384  ++clusterSize;
385  }
386  else if (clusterSize) {
387  if ( is10Bit && (clusterSize%4) ) { channelBuffer->push_back(adc_pre); }
388  (*channelBuffer)[size_pos] = clusterSize;
389  clusterSize = 0;
390  }
391  }
392  if(clusterSize) {
393  (*channelBuffer)[size_pos] = clusterSize;
394  if ( is10Bit && (clusterSize%4) ) { channelBuffer->push_back(adc_pre); }
395  }
396  }
397 
398  void FEDBufferPayloadCreator::fillClusterDataPreMixMode(std::vector<uint8_t>* channelBuffer, const FEDStripData::ChannelData& data) const
399  {
400  uint16_t clusterSize = 0;
401  const uint16_t nSamples = data.size();
402  for( uint16_t strip = 0; strip < nSamples; ++strip) {
403  const uint16_t adc = data.get10BitSample(strip);
404 
405  if(adc) {
406  if( clusterSize==0 || strip == STRIPS_PER_APV ) {
407  if(clusterSize) {
408  *(channelBuffer->end() - 2*clusterSize - 1) = clusterSize ;
409  clusterSize = 0;
410  }
411  channelBuffer->push_back(strip);
412  channelBuffer->push_back(0); //clustersize
413  }
414  channelBuffer->push_back(adc & 0xFF);
415  channelBuffer->push_back((adc & 0x0300) >> 8);
416 
417  ++clusterSize;
418  }
419 
420  else if(clusterSize) {
421  *(channelBuffer->end() - 2*clusterSize - 1) = clusterSize ;
422  clusterSize = 0;
423  }
424  }
425  if(clusterSize) {
426  *(channelBuffer->end() - 2*clusterSize - 1) = clusterSize ;
427  }
428  }
429 
430  //FEDBufferGenerator
431 
432  FEDBufferGenerator::FEDBufferGenerator(const uint32_t l1ID, const uint16_t bxID,
433  const std::vector<bool>& feUnitsEnabled, const std::vector<bool>& channelsEnabled,
434  const FEDReadoutMode readoutMode, const FEDHeaderType headerType, const FEDBufferFormat bufferFormat,
435  const FEDDAQEventType evtType)
436  : defaultDAQHeader_(l1ID,bxID,0,evtType),
437  defaultDAQTrailer_(0,0),
438  defaultTrackerSpecialHeader_(bufferFormat,readoutMode,headerType),
439  defaultFEHeader_(FEDFEHeader::newFEHeader(headerType)),
440  feUnitsEnabled_(feUnitsEnabled),
441  channelsEnabled_(channelsEnabled)
442  {
443  if (!defaultFEHeader_.get()) {
444  std::ostringstream ss;
445  ss << "Bad header format: " << headerType;
446  throw cms::Exception("FEDBufferGenerator") << ss.str();
447  }
448  }
449 
450  bool FEDBufferGenerator::getFEUnitEnabled(const uint8_t internalFEUnitNumber) const
451  {
452  try {
453  return feUnitsEnabled_.at(internalFEUnitNumber);
454  } catch (const std::out_of_range&) {
455  std::ostringstream ss;
456  ss << "Invalid FE unit number " << internalFEUnitNumber << ". Should be in internal numbering scheme (0-7)";
457  throw cms::Exception("FEDBufferGenerator") << ss.str();
458  }
459  }
460 
461  bool FEDBufferGenerator::getChannelEnabled(const uint8_t internalFEDChannelNumber) const
462  {
463  try {
464  return channelsEnabled_.at(internalFEDChannelNumber);
465  } catch (const std::out_of_range&) {
466 
467  std::ostringstream ss;
468  ss << "Invalid channel number " << internalFEDChannelNumber << ". "
469  << "Should be in internal numbering scheme (0-95)";
470  throw cms::Exception("FEDBufferGenerator") << ss.str();
471  }
472  }
473 
474  FEDBufferGenerator& FEDBufferGenerator::setFEUnitEnable(const uint8_t internalFEUnitNumber, const bool enabled)
475  {
476  try {
477  feUnitsEnabled_.at(internalFEUnitNumber) = enabled;
478  } catch (const std::out_of_range&) {
479  std::ostringstream ss;
480  ss << "Invalid FE unit number " << internalFEUnitNumber << ". "
481  << "Should be in internal numbering scheme (0-7)";
482  throw cms::Exception("FEDBufferGenerator") << ss.str();
483  }
484  return *this;
485  }
486 
487  FEDBufferGenerator& FEDBufferGenerator::setChannelEnable(const uint8_t internalFEDChannelNumber, const bool enabled)
488  {
489  try {
490  channelsEnabled_.at(internalFEDChannelNumber) = enabled;
491  } catch (const std::out_of_range&) {
492  std::ostringstream ss;
493  ss << "Invalid channel number " << internalFEDChannelNumber << ". "
494  <<"Should be in internal numbering scheme (0-95)";
495  throw cms::Exception("FEDBufferGenerator") << ss.str();
496  }
497  return *this;
498  }
499 
500  FEDBufferGenerator& FEDBufferGenerator::setFEUnitEnables(const std::vector<bool>& feUnitEnables)
501  {
502  if (feUnitEnables.size() != FEUNITS_PER_FED) {
503  std::ostringstream ss;
504  ss << "Setting FE enable vector with vector which is the wrong size. Size is " << feUnitEnables.size()
505  << " it must be " << FEUNITS_PER_FED << "." << std::endl;
506  throw cms::Exception("FEDBufferGenerator") << ss.str();
507  }
508  feUnitsEnabled_ = feUnitEnables;
509  return *this;
510  }
511 
512  FEDBufferGenerator& FEDBufferGenerator::setChannelEnables(const std::vector<bool>& channelEnables)
513  {
514  if (channelEnables.size() != FEDCH_PER_FED) {
515  std::ostringstream ss;
516  ss << "Setting FED channel enable vector with vector which is the wrong size. Size is " << channelEnables.size()
517  << " it must be " << FEDCH_PER_FED << "." << std::endl;
518  throw cms::Exception("FEDBufferGenerator") << ss.str();
519  }
520  channelsEnabled_ = channelEnables;
521  return *this;
522  }
523 
524  void FEDBufferGenerator::generateBuffer(FEDRawData* rawDataObject, const FEDStripData& data, uint16_t sourceID, uint8_t packetCode) const
525  {
526  //deal with disabled FE units and channels properly (FE enables, status bits)
528  std::unique_ptr<FEDFEHeader> fedFeHeader(defaultFEHeader_->clone());
529  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
530  const bool enabled = feUnitsEnabled_[iFE];
531  tkSpecialHeader.setFEEnableForFEUnit(iFE,enabled);
532  if (!enabled) {
533  for (uint8_t iFEUnitChannel = 0; iFEUnitChannel < FEDCH_PER_FEUNIT; iFEUnitChannel++) {
534  fedFeHeader->setChannelStatus(iFE,iFEUnitChannel,FEDChannelStatus(0));
535  }
536  }
537  }
538  for (uint8_t iCh = 0; iCh < FEDCH_PER_FED; iCh++) {
539  if (!channelsEnabled_[iCh]) {
540  fedFeHeader->setChannelStatus(iCh,FEDChannelStatus(0));
541  }
542  }
543  //set the source ID
545  daqHeader.setSourceID(sourceID);
546  //build payload
548  const FEDBufferPayload payload = payloadPacker(getReadoutMode(), packetCode, data);
549  //fill FE lengths
550  for (uint8_t iFE = 0; iFE < FEUNITS_PER_FED; iFE++) {
551  fedFeHeader->setFEUnitLength(iFE,payload.getFELength(iFE));
552  }
553  //resize buffer
554  rawDataObject->resize(bufferSizeInBytes(*fedFeHeader,payload));
555  //fill buffer
556  fillBuffer(rawDataObject->data(), daqHeader, defaultDAQTrailer_, tkSpecialHeader, *fedFeHeader, payload);
557  }
558 
559  void FEDBufferGenerator::fillBuffer(uint8_t* pointerToStartOfBuffer,
560  const FEDDAQHeader& daqHeader,
561  const FEDDAQTrailer& daqTrailer,
562  const TrackerSpecialHeader& tkSpecialHeader,
563  const FEDFEHeader& feHeader,
564  const FEDBufferPayload& payload)
565  {
566  //set the length in the DAQ trailer
567  const size_t lengthInBytes = bufferSizeInBytes(feHeader,payload);
568  FEDDAQTrailer updatedDAQTrailer(daqTrailer);
569  updatedDAQTrailer.setEventLengthIn64BitWords(lengthInBytes/8);
570  //copy pieces into buffer in order
571  uint8_t* bufferPointer = pointerToStartOfBuffer;
572  memcpy(bufferPointer,daqHeader.data(),8);
573  bufferPointer += 8;
574  memcpy(bufferPointer,tkSpecialHeader.data(),8);
575  bufferPointer += 8;
576  memcpy(bufferPointer,feHeader.data(),feHeader.lengthInBytes());
577  bufferPointer += feHeader.lengthInBytes();
578  memcpy(bufferPointer,payload.data(),payload.lengthInBytes());
579  bufferPointer += payload.lengthInBytes();
580  memcpy(bufferPointer,updatedDAQTrailer.data(),8);
581  //update CRC
582  const uint16_t crc = calculateFEDBufferCRC(pointerToStartOfBuffer,lengthInBytes);
583  updatedDAQTrailer.setCRC(crc);
584  memcpy(bufferPointer,updatedDAQTrailer.data(),8);
585  //word swap if necessary
586  if (tkSpecialHeader.wasSwapped()) {
587  for (size_t i = 0; i < 8; i++) {
588  bufferPointer[i] = bufferPointer[i^4];
589  }
590  }
591  }
592 
593 }
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
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:32
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)
constexpr size_t nSamples
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:82
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:28
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