Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:53:15

0001 #include "DataFormats/EcalDetId/interface/EBDetId.h"
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 
0004 #include <algorithm>
0005 const int EBDetId::kModuleBoundaries[4] = {25, 45, 65, 85};
0006 
0007 // pi / 180.
0008 const float EBDetId::crystalUnitToEta = 0.017453292519943295;
0009 
0010 EBDetId::EBDetId(int index1, int index2, int mode) : DetId(Ecal, EcalBarrel) {
0011   int crystal_ieta;
0012   int crystal_iphi;
0013   if (mode == ETAPHIMODE) {
0014     crystal_ieta = index1;
0015     crystal_iphi = index2;
0016   } else if (mode == SMCRYSTALMODE) {
0017     int SM = index1;
0018     int crystal = index2;
0019     int i = (int)floor((crystal - 1) / kCrystalsInPhi);
0020     int j = ((crystal - 1) - (kCrystalsInPhi * i));
0021     if (SM <= 18) {
0022       crystal_ieta = i + 1;
0023       crystal_iphi = ((SM - 1) * kCrystalsInPhi) + (kCrystalsInPhi - j);
0024     } else {
0025       crystal_ieta = -(i + 1);
0026       crystal_iphi = ((SM - 19) * kCrystalsInPhi) + j + 1;
0027     }
0028   } else {
0029     throw cms::Exception("InvalidDetId") << "EBDetId:  Cannot create object.  Unknown mode for (int, int) constructor.";
0030   }
0031 
0032   if (!validDetId(crystal_ieta, crystal_iphi)) {
0033     //    std::cout << "crystal_eta " << crystal_ieta << "crystal_phi " << crystal_iphi << std::endl;
0034     throw cms::Exception("InvalidDetId") << "EBDetId:  Cannot create object.  Indexes out of bounds \n"
0035                                          << "eta = " << crystal_ieta << " phi = " << crystal_iphi;
0036   }
0037   id_ |= ((crystal_ieta > 0) ? (0x10000 | (crystal_ieta << 9)) : ((-crystal_ieta) << 9)) | (crystal_iphi & 0x1FF);
0038 }
0039 
0040 //Following TB 2004  numbering scheme
0041 int EBDetId::ic() const {
0042   int ie = ietaAbs() - 1;
0043   return (ie * kCrystalsInPhi) +
0044          (positiveZ() ? (kCrystalsInPhi - ((iphi() - 1) % kCrystalsInPhi)) : ((iphi() - 1) % kCrystalsInPhi + 1));
0045 }
0046 
0047 //Maintains SM crystals in bunch of 1700 indices
0048 int EBDetId::numberBySM() const { return (ism() - 1) * kCrystalsPerSM + ic() - 1; }
0049 
0050 EBDetId EBDetId::offsetBy(int nrStepsEta, int nrStepsPhi) const {
0051   int newEta = ieta() + nrStepsEta;
0052   if (newEta * ieta() <= 0) {
0053     if (ieta() < 0) {
0054       newEta++;
0055     } else if (ieta() > 0) {
0056       newEta--;
0057     }
0058   }
0059   int newPhi = iphi() + nrStepsPhi;
0060   while (newPhi > 360)
0061     newPhi -= 360;
0062   while (newPhi <= 0)
0063     newPhi += 360;
0064 
0065   if (validDetId(newEta, newPhi)) {
0066     return EBDetId(newEta, newPhi);
0067   } else {
0068     return EBDetId(0);
0069   }
0070 }
0071 
0072 EBDetId EBDetId::switchZSide() const {
0073   int newEta = ieta() * -1;
0074   if (validDetId(newEta, iphi())) {
0075     return EBDetId(newEta, iphi());
0076   } else {
0077     return EBDetId(0);
0078   }
0079 }
0080 
0081 DetId EBDetId::offsetBy(const DetId startId, int nrStepsEta, int nrStepsPhi) {
0082   if (startId.det() == DetId::Ecal && startId.subdetId() == EcalBarrel) {
0083     EBDetId ebStartId(startId);
0084     return ebStartId.offsetBy(nrStepsEta, nrStepsPhi).rawId();
0085   } else {
0086     return DetId(0);
0087   }
0088 }
0089 
0090 DetId EBDetId::switchZSide(const DetId startId) {
0091   if (startId.det() == DetId::Ecal && startId.subdetId() == EcalBarrel) {
0092     EBDetId ebStartId(startId);
0093     return ebStartId.switchZSide().rawId();
0094   } else {
0095     return DetId(0);
0096   }
0097 }
0098 
0099 //corrects for HB/EB differing iphi=1
0100 int EBDetId::tower_iphi() const {
0101   int iphi_simple = ((iphi() - 1) / 5) + 1;
0102   iphi_simple -= 2;
0103   return ((iphi_simple <= 0) ? (iphi_simple + 72) : (iphi_simple));
0104 }
0105 
0106 bool EBDetId::isNextToBoundary(EBDetId id) { return isNextToEtaBoundary(id) || isNextToPhiBoundary(id); }
0107 
0108 bool EBDetId::isNextToEtaBoundary(EBDetId id) {
0109   int ieta = id.ietaSM();
0110   return ieta == 1 || (kModuleBoundaries + 4) != std::find(kModuleBoundaries, kModuleBoundaries + 4, ieta);
0111 }
0112 
0113 bool EBDetId::isNextToPhiBoundary(EBDetId id) {
0114   int iphi = id.iphiSM();
0115   return iphi == 1 || iphi == 20;
0116 }
0117 
0118 int EBDetId::distanceEta(const EBDetId& a, const EBDetId& b) {
0119   if (a.ieta() * b.ieta() > 0)
0120     return abs(a.ieta() - b.ieta());
0121   else
0122     return abs(a.ieta() - b.ieta()) - 1;
0123 }
0124 
0125 int EBDetId::distancePhi(const EBDetId& a, const EBDetId& b) {
0126   int PI = 180;
0127   int result = a.iphi() - b.iphi();
0128 
0129   while (result > PI)
0130     result -= 2 * PI;
0131   while (result <= -PI)
0132     result += 2 * PI;
0133   return abs(result);
0134 }
0135 
0136 float EBDetId::approxEta(const DetId id) {
0137   if (id.subdetId() == EcalBarrel) {
0138     EBDetId ebId(id);
0139     return ebId.approxEta();
0140   } else {
0141     return 0;
0142   }
0143 }
0144 
0145 #include <ostream>
0146 std::ostream& operator<<(std::ostream& s, const EBDetId& id) {
0147   return s << "(EB ieta " << id.ieta() << ", iphi " << id.iphi() << " ; ism " << id.ism() << " , ic " << id.ic() << ')';
0148 }