QIE11DataFrame

Sample

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
#ifndef DATAFORMATS_HCALDIGI_QIE11DATAFRAME_H
#define DATAFORMATS_HCALDIGI_QIE11DATAFRAME_H

#include "DataFormats/HcalDetId/interface/HcalDetId.h"
#include "DataFormats/Common/interface/DataFrame.h"
#include <ostream>

/** Precision readout digi from QIE11 including TDC information

 */
class QIE11DataFrame {
public:
  static const int WORDS_PER_SAMPLE = 1;
  static const int HEADER_WORDS = 1;
  static const int FLAG_WORDS = 1;

  static const int OFFSET_FLAVOR = 12;
  static const int MASK_FLAVOR = 0x7;
  static const int FLAVOR_HB = 3;
  static const int MASK_LINKERROR = 0x800;

  constexpr QIE11DataFrame() {}
  constexpr QIE11DataFrame(edm::DataFrame const& df) : m_data(df) {}

  class Sample {
  public:
    constexpr Sample(const edm::DataFrame& frame, edm::DataFrame::size_type i) : frame_(frame), i_(i) {}
    static const int MASK_ADC = 0xFF;
    static const int MASK_TDC_HE = 0x3F;
    static const int MASK_TDC_HB = 0x3;
    static const int OFFSET_TDC = 8;  // 8 bits
    static const int MASK_SOI = 0x4000;
    static const int MASK_LE_HB = 0x2000;
    static const int MASK_CAPID = 0x3;
    static const int MASK_CAPID_INV_HB = 0xF3FF;
    static const int MASK_CAPID_KEEP_HB = 0x0C00;
    static const int OFFSET_CAPID_HE = 8;
    static const int OFFSET_CAPID_HB = 10;
    constexpr int flavor() const { return ((frame_[0] >> OFFSET_FLAVOR) & MASK_FLAVOR); }
    constexpr int adc() const { return frame_[i_] & MASK_ADC; }
    constexpr int tdc() const {
      return (frame_[i_] >> OFFSET_TDC) & ((flavor() == FLAVOR_HB) ? (MASK_TDC_HB) : (MASK_TDC_HE));
    }
    constexpr bool soi() const { return frame_[i_] & MASK_SOI; }
    constexpr int capid() const {
      return (flavor() == FLAVOR_HB)
                 ? ((frame_[i_] >> OFFSET_CAPID_HB) & MASK_CAPID)
                 : ((((frame_[0] >> OFFSET_CAPID_HE) & MASK_CAPID) + i_ - HEADER_WORDS) & MASK_CAPID);
    }
    constexpr bool linkError() const {
      return (flavor() == FLAVOR_HB) ? (frame_[i_] & MASK_LE_HB) : (frame_[0] & MASK_LINKERROR);
    }

  private:
    const edm::DataFrame& frame_;
    edm::DataFrame::size_type i_;
  };

  constexpr void copyContent(const QIE11DataFrame& digi) {
    for (edm::DataFrame::size_type i = 0; i < size() && i < digi.size(); i++) {
      Sample sam = digi[i];
      setSample(i, sam.adc(), sam.tdc(), sam.soi());
    }
  }

  /// Get the detector id
  constexpr DetId detid() const { return DetId(m_data.id()); }
  constexpr edm::DataFrame::id_type id() const { return m_data.id(); }
  /// more accessors
  constexpr edm::DataFrame::size_type size() const { return m_data.size(); }
  /// iterators
  constexpr edm::DataFrame::iterator begin() { return m_data.begin(); }
  constexpr edm::DataFrame::iterator end() { return m_data.end(); }
  constexpr edm::DataFrame::const_iterator begin() const { return m_data.begin(); }
  constexpr edm::DataFrame::const_iterator end() const { return m_data.end(); }
  /// total number of samples in the digi
  constexpr int samples() const { return (size() - HEADER_WORDS - FLAG_WORDS) / WORDS_PER_SAMPLE; }
  /// for backward compatibility
  constexpr int presamples() const {
    for (int i = 0; i < samples(); i++) {
      if ((*this)[i].soi())
        return i;
    }
    return -1;
  }
  /// get the flavor of the frame
  constexpr int flavor() const { return ((m_data[0] >> OFFSET_FLAVOR) & MASK_FLAVOR); }
  /// was there a link error?
  constexpr bool linkError() const { return m_data[0] & MASK_LINKERROR; }
  /// was there a capid rotation error?
  static const int MASK_CAPIDERROR = 0x400;
  constexpr bool capidError() const { return m_data[0] & MASK_CAPIDERROR; }
  /// was this a mark-and-pass ZS event?
  constexpr bool zsMarkAndPass() const { return (flavor() == 1); }
  /// set ZS params
  constexpr void setZSInfo(bool markAndPass) {
    if (markAndPass)
      m_data[0] |= (markAndPass & MASK_FLAVOR) << OFFSET_FLAVOR;
  }
  /// get the sample
  constexpr inline Sample operator[](edm::DataFrame::size_type i) const { return Sample(m_data, i + HEADER_WORDS); }

  // set flavor
  constexpr void setFlavor(int flavor) {
    m_data[0] &= 0x9FFF;  // inversion of flavor mask
    m_data[0] |= ((flavor & MASK_FLAVOR) << OFFSET_FLAVOR);
  }

  constexpr void setCapid0(int cap0) {
    if (flavor() == FLAVOR_HB) {
      for (int i = 0; i < samples(); i++) {
        m_data[i + 1] &= Sample::MASK_CAPID_INV_HB;
        m_data[i + 1] |= ((cap0 + i) & Sample::MASK_CAPID) << Sample::OFFSET_CAPID_HB;
      }
    } else {
      m_data[0] &= 0xFCFF;  // inversion of the capid0 mask
      m_data[0] |= ((cap0 & Sample::MASK_CAPID) << Sample::OFFSET_CAPID_HE);
    }
  }
  /// set the sample contents
  constexpr void setSample(edm::DataFrame::size_type isample, int adc, int tdc, bool soi = false) {
    if (isample >= size())
      return;
    if (flavor() == FLAVOR_HB)
      m_data[isample + 1] = (adc & Sample::MASK_ADC) | (soi ? (Sample::MASK_SOI) : (0)) |
                            ((tdc & Sample::MASK_TDC_HB) << Sample::OFFSET_TDC) |
                            (m_data[isample + 1] & Sample::MASK_CAPID_KEEP_HB);
    else
      m_data[isample + 1] = (adc & Sample::MASK_ADC) | (soi ? (Sample::MASK_SOI) : (0)) |
                            ((tdc & Sample::MASK_TDC_HE) << Sample::OFFSET_TDC);
  }
  /// get the flag word
  constexpr uint16_t flags() const { return m_data[size() - 1]; }
  /// set the flag word
  constexpr void setFlags(uint16_t v) { m_data[size() - 1] = v; }

private:
  edm::DataFrame m_data;
};

std::ostream& operator<<(std::ostream&, const QIE11DataFrame&);

#endif  // DATAFORMATS_HCALDIGI_QIE11DATAFRAME_H