00001 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00002 #include "Geometry/HcalTowerAlgo/interface/HcalGeometry.h"
00003 #include "Geometry/HcalTowerAlgo//src/HcalHardcodeGeometryData.h"
00004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00005 #include <algorithm>
00006
00007 #include <Math/Transform3D.h>
00008 #include <Math/EulerAngles.h>
00009
00010 typedef CaloCellGeometry::CCGFloat CCGFloat ;
00011 typedef CaloCellGeometry::Pt3D Pt3D ;
00012 typedef CaloCellGeometry::Pt3DVec Pt3DVec ;
00013 typedef CaloCellGeometry::Tr3D Tr3D ;
00014
00015 HcalGeometry::HcalGeometry( const HcalTopology& topology ) :
00016 theTopology( topology ) {
00017 init();
00018 }
00019
00020
00021 HcalGeometry::~HcalGeometry() {}
00022
00023
00024 void HcalGeometry::init() {
00025 edm::LogInfo("HcalGeometry") << "HcalGeometry::init() "
00026 << " HBSize " << theTopology.getHBSize()
00027 << " HESize " << theTopology.getHESize()
00028 << " HOSize " << theTopology.getHOSize()
00029 << " HFSize " << theTopology.getHFSize();
00030
00031 m_hbCellVec = HBCellVec( theTopology.getHBSize() ) ;
00032 m_heCellVec = HECellVec( theTopology.getHESize() ) ;
00033 m_hoCellVec = HOCellVec( theTopology.getHOSize() ) ;
00034 m_hfCellVec = HFCellVec( theTopology.getHFSize() ) ;
00035 }
00036
00037 void
00038 HcalGeometry::fillDetIds() const
00039 {
00040 const std::vector<DetId>& baseIds ( CaloSubdetectorGeometry::getValidDetIds() ) ;
00041 for( unsigned int i ( 0 ) ; i != baseIds.size() ; ++i )
00042 {
00043 const DetId id ( baseIds[i] );
00044 if( id.subdetId() == HcalBarrel )
00045 {
00046 m_hbIds.push_back( id ) ;
00047 }
00048 else
00049 {
00050 if( id.subdetId() == HcalEndcap )
00051 {
00052 m_heIds.push_back( id ) ;
00053 }
00054 else
00055 {
00056 if( id.subdetId() == HcalOuter )
00057 {
00058 m_hoIds.push_back( id ) ;
00059 }
00060 else
00061 {
00062 if( id.subdetId() == HcalForward )
00063 {
00064 m_hfIds.push_back( id ) ;
00065 }
00066 }
00067 }
00068 }
00069 }
00070 std::sort( m_hbIds.begin(), m_hbIds.end() ) ;
00071 std::sort( m_heIds.begin(), m_heIds.end() ) ;
00072 std::sort( m_hoIds.begin(), m_hoIds.end() ) ;
00073 std::sort( m_hfIds.begin(), m_hfIds.end() ) ;
00074
00075 m_emptyIds.resize( 0 ) ;
00076 }
00077
00078 const std::vector<DetId>&
00079 HcalGeometry::getValidDetIds( DetId::Detector det,
00080 int subdet ) const
00081 {
00082 if( 0 != subdet &&
00083 0 == m_hbIds.size() ) fillDetIds() ;
00084 return ( 0 == subdet ? CaloSubdetectorGeometry::getValidDetIds() :
00085 ( HcalBarrel == subdet ? m_hbIds :
00086 ( HcalEndcap == subdet ? m_heIds :
00087 ( HcalOuter == subdet ? m_hoIds :
00088 ( HcalForward == subdet ? m_hfIds : m_emptyIds ) ) ) ) ) ;
00089 }
00090
00091 DetId HcalGeometry::getClosestCell(const GlobalPoint& r) const {
00092
00093
00094
00095 double abseta = fabs(r.eta());
00096
00097
00098 HcalSubdetector bc= HcalEmpty;
00099 if (abseta <= theHBHEEtaBounds[theTopology.lastHBRing()] ) {
00100 bc = HcalBarrel;
00101 } else if (abseta <= theHBHEEtaBounds[theTopology.lastHERing()] ) {
00102 bc = HcalEndcap;
00103 } else {
00104 bc = HcalForward;
00105 }
00106
00107 if (bc == HcalForward) {
00108 static const double z_short=1137.0;
00109 int etaring = etaRing(bc, abseta);
00110
00111
00112
00113
00114
00115
00116
00117
00118 if (etaring>theTopology.lastHFRing()) etaring=theTopology.lastHFRing();
00119
00120 int phibin = phiBin(r.phi(), etaring);
00121
00122
00123 int etabin = (r.z() > 0) ? etaring : -etaring;
00124
00125
00126
00127 HcalDetId bestId(bc,etabin,phibin,((fabs(r.z()) - z_short >-0.1)?(2):(1)));
00128 return bestId;
00129 } else {
00130
00131
00132 int etaring = etaRing(bc, abseta);
00133
00134 int phibin = phiBin(r.phi(), etaring);
00135
00136
00137 int etabin = (r.z() > 0) ? etaring : -etaring;
00138
00139
00140 int dbin = 1;
00141 double pointrz=0, drz=99999.;
00142 HcalDetId currentId(bc, etabin, phibin, dbin);
00143 if (bc == HcalBarrel) pointrz = r.mag();
00144 else pointrz = std::abs(r.z());
00145 HcalDetId bestId;
00146
00147 for ( ; currentId != HcalDetId(); theTopology.incrementDepth(currentId)) {
00148
00149 const CaloCellGeometry * cell = getGeometry(currentId);
00150 if (cell == 0) {
00151
00152 assert (bestId != HcalDetId());
00153 break;
00154 } else {
00155 double rz;
00156 if (bc == HcalEndcap) rz = std::abs(cell->getPosition().z());
00157 else rz = cell->getPosition().mag();
00158 if (std::abs(pointrz-rz)<drz) {
00159 bestId = currentId;
00160 drz = std::abs(pointrz-rz);
00161 }
00162 }
00163 }
00164
00165 return bestId;
00166 }
00167 }
00168
00169
00170 int HcalGeometry::etaRing(HcalSubdetector bc, double abseta) const
00171 {
00172 int etaring;
00173 if( bc == HcalForward ) {
00174 for(etaring = theTopology.firstHFRing();
00175 etaring <= theTopology.lastHFRing(); ++etaring)
00176 {
00177 if(theHFEtaBounds[etaring-theTopology.firstHFRing()+1] > abseta) break;
00178 }
00179 }
00180 else
00181 {
00182 for(etaring = 1;
00183 etaring <= theTopology.lastHERing(); ++etaring)
00184 {
00185 if(theHBHEEtaBounds[etaring] >= abseta) break;
00186 }
00187 }
00188
00189 return etaring;
00190 }
00191
00192
00193 int HcalGeometry::phiBin(double phi, int etaring) const
00194 {
00195 static const double twopi = M_PI+M_PI;
00196
00197 if(phi<0.0) phi += twopi;
00198 if(phi>twopi) phi -= twopi;
00199 int nphibins = theTopology.nPhiBins(etaring);
00200 int phibin= static_cast<int>(phi/twopi*nphibins)+1;
00201 int iphi;
00202
00203
00204
00205
00206
00207 if(etaring >= theTopology.firstHFQuadPhiRing())
00208 {
00209 phi+=(twopi/36);
00210 phibin=static_cast<int>(phi/twopi*nphibins);
00211 if (phibin==0) phibin=18;
00212 iphi=phibin*4-1;
00213 } else {
00214
00215 iphi=(phibin-1)*(72/nphibins) + 1;
00216 }
00217
00218 return iphi;
00219 }
00220
00221 CaloSubdetectorGeometry::DetIdSet
00222 HcalGeometry::getCells( const GlobalPoint& r,
00223 double dR ) const
00224 {
00225 CaloSubdetectorGeometry::DetIdSet dis;
00226
00227 if( 0.000001 < dR )
00228 {
00229 if( dR > M_PI/2. )
00230 {
00231 dis = CaloSubdetectorGeometry::getCells( r, dR ) ;
00232 }
00233 else
00234 {
00235 const double dR2 ( dR*dR ) ;
00236 const double reta ( r.eta() ) ;
00237 const double rphi ( r.phi() ) ;
00238 const double lowEta ( reta - dR ) ;
00239 const double highEta ( reta + dR ) ;
00240 const double lowPhi ( rphi - dR ) ;
00241 const double highPhi ( rphi + dR ) ;
00242
00243 const double hfEtaHi ( theHFEtaBounds[ theTopology.lastHFRing() -
00244 theTopology.firstHFRing() + 1 ] ) ;
00245
00246 if( highEta > -hfEtaHi &&
00247 lowEta < hfEtaHi )
00248 {
00249 const HcalSubdetector hs[] = { HcalBarrel, HcalOuter, HcalEndcap, HcalForward } ;
00250
00251 for( unsigned int is ( 0 ) ; is != 4 ; ++is )
00252 {
00253 const int sign ( reta>0 ? 1 : -1 ) ;
00254 const int ieta_center ( sign*etaRing( hs[is], fabs( reta ) ) ) ;
00255 const int ieta_lo ( ( 0 < lowEta*sign ? sign : -sign )*etaRing( hs[is], fabs( lowEta ) ) ) ;
00256 const int ieta_hi ( ( 0 < highEta*sign ? sign : -sign )*etaRing( hs[is], fabs( highEta ) ) ) ;
00257 const int iphi_lo ( phiBin( lowPhi , ieta_center ) ) ;
00258 const int iphi_hi ( phiBin( highPhi, ieta_center ) ) ;
00259 const int jphi_lo ( iphi_lo>iphi_hi ? iphi_lo - 72 : iphi_lo ) ;
00260 const int jphi_hi ( iphi_hi ) ;
00261
00262 const int idep_lo ( 1 == is ? 4 : 1 ) ;
00263 const int idep_hi ( 1 == is ? 4 :
00264 ( 2 == is ? 3 : 2 ) ) ;
00265 for( int ieta ( ieta_lo ) ; ieta <= ieta_hi ; ++ieta )
00266 {
00267 if( ieta != 0 )
00268 {
00269 for( int jphi ( jphi_lo ) ; jphi <= jphi_hi ; ++jphi )
00270 {
00271 const int iphi ( 1 > jphi ? jphi+72 : jphi ) ;
00272
00273 for( int idep ( idep_lo ) ; idep <= idep_hi ; ++idep )
00274 {
00275 const HcalDetId did ( hs[is], ieta, iphi, idep ) ;
00276 if( theTopology.valid(did) )
00277
00278 {
00279 const CaloCellGeometry* cell ( getGeometry( did ) );
00280 if( 0 != cell )
00281 {
00282 const GlobalPoint& p ( cell->getPosition() ) ;
00283 const double eta ( p.eta() ) ;
00284 const double phi ( p.phi() ) ;
00285 if( reco::deltaR2( eta, phi, reta, rphi ) < dR2 ) dis.insert( did ) ;
00286 }
00287 }
00288 }
00289 }
00290 }
00291 }
00292 }
00293 }
00294 }
00295 }
00296 return dis;
00297 }
00298
00299
00300
00301 DetId
00302 HcalGeometry::detIdFromBarrelAlignmentIndex( unsigned int i )
00303 {
00304 assert( i < numberOfBarrelAlignments() ) ;
00305 const int ieta ( i < numberOfBarrelAlignments()/2 ? -1 : 1 ) ;
00306 const int iphi ( 1 + (4*i)%72 ) ;
00307 return HcalDetId( HcalBarrel, ieta, iphi, 1 ) ;
00308 }
00309
00310 DetId
00311 HcalGeometry::detIdFromEndcapAlignmentIndex( unsigned int i )
00312 {
00313 assert( i < numberOfEndcapAlignments() ) ;
00314 const int ieta ( i < numberOfEndcapAlignments()/2 ? -16 : 16 ) ;
00315 const int iphi ( 1 + (4*i)%72 ) ;
00316 return HcalDetId( HcalEndcap, ieta, iphi, 1 ) ;
00317 }
00318
00319 DetId
00320 HcalGeometry::detIdFromForwardAlignmentIndex( unsigned int i )
00321 {
00322 assert( i < numberOfForwardAlignments() ) ;
00323 const int ieta ( i < numberOfForwardAlignments()/2 ? -29 : 29 ) ;
00324 const int iphi ( 1 + (4*i)%72 ) ;
00325 return HcalDetId( HcalForward, ieta, iphi, 1 ) ;
00326 }
00327
00328 DetId
00329 HcalGeometry::detIdFromOuterAlignmentIndex( unsigned int i )
00330 {
00331 assert( i < numberOfOuterAlignments() ) ;
00332 const int ring ( i/12 ) ;
00333 const int ieta ( 0 == ring ? -11 :
00334 1 == ring ? -5 :
00335 2 == ring ? 1 :
00336 3 == ring ? 5 : 11 ) ;
00337 const int iphi ( 1 + ( i - ring*12 )*6 ) ;
00338 return HcalDetId( HcalOuter, ieta, iphi, 4 ) ;
00339 }
00340
00341 DetId
00342 HcalGeometry::detIdFromLocalAlignmentIndex( unsigned int i )
00343 {
00344 assert( i < numberOfAlignments() ) ;
00345
00346 const unsigned int nB ( numberOfBarrelAlignments() ) ;
00347 const unsigned int nE ( numberOfEndcapAlignments() ) ;
00348 const unsigned int nF ( numberOfForwardAlignments() ) ;
00349
00350
00351 return ( i < nB ? detIdFromBarrelAlignmentIndex( i ) :
00352 i < nB+nE ? detIdFromEndcapAlignmentIndex( i - nB ) :
00353 i < nB+nE+nF ? detIdFromForwardAlignmentIndex( i - nB - nE ) :
00354 detIdFromOuterAlignmentIndex( i - nB - nE - nF ) ) ;
00355 }
00356
00357 unsigned int
00358 HcalGeometry::alignmentBarEndForIndexLocal( const DetId& id ,
00359 unsigned int nD )
00360 {
00361 const HcalDetId hid ( id ) ;
00362 const unsigned int iphi ( hid.iphi() ) ;
00363 const int ieta ( hid.ieta() ) ;
00364 const unsigned int index ( ( 0 < ieta ? nD/2 : 0 ) + ( iphi + 1 )%72/4 ) ;
00365 assert( index < nD ) ;
00366 return index ;
00367 }
00368
00369 unsigned int
00370 HcalGeometry::alignmentBarrelIndexLocal( const DetId& id )
00371 {
00372 return alignmentBarEndForIndexLocal( id, numberOfBarrelAlignments() ) ;
00373 }
00374 unsigned int
00375 HcalGeometry::alignmentEndcapIndexLocal( const DetId& id )
00376 {
00377 return alignmentBarEndForIndexLocal( id, numberOfEndcapAlignments() ) ;
00378 }
00379
00380 unsigned int
00381 HcalGeometry::alignmentForwardIndexLocal( const DetId& id )
00382 {
00383 return alignmentBarEndForIndexLocal( id, numberOfForwardAlignments() ) ;
00384 }
00385
00386 unsigned int
00387 HcalGeometry::alignmentOuterIndexLocal( const DetId& id )
00388 {
00389 const HcalDetId hid ( id ) ;
00390 const int ieta ( hid.ieta() ) ;
00391 const int iphi ( hid.iphi() ) ;
00392 const int ring ( ieta < -10 ? 0 :
00393 ( ieta < -4 ? 1 :
00394 ( ieta < 5 ? 2 :
00395 ( ieta < 11 ? 3 : 4 ) ) ) ) ;
00396
00397 const unsigned int index ( 12*ring + ( iphi - 1 )/6 ) ;
00398 assert( index < numberOfOuterAlignments() ) ;
00399 return index ;
00400 }
00401
00402 unsigned int
00403 HcalGeometry::alignmentTransformIndexLocal( const DetId& id )
00404 {
00405 assert(id.det() == DetId::Hcal) ;
00406
00407 const HcalDetId hid ( id ) ;
00408 bool isHB = (hid.subdet() == HcalBarrel);
00409 bool isHE = (hid.subdet() == HcalEndcap);
00410 bool isHF = (hid.subdet() == HcalForward);
00411
00412
00413 const unsigned int nB ( numberOfBarrelAlignments() ) ;
00414 const unsigned int nE ( numberOfEndcapAlignments() ) ;
00415 const unsigned int nF ( numberOfForwardAlignments() ) ;
00416
00417
00418 const unsigned int index (
00419 isHB ? alignmentBarrelIndexLocal(id) :
00420 isHE ? alignmentEndcapIndexLocal(id) + nB :
00421 isHF ? alignmentForwardIndexLocal( id ) + nB + nE :
00422 alignmentOuterIndexLocal(id) + nB + nE + nF
00423 );
00424
00425 assert( index < numberOfAlignments() ) ;
00426 return index ;
00427 }
00428
00429 unsigned int
00430 HcalGeometry::alignmentTransformIndexGlobal( const DetId& id )
00431 {
00432 return (unsigned int)DetId::Hcal - 1 ;
00433 }
00434
00435 void
00436 HcalGeometry::localCorners( Pt3DVec& lc ,
00437 const CCGFloat* pv ,
00438 unsigned int i ,
00439 Pt3D& ref )
00440 {
00441 HcalDetId hid=HcalDetId(theTopology.denseId2detId(i));
00442
00443 if( hid.subdet() == HcalForward )
00444 {
00445 IdealZPrism::localCorners( lc, pv, ref ) ;
00446 }
00447 else
00448 {
00449 IdealObliquePrism::localCorners( lc, pv, ref ) ;
00450 }
00451 }
00452
00453 void
00454 HcalGeometry::newCell( const GlobalPoint& f1 ,
00455 const GlobalPoint& f2 ,
00456 const GlobalPoint& f3 ,
00457 const CCGFloat* parm ,
00458 const DetId& detId ) {
00459
00460 assert (detId.det()==DetId::Hcal);
00461
00462 const HcalDetId hid ( detId ) ;
00463 unsigned int din=theTopology.detId2denseId(detId);
00464
00465 edm::LogInfo("HcalGeometry") << " newCell subdet "
00466 << detId.subdetId() << ", raw ID "
00467 << detId.rawId() << ", hid " << hid << ", din "
00468 << din << ", index ";
00469
00470 if( hid.subdet()==HcalBarrel) {
00471 m_hbCellVec[ din ] = IdealObliquePrism( f1, cornersMgr(), parm ) ;
00472 } else if( hid.subdet()==HcalEndcap ) {
00473 const unsigned int index ( din - m_hbCellVec.size() ) ;
00474 m_heCellVec[ index ] = IdealObliquePrism( f1, cornersMgr(), parm ) ;
00475 } else if( hid.subdet()==HcalOuter ) {
00476 const unsigned int index ( din
00477 - m_hbCellVec.size()
00478 - m_heCellVec.size() ) ;
00479 m_hoCellVec[ index ] = IdealObliquePrism( f1, cornersMgr(), parm ) ;
00480 } else {
00481 const unsigned int index ( din
00482 - m_hbCellVec.size()
00483 - m_heCellVec.size()
00484 - m_hoCellVec.size() ) ;
00485 m_hfCellVec[ index ] = IdealZPrism( f1, cornersMgr(), parm ) ;
00486 }
00487
00488 m_validIds.push_back( detId ) ;
00489 m_dins.push_back( din );
00490 }
00491
00492 const CaloCellGeometry*
00493 HcalGeometry::cellGeomPtr( unsigned int din ) const
00494 {
00495 const CaloCellGeometry* cell ( 0 ) ;
00496 if( m_hbCellVec.size() > din )
00497 {
00498 cell = &m_hbCellVec[ din ] ;
00499 }
00500 else
00501 {
00502 if( m_hbCellVec.size() +
00503 m_heCellVec.size() > din )
00504 {
00505 const unsigned int index ( din - m_hbCellVec.size() ) ;
00506 cell = &m_heCellVec[ index ] ;
00507 }
00508 else
00509 {
00510 if( m_hbCellVec.size() +
00511 m_heCellVec.size() +
00512 m_hoCellVec.size() > din )
00513 {
00514 const unsigned int index ( din
00515 - m_hbCellVec.size()
00516 - m_heCellVec.size() ) ;
00517 cell = &m_hoCellVec[ index ] ;
00518 }
00519 else
00520 {
00521 if( m_hbCellVec.size() +
00522 m_heCellVec.size() +
00523 m_hoCellVec.size() +
00524 m_hfCellVec.size() > din )
00525 {
00526 const unsigned int index ( din
00527 - m_hbCellVec.size()
00528 - m_heCellVec.size()
00529 - m_hoCellVec.size() ) ;
00530 cell = &m_hfCellVec[ index ] ;
00531 }
00532 }
00533 }
00534 }
00535
00536 return (( 0 == cell || 0 == cell->param()) ? 0 : cell ) ;
00537 }
00538
00539 void
00540 HcalGeometry::getSummary( CaloSubdetectorGeometry::TrVec& tVec,
00541 CaloSubdetectorGeometry::IVec& iVec,
00542 CaloSubdetectorGeometry::DimVec& dVec,
00543 CaloSubdetectorGeometry::IVec& dinsVec ) const
00544 {
00545 tVec.reserve( theTopology.ncells()*numberOfTransformParms() ) ;
00546 iVec.reserve( numberOfShapes()==1 ? 1 : theTopology.ncells() ) ;
00547 dVec.reserve( numberOfShapes()*numberOfParametersPerShape() ) ;
00548 dinsVec.reserve( m_dins.size() );
00549
00550 for( ParVecVec::const_iterator ivv ( parVecVec().begin() ) ; ivv != parVecVec().end() ; ++ivv )
00551 {
00552 const ParVec& pv ( *ivv ) ;
00553 for( ParVec::const_iterator iv ( pv.begin() ) ; iv != pv.end() ; ++iv )
00554 {
00555 dVec.push_back( *iv ) ;
00556 }
00557 }
00558
00559 for( unsigned int i ( 0 ) ; i < theTopology.ncells() ; ++i )
00560 {
00561 Tr3D tr ;
00562 const CaloCellGeometry* ptr ( cellGeomPtr( i ) ) ;
00563 dinsVec.push_back( i );
00564
00565 assert( 0 != ptr ) ;
00566 ptr->getTransform( tr, ( Pt3DVec* ) 0 ) ;
00567
00568 if( Tr3D() == tr )
00569 {
00570 const GlobalPoint& gp ( ptr->getPosition() ) ;
00571 tr = HepGeom::Translate3D( gp.x(), gp.y(), gp.z() ) ;
00572 }
00573
00574 const CLHEP::Hep3Vector tt ( tr.getTranslation() ) ;
00575 tVec.push_back( tt.x() ) ;
00576 tVec.push_back( tt.y() ) ;
00577 tVec.push_back( tt.z() ) ;
00578 if( 6 == numberOfTransformParms() )
00579 {
00580 const CLHEP::HepRotation rr ( tr.getRotation() ) ;
00581 const ROOT::Math::Transform3D rtr ( rr.xx(), rr.xy(), rr.xz(), tt.x(),
00582 rr.yx(), rr.yy(), rr.yz(), tt.y(),
00583 rr.zx(), rr.zy(), rr.zz(), tt.z() ) ;
00584 ROOT::Math::EulerAngles ea ;
00585 rtr.GetRotation( ea ) ;
00586 tVec.push_back( ea.Phi() ) ;
00587 tVec.push_back( ea.Theta() ) ;
00588 tVec.push_back( ea.Psi() ) ;
00589 }
00590
00591 const CCGFloat* par ( ptr->param() ) ;
00592
00593 unsigned int ishape ( 9999 ) ;
00594 for( unsigned int ivv ( 0 ) ; ivv != parVecVec().size() ; ++ivv )
00595 {
00596 bool ok ( true ) ;
00597 const CCGFloat* pv ( &(*parVecVec()[ivv].begin() ) ) ;
00598 for( unsigned int k ( 0 ) ; k != numberOfParametersPerShape() ; ++k )
00599 {
00600 ok = ok && ( fabs( par[k] - pv[k] ) < 1.e-6 ) ;
00601 }
00602 if( ok )
00603 {
00604 ishape = ivv ;
00605 break ;
00606 }
00607 }
00608 assert( 9999 != ishape ) ;
00609
00610 const unsigned int nn (( numberOfShapes()==1) ? (unsigned int)1 : m_dins.size() ) ;
00611 if( iVec.size() < nn ) iVec.push_back( ishape ) ;
00612 }
00613 }