CMS 3D CMS Logo

SiStripFEDBuffer.h
Go to the documentation of this file.
1 #ifndef EventFilter_SiStripRawToDigi_SiStripFEDBuffer_H
2 #define EventFilter_SiStripRawToDigi_SiStripFEDBuffer_H
3 
4 #include "boost/cstdint.hpp"
5 #include <string>
6 #include <vector>
7 #include <memory>
8 #include <ostream>
9 #include <cstring>
10 #include <cmath>
12 
14 
15 namespace sistrip {
16 
17  //
18  // Class definitions
19  //
20 
21  //class representing standard (non-spy channel) FED buffers
22  class FEDBuffer final : public FEDBufferBase
23  {
24  public:
25  //construct from buffer
26  //if allowBadBuffer is set to true then exceptions will not be thrown if the channel lengths do not make sense or the event format is not recognized
27  FEDBuffer(const uint8_t* fedBuffer, const uint16_t fedBufferSize, const bool allowBadBuffer = false);
28  ~FEDBuffer() override;
29  void print(std::ostream& os) const override;
30  const FEDFEHeader* feHeader() const;
31  //check that a FE unit is enabled, has a good majority address and, if in full debug mode, that it is present
32  bool feGood(const uint8_t internalFEUnitNum) const;
33  bool feGoodWithoutAPVEmulatorCheck(const uint8_t internalFEUnitNum) const;
34  //check that a FE unit is present in the data.
35  //The high order byte of the FEDStatus register in the tracker special header is used in APV error mode.
36  //The FE length from the full debug header is used in full debug mode.
37  bool fePresent(uint8_t internalFEUnitNum) const;
38  //check that a channel is present in data, found, on a good FE unit and has no errors flagged in status bits
40  virtual bool channelGood(const uint8_t internalFEDannelNum, const bool doAPVeCheck=true) const;
41  void setLegacyMode(bool legacy) { legacyUnpacker_ = legacy;}
42 
43  //functions to check buffer. All return true if there is no problem.
44  //minimum checks to do before using buffer
46  virtual bool doChecks(bool doCRC=true) const;
47 
48  //additional checks to check for corrupt buffers
49  //check channel lengths fit inside to buffer length
50  bool checkChannelLengths() const;
51  //check that channel lengths add up to buffer length (this does the previous check as well)
53  //check channel packet codes match readout mode
54  bool checkChannelPacketCodes() const;
55  //check FE unit lengths in FULL DEBUG header match the lengths of their channels
56  bool checkFEUnitLengths() const;
57  //check FE unit APV addresses in FULL DEBUG header are equal to the APVe address if the majority was good
58  bool checkFEUnitAPVAddresses() const;
59  //do all corrupt buffer checks
60  virtual bool doCorruptBufferChecks() const;
61 
62  //check that there are no errors in channel, APV or FEUnit status bits
63  //these are done by channelGood(). Channels with bad status bits may be disabled so bad status bits do not usually indicate an error
64  bool checkStatusBits(const uint8_t internalFEDChannelNum) const;
65  bool checkStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalChannelNum) const;
66  //same but for all channels on enabled FE units
67  bool checkAllChannelStatusBits() const;
68 
69  //check that all FE unit payloads are present
70  bool checkFEPayloadsPresent() const;
71 
72  //print a summary of all checks
73  std::string checkSummary() const override;
74  private:
75  uint8_t nFEUnitsPresent() const;
76  void findChannels();
77  inline uint8_t getCorrectPacketCode() const { return packetCode(legacyUnpacker_); }
78  uint16_t calculateFEUnitLength(const uint8_t internalFEUnitNumber) const;
79  std::auto_ptr<FEDFEHeader> feHeader_;
80  const uint8_t* payloadPointer_;
81  uint16_t payloadLength_;
82  uint8_t validChannels_;
84  bool legacyUnpacker_=false;
85  };
86 
87  //class for unpacking data from ZS FED channels
89  {
90  public:
91  static FEDZSChannelUnpacker zeroSuppressedModeUnpacker(const FEDChannel& channel);
92  static FEDZSChannelUnpacker zeroSuppressedLiteModeUnpacker(const FEDChannel& channel);
93  static FEDZSChannelUnpacker preMixRawModeUnpacker(const FEDChannel& channel);
95  uint8_t sampleNumber() const;
96  uint8_t adc() const;
97  uint16_t adcPreMix() const;
98  bool hasData() const;
99  FEDZSChannelUnpacker& operator ++ ();
100  FEDZSChannelUnpacker& operator ++ (int);
101  private:
102  //pointer to beginning of FED or FE data, offset of start of channel payload in data and length of channel payload
103  FEDZSChannelUnpacker(const uint8_t* payload, const uint16_t channelPayloadOffset, const int16_t channelPayloadLength, const uint16_t offsetIncrement=1);
104  void readNewClusterInfo();
105  static void throwBadChannelLength(const uint16_t length);
106  void throwBadClusterLength();
107  static void throwUnorderedData(const uint8_t currentStrip, const uint8_t firstStripOfNewCluster);
108  const uint8_t* data_;
109  uint16_t currentOffset_;
111  uint8_t currentStrip_;
115  };
116 
117  //class for unpacking data from raw FED channels
119  {
120  public:
124  explicit FEDRawChannelUnpacker(const FEDChannel& channel);
125  uint8_t sampleNumber() const;
126  uint16_t adc() const;
127  bool hasData() const;
128  FEDRawChannelUnpacker& operator ++ ();
129  FEDRawChannelUnpacker& operator ++ (int);
130  private:
131  static void throwBadChannelLength(const uint16_t length);
132  const uint8_t* data_;
133  uint16_t currentOffset_;
134  uint8_t currentStrip_;
135  uint16_t valuesLeft_;
136  };
137 
138  //class for unpacking data from any FED channels with a non-integer words bits stripping mode
140  {
141  public:
142  static FEDBSChannelUnpacker virginRawModeUnpacker(const FEDChannel& channel, uint16_t num_bits);
143  static FEDBSChannelUnpacker zeroSuppressedModeUnpacker(const FEDChannel& channel, uint16_t num_bits);
144  static FEDBSChannelUnpacker zeroSuppressedLiteModeUnpacker(const FEDChannel& channel, uint16_t num_bits);
146  uint8_t sampleNumber() const;
147  uint16_t adc() const;
148  bool hasData() const;
149  FEDBSChannelUnpacker& operator ++ ();
150  FEDBSChannelUnpacker& operator ++ (int);
151  private:
152  //pointer to beginning of FED or FE data, offset of start of channel payload in data and length of channel payload
153  FEDBSChannelUnpacker(const uint8_t* payload, const uint16_t channelPayloadOffset, const int16_t channelPayloadLength, const uint16_t offsetIncrement, bool useZS);
154  void readNewClusterInfo();
155  static void throwBadChannelLength(const uint16_t length);
156  static void throwBadWordLength(const uint16_t word_length);
157  static void throwUnorderedData(const uint8_t currentStrip, const uint8_t firstStripOfNewCluster);
158  const uint8_t* data_;
159  uint16_t oldWordOffset_;
164  uint8_t currentStrip_;
167  bool useZS_;
169  };
170 
171  //
172  // Inline function definitions
173  //
174 
175  //FEDBuffer
176 
177  inline const FEDFEHeader* FEDBuffer::feHeader() const
178  {
179  return feHeader_.get();
180  }
181 
182  inline bool FEDBuffer::feGood(const uint8_t internalFEUnitNum) const
183  {
184  return ( !majorityAddressErrorForFEUnit(internalFEUnitNum) && !feOverflow(internalFEUnitNum) && fePresent(internalFEUnitNum) );
185  }
186 
187  inline bool FEDBuffer::feGoodWithoutAPVEmulatorCheck(const uint8_t internalFEUnitNum) const
188  {
189  return ( !feOverflow(internalFEUnitNum) && fePresent(internalFEUnitNum) );
190  }
191 
192  inline bool FEDBuffer::fePresent(uint8_t internalFEUnitNum) const
193  {
194  return fePresent_[internalFEUnitNum];
195  }
196 
197  inline bool FEDBuffer::checkStatusBits(const uint8_t internalFEDChannelNum) const
198  {
199  return feHeader_->checkChannelStatusBits(internalFEDChannelNum);
200  }
201 
202  inline bool FEDBuffer::checkStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalChannelNum) const
203  {
204  return checkStatusBits(internalFEDChannelNum(internalFEUnitNum,internalChannelNum));
205  }
206 
207  //FEDBSChannelUnpacker
208 
210  : data_(nullptr),
211  oldWordOffset_(0), currentWordOffset_(0),
212  currentBitOffset_(0), currentLocalBitOffset_(0),
213  bitOffsetIncrement_(10),
214  currentStrip_(0),
215  channelPayloadOffset_(0), channelPayloadLength_(0),
216  useZS_(false), valuesLeftInCluster_(0)
217  { }
218 
219  inline FEDBSChannelUnpacker::FEDBSChannelUnpacker(const uint8_t* payload, const uint16_t channelPayloadOffset, const int16_t channelPayloadLength, const uint16_t offsetIncrement, bool useZS)
220  : data_(payload),
221  oldWordOffset_(0), currentWordOffset_(channelPayloadOffset),
223  bitOffsetIncrement_(offsetIncrement),
224  channelPayloadOffset_(channelPayloadOffset),
225  channelPayloadLength_(channelPayloadLength),
226  useZS_(useZS), valuesLeftInCluster_(0)
227  {
228  if (bitOffsetIncrement_>16) throwBadWordLength(bitOffsetIncrement_); // more than 2 words... still to be implemented
229  }
230 
232  {
233  uint16_t length = channel.length();
234  if (length & 0xF000) throwBadChannelLength(length);
235  if (num_bits<=0 or num_bits>16) throwBadWordLength(num_bits);
236  FEDBSChannelUnpacker result(channel.data(), channel.offset()+3, length-3, num_bits, false);
237  return result;
238  }
239 
241  {
242  uint16_t length = channel.length();
243  if (length & 0xF000) throwBadChannelLength(length);
244  FEDBSChannelUnpacker result(channel.data(), channel.offset()+7, length-7, num_bits, true);
245  return result;
246  }
247 
249  {
250  uint16_t length = channel.length();
251  if (length & 0xF000) throwBadChannelLength(length);
252  FEDBSChannelUnpacker result(channel.data(), channel.offset()+2, length-2, num_bits, true);
253  return result;
254  }
255 
256  inline uint8_t FEDBSChannelUnpacker::sampleNumber() const
257  {
258  return currentStrip_;
259  }
260 
261  inline uint16_t FEDBSChannelUnpacker::adc() const
262  {
263  uint16_t bits_missing = (bitOffsetIncrement_-8)+currentLocalBitOffset_;
264  uint16_t adc = (data_[currentWordOffset_^7]<<bits_missing);
266  adc += ( (data_[(currentWordOffset_+1)^7]>>(8-bits_missing)) );
267  }
268  return (adc&((1<<bitOffsetIncrement_)-1));
269  }
270 
271  inline bool FEDBSChannelUnpacker::hasData() const
272  {
274  }
275 
277  {
281  while (currentLocalBitOffset_>=8) {
284  }
285  if (useZS_) {
287  else {
288  if (hasData()) {
289  const uint8_t oldStrip = currentStrip_;
291  if ( !(currentStrip_ > oldStrip) ) throwUnorderedData(oldStrip,currentStrip_);
292  }
293  }
294  } else { currentStrip_++; }
295  return (*this);
296  }
297 
299  {
300  ++(*this); return *this;
301  }
302 
304  {
307  }
308 
309 
310  //FEDRawChannelUnpacker
311 
313  : data_(channel.data()),
314  currentOffset_(channel.offset()+3),
315  currentStrip_(0),
316  valuesLeft_((channel.length()-3)/2)
317  {
318  if ((channel.length()-3)%2) throwBadChannelLength(channel.length());
319  }
320 
321  inline uint8_t FEDRawChannelUnpacker::sampleNumber() const
322  {
323  return currentStrip_;
324  }
325 
326  inline uint16_t FEDRawChannelUnpacker::adc() const
327  {
328  return ( data_[currentOffset_^7] + ((data_[(currentOffset_+1)^7]&0x03)<<8) );
329  }
330 
331  inline bool FEDRawChannelUnpacker::hasData() const
332  {
333  return valuesLeft_;
334  }
335 
337  {
338  currentOffset_ += 2;
339  currentStrip_++;
340  valuesLeft_--;
341  return (*this);
342  }
343 
345  {
346  ++(*this); return *this;
347  }
348 
349  //FEDZSChannelUnpacker
350 
352  : data_(nullptr),
353  offsetIncrement_(1),
354  valuesLeftInCluster_(0),
355  channelPayloadOffset_(0),
356  channelPayloadLength_(0)
357  { }
358 
359  inline FEDZSChannelUnpacker::FEDZSChannelUnpacker(const uint8_t* payload, const uint16_t channelPayloadOffset, const int16_t channelPayloadLength, const uint16_t offsetIncrement)
360  : data_(payload),
361  currentOffset_(channelPayloadOffset),
362  offsetIncrement_(offsetIncrement),
363  currentStrip_(0),
365  channelPayloadOffset_(channelPayloadOffset),
366  channelPayloadLength_(channelPayloadLength)
367  {
369  }
370 
372  {
373  uint16_t length = channel.length();
374  if (length & 0xF000) throwBadChannelLength(length);
375  FEDZSChannelUnpacker result(channel.data(),channel.offset()+7,length-7);
376  return result;
377  }
378 
380  {
381  uint16_t length = channel.length();
382  if (length & 0xF000) throwBadChannelLength(length);
383  FEDZSChannelUnpacker result(channel.data(),channel.offset()+2,length-2);
384  return result;
385  }
386 
388  {
389  //CAMM - to modify more ?
390  uint16_t length = channel.length();
391  if (length & 0xF000) throwBadChannelLength(length);
392  FEDZSChannelUnpacker result(channel.data(),channel.offset()+7,length-7,2);
393  return result;
394  }
395 
396  inline uint8_t FEDZSChannelUnpacker::sampleNumber() const
397  {
398  return currentStrip_;
399  }
400 
401  inline uint8_t FEDZSChannelUnpacker::adc() const
402  {
403  return data_[currentOffset_^7];
404  }
405 
406  inline uint16_t FEDZSChannelUnpacker::adcPreMix() const
407  {
408  return ( data_[currentOffset_^7] + ((data_[(currentOffset_+1)^7]&0x03)<<8) );
409  }
410 
411  inline bool FEDZSChannelUnpacker::hasData() const
412  {
414  }
415 
417  {
418  if (valuesLeftInCluster_) {
419  currentStrip_++;
422  } else {
424  if (hasData()) {
425  const uint8_t oldStrip = currentStrip_;
427  if ( !(currentStrip_ > oldStrip) ) throwUnorderedData(oldStrip,currentStrip_);
428  }
429  }
430  return (*this);
431  }
432 
434  {
435  ++(*this); return *this;
436  }
437 
439  {
442  }
443 
444 }
445 
446 #endif //ndef EventFilter_SiStripRawToDigi_SiStripFEDBuffer_H
int adc(sample_type sample)
get the ADC sample (12 bits)
static FEDRawChannelUnpacker procRawModeUnpacker(const FEDChannel &channel)
std::auto_ptr< FEDFEHeader > feHeader_
static void throwUnorderedData(const uint8_t currentStrip, const uint8_t firstStripOfNewCluster)
bool checkFEUnitLengths() const
static FEDZSChannelUnpacker zeroSuppressedModeUnpacker(const FEDChannel &channel)
bool checkStatusBits(const uint8_t internalFEDChannelNum) const
static void throwBadChannelLength(const uint16_t length)
virtual bool doCorruptBufferChecks() const
static void throwBadWordLength(const uint16_t word_length)
bool checkFEPayloadsPresent() const
static FEDZSChannelUnpacker preMixRawModeUnpacker(const FEDChannel &channel)
static FEDRawChannelUnpacker scopeModeUnpacker(const FEDChannel &channel)
static FEDRawChannelUnpacker virginRawModeUnpacker(const FEDChannel &channel)
FEDRawChannelUnpacker(const FEDChannel &channel)
uint8_t internalFEDChannelNum(const uint8_t internalFEUnitNum, const uint8_t internalFEUnitChannelNum)
static FEDBSChannelUnpacker zeroSuppressedModeUnpacker(const FEDChannel &channel, uint16_t num_bits)
static void throwBadChannelLength(const uint16_t length)
static void throwUnorderedData(const uint8_t currentStrip, const uint8_t firstStripOfNewCluster)
static FEDBSChannelUnpacker zeroSuppressedLiteModeUnpacker(const FEDChannel &channel, uint16_t num_bits)
static FEDBSChannelUnpacker virginRawModeUnpacker(const FEDChannel &channel, uint16_t num_bits)
#define nullptr
const FEDFEHeader * feHeader() const
virtual bool channelGood(const uint8_t internalFEDannelNum, const bool doAPVeCheck=true) const
sistrip classes
bool feGoodWithoutAPVEmulatorCheck(const uint8_t internalFEUnitNum) const
bool fePresent_[FEUNITS_PER_FED]
void setLegacyMode(bool legacy)
const uint8_t * payloadPointer_
bool fePresent(uint8_t internalFEUnitNum) const
bool majorityAddressErrorForFEUnit(const uint8_t internalFEUnitNum) const
static const uint16_t FEUNITS_PER_FED
uint8_t packetCode(bool legacy=false, const uint8_t internalFEDChannelNum=0) const
const FEDChannel & channel(const uint8_t internalFEDChannelNum) const
FEDRawChannelUnpacker & operator++()
bool checkChannelPacketCodes() const
FEDZSChannelUnpacker & operator++()
static FEDZSChannelUnpacker zeroSuppressedLiteModeUnpacker(const FEDChannel &channel)
uint8_t nFEUnitsPresent() const
bool checkFEUnitAPVAddresses() const
std::string checkSummary() const override
const uint8_t * data() const
FEDBuffer(const uint8_t *fedBuffer, const uint16_t fedBufferSize, const bool allowBadBuffer=false)
uint8_t getCorrectPacketCode() const
bool checkChannelLengthsMatchBufferLength() const
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
bool checkAllChannelStatusBits() const
static void throwBadChannelLength(const uint16_t length)
virtual bool channelGood(const uint8_t internalFEDChannelNum) const
uint16_t calculateFEUnitLength(const uint8_t internalFEUnitNumber) const
bool checkChannelLengths() const
bool feGood(const uint8_t internalFEUnitNum) const
FEDBSChannelUnpacker & operator++()
void print(std::ostream &os) const override
bool feOverflow(const uint8_t internalFEUnitNum) const