Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:08:48

0001 #ifndef DQM_SiStripMonitorHardware_SiStripFEDSpyBuffer_H
0002 #define DQM_SiStripMonitorHardware_SiStripFEDSpyBuffer_H
0003 
0004 #include <string>
0005 #include <ostream>
0006 #include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBufferComponents.h"
0007 #include <cstdint>
0008 
0009 namespace sistrip {
0010 
0011   //
0012   // Constants
0013   //
0014 
0015   static const uint16_t FEDCH_PER_DELAY_CHIP = 4;
0016   static const uint16_t DELAY_CHIPS_PER_FED = FEDCH_PER_FED / FEDCH_PER_DELAY_CHIP;
0017   static const uint16_t SPY_DELAY_CHIP_PAYLOAD_SIZE_IN_BYTES = 376 * 4;  // 376 32bit words
0018   static const uint16_t SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES =
0019       SPY_DELAY_CHIP_PAYLOAD_SIZE_IN_BYTES + 8;                  // Extra 8 bytes for counters
0020   static const uint16_t SPY_DELAYCHIP_DATA_OFFSET_IN_BITS = 44;  // Offset to start of data
0021   //static const uint16_t SPY_SAMPLES_PER_CHANNEL = ( (SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES * 8) - SPY_DELAYCHIP_DATA_OFFSET_IN_BITS ) / 10 / FEDCH_PER_DELAY_CHIP;
0022   // TW Dirty hack to lose the 3 samples from the end that screw things up...
0023   static const uint16_t SPY_SAMPLES_PER_CHANNEL = 298;
0024   static const uint16_t SPY_BUFFER_SIZE_IN_BYTES = SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES * DELAY_CHIPS_PER_FED + 40;
0025   // Delaychip data + 8 bytes header for counters + 8 bytes for word with delay chip enable bits
0026   // + 16 bytes for DAQ header and trailer
0027 
0028   //
0029   // Class definitions
0030   //
0031 
0032   //class representing spy channel buffers
0033   class FEDSpyBuffer : public FEDBufferBase {
0034   public:
0035     /**
0036      * constructor from a FEDRawData buffer
0037      *
0038      * The sistrip::preconstructCheckFEDSpyBuffer() method should be used
0039      * to check the validity of fedBuffer before constructing a sistrip::FEDBuffer.
0040      *
0041      * @see sistrip::preconstructCheckFEDSpyBuffer()
0042      */
0043     //construct from buffer
0044     explicit FEDSpyBuffer(const FEDRawData& fedBuffer);
0045     ~FEDSpyBuffer() override;
0046     void print(std::ostream& os) const override;
0047 
0048     //get the run number from the corresponding global run
0049     uint32_t globalRunNumber() const;
0050     //get the L1 ID stored in the spy header
0051     uint32_t spyHeaderL1ID() const;
0052     //get the total frame count stored in the spy header
0053     uint32_t spyHeaderTotalEventCount() const;
0054     //get the L1 ID after reading a given delay chip
0055     uint32_t delayChipL1ID(const uint8_t delayChip) const;
0056     //get the total event count after reading a given delay chip
0057     uint32_t delayChipTotalEventCount(const uint8_t delayChip) const;
0058 
0059     //checks that a delay chip is complete i.e. that it all came from the same event
0060     bool delayChipGood(const uint8_t delayChip) const;
0061     //checks that a channel is usable (i.e. that the delay chip it is on is good)
0062     bool channelGood(const uint8_t internalFEDannelNum) const override;
0063 
0064   private:
0065     //mapping of channel index to position in data
0066     static const uint8_t channelPositionsInData_[FEDCH_PER_DELAY_CHIP];
0067 
0068     //setup the channel objects
0069     void findChannels();
0070 
0071     const uint8_t* payloadPointer_;
0072     uint16_t payloadLength_;
0073     uint8_t versionId_;
0074   };
0075 
0076   class FEDSpyChannelUnpacker {
0077   public:
0078     explicit FEDSpyChannelUnpacker(const FEDChannel& channel);
0079     uint16_t sampleNumber() const;
0080     uint16_t adc() const;
0081     bool hasData() const;
0082     FEDSpyChannelUnpacker& operator++();
0083     FEDSpyChannelUnpacker& operator++(int);
0084 
0085   private:
0086     const uint32_t* data_;
0087     size_t currentOffset_;
0088     uint16_t currentSample_;
0089     uint16_t valuesLeft_;
0090   };
0091 
0092   //
0093   // Inline function definitions
0094   //
0095 
0096   /**
0097    * Check if a FEDRawData object satisfies the requirements for constructing a sistrip::FEDSpyBuffer
0098    *
0099    * These are:
0100    *   - those from sistrip::preconstructCheckFEDBufferBase() (with checkRecognizedFormat equal to true)
0101    *   - the readout mode should be equal to sistrip::READOUT_MODE_SPY
0102    *
0103    * In case any check fails, a value different from sistrip::FEDBufferStatusCode::SUCCESS
0104    * is returned, and detailed information printed to LogDebug("FEDBuffer"), if relevant.
0105    *
0106    * @see sistrip::preconstructCheckFEDBufferBase()
0107    */
0108   inline FEDBufferStatusCode preconstructCheckFEDSpyBuffer(const FEDRawData& fedBuffer) {
0109     const auto st_base = preconstructCheckFEDBufferBase(fedBuffer, true);
0110     if (FEDBufferStatusCode::SUCCESS != st_base)
0111       return st_base;
0112     const TrackerSpecialHeader hdr{fedBuffer.data() + 8};
0113     if (READOUT_MODE_SPY != hdr.readoutMode())
0114       return FEDBufferStatusCode::EXPECT_SPY;
0115     return FEDBufferStatusCode::SUCCESS;
0116   }
0117 
0118   //FEDSpyChannelUnpacker
0119 
0120   inline FEDSpyChannelUnpacker::FEDSpyChannelUnpacker(const FEDChannel& channel)
0121       : data_(reinterpret_cast<const uint32_t*>(channel.data())),
0122         currentOffset_(channel.offset()),
0123         currentSample_(0),
0124         valuesLeft_(channel.length()) {}
0125 
0126   inline uint16_t FEDSpyChannelUnpacker::sampleNumber() const { return currentSample_; }
0127 
0128   inline bool FEDSpyChannelUnpacker::hasData() const { return (valuesLeft_ != 0); }
0129 
0130   inline FEDSpyChannelUnpacker& FEDSpyChannelUnpacker::operator++() {
0131     currentOffset_ += FEDCH_PER_DELAY_CHIP * 10;
0132     currentSample_++;
0133     valuesLeft_--;
0134     return (*this);
0135   }
0136 
0137   inline FEDSpyChannelUnpacker& FEDSpyChannelUnpacker::operator++(int) {
0138     ++(*this);
0139     return *this;
0140   }
0141 
0142 }  // namespace sistrip
0143 
0144 #endif  //ndef DQM_SiStripMonitorHardware_SiStripFEDSpyBuffer_H