CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/Geometry/CommonTopologies/src/RadialStripTopology.cc

Go to the documentation of this file.
00001 #include <Geometry/CommonTopologies/interface/RadialStripTopology.h>
00002 #include <FWCore/MessageLogger/interface/MessageLogger.h>
00003 #include <Utilities/General/interface/CMSexception.h>
00004 
00005 #include <iostream>
00006 #include <cmath>
00007 #include <algorithm>
00008 
00009 RadialStripTopology::RadialStripTopology(int ns, float aw, float dh, float r, int yAx, float yMid) :
00010   theNumberOfStrips(ns), theAngularWidth(aw), 
00011   theDetHeight(dh), theCentreToIntersection(r),
00012   theYAxisOrientation(yAx), yCentre( yMid) {   
00013   // Angular offset of extreme edge of detector, so that angle is
00014   // zero for a strip lying along local y axis = long symmetry axis of plane of strips
00015   thePhiOfOneEdge = -(0.5*theNumberOfStrips) * theAngularWidth * yAx;
00016   
00017   LogTrace("RadialStripTopology") << "RadialStripTopology: constructed with"
00018         << " strips = " << ns
00019         << " width = " << aw << " rad "
00020         << " det_height = " << dh
00021         << " ctoi = " << r 
00022         << " phi_edge = " << thePhiOfOneEdge << " rad "
00023         << " y_ax_ori = " << theYAxisOrientation
00024         << " y_det_centre = " << yCentre 
00025         << "\n";
00026 }    
00027 
00028 int RadialStripTopology::channel(const LocalPoint& lp) const { return   std::min( int( strip(lp) ), theNumberOfStrips-1 ) ;}
00029 
00030 int RadialStripTopology::nearestStrip(const LocalPoint & lp) const {   return std::min( nstrips(), static_cast<int>( std::max(float(0), strip(lp)) ) + 1);}
00031 
00032 float RadialStripTopology::stripAngle(float strip) const { return   phiOfOneEdge() + yAxisOrientation() * strip * angularWidth() ;}
00033 
00034 float RadialStripTopology::yDistanceToIntersection( float y ) const { return   yAxisOrientation()*y + originToIntersection() ;}
00035 
00036 float RadialStripTopology::localStripLength(const LocalPoint& lp) const {  
00037   return detHeight() * std::sqrt(1.f + std::pow( lp.x()/yDistanceToIntersection(lp.y()), 2.f) );
00038 }
00039 
00040 float RadialStripTopology::xOfStrip(int strip, float y) const { 
00041   return   
00042     yAxisOrientation() * yDistanceToIntersection( y ) * std::tan( stripAngle(static_cast<float>(strip) - 0.5 ) );
00043 }
00044 
00045 float RadialStripTopology::strip(const LocalPoint& lp) const {
00046   const float   // phi is measured from y axis --> sign of angle is sign of x * yAxisOrientation --> use atan2(x,y), not atan2(y,x)
00047     phi( std::atan2( lp.x(), yDistanceToIntersection( lp.y() ) )),
00048     aStrip( ( phi - yAxisOrientation() * phiOfOneEdge() )/angularWidth());
00049   return  std::max(float(0), std::min( (float)nstrips(), aStrip ));
00050 }
00051 
00052 LocalPoint RadialStripTopology::localPosition(float strip) const {
00053   return LocalPoint( yAxisOrientation() * originToIntersection() * tan( stripAngle(strip) ), 0 );
00054 }
00055 
00056 LocalPoint RadialStripTopology::localPosition(const MeasurementPoint& mp) const {
00057   const float  // y = (L/cos(phi))*mp.y()*cos(phi) 
00058     y( mp.y()*detHeight()  +  yCentreOfStripPlane() ),
00059     x( yAxisOrientation() * yDistanceToIntersection( y ) * std::tan ( stripAngle( mp.x() ) ) );
00060   return LocalPoint( x, y );
00061 }
00062 
00063 MeasurementPoint RadialStripTopology::measurementPosition(const LocalPoint& lp) const {
00064   const float // phi is [pi/2 - conventional local phi], use atan2(x,y) rather than atan2(y,x)
00065     phi( yAxisOrientation() * std::atan2( lp.x(), yDistanceToIntersection( lp.y() ) ));
00066   return MeasurementPoint( yAxisOrientation()*( phi-phiOfOneEdge() ) / angularWidth(),
00067                            ( lp.y() - yCentreOfStripPlane() )        / detHeight() );
00068 }
00069 
00070 LocalError RadialStripTopology::localError(float strip, float stripErr2) const {
00071   const double
00072     phi(stripAngle(strip)), t1(std::tan(phi)), t2(t1*t1),
00073     // s1(std::sin(phi)), c1(std::cos(phi)),
00074     // cs(s1*c1), s2(s1*s1), c2(1-s2), // rotation matrix
00075 
00076     tt( stripErr2 * std::pow( centreToIntersection()*angularWidth() ,2.f) ), // tangential sigma^2   *c2
00077     rr( std::pow(detHeight(), 2.f) * (1.f/12.f) ),                                   // radial sigma^2( uniform prob density along strip)  *c2
00078 
00079     xx( tt + t2*rr  ),
00080     yy( t2*tt + rr  ),
00081     xy( t1*( rr - tt ) );
00082   
00083   return LocalError( xx, xy, yy );
00084 }
00085 
00086 LocalError RadialStripTopology::localError(const MeasurementPoint& mp, const MeasurementError& me) const {
00087   const double
00088     phi(stripAngle(mp.x())), s1(std::sin(phi)), c1(std::cos(phi)),
00089     cs(s1*c1), s2(s1*s1), c2(1-s2), // rotation matrix
00090 
00091     T( angularWidth() * ( centreToIntersection() + yAxisOrientation()*mp.y()*detHeight()) / c1 ), // tangential measurement unit (local pitch)
00092     R( detHeight()/ c1 ),  // radial measurement unit (strip length)
00093     tt( me.uu() * T*T ),   // tangential sigma^2
00094     rr( me.vv() * R*R   ), // radial sigma^2
00095     tr( me.uv() * T*R ),  
00096     
00097     xx(  c2*tt  +  2*cs*tr  +  s2*rr      ),
00098     yy(  s2*tt  -  2*cs*tr  +  c2*rr      ),
00099     xy( cs*( rr - tt )  +  tr*( c2 - s2 ) );
00100 
00101   return LocalError( xx, xy, yy );
00102 }
00103 
00104 MeasurementError RadialStripTopology::measurementError(const LocalPoint& p,  const LocalError& e) const {
00105   const double
00106     yHitToInter(yDistanceToIntersection(p.y())),
00107     t(yAxisOrientation() * p.x() / yHitToInter),   // tan(strip angle) 
00108     cs(t/(1+t*t)), s2(t*cs), c2(1-s2),             // rotation matrix
00109 
00110     T2( 1./(std::pow(angularWidth(),2.f) * ( std::pow(p.x(),2.f) + std::pow(yHitToInter,2)) )), // 1./tangential measurement unit (local pitch) ^2
00111     R2( c2/std::pow(detHeight(),2.f) ),                                    // 1./ radial measurement unit (strip length) ^2
00112 
00113     uu(       ( c2*e.xx() - 2*cs*e.xy() + s2*e.yy() )   * T2 ),
00114     vv(       ( s2*e.xx() + 2*cs*e.xy() + c2*e.yy() )   * R2 ),
00115     uv( ( cs*( e.xx() - e.yy() ) + e.xy()*( c2 - s2 ) )  * std::sqrt (T2*R2) );
00116   
00117   return MeasurementError(uu, uv, vv);
00118 }
00119  
00120 float RadialStripTopology::pitch() const {  throw Genexception("RadialStripTopology::pitch() called - makes no sense, use localPitch(.) instead."); return 0.;}
00121 
00122 float RadialStripTopology::localPitch(const LocalPoint& lp) const { 
00123  // The local pitch is the local x width of the strip at the local (x,y)
00124   const int istrip = std::min(nstrips(), static_cast<int>(strip(lp)) + 1); // which strip number
00125   const float fangle = stripAngle(static_cast<float>(istrip) - 0.5); // angle of strip centre
00126   return
00127     yDistanceToIntersection( lp.y() ) * std::sin(angularWidth()) /
00128     std::pow( std::cos(fangle-0.5f*angularWidth()), 2.f);
00129 }
00130     
00131 
00132 std::ostream & operator<<( std::ostream & os, const RadialStripTopology & rst ) {
00133   os  << "RadialStripTopology " << std::endl
00134       << " " << std::endl
00135       << "number of strips          " << rst.nstrips() << std::endl
00136       << "centre to whereStripsMeet " << rst.centreToIntersection() << std::endl
00137       << "detector height in y      " << rst.detHeight() << std::endl
00138       << "angular width of strips   " << rst.phiPitch() << std::endl
00139       << "phi of one edge           " << rst.phiOfOneEdge() << std::endl
00140       << "y axis orientation        " << rst.yAxisOrientation() << std::endl
00141       << "y of centre of strip plane " << rst.yCentreOfStripPlane() << std::endl;
00142   return os;
00143 }