00001
00002 #include "RecoPixelVertexing/PixelTriplets/interface/ThirdHitPredictionFromInvParabola.h"
00003
00004 #include <cmath>
00005 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
00006 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00007
00008 #include "RecoTracker/TkHitPairs/interface/OrderedHitPair.h"
00009 #include "RecoTracker/TkTrackingRegions/interface/TrackingRegion.h"
00010 #include "RecoTracker/TkMSParametrization/interface/PixelRecoUtilities.h"
00011
00012 #include "RecoTracker/TkMSParametrization/interface/PixelRecoRange.h"
00013
00014 namespace {
00015 template <class T> inline T sqr( T t) {return t*t;}
00016 }
00017
00018
00019 typedef Basic3DVector<double> Point3D;
00020 typedef Basic2DVector<double> Point2D;
00021 typedef PixelRecoRange<double> Ranged;
00022
00023 using namespace std;
00024
00025 ThirdHitPredictionFromInvParabola::ThirdHitPredictionFromInvParabola(
00026 const GlobalPoint& P1, const GlobalPoint& P2,double ip, double curv, double torlerance)
00027 : theTolerance(torlerance)
00028 {
00029 init(P1,P2,ip,fabs(curv));
00030 }
00031
00032
00033 void ThirdHitPredictionFromInvParabola::
00034 init( const GlobalPoint & P1, const GlobalPoint & P2, double ip, double curv)
00035 {
00036
00037 GlobalVector aX = GlobalVector( P1.x(), P1.y(), 0.).unit();
00038 GlobalVector aY( -aX.y(), aX.x(), 0.);
00039 GlobalVector aZ( 0., 0., 1.);
00040 theRotation = Rotation(aX,aY,aZ);
00041
00042 p1 = PointUV(Point2D(P1.x(),P1.y()), &theRotation);
00043 p2 = PointUV(Point2D(P2.x(),P2.y()), &theRotation);
00044
00045 Range ipRange(-ip, ip);
00046 ipRange.sort();
00047
00048 double ipIntyPlus = ipFromCurvature(0.,1);
00049 double ipCurvPlus = ipFromCurvature(std::abs(curv), 1);
00050 double ipCurvMinus = ipFromCurvature(std::abs(curv), -1);
00051
00052
00053 Range ipRangePlus = Range(ipIntyPlus, ipCurvPlus); ipRangePlus.sort();
00054 Range ipRangeMinus = Range(-ipIntyPlus, ipCurvMinus); ipRangeMinus.sort();
00055
00056 theIpRangePlus = ipRangePlus.intersection(ipRange);
00057 theIpRangeMinus = ipRangeMinus.intersection(ipRange);
00058 }
00059
00060
00061 ThirdHitPredictionFromInvParabola::PointUV ThirdHitPredictionFromInvParabola::findPointAtCurve(
00062 double r, int c, double ip) const
00063 {
00064
00065
00066
00067
00068 double A = coeffA(ip,c);
00069 double B = coeffB(ip,c);
00070
00071 double overR = 1./r;
00072 double ipOverR = ip*overR;
00073
00074 double delta = 1-4*(0.5*B+ipOverR)*(-B+A*r-ipOverR);
00075 double sqrtdelta = (delta > 0) ? std::sqrt(delta) : 0.;
00076 double alpha = (c>0)? (-c+sqrtdelta)/(B+2*ipOverR) : (-c-sqrtdelta)/(B+2*ipOverR);
00077
00078 double v = alpha*overR;
00079 double d2 = overR*overR - v*v;
00080 double u = (d2 > 0) ? std::sqrt(d2) : 0.;
00081
00082 return PointUV(u,v,&theRotation);
00083 }
00084
00085 ThirdHitPredictionFromInvParabola::Range ThirdHitPredictionFromInvParabola::rangeRPhi(
00086 double radius, int charge) const
00087 {
00088 Range predRPhi(1.,-1.);
00089 Range ip = (charge > 0) ? theIpRangePlus : theIpRangeMinus;
00090
00091 PointUV pred_tmp1 = findPointAtCurve(radius,charge,ip.min());
00092 PointUV pred_tmp2 = findPointAtCurve(radius,charge,ip.max());
00093
00094 double phi1 = pred_tmp1.unmap().phi();
00095 while ( phi1 >= M_PI) phi1 -= 2*M_PI;
00096 while ( phi1 < -M_PI) phi1 += 2*M_PI;
00097 double phi2 = phi1+radius*(pred_tmp2.v()-pred_tmp1.v());
00098
00099 if (ip.empty()) {
00100 Range r1(phi1*radius-theTolerance, phi1*radius+theTolerance);
00101 Range r2(phi2*radius-theTolerance, phi2*radius+theTolerance);
00102 predRPhi = r1.intersection(r2);
00103 } else {
00104 Range r(phi1, phi2);
00105 r.sort();
00106 predRPhi= Range(radius*r.min()-theTolerance, radius*r.max()+theTolerance);
00107 }
00108
00109 return predRPhi;
00110 }
00111
00112
00113 ThirdHitPredictionFromInvParabola::Range ThirdHitPredictionFromInvParabola::rangeRPhiSlow(
00114 double radius, int charge, int nIter) const
00115 {
00116 Range predRPhi(1.,-1.);
00117
00118 double invr2 = 1/radius/radius;
00119 double u = sqrt(invr2);
00120 double v = 0.;
00121
00122 Range ip = (charge > 0) ? theIpRangePlus : theIpRangeMinus;
00123
00124 for (int i=0; i < nIter; ++i) {
00125 v = predV(u, ip.min(), charge);
00126 double d2 = invr2-sqr(v);
00127 u = (d2 > 0) ? sqrt(d2) : 0.;
00128 }
00129 PointUV pred_tmp1(u, v, &theRotation);
00130 double phi1 = pred_tmp1.unmap().phi();
00131 while ( phi1 >= M_PI) phi1 -= 2*M_PI;
00132 while ( phi1 < -M_PI) phi1 += 2*M_PI;
00133
00134
00135 u = sqrt(invr2);
00136 v=0;
00137 for (int i=0; i < nIter; ++i) {
00138 v = predV(u, ip.max(), charge);
00139 double d2 = invr2-sqr(v);
00140 u = (d2 > 0) ? sqrt(d2) : 0.;
00141 }
00142 PointUV pred_tmp2(u, v, &theRotation);
00143 double phi2 = pred_tmp2.unmap().phi();
00144 while ( phi2-phi1 >= M_PI) phi2 -= 2*M_PI;
00145 while ( phi2-phi1 < -M_PI) phi2 += 2*M_PI;
00146
00147
00148
00149
00150 if (ip.empty()) {
00151 Range r1(phi1*radius-theTolerance, phi1*radius+theTolerance);
00152 Range r2(phi2*radius-theTolerance, phi2*radius+theTolerance);
00153 predRPhi = r1.intersection(r2);
00154 } else {
00155 Range r(phi1, phi2);
00156 r.sort();
00157 predRPhi= Range(radius*r.min()-theTolerance, radius*r.max()+theTolerance);
00158 }
00159 return predRPhi;
00160
00161 }
00162
00163
00164 double ThirdHitPredictionFromInvParabola::
00165 ipFromCurvature(double curvature, int charge) const
00166 {
00167 double u1u2 = p1.u()*p2.u();
00168 double du = p2.u() - p1.u();
00169 double pv = p1.v()*p2.u() - p2.v()*p1.u();
00170
00171 double inInf = -charge*pv/(du*u1u2);
00172 return inInf-curvature/(2.*u1u2);
00173 }
00174
00175
00176
00177 double ThirdHitPredictionFromInvParabola::
00178 predV( double u, double ip, int charge) const
00179 {
00180 return -charge*( coeffA(ip,charge) - coeffB(ip,charge)*u - ip*sqr(u));
00181 }