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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
|
//-------------------------------------------------
//
/* L1MuPacking
*
* define abstract packing and three implementations
*
*/
//
// $Date: 2008/04/16 23:25:10 $
// $Revision: 1.4 $
//
// Original Author :
// H. Sakulin HEPHY Vienna
//
// Migrated to CMSSW:
// I. Mikulec
//
//--------------------------------------------------
#ifndef CondFormatsL1TObjects_L1MuPacking_h
#define CondFormatsL1TObjects_L1MuPacking_h
#include "CondFormats/Serialization/interface/Serializable.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include <cstdlib>
#include <limits>
/**
* \class L1MuPacking
*
* Abstract Packing of an int in a bit-field
*/
class L1MuPacking {
public:
virtual ~L1MuPacking() {}
/// get the sign from the packed notation (0=positive, 1=negative)
virtual int signFromPacked(unsigned packed) const = 0;
/// get the value from the packed notation
virtual int idxFromPacked(unsigned packed) const = 0;
/// get the packed notation of a value
virtual unsigned packedFromIdx(int idx) const = 0;
COND_SERIALIZABLE;
};
/**
* \class L1MuUnsignedPacking
*
* Packing of an unsigned int in a bit field
*/
template <unsigned int Bits>
class L1MuUnsignedPacking : public L1MuPacking {
public:
/// get the sign from the packed notation. always psitive (0)
int signFromPacked(unsigned packed) const override { return 0; };
/// get the value from the packed notation (always positive)
int idxFromPacked(unsigned packed) const override { return (int)packed; };
/// get the packed notation of a value, check the range
unsigned packedFromIdx(int idx) const override {
if (idx >= (1 << Bits))
edm::LogWarning("ScaleRangeViolation")
<< "L1MuUnignedPacking::packedFromIdx: warning value " << idx << "exceeds " << Bits << "-bit range !!!";
return (unsigned)idx;
};
};
class L1MuUnsignedPackingGeneric : public L1MuPacking {
public:
/// get the sign from the packed notation. always psitive (0)
static int signFromPacked(unsigned packed, unsigned int nbits) { return 0; };
/// get the value from the packed notation (always positive)
static int idxFromPacked(unsigned packed, unsigned int nbits) { return (int)packed; };
/// get the packed notation of a value, check the range
static unsigned packedFromIdx(int idx, unsigned int nbits) {
if (idx >= (1 << nbits))
edm::LogWarning("ScaleRangeViolation")
<< "L1MuUnignedPacking::packedFromIdx: warning value " << idx << "exceeds " << nbits << "-bit range !!!";
return (unsigned)idx;
};
private:
int signFromPacked(unsigned packed) const = 0;
int idxFromPacked(unsigned packed) const = 0;
unsigned packedFromIdx(int idx) const = 0;
};
/**
* \class L1MuSignedPacking
*
* Packing of a signed int in a bit field (2's complement)
*/
template <unsigned int Bits>
class L1MuSignedPacking : public L1MuPacking {
public:
/// get the sign from the packed notation (0=positive, 1=negative)
int signFromPacked(unsigned packed) const override { return packed & (1 << (Bits - 1)) ? 1 : 0; };
/// get the value from the packed notation (+/-)
int idxFromPacked(unsigned packed) const override {
return packed & (1 << (Bits - 1)) ? (packed - (1 << Bits)) : packed;
};
/// get the packed notation of a value, check range
unsigned packedFromIdx(int idx) const override {
unsigned maxabs = 1U << (Bits - 1);
if (idx < -(int)maxabs && idx >= (int)maxabs)
edm::LogWarning("ScaleRangeViolation")
<< "L1MuSignedPacking::packedFromIdx: warning value " << idx << "exceeds " << Bits << "-bit range !!!";
return ~(std::numeric_limits<unsigned>::max() << Bits) & (idx < 0 ? (1U << Bits) + idx : idx);
};
};
class L1MuSignedPackingGeneric : public L1MuPacking {
public:
/// get the sign from the packed notation (0=positive, 1=negative)
static int signFromPacked(unsigned packed, unsigned int nbits) { return packed & (1 << (nbits - 1)) ? 1 : 0; };
/// get the value from the packed notation (+/-)
static int idxFromPacked(unsigned packed, unsigned int nbits) {
return packed & (1 << (nbits - 1)) ? (packed - (1 << nbits)) : packed;
};
/// get the packed notation of a value, check range
static unsigned packedFromIdx(int idx, unsigned int nbits) {
unsigned maxabs = 1U << (nbits - 1);
if (idx < -(int)maxabs && idx >= (int)maxabs)
edm::LogWarning("ScaleRangeViolation")
<< "L1MuSignedPacking::packedFromIdx: warning value " << idx << "exceeds " << nbits << "-bit range !!!";
return ~(std::numeric_limits<unsigned>::max() << nbits) & (idx < 0 ? (1U << nbits) + idx : idx);
};
private:
int signFromPacked(unsigned packed) const = 0;
int idxFromPacked(unsigned packed) const = 0;
unsigned packedFromIdx(int idx) const = 0;
};
/**
* \class L1MuPseudoSignedPacking
*
* Packing of a signed int in a bit field (pseudo-sign)
*
* There is a -0 and a +0 in the pseudo-signed scale
*/
class L1MuPseudoSignedPacking : public L1MuPacking {
public:
L1MuPseudoSignedPacking() {}
~L1MuPseudoSignedPacking() override {}
L1MuPseudoSignedPacking(unsigned int nbits) : m_nbits(nbits) {}
/// get the (pseudo-)sign from the packed notation (0=positive, 1=negative)
int signFromPacked(unsigned packed) const override { return (packed & (1 << (m_nbits - 1))) ? 1 : 0; };
/// get the value from the packed notation (+/-)
int idxFromPacked(unsigned packed) const override {
unsigned mask = (1 << (m_nbits - 1)) - 1; // for lower bits
int absidx = (int)(packed & mask);
unsigned psmask = (1 << (m_nbits - 1));
return absidx * (((packed & psmask) == psmask) ? -1 : 1); // pseudo sign==1 is negative
};
/// get the packed notation of a value, check range
unsigned packedFromIdx(int idx) const override {
unsigned packed = std::abs(idx);
unsigned maxabs = (1 << (m_nbits - 1)) - 1;
if (packed > maxabs)
edm::LogWarning("ScaleRangeViolation") << "L1MuPseudoSignedPacking::packedFromIdx: warning value " << idx
<< "exceeds " << m_nbits << "-bit range !!!";
if (idx < 0)
packed |= 1 << (m_nbits - 1);
return packed;
}
/// get the packed notation of a value, check range; sets the sign separately, 1 is neg. sign(!)
virtual unsigned packedFromIdx(int idx, int sig) const {
unsigned packed = std::abs(idx);
unsigned maxabs = (1 << (m_nbits - 1)) - 1;
if (packed > maxabs)
edm::LogWarning("ScaleRangeViolation") << "L1MuPseudoSignedPacking::packedFromIdx: warning value " << idx
<< "exceeds " << m_nbits << "-bit range !!!";
if (sig == 1)
packed |= 1 << (m_nbits - 1); // sig==1 is negative
return packed;
}
private:
unsigned int m_nbits;
COND_SERIALIZABLE;
};
#endif
|