CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoPixelVertexing/PixelTriplets/plugins/ThirdHitPredictionFromInvParabola.cc

Go to the documentation of this file.
00001 
00002 #include "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 using namespace std;
00019 
00020 ThirdHitPredictionFromInvParabola::ThirdHitPredictionFromInvParabola( 
00021     const GlobalPoint& P1, const GlobalPoint& P2,Scalar ip, Scalar curv, Scalar tolerance)
00022   : theTolerance(tolerance)
00023 {
00024   init(P1,P2,ip,std::abs(curv));
00025 }
00026 
00027 
00028 void ThirdHitPredictionFromInvParabola:: init(Scalar x1,Scalar y1, Scalar x2,Scalar y2,  Scalar ip, Scalar curv) {
00029 //  GlobalVector aX = GlobalVector( P2.x()-P1.x(), P2.y()-P1.y(), 0.).unit();
00030  
00031   Point2D p1(x1,y1);
00032   Point2D p2(x2,y2);
00033   theRotation = Rotation(p1);
00034   p1 = transform(p1);  // (1./P1.xy().mag(),0); 
00035   p2 = transform(p2);
00036 
00037  
00038   u1u2 = p1.x()*p2.x();
00039   overDu = 1./(p2.x() - p1.x());
00040   pv = p1.y()*p2.x() - p2.y()*p1.x();
00041   dv = p2.y() - p1.y();
00042   su = p2.x() + p1.x();
00043 
00044   RangeD ipRange(-ip, ip); 
00045   ipRange.sort();
00046   
00047   Scalar ipIntyPlus = ipFromCurvature(0.,true);
00048   Scalar ipCurvPlus = ipFromCurvature(curv, true);
00049   Scalar ipCurvMinus = ipFromCurvature(curv, false);
00050 
00051   
00052   RangeD ipRangePlus(ipIntyPlus, ipCurvPlus); ipRangePlus.sort();
00053   RangeD ipRangeMinus(-ipIntyPlus, ipCurvMinus); ipRangeMinus.sort();
00054 
00055   theIpRangePlus  = ipRangePlus.intersection(ipRange);
00056   theIpRangeMinus = ipRangeMinus.intersection(ipRange);
00057 }
00058     
00059 
00060 
00061 ThirdHitPredictionFromInvParabola::Range 
00062 ThirdHitPredictionFromInvParabola::rangeRPhi(Scalar radius, int icharge) const
00063 {
00064   bool pos =  icharge>0;
00065 
00066   RangeD ip = (pos) ? theIpRangePlus : theIpRangeMinus;
00067 
00068 
00069   //  it will vectorize with gcc 4.7 (with -O3 -fno-math-errno)
00070   // change sign as intersect assume -ip for negative charge...
00071   Scalar ipv[2]={(pos)? ip.min() : -ip.min() ,(pos)? ip.max() : -ip.max()};
00072   Scalar u[2], v[2];
00073   for (int i=0; i!=2; ++i)
00074     findPointAtCurve(radius,ipv[i],u[i],v[i]);
00075 
00076   // 
00077   Scalar phi1 = theRotation.rotateBack(Point2D(u[0],v[0])).barePhi();
00078   Scalar phi2 = phi1+(v[1]-v[0]); 
00079   
00080   if (ip.empty()) {
00081     Range r1(phi1*radius-theTolerance, phi1*radius+theTolerance); 
00082     Range r2(phi2*radius-theTolerance, phi2*radius+theTolerance); 
00083     return r1.intersection(r2);
00084   }
00085 
00086   if (phi2<phi1) std::swap(phi1, phi2); 
00087   return Range(radius*phi1-theTolerance, radius*phi2+theTolerance);
00088   
00089 }
00090 
00091 /*
00092 ThirdHitPredictionFromInvParabola::Range ThirdHitPredictionFromInvParabola::rangeRPhiSlow(
00093     Scalar radius, int charge, int nIter) const
00094 {
00095   Range predRPhi(1.,-1.);
00096 
00097   Scalar invr2 = 1/(radius*radius);
00098   Scalar u = sqrt(invr2);
00099   Scalar v = 0.;
00100 
00101   Range ip = (charge > 0) ? theIpRangePlus : theIpRangeMinus;
00102 
00103   for (int i=0; i < nIter; ++i) {
00104     v = predV(u, charge*ip.min()); 
00105     Scalar d2 = invr2-sqr(v);
00106     u = (d2 > 0) ? sqrt(d2) : 0.;
00107   }
00108   Point2D  pred_tmp1(u, v);
00109   Scalar phi1 = transformBack(pred_tmp1).phi(); 
00110   while ( phi1 >= M_PI) phi1 -= 2*M_PI;
00111   while ( phi1 < -M_PI) phi1 += 2*M_PI;
00112 
00113 
00114   u = sqrt(invr2); 
00115   v=0;
00116   for (int i=0; i < nIter; ++i) {
00117     v = predV(u, ip.max(), charge); 
00118     Scalar d2 = invr2-sqr(v);
00119     u = (d2 > 0) ? sqrt(d2) : 0.;
00120   }
00121   Point2D  pred_tmp2(u, v);
00122   Scalar phi2 = transformBack(pred_tmp2).phi(); 
00123   while ( phi2-phi1 >= M_PI) phi2 -= 2*M_PI;
00124   while ( phi2-phi1 < -M_PI) phi2 += 2*M_PI;
00125 
00126 // check faster alternative, without while(..) it is enough to:
00127 //  phi2 = phi1+radius*(pred_tmp2.v()-pred_tmp1.v()); 
00128 
00129   if (ip.empty()) {
00130     Range r1(phi1*radius-theTolerance, phi1*radius+theTolerance); 
00131     Range r2(phi2*radius-theTolerance, phi2*radius+theTolerance); 
00132     predRPhi = r1.intersection(r2);
00133   } else {
00134     Range r(phi1, phi2); 
00135     r.sort();
00136     predRPhi= Range(radius*r.min()-theTolerance, radius*r.max()+theTolerance);
00137   }
00138   return predRPhi;
00139 
00140 }
00141 */
00142