CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/DataFormats/EcalDetId/src/EcalTrigTowerDetId.cc

Go to the documentation of this file.
00001 #include "DataFormats/EcalDetId/interface/EcalTrigTowerDetId.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003 #include <cassert>
00004 
00005 EcalTrigTowerDetId::EcalTrigTowerDetId() {
00006 }
00007   
00008   
00009 EcalTrigTowerDetId::EcalTrigTowerDetId(uint32_t rawid) : DetId(rawid) {
00010 }
00011 
00012 EcalTrigTowerDetId::EcalTrigTowerDetId(int zside, EcalSubdetector subDet, int i, int j, int mode)
00013   : DetId(Ecal,EcalTriggerTower) 
00014 {
00015   int tower_i=0;
00016   int tower_j=0;
00017 
00018   if (mode == SUBDETIJMODE)
00019     {
00020       tower_i=i;
00021       tower_j=j;
00022     }
00023   else if (mode == SUBDETDCCTTMODE)
00024     {
00025       throw cms::Exception("InvalidDetId") << "EcalTriggerTowerDetId:  Cannot create object. SUBDETDCCTTMODE not yet implemented.";   
00026     }
00027   else
00028     throw cms::Exception("InvalidDetId") << "EcalTriggerTowerDetId:  Cannot create object.  Unknown mode for (int, EcalSubdetector, int, int) constructor.";
00029   
00030   if (tower_i > MAX_I || tower_i < MIN_I  || tower_j > MAX_J || tower_j < MIN_J)
00031     throw cms::Exception("InvalidDetId") << "EcalTriggerTowerDetId:  Cannot create object.  Indexes out of bounds.";
00032   
00033   id_|= ((zside>0)?(0x8000):(0x0)) | ((subDet == EcalBarrel)?(0x4000):(0x0)) | (tower_i<<7) | (tower_j & 0x7F);
00034 
00035 }
00036   
00037 EcalTrigTowerDetId::EcalTrigTowerDetId(const DetId& gen) 
00038 {
00039   if (!gen.null() && ( gen.det()!=Ecal || gen.subdetId()!=EcalTriggerTower )) {
00040     throw cms::Exception("InvalidDetId");  }
00041   id_=gen.rawId();
00042 }
00043   
00044 EcalTrigTowerDetId& EcalTrigTowerDetId::operator=(const DetId& gen) {
00045   if (!gen.null() && ( gen.det()!=Ecal || gen.subdetId()!=EcalTriggerTower )) {
00046     throw cms::Exception("InvalidDetId");
00047   }
00048   id_=gen.rawId();
00049   return *this;
00050 }
00051 
00052 //New SM numbering scheme. Avoids discontinuity in phi crossing \eta=0  
00053 int EcalTrigTowerDetId::iDCC() const 
00054 {
00055   if ( subDet() == EcalBarrel )
00056     {
00057       //Correction since iphi is uniformized with HB convention 
00058       int iphi_simple = iphi() + 2 ;
00059       if (iphi_simple > 72 ) iphi_simple = iphi_simple % 72;
00060       int id = ( iphi_simple - 1 ) / kEBTowersInPhi + 1;
00061       if ( zside() < 0 ) id += 18;
00062       return id;
00063     }
00064   else
00065     throw cms::Exception("MethodNotImplemented") << "EcalTriggerTowerDetId: iDCC not yet implemented";
00066 }
00067 
00068 int EcalTrigTowerDetId::iTT() const 
00069 {
00070   if ( subDet() == EcalBarrel )
00071     {
00072       int ie = ietaAbs() -1;
00073       int ip;
00074       int iphi_simple = iphi() + 2 ;
00075       if (iphi_simple > 72 )  iphi_simple = iphi_simple % 72;
00076       if (zside() < 0) {
00077         ip = (( iphi_simple -1 ) % kEBTowersInPhi ) + 1;
00078       } else {
00079         ip = kEBTowersInPhi - ((iphi_simple -1 ) % kEBTowersInPhi );
00080       }
00081       
00082       return (ie * kEBTowersInPhi) + ip;
00083     }
00084   else
00085     throw cms::Exception("MethodNotImplemented") << "EcalTriggerTowerDetId: iTT not yet implemented";
00086 }
00087 
00088 int EcalTrigTowerDetId::iquadrant() const
00089 {
00090   if ( subDet() == EcalEndcap )
00091     return int((iphi()-1)/kEETowersInPhiPerQuadrant)+1;
00092   else
00093     throw cms::Exception("MethodNotApplicable") << "EcalTriggerTowerDetId: iquadrant not applicable";
00094 }  
00095 
00096 bool
00097 EcalTrigTowerDetId::validDetId( int iz, EcalSubdetector sd , int i, int j )
00098 {
00099    return ( 1 == abs( iz )               &&
00100             0 <  i                       &&
00101             0 <  j                       &&
00102             kEETowersInPhiPerEndcap >= j &&
00103             ( ( EcalBarrel     == sd &&
00104                 kEBTowersInEta >=  i     ) ||
00105               ( EcalEndcap     == sd &&
00106                 kEEOuterEta    <=  i &&
00107                 kEEInnerEta    >=  i &&
00108                 ( 27 > i ||
00109                   (  ( 0 >  iz  &&
00110                        0 == j%2    ) ||
00111                      ( 0 <  iz  &&
00112                        1 == j%2         ) ) ) ) ) ) ;
00113             
00114 }
00115 
00116 int 
00117 EcalTrigTowerDetId::hashedIndex() const 
00118 {
00119    const unsigned int iea ( ietaAbs() ) ;
00120    const unsigned int iph ( iphi()    ) ;
00121    return ( subDet() == EcalBarrel  ? 
00122             ( iDCC() - 1 )*kEBTowersPerSM + iTT() - 1 :
00123             kEBTotalTowers + ( ( zside() + 1 )/2 )*kEETowersPerEndcap +
00124             ( ( iea < 27 ? iea : 27 ) - kEEOuterEta )*kEETowersInPhiPerEndcap + 
00125             ( iea < 27 ? iph : // for iphi=27,28 only half TT present, odd for EE-, even EE+
00126               ( iea - 27 )*kEETowersInPhiPerEndcap/2 + ( iph + 1 )/2 ) - 1 ) ;
00127 }
00128 
00129 EcalTrigTowerDetId 
00130 EcalTrigTowerDetId::detIdFromDenseIndex( uint32_t di ) 
00131 {
00132    const EcalSubdetector sd ( di < kEBTotalTowers ? EcalBarrel : EcalEndcap ) ;
00133    const int iz ( di < kEBTotalTowers ? 
00134                   ( di < kEBHalfTowers ?  1 : -1 ) :
00135                   ( di - kEBTotalTowers < kEETowersPerEndcap ? -1 : 1 ) ) ;
00136    int i ;
00137    int j ;
00138    if( di < kEBTotalTowers ) // barrel
00139    {
00140       const unsigned int itt ( di%kEBTowersPerSM ) ;
00141       const unsigned int idc ( di/kEBTowersPerSM ) ;
00142       j = (idc%18)*kEBTowersInPhi + 
00143          ( (1+iz)/2 )*kEBTowersInPhi - 
00144          iz*(itt%kEBTowersInPhi)  + 1 - (1+iz)/2 - 2 ;
00145       if( j < 1 ) j += 72 ;
00146       i = 1 + itt/kEBTowersInPhi ;
00147    }
00148    else
00149    {
00150       const int eonly ( ( di - kEBTotalTowers )%kEETowersPerEndcap ) ;
00151       i = kEEOuterEta + eonly/kEETowersInPhiPerEndcap ;
00152       j = 1 + eonly%kEETowersInPhiPerEndcap ;
00153       if( 27 == i ) // last two rings have half of normal phi elementes
00154       {
00155          if( j > kEETowersInPhiPerEndcap/2 )
00156          {
00157             ++i ; 
00158             j -= kEETowersInPhiPerEndcap/2 ;
00159          }
00160          j = 2*j ;
00161          if( 0 < iz ) --j ;
00162       }
00163    }
00164    assert( validDetId( iz, sd, i, j ) ) ;
00165    return EcalTrigTowerDetId( iz, sd, i, j ) ;
00166 }
00167 
00168 std::ostream& operator<<(std::ostream& s,const EcalTrigTowerDetId& id) {
00169   return s << "(EcalTT subDet " << ((id.subDet()==EcalBarrel)?("Barrel"):("Endcap")) 
00170            <<  " iz " << ((id.zside()>0)?("+ "):("- ")) << " ieta " 
00171            << id.ietaAbs() << " iphi " << id.iphi() << ')';
00172 }
00173