CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/DataFormats/EcalDetId/src/EBDetId.cc

Go to the documentation of this file.
00001 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003 
00004 //#include <iostream>
00005 #include <algorithm>
00006 const int EBDetId::kModuleBoundaries[4] = { 25, 45, 65, 85 };
00007 
00008 // pi / 180.
00009 const float EBDetId::crystalUnitToEta = 0.017453292519943295;
00010 
00011 EBDetId
00012 EBDetId::unhashIndex( int hi )  
00013 {
00014    const int pseudo_eta = hi/MAX_IPHI - MAX_IETA;
00015    return ( validHashIndex( hi ) ?
00016             EBDetId(pseudo_eta<0 ? pseudo_eta :  pseudo_eta+1, hi%MAX_IPHI+1) :
00017             EBDetId() ) ;
00018 }
00019   
00020 EBDetId::EBDetId(int index1, int index2, int mode) 
00021   : DetId(Ecal,EcalBarrel)
00022 {
00023   int crystal_ieta;
00024   int crystal_iphi;
00025   if (mode == ETAPHIMODE) {
00026     crystal_ieta = index1;
00027     crystal_iphi = index2;  
00028   } else if (mode == SMCRYSTALMODE) {
00029     int SM = index1;
00030     int crystal = index2;
00031     int i = (int)  floor((crystal-1) / kCrystalsInPhi);
00032     int j = ((crystal-1) - (kCrystalsInPhi*i));
00033     if (SM <= 18) {
00034       crystal_ieta = i + 1;
00035       crystal_iphi = ((SM-1) * kCrystalsInPhi) + (kCrystalsInPhi-j);
00036     } else {
00037       crystal_ieta = -(i+1);
00038       crystal_iphi = ((SM-19) * kCrystalsInPhi) + j+1;
00039     }
00040   } else {
00041     throw cms::Exception("InvalidDetId") << "EBDetId:  Cannot create object.  Unknown mode for (int, int) constructor."; 
00042   }
00043 
00044   if ( !validDetId(crystal_ieta, crystal_iphi) ) {
00045     //    std::cout << "crystal_eta " << crystal_ieta << "crystal_phi " << crystal_iphi << std::endl;
00046     throw cms::Exception("InvalidDetId") << "EBDetId:  Cannot create object.  Indexes out of bounds \n" 
00047                                          << "eta = " << crystal_ieta << " phi = " << crystal_iphi;
00048   }
00049   id_|=((crystal_ieta>0)?(0x10000|(crystal_ieta<<9)):((-crystal_ieta)<<9))|(crystal_iphi&0x1FF);
00050 }
00051   
00052 EBDetId::EBDetId(const DetId& gen) {
00053   if (!gen.null() && ( gen.det()!=Ecal || gen.subdetId()!=EcalBarrel )) {
00054     throw cms::Exception("InvalidDetId");
00055   }
00056   id_=gen.rawId();
00057 }
00058 
00059 bool EBDetId::validDetId(int i, int j) {
00060 
00061   bool valid = true;
00062   if (i < -MAX_IETA || i == 0 || i > MAX_IETA ||
00063       j < MIN_IPHI || j > MAX_IPHI) {
00064     valid = false;
00065   }  
00066   return valid;
00067 
00068 }
00069   
00070 EBDetId& EBDetId::operator=(const DetId& gen) {
00071   if (!gen.null() && ( gen.det()!=Ecal || gen.subdetId()!=EcalBarrel )) {
00072     throw cms::Exception("InvalidDetId");
00073   }
00074   id_=gen.rawId();
00075   return *this;
00076 }
00077 
00078 //New SM numbering scheme. Avoids discontinuity in phi crossing \eta=0  
00079 int EBDetId::ism() const {
00080   int id = ( iphi() - 1 ) / kCrystalsInPhi + 1;
00081   if ( zside() < 0 ) id += 18;
00082   return id;
00083 }
00084 
00085 int EBDetId::im() const {
00086   for (int i=0; i < 4 ; i++)
00087     if ( ietaAbs() <= kModuleBoundaries[i] )
00088       return i+1;
00089   //Shold never be reached!
00090   return -1;
00091 }
00092 
00093 //Following TB 2004  numbering scheme 
00094 int EBDetId::ic() const {
00095   int ie = ietaAbs() -1;
00096   int ip;
00097   if (zside() < 0) {
00098     ip = (( iphi() -1 ) % kCrystalsInPhi ) + 1;
00099   } else {
00100     ip = kCrystalsInPhi - ((iphi() -1 ) % kCrystalsInPhi );
00101   }
00102 
00103   return (ie * kCrystalsInPhi) + ip;
00104 }
00105 
00106 //Maintains SM crystals in bunch of 1700 indices
00107 int EBDetId::numberBySM() const {
00108   return (ism()-1) * kCrystalsPerSM + ic() -1;
00109 }
00110 
00111 EBDetId EBDetId::offsetBy(int nrStepsEta, int nrStepsPhi ) const
00112 {
00113         int newEta = ieta()+nrStepsEta;
00114         if( newEta*ieta() <= 0 ) {
00115                 if( ieta() < 0 ) {
00116                         newEta++;
00117                 } else if ( ieta() > 0 ) {
00118                         newEta--;
00119                 }
00120         }
00121         int newPhi = iphi() + nrStepsPhi;
00122         while ( newPhi>360 ) newPhi -= 360;
00123         while ( newPhi<=0  ) newPhi += 360;
00124 
00125         if( validDetId( newEta, newPhi ) ) {
00126                 return EBDetId( newEta, newPhi);
00127         } else {
00128                 return EBDetId(0);
00129         }
00130 }
00131 
00132 EBDetId EBDetId::switchZSide() const
00133 {
00134         int newEta = ieta()*-1;
00135         if( validDetId( newEta, iphi() ) ) {
00136                 return EBDetId( newEta, iphi() );
00137         } else {
00138                 return EBDetId(0);
00139         }
00140 }
00141 
00142 
00143 DetId EBDetId::offsetBy(const DetId startId, int nrStepsEta, int nrStepsPhi )
00144 {
00145         if( startId.det() == DetId::Ecal && startId.subdetId() == EcalBarrel ) {
00146                 EBDetId ebStartId(startId);
00147                 return ebStartId.offsetBy( nrStepsEta, nrStepsPhi ).rawId();
00148         } else {
00149                 return DetId(0);
00150         }
00151 }
00152 
00153 DetId EBDetId::switchZSide( const DetId startId )
00154 {
00155         if( startId.det() == DetId::Ecal && startId.subdetId() == EcalBarrel ) {
00156                 EBDetId ebStartId(startId);
00157                 return ebStartId.switchZSide().rawId();
00158         } else {
00159                 return DetId(0);
00160         }
00161 }
00162 
00163 //corrects for HB/EB differing iphi=1
00164 int EBDetId::tower_iphi() const { 
00165   int iphi_simple=((iphi()-1)/5)+1; 
00166   iphi_simple-=2;
00167   return ((iphi_simple<=0)?(iphi_simple+72):(iphi_simple));
00168 }
00169 
00170 
00171 bool EBDetId::isNextToBoundary(EBDetId id) {
00172         return isNextToEtaBoundary( id ) || isNextToPhiBoundary( id );
00173 }
00174 
00175 bool EBDetId::isNextToEtaBoundary(EBDetId id) {
00176         int ieta = id.ietaSM();
00177         return ieta == 1 || std::binary_search( kModuleBoundaries, kModuleBoundaries + 4, ieta ) || ieta == 85;
00178 }
00179 
00180 bool EBDetId::isNextToPhiBoundary(EBDetId id) {
00181         int iphi = id.iphiSM();
00182         return iphi == 1 || iphi == 20;
00183 }
00184 
00185 int EBDetId::distanceEta(const EBDetId& a,const EBDetId& b)
00186 {
00187   if (a.ieta() * b.ieta() > 0)
00188     return abs(a.ieta()-b.ieta());
00189   else
00190     return abs(a.ieta()-b.ieta())-1;
00191 }
00192 
00193 int EBDetId::distancePhi(const EBDetId& a,const EBDetId& b)
00194 {
00195   if (abs(a.iphi() -b.iphi()) > 180)
00196     return abs(a.iphi() - b.iphi()) - 180;
00197   else
00198     return abs(a.iphi()-b.iphi());
00199 }
00200 
00201 float EBDetId::approxEta( const DetId id ) {
00202         if( id.subdetId() == EcalBarrel ) {
00203                 EBDetId ebId( id );
00204                 return ebId.approxEta();
00205         } else {
00206                 return 0;
00207         }
00208 }
00209   
00210 std::ostream& operator<<(std::ostream& s,const EBDetId& id) {
00211   return s << "(EB ieta " << id.ieta() << ", iphi" << id.iphi() 
00212            << " ; ism " << id.ism() << " , ic " << id.ic()  << ')';
00213 }
00214