Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:11:02

0001 #ifndef EventFilter_SiStripRawToDigi_SiStripFEDBufferGenerator_H
0002 #define EventFilter_SiStripRawToDigi_SiStripFEDBufferGenerator_H
0003 
0004 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBufferComponents.h"
0005 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0006 #include <vector>
0007 #include <list>
0008 #include <utility>
0009 #include <memory>
0010 #include <cstdint>
0011 
0012 namespace sistrip {
0013 
0014   //
0015   // Class definitions
0016   //
0017 
0018   class FEDStripData {
0019   public:
0020     //class used to represent channel data
0021     class ChannelData {
0022     public:
0023       ChannelData(bool dataIsAlreadyConvertedTo8Bit,
0024                   const size_t numberOfSamples,
0025                   const std::pair<uint16_t, uint16_t> medians = std::make_pair<uint16_t>(0, 0));
0026       //number of samples
0027       size_t size() const;
0028       //get common mode medians for first and second APV
0029       std::pair<uint16_t, uint16_t> getMedians() const;
0030       //set common mode medians for first and second APV
0031       void setMedians(const std::pair<uint16_t, uint16_t> values);
0032       //get the 10bit value to be used for raw modes
0033       uint16_t getSample(const uint16_t sampleNumber) const;
0034       //get the 8 bit value to be used for ZS modes, converting it as the FED does if specified in constructor
0035       uint8_t get8BitSample(const uint16_t sampleNumber, uint16_t nBotBitsToDrop) const;
0036       uint16_t get10BitSample(const uint16_t sampleNumber) const;
0037       void setSample(const uint16_t sampleNumber, const uint16_t adcValue);
0038       //setting value directly is equivalent to get and set Sample but without length check
0039       uint16_t& operator[](const size_t sampleNumber);
0040       const uint16_t& operator[](const size_t sampleNumber) const;
0041 
0042     private:
0043       std::pair<uint16_t, uint16_t> medians_;
0044       std::vector<uint16_t> data_;
0045       bool dataIs8Bit_;
0046     };
0047 
0048     FEDStripData(const std::vector<ChannelData>& data);
0049     //specify whether the data is already in the 8bit ZS format (only affects what is returned by ChannelData::get8BitSample() if the value if >253)
0050     //if the data is for scope mode then specify the scope length
0051     FEDStripData(bool dataIsAlreadyConvertedTo8Bit = true, const size_t samplesPerChannel = STRIPS_PER_FEDCH);
0052     //access to elements
0053     ChannelData& operator[](const uint8_t internalFEDChannelNum);
0054     const ChannelData& operator[](const uint8_t internalFEDChannelNum) const;
0055     ChannelData& channel(const uint8_t internalFEDChannelNum);
0056     const ChannelData& channel(const uint8_t internalFEDChannelNum) const;
0057 
0058   private:
0059     std::vector<ChannelData> data_;
0060   };
0061 
0062   class FEDBufferPayload {
0063   public:
0064     FEDBufferPayload(const std::vector<std::vector<uint8_t> >& channelBuffers);
0065     //size of payload in bytes
0066     size_t lengthInBytes() const;
0067     //returns NULL if payload size is 0, otherwise return a pointer to the payload buffer
0068     const uint8_t* data() const;
0069     //size of FE unit payload
0070     uint16_t getFELength(const uint8_t internalFEUnitNum) const;
0071 
0072   private:
0073     void appendToBuffer(size_t* pIndexInBuffer, const uint8_t value);
0074     void appendToBuffer(size_t* pIndexInBuffer,
0075                         std::vector<uint8_t>::const_iterator start,
0076                         std::vector<uint8_t>::const_iterator finish);
0077     std::vector<uint8_t> data_;
0078     std::vector<uint16_t> feLengths_;
0079   };
0080 
0081   class FEDBufferPayloadCreator {
0082   public:
0083     //specify which FE units and channels should have data generated for them
0084     //If an FE unit is disabled then the channel is as well. The whole FE payload will be missing.
0085     //If a channel is disabled then it is considered to have all zeros in the data but will be present in the data
0086     FEDBufferPayloadCreator(const std::vector<bool>& enabledFEUnits, const std::vector<bool>& enabledChannels);
0087     //create the payload for a particular mode
0088     FEDBufferPayload createPayload(FEDReadoutMode mode, uint8_t packetCode, const FEDStripData& data) const;
0089     FEDBufferPayload operator()(FEDReadoutMode mode, uint8_t packetCode, const FEDStripData& data) const;
0090 
0091   private:
0092     //fill vector with channel data
0093     void fillChannelBuffer(std::vector<uint8_t>* channelBuffer,
0094                            FEDReadoutMode mode,
0095                            uint8_t packetCode,
0096                            const FEDStripData::ChannelData& data,
0097                            const bool channelEnabled) const;
0098     //fill the vector with channel data for raw mode
0099     void fillRawChannelBuffer(std::vector<uint8_t>* channelBuffer,
0100                               const uint8_t packetCode,
0101                               const FEDStripData::ChannelData& data,
0102                               const bool channelEnabled,
0103                               const bool reorderData) const;
0104     //fill the vector with channel data for zero suppressed modes
0105     void fillZeroSuppressedChannelBuffer(std::vector<uint8_t>* channelBuffer,
0106                                          const uint8_t packetCode,
0107                                          const FEDStripData::ChannelData& data,
0108                                          const bool channelEnabled) const;
0109     void fillZeroSuppressedLiteChannelBuffer(std::vector<uint8_t>* channelBuffer,
0110                                              const FEDStripData::ChannelData& data,
0111                                              const bool channelEnabled,
0112                                              const FEDReadoutMode mode) const;
0113     void fillPreMixRawChannelBuffer(std::vector<uint8_t>* channelBuffer,
0114                                     const FEDStripData::ChannelData& data,
0115                                     const bool channelEnabled) const;
0116     //add the ZS cluster data for the channel to the end of the vector
0117     void fillClusterData(std::vector<uint8_t>* channelBuffer,
0118                          uint8_t packetCode,
0119                          const FEDStripData::ChannelData& data,
0120                          const FEDReadoutMode mode) const;
0121     void fillClusterDataPreMixMode(std::vector<uint8_t>* channelBuffer, const FEDStripData::ChannelData& data) const;
0122     std::vector<bool> feUnitsEnabled_;
0123     std::vector<bool> channelsEnabled_;
0124   };
0125 
0126   class FEDBufferGenerator {
0127   public:
0128     //constructor in which you can specify the defaults for some parameters
0129     FEDBufferGenerator(const uint32_t l1ID = 0,
0130                        const uint16_t bxID = 0,
0131                        const std::vector<bool>& feUnitsEnabled = std::vector<bool>(FEUNITS_PER_FED, true),
0132                        const std::vector<bool>& channelsEnabled = std::vector<bool>(FEDCH_PER_FED, true),
0133                        const FEDReadoutMode readoutMode = READOUT_MODE_ZERO_SUPPRESSED,
0134                        const FEDHeaderType headerType = HEADER_TYPE_FULL_DEBUG,
0135                        const FEDBufferFormat bufferFormat = BUFFER_FORMAT_OLD_SLINK,
0136                        const FEDDAQEventType evtType = DAQ_EVENT_TYPE_PHYSICS);
0137     //methods to get and set the defaults
0138     uint32_t getL1ID() const;
0139     uint16_t getBXID() const;
0140     FEDReadoutMode getReadoutMode() const;
0141     FEDHeaderType getHeaderType() const;
0142     FEDBufferFormat getBufferFormat() const;
0143     FEDDAQEventType getDAQEventType() const;
0144     FEDBufferGenerator& setL1ID(const uint32_t newL1ID);
0145     FEDBufferGenerator& setBXID(const uint16_t newBXID);
0146     FEDBufferGenerator& setReadoutMode(const FEDReadoutMode newReadoutMode);
0147     FEDBufferGenerator& setHeaderType(const FEDHeaderType newHeaderType);
0148     FEDBufferGenerator& setBufferFormat(const FEDBufferFormat newBufferFormat);
0149     FEDBufferGenerator& setDAQEventType(const FEDDAQEventType newDAQEventType);
0150     //disabled FE units produce no data at all
0151     //disabled channels have headers but data is all zeros (raw modes) or have no clusters (ZS)
0152     bool getFEUnitEnabled(const uint8_t internalFEUnitNumber) const;
0153     bool getChannelEnabled(const uint8_t internalFEDChannelNumber) const;
0154     FEDBufferGenerator& setFEUnitEnable(const uint8_t internalFEUnitNumber, const bool enabled);
0155     FEDBufferGenerator& setChannelEnable(const uint8_t internalFEDChannelNumber, const bool enabled);
0156     FEDBufferGenerator& setFEUnitEnables(const std::vector<bool>& feUnitsEnabled);
0157     FEDBufferGenerator& setChannelEnables(const std::vector<bool>& channelsEnabled);
0158     //make finer changes to defaults for parts of buffer
0159     //setting source ID in DAQ header and length and CRC in DAQ trailer has no effect since they are set when buffer is built
0160     FEDDAQHeader& daqHeader();
0161     FEDDAQTrailer& daqTrailer();
0162     TrackerSpecialHeader& trackerSpecialHeader();
0163     FEDFEHeader& feHeader();
0164     //method to generate buffer
0165     //unspecified parameters use defaults set by constructor or setters
0166     //FEDRawData object will be resized to fit buffer and filled
0167     void generateBuffer(FEDRawData* rawDataObject,
0168                         const FEDStripData& data,
0169                         uint16_t sourceID,
0170                         uint8_t packetCode) const;
0171 
0172   private:
0173     //method to fill buffer at pointer from pre generated components (only the length and CRC will be changed)
0174     //at least bufferSizeInBytes(feHeader,payload) must have already been allocated
0175     static void fillBuffer(uint8_t* pointerToStartOfBuffer,
0176                            const FEDDAQHeader& daqHeader,
0177                            const FEDDAQTrailer& daqTrailer,
0178                            const TrackerSpecialHeader& tkSpecialHeader,
0179                            const FEDFEHeader& feHeader,
0180                            const FEDBufferPayload& payload);
0181     //returns required size of buffer from given components
0182     static size_t bufferSizeInBytes(const FEDFEHeader& feHeader, const FEDBufferPayload& payload);
0183     //used to store default values
0184     FEDDAQHeader defaultDAQHeader_;
0185     FEDDAQTrailer defaultDAQTrailer_;
0186     TrackerSpecialHeader defaultTrackerSpecialHeader_;
0187     std::unique_ptr<FEDFEHeader> defaultFEHeader_;
0188     std::vector<bool> feUnitsEnabled_;
0189     std::vector<bool> channelsEnabled_;
0190   };
0191 
0192   //
0193   // Inline function definitions
0194   //
0195 
0196   //FEDStripData
0197 
0198   inline FEDStripData::FEDStripData(const std::vector<ChannelData>& data) : data_(data) {}
0199 
0200   //re-use const method
0201   inline FEDStripData::ChannelData& FEDStripData::channel(const uint8_t internalFEDChannelNum) {
0202     return const_cast<FEDStripData::ChannelData&>(std::as_const(*this).channel(internalFEDChannelNum));
0203   }
0204 
0205   inline FEDStripData::ChannelData& FEDStripData::operator[](const uint8_t internalFEDChannelNum) {
0206     return channel(internalFEDChannelNum);
0207   }
0208 
0209   inline const FEDStripData::ChannelData& FEDStripData::operator[](const uint8_t internalFEDChannelNum) const {
0210     return channel(internalFEDChannelNum);
0211   }
0212 
0213   inline FEDStripData::ChannelData::ChannelData(bool dataIsAlreadyConvertedTo8Bit,
0214                                                 const size_t numberOfSamples,
0215                                                 const std::pair<uint16_t, uint16_t> medians)
0216       : medians_(medians), data_(numberOfSamples, 0), dataIs8Bit_(dataIsAlreadyConvertedTo8Bit) {}
0217 
0218   inline size_t FEDStripData::ChannelData::size() const { return data_.size(); }
0219 
0220   inline const uint16_t& FEDStripData::ChannelData::operator[](const size_t sampleNumber) const {
0221     return data_[sampleNumber];
0222   }
0223 
0224   //re-use const method
0225   inline uint16_t& FEDStripData::ChannelData::operator[](const size_t sampleNumber) {
0226     return const_cast<uint16_t&>(std::as_const(*this)[sampleNumber]);
0227   }
0228 
0229   inline uint16_t FEDStripData::ChannelData::getSample(const uint16_t sampleNumber) const {
0230     //try {
0231     //  return data_.at(sampleNumber);
0232     //} catch (const std::out_of_range&) {
0233     //  std::ostringstream ss;
0234     //  ss << "Sample index out of range. "
0235     //     << "Requesting sample " << sampleNumber
0236     //     << " when channel has only " << data_.size() << " samples.";
0237     //  throw cms::Exception("FEDBufferGenerator") << ss.str();
0238     //}
0239     return data_[sampleNumber];
0240   }
0241 
0242   inline uint8_t FEDStripData::ChannelData::get8BitSample(const uint16_t sampleNumber, uint16_t nBotBitsToDrop) const {
0243     uint16_t sample = getSample(sampleNumber) >> nBotBitsToDrop;
0244     if (dataIs8Bit_) {
0245       return (0xFF & sample);
0246     } else {
0247       if (sample < 0xFE)
0248         return sample;
0249       else if (sample == 0x3FF)
0250         return 0xFF;
0251       else
0252         return 0xFE;
0253     }
0254   }
0255 
0256   inline uint16_t FEDStripData::ChannelData::get10BitSample(const uint16_t sampleNumber) const {
0257     if (dataIs8Bit_) {
0258       return (0xFF & getSample(sampleNumber));
0259     } else {
0260       const uint16_t sample = getSample(sampleNumber);
0261       if (sample < 0x3FF)
0262         return sample;
0263       else
0264         return 0x3FF;
0265     }
0266   }
0267 
0268   inline std::pair<uint16_t, uint16_t> FEDStripData::ChannelData::getMedians() const { return medians_; }
0269 
0270   inline void FEDStripData::ChannelData::setMedians(const std::pair<uint16_t, uint16_t> values) { medians_ = values; }
0271 
0272   //FEDBufferPayload
0273 
0274   inline size_t FEDBufferPayload::lengthInBytes() const { return data_.size(); }
0275 
0276   inline void FEDBufferPayload::appendToBuffer(size_t* pIndexInBuffer, const uint8_t value) {
0277     data_[((*pIndexInBuffer)++) ^ 7] = value;
0278   }
0279 
0280   inline void FEDBufferPayload::appendToBuffer(size_t* pIndexInBuffer,
0281                                                std::vector<uint8_t>::const_iterator start,
0282                                                std::vector<uint8_t>::const_iterator finish) {
0283     for (std::vector<uint8_t>::const_iterator iVal = start; iVal != finish; iVal++) {
0284       appendToBuffer(pIndexInBuffer, *iVal);
0285     }
0286   }
0287 
0288   //FEDBufferPayloadCreator
0289 
0290   inline FEDBufferPayloadCreator::FEDBufferPayloadCreator(const std::vector<bool>& feUnitsEnabled,
0291                                                           const std::vector<bool>& channelsEnabled)
0292       : feUnitsEnabled_(feUnitsEnabled), channelsEnabled_(channelsEnabled) {}
0293 
0294   inline FEDBufferPayload FEDBufferPayloadCreator::operator()(FEDReadoutMode mode,
0295                                                               uint8_t packetCode,
0296                                                               const FEDStripData& data) const {
0297     return createPayload(mode, packetCode, data);
0298   }
0299 
0300   //FEDBufferGenerator
0301 
0302   inline uint32_t FEDBufferGenerator::getL1ID() const { return defaultDAQHeader_.l1ID(); }
0303 
0304   inline uint16_t FEDBufferGenerator::getBXID() const { return defaultDAQHeader_.bxID(); }
0305 
0306   inline FEDReadoutMode FEDBufferGenerator::getReadoutMode() const {
0307     return defaultTrackerSpecialHeader_.readoutMode();
0308   }
0309 
0310   inline FEDHeaderType FEDBufferGenerator::getHeaderType() const { return defaultTrackerSpecialHeader_.headerType(); }
0311 
0312   inline FEDBufferFormat FEDBufferGenerator::getBufferFormat() const {
0313     return defaultTrackerSpecialHeader_.bufferFormat();
0314   }
0315 
0316   inline FEDDAQEventType FEDBufferGenerator::getDAQEventType() const { return defaultDAQHeader_.eventType(); }
0317 
0318   inline FEDBufferGenerator& FEDBufferGenerator::setL1ID(const uint32_t newL1ID) {
0319     defaultDAQHeader_.setL1ID(newL1ID);
0320     return *this;
0321   }
0322 
0323   inline FEDBufferGenerator& FEDBufferGenerator::setBXID(const uint16_t newBXID) {
0324     defaultDAQHeader_.setBXID(newBXID);
0325     return *this;
0326   }
0327 
0328   inline FEDBufferGenerator& FEDBufferGenerator::setReadoutMode(const FEDReadoutMode newReadoutMode) {
0329     defaultTrackerSpecialHeader_.setReadoutMode(newReadoutMode);
0330     return *this;
0331   }
0332 
0333   inline FEDBufferGenerator& FEDBufferGenerator::setHeaderType(const FEDHeaderType newHeaderType) {
0334     defaultTrackerSpecialHeader_.setHeaderType(newHeaderType);
0335     return *this;
0336   }
0337 
0338   inline FEDBufferGenerator& FEDBufferGenerator::setBufferFormat(const FEDBufferFormat newBufferFormat) {
0339     defaultTrackerSpecialHeader_.setBufferFormat(newBufferFormat);
0340     return *this;
0341   }
0342 
0343   inline FEDBufferGenerator& FEDBufferGenerator::setDAQEventType(const FEDDAQEventType newDAQEventType) {
0344     defaultDAQHeader_.setEventType(newDAQEventType);
0345     return *this;
0346   }
0347 
0348   inline FEDDAQHeader& FEDBufferGenerator::daqHeader() { return defaultDAQHeader_; }
0349 
0350   inline FEDDAQTrailer& FEDBufferGenerator::daqTrailer() { return defaultDAQTrailer_; }
0351 
0352   inline TrackerSpecialHeader& FEDBufferGenerator::trackerSpecialHeader() { return defaultTrackerSpecialHeader_; }
0353 
0354   inline FEDFEHeader& FEDBufferGenerator::feHeader() { return *defaultFEHeader_; }
0355 
0356   inline size_t FEDBufferGenerator::bufferSizeInBytes(const FEDFEHeader& feHeader, const FEDBufferPayload& payload) {
0357     //FE header + payload + tracker special header + daq header + daq trailer
0358     return feHeader.lengthInBytes() + payload.lengthInBytes() + 8 + 8 + 8;
0359   }
0360 
0361 }  // namespace sistrip
0362 
0363 #endif  //ndef EventFilter_SiStripRawToDigi_FEDBufferGenerator_H