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
|
#ifndef DATAFORMATS_HCALDIGI_QIE10DATAFRAME_H
#define DATAFORMATS_HCALDIGI_QIE10DATAFRAME_H
#include "DataFormats/HcalDetId/interface/HcalDetId.h"
#include "DataFormats/Common/interface/DataFrame.h"
#include <ostream>
/** Precision readout digi from QIE10 including TDC information
*/
class QIE10DataFrame {
public:
static const int WORDS_PER_SAMPLE = 2;
static const int HEADER_WORDS = 1;
static const int FLAG_WORDS = 1;
constexpr QIE10DataFrame() {}
constexpr QIE10DataFrame(edm::DataFrame const& df) : m_data(df) {}
class Sample {
public:
typedef uint32_t wide_type;
constexpr Sample(const edm::DataFrame& frame, edm::DataFrame::size_type i)
: word1_(frame[i]), word2_(frame[i + 1]) {}
constexpr Sample(const edm::DataFrame::data_type& word1, const edm::DataFrame::data_type& word2)
: word1_(word1), word2_(word2) {}
explicit Sample(const wide_type wide) : word1_{0}, word2_{0} {
static_assert(sizeof(wide) == 2 * sizeof(word1_), "The wide input type must be able to contain two words");
const edm::DataFrame::data_type* ptr = reinterpret_cast<const edm::DataFrame::data_type*>(&wide);
word1_ = ptr[0];
word2_ = ptr[1];
}
static const int MASK_ADC = 0xFF;
static const int MASK_LE_TDC = 0x3F;
static const int MASK_TE_TDC = 0x1F;
static const int OFFSET_TE_TDC = 6;
static const int MASK_SOI = 0x2000;
static const int MASK_OK = 0x1000;
static const int MASK_CAPID = 0x3;
static const int OFFSET_CAPID = 12;
constexpr inline int adc() const { return word1_ & MASK_ADC; }
constexpr inline int le_tdc() const { return word2_ & MASK_LE_TDC; }
constexpr inline int te_tdc() const { return (word2_ >> OFFSET_TE_TDC) & MASK_TE_TDC; }
constexpr inline bool ok() const { return word1_ & MASK_OK; }
constexpr inline bool soi() const { return word1_ & MASK_SOI; }
constexpr inline int capid() const { return (word2_ >> OFFSET_CAPID) & MASK_CAPID; }
constexpr inline edm::DataFrame::data_type raw(edm::DataFrame::size_type i) const {
return (i > WORDS_PER_SAMPLE) ? 0 : ((i == 1) ? word2_ : word1_);
}
QIE10DataFrame::Sample::wide_type wideRaw() const {
static_assert(sizeof(QIE10DataFrame::Sample::wide_type) == 2 * sizeof(word1_),
"The wide result type must be able to contain two words");
wide_type result = 0;
edm::DataFrame::data_type* ptr = reinterpret_cast<edm::DataFrame::data_type*>(&result);
ptr[0] = word1_;
ptr[1] = word2_;
return result;
}
private:
edm::DataFrame::data_type word1_;
edm::DataFrame::data_type word2_;
};
constexpr void copyContent(const QIE10DataFrame& digi) {
for (edm::DataFrame::size_type i = 0; i < size() && i < digi.size(); i++) {
Sample sam = digi[i];
setSample(i, sam.adc(), sam.le_tdc(), sam.te_tdc(), sam.capid(), sam.soi(), sam.ok());
}
}
/// 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
static const int OFFSET_FLAVOR = 12;
static const int MASK_FLAVOR = 0x7;
constexpr int flavor() const { return ((m_data[0] >> OFFSET_FLAVOR) & MASK_FLAVOR); }
/// was there a link error?
static const int MASK_LINKERROR = 0x800;
constexpr bool linkError() const { return m_data[0] & MASK_LINKERROR; }
/// was this a mark-and-pass ZS event?
static const int MASK_MARKPASS = 0x100;
constexpr bool zsMarkAndPass() const { return m_data[0] & MASK_MARKPASS; }
/// set ZS params
constexpr void setZSInfo(bool markAndPass) {
if (markAndPass)
m_data[0] |= MASK_MARKPASS;
}
/// get the sample
constexpr inline Sample operator[](edm::DataFrame::size_type i) const {
return Sample(m_data, i * WORDS_PER_SAMPLE + HEADER_WORDS);
}
/// set the sample contents
constexpr void setSample(
edm::DataFrame::size_type isample, int adc, int le_tdc, int te_tdc, int capid, bool soi = false, bool ok = true) {
if (isample >= size())
return;
m_data[isample * WORDS_PER_SAMPLE + HEADER_WORDS] =
(adc & Sample::MASK_ADC) | (soi ? (Sample::MASK_SOI) : (0)) | (ok ? (Sample::MASK_OK) : (0));
m_data[isample * WORDS_PER_SAMPLE + HEADER_WORDS + 1] =
(le_tdc & Sample::MASK_LE_TDC) | ((te_tdc & Sample::MASK_TE_TDC) << Sample::OFFSET_TE_TDC) |
((capid & Sample::MASK_CAPID) << Sample::OFFSET_CAPID) | 0x4000; // 0x4000 marks this as second word of a pair
}
/// 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 QIE10DataFrame&);
#endif // DATAFORMATS_HCALDIGI_QIE10DATAFRAME_H
|