File indexing completed on 2024-04-06 12:14:36
0001
0002 #include "Geometry/EcalMapping/interface/EcalElectronicsMapping.h"
0003 #include "DataFormats/EcalDetId/interface/EEDetId.h"
0004 #include "DataFormats/EcalDetId/interface/EBDetId.h"
0005 #include "DataFormats/EcalDetId/interface/EcalTrigTowerDetId.h"
0006
0007 #include "DataFormats/EcalDetId/interface/EcalElectronicsId.h"
0008 #include "DataFormats/EcalDetId/interface/EcalTriggerElectronicsId.h"
0009
0010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0011 #include "FWCore/Utilities/interface/Exception.h"
0012 #include <cassert>
0013 #include <sstream>
0014
0015 using boost::multi_index_container;
0016 using namespace boost::multi_index;
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 EcalElectronicsMapping::EcalElectronicsMapping() {
0038
0039
0040
0041 int ilm = MIN_LM_EBM;
0042 for (int dcc = MIN_DCCID_EBM; dcc <= MAX_DCCID_EBM; dcc++) {
0043 LaserMonitoringMap_EB[dcc] = ilm;
0044 ilm += 2;
0045 }
0046 ilm = MIN_LM_EBP;
0047 for (int dcc = MIN_DCCID_EBP; dcc <= MAX_DCCID_EBP; dcc++) {
0048 LaserMonitoringMap_EB[dcc] = ilm;
0049 ilm += 2;
0050 }
0051
0052
0053
0054
0055 ilm = MIN_LM_EEM;
0056 for (int dcc = MIN_DCCID_EEM; dcc <= MAX_DCCID_EEM; dcc++) {
0057 LaserMonitoringMap_EE[dcc] = ilm;
0058 ilm += 1;
0059 if (dcc == 8)
0060 ilm += 1;
0061 }
0062 ilm = MIN_LM_EEP;
0063 for (int dcc = MIN_DCCID_EEP; dcc <= MAX_DCCID_EEP; dcc++) {
0064 LaserMonitoringMap_EE[dcc] = ilm;
0065 ilm += 1;
0066 if (dcc == 53)
0067 ilm += 1;
0068 }
0069 }
0070
0071 int EcalElectronicsMapping::DCCid(const EBDetId& id) const
0072
0073
0074
0075
0076
0077 {
0078 int dcc = id.ism();
0079 if (id.zside() < 0) {
0080 dcc += DCCID_PHI0_EBM - 19;
0081 } else {
0082 dcc += DCCID_PHI0_EBP - 1;
0083 }
0084 return dcc;
0085 }
0086
0087 int EcalElectronicsMapping::TCCid(const EBDetId& id) const
0088
0089
0090
0091
0092
0093 {
0094 int tcc = id.ism();
0095 if (id.zside() < 0) {
0096 tcc += TCCID_PHI0_EBM - 19;
0097 } else {
0098 tcc += TCCID_PHI0_EBP - 1;
0099 }
0100 return tcc;
0101 }
0102
0103 int EcalElectronicsMapping::iTT(const EcalTrigTowerDetId& id) const
0104
0105
0106
0107
0108
0109 {
0110 if (id.subDet() == EcalBarrel) {
0111 int ie = id.ietaAbs() - 1;
0112 int ip;
0113 int phi = id.iphi();
0114 phi += 2;
0115 if (phi > 72)
0116 phi = phi - 72;
0117 if (id.zside() < 0) {
0118 ip = ((phi - 1) % kEBTowersInPhi) + 1;
0119 } else {
0120 ip = kEBTowersInPhi - ((phi - 1) % kEBTowersInPhi);
0121 }
0122
0123 return (ie * kEBTowersInPhi) + ip;
0124 } else if (id.subDet() == EcalEndcap) {
0125 int ie = id.ietaAbs();
0126 bool inner = (ie >= iEEEtaMinInner);
0127 if (inner) {
0128 ie = ie - iEEEtaMinInner;
0129 ie = ie % kEETowersInEtaPerInnerTCC;
0130 } else {
0131 ie = ie - iEEEtaMinOuter;
0132 ie = ie % kEETowersInEtaPerOuterTCC;
0133 }
0134
0135 int ip = id.iphi();
0136 ip = (ip + 1) % (kEETowersInPhiPerQuadrant * 4);
0137
0138
0139 ip = ip % kEETowersInPhiPerTCC;
0140 int itt = kEETowersInPhiPerTCC * ie + ip + 1;
0141 return itt;
0142 } else {
0143 throw cms::Exception("InvalidDetId") << " Wrong EcalTrigTowerDetId in EcalElectronicsMapping::iTT. ";
0144 return 0;
0145 }
0146 }
0147
0148 int EcalElectronicsMapping::TCCid(const EcalTrigTowerDetId& id) const {
0149 if (id.subDet() == EcalBarrel) {
0150 int phi = id.iphi() + 2;
0151 if (phi > 72)
0152 phi = phi - 72;
0153 int tcc = (phi - 1) / kEBTowersInPhi + 1;
0154 if (id.zside() < 0)
0155 tcc += 18;
0156 if (id.zside() < 0) {
0157 tcc += TCCID_PHI0_EBM - 19;
0158 } else {
0159 tcc += TCCID_PHI0_EBP - 1;
0160 }
0161 return tcc;
0162 }
0163
0164 else if (id.subDet() == EcalEndcap) {
0165 int ie = id.ietaAbs();
0166 bool inner = (ie >= iEEEtaMinInner);
0167 int ip = id.iphi();
0168 ip = (ip + 1) % (kEETowersInPhiPerQuadrant * 4);
0169
0170
0171 int Phiindex = ip / 4;
0172 if (inner) {
0173 if (id.ieta() > 0)
0174 Phiindex += TCCID_PHI0_EEP_IN;
0175 else
0176 Phiindex += TCCID_PHI0_EEM_IN;
0177 } else {
0178 if (id.ieta() > 0)
0179 Phiindex += TCCID_PHI0_EEP_OUT;
0180 else
0181 Phiindex += TCCID_PHI0_EEM_OUT;
0182 }
0183 return Phiindex;
0184 } else {
0185 throw cms::Exception("InvalidDetId") << " Wrong EcalTrigTowerDetId in EcalElectronicsMapping::TCCid.";
0186 return 0;
0187 }
0188 }
0189
0190 int EcalElectronicsMapping::DCCid(const EcalTrigTowerDetId& id) const {
0191
0192
0193
0194 if (id.subDet() == EcalBarrel) {
0195 int phi = id.iphi() + 2;
0196 if (phi > 72)
0197 phi = phi - 72;
0198 int dcc = (phi - 1) / kEBTowersInPhi + 1;
0199 if (id.zside() < 0)
0200 dcc += 18;
0201 if (id.zside() < 0) {
0202 dcc += DCCID_PHI0_EBM - 19;
0203 } else {
0204 dcc += DCCID_PHI0_EBP - 1;
0205 }
0206 return dcc;
0207 } else if (id.subDet() == EcalEndcap) {
0208 int tccid = TCCid(id);
0209 int dcc = 0;
0210 int offset = 0;
0211 if (tccid >= 73) {
0212 tccid = tccid - 72;
0213 offset = 45;
0214 }
0215 if (tccid == 24 || tccid == 25 || tccid == 6 || tccid == 7)
0216 dcc = 4;
0217 if (tccid == 26 || tccid == 27 || tccid == 8 || tccid == 9)
0218 dcc = 5;
0219 if (tccid == 28 || tccid == 29 || tccid == 10 || tccid == 11)
0220 dcc = 6;
0221 if (tccid == 30 || tccid == 31 || tccid == 12 || tccid == 13)
0222 dcc = 7;
0223 if (tccid == 32 || tccid == 33 || tccid == 14 || tccid == 15)
0224 dcc = 8;
0225 if (tccid == 34 || tccid == 35 || tccid == 16 || tccid == 17)
0226 dcc = 9;
0227 if (tccid == 36 || tccid == 19 || tccid == 18 || tccid == 1)
0228 dcc = 1;
0229 if (tccid == 20 || tccid == 21 || tccid == 2 || tccid == 3)
0230 dcc = 2;
0231 if (tccid == 22 || tccid == 23 || tccid == 4 || tccid == 5)
0232 dcc = 3;
0233 dcc += offset;
0234 return dcc;
0235 } else {
0236 throw cms::Exception("InvalidDetId") << " Wrong EcalTrigTowerDetId in EcalElectronicsMapping::DCCid.";
0237 return 0;
0238 }
0239 }
0240
0241 EcalTrigTowerDetId EcalElectronicsMapping::getTrigTowerDetId(int TCCid, int iTT) const {
0242
0243
0244 EcalSubdetector sub = subdet(TCCid, TCCMODE);
0245 int zIndex = zside(TCCid, TCCMODE);
0246
0247 if (sub == EcalBarrel) {
0248 int DCCid = 0;
0249 int jtower = iTT - 1;
0250 if (zIndex > 0)
0251 DCCid = TCCid - TCCID_PHI0_EBP + DCCID_PHI0_EBP;
0252 else
0253 DCCid = TCCid - TCCID_PHI0_EBM + DCCID_PHI0_EBM;
0254 int SMid = (zIndex > 0) ? DCCid - 27 : DCCid + 9;
0255
0256 int etaTT = jtower / kTowersInPhi + 1;
0257 int phiTT;
0258
0259 if (zIndex > 0)
0260 phiTT = (SMid - 1) * kTowersInPhi + (kTowersInPhi - (jtower % kTowersInPhi)) - 1;
0261 else
0262 phiTT = (SMid - 19) * kTowersInPhi + jtower % kTowersInPhi;
0263 phiTT++;
0264 phiTT = phiTT - 2;
0265 if (phiTT <= 0)
0266 phiTT = 72 + phiTT;
0267 EcalTrigTowerDetId tdetid(zIndex, EcalBarrel, etaTT, phiTT, EcalTrigTowerDetId::SUBDETIJMODE);
0268 return tdetid;
0269 }
0270
0271 else if (sub == EcalEndcap) {
0272 bool EEminus = (zIndex < 0);
0273 bool EEplus = (zIndex > 0);
0274 if ((!EEminus) && (!EEplus))
0275 throw cms::Exception("InvalidDetId") << "EcalElectronicsMapping: Cannot create EcalTrigTowerDetId object. ";
0276 int iz = 0;
0277 int tcc = TCCid;
0278 if (tcc < TCCID_PHI0_EEM_OUT + kTCCinPhi)
0279 iz = -1;
0280 else if (tcc >= TCCID_PHI0_EEP_OUT)
0281 iz = +1;
0282
0283 bool inner = false;
0284 if (iz < 0 && tcc >= TCCID_PHI0_EEM_IN && tcc < TCCID_PHI0_EEM_IN + kTCCinPhi)
0285 inner = true;
0286 if (iz > 0 && tcc >= TCCID_PHI0_EEP_IN && tcc < TCCID_PHI0_EEP_IN + kTCCinPhi)
0287 inner = true;
0288 bool outer = !inner;
0289
0290 int ieta = (iTT - 1) / kEETowersInPhiPerTCC;
0291 int iphi = (iTT - 1) % kEETowersInPhiPerTCC;
0292 if (inner)
0293 ieta += iEEEtaMinInner;
0294 else
0295 ieta += iEEEtaMinOuter;
0296 if (iz < 0)
0297 ieta = -ieta;
0298
0299 int TCC_origin = 0;
0300 if (inner && iz < 0)
0301 TCC_origin = TCCID_PHI0_EEM_IN;
0302 if (outer && iz < 0)
0303 TCC_origin = TCCID_PHI0_EEM_OUT;
0304 if (inner && iz > 0)
0305 TCC_origin = TCCID_PHI0_EEP_IN;
0306 if (outer && iz > 0)
0307 TCC_origin = TCCID_PHI0_EEP_OUT;
0308 tcc = tcc - TCC_origin;
0309
0310 iphi += kEETowersInPhiPerTCC * tcc;
0311 iphi = (iphi - 2 + 4 * kEETowersInPhiPerQuadrant) % (4 * kEETowersInPhiPerQuadrant) + 1;
0312
0313 int tower_i = abs(ieta);
0314 int tower_j = iphi;
0315
0316 EcalTrigTowerDetId tdetid(zIndex, EcalEndcap, tower_i, tower_j, EcalTrigTowerDetId::SUBDETIJMODE);
0317 return tdetid;
0318
0319 } else {
0320 throw cms::Exception("InvalidDetId") << " Wrong indices in EcalElectronicsMapping::getTrigTowerDetId. TCCid = "
0321 << TCCid << " iTT = " << iTT << ".";
0322 }
0323 }
0324
0325 EcalElectronicsId EcalElectronicsMapping::getElectronicsId(const DetId& id) const {
0326 EcalSubdetector subdet = EcalSubdetector(id.subdetId());
0327 if (subdet == EcalBarrel) {
0328 const EBDetId ebdetid = EBDetId(id);
0329
0330 int dcc = DCCid(ebdetid);
0331 bool EBPlus = (zside(dcc, DCCMODE) > 0);
0332 bool EBMinus = !EBPlus;
0333
0334 EcalTrigTowerDetId trigtower = ebdetid.tower();
0335
0336 int tower = iTT(trigtower);
0337
0338 int ieta = EBDetId(id).ietaAbs();
0339 int iphi = EBDetId(id).iphi();
0340 int strip(0);
0341 int channel(0);
0342 bool RightTower = rightTower(tower);
0343 if (RightTower) {
0344 strip = (ieta - 1) % 5;
0345 if (strip % 2 == 0) {
0346 if (EBMinus)
0347 channel = (iphi - 1) % 5;
0348 if (EBPlus)
0349 channel = 4 - ((iphi - 1) % 5);
0350 } else {
0351 if (EBMinus)
0352 channel = 4 - ((iphi - 1) % 5);
0353 if (EBPlus)
0354 channel = (iphi - 1) % 5;
0355 }
0356 } else {
0357 strip = 4 - ((ieta - 1) % 5);
0358 if (strip % 2 == 0) {
0359 if (EBMinus)
0360 channel = 4 - ((iphi - 1) % 5);
0361 if (EBPlus)
0362 channel = (iphi - 1) % 5;
0363 } else {
0364 if (EBMinus)
0365 channel = (iphi - 1) % 5;
0366 if (EBPlus)
0367 channel = 4 - ((iphi - 1) % 5);
0368 }
0369 }
0370 strip += 1;
0371 channel += 1;
0372
0373 EcalElectronicsId elid = EcalElectronicsId(dcc, tower, strip, channel);
0374
0375 return elid;
0376 } else if (subdet == EcalEndcap) {
0377 EcalElectronicsMap_by_DetId::const_iterator it = get<0>(m_items).find(id);
0378 if (it == get<0>(m_items).end()) {
0379 EcalElectronicsId elid(0);
0380 edm::LogError("EcalElectronicsMapping") << "Ecal mapping was asked non valid id";
0381 return elid;
0382 }
0383 EcalElectronicsId elid = it->elid;
0384 return elid;
0385 } else {
0386 throw cms::Exception("InvalidDetId") << " Wrong DetId in EcalElectronicsMapping::getElectronicsId.";
0387 }
0388 }
0389
0390 EcalTriggerElectronicsId EcalElectronicsMapping::getTriggerElectronicsId(const DetId& id) const {
0391 EcalSubdetector subdet = EcalSubdetector(id.subdetId());
0392
0393 if (subdet == EcalBarrel) {
0394 const EcalElectronicsId& elid = getElectronicsId(id);
0395 EcalTriggerElectronicsId trelid = getTriggerElectronicsId(elid);
0396 return trelid;
0397 } else if (subdet == EcalEndcap) {
0398 EcalElectronicsMap_by_DetId::const_iterator it = get<0>(m_items).find(id);
0399 if (it == get<0>(m_items).end()) {
0400 EcalTriggerElectronicsId trelid(0);
0401 edm::LogError("EcalElectronicsMapping") << "Ecal mapping was asked non valid trig id";
0402 return trelid;
0403 }
0404 EcalTriggerElectronicsId trelid = it->trelid;
0405 return trelid;
0406 } else {
0407 throw cms::Exception("InvalidDetId") << " Wrong DetId in EcalElectronicsMapping::getTriggerElectronicsId.";
0408 }
0409 }
0410
0411 DetId EcalElectronicsMapping::getDetId(const EcalElectronicsId& id) const {
0412 EcalSubdetector subdet = id.subdet();
0413
0414 if (subdet == EcalBarrel) {
0415 int dcc = id.dccId();
0416 int tower = id.towerId();
0417 int strip = id.stripId();
0418 int channel = id.xtalId();
0419
0420 int smid = 0;
0421 int iphi = 0;
0422 bool EBPlus = (id.zside() > 0);
0423 bool EBMinus = !EBPlus;
0424
0425 if (id.zside() < 0) {
0426 smid = dcc + 19 - DCCID_PHI0_EBM;
0427 iphi = (smid - 19) * kCrystalsInPhi;
0428 iphi += 5 * ((tower - 1) % kTowersInPhi);
0429 } else {
0430 smid = dcc + 1 - DCCID_PHI0_EBP;
0431 iphi = (smid - 1) * kCrystalsInPhi;
0432 iphi += 5 * (kTowersInPhi - ((tower - 1) % kTowersInPhi) - 1);
0433 }
0434 bool RightTower = rightTower(tower);
0435 int ieta = 5 * ((tower - 1) / kTowersInPhi) + 1;
0436 if (RightTower) {
0437 ieta += (strip - 1);
0438 if (strip % 2 == 1) {
0439 if (EBMinus)
0440 iphi += (channel - 1) + 1;
0441 if (EBPlus)
0442 iphi += (4 - (channel - 1)) + 1;
0443 } else {
0444 if (EBMinus)
0445 iphi += (4 - (channel - 1)) + 1;
0446 if (EBPlus)
0447 iphi += (channel - 1) + 1;
0448 }
0449 } else {
0450 ieta += 4 - (strip - 1);
0451 if (strip % 2 == 1) {
0452 if (EBMinus)
0453 iphi += (4 - (channel - 1)) + 1;
0454 if (EBPlus)
0455 iphi += (channel - 1) + 1;
0456 } else {
0457 if (EBMinus)
0458 iphi += (channel - 1) + 1;
0459 if (EBPlus)
0460 iphi += (4 - (channel - 1)) + 1;
0461 }
0462 }
0463 if (id.zside() < 0)
0464 ieta = -ieta;
0465
0466 EBDetId e(ieta, iphi, EBDetId::ETAPHIMODE);
0467 return e;
0468 }
0469
0470 else if (subdet == EcalEndcap) {
0471 EcalElectronicsMap_by_ElectronicsId::const_iterator it = get<1>(m_items).find(id);
0472 if (it == (get<1>(m_items).end())) {
0473 DetId cell(0);
0474 edm::LogError("EcalElectronicsMapping") << "Ecal mapping was asked non DetId";
0475 return cell;
0476 }
0477 DetId cell = it->cell;
0478 return cell;
0479 } else
0480 throw cms::Exception("InvalidDetId") << "Wrong EcalElectronicsId in EcalElectronicsMapping::getDetId.";
0481 }
0482
0483 EcalTriggerElectronicsId EcalElectronicsMapping::getTriggerElectronicsId(const EcalElectronicsId& id) const {
0484 EcalSubdetector subdet = id.subdet();
0485
0486 if (subdet == EcalBarrel) {
0487 int strip = id.stripId();
0488 int xtal = id.xtalId();
0489 int tower = id.towerId();
0490 int tcc = id.dccId();
0491 if (id.zside() < 0) {
0492 tcc += TCCID_PHI0_EBM - DCCID_PHI0_EBM;
0493 } else {
0494 tcc += TCCID_PHI0_EBP - DCCID_PHI0_EBP;
0495 }
0496 EcalTriggerElectronicsId trelid(tcc, tower, strip, xtal);
0497 return trelid;
0498
0499 } else if (subdet == EcalEndcap) {
0500 EcalElectronicsMap_by_ElectronicsId::const_iterator it = get<1>(m_items).find(id);
0501 if (it == get<1>(m_items).end()) {
0502 EcalTriggerElectronicsId trelid(0);
0503 edm::LogError("EcalElectronicsMapping") << "Ecal mapping was asked non valid id";
0504 return trelid;
0505 }
0506 EcalTriggerElectronicsId trelid = it->trelid;
0507 return trelid;
0508 } else
0509 throw cms::Exception("InvalidDetId")
0510 << "Wrong EcalElectronicsId in EcalElectronicsMapping::getTriggerElectronicsId.";
0511 }
0512
0513 DetId EcalElectronicsMapping::getDetId(const EcalTriggerElectronicsId& id) const {
0514 EcalSubdetector subdet = id.subdet();
0515
0516 if (subdet == EcalBarrel) {
0517 const EcalElectronicsId& elid = getElectronicsId(id);
0518 DetId cell = getDetId(elid);
0519 return cell;
0520 } else if (subdet == EcalEndcap) {
0521 EcalElectronicsMap_by_TriggerElectronicsId::const_iterator it = get<2>(m_items).find(id);
0522 if (it == get<2>(m_items).end()) {
0523 DetId cell(0);
0524 edm::LogError("EcalElectronicsMapping") << "Ecal mapping was asked non valid DetId";
0525 return cell;
0526 }
0527 DetId cell = it->cell;
0528 return cell;
0529 } else
0530 throw cms::Exception("InvalidDetId") << "Wrong EcalTriggerElectronicsId in EcalElectronicsMapping::getDetId.";
0531 }
0532
0533 EcalElectronicsId EcalElectronicsMapping::getElectronicsId(const EcalTriggerElectronicsId& id) const {
0534 EcalSubdetector subdet = id.subdet();
0535
0536 if (subdet == EcalBarrel) {
0537 int strip = id.pseudoStripId();
0538 int xtal = id.channelId();
0539 int tower = id.ttId();
0540 int dcc = id.tccId();
0541 if (id.zside() < 0) {
0542 dcc -= TCCID_PHI0_EBM - DCCID_PHI0_EBM;
0543 } else {
0544 dcc -= TCCID_PHI0_EBP - DCCID_PHI0_EBP;
0545 }
0546 EcalElectronicsId elid(dcc, tower, strip, xtal);
0547 return elid;
0548 } else if (subdet == EcalEndcap) {
0549 EcalElectronicsMap_by_TriggerElectronicsId::const_iterator it = get<2>(m_items).find(id);
0550 if (it == get<2>(m_items).end()) {
0551 EcalElectronicsId elid(0);
0552 edm::LogError("EcalElectronicsMapping") << "Ecal mapping was asked non valid id";
0553 return elid;
0554 }
0555 EcalElectronicsId elid = it->elid;
0556 return elid;
0557 } else
0558 throw cms::Exception("InvalidDetId")
0559 << "Wrong EcalTriggerElectronicsId in EcalElectronicsMapping::getElectronicsId.";
0560 }
0561
0562 std::vector<DetId> EcalElectronicsMapping::dccConstituents(int dccId) const {
0563 EcalSubdetector sub = subdet(dccId, DCCMODE);
0564 std::vector<DetId> items;
0565
0566 if (sub == EcalBarrel) {
0567 for (int tower = 1; tower <= kEBTowersPerSM; tower++) {
0568 std::vector<DetId> xtals = dccTowerConstituents(dccId, tower);
0569 int size = xtals.size();
0570 for (int i = 0; i < size; i++) {
0571 DetId detid = xtals[i];
0572 items.emplace_back(detid);
0573 }
0574 }
0575 return items;
0576 } else if (sub == EcalEndcap) {
0577 EcalElectronicsMap_by_DccId::const_iterator lb, ub;
0578 boost::tuples::tie(lb, ub) = get<3>(m_items).equal_range(dccId);
0579 while (lb != ub) {
0580 DetId cell = lb->cell;
0581 items.emplace_back(cell);
0582 ++lb;
0583 }
0584 return items;
0585 } else
0586 throw cms::Exception("InvalidDetId") << "Wrong dccId = " << dccId
0587 << " in EcalElectronicsMapping::dccConstituents. ";
0588 }
0589
0590 std::vector<DetId> EcalElectronicsMapping::dccTowerConstituents(int dccId, int tower) const {
0591 EcalSubdetector sub = subdet(dccId, DCCMODE);
0592 std::vector<DetId> items;
0593
0594 if (sub == EcalBarrel) {
0595 int iz = zside(dccId, DCCMODE);
0596 int smid = 0;
0597 int iphi = 0;
0598 if (iz < 0) {
0599 smid = dccId + 19 - DCCID_PHI0_EBM;
0600 iphi = (smid - 19) * kCrystalsInPhi;
0601 iphi += 5 * ((tower - 1) % kTowersInPhi);
0602 } else {
0603 smid = dccId + 1 - DCCID_PHI0_EBP;
0604 iphi = (smid - 1) * kCrystalsInPhi;
0605 iphi += 5 * (kTowersInPhi - ((tower - 1) % kTowersInPhi) - 1);
0606 }
0607 int ieta = 5 * ((tower - 1) / kTowersInPhi) + 1;
0608 for (int ip = 1; ip <= 5; ip++) {
0609 for (int ie = 0; ie <= 4; ie++) {
0610 int ieta_xtal = ieta + ie;
0611 int iphi_xtal = iphi + ip;
0612 if (iz < 0)
0613 ieta_xtal = -ieta_xtal;
0614 EBDetId ebdetid(ieta_xtal, iphi_xtal, EBDetId::ETAPHIMODE);
0615 items.emplace_back(ebdetid);
0616 }
0617 }
0618 return items;
0619 }
0620
0621 else if (sub == EcalEndcap) {
0622 EcalElectronicsMap_by_DccId_and_TowerId::const_iterator lb, ub;
0623 boost::tuples::tie(lb, ub) = get<4>(m_items).equal_range(boost::make_tuple(int(dccId), int(tower)));
0624 while (lb != ub) {
0625 DetId cell = lb->cell;
0626 items.emplace_back(cell);
0627 ++lb;
0628 }
0629 return items;
0630 } else
0631 throw cms::Exception("InvalidDetId") << "Wrong dccId = " << dccId << " tower = " << tower
0632 << " in EcalElectronicsMapping::dccTowerConstituents.";
0633 }
0634
0635 std::vector<DetId> EcalElectronicsMapping::stripConstituents(int dccId, int tower, int strip) const {
0636 EcalSubdetector sub = subdet(dccId, DCCMODE);
0637 std::vector<DetId> items;
0638
0639 if (sub == EcalBarrel) {
0640 int iz = zside(dccId, DCCMODE);
0641 bool RightTower = rightTower(tower);
0642 int smid = 0;
0643 int iphi = 0;
0644 if (iz < 0) {
0645 smid = dccId + 19 - DCCID_PHI0_EBM;
0646 iphi = (smid - 19) * kCrystalsInPhi;
0647 iphi += 5 * ((tower - 1) % kTowersInPhi);
0648 } else {
0649 smid = dccId + 1 - DCCID_PHI0_EBP;
0650 iphi = (smid - 1) * kCrystalsInPhi;
0651 iphi += 5 * (kTowersInPhi - ((tower - 1) % kTowersInPhi) - 1);
0652 }
0653 int ieta = 5 * ((tower - 1) / kTowersInPhi) + 1;
0654 if (RightTower) {
0655 ieta += (strip - 1);
0656 } else {
0657 ieta += 4 - (strip - 1);
0658 }
0659 for (int ip = 1; ip <= 5; ip++) {
0660 int ieta_xtal = ieta;
0661 int iphi_xtal = iphi + ip;
0662 if (iz < 0)
0663 ieta_xtal = -ieta_xtal;
0664 EBDetId ebdetid(ieta_xtal, iphi_xtal, EBDetId::ETAPHIMODE);
0665 items.emplace_back(ebdetid);
0666 }
0667
0668 return items;
0669 } else {
0670 EcalElectronicsMap_by_DccId_TowerId_and_StripId::const_iterator lb, ub;
0671 boost::tuples::tie(lb, ub) = get<5>(m_items).equal_range(boost::make_tuple(int(dccId), int(tower), int(strip)));
0672 while (lb != ub) {
0673 DetId cell = lb->cell;
0674 items.emplace_back(cell);
0675 ++lb;
0676 }
0677 return items;
0678 }
0679 }
0680
0681 std::vector<DetId> EcalElectronicsMapping::tccConstituents(int tccId) const {
0682 EcalSubdetector sub = subdet(tccId, TCCMODE);
0683 std::vector<DetId> items;
0684
0685 if (sub == EcalBarrel) {
0686 int iz = zside(tccId, TCCMODE);
0687 int dccId = tccId;
0688 if (iz > 0)
0689 dccId = dccId - TCCID_PHI0_EBP + DCCID_PHI0_EBP;
0690 else
0691 dccId = dccId - TCCID_PHI0_EBM + DCCID_PHI0_EBM;
0692 items = dccConstituents(dccId);
0693 return items;
0694 } else {
0695 EcalElectronicsMap_by_TccId::const_iterator lb, ub;
0696 boost::tuples::tie(lb, ub) = get<6>(m_items).equal_range(tccId);
0697 while (lb != ub) {
0698 DetId cell = lb->cell;
0699 items.emplace_back(cell);
0700 ++lb;
0701 }
0702 return items;
0703 }
0704 }
0705
0706 std::vector<DetId> EcalElectronicsMapping::ttConstituents(int tccId, int tt) const {
0707 EcalSubdetector sub = subdet(tccId, TCCMODE);
0708 std::vector<DetId> items;
0709
0710 if (sub == EcalBarrel) {
0711 int iz = zside(tccId, TCCMODE);
0712 int dccId = tccId;
0713 if (iz > 0)
0714 dccId = dccId - TCCID_PHI0_EBP + DCCID_PHI0_EBP;
0715 else
0716 dccId = dccId - TCCID_PHI0_EBM + DCCID_PHI0_EBM;
0717 items = dccTowerConstituents(dccId, tt);
0718 return items;
0719 } else {
0720 EcalElectronicsMap_by_TccId_and_TtId::const_iterator lb, ub;
0721 boost::tuples::tie(lb, ub) = get<7>(m_items).equal_range(boost::make_tuple(int(tccId), int(tt)));
0722 while (lb != ub) {
0723 DetId cell = lb->cell;
0724 items.emplace_back(cell);
0725 ++lb;
0726 }
0727 return items;
0728 }
0729 }
0730
0731 std::vector<DetId> EcalElectronicsMapping::pseudoStripConstituents(int tccId, int tt, int pseudostrip) const {
0732 EcalSubdetector sub = subdet(tccId, TCCMODE);
0733 std::vector<DetId> items;
0734
0735 if (sub == EcalBarrel) {
0736 int iz = zside(tccId, TCCMODE);
0737 int dccId = tccId;
0738 if (iz > 0)
0739 dccId = dccId - TCCID_PHI0_EBP + DCCID_PHI0_EBP;
0740 else
0741 dccId = dccId - TCCID_PHI0_EBM + DCCID_PHI0_EBM;
0742 items = stripConstituents(dccId, tt, pseudostrip);
0743 return items;
0744 } else {
0745 EcalElectronicsMap_by_TccId_TtId_and_PseudostripId::const_iterator lb, ub;
0746 boost::tuples::tie(lb, ub) = get<8>(m_items).equal_range(boost::make_tuple(int(tccId), int(tt), int(pseudostrip)));
0747 while (lb != ub) {
0748 DetId cell = lb->cell;
0749 items.emplace_back(cell);
0750 ++lb;
0751 }
0752 return items;
0753 }
0754 }
0755
0756 void EcalElectronicsMapping::assign(const DetId& cell,
0757 const EcalElectronicsId& elid,
0758 const EcalTriggerElectronicsId& tower) {
0759 m_items.insert(MapItem(cell, elid, tower));
0760 }
0761
0762 std::pair<int, int> EcalElectronicsMapping::getDCCandSC(EcalScDetId id) const {
0763
0764
0765
0766
0767
0768 std::pair<int, int> ind;
0769 EEDetId dum;
0770 int ix = id.ix();
0771 int iy = id.iy();
0772 int zside = id.zside();
0773 ix = (ix - 1) * 5 + 1;
0774 iy = (iy - 1) * 5 + 1;
0775 ix = 5 * (ix / 5) + 1;
0776 iy = 5 * (iy / 5) + 1;
0777 int ix_c = ix;
0778 int iy_c = iy;
0779 if (!dum.validDetId(ix_c, iy_c, zside)) {
0780 ix_c = ix + 4;
0781 iy_c = iy;
0782 if (!dum.validDetId(ix_c, iy_c, zside)) {
0783 ix_c = ix + 4;
0784 iy_c = iy + 4;
0785 if (!dum.validDetId(ix_c, iy_c, zside)) {
0786 ix_c = ix;
0787 iy_c = iy + 4;
0788 }
0789 }
0790 }
0791 EEDetId eedetid(ix_c, iy_c, zside, EEDetId::XYMODE);
0792 EcalElectronicsId elid = getElectronicsId(eedetid);
0793 int Dccid = elid.dccId();
0794 int DCC_Channel = elid.towerId();
0795 ind.first = Dccid;
0796 ind.second = DCC_Channel;
0797 return ind;
0798 }
0799
0800 std::vector<EcalScDetId> EcalElectronicsMapping::getEcalScDetId(int DCCid,
0801 int DCC_Channel,
0802 bool ignoreSingleCrystal) const {
0803
0804 const bool debug = false;
0805
0806
0807
0808
0809
0810
0811 std::vector<EcalScDetId> scDetIds;
0812
0813
0814
0815
0816 std::vector<int> nReadoutXtals;
0817
0818 std::vector<DetId> xtals = dccTowerConstituents(DCCid, DCC_Channel);
0819
0820 if (debug) {
0821 std::ostringstream st1;
0822 st1 << __FILE__ << ":" << __LINE__ << ": " << xtals.size() << " crystals read out by channel " << DCC_Channel
0823 << " of DCC " << DCCid << ": ";
0824 for (auto xtal : xtals) {
0825 st1 << EEDetId(xtal) << " ";
0826 }
0827 edm::LogVerbatim("EcalMapping") << st1.str() << "\n";
0828 }
0829
0830 if (xtals.empty())
0831 throw cms::Exception("InvalidDetId") << "EcalElectronicsMapping : can not create EcalScDetId for DCC " << DCCid
0832 << " and DCC_Channel " << DCC_Channel << ".";
0833
0834 for (auto xtal : xtals) {
0835 EEDetId eedetid = xtal;
0836 int ix = eedetid.ix();
0837 int iy = eedetid.iy();
0838 int iz = eedetid.zside();
0839 int ix_SC = (ix - 1) / 5 + 1;
0840 int iy_SC = (iy - 1) / 5 + 1;
0841
0842 EcalScDetId scdetid(ix_SC, iy_SC, iz);
0843 size_t iSc = 0;
0844
0845 while (iSc < scDetIds.size() && scDetIds[iSc] != scdetid)
0846 ++iSc;
0847 if (iSc == scDetIds.size()) {
0848 scDetIds.emplace_back(scdetid);
0849 nReadoutXtals.emplace_back(1);
0850 } else {
0851 ++nReadoutXtals[iSc];
0852 }
0853 }
0854
0855 if (ignoreSingleCrystal) {
0856
0857
0858
0859
0860
0861 assert(scDetIds.size() == nReadoutXtals.size());
0862 for (size_t iSc = 0; iSc < scDetIds.size(); ) {
0863 if (nReadoutXtals[iSc] <= 1) {
0864 if (debug)
0865 edm::LogVerbatim("EcalMapping") << "EcalElectronicsMapping::getEcalScDetId: Ignore SC " << scDetIds[iSc]
0866 << " whose only one channel is read out by "
0867 "the DCC channel (DCC "
0868 << DCCid << ", ch " << DCC_Channel << ").\n";
0869 scDetIds.erase(scDetIds.begin() + iSc);
0870 nReadoutXtals.erase(nReadoutXtals.begin() + iSc);
0871 } else {
0872 ++iSc;
0873 }
0874 }
0875 }
0876
0877 return scDetIds;
0878 }
0879
0880 EcalSubdetector EcalElectronicsMapping::subdet(int dcctcc, int mode) const {
0881 if (mode == DCCMODE) {
0882 if ((dcctcc >= MIN_DCCID_EBM && dcctcc <= MAX_DCCID_EBM) || (dcctcc >= MIN_DCCID_EBP && dcctcc <= MAX_DCCID_EBP))
0883 return EcalBarrel;
0884 else
0885 return EcalEndcap;
0886 } else if (mode == TCCMODE) {
0887 if ((dcctcc >= MIN_TCCID_EBM && dcctcc <= MAX_TCCID_EBM) || (dcctcc >= MIN_TCCID_EBP && dcctcc <= MAX_TCCID_EBP))
0888 return EcalBarrel;
0889 else
0890 return EcalEndcap;
0891 } else
0892 throw cms::Exception("InvalidDetId") << " Wrong mode in EcalElectronicsMapping::subdet " << mode << ".";
0893 }
0894
0895 int EcalElectronicsMapping::zside(int dcctcc, int mode) const {
0896 if (mode == DCCMODE) {
0897 if (dcctcc >= MIN_DCCID_EBM && dcctcc <= MAX_DCCID_EBM)
0898 return -1;
0899 if (dcctcc >= MIN_DCCID_EBP && dcctcc <= MAX_DCCID_EBP)
0900 return +1;
0901 if (dcctcc >= MIN_DCCID_EEM && dcctcc <= MAX_DCCID_EEM)
0902 return -1;
0903 if (dcctcc >= MIN_DCCID_EEP && dcctcc <= MAX_DCCID_EEP)
0904 return +1;
0905 } else if (mode == TCCMODE) {
0906 if (dcctcc >= MIN_TCCID_EBM && dcctcc <= MAX_TCCID_EBM)
0907 return -1;
0908 if (dcctcc >= MIN_TCCID_EBP && dcctcc <= MAX_TCCID_EBP)
0909 return +1;
0910 if (dcctcc >= MIN_TCCID_EEM && dcctcc <= MAX_TCCID_EEM)
0911 return -1;
0912 if (dcctcc >= MIN_TCCID_EEP && dcctcc <= MAX_TCCID_EEP)
0913 return +1;
0914 } else {
0915 throw cms::Exception("InvalidDetId") << " Wrong mode in EcalElectronicsMapping::zside " << mode << ".";
0916 }
0917 return 0;
0918 }
0919
0920 bool EcalElectronicsMapping::rightTower(int tower) const {
0921
0922
0923 if ((tower > 12 && tower < 21) || (tower > 28 && tower < 37) || (tower > 44 && tower < 53) ||
0924 (tower > 60 && tower < 69))
0925 return true;
0926 else
0927 return false;
0928 }
0929
0930 int EcalElectronicsMapping::DCCBoundary(int FED) const {
0931 if (FED >= MIN_DCCID_EEM && FED <= MAX_DCCID_EEM)
0932 return MIN_DCCID_EEM;
0933 if (FED >= MIN_DCCID_EBM && FED <= MAX_DCCID_EBM)
0934 return MIN_DCCID_EBM;
0935 if (FED >= MIN_DCCID_EBP && FED <= MAX_DCCID_EBP)
0936 return MIN_DCCID_EBP;
0937 if (FED >= MIN_DCCID_EEP && FED <= MAX_DCCID_EEP)
0938 return MIN_DCCID_EEP;
0939 return -1;
0940 }
0941
0942 std::vector<int> EcalElectronicsMapping::GetListofFEDs(const RectangularEtaPhiRegion& region) const {
0943 std::vector<int> FEDs;
0944 GetListofFEDs(region, FEDs);
0945 return FEDs;
0946 }
0947 void EcalElectronicsMapping::GetListofFEDs(const RectangularEtaPhiRegion& region, std::vector<int>& FEDs) const {
0948
0949
0950
0951
0952 double radTodeg = 180. / M_PI;
0953 ;
0954
0955 bool debug = false;
0956
0957 double etalow = region.etaLow();
0958 double philow = region.phiLow() * radTodeg;
0959 if (debug)
0960 edm::LogVerbatim("EcalMapping") << " etalow philow " << etalow << " " << philow;
0961 int FED_LB = GetFED(etalow, philow);
0962
0963 double phihigh = region.phiHigh() * radTodeg;
0964 if (debug)
0965 edm::LogVerbatim("EcalMapping") << " etalow phihigh " << etalow << " " << phihigh;
0966 int FED_LT = GetFED(etalow, phihigh);
0967
0968 int DCC_BoundaryL = DCCBoundary(FED_LB);
0969 int deltaL = 18;
0970 if (FED_LB < MIN_DCCID_EBM || FED_LB > MAX_DCCID_EBP)
0971 deltaL = 9;
0972
0973 if (philow < -170 && phihigh > 170) {
0974 FED_LB = DCC_BoundaryL;
0975 FED_LT = DCC_BoundaryL + deltaL - 1;
0976 }
0977 if (debug)
0978 edm::LogVerbatim("EcalMapping") << " FED_LB FED_LT " << FED_LB << " " << FED_LT;
0979
0980 bool dummy = true;
0981 int idx = 0;
0982 while (dummy) {
0983 int iL = (FED_LB - DCC_BoundaryL + idx) % deltaL + DCC_BoundaryL;
0984 FEDs.emplace_back(iL);
0985 if (debug)
0986 edm::LogVerbatim("EcalMapping") << " add fed " << iL;
0987 if (iL == FED_LT)
0988 break;
0989 idx++;
0990 }
0991
0992 double etahigh = region.etaHigh();
0993 int FED_RB = GetFED(etahigh, philow);
0994 if (FED_RB == FED_LB)
0995 return;
0996
0997 int FED_RT = GetFED(etahigh, phihigh);
0998
0999 if (debug)
1000 edm::LogVerbatim("EcalMapping") << "etahigh philow phihigh " << etahigh << " " << philow << " " << phihigh;
1001 int DCC_BoundaryR = DCCBoundary(FED_RB);
1002 int deltaR = 18;
1003 if (FED_RB < MIN_DCCID_EBM || FED_RB > MAX_DCCID_EBP)
1004 deltaR = 9;
1005
1006 if (philow < -170 && phihigh > 170) {
1007 FED_RB = DCC_BoundaryR;
1008 FED_RT = DCC_BoundaryR + deltaR - 1;
1009 }
1010 if (debug)
1011 edm::LogVerbatim("EcalMapping") << " FED_RB FED_RT " << FED_RB << " " << FED_RT;
1012 idx = 0;
1013 while (dummy) {
1014 int iR = (FED_RB - DCC_BoundaryR + idx) % deltaR + DCC_BoundaryR;
1015 FEDs.emplace_back(iR);
1016 if (debug)
1017 edm::LogVerbatim("EcalMapping") << " add fed " << iR;
1018 if (iR == FED_RT)
1019 break;
1020 idx++;
1021 }
1022
1023 if (FED_LB >= MIN_DCCID_EBM && FED_LB <= MAX_DCCID_EBM && FED_RB >= MIN_DCCID_EEP && FED_RB <= MAX_DCCID_EEP) {
1024 int minR = FED_LB + 18;
1025 int maxR = FED_LT + 18;
1026 int idx = 0;
1027 while (dummy) {
1028 int iR = (minR - MIN_DCCID_EBP + idx) % 18 + MIN_DCCID_EBP;
1029 FEDs.emplace_back(iR);
1030 if (debug)
1031 edm::LogVerbatim("EcalMapping") << " add fed " << iR;
1032 if (iR == maxR)
1033 break;
1034 idx++;
1035 }
1036 return;
1037 }
1038
1039 if (FED_LB >= MIN_DCCID_EEM && FED_LB <= MAX_DCCID_EEM && FED_RB >= MIN_DCCID_EBP && FED_RB <= MAX_DCCID_EBP) {
1040 int minL = FED_RB - 18;
1041 int maxL = FED_RT - 18;
1042 int idx = 0;
1043 while (dummy) {
1044 int iL = (minL - MIN_DCCID_EBM + idx) % 18 + MIN_DCCID_EBM;
1045 FEDs.emplace_back(iL);
1046 if (debug)
1047 edm::LogVerbatim("EcalMapping") << " add fed " << iL;
1048 if (iL == maxL)
1049 break;
1050 idx++;
1051 }
1052 return;
1053 }
1054
1055 if (FED_LB >= MIN_DCCID_EEM && FED_LB <= MAX_DCCID_EEM && FED_RB >= MIN_DCCID_EEP && FED_RB <= MAX_DCCID_EEP) {
1056 int minL = (FED_LB - 1) * 2 + MIN_DCCID_EBM;
1057 if (minL == MIN_DCCID_EBM)
1058 minL = MAX_DCCID_EBM;
1059 else
1060 minL = minL - 1;
1061 int maxL = (FED_LT - 1) * 2 + MIN_DCCID_EBM;
1062 int idx = 0;
1063 while (dummy) {
1064 int iL = (minL - MIN_DCCID_EBM + idx) % 18 + MIN_DCCID_EBM;
1065 FEDs.emplace_back(iL);
1066 if (debug)
1067 edm::LogVerbatim("EcalMapping") << " add fed " << iL;
1068 if (iL == maxL)
1069 break;
1070 idx++;
1071 }
1072 int minR = minL + 18;
1073 int maxR = maxL + 18;
1074 idx = 0;
1075 while (dummy) {
1076 int iR = (minR - MIN_DCCID_EBP + idx) % 18 + MIN_DCCID_EBP;
1077 FEDs.emplace_back(iR);
1078 if (debug)
1079 edm::LogVerbatim("EcalMapping") << " add fed " << iR;
1080 if (iR == maxR)
1081 break;
1082 idx++;
1083 }
1084 }
1085
1086 return;
1087 }
1088
1089 int EcalElectronicsMapping::GetFED(double eta, double phi) const {
1090
1091
1092
1093 int DCC_Phi0 = 0;
1094 bool IsBarrel = true;
1095 if (fabs(eta) > 1.479)
1096 IsBarrel = false;
1097 bool Positive = (eta > 0);
1098
1099 if (IsBarrel && Positive)
1100 DCC_Phi0 = DCCID_PHI0_EBP;
1101 if (IsBarrel && (!Positive))
1102 DCC_Phi0 = DCCID_PHI0_EBM;
1103 if ((!IsBarrel) && Positive)
1104 DCC_Phi0 = MIN_DCCID_EEP;
1105 if ((!IsBarrel) && (!Positive))
1106 DCC_Phi0 = MIN_DCCID_EEM;
1107
1108
1109 if (phi < 0)
1110 phi += 360;
1111 if (phi > 360.)
1112 phi = 360.;
1113 if (phi < 0)
1114 phi = 0.;
1115
1116 if (IsBarrel)
1117 phi = phi - 350;
1118 else
1119 phi = phi - 330;
1120 if (phi < 0)
1121 phi += 360;
1122 int iphi = -1;
1123 if (IsBarrel)
1124 iphi = (int)(phi / 20.);
1125 else
1126 iphi = (int)(phi / 40.);
1127
1128
1129
1130 int DCC = iphi + DCC_Phi0;
1131
1132 return DCC;
1133 }
1134
1135 int EcalElectronicsMapping::getLMNumber(const DetId& id) const {
1136
1137
1138 EcalSubdetector subdet = EcalSubdetector(id.subdetId());
1139
1140 if (subdet == EcalBarrel) {
1141 const EBDetId ebdetid = EBDetId(id);
1142 int dccid = DCCid(ebdetid);
1143 std::map<int, int>::const_iterator it = LaserMonitoringMap_EB.find(dccid);
1144 if (it != LaserMonitoringMap_EB.end()) {
1145 int ilm = it->second;
1146 int iETA = ebdetid.ietaSM();
1147 int iPHI = ebdetid.iphiSM();
1148 if (iPHI > 10 && iETA > 5) {
1149 ilm++;
1150 };
1151 return ilm;
1152 } else
1153 throw cms::Exception("InvalidDCCId") << "Wrong DCCId (EB) in EcalElectronicsMapping::getLMNumber.";
1154 }
1155
1156 else if (subdet == EcalEndcap) {
1157 EcalElectronicsId elid = getElectronicsId(id);
1158 int dccid = elid.dccId();
1159 EEDetId eedetid = EEDetId(id);
1160 std::map<int, int>::const_iterator it = LaserMonitoringMap_EE.find(dccid);
1161 if (it != LaserMonitoringMap_EB.end()) {
1162 int ilm = it->second;
1163 if (dccid == 8) {
1164 int ix = eedetid.ix();
1165 if (ix > 50)
1166 ilm += 1;
1167 }
1168 if (dccid == 53) {
1169 int ix = eedetid.ix();
1170 if (ix > 50)
1171 ilm += 1;
1172 }
1173 return ilm;
1174 } else
1175 throw cms::Exception("InvalidDCCId") << "Wrong DCCId (EE) in EcalElectronicsMapping::getLMNumber.";
1176 }
1177
1178 return -1;
1179 }