CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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  virtual ~FEDBuffer();
29  virtual void print(std::ostream& os) const;
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
39  virtual bool channelGood(const uint8_t internalFEDannelNum, const bool doAPVeCheck=true) const;
40  void setLegacyMode(bool legacy) { legacyUnpacker_ = legacy;}
41 
42  //functions to check buffer. All return true if there is no problem.
43  //minimum checks to do before using buffer
44  virtual bool doChecks(bool doCRC=true) const;
45 
46  //additional checks to check for corrupt buffers
47  //check channel lengths fit inside to buffer length
48  bool checkChannelLengths() const;
49  //check that channel lengths add up to buffer length (this does the previous check as well)
51  //check channel packet codes match readout mode
52  bool checkChannelPacketCodes() const;
53  //check FE unit lengths in FULL DEBUG header match the lengths of their channels
54  bool checkFEUnitLengths() const;
55  //check FE unit APV addresses in FULL DEBUG header are equal to the APVe address if the majority was good
56  bool checkFEUnitAPVAddresses() const;
57  //do all corrupt buffer checks
58  virtual bool doCorruptBufferChecks() const;
59 
60  //check that there are no errors in channel, APV or FEUnit status bits
61  //these are done by channelGood(). Channels with bad status bits may be disabled so bad status bits do not usually indicate an error
62  bool checkStatusBits(const uint8_t internalFEDChannelNum) const;
63  bool checkStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalChannelNum) const;
64  //same but for all channels on enabled FE units
65  bool checkAllChannelStatusBits() const;
66 
67  //check that all FE unit payloads are present
68  bool checkFEPayloadsPresent() const;
69 
70  //print a summary of all checks
71  virtual std::string checkSummary() const;
72  private:
73  uint8_t nFEUnitsPresent() const;
74  void findChannels();
75  inline uint8_t getCorrectPacketCode() const { return packetCode(legacyUnpacker_); }
76  uint16_t calculateFEUnitLength(const uint8_t internalFEUnitNumber) const;
77  std::auto_ptr<FEDFEHeader> feHeader_;
78  const uint8_t* payloadPointer_;
79  uint16_t payloadLength_;
80  uint8_t validChannels_;
82  bool legacyUnpacker_=false;
83  };
84 
85  //class for unpacking data from ZS FED channels
87  {
88  public:
93  uint8_t sampleNumber() const;
94  uint8_t adc() const;
95  uint16_t adcPreMix() const;
96  bool hasData() const;
99  private:
100  //pointer to beginning of FED or FE data, offset of start of channel payload in data and length of channel payload
101  FEDZSChannelUnpacker(const uint8_t* payload, const uint16_t channelPayloadOffset, const int16_t channelPayloadLength, const uint16_t offsetIncrement=1);
102  void readNewClusterInfo();
103  static void throwBadChannelLength(const uint16_t length);
104  void throwBadClusterLength();
105  static void throwUnorderedData(const uint8_t currentStrip, const uint8_t firstStripOfNewCluster);
106  const uint8_t* data_;
107  uint16_t currentOffset_;
109  uint8_t currentStrip_;
113  };
114 
115  //class for unpacking data from raw FED channels
117  {
118  public:
119  static FEDRawChannelUnpacker scopeModeUnpacker(const FEDChannel& channel) { return FEDRawChannelUnpacker(channel); }
121  static FEDRawChannelUnpacker procRawModeUnpacker(const FEDChannel& channel) { return FEDRawChannelUnpacker(channel); }
122  explicit FEDRawChannelUnpacker(const FEDChannel& channel);
123  uint8_t sampleNumber() const;
124  uint16_t adc() const;
125  bool hasData() const;
128  private:
129  static void throwBadChannelLength(const uint16_t length);
130  const uint8_t* data_;
131  uint16_t currentOffset_;
132  uint8_t currentStrip_;
133  uint16_t valuesLeft_;
134  };
135 
136  //class for unpacking data from any FED channels with a non-integer words bits stripping mode
138  {
139  public:
140  static FEDBSChannelUnpacker virginRawModeUnpacker(const FEDChannel& channel, uint16_t num_bits);
141  static FEDBSChannelUnpacker zeroSuppressedModeUnpacker(const FEDChannel& channel, uint16_t num_bits);
142  static FEDBSChannelUnpacker zeroSuppressedLiteModeUnpacker(const FEDChannel& channel, uint16_t num_bits);
144  uint8_t sampleNumber() const;
145  uint16_t adc() const;
146  bool hasData() const;
149  private:
150  //pointer to beginning of FED or FE data, offset of start of channel payload in data and length of channel payload
151  FEDBSChannelUnpacker(const uint8_t* payload, const uint16_t channelPayloadOffset, const int16_t channelPayloadLength, const uint16_t offsetIncrement, bool useZS);
152  void readNewClusterInfo();
153  static void throwBadChannelLength(const uint16_t length);
154  static void throwBadWordLength(const uint16_t word_length);
155  static void throwUnorderedData(const uint8_t currentStrip, const uint8_t firstStripOfNewCluster);
156  const uint8_t* data_;
157  uint16_t oldWordOffset_;
162  uint8_t currentStrip_;
165  bool useZS_;
167  };
168 
169  //
170  // Inline function definitions
171  //
172 
173  //FEDBuffer
174 
175  inline const FEDFEHeader* FEDBuffer::feHeader() const
176  {
177  return feHeader_.get();
178  }
179 
180  inline bool FEDBuffer::feGood(const uint8_t internalFEUnitNum) const
181  {
182  return ( !majorityAddressErrorForFEUnit(internalFEUnitNum) && !feOverflow(internalFEUnitNum) && fePresent(internalFEUnitNum) );
183  }
184 
185  inline bool FEDBuffer::feGoodWithoutAPVEmulatorCheck(const uint8_t internalFEUnitNum) const
186  {
187  return ( !feOverflow(internalFEUnitNum) && fePresent(internalFEUnitNum) );
188  }
189 
190  inline bool FEDBuffer::fePresent(uint8_t internalFEUnitNum) const
191  {
192  return fePresent_[internalFEUnitNum];
193  }
194 
195  inline bool FEDBuffer::checkStatusBits(const uint8_t internalFEDChannelNum) const
196  {
197  return feHeader_->checkChannelStatusBits(internalFEDChannelNum);
198  }
199 
200  inline bool FEDBuffer::checkStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalChannelNum) const
201  {
202  return checkStatusBits(internalFEDChannelNum(internalFEUnitNum,internalChannelNum));
203  }
204 
205  //FEDBSChannelUnpacker
206 
208  : data_(NULL),
209  oldWordOffset_(0), currentWordOffset_(0),
210  currentBitOffset_(0), currentLocalBitOffset_(0),
211  bitOffsetIncrement_(10),
212  currentStrip_(0),
213  channelPayloadOffset_(0), channelPayloadLength_(0),
214  useZS_(false), valuesLeftInCluster_(0)
215  { }
216 
217  inline FEDBSChannelUnpacker::FEDBSChannelUnpacker(const uint8_t* payload, const uint16_t channelPayloadOffset, const int16_t channelPayloadLength, const uint16_t offsetIncrement, bool useZS)
218  : data_(payload),
219  oldWordOffset_(0), currentWordOffset_(channelPayloadOffset),
220  currentBitOffset_(0), currentLocalBitOffset_(0),
221  bitOffsetIncrement_(offsetIncrement),
222  channelPayloadOffset_(channelPayloadOffset),
223  channelPayloadLength_(channelPayloadLength),
224  useZS_(useZS), valuesLeftInCluster_(0)
225  {
226  if (bitOffsetIncrement_>16) throwBadWordLength(bitOffsetIncrement_); // more than 2 words... still to be implemented
227  }
228 
230  {
231  uint16_t length = channel.length();
232  if (length & 0xF000) throwBadChannelLength(length);
233  if (num_bits<=0 or num_bits>16) throwBadWordLength(num_bits);
234  FEDBSChannelUnpacker result(channel.data(), channel.offset()+3, length-3, num_bits, false);
235  return result;
236  }
237 
239  {
240  uint16_t length = channel.length();
241  if (length & 0xF000) throwBadChannelLength(length);
242  FEDBSChannelUnpacker result(channel.data(), channel.offset()+7, length-7, num_bits, true);
243  return result;
244  }
245 
247  {
248  uint16_t length = channel.length();
249  if (length & 0xF000) throwBadChannelLength(length);
250  FEDBSChannelUnpacker result(channel.data(), channel.offset()+2, length-2, num_bits, true);
251  return result;
252  }
253 
254  inline uint8_t FEDBSChannelUnpacker::sampleNumber() const
255  {
256  return currentStrip_;
257  }
258 
259  inline uint16_t FEDBSChannelUnpacker::adc() const
260  {
261  uint16_t bits_missing = (bitOffsetIncrement_-8)+currentLocalBitOffset_;
262  uint16_t adc = (data_[currentWordOffset_^7]<<bits_missing);
264  adc += ( (data_[(currentWordOffset_+1)^7]>>(8-bits_missing)) );
265  }
266  return (adc&((1<<bitOffsetIncrement_)-1));
267  }
268 
269  inline bool FEDBSChannelUnpacker::hasData() const
270  {
272  }
273 
275  {
279  while (currentLocalBitOffset_>=8) {
282  }
283  if (useZS_) {
285  else {
286  if (hasData()) {
287  const uint8_t oldStrip = currentStrip_;
289  if ( !(currentStrip_ > oldStrip) ) throwUnorderedData(oldStrip,currentStrip_);
290  }
291  }
292  } else { currentStrip_++; }
293  return (*this);
294  }
295 
297  {
298  ++(*this); return *this;
299  }
300 
302  {
305  }
306 
307 
308  //FEDRawChannelUnpacker
309 
311  : data_(channel.data()),
312  currentOffset_(channel.offset()+3),
313  currentStrip_(0),
314  valuesLeft_((channel.length()-3)/2)
315  {
316  if ((channel.length()-3)%2) throwBadChannelLength(channel.length());
317  }
318 
319  inline uint8_t FEDRawChannelUnpacker::sampleNumber() const
320  {
321  return currentStrip_;
322  }
323 
324  inline uint16_t FEDRawChannelUnpacker::adc() const
325  {
326  return ( data_[currentOffset_^7] + ((data_[(currentOffset_+1)^7]&0x03)<<8) );
327  }
328 
329  inline bool FEDRawChannelUnpacker::hasData() const
330  {
331  return valuesLeft_;
332  }
333 
335  {
336  currentOffset_ += 2;
337  currentStrip_++;
338  valuesLeft_--;
339  return (*this);
340  }
341 
343  {
344  ++(*this); return *this;
345  }
346 
347  //FEDZSChannelUnpacker
348 
350  : data_(NULL),
351  offsetIncrement_(1),
352  valuesLeftInCluster_(0),
353  channelPayloadOffset_(0),
354  channelPayloadLength_(0)
355  { }
356 
357  inline FEDZSChannelUnpacker::FEDZSChannelUnpacker(const uint8_t* payload, const uint16_t channelPayloadOffset, const int16_t channelPayloadLength, const uint16_t offsetIncrement)
358  : data_(payload),
359  currentOffset_(channelPayloadOffset),
360  offsetIncrement_(offsetIncrement),
361  currentStrip_(0),
362  valuesLeftInCluster_(0),
363  channelPayloadOffset_(channelPayloadOffset),
364  channelPayloadLength_(channelPayloadLength)
365  {
367  }
368 
370  {
371  uint16_t length = channel.length();
372  if (length & 0xF000) throwBadChannelLength(length);
373  FEDZSChannelUnpacker result(channel.data(),channel.offset()+7,length-7);
374  return result;
375  }
376 
378  {
379  uint16_t length = channel.length();
380  if (length & 0xF000) throwBadChannelLength(length);
381  FEDZSChannelUnpacker result(channel.data(),channel.offset()+2,length-2);
382  return result;
383  }
384 
386  {
387  //CAMM - to modify more ?
388  uint16_t length = channel.length();
389  if (length & 0xF000) throwBadChannelLength(length);
390  FEDZSChannelUnpacker result(channel.data(),channel.offset()+7,length-7,2);
391  return result;
392  }
393 
394  inline uint8_t FEDZSChannelUnpacker::sampleNumber() const
395  {
396  return currentStrip_;
397  }
398 
399  inline uint8_t FEDZSChannelUnpacker::adc() const
400  {
401  return data_[currentOffset_^7];
402  }
403 
404  inline uint16_t FEDZSChannelUnpacker::adcPreMix() const
405  {
406  return ( data_[currentOffset_^7] + ((data_[(currentOffset_+1)^7]&0x03)<<8) );
407  }
408 
409  inline bool FEDZSChannelUnpacker::hasData() const
410  {
412  }
413 
415  {
416  if (valuesLeftInCluster_) {
417  currentStrip_++;
420  } else {
422  if (hasData()) {
423  const uint8_t oldStrip = currentStrip_;
425  if ( !(currentStrip_ > oldStrip) ) throwUnorderedData(oldStrip,currentStrip_);
426  }
427  }
428  return (*this);
429  }
430 
432  {
433  ++(*this); return *this;
434  }
435 
437  {
440  }
441 
442 }
443 
444 #endif //ndef EventFilter_SiStripRawToDigi_SiStripFEDBuffer_H
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)
virtual void print(std::ostream &os) const
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)
#define NULL
Definition: scimark2.h:8
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)
const FEDFEHeader * feHeader() const
virtual bool channelGood(const uint8_t internalFEDannelNum, const bool doAPVeCheck=true) const
tuple result
Definition: mps_fire.py:95
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
virtual std::string checkSummary() const
FEDRawChannelUnpacker & operator++()
bool checkChannelPacketCodes() const
FEDZSChannelUnpacker & operator++()
static FEDZSChannelUnpacker zeroSuppressedLiteModeUnpacker(const FEDChannel &channel)
uint8_t nFEUnitsPresent() const
bool checkFEUnitAPVAddresses() const
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
bool checkAllChannelStatusBits() const
static void throwBadChannelLength(const uint16_t length)
uint16_t calculateFEUnitLength(const uint8_t internalFEUnitNumber) const
bool checkChannelLengths() const
volatile std::atomic< bool > shutdown_flag false
bool feGood(const uint8_t internalFEUnitNum) const
FEDBSChannelUnpacker & operator++()
bool feOverflow(const uint8_t internalFEUnitNum) const