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
|
#include "DataFormats/EcalDetId/interface/EcalScDetId.h"
#include "FWCore/Utilities/interface/Exception.h"
#include <ostream>
#include <cassert>
#include <mutex>
short EcalScDetId::xyz2HashedIndex[EcalScDetId::IX_MAX][EcalScDetId::IY_MAX][EcalScDetId::nEndcaps];
EcalScDetId EcalScDetId::hashedIndex2DetId[kSizeForDenseIndexing];
EcalScDetId::EcalScDetId() : DetId() {}
EcalScDetId::EcalScDetId(uint32_t rawid) : DetId(rawid) {}
EcalScDetId::EcalScDetId(int ix, int iy, int iz) : DetId(Ecal, EcalEndcap) {
if (!validDetId(ix, iy, iz)) {
throw cms::Exception("InvalidDetId") << "EcalScDetId: Cannot create object. Indexes out of bounds \n"
<< "x = " << ix << " y = " << iy << " z = " << iz;
}
const int scBit = 1 << 15; //bit set to 1 to distinguish from crystal id (EEDetId)
// and for a reasonale behaviour of DetId ccomparison operators.
id_ |= (iy & 0x7f) | ((ix & 0x7f) << 7) | ((iz > 0) ? (1 << 14) : (0)) | scBit;
}
EcalScDetId::EcalScDetId(const DetId& gen) {
if (!gen.null() && (gen.det() != Ecal || gen.subdetId() != EcalEndcap)) {
throw cms::Exception("InvalidDetId");
}
id_ = gen.rawId();
}
EcalScDetId& EcalScDetId::operator=(const DetId& gen) {
if (!gen.null() && (gen.det() != Ecal || gen.subdetId() != EcalEndcap)) {
throw cms::Exception("InvalidDetId");
}
id_ = gen.rawId();
return *this;
}
int EcalScDetId::iquadrant() const {
const int xMiddle = IX_MAX / 2; //y = 0 between xMiddle and xMiddle+1
const int yMiddle = IY_MAX / 2; //x = 0 between yMiddle and yMiddle+1
if (iy() > yMiddle) { // y>0
if (ix() > xMiddle) // A y
return 1; // |
else // Q2 | Q1
return 2; // |
} else { // y<0 // ----------o---------> x
if (ix() > xMiddle) // |
return 4; // Q3 | Q4
else // |
return 3;
}
//Should never be reached
return -1;
}
bool EcalScDetId::validDetId(int iX, int iY, int iZ) {
static const char endcapMap[401] = {
" XXXXXX "
" XXXXXXXXXXXX "
" XXXXXXXXXXXXXX "
" XXXXXXXXXXXXXXXX "
" XXXXXXXXXXXXXXXXXX "
" XXXXXXXXXXXXXXXXXX " // Z
" XXXXXXXXXXXXXXXXXX " // x-----> X
"XXXXXXXXXXXXXXXXXXXX" // |
"XXXXXXXXX XXXXXXXXX" // |
"XXXXXXXX XXXXXXXX" //_ // |
"XXXXXXXX XXXXXXXX" // V Y
"XXXXXXXXX XXXXXXXXX"
"XXXXXXXXXXXXXXXXXXXX"
" XXXXXXXXXXXXXXXXXX "
" XXXXXXXXXXXXXXXXXX "
" XXXXXXXXXXXXXXXXXX "
" XXXXXXXXXXXXXXXX "
" XXXXXXXXXXXXXX "
" XXXXXXXXXXXX "
" XXXXXX "};
return abs(iZ) == 1 && endcapMap[iX - 1 + (iY - 1) * 20] != ' ';
}
std::ostream& operator<<(std::ostream& s, const EcalScDetId& id) {
return s << "(EE iz " << ((id.zside() > 0) ? ("+ ") : ("- ")) << " ix " << id.ix() << " , iy " << id.iy() << ')';
}
//NOTE: When looping is possible in constexpr, this should be changed to one
static std::once_flag initializedFlag;
void EcalScDetId::checkHashedIndexMap() {
std::call_once(initializedFlag, []() {
int hashedIndex = -1;
for (int iZ = -1; iZ <= +1; iZ += 2) {
for (int iY = IY_MIN; iY <= IY_MAX; ++iY) {
for (int iX = IX_MIN; iX <= IX_MAX; ++iX) {
if (validDetId(iX, iY, iZ)) {
xyz2HashedIndex[iX - IX_MIN][iY - IY_MIN][iZ > 0 ? 1 : 0] = ++hashedIndex;
assert((unsigned)hashedIndex < sizeof(hashedIndex2DetId) / sizeof(hashedIndex2DetId[0]));
hashedIndex2DetId[hashedIndex] = EcalScDetId(iX, iY, iZ);
}
}
}
}
});
}
|