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