00001 #include "Geometry/CaloGeometry/interface/CaloGenericDetId.h"
00002 #include "Geometry/EcalAlgo/interface/EcalEndcapGeometry.h"
00003 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00004 #include "Geometry/CaloGeometry/interface/TruncatedPyramid.h"
00005 #include "FWCore/Utilities/interface/Exception.h"
00006 #include <CLHEP/Geometry/Point3D.h>
00007 #include <CLHEP/Geometry/Plane3D.h>
00008
00009 EcalEndcapGeometry::EcalEndcapGeometry() :
00010 _nnmods ( 316 ) ,
00011 _nncrys ( 25 ) ,
00012 m_borderMgr ( 0 ),
00013 m_borderPtrVec ( 0 ),
00014 m_avgZ ( -1 )
00015 {
00016 }
00017
00018 EcalEndcapGeometry::~EcalEndcapGeometry()
00019 {
00020 delete m_borderPtrVec ;
00021 delete m_borderMgr ;
00022 }
00023
00024 unsigned int
00025 EcalEndcapGeometry::alignmentTransformIndexLocal( const DetId& id )
00026 {
00027 const CaloGenericDetId gid ( id ) ;
00028
00029 assert( gid.isEE() ) ;
00030 unsigned int index ( EEDetId(id).ix()/51 + ( EEDetId(id).zside()<0 ? 0 : 2 ) ) ;
00031
00032 return index ;
00033 }
00034
00035 DetId
00036 EcalEndcapGeometry::detIdFromLocalAlignmentIndex( unsigned int iLoc )
00037 {
00038 return EEDetId( 20 + 50*( iLoc%2 ), 50, 2*( iLoc/2 ) - 1 ) ;
00039 }
00040
00041 unsigned int
00042 EcalEndcapGeometry::alignmentTransformIndexGlobal( const DetId& id )
00043 {
00044 return (unsigned int)DetId::Ecal - 1 ;
00045 }
00046
00047 void
00048 EcalEndcapGeometry::initializeParms()
00049 {
00050 zeP=0.;
00051 zeN=0.;
00052 unsigned nP=0;
00053 unsigned nN=0;
00054 m_nref = 0 ;
00055
00056 for( uint32_t i ( 0 ) ; i != cellGeometries().size() ; ++i )
00057 {
00058 if( 0 != cellGeometries()[i] )
00059 {
00060
00061 const double z ( cellGeometries()[i]->getPosition().z() ) ;
00062 if(z>0.)
00063 {
00064 zeP+=z;
00065 ++nP;
00066 }
00067 else
00068 {
00069 zeN+=z;
00070 ++nN;
00071 }
00072 const EEDetId myId ( EEDetId::detIdFromDenseIndex(i) ) ;
00073 const unsigned int ix ( myId.ix() ) ;
00074 const unsigned int iy ( myId.iy() ) ;
00075 if( ix > m_nref ) m_nref = ix ;
00076 if( iy > m_nref ) m_nref = iy ;
00077 }
00078 }
00079 if( 0 < nP ) zeP/=(double)nP;
00080 if( 0 < nN ) zeN/=(double)nN;
00081
00082 m_xlo[0] = 999 ;
00083 m_xhi[0] = -999 ;
00084 m_ylo[0] = 999 ;
00085 m_yhi[0] = -999 ;
00086 m_xlo[1] = 999 ;
00087 m_xhi[1] = -999 ;
00088 m_ylo[1] = 999 ;
00089 m_yhi[1] = -999 ;
00090 for( uint32_t i ( 0 ) ; i != cellGeometries().size() ; ++i )
00091 {
00092 const GlobalPoint p ( cellGeometries()[i]->getPosition() ) ;
00093 const double z ( p.z() ) ;
00094 const double zz ( 0 > z ? zeN : zeP ) ;
00095 const double x ( p.x()*zz/z ) ;
00096 const double y ( p.y()*zz/z ) ;
00097
00098 if( 0 > z && x < m_xlo[0] ) m_xlo[0] = x ;
00099 if( 0 < z && x < m_xlo[1] ) m_xlo[1] = x ;
00100 if( 0 > z && y < m_ylo[0] ) m_ylo[0] = y ;
00101 if( 0 < z && y < m_ylo[1] ) m_ylo[1] = y ;
00102
00103 if( 0 > z && x > m_xhi[0] ) m_xhi[0] = x ;
00104 if( 0 < z && x > m_xhi[1] ) m_xhi[1] = x ;
00105 if( 0 > z && y > m_yhi[0] ) m_yhi[0] = y ;
00106 if( 0 < z && y > m_yhi[1] ) m_yhi[1] = y ;
00107 }
00108
00109 m_xoff[0] = ( m_xhi[0] + m_xlo[0] )/2. ;
00110 m_xoff[1] = ( m_xhi[1] + m_xlo[1] )/2. ;
00111 m_yoff[0] = ( m_yhi[0] + m_ylo[0] )/2. ;
00112 m_yoff[1] = ( m_yhi[1] + m_ylo[1] )/2. ;
00113
00114 m_del = ( m_xhi[0] - m_xlo[0] + m_xhi[1] - m_xlo[1] +
00115 m_yhi[0] - m_ylo[0] + m_yhi[1] - m_ylo[1] ) ;
00116
00117 m_wref = m_del/(4.*(m_nref-1)) ;
00118
00119 m_xlo[0] -= m_wref/2 ;
00120 m_xlo[1] -= m_wref/2 ;
00121 m_xhi[0] += m_wref/2 ;
00122 m_xhi[1] += m_wref/2 ;
00123
00124 m_ylo[0] -= m_wref/2 ;
00125 m_ylo[1] -= m_wref/2 ;
00126 m_yhi[0] += m_wref/2 ;
00127 m_yhi[1] += m_wref/2 ;
00128
00129 m_del += m_wref ;
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 }
00141
00142
00143 unsigned int
00144 EcalEndcapGeometry::xindex( double x,
00145 double z ) const
00146 {
00147 const double xlo ( 0 > z ? m_xlo[0] : m_xlo[1] ) ;
00148 const int i ( 1 + int( ( x - xlo )/m_wref ) ) ;
00149
00150 return ( 1 > i ? 1 :
00151 ( m_nref < (unsigned int) i ? m_nref : (unsigned int) i ) ) ;
00152
00153 }
00154
00155 unsigned int
00156 EcalEndcapGeometry::yindex( double y,
00157 double z ) const
00158 {
00159 const double ylo ( 0 > z ? m_ylo[0] : m_ylo[1] ) ;
00160 const int i ( 1 + int( ( y - ylo )/m_wref ) ) ;
00161
00162 return ( 1 > i ? 1 :
00163 ( m_nref < (unsigned int) i ? m_nref : (unsigned int) i ) ) ;
00164 }
00165
00166 EEDetId
00167 EcalEndcapGeometry::gId( float x,
00168 float y,
00169 float z ) const
00170 {
00171 const double fac ( fabs( ( 0 > z ? zeN : zeP )/z ) ) ;
00172 const unsigned int ix ( xindex( x*fac, z ) ) ;
00173 const unsigned int iy ( yindex( y*fac, z ) ) ;
00174 const unsigned int iz ( z>0 ? 1 : -1 ) ;
00175
00176 if( EEDetId::validDetId( ix, iy, iz ) )
00177 {
00178 return EEDetId( ix, iy, iz ) ;
00179 }
00180 else
00181 {
00182 for( unsigned int i ( 1 ) ; i != 6 ; ++i )
00183 {
00184 for( unsigned int k ( 0 ) ; k != 8 ; ++k )
00185 {
00186 const int jx ( 0 == k || 4 == k || 5 == k ? +i :
00187 ( 1 == k || 5 < k ? -i : 0 ) ) ;
00188 const int jy ( 2 == k || 4 == k || 6 == k ? +i :
00189 ( 3 == k || 5 == k || 7 == k ? -i : 0 ) ) ;
00190 if( EEDetId::validDetId( ix + jx, iy + jy, iz ) )
00191 {
00192 return EEDetId( ix + jx, iy + jy, iz ) ;
00193 }
00194 }
00195 }
00196 }
00197 return EEDetId() ;
00198 }
00199
00200
00201
00202 DetId
00203 EcalEndcapGeometry::getClosestCell( const GlobalPoint& r ) const
00204 {
00205 try
00206 {
00207 EEDetId mycellID ( gId( r.x(), r.y(), r.z() ) ) ;
00208
00209 if( EEDetId::validDetId( mycellID.ix(),
00210 mycellID.iy(),
00211 mycellID.zside() ) )
00212 {
00213
00214
00215 HepGeom::Point3D<double> A;
00216 HepGeom::Point3D<double> B;
00217 HepGeom::Point3D<double> C;
00218 HepGeom::Point3D<double> point(r.x(),r.y(),r.z());
00219
00220
00221
00222
00223 double x,y,z;
00224 unsigned offset=0;
00225 int zsign=1;
00226
00227 std::vector<double> SS;
00228
00229
00230
00231
00232 if( 0 != getGeometry(mycellID) )
00233 {
00234 const GlobalPoint& myPosition=getGeometry(mycellID)->getPosition();
00235
00236 x=myPosition.x();
00237 y=myPosition.y();
00238 z=myPosition.z();
00239
00240 offset=0;
00241
00242 zsign=1;
00243
00244 if(z>0)
00245 {
00246 if(x>0&&y>0)
00247 offset=1;
00248 else if(x<0&&y>0)
00249 offset=2;
00250 else if(x>0&&y<0)
00251 offset=0;
00252 else if (x<0&&y<0)
00253 offset=3;
00254 zsign=1;
00255 }
00256 else
00257 {
00258 if(x>0&&y>0)
00259 offset=3;
00260 else if(x<0&&y>0)
00261 offset=2;
00262 else if(x>0&&y<0)
00263 offset=0;
00264 else if(x<0&&y<0)
00265 offset=1;
00266 zsign=-1;
00267 }
00268 std::vector<GlobalPoint> corners;
00269 corners.clear();
00270 corners.resize(8);
00271 for(unsigned ic=0;ic<4;++ic)
00272 {
00273 corners[ic]=getGeometry(mycellID)->getCorners()[(unsigned)((zsign*ic+offset)%4)];
00274 corners[4+ic]=getGeometry(mycellID)->getCorners()[(unsigned)(4+(zsign*ic+offset)%4)];
00275 }
00276
00277 for (short i=0; i < 4 ; ++i)
00278 {
00279 A = HepGeom::Point3D<double> (corners[i%4].x(),corners[i%4].y(),corners[i%4].z());
00280 B = HepGeom::Point3D<double> (corners[(i+1)%4].x(),corners[(i+1)%4].y(),corners[(i+1)%4].z());
00281 C = HepGeom::Point3D<double> (corners[4+(i+1)%4].x(),corners[4+(i+1)%4].y(),corners[4+(i+1)%4].z());
00282 HepGeom::Plane3D<double> plane(A,B,C);
00283 plane.normalize();
00284 double distance = plane.distance(point);
00285 if (corners[0].z()<0.) distance=-distance;
00286 SS.push_back(distance);
00287 }
00288
00289
00290
00291 const bool yout ( 0 > SS[0]*SS[2] ) ;
00292 const bool xout ( 0 > SS[1]*SS[3] ) ;
00293
00294 if( yout || xout )
00295 {
00296 const int ydel ( !yout ? 0 : ( 0 < SS[0] ? -1 : 1 ) ) ;
00297 const int xdel ( !xout ? 0 : ( 0 < SS[1] ? -1 : 1 ) ) ;
00298 const unsigned int ix ( mycellID.ix() + xdel ) ;
00299 const unsigned int iy ( mycellID.iy() + ydel ) ;
00300 const unsigned int iz ( mycellID.zside() ) ;
00301 if( EEDetId::validDetId( ix, iy, iz ) )
00302 mycellID = EEDetId( ix, iy, iz ) ;
00303 }
00304
00305 return mycellID;
00306 }
00307 return DetId(0);
00308 }
00309 }
00310 catch ( cms::Exception &e )
00311 {
00312 return DetId(0);
00313 }
00314 return DetId(0);
00315 }
00316
00317 CaloSubdetectorGeometry::DetIdSet
00318 EcalEndcapGeometry::getCells( const GlobalPoint& r,
00319 double dR ) const
00320 {
00321 CaloSubdetectorGeometry::DetIdSet dis ;
00322 if( 0.000001 < dR )
00323 {
00324 if( dR > M_PI/2. )
00325 {
00326 dis = CaloSubdetectorGeometry::getCells( r, dR ) ;
00327 }
00328 else
00329 {
00330 const double dR2 ( dR*dR ) ;
00331 const double reta ( r.eta() ) ;
00332 const double rphi ( r.phi() ) ;
00333 const double rx ( r.x() ) ;
00334 const double ry ( r.y() ) ;
00335 const double rz ( r.z() ) ;
00336 const double fac ( fabs( zeP/rz ) ) ;
00337 const double xx ( rx*fac ) ;
00338 const double yy ( ry*fac ) ;
00339 const double zz ( rz*fac ) ;
00340
00341 const double xang ( atan( xx/zz ) ) ;
00342 const double lowX ( zz>0 ? zz*tan( xang - dR ) : zz*tan( xang + dR ) ) ;
00343 const double highX ( zz>0 ? zz*tan( xang + dR ) : zz*tan( xang - dR ) ) ;
00344 const double yang ( atan( yy/zz ) ) ;
00345 const double lowY ( zz>0 ? zz*tan( yang - dR ) : zz*tan( yang + dR ) ) ;
00346 const double highY ( zz>0 ? zz*tan( yang + dR ) : zz*tan( yang - dR ) ) ;
00347
00348 const double refxlo ( 0 > rz ? m_xlo[0] : m_xlo[1] ) ;
00349 const double refxhi ( 0 > rz ? m_xhi[0] : m_xhi[1] ) ;
00350 const double refylo ( 0 > rz ? m_ylo[0] : m_ylo[1] ) ;
00351 const double refyhi ( 0 > rz ? m_yhi[0] : m_yhi[1] ) ;
00352
00353 if( lowX < refxhi &&
00354 lowY < refyhi &&
00355 highX > refxlo &&
00356 highY > refylo )
00357 {
00358 const int ix_ctr ( xindex( xx, rz ) ) ;
00359 const int iy_ctr ( yindex( yy, rz ) ) ;
00360 const int iz ( rz>0 ? 1 : -1 ) ;
00361
00362 const int ix_hi ( ix_ctr + int( ( highX - xx )/m_wref ) + 2 ) ;
00363 const int ix_lo ( ix_ctr - int( ( xx - lowX )/m_wref ) - 2 ) ;
00364
00365 const int iy_hi ( iy_ctr + int( ( highY - yy )/m_wref ) + 2 ) ;
00366 const int iy_lo ( iy_ctr - int( ( yy - lowY )/m_wref ) - 2 ) ;
00367
00368 for( int kx ( ix_lo ) ; kx <= ix_hi ; ++kx )
00369 {
00370 if( kx > 0 &&
00371 kx <= (int) m_nref )
00372 {
00373 for( int ky ( iy_lo ) ; ky <= iy_hi ; ++ky )
00374 {
00375 if( ky > 0 &&
00376 ky <= (int) m_nref )
00377 {
00378 if( EEDetId::validDetId( kx, ky, iz ) )
00379 {
00380 const EEDetId id ( kx, ky, iz ) ;
00381 const CaloCellGeometry* cell ( getGeometry( id ) );
00382 if( 0 != cell )
00383 {
00384 const GlobalPoint& p ( cell->getPosition() ) ;
00385 const double eta ( p.eta() ) ;
00386 const double phi ( p.phi() ) ;
00387 if( reco::deltaR2( eta, phi, reta, rphi ) < dR2 ) dis.insert( id ) ;
00388 }
00389 }
00390 }
00391 }
00392 }
00393 }
00394 }
00395 }
00396 }
00397 return dis;
00398 }
00399
00400 const EcalEndcapGeometry::OrderedListOfEBDetId*
00401 EcalEndcapGeometry::getClosestBarrelCells( EEDetId id ) const
00402 {
00403 OrderedListOfEBDetId* ptr ( 0 ) ;
00404 if( 0 != id.rawId() &&
00405 0 != getGeometry( id ) )
00406 {
00407 const float phi ( 370. +
00408 getGeometry( id )->getPosition().phi().degrees() );
00409 const int iPhi ( 1 + int(phi)%360 ) ;
00410 const int iz ( id.zside() ) ;
00411 if( 0 == m_borderMgr )
00412 {
00413 m_borderMgr = new EZMgrFL<EBDetId>( 720*9, 9 ) ;
00414 }
00415 if( 0 == m_borderPtrVec )
00416 {
00417 m_borderPtrVec = new VecOrdListEBDetIdPtr() ;
00418 m_borderPtrVec->reserve( 720 ) ;
00419 for( unsigned int i ( 0 ) ; i != 720 ; ++i )
00420 {
00421 const int kz ( 360>i ? -1 : 1 ) ;
00422 const int iEta ( kz*85 ) ;
00423 const int iEtam1 ( kz*84 ) ;
00424 const int iEtam2 ( kz*83 ) ;
00425 const int jPhi ( i%360 + 1 ) ;
00426 OrderedListOfEBDetId& olist ( *new OrderedListOfEBDetId( m_borderMgr ) );
00427 olist[0]=EBDetId( iEta , jPhi ) ;
00428 olist[1]=EBDetId( iEta , myPhi( jPhi+1 ) ) ;
00429 olist[2]=EBDetId( iEta , myPhi( jPhi-1 ) ) ;
00430 olist[3]=EBDetId( iEtam1, jPhi ) ;
00431 olist[4]=EBDetId( iEtam1, myPhi( jPhi+1 ) ) ;
00432 olist[5]=EBDetId( iEtam1, myPhi( jPhi-1 ) ) ;
00433 olist[6]=EBDetId( iEta , myPhi( jPhi+2 ) ) ;
00434 olist[7]=EBDetId( iEta , myPhi( jPhi-2 ) ) ;
00435 olist[8]=EBDetId( iEtam2, jPhi ) ;
00436 m_borderPtrVec->push_back( &olist ) ;
00437 }
00438 }
00439 ptr = (*m_borderPtrVec)[ ( iPhi - 1 ) + ( 0>iz ? 0 : 360 ) ] ;
00440 }
00441 return ptr ;
00442 }
00443
00444 std::vector<HepGeom::Point3D<double> >
00445 EcalEndcapGeometry::localCorners( const double* pv,
00446 unsigned int i,
00447 HepGeom::Point3D<double> & ref )
00448 {
00449 return ( TruncatedPyramid::localCorners( pv, ref ) ) ;
00450 }
00451
00452 CaloCellGeometry*
00453 EcalEndcapGeometry::newCell( const GlobalPoint& f1 ,
00454 const GlobalPoint& f2 ,
00455 const GlobalPoint& f3 ,
00456 CaloCellGeometry::CornersMgr* mgr,
00457 const double* parm ,
00458 const DetId& detId )
00459 {
00460 return ( new TruncatedPyramid( mgr, f1, f2, f3, parm ) ) ;
00461 }
00462
00463
00464 double
00465 EcalEndcapGeometry::avgAbsZFrontFaceCenter() const
00466 {
00467 if( 0 > m_avgZ )
00468 {
00469 double sum ( 0 ) ;
00470 const CaloSubdetectorGeometry::CellCont& cells ( cellGeometries() ) ;
00471 for( unsigned int i ( 0 ) ; i != cells.size() ; ++i )
00472 {
00473 sum += fabs( cells[i]->getPosition().z() ) ;
00474 }
00475 m_avgZ = sum/cells.size() ;
00476 }
00477 return m_avgZ ;
00478 }