File indexing completed on 2024-04-06 12:04:03
0001 #include "DataFormats/EcalDetId/interface/EcalTrigTowerDetId.h"
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 #include <cassert>
0004
0005 EcalTrigTowerDetId::EcalTrigTowerDetId() {}
0006
0007 EcalTrigTowerDetId::EcalTrigTowerDetId(uint32_t rawid) : DetId(rawid) {}
0008
0009 EcalTrigTowerDetId::EcalTrigTowerDetId(int zside, EcalSubdetector subDet, int i, int j, int mode)
0010 : DetId(Ecal, EcalTriggerTower) {
0011 int tower_i = 0;
0012 int tower_j = 0;
0013
0014 if (mode == SUBDETIJMODE) {
0015 tower_i = i;
0016 tower_j = j;
0017 } else if (mode == SUBDETDCCTTMODE) {
0018 throw cms::Exception("InvalidDetId")
0019 << "EcalTriggerTowerDetId: Cannot create object. SUBDETDCCTTMODE not yet implemented.";
0020 } else
0021 throw cms::Exception("InvalidDetId") << "EcalTriggerTowerDetId: Cannot create object. Unknown mode for (int, "
0022 "EcalSubdetector, int, int) constructor.";
0023
0024 if (tower_i > MAX_I || tower_i < MIN_I || tower_j > MAX_J || tower_j < MIN_J)
0025 throw cms::Exception("InvalidDetId") << "EcalTriggerTowerDetId: Cannot create object. Indexes out of bounds.";
0026
0027 id_ |= ((zside > 0) ? (0x8000) : (0x0)) | ((subDet == EcalBarrel) ? (0x4000) : (0x0)) | (tower_i << 7) |
0028 (tower_j & 0x7F);
0029 }
0030
0031 EcalTrigTowerDetId::EcalTrigTowerDetId(const DetId& gen) {
0032 if (!gen.null() && (gen.det() != Ecal || gen.subdetId() != EcalTriggerTower)) {
0033 throw cms::Exception("InvalidDetId");
0034 }
0035 id_ = gen.rawId();
0036 }
0037
0038 EcalTrigTowerDetId& EcalTrigTowerDetId::operator=(const DetId& gen) {
0039 if (!gen.null() && (gen.det() != Ecal || gen.subdetId() != EcalTriggerTower)) {
0040 throw cms::Exception("InvalidDetId");
0041 }
0042 id_ = gen.rawId();
0043 return *this;
0044 }
0045
0046
0047 int EcalTrigTowerDetId::iDCC() const {
0048 if (subDet() == EcalBarrel) {
0049
0050 int iphi_simple = iphi() + 2;
0051 if (iphi_simple > 72)
0052 iphi_simple = iphi_simple % 72;
0053 int id = (iphi_simple - 1) / kEBTowersInPhi + 1;
0054 if (zside() < 0)
0055 id += 18;
0056 return id;
0057 } else
0058 throw cms::Exception("MethodNotImplemented") << "EcalTriggerTowerDetId: iDCC not yet implemented";
0059 }
0060
0061 int EcalTrigTowerDetId::iTT() const {
0062 if (subDet() == EcalBarrel) {
0063 int ie = ietaAbs() - 1;
0064 int ip;
0065 int iphi_simple = iphi() + 2;
0066 if (iphi_simple > 72)
0067 iphi_simple = iphi_simple % 72;
0068 if (zside() < 0) {
0069 ip = ((iphi_simple - 1) % kEBTowersInPhi) + 1;
0070 } else {
0071 ip = kEBTowersInPhi - ((iphi_simple - 1) % kEBTowersInPhi);
0072 }
0073
0074 return (ie * kEBTowersInPhi) + ip;
0075 } else
0076 throw cms::Exception("MethodNotImplemented") << "EcalTriggerTowerDetId: iTT not yet implemented";
0077 }
0078
0079 int EcalTrigTowerDetId::iquadrant() const {
0080 if (subDet() == EcalEndcap)
0081 return int((iphi() - 1) / kEETowersInPhiPerQuadrant) + 1;
0082 else
0083 throw cms::Exception("MethodNotApplicable") << "EcalTriggerTowerDetId: iquadrant not applicable";
0084 }
0085
0086 bool EcalTrigTowerDetId::validDetId(int iz, EcalSubdetector sd, int i, int j) {
0087 return (
0088 1 == abs(iz) && 0 < i && 0 < j && kEETowersInPhiPerEndcap >= j &&
0089 ((EcalBarrel == sd && kEBTowersInEta >= i) || (EcalEndcap == sd && kEEOuterEta <= i && kEEInnerEta >= i &&
0090 (27 > i || ((0 > iz && 0 == j % 2) || (0 < iz && 1 == j % 2))))));
0091 }
0092
0093 int EcalTrigTowerDetId::hashedIndex() const {
0094 const unsigned int iea(ietaAbs());
0095 const unsigned int iph(iphi());
0096 return (subDet() == EcalBarrel ? (iDCC() - 1) * kEBTowersPerSM + iTT() - 1
0097 : kEBTotalTowers + ((zside() + 1) / 2) * kEETowersPerEndcap +
0098 ((iea < 27 ? iea : 27) - kEEOuterEta) * kEETowersInPhiPerEndcap +
0099 (iea < 27 ? iph :
0100 (iea - 27) * kEETowersInPhiPerEndcap / 2 + (iph + 1) / 2) -
0101 1);
0102 }
0103
0104 EcalTrigTowerDetId EcalTrigTowerDetId::detIdFromDenseIndex(uint32_t di) {
0105 const EcalSubdetector sd(di < kEBTotalTowers ? EcalBarrel : EcalEndcap);
0106 const int iz(di < kEBTotalTowers ? (di < kEBHalfTowers ? 1 : -1)
0107 : (di - kEBTotalTowers < kEETowersPerEndcap ? -1 : 1));
0108 int i;
0109 int j;
0110 if (di < kEBTotalTowers)
0111 {
0112 const unsigned int itt(di % kEBTowersPerSM);
0113 const unsigned int idc(di / kEBTowersPerSM);
0114 j = (idc % 18) * kEBTowersInPhi + ((1 + iz) / 2) * kEBTowersInPhi - iz * (itt % kEBTowersInPhi) + 1 - (1 + iz) / 2 -
0115 2;
0116 if (j < 1)
0117 j += 72;
0118 i = 1 + itt / kEBTowersInPhi;
0119 } else {
0120 const int eonly((di - kEBTotalTowers) % kEETowersPerEndcap);
0121 i = kEEOuterEta + eonly / kEETowersInPhiPerEndcap;
0122 j = 1 + eonly % kEETowersInPhiPerEndcap;
0123 if (27 == i)
0124 {
0125 if (j > kEETowersInPhiPerEndcap / 2) {
0126 ++i;
0127 j -= kEETowersInPhiPerEndcap / 2;
0128 }
0129 j = 2 * j;
0130 if (0 < iz)
0131 --j;
0132 }
0133 }
0134 assert(validDetId(iz, sd, i, j));
0135 return EcalTrigTowerDetId(iz, sd, i, j);
0136 }
0137
0138 #include <ostream>
0139 std::ostream& operator<<(std::ostream& s, const EcalTrigTowerDetId& id) {
0140 return s << "(EcalTT subDet " << ((id.subDet() == EcalBarrel) ? ("Barrel") : ("Endcap")) << " iz "
0141 << ((id.zside() > 0) ? ("+ ") : ("- ")) << " ieta " << id.ietaAbs() << " iphi " << id.iphi() << ')';
0142 }