FEDSpyBuffer

FEDSpyChannelUnpacker

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
#ifndef DQM_SiStripMonitorHardware_SiStripFEDSpyBuffer_H
#define DQM_SiStripMonitorHardware_SiStripFEDSpyBuffer_H

#include <string>
#include <ostream>
#include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBufferComponents.h"
#include <cstdint>

namespace sistrip {

  //
  // Constants
  //

  static const uint16_t FEDCH_PER_DELAY_CHIP = 4;
  static const uint16_t DELAY_CHIPS_PER_FED = FEDCH_PER_FED / FEDCH_PER_DELAY_CHIP;
  static const uint16_t SPY_DELAY_CHIP_PAYLOAD_SIZE_IN_BYTES = 376 * 4;  // 376 32bit words
  static const uint16_t SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES =
      SPY_DELAY_CHIP_PAYLOAD_SIZE_IN_BYTES + 8;                  // Extra 8 bytes for counters
  static const uint16_t SPY_DELAYCHIP_DATA_OFFSET_IN_BITS = 44;  // Offset to start of data
  //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;
  // TW Dirty hack to lose the 3 samples from the end that screw things up...
  static const uint16_t SPY_SAMPLES_PER_CHANNEL = 298;
  static const uint16_t SPY_BUFFER_SIZE_IN_BYTES = SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES * DELAY_CHIPS_PER_FED + 40;
  // Delaychip data + 8 bytes header for counters + 8 bytes for word with delay chip enable bits
  // + 16 bytes for DAQ header and trailer

  //
  // Class definitions
  //

  //class representing spy channel buffers
  class FEDSpyBuffer : public FEDBufferBase {
  public:
    /**
     * constructor from a FEDRawData buffer
     *
     * The sistrip::preconstructCheckFEDSpyBuffer() method should be used
     * to check the validity of fedBuffer before constructing a sistrip::FEDBuffer.
     *
     * @see sistrip::preconstructCheckFEDSpyBuffer()
     */
    //construct from buffer
    explicit FEDSpyBuffer(const FEDRawData& fedBuffer);
    ~FEDSpyBuffer() override;
    void print(std::ostream& os) const override;

    //get the run number from the corresponding global run
    uint32_t globalRunNumber() const;
    //get the L1 ID stored in the spy header
    uint32_t spyHeaderL1ID() const;
    //get the total frame count stored in the spy header
    uint32_t spyHeaderTotalEventCount() const;
    //get the L1 ID after reading a given delay chip
    uint32_t delayChipL1ID(const uint8_t delayChip) const;
    //get the total event count after reading a given delay chip
    uint32_t delayChipTotalEventCount(const uint8_t delayChip) const;

    //checks that a delay chip is complete i.e. that it all came from the same event
    bool delayChipGood(const uint8_t delayChip) const;
    //checks that a channel is usable (i.e. that the delay chip it is on is good)
    bool channelGood(const uint8_t internalFEDannelNum) const override;

  private:
    //mapping of channel index to position in data
    static const uint8_t channelPositionsInData_[FEDCH_PER_DELAY_CHIP];

    //setup the channel objects
    void findChannels();

    const uint8_t* payloadPointer_;
    uint16_t payloadLength_;
    uint8_t versionId_;
  };

  class FEDSpyChannelUnpacker {
  public:
    explicit FEDSpyChannelUnpacker(const FEDChannel& channel);
    uint16_t sampleNumber() const;
    uint16_t adc() const;
    bool hasData() const;
    FEDSpyChannelUnpacker& operator++();
    FEDSpyChannelUnpacker& operator++(int);

  private:
    const uint32_t* data_;
    size_t currentOffset_;
    uint16_t currentSample_;
    uint16_t valuesLeft_;
  };

  //
  // Inline function definitions
  //

  /**
   * Check if a FEDRawData object satisfies the requirements for constructing a sistrip::FEDSpyBuffer
   *
   * These are:
   *   - those from sistrip::preconstructCheckFEDBufferBase() (with checkRecognizedFormat equal to true)
   *   - the readout mode should be equal to sistrip::READOUT_MODE_SPY
   *
   * In case any check fails, a value different from sistrip::FEDBufferStatusCode::SUCCESS
   * is returned, and detailed information printed to LogDebug("FEDBuffer"), if relevant.
   *
   * @see sistrip::preconstructCheckFEDBufferBase()
   */
  inline FEDBufferStatusCode preconstructCheckFEDSpyBuffer(const FEDRawData& fedBuffer) {
    const auto st_base = preconstructCheckFEDBufferBase(fedBuffer, true);
    if (FEDBufferStatusCode::SUCCESS != st_base)
      return st_base;
    const TrackerSpecialHeader hdr{fedBuffer.data() + 8};
    if (READOUT_MODE_SPY != hdr.readoutMode())
      return FEDBufferStatusCode::EXPECT_SPY;
    return FEDBufferStatusCode::SUCCESS;
  }

  //FEDSpyChannelUnpacker

  inline FEDSpyChannelUnpacker::FEDSpyChannelUnpacker(const FEDChannel& channel)
      : data_(reinterpret_cast<const uint32_t*>(channel.data())),
        currentOffset_(channel.offset()),
        currentSample_(0),
        valuesLeft_(channel.length()) {}

  inline uint16_t FEDSpyChannelUnpacker::sampleNumber() const { return currentSample_; }

  inline bool FEDSpyChannelUnpacker::hasData() const { return (valuesLeft_ != 0); }

  inline FEDSpyChannelUnpacker& FEDSpyChannelUnpacker::operator++() {
    currentOffset_ += FEDCH_PER_DELAY_CHIP * 10;
    currentSample_++;
    valuesLeft_--;
    return (*this);
  }

  inline FEDSpyChannelUnpacker& FEDSpyChannelUnpacker::operator++(int) {
    ++(*this);
    return *this;
  }

}  // namespace sistrip

#endif  //ndef DQM_SiStripMonitorHardware_SiStripFEDSpyBuffer_H