Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:07:13

0001 #include "DQM/EcalCommon/interface/MESetBinningUtils.h"
0002 
0003 #include "DQM/EcalCommon/interface/EcalDQMCommonUtils.h"
0004 
0005 #include "DataFormats/EcalDetId/interface/EcalPnDiodeDetId.h"
0006 
0007 #include <algorithm>
0008 
0009 #include "TMath.h"
0010 
0011 namespace ecaldqm {
0012   namespace binning {
0013     int xlow_(int _iSM) {
0014       switch (_iSM) {
0015         case kEEm01:
0016         case kEEp01:
0017           return 20;
0018         case kEEm02:
0019         case kEEp02:
0020           return 0;
0021         case kEEm03:
0022         case kEEp03:
0023           return 0;
0024         case kEEm04:
0025         case kEEp04:
0026           return 5;
0027         case kEEm05:
0028         case kEEp05:
0029           return 35;
0030         case kEEm06:
0031         case kEEp06:
0032           return 55;
0033         case kEEm07:
0034         case kEEp07:
0035           return 60;
0036         case kEEm08:
0037         case kEEp08:
0038           return 55;
0039         case kEEm09:
0040         case kEEp09:
0041           return 50;
0042         default:
0043           break;
0044       }
0045 
0046       if (_iSM >= kEBmLow && _iSM <= kEBpHigh)
0047         return 0;
0048 
0049       return 0;
0050     }
0051 
0052     int ylow_(int _iSM) {
0053       switch (_iSM) {
0054         case kEEm01:
0055         case kEEp01:
0056         case kEEm09:
0057         case kEEp09:
0058           return 60;
0059         case kEEm02:
0060         case kEEp02:
0061         case kEEm08:
0062         case kEEp08:
0063           return 50;
0064         case kEEm03:
0065         case kEEp03:
0066         case kEEm07:
0067         case kEEp07:
0068           return 25;
0069         case kEEm04:
0070         case kEEp04:
0071         case kEEm06:
0072         case kEEp06:
0073           return 5;
0074         case kEEm05:
0075         case kEEp05:
0076           return 0;
0077         default:
0078           break;
0079       }
0080 
0081       if (_iSM >= kEBmLow && _iSM <= kEBmHigh)
0082         return ((_iSM - kEBmLow) % 18) * 20;
0083       if (_iSM >= kEBpLow && _iSM <= kEBpHigh)
0084         return (-1 - ((_iSM - kEBpLow) % 18)) * 20;
0085 
0086       return 0;
0087     }
0088 
0089     AxisSpecs getBinningEB_(BinningType _btype, bool _isMap, int _axis) {
0090       AxisSpecs specs;
0091 
0092       if (!_isMap) {
0093         switch (_btype) {
0094           case kTCC:
0095             specs.nbins = 36;
0096             specs.low = 9.;
0097             specs.high = 45.;
0098             specs.title = "iTCC";
0099             break;
0100           case kDCC:
0101             specs.nbins = 36;
0102             specs.low = 9.;
0103             specs.high = 45.;
0104             break;
0105           case kProjEta:
0106             specs.nbins = nEBEtaBins;
0107             specs.low = -etaBound;
0108             specs.high = etaBound;
0109             specs.title = "eta";
0110             break;
0111           case kProjPhi:
0112             specs.nbins = nPhiBins;
0113             specs.low = -TMath::Pi() / 18.;
0114             specs.high = TMath::Pi() * 35. / 18.;
0115             specs.title = "phi";
0116             break;
0117           default:
0118             break;
0119         }
0120       } else {
0121         switch (_btype) {
0122           case kCrystal:
0123             if (_axis == 1)
0124               specs.nbins = 360;
0125             else if (_axis == 2)
0126               specs.nbins = 170;
0127             break;
0128           case kSuperCrystal:
0129           case kTriggerTower:
0130           case kPseudoStrip:
0131             if (_axis == 1)
0132               specs.nbins = 72;
0133             else if (_axis == 2)
0134               specs.nbins = 34;
0135             break;
0136           default:
0137             return specs;
0138         }
0139 
0140         if (_axis == 1) {
0141           specs.low = 0.;
0142           specs.high = 360.;
0143           specs.title = "iphi";
0144         } else if (_axis == 2) {
0145           specs.low = -85.;
0146           specs.high = 85.;
0147           specs.title = "ieta";
0148         }
0149       }
0150 
0151       return specs;
0152     }
0153 
0154     AxisSpecs getBinningEE_(BinningType _btype, bool _isMap, int _zside, int _axis) {
0155       AxisSpecs specs;
0156 
0157       if (!_isMap) {
0158         switch (_btype) {
0159           case kTCC:
0160             specs.nbins = _zside ? 36 : 72;
0161             specs.low = 0.;
0162             specs.high = _zside ? 36. : 72.;
0163             specs.title = "iTCC";
0164             break;
0165           case kDCC:
0166             specs.nbins = _zside ? 9 : 18;
0167             specs.low = 0.;
0168             specs.high = _zside ? 9. : 18.;
0169             break;
0170           case kProjEta:
0171             if (_zside == 0) {
0172               specs.nbins = nEEEtaBins / (3. - etaBound) * 6.;
0173               specs.low = -3.;
0174               specs.high = 3.;
0175             } else {
0176               specs.nbins = nEEEtaBins;
0177               specs.low = _zside < 0 ? -3. : etaBound;
0178               specs.high = _zside < 0 ? -etaBound : 3.;
0179             }
0180             specs.title = "eta";
0181             break;
0182           case kProjPhi:
0183             specs.nbins = nPhiBins;
0184             specs.low = -TMath::Pi() / 18.;
0185             specs.high = TMath::Pi() * 35. / 18.;
0186             specs.title = "phi";
0187             break;
0188           default:
0189             break;
0190         }
0191       } else {
0192         switch (_btype) {
0193           case kCrystal:
0194           case kTriggerTower:
0195           case kPseudoStrip:
0196             if (_axis == 1)
0197               specs.nbins = _zside ? 100 : 200;
0198             if (_axis == 2)
0199               specs.nbins = 100;
0200             break;
0201           case kSuperCrystal:
0202             if (_axis == 1)
0203               specs.nbins = _zside ? 20 : 40;
0204             if (_axis == 2)
0205               specs.nbins = 20;
0206             break;
0207           default:
0208             return specs;
0209         }
0210 
0211         if (_axis == 1) {
0212           specs.low = 0.;
0213           specs.high = _zside ? 100. : 200.;
0214           specs.title = "ix";
0215         } else if (_axis == 2) {
0216           specs.low = 0.;
0217           specs.high = 100.;
0218           specs.title = "iy";
0219         }
0220       }
0221 
0222       return specs;
0223     }
0224 
0225     AxisSpecs getBinningSM_(
0226         BinningType _btype, bool _isMap, unsigned _iObj, int _axis, const EcalElectronicsMapping *electronicsMap) {
0227       AxisSpecs specs;
0228 
0229       unsigned iSM(_iObj);
0230 
0231       const bool isBarrel(iSM >= kEBmLow && iSM <= kEBpHigh);
0232 
0233       if (!_isMap) {
0234         switch (_btype) {
0235           case kCrystal:
0236             specs.nbins = isBarrel ? 1700 : electronicsMap->dccConstituents(iSM + 1).size();
0237             specs.low = 0.;
0238             specs.high = specs.nbins;
0239             specs.title = "crystal";
0240             break;
0241           case kTriggerTower:
0242           case kPseudoStrip:
0243             specs.nbins = isBarrel ? 68 : (2 * nTTOuter + 2 * nTTInner);  // For EE: numbering of bins
0244             // is in the order (inner1, inner2, outer1, outer2). ("inner"" := closer
0245             // to the beam)
0246             specs.low = 1.;
0247             specs.high = specs.nbins + specs.low;
0248             specs.title = "tower";
0249             break;
0250           case kSuperCrystal:
0251             specs.nbins = isBarrel ? 68 : nSuperCrystals(iSM + 1);
0252             specs.low = 1.;
0253             specs.high = specs.nbins + specs.low;
0254             specs.title = "tower";
0255             break;
0256           default:
0257             break;
0258         }
0259       } else {
0260         int nEEX(nEESMX);
0261         int nEEY(nEESMY);
0262         if (iSM == kEEm02 || iSM == kEEm08 || iSM == kEEp02 || iSM == kEEp08)
0263           nEEX = nEESMXExt;
0264         if (iSM == kEEm01 || iSM == kEEm05 || iSM == kEEm09 || iSM == kEEp01 || iSM == kEEp05 || iSM == kEEp09)
0265           nEEX = nEESMXRed;
0266         if (iSM == kEEm03 || iSM == kEEm07 || iSM == kEEp03 || iSM == kEEp07)
0267           nEEY = nEESMYRed;
0268 
0269         switch (_btype) {
0270           case kCrystal:
0271             if (_axis == 1)
0272               specs.nbins = isBarrel ? nEBSMEta : nEEX;
0273             else if (_axis == 2)
0274               specs.nbins = isBarrel ? nEBSMPhi : nEEY;
0275             break;
0276           case kTriggerTower:
0277           case kPseudoStrip:
0278             if (_axis == 1)
0279               specs.nbins = isBarrel ? nEBSMEta / 5 : nEEX;
0280             else if (_axis == 2)
0281               specs.nbins = isBarrel ? nEBSMPhi / 5 : nEEY;
0282             break;
0283           case kSuperCrystal:
0284             if (_axis == 1)
0285               specs.nbins = isBarrel ? nEBSMEta / 5 : nEEX / 5;
0286             else if (_axis == 2)
0287               specs.nbins = isBarrel ? nEBSMPhi / 5 : nEEY / 5;
0288             break;
0289           default:
0290             return specs;
0291         }
0292 
0293         if (_axis == 1) {
0294           specs.low = xlow_(iSM);
0295           specs.high = specs.low + (isBarrel ? nEBSMEta : nEEX);
0296           specs.title = isBarrel ? (iSM < kEBpLow ? "-ieta" : "ieta") : "ix";
0297         } else if (_axis == 2) {
0298           specs.low = ylow_(iSM);
0299           specs.high = specs.low + (isBarrel ? nEBSMPhi : nEEY);
0300           specs.title = isBarrel ? "iphi" : "iy";
0301         }
0302       }
0303 
0304       return specs;
0305     }
0306 
0307     AxisSpecs getBinningSMMEM_(BinningType _btype, bool _isMap, unsigned _iObj, int _axis) {
0308       AxisSpecs specs;
0309 
0310       unsigned iSM(memDCCId(_iObj) - 1);
0311 
0312       if (iSM == unsigned(-1) || _btype != kCrystal)
0313         return specs;
0314 
0315       if (_axis == 1) {
0316         specs.nbins = 10;
0317         specs.low = 0.;
0318         specs.high = 10.;
0319         if (_isMap)
0320           specs.title = "pseudo-strip";
0321         else
0322           specs.title = "iPN";
0323       } else if (_axis == 2) {
0324         specs.nbins = 1;
0325         specs.low = 0.;
0326         specs.high = 5.;
0327         specs.title = "channel";
0328       }
0329 
0330       return specs;
0331     }
0332 
0333     AxisSpecs getBinningEcal_(BinningType _btype, bool _isMap, int _axis) {
0334       AxisSpecs specs;
0335 
0336       if (!_isMap) {
0337         switch (_btype) {
0338           case kTCC:
0339             specs.nbins = 108;
0340             specs.low = 0.;
0341             specs.high = 108.;
0342             specs.title = "iTCC";
0343             break;
0344           case kDCC:
0345             specs.nbins = 54;
0346             specs.low = 0.;
0347             specs.high = 54.;
0348             specs.title = "iDCC";
0349             break;
0350           case kProjEta:
0351             specs.nbins = nEBEtaBins + 2 * nEEEtaBins;
0352             specs.edges = std::vector(specs.nbins + 1, 0.f);
0353             for (int i(0); i <= nEEEtaBins; i++)
0354               specs.edges[i] = -3. + (3. - etaBound) / nEEEtaBins * i;
0355             for (int i(1); i <= nEBEtaBins; i++)
0356               specs.edges[i + nEEEtaBins] = -etaBound + 2. * etaBound / nEBEtaBins * i;
0357             for (int i(1); i <= nEEEtaBins; i++)
0358               specs.edges[i + nEEEtaBins + nEBEtaBins] = etaBound + (3. - etaBound) / nEEEtaBins * i;
0359             specs.title = "eta";
0360             break;
0361           case kProjPhi:
0362             specs.nbins = nPhiBins;
0363             specs.low = -TMath::Pi() / 18.;
0364             specs.high = TMath::Pi() * 35. / 18.;
0365             specs.title = "phi";
0366             break;
0367           default:
0368             break;
0369         }
0370       } else {
0371         switch (_btype) {
0372           case kDCC:
0373             if (_axis == 1) {
0374               specs.nbins = 9;
0375               specs.low = 0.;
0376               specs.high = 9.;
0377             } else if (_axis == 2) {
0378               specs.nbins = 6;
0379               specs.low = 0.;
0380               specs.high = 6.;
0381             }
0382             break;
0383           case kRCT:
0384             if (_axis == 1) {
0385               specs.nbins = 64;
0386               specs.low = -32.;
0387               specs.high = 32.;
0388               specs.title = "RCT iEta";
0389             } else if (_axis == 2) {
0390               specs.nbins = 72;
0391               specs.low = 0.;
0392               specs.high = 72.;
0393               specs.title = "RCT Phi";
0394             }
0395             break;
0396           default:
0397             break;
0398         }
0399       }
0400 
0401       return specs;
0402     }
0403 
0404     AxisSpecs getBinningMEM_(BinningType _btype, bool _isMap, int _subdet, int _axis) {
0405       AxisSpecs specs;
0406 
0407       if (_btype != kCrystal)
0408         return specs;
0409 
0410       int nbins(44);
0411       if (_subdet == EcalBarrel)
0412         nbins = 36;
0413       else if (_subdet == EcalEndcap)
0414         nbins = 8;
0415 
0416       if (_axis == 1) {
0417         specs.nbins = nbins;
0418         specs.low = 0.;
0419         specs.high = nbins;
0420       } else if (_axis == 2) {
0421         specs.nbins = 10;
0422         specs.low = 0.;
0423         specs.high = 10.;
0424         specs.title = "iPN";
0425       }
0426 
0427       return specs;
0428     }
0429 
0430     int findBinCrystal_(const EcalElectronicsMapping *electronicsMap,
0431                         ObjectType _otype,
0432                         const DetId &_id,
0433                         int _iSM /* = -1*/) {
0434       int xbin(0), ybin(0);
0435       int nbinsX(0);
0436       int subdet(_id.subdetId());
0437 
0438       if (subdet == EcalBarrel) {
0439         EBDetId ebid(_id);
0440         int iphi(ebid.iphi());
0441         int ieta(ebid.ieta());
0442         switch (_otype) {
0443           case kEB:
0444             xbin = iphi;
0445             ybin = ieta < 0 ? ieta + 86 : ieta + 85;
0446             nbinsX = 360;
0447             break;
0448           case kSM:
0449           case kEBSM:
0450             xbin = ieta < 0 ? -ieta : ieta;
0451             ybin = ieta < 0 ? (iphi - 1) % 20 + 1 : 20 - (iphi - 1) % 20;
0452             nbinsX = nEBSMEta;
0453             break;
0454           default:
0455             break;
0456         }
0457       } else if (subdet == EcalEndcap) {
0458         EEDetId eeid(_id);
0459         int ix(eeid.ix());
0460         int iy(eeid.iy());
0461         switch (_otype) {
0462           case kEE:
0463             xbin = eeid.zside() < 0 ? ix : ix + 100;
0464             ybin = iy;
0465             nbinsX = 200;
0466             break;
0467           case kEEm:
0468           case kEEp:
0469             xbin = ix;
0470             ybin = iy;
0471             nbinsX = 100;
0472             break;
0473           case kSM:
0474           case kEESM: {
0475             int iSM(_iSM >= 0 ? _iSM : dccId(_id, electronicsMap) - 1);
0476             xbin = ix - xlow_(iSM);
0477             ybin = iy - ylow_(iSM);
0478             if (iSM == kEEm02 || iSM == kEEm08 || iSM == kEEp02 || iSM == kEEp08)
0479               nbinsX = nEESMXExt;
0480             else if (iSM == kEEm01 || iSM == kEEm05 || iSM == kEEm09 || iSM == kEEp01 || iSM == kEEp05 || iSM == kEEp09)
0481               nbinsX = nEESMXRed;
0482             else
0483               nbinsX = nEESMX;
0484           } break;
0485           default:
0486             break;
0487         }
0488       } else if (subdet == EcalLaserPnDiode) {
0489         EcalPnDiodeDetId pnid(_id);
0490         switch (_otype) {
0491           case kSMMEM:
0492           case kEBSMMEM:
0493           case kEESMMEM:
0494             xbin = pnid.iPnId();
0495             ybin = 1;
0496             nbinsX = 10;
0497             break;
0498           case kMEM:
0499             xbin = memDCCIndex(dccId(_id, electronicsMap)) + 1;
0500             ybin = pnid.iPnId();
0501             nbinsX = 44;
0502             break;
0503           case kEBMEM:
0504             xbin = memDCCIndex(dccId(_id, electronicsMap)) - 3;
0505             ybin = pnid.iPnId();
0506             nbinsX = 36;
0507             break;
0508           case kEEMEM:
0509             xbin = memDCCIndex(dccId(_id, electronicsMap)) + 1;
0510             if (xbin > kEEmHigh + 1)
0511               xbin -= 36;
0512             ybin = pnid.iPnId();
0513             nbinsX = 8;
0514             break;
0515           default:
0516             break;
0517         }
0518       }
0519 
0520       return (nbinsX + 2) * ybin + xbin;
0521     }
0522 
0523     int findBinCrystal_(const EcalElectronicsMapping *electronicsMap, ObjectType _otype, EcalElectronicsId const &_id) {
0524       return findBinCrystal_(electronicsMap, _otype, electronicsMap->getDetId(_id));
0525     }
0526 
0527     int findBinRCT_(ObjectType _otype, DetId const &_id) {
0528       int xbin(0);
0529       int ybin(0);
0530       int nbinsX(0);
0531 
0532       EcalTrigTowerDetId ttid(_id);
0533       int ieta(ttid.ieta());
0534       int iphi((ttid.iphi() + 1) % 72 + 1);
0535 
0536       xbin = ieta < 0 ? ieta + 33 : ieta + 32;
0537       ybin = iphi;
0538       nbinsX = 64;
0539 
0540       return (nbinsX + 2) * ybin + xbin;
0541     }
0542 
0543     int findBinTriggerTower_(const EcalElectronicsMapping *electronicsMap, ObjectType _otype, DetId const &_id) {
0544       int xbin(0);
0545       int ybin(0);
0546       int nbinsX(0);
0547       int subdet(_id.subdetId());
0548 
0549       if ((subdet == EcalTriggerTower && !isEndcapTTId(_id)) || subdet == EcalBarrel) {
0550         EcalTrigTowerDetId ttid;
0551         if (subdet == EcalBarrel)
0552           ttid = EBDetId(_id).tower();
0553         else
0554           ttid = _id;
0555 
0556         int ieta(ttid.ieta());
0557         int iphi((ttid.iphi() + 1) % 72 + 1);
0558         switch (_otype) {
0559           case kEB:
0560             xbin = iphi;
0561             ybin = ieta < 0 ? ieta + 18 : ieta + 17;
0562             nbinsX = 72;
0563             break;
0564           case kSM:
0565           case kEBSM:
0566             xbin = ieta < 0 ? -ieta : ieta;
0567             ybin = ieta < 0 ? (iphi - 1) % 4 + 1 : 4 - (iphi - 1) % 4;
0568             nbinsX = 17;
0569             break;
0570           case kEcal:
0571             xbin = ieta < 0 ? ieta + 33 : ieta + 32;
0572             ybin = iphi > 70 ? iphi - 70 : iphi + 2;
0573             nbinsX = 64;
0574           default:
0575             break;
0576         }
0577       } else if (subdet == EcalEndcap) {
0578         unsigned tccid(tccId(_id, electronicsMap));
0579         unsigned iSM(tccid <= 36 ? tccid % 18 / 2 : (tccid - 72) % 18 / 2);
0580         return findBinCrystal_(electronicsMap, _otype, _id, iSM);
0581       }
0582 
0583       return (nbinsX + 2) * ybin + xbin;
0584     }
0585 
0586     int findBinPseudoStrip_(const EcalElectronicsMapping *electronicsMap, ObjectType _otype, DetId const &_id) {
0587       int xbin(0);
0588       int ybin(0);
0589       int nbinsX(0);
0590       int subdet(_id.subdetId());
0591 
0592       if ((subdet == EcalTriggerTower && !isEndcapTTId(_id)) || subdet == EcalBarrel) {
0593         return findBinTriggerTower_(electronicsMap, _otype, _id);
0594       } else if (subdet == EcalEndcap) {
0595         unsigned tccid(tccId(_id, electronicsMap));
0596         unsigned iSM(tccid <= 36 ? tccid % 18 / 2 : (tccid - 72) % 18 / 2);
0597         return findBinCrystal_(electronicsMap, _otype, _id, iSM);
0598       }
0599 
0600       return (nbinsX + 2) * ybin + xbin;
0601     }
0602 
0603     int findBinSuperCrystal_(const EcalElectronicsMapping *electronicsMap,
0604                              ObjectType _otype,
0605                              const DetId &_id,
0606                              int _iSM /* -1*/) {
0607       int xbin(0);
0608       int ybin(0);
0609       int nbinsX(0);
0610       int subdet(_id.subdetId());
0611 
0612       if (subdet == EcalBarrel) {
0613         EBDetId ebid(_id);
0614         int iphi(ebid.iphi());
0615         int ieta(ebid.ieta());
0616         switch (_otype) {
0617           case kEB:
0618             xbin = (iphi - 1) / 5 + 1;
0619             ybin = (ieta < 0 ? ieta + 85 : ieta + 84) / 5 + 1;
0620             nbinsX = 72;
0621             break;
0622           case kSM:
0623           case kEBSM:
0624             xbin = (ieta < 0 ? -ieta - 1 : ieta - 1) / 5 + 1;
0625             ybin = (ieta < 0 ? (iphi - 1) % 20 : 19 - (iphi - 1) % 20) / 5 + 1;
0626             nbinsX = nEBSMEta / 5;
0627             break;
0628           default:
0629             break;
0630         }
0631       } else if (subdet == EcalEndcap) {
0632         if (isEcalScDetId(_id)) {
0633           EcalScDetId scid(_id);
0634           int ix(scid.ix());
0635           int iy(scid.iy());
0636           switch (_otype) {
0637             case kEE: {
0638               int zside(scid.zside());
0639               xbin = zside < 0 ? ix : ix + 20;
0640               ybin = iy;
0641               nbinsX = 40;
0642             } break;
0643             case kEEm:
0644             case kEEp:
0645               xbin = ix;
0646               ybin = iy;
0647               nbinsX = 20;
0648               break;
0649             case kSM:
0650             case kEESM: {
0651               int iSM(_iSM >= 0 ? _iSM : dccId(_id, electronicsMap) - 1);
0652               xbin = ix - xlow_(iSM) / 5;
0653               ybin = iy - ylow_(iSM) / 5;
0654               if (iSM == kEEm02 || iSM == kEEm08 || iSM == kEEp02 || iSM == kEEp08)
0655                 nbinsX = nEESMXExt / 5;
0656               else if (iSM == kEEm01 || iSM == kEEm05 || iSM == kEEm09 || iSM == kEEp01 || iSM == kEEp05 ||
0657                        iSM == kEEp09)
0658                 nbinsX = nEESMXRed / 5;
0659               else
0660                 nbinsX = nEESMX / 5;
0661             } break;
0662             default:
0663               break;
0664           }
0665         } else {
0666           EEDetId eeid(_id);
0667           int ix(eeid.ix());
0668           int iy(eeid.iy());
0669           switch (_otype) {
0670             case kEE:
0671               xbin = (eeid.zside() < 0 ? ix - 1 : ix + 99) / 5 + 1;
0672               ybin = (iy - 1) / 5 + 1;
0673               nbinsX = 40;
0674               break;
0675             case kEEm:
0676             case kEEp:
0677               xbin = (ix - 1) / 5 + 1;
0678               ybin = (iy - 1) / 5 + 1;
0679               nbinsX = 20;
0680               break;
0681             case kSM:
0682             case kEESM: {
0683               int iSM(_iSM >= 0 ? _iSM : dccId(_id, electronicsMap) - 1);
0684               xbin = (ix - xlow_(iSM) - 1) / 5 + 1;
0685               ybin = (iy - ylow_(iSM) - 1) / 5 + 1;
0686               if (iSM == kEEm02 || iSM == kEEm08 || iSM == kEEp02 || iSM == kEEp08)
0687                 nbinsX = nEESMXExt / 5;
0688               else if (iSM == kEEm01 || iSM == kEEm05 || iSM == kEEm09 || iSM == kEEp01 || iSM == kEEp05 ||
0689                        iSM == kEEp09)
0690                 nbinsX = nEESMXRed / 5;
0691               else
0692                 nbinsX = nEESMX / 5;
0693             } break;
0694             default:
0695               break;
0696           }
0697         }
0698       } else if (subdet == EcalTriggerTower && !isEndcapTTId(_id)) {
0699         EcalTrigTowerDetId ttid(_id);
0700         int ieta(ttid.ieta());
0701         int iphi((ttid.iphi() + 1) % 72 + 1);
0702         switch (_otype) {
0703           case kEB:
0704             xbin = iphi;
0705             ybin = ieta < 0 ? ieta + 18 : ieta + 17;
0706             nbinsX = 72;
0707             break;
0708           case kSM:
0709           case kEBSM:
0710             xbin = ieta < 0 ? -ieta : ieta;
0711             ybin = ieta < 0 ? (iphi - 1) % 4 + 1 : 4 - (iphi - 1) % 4;
0712             nbinsX = nEBSMEta / 5;
0713             break;
0714           default:
0715             break;
0716         }
0717       }
0718 
0719       return (nbinsX + 2) * ybin + xbin;
0720     }
0721 
0722     int findBinSuperCrystal_(const EcalElectronicsMapping *electronicsMap,
0723                              ObjectType _otype,
0724                              const EcalElectronicsId &_id) {
0725       int xbin(0);
0726       int ybin(0);
0727       int nbinsX(0);
0728       int iDCC(_id.dccId() - 1);
0729 
0730       if (iDCC >= kEBmLow && iDCC <= kEBpHigh) {
0731         unsigned towerid(_id.towerId());
0732         bool isEBm(iDCC <= kEBmHigh);
0733         switch (_otype) {
0734           case kEB:
0735             xbin = 4 * ((iDCC - 9) % 18) + (isEBm ? towerid - 1 : 68 - towerid) % 4 + 1;
0736             ybin = (towerid - 1) / 4 * (isEBm ? -1 : 1) + (isEBm ? 18 : 17);
0737             nbinsX = 72;
0738             break;
0739           case kSM:
0740           case kEBSM:
0741             xbin = (towerid - 1) / 4 + 1;
0742             //In by SM plots, using towerid, the ybinning always increases from 1 to 4,
0743             //whereas using iphi it flips for EB- and EB+
0744             ybin = (towerid - 1) % 4 + 1;
0745             nbinsX = 17;
0746             break;
0747           default:
0748             break;
0749         }
0750       } else {
0751         return findBinSuperCrystal_(electronicsMap, _otype, EEDetId(electronicsMap->getDetId(_id)).sc());
0752       }
0753 
0754       return (nbinsX + 2) * ybin + xbin;
0755     }
0756   }  // namespace binning
0757 }  // namespace ecaldqm