CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/EventFilter/SiStripRawToDigi/interface/SiStripFEDBufferGenerator.h

Go to the documentation of this file.
00001 #ifndef EventFilter_SiStripRawToDigi_SiStripFEDBufferGenerator_H
00002 #define EventFilter_SiStripRawToDigi_SiStripFEDBufferGenerator_H
00003 
00004 #include "boost/cstdint.hpp"
00005 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBufferComponents.h"
00006 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
00007 #include <vector>
00008 #include <list>
00009 #include <utility>
00010 #include <memory>
00011 
00012 namespace sistrip {
00013   
00014   //
00015   // Class definitions
00016   //
00017   
00018   class FEDStripData
00019     {
00020     public:
00021       //class used to represent channel data
00022       class ChannelData {
00023       public:
00024         ChannelData(bool dataIsAlreadyConvertedTo8Bit, const size_t numberOfSamples,
00025                     const std::pair<uint16_t,uint16_t> medians = std::make_pair<uint16_t>(0,0));
00026         //number of samples
00027         size_t size() const;
00028         //get common mode medians for first and second APV
00029         std::pair<uint16_t,uint16_t> getMedians() const;
00030         //set common mode medians for first and second APV
00031         void setMedians(const std::pair<uint16_t,uint16_t> values);
00032         //get the 10bit value to be used for raw modes
00033         uint16_t getSample(const uint16_t sampleNumber) const;
00034         //get the 8 bit value to be used for ZS modes, converting it as the FED does if specified in constructor
00035         uint8_t get8BitSample(const uint16_t sampleNumber) const;
00036         void setSample(const uint16_t sampleNumber, const uint16_t adcValue);
00037         //setting value directly is equivalent to get and set Sample but without length check
00038         uint16_t& operator [] (const size_t sampleNumber);
00039         const uint16_t& operator [] (const size_t sampleNumber) const;
00040       private:
00041         std::pair<uint16_t,uint16_t> medians_;
00042         std::vector<uint16_t> data_;
00043         bool dataIs8Bit_;
00044       };
00045       
00046       FEDStripData(const std::vector<ChannelData>& data);
00047       //specify whether the data is already in the 8bit ZS format (only affects what is returned by ChannelData::get8BitSample() if the value if >253)
00048       //if the data is for scope mode then specify the scope length
00049       FEDStripData(bool dataIsAlreadyConvertedTo8Bit = true, const size_t samplesPerChannel = STRIPS_PER_FEDCH);
00050       //access to elements
00051       ChannelData& operator [] (const uint8_t internalFEDChannelNum);
00052       const ChannelData& operator [] (const uint8_t internalFEDChannelNum) const;
00053       ChannelData& channel(const uint8_t internalFEDChannelNum);
00054       const ChannelData& channel(const uint8_t internalFEDChannelNum) const;
00055     private:
00056       std::vector<ChannelData> data_;
00057     };
00058   
00059   class FEDBufferPayload
00060     {
00061     public:
00062       FEDBufferPayload(const std::vector< std::vector<uint8_t> >& channelBuffers);
00063       //size of payload in bytes
00064       size_t lengthInBytes() const;
00065       //returns NULL if payload size is 0, otherwise return a pointer to the payload buffer
00066       const uint8_t* data() const;
00067       //size of FE unit payload
00068       uint16_t getFELength(const uint8_t internalFEUnitNum) const;
00069     private:
00070       void appendToBuffer(size_t* pIndexInBuffer, const uint8_t value);
00071       void appendToBuffer(size_t* pIndexInBuffer, std::vector<uint8_t>::const_iterator start, std::vector<uint8_t>::const_iterator finish);
00072       std::vector<uint8_t> data_;
00073       std::vector<uint16_t> feLengths_;
00074     };
00075   
00076   class FEDBufferPayloadCreator
00077     {
00078     public:
00079       //specify which FE units and channels should have data generated for them
00080       //If an FE unit is disabled then the channel is as well. The whole FE payload will be missing. 
00081       //If a channel is disabled then it is considered to have all zeros in the data but will be present in the data
00082       FEDBufferPayloadCreator(const std::vector<bool>& enabledFEUnits, const std::vector<bool>& enabledChannels);
00083       //create the payload for a particular mode
00084       FEDBufferPayload createPayload(const FEDReadoutMode mode, const FEDStripData& data) const;
00085       FEDBufferPayload operator () (const FEDReadoutMode mode, const FEDStripData& data) const;
00086     private:
00087       //fill vector with channel data
00088       void fillChannelBuffer(std::vector<uint8_t>* channelBuffer, const FEDReadoutMode mode,
00089                              const FEDStripData::ChannelData& data, const bool channelEnabled) const;
00090       //fill the vector with channel data for raw mode
00091       void fillRawChannelBuffer(std::vector<uint8_t>* channelBuffer, const uint8_t packetCode,
00092                                 const FEDStripData::ChannelData& data, const bool channelEnabled, const bool reorderData) const;
00093       //fill the vector with channel data for zero suppressed modes
00094       void fillZeroSuppressedChannelBuffer(std::vector<uint8_t>* channelBuffer, const FEDStripData::ChannelData& data, const bool channelEnabled) const;
00095       void fillZeroSuppressedLiteChannelBuffer(std::vector<uint8_t>* channelBuffer, const FEDStripData::ChannelData& data, const bool channelEnabled) const;
00096       //add the ZS cluster data for the channel to the end of the vector
00097       void fillClusterData(std::vector<uint8_t>* channelBuffer, const FEDStripData::ChannelData& data) const;
00098       std::vector<bool> feUnitsEnabled_;
00099       std::vector<bool> channelsEnabled_;
00100     };
00101   
00102   class FEDBufferGenerator
00103     {
00104     public:
00105       //constructor in which you can specify the defaults for some parameters
00106       FEDBufferGenerator(const uint32_t l1ID = 0,
00107                          const uint16_t bxID = 0,
00108                          const std::vector<bool>& feUnitsEnabled = std::vector<bool>(FEUNITS_PER_FED,true),
00109                          const std::vector<bool>& channelsEnabled = std::vector<bool>(FEDCH_PER_FED,true),
00110                          const FEDReadoutMode readoutMode = READOUT_MODE_ZERO_SUPPRESSED,
00111                          const FEDHeaderType headerType = HEADER_TYPE_FULL_DEBUG,
00112                          const FEDBufferFormat bufferFormat = BUFFER_FORMAT_OLD_SLINK,
00113                          const FEDDAQEventType evtType = DAQ_EVENT_TYPE_PHYSICS,
00114                          const FEDDataType dataType = DATA_TYPE_FAKE);
00115       //methods to get and set the defaults
00116       uint32_t getL1ID() const;
00117       uint16_t getBXID() const;
00118       FEDReadoutMode getReadoutMode() const;
00119       FEDHeaderType getHeaderType() const;
00120       FEDBufferFormat getBufferFormat() const;
00121       FEDDAQEventType getDAQEventType() const;
00122       FEDDataType getFEDDataType() const;
00123       FEDBufferGenerator& setL1ID(const uint32_t newL1ID);
00124       FEDBufferGenerator& setBXID(const uint16_t newBXID);
00125       FEDBufferGenerator& setReadoutMode(const FEDReadoutMode newReadoutMode);
00126       FEDBufferGenerator& setHeaderType(const FEDHeaderType newHeaderType);
00127       FEDBufferGenerator& setBufferFormat(const FEDBufferFormat newBufferFormat);
00128       FEDBufferGenerator& setDAQEventType(const FEDDAQEventType newDAQEventType);
00129       FEDBufferGenerator& setFEDDataType(const FEDDataType newFEDDataType);
00130       //disabled FE units produce no data at all
00131       //disabled channels have headers but data is all zeros (raw modes) or have no clusters (ZS)
00132       bool getFEUnitEnabled(const uint8_t internalFEUnitNumber) const;
00133       bool getChannelEnabled(const uint8_t internalFEDChannelNumber) const;
00134       FEDBufferGenerator& setFEUnitEnable(const uint8_t internalFEUnitNumber, const bool enabled);
00135       FEDBufferGenerator& setChannelEnable(const uint8_t internalFEDChannelNumber, const bool enabled);
00136       FEDBufferGenerator& setFEUnitEnables(const std::vector<bool>& feUnitsEnabled);
00137       FEDBufferGenerator& setChannelEnables(const std::vector<bool>& channelsEnabled);
00138       //make finer changes to defaults for parts of buffer
00139       //setting source ID in DAQ header and length and CRC in DAQ trailer has no effect since they are set when buffer is built
00140       FEDDAQHeader& daqHeader();
00141       FEDDAQTrailer& daqTrailer();
00142       TrackerSpecialHeader& trackerSpecialHeader();
00143       FEDFEHeader& feHeader();
00144       //method to generate buffer
00145       //unspecified parameters use defaults set by constructor or setters
00146       //FEDRawData object will be resized to fit buffer and filled
00147       void generateBuffer(FEDRawData* rawDataObject,
00148                           const FEDStripData& data,
00149                           const uint16_t sourceID) const;
00150     private:
00151       //method to fill buffer at pointer from pre generated components (only the length and CRC will be changed)
00152       //at least bufferSizeInBytes(feHeader,payload) must have already been allocated
00153       static void fillBuffer(uint8_t* pointerToStartOfBuffer,
00154                              const FEDDAQHeader& daqHeader,
00155                              const FEDDAQTrailer& daqTrailer,
00156                              const TrackerSpecialHeader& tkSpecialHeader,
00157                              const FEDFEHeader& feHeader,
00158                              const FEDBufferPayload& payload);
00159       //returns required size of buffer from given components
00160       static size_t bufferSizeInBytes(const FEDFEHeader& feHeader,
00161                                       const FEDBufferPayload& payload);
00162       //used to store default values
00163       FEDDAQHeader defaultDAQHeader_;
00164       FEDDAQTrailer defaultDAQTrailer_;
00165       TrackerSpecialHeader defaultTrackerSpecialHeader_;
00166       std::auto_ptr<FEDFEHeader> defaultFEHeader_;
00167       std::vector<bool> feUnitsEnabled_;
00168       std::vector<bool> channelsEnabled_;
00169     };
00170   
00171   //
00172   // Inline function definitions
00173   //
00174   
00175   //FEDStripData
00176   
00177   inline FEDStripData::FEDStripData(const std::vector<ChannelData>& data)
00178     : data_(data)
00179     { }
00180   
00181   //re-use non-const method
00182   inline FEDStripData::ChannelData& FEDStripData::channel(const uint8_t internalFEDChannelNum)
00183     {
00184       return const_cast<ChannelData&>(static_cast<const FEDStripData*>(this)->channel(internalFEDChannelNum));
00185     }
00186   
00187   inline FEDStripData::ChannelData& FEDStripData:: operator [] (const uint8_t internalFEDChannelNum)
00188     {
00189       return channel(internalFEDChannelNum);
00190     }
00191   
00192   inline const FEDStripData::ChannelData& FEDStripData:: operator [] (const uint8_t internalFEDChannelNum) const
00193     {
00194       return channel(internalFEDChannelNum);
00195     }
00196   
00197   inline FEDStripData::ChannelData::ChannelData(bool dataIsAlreadyConvertedTo8Bit, const size_t numberOfSamples,
00198                                                 const std::pair<uint16_t,uint16_t> medians)
00199     : medians_(medians),
00200       data_(numberOfSamples,0),
00201       dataIs8Bit_(dataIsAlreadyConvertedTo8Bit)
00202     { }
00203   
00204   inline size_t FEDStripData::ChannelData::size() const
00205     {
00206       return data_.size();
00207     }
00208   
00209   inline const uint16_t& FEDStripData::ChannelData::operator [] (const size_t sampleNumber) const
00210     {
00211       return data_[sampleNumber];
00212     }
00213   
00214   //re-use const method
00215   inline uint16_t& FEDStripData::ChannelData::operator [] (const size_t sampleNumber)
00216     {
00217       return const_cast<uint16_t&>(static_cast<const ChannelData&>(*this)[sampleNumber]);
00218     }
00219   
00220   inline uint16_t FEDStripData::ChannelData::getSample(const uint16_t sampleNumber) const
00221   {
00222     //try {
00223     //  return data_.at(sampleNumber);
00224     //} catch (const std::out_of_range&) {
00225     //  std::ostringstream ss;
00226     //  ss << "Sample index out of range. "
00227     //     << "Requesting sample " << sampleNumber
00228     //     << " when channel has only " << data_.size() << " samples.";
00229     //  throw cms::Exception("FEDBufferGenerator") << ss.str();
00230     //}
00231     return data_[sampleNumber];
00232   }
00233   
00234   inline uint8_t FEDStripData::ChannelData::get8BitSample(const uint16_t sampleNumber) const
00235   {
00236     if (dataIs8Bit_) return (0xFF & getSample(sampleNumber));
00237     else {
00238       const uint16_t sample = getSample(sampleNumber);
00239       if (sample < 0xFE) return sample;
00240       else if (sample == 0x3FF) return 0xFF;
00241       else return 0xFE;
00242     }
00243   }
00244   
00245   inline std::pair<uint16_t,uint16_t> FEDStripData::ChannelData::getMedians() const
00246     {
00247       return medians_;
00248     }
00249   
00250   inline void FEDStripData::ChannelData::setMedians(const std::pair<uint16_t,uint16_t> values)
00251     {
00252       medians_ = values;
00253     }
00254   
00255   //FEDBufferPayload
00256   
00257   inline size_t FEDBufferPayload::lengthInBytes() const
00258     {
00259       return data_.size();
00260     }
00261   
00262   inline void FEDBufferPayload::appendToBuffer(size_t* pIndexInBuffer, const uint8_t value)
00263     {
00264       data_[((*pIndexInBuffer)++)^7] = value;
00265     }
00266   
00267   inline void FEDBufferPayload::appendToBuffer(size_t* pIndexInBuffer, std::vector<uint8_t>::const_iterator start, std::vector<uint8_t>::const_iterator finish)
00268     {
00269       for (std::vector<uint8_t>::const_iterator iVal = start; iVal != finish; iVal++) {
00270         appendToBuffer(pIndexInBuffer,*iVal);
00271       }
00272     }
00273   
00274   //FEDBufferPayloadCreator
00275   
00276   inline FEDBufferPayloadCreator::FEDBufferPayloadCreator(const std::vector<bool>& feUnitsEnabled, const std::vector<bool>& channelsEnabled)
00277     : feUnitsEnabled_(feUnitsEnabled),
00278       channelsEnabled_(channelsEnabled)
00279     {}
00280   
00281   inline FEDBufferPayload FEDBufferPayloadCreator::operator () (const FEDReadoutMode mode, const FEDStripData& data) const
00282     {
00283       return createPayload(mode,data);
00284     }
00285   
00286   //FEDBufferGenerator
00287   
00288   inline uint32_t FEDBufferGenerator::getL1ID() const
00289     {
00290       return defaultDAQHeader_.l1ID();
00291     }
00292   
00293   inline uint16_t FEDBufferGenerator::getBXID() const
00294     {
00295       return defaultDAQHeader_.bxID();
00296     }
00297   
00298   inline FEDReadoutMode FEDBufferGenerator::getReadoutMode() const
00299     {
00300       return defaultTrackerSpecialHeader_.readoutMode();
00301     }
00302   
00303   inline FEDHeaderType FEDBufferGenerator::getHeaderType() const
00304     {
00305       return defaultTrackerSpecialHeader_.headerType();
00306     }
00307   
00308   inline FEDBufferFormat FEDBufferGenerator::getBufferFormat() const
00309     {
00310       return defaultTrackerSpecialHeader_.bufferFormat();
00311     }
00312   
00313   inline FEDDAQEventType FEDBufferGenerator::getDAQEventType() const
00314     {
00315       return defaultDAQHeader_.eventType();
00316     }
00317   
00318   inline FEDDataType FEDBufferGenerator::getFEDDataType() const
00319     {
00320       return defaultTrackerSpecialHeader_.dataType();
00321     }
00322   
00323   inline FEDBufferGenerator& FEDBufferGenerator::setL1ID(const uint32_t newL1ID)
00324     {
00325       defaultDAQHeader_.setL1ID(newL1ID);
00326       return *this;
00327     }
00328   
00329   inline FEDBufferGenerator& FEDBufferGenerator::setBXID(const uint16_t newBXID)
00330     {
00331       defaultDAQHeader_.setBXID(newBXID);
00332       return *this;
00333     }
00334   
00335   inline FEDBufferGenerator& FEDBufferGenerator::setReadoutMode(const FEDReadoutMode newReadoutMode)
00336     {
00337       defaultTrackerSpecialHeader_.setReadoutMode(newReadoutMode);
00338       return *this;
00339     }
00340   
00341   inline FEDBufferGenerator& FEDBufferGenerator::setHeaderType(const FEDHeaderType newHeaderType)
00342     {
00343       defaultTrackerSpecialHeader_.setHeaderType(newHeaderType);
00344       return *this;
00345     }
00346   
00347   inline FEDBufferGenerator& FEDBufferGenerator::setBufferFormat(const FEDBufferFormat newBufferFormat)
00348     {
00349       defaultTrackerSpecialHeader_.setBufferFormat(newBufferFormat);
00350       return *this;
00351     }
00352   
00353   inline FEDBufferGenerator& FEDBufferGenerator::setDAQEventType(const FEDDAQEventType newDAQEventType)
00354     {
00355       defaultDAQHeader_.setEventType(newDAQEventType);
00356       return *this;
00357     }
00358   
00359   inline FEDBufferGenerator& FEDBufferGenerator::setFEDDataType(const FEDDataType newFEDDataType)
00360     {
00361       defaultTrackerSpecialHeader_.setDataType(newFEDDataType);
00362       return *this;
00363     }
00364   
00365   inline FEDDAQHeader& FEDBufferGenerator::daqHeader()
00366     {
00367       return defaultDAQHeader_;
00368     }
00369   
00370   inline FEDDAQTrailer& FEDBufferGenerator::daqTrailer()
00371     {
00372       return defaultDAQTrailer_;
00373     }
00374   
00375   inline TrackerSpecialHeader& FEDBufferGenerator::trackerSpecialHeader()
00376     {
00377       return defaultTrackerSpecialHeader_;
00378     }
00379   
00380   inline FEDFEHeader& FEDBufferGenerator::feHeader()
00381     {
00382       return *defaultFEHeader_;
00383     }
00384   
00385   inline size_t FEDBufferGenerator::bufferSizeInBytes(const FEDFEHeader& feHeader,
00386                                                              const FEDBufferPayload& payload)
00387     {
00388       //FE header + payload + tracker special header + daq header + daq trailer
00389       return feHeader.lengthInBytes()+payload.lengthInBytes()+8+8+8;
00390     }
00391   
00392 }
00393 
00394 #endif //ndef EventFilter_SiStripRawToDigi_FEDBufferGenerator_H