File indexing completed on 2024-04-06 12:04:18
0001 #ifndef DATAFORMATS_HCALDIGI_QIE10DATAFRAME_H
0002 #define DATAFORMATS_HCALDIGI_QIE10DATAFRAME_H
0003
0004 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
0005 #include "DataFormats/Common/interface/DataFrame.h"
0006 #include <ostream>
0007
0008
0009
0010
0011 class QIE10DataFrame {
0012 public:
0013 static const int WORDS_PER_SAMPLE = 2;
0014 static const int HEADER_WORDS = 1;
0015 static const int FLAG_WORDS = 1;
0016
0017 constexpr QIE10DataFrame() {}
0018 constexpr QIE10DataFrame(edm::DataFrame const& df) : m_data(df) {}
0019
0020 class Sample {
0021 public:
0022 typedef uint32_t wide_type;
0023
0024 constexpr Sample(const edm::DataFrame& frame, edm::DataFrame::size_type i)
0025 : word1_(frame[i]), word2_(frame[i + 1]) {}
0026 constexpr Sample(const edm::DataFrame::data_type& word1, const edm::DataFrame::data_type& word2)
0027 : word1_(word1), word2_(word2) {}
0028 explicit Sample(const wide_type wide) : word1_{0}, word2_{0} {
0029 static_assert(sizeof(wide) == 2 * sizeof(word1_), "The wide input type must be able to contain two words");
0030 const edm::DataFrame::data_type* ptr = reinterpret_cast<const edm::DataFrame::data_type*>(&wide);
0031 word1_ = ptr[0];
0032 word2_ = ptr[1];
0033 }
0034
0035 static const int MASK_ADC = 0xFF;
0036 static const int MASK_LE_TDC = 0x3F;
0037 static const int MASK_TE_TDC = 0x1F;
0038 static const int OFFSET_TE_TDC = 6;
0039 static const int MASK_SOI = 0x2000;
0040 static const int MASK_OK = 0x1000;
0041 static const int MASK_CAPID = 0x3;
0042 static const int OFFSET_CAPID = 12;
0043
0044 constexpr inline int adc() const { return word1_ & MASK_ADC; }
0045 constexpr inline int le_tdc() const { return word2_ & MASK_LE_TDC; }
0046 constexpr inline int te_tdc() const { return (word2_ >> OFFSET_TE_TDC) & MASK_TE_TDC; }
0047 constexpr inline bool ok() const { return word1_ & MASK_OK; }
0048 constexpr inline bool soi() const { return word1_ & MASK_SOI; }
0049 constexpr inline int capid() const { return (word2_ >> OFFSET_CAPID) & MASK_CAPID; }
0050 constexpr inline edm::DataFrame::data_type raw(edm::DataFrame::size_type i) const {
0051 return (i > WORDS_PER_SAMPLE) ? 0 : ((i == 1) ? word2_ : word1_);
0052 }
0053 QIE10DataFrame::Sample::wide_type wideRaw() const {
0054 static_assert(sizeof(QIE10DataFrame::Sample::wide_type) == 2 * sizeof(word1_),
0055 "The wide result type must be able to contain two words");
0056 wide_type result = 0;
0057 edm::DataFrame::data_type* ptr = reinterpret_cast<edm::DataFrame::data_type*>(&result);
0058 ptr[0] = word1_;
0059 ptr[1] = word2_;
0060 return result;
0061 }
0062
0063 private:
0064 edm::DataFrame::data_type word1_;
0065 edm::DataFrame::data_type word2_;
0066 };
0067
0068 constexpr void copyContent(const QIE10DataFrame& digi) {
0069 for (edm::DataFrame::size_type i = 0; i < size() && i < digi.size(); i++) {
0070 Sample sam = digi[i];
0071 setSample(i, sam.adc(), sam.le_tdc(), sam.te_tdc(), sam.capid(), sam.soi(), sam.ok());
0072 }
0073 }
0074
0075
0076 constexpr DetId detid() const { return DetId(m_data.id()); }
0077 constexpr edm::DataFrame::id_type id() const { return m_data.id(); }
0078
0079 constexpr edm::DataFrame::size_type size() const { return m_data.size(); }
0080
0081 constexpr edm::DataFrame::iterator begin() { return m_data.begin(); }
0082 constexpr edm::DataFrame::iterator end() { return m_data.end(); }
0083 constexpr edm::DataFrame::const_iterator begin() const { return m_data.begin(); }
0084 constexpr edm::DataFrame::const_iterator end() const { return m_data.end(); }
0085
0086 constexpr int samples() const { return (size() - HEADER_WORDS - FLAG_WORDS) / WORDS_PER_SAMPLE; }
0087
0088 constexpr int presamples() const {
0089 for (int i = 0; i < samples(); i++) {
0090 if ((*this)[i].soi())
0091 return i;
0092 }
0093 return -1;
0094 }
0095
0096 static const int OFFSET_FLAVOR = 12;
0097 static const int MASK_FLAVOR = 0x7;
0098 constexpr int flavor() const { return ((m_data[0] >> OFFSET_FLAVOR) & MASK_FLAVOR); }
0099
0100 static const int MASK_LINKERROR = 0x800;
0101 constexpr bool linkError() const { return m_data[0] & MASK_LINKERROR; }
0102
0103 static const int MASK_MARKPASS = 0x100;
0104 constexpr bool zsMarkAndPass() const { return m_data[0] & MASK_MARKPASS; }
0105
0106 constexpr void setZSInfo(bool markAndPass) {
0107 if (markAndPass)
0108 m_data[0] |= MASK_MARKPASS;
0109 }
0110
0111 constexpr inline Sample operator[](edm::DataFrame::size_type i) const {
0112 return Sample(m_data, i * WORDS_PER_SAMPLE + HEADER_WORDS);
0113 }
0114
0115 constexpr void setSample(
0116 edm::DataFrame::size_type isample, int adc, int le_tdc, int te_tdc, int capid, bool soi = false, bool ok = true) {
0117 if (isample >= size())
0118 return;
0119 m_data[isample * WORDS_PER_SAMPLE + HEADER_WORDS] =
0120 (adc & Sample::MASK_ADC) | (soi ? (Sample::MASK_SOI) : (0)) | (ok ? (Sample::MASK_OK) : (0));
0121 m_data[isample * WORDS_PER_SAMPLE + HEADER_WORDS + 1] =
0122 (le_tdc & Sample::MASK_LE_TDC) | ((te_tdc & Sample::MASK_TE_TDC) << Sample::OFFSET_TE_TDC) |
0123 ((capid & Sample::MASK_CAPID) << Sample::OFFSET_CAPID) | 0x4000;
0124 }
0125
0126 constexpr uint16_t flags() const { return m_data[size() - 1]; }
0127
0128 constexpr void setFlags(uint16_t v) { m_data[size() - 1] = v; }
0129
0130 private:
0131 edm::DataFrame m_data;
0132 };
0133
0134 std::ostream& operator<<(std::ostream&, const QIE10DataFrame&);
0135
0136 #endif