CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/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 <algorithm>
00005 const int EBDetId::kModuleBoundaries[4] = { 25, 45, 65, 85 };
00006 
00007 // pi / 180.
00008 const float EBDetId::crystalUnitToEta = 0.017453292519943295;
00009 
00010  
00011 EBDetId::EBDetId(int index1, int index2, int mode) 
00012   : DetId(Ecal,EcalBarrel)
00013 {
00014   int crystal_ieta;
00015   int crystal_iphi;
00016   if (mode == ETAPHIMODE) {
00017     crystal_ieta = index1;
00018     crystal_iphi = index2;  
00019   } else if (mode == SMCRYSTALMODE) {
00020     int SM = index1;
00021     int crystal = index2;
00022     int i = (int)  floor((crystal-1) / kCrystalsInPhi);
00023     int j = ((crystal-1) - (kCrystalsInPhi*i));
00024     if (SM <= 18) {
00025       crystal_ieta = i + 1;
00026       crystal_iphi = ((SM-1) * kCrystalsInPhi) + (kCrystalsInPhi-j);
00027     } else {
00028       crystal_ieta = -(i+1);
00029       crystal_iphi = ((SM-19) * kCrystalsInPhi) + j+1;
00030     }
00031   } else {
00032     throw cms::Exception("InvalidDetId") << "EBDetId:  Cannot create object.  Unknown mode for (int, int) constructor."; 
00033   }
00034 
00035   if ( !validDetId(crystal_ieta, crystal_iphi) ) {
00036     //    std::cout << "crystal_eta " << crystal_ieta << "crystal_phi " << crystal_iphi << std::endl;
00037     throw cms::Exception("InvalidDetId") << "EBDetId:  Cannot create object.  Indexes out of bounds \n" 
00038                                          << "eta = " << crystal_ieta << " phi = " << crystal_iphi;
00039   }
00040   id_|=((crystal_ieta>0)?(0x10000|(crystal_ieta<<9)):((-crystal_ieta)<<9))|(crystal_iphi&0x1FF);
00041 }
00042   
00043 
00044 
00045 //Following TB 2004  numbering scheme 
00046 int EBDetId::ic() const {
00047   int ie = ietaAbs() -1;
00048   return  (ie * kCrystalsInPhi)
00049     +  ( positiveZ() ?
00050          ( kCrystalsInPhi - ( (iphi() -1 ) % kCrystalsInPhi ) )
00051          : ( ( iphi() -1 ) % kCrystalsInPhi  + 1)  
00052          );
00053 }
00054 
00055 
00056 //Maintains SM crystals in bunch of 1700 indices
00057 int EBDetId::numberBySM() const {
00058   return (ism()-1) * kCrystalsPerSM + ic() -1;
00059 }
00060 
00061 EBDetId EBDetId::offsetBy(int nrStepsEta, int nrStepsPhi ) const
00062 {
00063         int newEta = ieta()+nrStepsEta;
00064         if( newEta*ieta() <= 0 ) {
00065                 if( ieta() < 0 ) {
00066                         newEta++;
00067                 } else if ( ieta() > 0 ) {
00068                         newEta--;
00069                 }
00070         }
00071         int newPhi = iphi() + nrStepsPhi;
00072         while ( newPhi>360 ) newPhi -= 360;
00073         while ( newPhi<=0  ) newPhi += 360;
00074 
00075         if( validDetId( newEta, newPhi ) ) {
00076                 return EBDetId( newEta, newPhi);
00077         } else {
00078                 return EBDetId(0);
00079         }
00080 }
00081 
00082 EBDetId EBDetId::switchZSide() const
00083 {
00084         int newEta = ieta()*-1;
00085         if( validDetId( newEta, iphi() ) ) {
00086                 return EBDetId( newEta, iphi() );
00087         } else {
00088                 return EBDetId(0);
00089         }
00090 }
00091 
00092 
00093 DetId EBDetId::offsetBy(const DetId startId, int nrStepsEta, int nrStepsPhi )
00094 {
00095         if( startId.det() == DetId::Ecal && startId.subdetId() == EcalBarrel ) {
00096                 EBDetId ebStartId(startId);
00097                 return ebStartId.offsetBy( nrStepsEta, nrStepsPhi ).rawId();
00098         } else {
00099                 return DetId(0);
00100         }
00101 }
00102 
00103 DetId EBDetId::switchZSide( const DetId startId )
00104 {
00105         if( startId.det() == DetId::Ecal && startId.subdetId() == EcalBarrel ) {
00106                 EBDetId ebStartId(startId);
00107                 return ebStartId.switchZSide().rawId();
00108         } else {
00109                 return DetId(0);
00110         }
00111 }
00112 
00113 //corrects for HB/EB differing iphi=1
00114 int EBDetId::tower_iphi() const { 
00115   int iphi_simple=((iphi()-1)/5)+1; 
00116   iphi_simple-=2;
00117   return ((iphi_simple<=0)?(iphi_simple+72):(iphi_simple));
00118 }
00119 
00120 
00121 bool EBDetId::isNextToBoundary(EBDetId id) {
00122   return isNextToEtaBoundary( id ) || isNextToPhiBoundary( id );
00123 }
00124 
00125 bool EBDetId::isNextToEtaBoundary(EBDetId id) {
00126   int ieta = id.ietaSM();
00127   return ieta == 1 || (kModuleBoundaries + 4)!=std::find( kModuleBoundaries, kModuleBoundaries + 4, ieta );
00128 }
00129 
00130 bool EBDetId::isNextToPhiBoundary(EBDetId id) {
00131   int iphi = id.iphiSM();
00132   return iphi == 1 || iphi == 20;
00133 }
00134 
00135 int EBDetId::distanceEta(const EBDetId& a,const EBDetId& b)
00136 {
00137   if (a.ieta() * b.ieta() > 0)
00138     return abs(a.ieta()-b.ieta());
00139   else
00140     return abs(a.ieta()-b.ieta())-1;
00141 }
00142 
00143 int EBDetId::distancePhi(const EBDetId& a,const EBDetId& b) {
00144   int PI = 180;
00145   int  result = a.iphi() - b.iphi();
00146   
00147   while  (result > PI)    result -= 2*PI;
00148   while  (result <= -PI)  result += 2*PI;
00149   return abs(result);
00150 
00151 }
00152 
00153 float EBDetId::approxEta( const DetId id ) {
00154   if( id.subdetId() == EcalBarrel ) {
00155     EBDetId ebId( id );
00156     return ebId.approxEta();
00157   } else {
00158     return 0;
00159   }
00160 }
00161   
00162 
00163 #include<ostream>
00164 std::ostream& operator<<(std::ostream& s,const EBDetId& id) {
00165   return s << "(EB ieta " << id.ieta() << ", iphi " << id.iphi() 
00166            << " ; ism " << id.ism() << " , ic " << id.ic()  << ')';
00167 }
00168