Back to home page

Project CMSSW displayed by LXR

 
 

    


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 /** Precision readout digi from QIE10 including TDC information
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   /// Get the detector id
0076   constexpr DetId detid() const { return DetId(m_data.id()); }
0077   constexpr edm::DataFrame::id_type id() const { return m_data.id(); }
0078   /// more accessors
0079   constexpr edm::DataFrame::size_type size() const { return m_data.size(); }
0080   /// iterators
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   /// total number of samples in the digi
0086   constexpr int samples() const { return (size() - HEADER_WORDS - FLAG_WORDS) / WORDS_PER_SAMPLE; }
0087   /// for backward compatibility
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   /// get the flavor of the frame
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   /// was there a link error?
0100   static const int MASK_LINKERROR = 0x800;
0101   constexpr bool linkError() const { return m_data[0] & MASK_LINKERROR; }
0102   /// was this a mark-and-pass ZS event?
0103   static const int MASK_MARKPASS = 0x100;
0104   constexpr bool zsMarkAndPass() const { return m_data[0] & MASK_MARKPASS; }
0105   /// set ZS params
0106   constexpr void setZSInfo(bool markAndPass) {
0107     if (markAndPass)
0108       m_data[0] |= MASK_MARKPASS;
0109   }
0110   /// get the sample
0111   constexpr inline Sample operator[](edm::DataFrame::size_type i) const {
0112     return Sample(m_data, i * WORDS_PER_SAMPLE + HEADER_WORDS);
0113   }
0114   /// set the sample contents
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;  // 0x4000 marks this as second word of a pair
0124   }
0125   /// get the flag word
0126   constexpr uint16_t flags() const { return m_data[size() - 1]; }
0127   /// set the flag word
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  // DATAFORMATS_HCALDIGI_QIE10DATAFRAME_H