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 PointUV p1(Point2D(P1.x(),P1.y()), &theRotation);
00043 PointUV p2(Point2D(P2.x(),P2.y()), &theRotation);
00044
00045 u1u2 = p1.u()*p2.u();
00046 overDu = 1./(p2.u() - p1.u());
00047 pv = p1.v()*p2.u() - p2.v()*p1.u();
00048 dv = p2.v() - p1.v();
00049 su = p2.u() + p1.u();
00050
00051 Range ipRange(-ip, ip);
00052 ipRange.sort();
00053
00054 double ipIntyPlus = ipFromCurvature(0.,1);
00055 double ipCurvPlus = ipFromCurvature(std::abs(curv), 1);
00056 double ipCurvMinus = ipFromCurvature(std::abs(curv), -1);
00057
00058
00059 Range ipRangePlus = Range(ipIntyPlus, ipCurvPlus); ipRangePlus.sort();
00060 Range ipRangeMinus = Range(-ipIntyPlus, ipCurvMinus); ipRangeMinus.sort();
00061
00062 theIpRangePlus = ipRangePlus.intersection(ipRange);
00063 theIpRangeMinus = ipRangeMinus.intersection(ipRange);
00064 }
00065
00066
00067 ThirdHitPredictionFromInvParabola::PointUV ThirdHitPredictionFromInvParabola::findPointAtCurve(
00068 double r, int c, double ip) const
00069 {
00070
00071
00072
00073
00074 double A = coeffA(ip,c);
00075 double B = coeffB(ip,c);
00076
00077 double overR = 1./r;
00078 double ipOverR = ip*overR;
00079
00080 double delta = 1-4*(0.5*B+ipOverR)*(-B+A*r-ipOverR);
00081 double sqrtdelta = (delta > 0) ? std::sqrt(delta) : 0.;
00082 double alpha = (c>0)? (-c+sqrtdelta)/(B+2*ipOverR) : (-c-sqrtdelta)/(B+2*ipOverR);
00083
00084 double v = alpha*overR;
00085 double d2 = overR*overR - v*v;
00086 double u = (d2 > 0) ? std::sqrt(d2) : 0.;
00087
00088 return PointUV(u,v,&theRotation);
00089 }
00090
00091 ThirdHitPredictionFromInvParabola::Range ThirdHitPredictionFromInvParabola::rangeRPhi(
00092 double radius, int charge) const
00093 {
00094 Range predRPhi(1.,-1.);
00095 Range ip = (charge > 0) ? theIpRangePlus : theIpRangeMinus;
00096
00097 PointUV pred_tmp1 = findPointAtCurve(radius,charge,ip.min());
00098 PointUV pred_tmp2 = findPointAtCurve(radius,charge,ip.max());
00099
00100 double phi1 = pred_tmp1.unmap().phi();
00101 while ( phi1 >= M_PI) phi1 -= 2*M_PI;
00102 while ( phi1 < -M_PI) phi1 += 2*M_PI;
00103 double phi2 = phi1+radius*(pred_tmp2.v()-pred_tmp1.v());
00104
00105 if (ip.empty()) {
00106 Range r1(phi1*radius-theTolerance, phi1*radius+theTolerance);
00107 Range r2(phi2*radius-theTolerance, phi2*radius+theTolerance);
00108 predRPhi = r1.intersection(r2);
00109 } else {
00110 Range r(phi1, phi2);
00111 r.sort();
00112 predRPhi= Range(radius*r.min()-theTolerance, radius*r.max()+theTolerance);
00113 }
00114
00115 return predRPhi;
00116 }
00117
00118
00119 ThirdHitPredictionFromInvParabola::Range ThirdHitPredictionFromInvParabola::rangeRPhiSlow(
00120 double radius, int charge, int nIter) const
00121 {
00122 Range predRPhi(1.,-1.);
00123
00124 double invr2 = 1/radius/radius;
00125 double u = sqrt(invr2);
00126 double v = 0.;
00127
00128 Range ip = (charge > 0) ? theIpRangePlus : theIpRangeMinus;
00129
00130 for (int i=0; i < nIter; ++i) {
00131 v = predV(u, ip.min(), charge);
00132 double d2 = invr2-sqr(v);
00133 u = (d2 > 0) ? sqrt(d2) : 0.;
00134 }
00135 PointUV pred_tmp1(u, v, &theRotation);
00136 double phi1 = pred_tmp1.unmap().phi();
00137 while ( phi1 >= M_PI) phi1 -= 2*M_PI;
00138 while ( phi1 < -M_PI) phi1 += 2*M_PI;
00139
00140
00141 u = sqrt(invr2);
00142 v=0;
00143 for (int i=0; i < nIter; ++i) {
00144 v = predV(u, ip.max(), charge);
00145 double d2 = invr2-sqr(v);
00146 u = (d2 > 0) ? sqrt(d2) : 0.;
00147 }
00148 PointUV pred_tmp2(u, v, &theRotation);
00149 double phi2 = pred_tmp2.unmap().phi();
00150 while ( phi2-phi1 >= M_PI) phi2 -= 2*M_PI;
00151 while ( phi2-phi1 < -M_PI) phi2 += 2*M_PI;
00152
00153
00154
00155
00156 if (ip.empty()) {
00157 Range r1(phi1*radius-theTolerance, phi1*radius+theTolerance);
00158 Range r2(phi2*radius-theTolerance, phi2*radius+theTolerance);
00159 predRPhi = r1.intersection(r2);
00160 } else {
00161 Range r(phi1, phi2);
00162 r.sort();
00163 predRPhi= Range(radius*r.min()-theTolerance, radius*r.max()+theTolerance);
00164 }
00165 return predRPhi;
00166
00167 }
00168
00169
00170 double ThirdHitPredictionFromInvParabola::
00171 predV( double u, double ip, int charge) const
00172 {
00173 return -charge*( coeffA(ip,charge) - coeffB(ip,charge)*u - ip*sqr(u));
00174 }