00001 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00002 #include "Geometry/CaloGeometry/interface/CaloGenericDetId.h"
00003 #include "Geometry/CaloGeometry/interface/IdealObliquePrism.h"
00004 #include "Geometry/CaloGeometry/interface/IdealZPrism.h"
00005 #include "Geometry/HcalTowerAlgo/interface/HcalGeometry.h"
00006 #include "Geometry/HcalTowerAlgo//src/HcalHardcodeGeometryData.h"
00007 #include <algorithm>
00008
00009 HcalGeometry::HcalGeometry() :
00010 theTopology ( new HcalTopology ),
00011 m_ownsTopology ( true )
00012 {
00013 }
00014
00015 HcalGeometry::HcalGeometry( const HcalTopology* topology ) :
00016 theTopology ( topology ) ,
00017 m_ownsTopology ( false )
00018 {
00019 }
00020
00021
00022 HcalGeometry::~HcalGeometry()
00023 {
00024 if( m_ownsTopology ) delete theTopology ;
00025 }
00026
00027
00028 void
00029 HcalGeometry::fillDetIds() const
00030 {
00031 const std::vector<DetId>& baseIds ( CaloSubdetectorGeometry::getValidDetIds() ) ;
00032 for( unsigned int i ( 0 ) ; i != baseIds.size() ; ++i )
00033 {
00034 const DetId id ( baseIds[i] );
00035 if( id.subdetId() == HcalBarrel )
00036 {
00037 m_hbIds.push_back( id ) ;
00038 }
00039 else
00040 {
00041 if( id.subdetId() == HcalEndcap )
00042 {
00043 m_heIds.push_back( id ) ;
00044 }
00045 else
00046 {
00047 if( id.subdetId() == HcalOuter )
00048 {
00049 m_hoIds.push_back( id ) ;
00050 }
00051 else
00052 {
00053 if( id.subdetId() == HcalForward )
00054 {
00055 m_hfIds.push_back( id ) ;
00056 }
00057 }
00058 }
00059 }
00060 }
00061 std::sort( m_hbIds.begin(), m_hbIds.end() ) ;
00062 std::sort( m_heIds.begin(), m_heIds.end() ) ;
00063 std::sort( m_hoIds.begin(), m_hoIds.end() ) ;
00064 std::sort( m_hfIds.begin(), m_hfIds.end() ) ;
00065 m_emptyIds.resize( 0 ) ;
00066 }
00067
00068 const std::vector<DetId>&
00069 HcalGeometry::getValidDetIds( DetId::Detector det,
00070 int subdet ) const
00071 {
00072 if( 0 != subdet &&
00073 0 == m_hbIds.size() ) fillDetIds() ;
00074 return ( 0 == subdet ? CaloSubdetectorGeometry::getValidDetIds() :
00075 ( HcalBarrel == subdet ? m_hbIds :
00076 ( HcalEndcap == subdet ? m_heIds :
00077 ( HcalOuter == subdet ? m_hoIds :
00078 ( HcalForward == subdet ? m_hfIds : m_emptyIds ) ) ) ) ) ;
00079 }
00080
00081 DetId HcalGeometry::getClosestCell(const GlobalPoint& r) const {
00082
00083
00084
00085 double abseta = fabs(r.eta());
00086
00087
00088 HcalSubdetector bc= HcalEmpty;
00089 if (abseta <= theHBHEEtaBounds[theTopology->lastHBRing()] ) {
00090 bc = HcalBarrel;
00091 } else if (abseta <= theHBHEEtaBounds[theTopology->lastHERing()] ) {
00092 bc = HcalEndcap;
00093 } else {
00094 bc = HcalForward;
00095 }
00096
00097 if (bc == HcalForward) {
00098 static const double z_short=1137.0;
00099 int etaring = etaRing(bc, abseta);
00100
00101
00102
00103
00104
00105
00106
00107
00108 if (etaring>theTopology->lastHFRing()) etaring=theTopology->lastHFRing();
00109
00110 int phibin = phiBin(r.phi(), etaring);
00111
00112
00113 int etabin = (r.z() > 0) ? etaring : -etaring;
00114
00115 HcalDetId bestId(bc,etabin,phibin,((fabs(r.z())>=z_short)?(2):(1)));
00116 return bestId;
00117 } else {
00118
00119
00120 int etaring = etaRing(bc, abseta);
00121
00122 int phibin = phiBin(r.phi(), etaring);
00123
00124
00125 int etabin = (r.z() > 0) ? etaring : -etaring;
00126
00127
00128 int dbin = 1;
00129 double pointrz=0, drz=99999.;
00130 HcalDetId currentId(bc, etabin, phibin, dbin);
00131 if (bc == HcalBarrel) pointrz = r.mag();
00132 else pointrz = std::abs(r.z());
00133 HcalDetId bestId;
00134 for ( ; currentId != HcalDetId(); theTopology->incrementDepth(currentId)) {
00135 const CaloCellGeometry * cell = getGeometry(currentId);
00136 assert(cell != 0);
00137 double rz;
00138 if (bc == HcalEndcap) rz = std::abs(cell->getPosition().z());
00139 else rz = cell->getPosition().mag();
00140 if (std::abs(pointrz-rz)<drz) {
00141 bestId = currentId;
00142 drz = std::abs(pointrz-rz);
00143 }
00144 }
00145
00146 return bestId;
00147 }
00148 }
00149
00150
00151 int HcalGeometry::etaRing(HcalSubdetector bc, double abseta) const
00152 {
00153 int etaring;
00154 if( bc == HcalForward ) {
00155 for(etaring = theTopology->firstHFRing();
00156 etaring <= theTopology->lastHFRing(); ++etaring)
00157 {
00158 if(theHFEtaBounds[etaring-theTopology->firstHFRing()+1] > abseta) break;
00159 }
00160 }
00161 else
00162 {
00163 for(etaring = 1;
00164 etaring <= theTopology->lastHERing(); ++etaring)
00165 {
00166 if(theHBHEEtaBounds[etaring] >= abseta) break;
00167 }
00168 }
00169
00170 return etaring;
00171 }
00172
00173
00174 int HcalGeometry::phiBin(double phi, int etaring) const
00175 {
00176 static const double twopi = M_PI+M_PI;
00177
00178 if(phi<0.0) phi += twopi;
00179 if(phi>twopi) phi -= twopi;
00180 int nphibins = theTopology->nPhiBins(etaring);
00181 int phibin= static_cast<int>(phi/twopi*nphibins)+1;
00182 int iphi;
00183
00184
00185
00186
00187
00188 if(etaring >= theTopology->firstHFQuadPhiRing())
00189 {
00190 phi+=(twopi/36);
00191 phibin=static_cast<int>(phi/twopi*nphibins);
00192 if (phibin==0) phibin=18;
00193 iphi=phibin*4-1;
00194 } else {
00195
00196 iphi=(phibin-1)*(72/nphibins) + 1;
00197 }
00198
00199 return iphi;
00200 }
00201
00202 CaloSubdetectorGeometry::DetIdSet
00203 HcalGeometry::getCells( const GlobalPoint& r,
00204 double dR ) const
00205 {
00206 CaloSubdetectorGeometry::DetIdSet dis;
00207
00208 if( 0.000001 < dR )
00209 {
00210 if( dR > M_PI/2. )
00211 {
00212 dis = CaloSubdetectorGeometry::getCells( r, dR ) ;
00213 }
00214 else
00215 {
00216 const double dR2 ( dR*dR ) ;
00217 const double reta ( r.eta() ) ;
00218 const double rphi ( r.phi() ) ;
00219 const double lowEta ( reta - dR ) ;
00220 const double highEta ( reta + dR ) ;
00221 const double lowPhi ( rphi - dR ) ;
00222 const double highPhi ( rphi + dR ) ;
00223
00224 const double hfEtaHi ( theHFEtaBounds[ theTopology->lastHFRing() -
00225 theTopology->firstHFRing() + 1 ] ) ;
00226
00227 if( highEta > -hfEtaHi &&
00228 lowEta < hfEtaHi )
00229 {
00230 const HcalSubdetector hs[] = { HcalBarrel, HcalOuter, HcalEndcap, HcalForward } ;
00231
00232 for( unsigned int is ( 0 ) ; is != 4 ; ++is )
00233 {
00234 const int sign ( reta>0 ? 1 : -1 ) ;
00235 const int ieta_center ( sign*etaRing( hs[is], fabs( reta ) ) ) ;
00236 const int ieta_lo ( ( 0 < lowEta*sign ? sign : -sign )*etaRing( hs[is], fabs( lowEta ) ) ) ;
00237 const int ieta_hi ( ( 0 < highEta*sign ? sign : -sign )*etaRing( hs[is], fabs( highEta ) ) ) ;
00238 const int iphi_lo ( phiBin( lowPhi , ieta_center ) ) ;
00239 const int iphi_hi ( phiBin( highPhi, ieta_center ) ) ;
00240 const int jphi_lo ( iphi_lo>iphi_hi ? iphi_lo - 72 : iphi_lo ) ;
00241 const int jphi_hi ( iphi_hi ) ;
00242
00243 const int idep_lo ( 1 == is ? 4 : 1 ) ;
00244 const int idep_hi ( 1 == is ? 4 :
00245 ( 2 == is ? 3 : 2 ) ) ;
00246 for( int ieta ( ieta_lo ) ; ieta <= ieta_hi ; ++ieta )
00247 {
00248 if( ieta != 0 )
00249 {
00250 for( int jphi ( jphi_lo ) ; jphi <= jphi_hi ; ++jphi )
00251 {
00252 const int iphi ( 1 > jphi ? jphi+72 : jphi ) ;
00253
00254 for( int idep ( idep_lo ) ; idep <= idep_hi ; ++idep )
00255 {
00256 if( HcalDetId::validDetId( hs[is], ieta, iphi, idep ) )
00257 {
00258 const HcalDetId did ( hs[is], ieta, iphi, idep ) ;
00259 const CaloCellGeometry* cell ( getGeometry( did ) );
00260 if( 0 != cell )
00261 {
00262 const GlobalPoint& p ( cell->getPosition() ) ;
00263 const double eta ( p.eta() ) ;
00264 const double phi ( p.phi() ) ;
00265 if( reco::deltaR2( eta, phi, reta, rphi ) < dR2 ) dis.insert( did ) ;
00266 }
00267 }
00268 }
00269 }
00270 }
00271 }
00272 }
00273 }
00274 }
00275 }
00276 return dis;
00277 }
00278
00279
00280 unsigned int
00281 HcalGeometry::alignmentTransformIndexLocal( const DetId& id )
00282 {
00283 const CaloGenericDetId gid ( id ) ;
00284
00285 assert( gid.isHcal() ) ;
00286
00287
00288 const HcalDetId hid ( id ) ;
00289
00290 const int jz ( ( hid.zside() + 1 )/2 ) ;
00291
00292 const int zoff ( jz*numberOfAlignments()/2 ) ;
00293
00294 const int detoff ( zoff +
00295 ( gid.isHB() ? 0 :
00296 ( gid.isHE() ? numberOfBarrelAlignments()/2 :
00297 ( gid.isHF() ? ( numberOfBarrelAlignments() +
00298 numberOfEndcapAlignments() )/2 :
00299 ( numberOfBarrelAlignments() +
00300 numberOfEndcapAlignments() +
00301 numberOfForwardAlignments() )/2 ) ) ) ) ;
00302
00303 const int iphi ( hid.iphi() ) ;
00304
00305 unsigned int index ( numberOfAlignments() ) ;
00306 if( gid.isHO() )
00307 {
00308 const int ieta ( hid.ieta() ) ;
00309 const int ring ( ieta < -10 ? 0 :
00310 ( ieta < -4 ? 1 :
00311 ( ieta < 5 ? 2 :
00312 ( ieta < 11 ? 3 : 4 ) ) ) ) ;
00313
00314 index = detoff + 12*ring + ( iphi - 1 )%6 ;
00315 }
00316 else
00317 {
00318 index = detoff + ( iphi - 1 )%4 ;
00319 }
00320
00321 assert( index < numberOfAlignments() ) ;
00322 return index ;
00323 }
00324
00325 unsigned int
00326 HcalGeometry::alignmentTransformIndexGlobal( const DetId& id )
00327 {
00328 return (unsigned int)DetId::Hcal - 1 ;
00329 }
00330
00331 std::vector<HepGeom::Point3D<double> >
00332 HcalGeometry::localCorners( const double* pv,
00333 unsigned int i,
00334 HepGeom::Point3D<double> & ref )
00335 {
00336 const HcalDetId hid ( HcalDetId::detIdFromDenseIndex( i ) ) ;
00337 const CaloGenericDetId cgid ( hid ) ;
00338 if( cgid.isHF() )
00339 {
00340 return ( calogeom::IdealZPrism::localCorners( pv, ref ) ) ;
00341 }
00342 else
00343 {
00344 return ( calogeom::IdealObliquePrism::localCorners( pv, ref ) ) ;
00345 }
00346 }
00347
00348 CaloCellGeometry*
00349 HcalGeometry::newCell( const GlobalPoint& f1 ,
00350 const GlobalPoint& f2 ,
00351 const GlobalPoint& f3 ,
00352 CaloCellGeometry::CornersMgr* mgr,
00353 const double* parm ,
00354 const DetId& detId )
00355 {
00356 const CaloGenericDetId cgid ( detId ) ;
00357
00358 assert( cgid.isHcal() ) ;
00359
00360 if( cgid.isHF() )
00361 {
00362 return ( new calogeom::IdealZPrism( f1, mgr, parm ) ) ;
00363 }
00364 else
00365 {
00366 return ( new calogeom::IdealObliquePrism( f1, mgr, parm ) ) ;
00367 }
00368 }