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
00014
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
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
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
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
00074
00075
00076 tt( stripErr2 * std::pow( centreToIntersection()*angularWidth() ,2.f) ),
00077 rr( std::pow(detHeight(), 2.f) * (1.f/12.f) ),
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),
00090
00091 T( angularWidth() * ( centreToIntersection() + yAxisOrientation()*mp.y()*detHeight()) / c1 ),
00092 R( detHeight()/ c1 ),
00093 tt( me.uu() * T*T ),
00094 rr( me.vv() * R*R ),
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),
00108 cs(t/(1+t*t)), s2(t*cs), c2(1-s2),
00109
00110 T2( 1./(std::pow(angularWidth(),2.f) * ( std::pow(p.x(),2.f) + std::pow(yHitToInter,2)) )),
00111 R2( c2/std::pow(detHeight(),2.f) ),
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
00124 const int istrip = std::min(nstrips(), static_cast<int>(strip(lp)) + 1);
00125 const float fangle = stripAngle(static_cast<float>(istrip) - 0.5);
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 }