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