00001 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00002 #include "Geometry/CaloGeometry/interface/CaloGenericDetId.h"
00003
00004 #include <Math/Transform3D.h>
00005 #include <Math/EulerAngles.h>
00006
00007 CaloSubdetectorGeometry::CaloSubdetectorGeometry() :
00008 m_parMgr ( 0 ) ,
00009 m_cmgr ( 0 ) ,
00010 m_sortedIds (false) ,
00011 m_deltaPhi ( 0 ) ,
00012 m_deltaEta ( 0 )
00013 {
00014 }
00015
00016
00017 CaloSubdetectorGeometry::~CaloSubdetectorGeometry()
00018 {
00019 for( CellCont::iterator i ( m_cellG.begin() );
00020 i!=m_cellG.end(); ++i )
00021 {
00022 delete *i ;
00023 }
00024
00025 delete m_cmgr ;
00026 delete m_parMgr ;
00027 delete m_deltaPhi ;
00028 delete m_deltaEta ;
00029 }
00030
00031 void
00032 CaloSubdetectorGeometry::addCell( const DetId& id ,
00033 CaloCellGeometry* ccg )
00034 {
00035 const CaloGenericDetId cdid ( id ) ;
00036
00037
00038
00039 const uint32_t index ( cdid.denseIndex() ) ;
00040
00041
00042
00043
00044
00045
00046
00047
00048 m_cellG[ index ] = ccg ;
00049 m_validIds.push_back( id ) ;
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 }
00062
00063 const std::vector<DetId>&
00064 CaloSubdetectorGeometry::getValidDetIds( DetId::Detector det ,
00065 int subdet ) const
00066 {
00067 if( !m_sortedIds )
00068 {
00069 m_sortedIds = true ;
00070 std::sort( m_validIds.begin(), m_validIds.end() ) ;
00071 }
00072 return m_validIds ;
00073 }
00074
00075 const CaloCellGeometry*
00076 CaloSubdetectorGeometry::getGeometry( const DetId& id ) const
00077 {
00078 return m_cellG[ CaloGenericDetId( id ).denseIndex() ] ;
00079 }
00080
00081 bool
00082 CaloSubdetectorGeometry::present( const DetId& id ) const
00083 {
00084
00085 return 0 != m_cellG[ CaloGenericDetId( id ).denseIndex() ] ;
00086 }
00087
00088 DetId
00089 CaloSubdetectorGeometry::getClosestCell( const GlobalPoint& r ) const
00090 {
00091 const double eta ( r.eta() ) ;
00092 const double phi ( r.phi() ) ;
00093 uint32_t index ( ~0 ) ;
00094 double closest ( 1e9 ) ;
00095
00096 CellCont::const_iterator cBeg ( cellGeometries().begin() ) ;
00097 for( CellCont::const_iterator i ( cBeg );
00098 i != m_cellG.end() ; ++i )
00099 {
00100 if( 0 != *i )
00101 {
00102 const GlobalPoint& p ( (*i)->getPosition() ) ;
00103 const double eta0 ( p.eta() ) ;
00104 const double phi0 ( p.phi() ) ;
00105 const double dR2 ( reco::deltaR2( eta0, phi0, eta, phi ) ) ;
00106 if( dR2 < closest )
00107 {
00108 closest = dR2 ;
00109 index = i - cBeg ;
00110 }
00111 }
00112 }
00113 const DetId tid ( m_validIds.front() ) ;
00114 return ( closest > 0.9e9 ||
00115 (uint32_t)(~0) == index ? DetId(0) :
00116 CaloGenericDetId( tid.det(),
00117 tid.subdetId(),
00118 index ) ) ;
00119 }
00120
00121 CaloSubdetectorGeometry::DetIdSet
00122 CaloSubdetectorGeometry::getCells( const GlobalPoint& r,
00123 double dR ) const
00124 {
00125 const double dR2 ( dR*dR ) ;
00126 const double eta ( r.eta() ) ;
00127 const double phi ( r.phi() ) ;
00128
00129 DetIdSet dss;
00130
00131 CellCont::const_iterator cBeg ( cellGeometries().begin() ) ;
00132 if( 0.000001 < dR )
00133 {
00134 for( CellCont::const_iterator i ( m_cellG.begin() );
00135 i != m_cellG.end() ; ++i )
00136 {
00137 if( 0 != *i )
00138 {
00139 const GlobalPoint& p ( (*i)->getPosition() ) ;
00140 const double eta0 ( p.eta() ) ;
00141 if( fabs( eta - eta0 ) < dR )
00142 {
00143 const double phi0 ( p.phi() ) ;
00144 double delp ( fabs( phi - phi0 ) ) ;
00145 if( delp > M_PI ) delp = 2*M_PI - delp ;
00146 if( delp < dR )
00147 {
00148 const double dist2 ( reco::deltaR2( eta0, phi0, eta, phi ) ) ;
00149 const DetId tid ( m_validIds.front() ) ;
00150 if( dist2 < dR2 ) dss.insert( CaloGenericDetId( tid.det(),
00151 tid.subdetId(),
00152 i - cBeg ) ) ;
00153 }
00154 }
00155 }
00156 }
00157 }
00158 return dss;
00159 }
00160
00161 void
00162 CaloSubdetectorGeometry::allocateCorners( CaloCellGeometry::CornersVec::size_type n )
00163 {
00164 assert( 0 == m_cmgr ) ;
00165 m_cmgr = new CaloCellGeometry::CornersMgr( n*( CaloCellGeometry::k_cornerSize ),
00166 CaloCellGeometry::k_cornerSize ) ;
00167
00168 m_validIds.reserve( n ) ;
00169
00170 m_cellG.reserve( n ) ;
00171 m_cellG.assign( n, CellCont::value_type ( 0 ) ) ;
00172 }
00173
00174 void
00175 CaloSubdetectorGeometry::allocatePar( ParVec::size_type n,
00176 unsigned int m )
00177 {
00178 assert( 0 == m_parMgr ) ;
00179 m_parMgr = new ParMgr( n*m, m ) ;
00180 }
00181
00182 void
00183 CaloSubdetectorGeometry::getSummary( CaloSubdetectorGeometry::TrVec& tVec ,
00184 CaloSubdetectorGeometry::IVec& iVec ,
00185 CaloSubdetectorGeometry::DimVec& dVec ) const
00186 {
00187 tVec.reserve( cellGeometries().size()*numberOfTransformParms() ) ;
00188 iVec.reserve( numberOfShapes()==1 ? 1 : cellGeometries().size() ) ;
00189 dVec.reserve( numberOfShapes()*numberOfParametersPerShape() ) ;
00190
00191 for( ParVecVec::const_iterator ivv ( parVecVec().begin() ) ; ivv != parVecVec().end() ; ++ivv )
00192 {
00193 const ParVec& pv ( *ivv ) ;
00194 for( ParVec::const_iterator iv ( pv.begin() ) ; iv != pv.end() ; ++iv )
00195 {
00196 dVec.push_back( *iv ) ;
00197 }
00198 }
00199
00200 for( CellCont::const_iterator i ( cellGeometries().begin() ) ;
00201 i != cellGeometries().end() ; ++i )
00202 {
00203 HepGeom::Transform3D tr ( (*i)->getTransform( ( std::vector<HepGeom::Point3D<double> >* ) 0 ) ) ;
00204
00205 if( HepGeom::Transform3D() == tr )
00206 {
00207 const GlobalPoint& gp ( (*i)->getPosition() ) ;
00208 tr = HepGeom::Translate3D( gp.x(), gp.y(), gp.z() ) ;
00209 }
00210
00211 const CLHEP::Hep3Vector tt ( tr.getTranslation() ) ;
00212 tVec.push_back( tt.x() ) ;
00213 tVec.push_back( tt.y() ) ;
00214 tVec.push_back( tt.z() ) ;
00215 if( 6 == numberOfTransformParms() )
00216 {
00217 const CLHEP::HepRotation rr ( tr.getRotation() ) ;
00218 const ROOT::Math::Transform3D rtr ( rr.xx(), rr.xy(), rr.xz(), tt.x(),
00219 rr.yx(), rr.yy(), rr.yz(), tt.y(),
00220 rr.zx(), rr.zy(), rr.zz(), tt.z() ) ;
00221 ROOT::Math::EulerAngles ea ;
00222 rtr.GetRotation( ea ) ;
00223 tVec.push_back( ea.Phi() ) ;
00224 tVec.push_back( ea.Theta() ) ;
00225 tVec.push_back( ea.Psi() ) ;
00226 }
00227
00228 const double* par ( (*i)->param() ) ;
00229
00230 unsigned int ishape ( 9999 ) ;
00231 for( unsigned int ivv ( 0 ) ; ivv != parVecVec().size() ; ++ivv )
00232 {
00233 bool ok ( true ) ;
00234 const double* pv ( &(*parVecVec()[ivv].begin() ) ) ;
00235 for( unsigned int k ( 0 ) ; k != numberOfParametersPerShape() ; ++k )
00236 {
00237 ok = ok && ( fabs( par[k] - pv[k] ) < 1.e-6 ) ;
00238 }
00239 if( ok )
00240 {
00241 ishape = ivv ;
00242 break ;
00243 }
00244 }
00245 assert( 9999 != ishape ) ;
00246
00247 const unsigned int nn (( numberOfShapes()==1) ? (unsigned int)1 : cellGeometries().size() ) ;
00248 if( iVec.size() < nn ) iVec.push_back( ishape ) ;
00249 }
00250 }
00251
00252 double
00253 CaloSubdetectorGeometry::deltaPhi( const DetId& detId ) const
00254 {
00255 const CaloGenericDetId cgId ( detId ) ;
00256
00257 if( 0 == m_deltaPhi )
00258 {
00259 const uint32_t kSize ( cgId.sizeForDenseIndexing() ) ;
00260 m_deltaPhi = new std::vector<double> ( kSize ) ;
00261 for( uint32_t i ( 0 ) ; i != kSize ; ++i )
00262 {
00263 const CaloCellGeometry& cell ( *cellGeometries()[ i ] ) ;
00264 double dPhi1 ( fabs(
00265 GlobalPoint( ( cell.getCorners()[0].x() +
00266 cell.getCorners()[1].x() )/2. ,
00267 ( cell.getCorners()[0].y() +
00268 cell.getCorners()[1].y() )/2. ,
00269 ( cell.getCorners()[0].z() +
00270 cell.getCorners()[1].z() )/2. ).phi() -
00271 GlobalPoint( ( cell.getCorners()[2].x() +
00272 cell.getCorners()[3].x() )/2. ,
00273 ( cell.getCorners()[2].y() +
00274 cell.getCorners()[3].y() )/2. ,
00275 ( cell.getCorners()[2].z() +
00276 cell.getCorners()[3].z() )/2. ).phi() ) ) ;
00277 double dPhi2 ( fabs(
00278 GlobalPoint( ( cell.getCorners()[0].x() +
00279 cell.getCorners()[3].x() )/2. ,
00280 ( cell.getCorners()[0].y() +
00281 cell.getCorners()[3].y() )/2. ,
00282 ( cell.getCorners()[0].z() +
00283 cell.getCorners()[3].z() )/2. ).phi() -
00284 GlobalPoint( ( cell.getCorners()[2].x() +
00285 cell.getCorners()[1].x() )/2. ,
00286 ( cell.getCorners()[2].y() +
00287 cell.getCorners()[1].y() )/2. ,
00288 ( cell.getCorners()[2].z() +
00289 cell.getCorners()[1].z() )/2. ).phi() ) ) ;
00290 if( M_PI < dPhi1 ) dPhi1 = fabs( dPhi1 - 2.*M_PI ) ;
00291 if( M_PI < dPhi2 ) dPhi2 = fabs( dPhi2 - 2.*M_PI ) ;
00292 (*m_deltaPhi)[i] = dPhi1>dPhi2 ? dPhi1 : dPhi2 ;
00293 }
00294 }
00295 return (*m_deltaPhi)[ cgId.denseIndex() ] ;
00296 }
00297
00298 double
00299 CaloSubdetectorGeometry::deltaEta( const DetId& detId ) const
00300 {
00301 const CaloGenericDetId cgId ( detId ) ;
00302
00303 if( 0 == m_deltaEta )
00304 {
00305 const uint32_t kSize ( cgId.sizeForDenseIndexing() ) ;
00306 m_deltaEta = new std::vector<double> ( kSize ) ;
00307 for( uint32_t i ( 0 ) ; i != kSize ; ++i )
00308 {
00309 const CaloCellGeometry& cell ( *cellGeometries()[ i ] ) ;
00310 const double dEta1 ( fabs(
00311 GlobalPoint( ( cell.getCorners()[0].x() +
00312 cell.getCorners()[1].x() )/2. ,
00313 ( cell.getCorners()[0].y() +
00314 cell.getCorners()[1].y() )/2. ,
00315 ( cell.getCorners()[0].z() +
00316 cell.getCorners()[1].z() )/2. ).eta() -
00317 GlobalPoint( ( cell.getCorners()[2].x() +
00318 cell.getCorners()[3].x() )/2. ,
00319 ( cell.getCorners()[2].y() +
00320 cell.getCorners()[3].y() )/2. ,
00321 ( cell.getCorners()[2].z() +
00322 cell.getCorners()[3].z() )/2. ).eta() ) ) ;
00323 const double dEta2 ( fabs(
00324 GlobalPoint( ( cell.getCorners()[0].x() +
00325 cell.getCorners()[3].x() )/2. ,
00326 ( cell.getCorners()[0].y() +
00327 cell.getCorners()[3].y() )/2. ,
00328 ( cell.getCorners()[0].z() +
00329 cell.getCorners()[3].z() )/2. ).eta() -
00330 GlobalPoint( ( cell.getCorners()[2].x() +
00331 cell.getCorners()[1].x() )/2. ,
00332 ( cell.getCorners()[2].y() +
00333 cell.getCorners()[1].y() )/2. ,
00334 ( cell.getCorners()[2].z() +
00335 cell.getCorners()[1].z() )/2. ).eta() ) ) ;
00336 (*m_deltaEta)[i] = dEta1>dEta2 ? dEta1 : dEta2 ;
00337 }
00338 }
00339 return (*m_deltaEta)[ cgId.denseIndex() ] ;
00340 }