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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
#ifndef DataFormats_SiPixelRecHitQuality_h
#define DataFormats_SiPixelRecHitQuality_h 1
#include <cmath>
class SiPixelRecHitQuality {
public:
typedef unsigned int QualWordType;
public:
class Packing {
public:
// Constructor: pre-computes masks and shifts from field widths
Packing();
public:
QualWordType probX_mask;
int probX_shift;
float probX_units;
double probX_1_over_log_units;
char probX_width;
//
QualWordType probY_mask;
int probY_shift;
float probY_units;
double probY_1_over_log_units;
char probY_width;
//
QualWordType qBin_mask;
int qBin_shift;
char qBin_width;
//
QualWordType edge_mask;
int edge_shift;
char edge_width;
//
QualWordType bad_mask;
int bad_shift;
char bad_width;
//
QualWordType twoROC_mask;
int twoROC_shift;
char twoROC_width;
//
QualWordType hasFilledProb_mask;
int hasFilledProb_shift;
char hasFilledProb_width;
char spare_width;
//--- Template fit probability, in X and Y directions
// To pack: int raw = - log(prob)/log(prob_units)
// Unpack : prob = prob_units^{-raw}
//
//--- We've obsoleted probX and probY in favor of probXY and probQ as of 09/10
inline float probabilityX(QualWordType qualWord) const {
warningObsolete();
return -10;
}
inline float probabilityY(QualWordType qualWord) const {
warningObsolete();
return -10;
}
inline float probabilityXY(QualWordType qualWord) const {
int raw = (qualWord >> probX_shift) & probX_mask;
if (raw < 0 || raw > 16383) {
warningOutOfBoundRaw("XY", raw, qualWord);
raw = 16383;
}
float prob = (raw == 16383) ? 0 : pow(probX_units, (float)(-raw));
// cout << "Bits = " << raw << " --> Prob = " << prob << endl;
return prob;
}
inline float probabilityQ(QualWordType qualWord) const {
int raw = (qualWord >> probY_shift) & probY_mask;
if (raw < 0 || raw > 255) {
warningOutOfBoundRaw("Q", raw, qualWord);
raw = 255;
}
float prob = (raw == 255) ? 0 : pow(probY_units, (float)(-raw));
// cout << "Bits = " << raw << " --> Prob = " << prob << endl;
return prob;
}
//
//--- Charge `bin' (0,1,2,3 ~ charge, qBin==4 is a new minimum charge state, qBin=5 is unphysical, qBin6,7 = unused)
inline int qBin(QualWordType qualWord) const {
int qbin = (qualWord >> qBin_shift) & qBin_mask;
if (qbin < 0 || qbin > 7) {
warningOutOfBoundQbin(qbin, qualWord);
qbin = 0;
}
return qbin;
}
//--- Quality flags (true or false):
//--- cluster is on the edge of the module, or straddles a dead ROC
inline bool isOnEdge(QualWordType qualWord) const { return (qualWord >> edge_shift) & edge_mask; }
//--- cluster contains bad pixels, or straddles bad column or two-column
inline bool hasBadPixels(QualWordType qualWord) const { return (qualWord >> bad_shift) & bad_mask; }
//--- the cluster spans two ROCS (and thus contains big pixels)
inline bool spansTwoROCs(QualWordType qualWord) const { return (qualWord >> twoROC_shift) & twoROC_mask; }
//--- the probability is filled
inline bool hasFilledProb(QualWordType qualWord) const {
return (qualWord >> hasFilledProb_shift) & hasFilledProb_mask;
}
//------------------------------------------------------
//--- Setters: the inverse of the above.
//------------------------------------------------------
//
inline void setProbabilityXY(float prob, QualWordType& qualWord) const {
if (prob > 1.0f && prob <= 1.0f + std::numeric_limits<float>::epsilon()) {
prob = 1;
} else if (prob < 0.0f || prob > 1.0f + std::numeric_limits<float>::epsilon()) {
warningOutOfBoundProb("XY", prob, qualWord);
prob = 0;
}
double draw = (prob <= 1.6E-13) ? 16383 : -log((double)prob) * probX_1_over_log_units;
unsigned int raw = (int)(draw + 0.5); // convert to integer, round correctly
// cout << "Prob = " << prob << " --> Bits = " << raw << endl;
qualWord |= ((raw & probX_mask) << probX_shift);
}
inline void setProbabilityQ(float prob, QualWordType& qualWord) const {
if (prob > 1.0f && prob <= 1.0f + std::numeric_limits<float>::epsilon()) {
prob = 1;
} else if (prob == -1.0f) {
// default prob in absence of Q probability computation is -1 --> set to 0
prob = 0;
} else if (prob < 0.0f || prob > 1.0f + std::numeric_limits<float>::epsilon()) {
warningOutOfBoundProb("Q", prob, qualWord);
prob = 0;
}
double draw = (prob <= 1E-5) ? 255 : -log((double)prob) * probY_1_over_log_units;
unsigned int raw = (int)(draw + 0.5); // convert to integer, round correctly
// cout << "Prob = " << prob << " --> Bits = " << raw << endl;
qualWord |= ((raw & probY_mask) << probY_shift);
}
inline void setQBin(int qbin, QualWordType& qualWord) const {
if (qbin < 0 || qbin > 7) {
warningOutOfBoundQbin(qbin, qualWord);
qbin = 0;
}
qualWord |= ((qbin & qBin_mask) << qBin_shift);
}
inline void setIsOnEdge(bool flag, QualWordType& qualWord) const { qualWord |= ((flag & edge_mask) << edge_shift); }
inline void setHasBadPixels(bool flag, QualWordType& qualWord) const {
qualWord |= ((flag & bad_mask) << bad_shift);
}
inline void setSpansTwoROCs(bool flag, QualWordType& qualWord) const {
qualWord |= ((flag & twoROC_mask) << twoROC_shift);
}
inline void setHasFilledProb(bool flag, QualWordType& qualWord) const {
qualWord |= ((flag & hasFilledProb_mask) << hasFilledProb_shift);
}
};
public:
static const Packing thePacking;
private:
static void warningObsolete();
static void warningOutOfBoundQbin(int, QualWordType const&);
static void warningOutOfBoundProb(const char* iVariable, float, QualWordType const&);
static void warningOutOfBoundRaw(const char* iVariable, int iRaw, QualWordType const&);
};
#endif
|