Go to the documentation of this file.00001 #ifndef EventFilter_SiStripRawToDigi_SiStripFEDBuffer_H
00002 #define EventFilter_SiStripRawToDigi_SiStripFEDBuffer_H
00003
00004 #include "boost/cstdint.hpp"
00005 #include <string>
00006 #include <vector>
00007 #include <memory>
00008 #include <ostream>
00009 #include <cstring>
00010 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBufferComponents.h"
00011
00012 namespace sistrip {
00013
00014
00015
00016
00017
00018
00019 class FEDBuffer : public FEDBufferBase
00020 {
00021 public:
00022
00023
00024 FEDBuffer(const uint8_t* fedBuffer, const size_t fedBufferSize, const bool allowBadBuffer = false);
00025 virtual ~FEDBuffer();
00026 virtual void print(std::ostream& os) const;
00027 const FEDFEHeader* feHeader() const;
00028
00029 bool feGood(const uint8_t internalFEUnitNum) const;
00030
00031
00032
00033 bool fePresent(uint8_t internalFEUnitNum) const;
00034
00035 virtual bool channelGood(const uint8_t internalFEDannelNum) const;
00036
00037
00038
00039 virtual bool doChecks() const;
00040
00041
00042
00043 bool checkChannelLengths() const;
00044
00045 bool checkChannelLengthsMatchBufferLength() const;
00046
00047 bool checkChannelPacketCodes() const;
00048
00049 bool checkFEUnitLengths() const;
00050
00051 bool checkFEUnitAPVAddresses() const;
00052
00053 virtual bool doCorruptBufferChecks() const;
00054
00055
00056
00057 bool checkStatusBits(const uint8_t internalFEDChannelNum) const;
00058 bool checkStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalChannelNum) const;
00059
00060 bool checkAllChannelStatusBits() const;
00061
00062
00063 bool checkFEPayloadsPresent() const;
00064
00065
00066 virtual std::string checkSummary() const;
00067 private:
00068 uint8_t nFEUnitsPresent() const;
00069 void findChannels();
00070 uint8_t getCorrectPacketCode() const;
00071 uint16_t calculateFEUnitLength(const uint8_t internalFEUnitNumber) const;
00072 std::auto_ptr<FEDFEHeader> feHeader_;
00073 const uint8_t* payloadPointer_;
00074 uint16_t payloadLength_;
00075 uint8_t validChannels_;
00076 bool fePresent_[FEUNITS_PER_FED];
00077 };
00078
00079
00080 class FEDZSChannelUnpacker
00081 {
00082 public:
00083 static FEDZSChannelUnpacker zeroSuppressedModeUnpacker(const FEDChannel& channel);
00084 static FEDZSChannelUnpacker zeroSuppressedLiteModeUnpacker(const FEDChannel& channel);
00085 FEDZSChannelUnpacker();
00086 uint8_t sampleNumber() const;
00087 uint8_t adc() const;
00088 bool hasData() const;
00089 FEDZSChannelUnpacker& operator ++ ();
00090 FEDZSChannelUnpacker& operator ++ (int);
00091 private:
00092
00093 FEDZSChannelUnpacker(const uint8_t* payload, const size_t channelPayloadOffset, const int16_t channelPayloadLength);
00094 void readNewClusterInfo();
00095 static void throwBadChannelLength(const uint16_t length);
00096 void throwBadClusterLength();
00097 static void throwUnorderedData(const uint8_t currentStrip, const uint8_t firstStripOfNewCluster);
00098 const uint8_t* data_;
00099 size_t currentOffset_;
00100 uint8_t currentStrip_;
00101 uint8_t valuesLeftInCluster_;
00102 uint16_t channelPayloadOffset_;
00103 uint16_t channelPayloadLength_;
00104 };
00105
00106
00107 class FEDRawChannelUnpacker
00108 {
00109 public:
00110 static FEDRawChannelUnpacker scopeModeUnpacker(const FEDChannel& channel) { return FEDRawChannelUnpacker(channel); }
00111 static FEDRawChannelUnpacker virginRawModeUnpacker(const FEDChannel& channel) { return FEDRawChannelUnpacker(channel); }
00112 static FEDRawChannelUnpacker procRawModeUnpacker(const FEDChannel& channel) { return FEDRawChannelUnpacker(channel); }
00113 explicit FEDRawChannelUnpacker(const FEDChannel& channel);
00114 uint8_t sampleNumber() const;
00115 uint16_t adc() const;
00116 bool hasData() const;
00117 FEDRawChannelUnpacker& operator ++ ();
00118 FEDRawChannelUnpacker& operator ++ (int);
00119 private:
00120 static void throwBadChannelLength(const uint16_t length);
00121 const uint8_t* data_;
00122 size_t currentOffset_;
00123 uint8_t currentStrip_;
00124 uint16_t valuesLeft_;
00125 };
00126
00127
00128
00129
00130
00131
00132
00133 inline const FEDFEHeader* FEDBuffer::feHeader() const
00134 {
00135 return feHeader_.get();
00136 }
00137
00138 inline bool FEDBuffer::feGood(const uint8_t internalFEUnitNum) const
00139 {
00140 return ( !majorityAddressErrorForFEUnit(internalFEUnitNum) && !feOverflow(internalFEUnitNum) && fePresent(internalFEUnitNum) );
00141 }
00142
00143 inline bool FEDBuffer::fePresent(uint8_t internalFEUnitNum) const
00144 {
00145 return fePresent_[internalFEUnitNum];
00146 }
00147
00148 inline bool FEDBuffer::checkStatusBits(const uint8_t internalFEDChannelNum) const
00149 {
00150 return feHeader_->checkChannelStatusBits(internalFEDChannelNum);
00151 }
00152
00153 inline bool FEDBuffer::checkStatusBits(const uint8_t internalFEUnitNum, const uint8_t internalChannelNum) const
00154 {
00155 return checkStatusBits(internalFEDChannelNum(internalFEUnitNum,internalChannelNum));
00156 }
00157
00158
00159
00160 inline FEDRawChannelUnpacker::FEDRawChannelUnpacker(const FEDChannel& channel)
00161 : data_(channel.data()),
00162 currentOffset_(channel.offset()+3),
00163 currentStrip_(0),
00164 valuesLeft_((channel.length()-3)/2)
00165 {
00166 if ((channel.length()-3)%2) throwBadChannelLength(channel.length());
00167 }
00168
00169 inline uint8_t FEDRawChannelUnpacker::sampleNumber() const
00170 {
00171 return currentStrip_;
00172 }
00173
00174 inline uint16_t FEDRawChannelUnpacker::adc() const
00175 {
00176 return ( data_[currentOffset_^7] + ((data_[(currentOffset_+1)^7]&0x03)<<8) );
00177 }
00178
00179 inline bool FEDRawChannelUnpacker::hasData() const
00180 {
00181 return valuesLeft_;
00182 }
00183
00184 inline FEDRawChannelUnpacker& FEDRawChannelUnpacker::operator ++ ()
00185 {
00186 currentOffset_ += 2;
00187 currentStrip_++;
00188 valuesLeft_--;
00189 return (*this);
00190 }
00191
00192 inline FEDRawChannelUnpacker& FEDRawChannelUnpacker::operator ++ (int)
00193 {
00194 ++(*this); return *this;
00195 }
00196
00197
00198
00199 inline FEDZSChannelUnpacker::FEDZSChannelUnpacker()
00200 : data_(NULL),
00201 valuesLeftInCluster_(0),
00202 channelPayloadOffset_(0),
00203 channelPayloadLength_(0)
00204 { }
00205
00206 inline FEDZSChannelUnpacker::FEDZSChannelUnpacker(const uint8_t* payload, const size_t channelPayloadOffset, const int16_t channelPayloadLength)
00207 : data_(payload),
00208 currentOffset_(channelPayloadOffset),
00209 currentStrip_(0),
00210 valuesLeftInCluster_(0),
00211 channelPayloadOffset_(channelPayloadOffset),
00212 channelPayloadLength_(channelPayloadLength)
00213 {
00214 if (channelPayloadLength_) readNewClusterInfo();
00215 }
00216
00217 inline FEDZSChannelUnpacker FEDZSChannelUnpacker::zeroSuppressedModeUnpacker(const FEDChannel& channel)
00218 {
00219 uint16_t length = channel.length();
00220 if (length & 0xF000) throwBadChannelLength(length);
00221 FEDZSChannelUnpacker result(channel.data(),channel.offset()+7,length-7);
00222 return result;
00223 }
00224
00225 inline FEDZSChannelUnpacker FEDZSChannelUnpacker::zeroSuppressedLiteModeUnpacker(const FEDChannel& channel)
00226 {
00227 uint16_t length = channel.length();
00228 if (length & 0xF000) throwBadChannelLength(length);
00229 FEDZSChannelUnpacker result(channel.data(),channel.offset()+2,length-2);
00230 return result;
00231 }
00232
00233 inline uint8_t FEDZSChannelUnpacker::sampleNumber() const
00234 {
00235 return currentStrip_;
00236 }
00237
00238 inline uint8_t FEDZSChannelUnpacker::adc() const
00239 {
00240 return data_[currentOffset_^7];
00241 }
00242
00243 inline bool FEDZSChannelUnpacker::hasData() const
00244 {
00245 return (currentOffset_<channelPayloadOffset_+channelPayloadLength_);
00246 }
00247
00248 inline FEDZSChannelUnpacker& FEDZSChannelUnpacker::operator ++ ()
00249 {
00250 if (valuesLeftInCluster_) {
00251 currentStrip_++;
00252 currentOffset_++;
00253 valuesLeftInCluster_--;
00254 } else {
00255 currentOffset_++;
00256 if (hasData()) {
00257 const uint8_t oldStrip = currentStrip_;
00258 readNewClusterInfo();
00259 if ( !(currentStrip_ > oldStrip) ) throwUnorderedData(oldStrip,currentStrip_);
00260 }
00261 }
00262 return (*this);
00263 }
00264
00265 inline FEDZSChannelUnpacker& FEDZSChannelUnpacker::operator ++ (int)
00266 {
00267 ++(*this); return *this;
00268 }
00269
00270 inline void FEDZSChannelUnpacker::readNewClusterInfo()
00271 {
00272 currentStrip_ = data_[(currentOffset_++)^7];
00273 valuesLeftInCluster_ = data_[(currentOffset_++)^7]-1;
00274 }
00275
00276 }
00277
00278 #endif //ndef EventFilter_SiStripRawToDigi_SiStripFEDBuffer_H