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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
|
//-------------------------------------------------
//
// \class L1MuScale
//
// Description: A Scale for use in the L1 muon trigger
//
//
//
// $Date: 2011/05/30 04:59:35 $
// $Revision: 1.8 $
//
// Original Author :
// Hannes Sakulin HEPHY / Vienna
//
// Migrated to CMSSW:
// I. Mikulec
//
//--------------------------------------------------
#ifndef CondFormatsL1TObjects_L1MuScale_h
#define CondFormatsL1TObjects_L1MuScale_h
#include "CondFormats/Serialization/interface/Serializable.h"
#include <iostream>
#include <sstream>
#include <iomanip>
#include <vector>
#include <cmath>
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "CondFormats/L1TObjects/interface/L1MuPacking.h"
/**
* \class L1MuScale
*
* define the abstract interface to all scales
*/
class L1MuScale {
public:
L1MuScale() {}
virtual ~L1MuScale() {}
/// get the center of bin represented by packed
virtual float getCenter(unsigned packed) const = 0;
/// get the low edge of bin represented by packed
virtual float getLowEdge(unsigned packed) const = 0;
/// get the upper edge of bin represented by packed
virtual float getHighEdge(unsigned packed) const = 0;
/// get the upper edge of the last bin
virtual float getScaleMax() const = 0;
/// get the lower edge of the first bin
virtual float getScaleMin() const = 0;
/// pack a value
virtual unsigned getPacked(float value) const = 0;
/// get number of bins
virtual unsigned getNBins() const = 0;
/// get value of the underlying vector for bin i
virtual float getValue(unsigned i) const = 0;
virtual std::string print() const = 0;
private:
COND_SERIALIZABLE;
};
//
// define default scale implementations
//
/**
* \class L1MuBinnedScale
*
* implements a continuous scale of NBins bins.
*
* the index into the binned scale runs from 0 to NBins-1.
*
* It is packed into a data word (unsigned) using a Packing (template parameter)
*
* If the packing accepts negative values, an offset can be specified which
* will be subtracted from the index before packing. ( The offset is in turn added to the packed
* value before using it as an index into the scale.)
*
*/
class L1MuBinnedScale : public L1MuScale {
public:
///
/// constructor
///
/// packing is a pointer to a packing object. The L1MuBinnedScale
/// takes ownership of the packing object and deletes it in its
/// destructor
///
L1MuBinnedScale() : m_nbits(0), m_signedPacking(false), m_NBins(0), m_idxoffset(0) {}
/// NBins=number of bins, Scale[NBins+1]=bin edges, idx_offset=offeset to index (if stored as signed)
///
// L1MuBinnedScale(unsigned int nbits, bool signedPacking, int NBins, const float* Scale, int idx_offset=0)
L1MuBinnedScale(
unsigned int nbits, bool signedPacking, int NBins, const std::vector<double>& Scale, int idx_offset = 0)
: m_nbits(nbits), m_signedPacking(signedPacking) {
m_NBins = NBins;
m_idxoffset = idx_offset;
m_Scale.reserve(m_NBins + 1);
for (int i = 0; i < m_NBins + 1; i++)
//m_Scale[i] = Scale[i];
m_Scale.push_back(Scale[i]);
};
///
/// constructor
///
/// packing is a pointer to a packing object. The L1MuBinnedScale
/// takes ownership of the packing object and deletes it in its
/// destructor
///
/// NBins=number of bins, xmin = low edge of first bin,
/// xmax=high edge of last bin, idx_offset=offeset to index (if stored as signed)
///
L1MuBinnedScale(unsigned int nbits, bool signedPacking, int NBins, float xmin, float xmax, int idx_offset = 0)
: m_nbits(nbits), m_signedPacking(signedPacking) {
m_NBins = NBins;
m_idxoffset = idx_offset;
m_Scale.reserve(m_NBins + 1);
for (int i = 0; i < m_NBins + 1; i++)
// m_Scale[i] = xmin + i * (xmax-xmin) / m_NBins;
m_Scale.push_back(xmin + i * (xmax - xmin) / m_NBins);
};
/// destructor
~L1MuBinnedScale() override {
// delete m_packing;
};
/// get the center of bin represented by packed
float getCenter(unsigned packed) const override {
int idx = get_idx(packed);
return (m_Scale[idx] + m_Scale[idx + 1]) / 2.;
};
/// get the low edge of bin represented by packed
float getLowEdge(unsigned packed) const override { return m_Scale[get_idx(packed)]; };
/// get the upper edge of bin represented by packed
float getHighEdge(unsigned packed) const override { return m_Scale[get_idx(packed) + 1]; };
/// pack a value
unsigned getPacked(float value) const override {
if (value < m_Scale[0] || value > m_Scale[m_NBins])
edm::LogWarning("ScaleRangeViolation")
<< "L1MuBinnedScale::getPacked: value out of scale range: " << value << std::endl;
int idx = 0;
if (value < m_Scale[0])
idx = 0;
else if (value >= m_Scale[m_NBins])
idx = m_NBins - 1;
else {
for (; idx < m_NBins; idx++)
if (value >= m_Scale[idx] && value < m_Scale[idx + 1])
break;
}
return (m_signedPacking ? L1MuSignedPackingGeneric::packedFromIdx(idx - m_idxoffset, m_nbits)
: L1MuUnsignedPackingGeneric::packedFromIdx(idx - m_idxoffset, m_nbits));
};
/// get the upper edge of the last bin
float getScaleMax() const override { return m_Scale[m_NBins]; }
/// get the lower edge of the first bin
float getScaleMin() const override { return m_Scale[0]; }
/// get number of bins
unsigned getNBins() const override { return m_NBins; }
/// get value of the underlying vector for bin i
float getValue(unsigned i) const override { return m_Scale[i]; }
std::string print() const override {
std::ostringstream str;
str << " ind | low edge | center | high edge" << std::endl;
str << "-------------------------------------------" << std::endl;
for (int i = 0; i < m_NBins; i++) {
unsigned int ipack = getPacked(m_Scale[i]);
str << std::setw(4) << ipack << " | " << std::setw(10) << getLowEdge(ipack) << " | " << std::setw(10)
<< getCenter(ipack) << " | " << std::setw(10) << getHighEdge(ipack) << std::endl;
}
return str.str();
}
protected:
int get_idx(unsigned packed) const {
int idxFromPacked = m_signedPacking ? L1MuSignedPackingGeneric::idxFromPacked(packed, m_nbits)
: L1MuUnsignedPackingGeneric::idxFromPacked(packed, m_nbits);
int idx = idxFromPacked + m_idxoffset;
if (idx < 0)
idx = 0;
if (idx >= m_NBins)
idx = m_NBins - 1;
return idx;
}
unsigned int m_nbits;
bool m_signedPacking;
int m_NBins;
int m_idxoffset;
std::vector<float> m_Scale;
COND_SERIALIZABLE;
};
/**
* \class L1MuSymmetricBinnedScale
*
* In the GMT the concept of a symmetric scale exists
* The internal representation of scale values is "pseudo-signed", i.e.
* the highest bit stores the sign and the lower bits contain the absolute value
*
* Attention: for reasons of symmetry, the low edge in this scale is the edge closer to zero.
* the high edge is the edge further away from zero
*/
class L1MuSymmetricBinnedScale : public L1MuScale {
public:
///
/// constructor
///
/// packing is a pointer to a packing object. The L1MuSymmetricBinnedScale
/// takes ownership of the packing object and deletes it in its
/// destructor
///
L1MuSymmetricBinnedScale() : m_NBins(0) {}
/// NBins=number of bins (in one half of the scale), Scale[NBins+1]=bin edges
///
// L1MuSymmetricBinnedScale(int nbits, int NBins, const float* Scale)
L1MuSymmetricBinnedScale(int nbits, int NBins, const std::vector<double>& Scale)
: m_packing(L1MuPseudoSignedPacking(nbits)) {
m_NBins = NBins;
m_Scale.reserve(m_NBins + 1);
for (int i = 0; i < m_NBins + 1; i++)
// m_Scale[i] = Scale[i];
m_Scale.push_back(Scale[i]);
};
///
/// constructor
///
/// packing is a pointer to a packing object. The L1MuSymmetricBinnedScale
/// takes ownership of the packing object and deletes it in its
/// destructor
///
/// NBins=number of bins, xmin = low edge of first bin (in positive half)
/// xmax=high edge of last bin (in positive half)
///
L1MuSymmetricBinnedScale(int nbits, int NBins, float xmin, float xmax) : m_packing(L1MuPseudoSignedPacking(nbits)) {
m_NBins = NBins;
m_Scale.reserve(m_NBins + 1);
for (int i = 0; i < m_NBins + 1; i++)
// m_Scale[i] = xmin + i * (xmax-xmin) / m_NBins;
m_Scale.push_back(xmin + i * (xmax - xmin) / m_NBins);
};
/// destructor
~L1MuSymmetricBinnedScale() override {
// delete m_packing;
};
/// get the center of bin represented by packed
float getCenter(unsigned packed) const override {
int absidx = abs(m_packing.idxFromPacked(packed));
if (absidx >= m_NBins)
absidx = m_NBins - 1;
float center = (m_Scale[absidx] + m_Scale[absidx + 1]) / 2.;
float fsign = m_packing.signFromPacked(packed) == 0 ? 1. : -1.;
return center * fsign;
};
/// get the low edge of bin represented by packed
float getLowEdge(unsigned packed) const override { // === edge towards 0
int absidx = abs(m_packing.idxFromPacked(packed));
if (absidx >= m_NBins)
absidx = m_NBins - 1;
float low = m_Scale[absidx];
float fsign = m_packing.signFromPacked(packed) == 0 ? 1. : -1.;
return low * fsign;
};
/// get the upper edge of bin represented by packed
float getHighEdge(unsigned packed) const override {
edm::LogWarning("NotImplemented") << "L1MuSymmetricBinnedScale::getHighEdge not implemented" << std::endl;
return 0;
};
/// pack a value
unsigned getPacked(float value) const override {
float absval = fabs(value);
if (absval < m_Scale[0] || absval > m_Scale[m_NBins])
edm::LogWarning("ScaleRangeViolation")
<< "L1MuSymmetricBinnedScale::getPacked: value out of scale range!!! abs(val) = " << absval
<< " min= " << m_Scale[0] << " max = " << m_Scale[m_NBins] << std::endl;
int idx = 0;
for (; idx < m_NBins; idx++)
if (absval >= m_Scale[idx] && absval < m_Scale[idx + 1])
break;
if (idx >= m_NBins)
idx = m_NBins - 1;
return m_packing.packedFromIdx(idx, (value >= 0) ? 0 : 1);
};
/// get the upper edge of the last bin (posivie half)
float getScaleMax() const override { return m_Scale[m_NBins]; }
/// get the lower edge of the first bin (positive half)
float getScaleMin() const override { return m_Scale[0]; }
/// get number of bins
unsigned getNBins() const override { return m_NBins; }
/// get value of the underlying vector for bin i
float getValue(unsigned i) const override { return m_Scale[i]; }
std::string print() const override {
std::ostringstream str;
str << " ind | low edge | center" << std::endl;
str << "-------------------------------------------" << std::endl;
for (int i = 0; i < m_NBins; i++) {
unsigned int ipack = getPacked(m_Scale[i]);
str << std::setw(4) << ipack << " | " << std::setw(10) << getLowEdge(ipack) << " | " << std::setw(10)
<< getCenter(ipack) << std::endl;
}
return str.str();
}
protected:
L1MuPseudoSignedPacking m_packing;
int m_NBins;
std::vector<float> m_Scale;
COND_SERIALIZABLE;
};
#endif
|