CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/Geometry/EcalAlgo/src/EcalEndcapGeometry.cc

Go to the documentation of this file.
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 //      addCrystalToZGridmap(i->first,dynamic_cast<const TruncatedPyramid*>(i->second));
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   std::cout<<"zeP="<<zeP<<", zeN="<<zeN<<", nP="<<nP<<", nN="<<nN<<std::endl ;
00132 
00133   std::cout<<"xlo[0]="<<m_xlo[0]<<", xlo[1]="<<m_xlo[1]<<", xhi[0]="<<m_xhi[0]<<", xhi[1]="<<m_xhi[1]
00134            <<"\nylo[0]="<<m_ylo[0]<<", ylo[1]="<<m_ylo[1]<<", yhi[0]="<<m_yhi[0]<<", yhi[1]="<<m_yhi[1]<<std::endl ;
00135 
00136   std::cout<<"xoff[0]="<<m_xoff[0]<<", xoff[1]"<<m_xoff[1]<<", yoff[0]="<<m_yoff[0]<<", yoff[1]"<<m_yoff[1]<<std::endl ;
00137 
00138   std::cout<<"nref="<<m_nref<<", m_wref="<<m_wref<<std::endl ;
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 ) ; // first try is on target
00179    }
00180    else // try nearby coordinates, spiraling out from center
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() ; // nowhere near any crystal
00198 }
00199 
00200 
00201 // Get closest cell, etc...
00202 DetId 
00203 EcalEndcapGeometry::getClosestCell( const GlobalPoint& r ) const 
00204 {
00205    try
00206    {
00207       EEDetId mycellID ( gId( r.x(), r.y(), r.z() ) ) ; // educated guess
00208 
00209       if( EEDetId::validDetId( mycellID.ix(), 
00210                                mycellID.iy(),
00211                                mycellID.zside() ) )
00212       {
00213          // now get points in convenient ordering
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          // D.K. : equation of plane : AA*x+BB*y+CC*z+DD=0;
00220          // finding equation for each edge
00221          
00222          // ================================================================
00223          double x,y,z;
00224          unsigned offset=0;
00225          int zsign=1;
00226          //================================================================
00227          std::vector<double> SS;
00228       
00229          // compute the distance of the point with respect of the 4 crystal lateral planes
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             // This will disappear when Andre has applied his fix
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             // Only one move in necessary direction
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 ; // return object
00322    if( 0.000001 < dR )
00323    {
00324       if( dR > M_PI/2. ) // this code assumes small dR
00325       {
00326          dis = CaloSubdetectorGeometry::getCells( r, dR ) ; // base class version
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 ) ; // xyz at endcap z
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 &&   // proceed if any possible overlap with the endcap
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 ) ) // reject invalid ids
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 }