00001 #include "RecoPixelVertexing/PixelTrackFitting/interface/PixelFitterByHelixProjections.h"
00002 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00003
00004 #include "FWCore/Framework/interface/EventSetup.h"
00005 #include "FWCore/Framework/interface/ESHandle.h"
00006 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00007 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00008
00009 #include "DataFormats/GeometryVector/interface/LocalPoint.h"
00010 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00011 #include "DataFormats/GeometryCommonDetAlgo/interface/GlobalError.h"
00012
00013 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00014 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00015 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
00016
00017 #include "RecoTracker/TkMSParametrization/interface/PixelRecoUtilities.h"
00018
00019 #include "MagneticField/Engine/interface/MagneticField.h"
00020 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00021 #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHitBuilder.h"
00022 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
00023
00024 #include "CommonTools/Statistics/interface/LinearFit.h"
00025 #include "DataFormats/GeometryCommonDetAlgo/interface/Measurement1D.h"
00026
00027 #include "Geometry/CommonDetUnit/interface/GeomDetUnit.h"
00028 #include "Geometry/CommonDetUnit/interface/GeomDetType.h"
00029
00030 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00031
00032 #include "RZLine.h"
00033 #include "CircleFromThreePoints.h"
00034 #include "PixelTrackBuilder.h"
00035
00036 using namespace std;
00037
00038 PixelFitterByHelixProjections::PixelFitterByHelixProjections(
00039 const edm::ParameterSet& cfg)
00040 : theConfig(cfg), theTracker(0), theField(0), theTTRecHitBuilder(0) { }
00041
00042 reco::Track* PixelFitterByHelixProjections::run(
00043 const edm::EventSetup& es,
00044 const std::vector<const TrackingRecHit * > & hits,
00045 const TrackingRegion & region) const
00046 {
00047 int nhits = hits.size();
00048 if (nhits <2) return 0;
00049
00050 vector<GlobalPoint> points;
00051 vector<GlobalError> errors;
00052 vector<bool> isBarrel;
00053
00054 if (!theField || !theTracker || !theTTRecHitBuilder) {
00055
00056 edm::ESHandle<TrackerGeometry> trackerESH;
00057 es.get<TrackerDigiGeometryRecord>().get(trackerESH);
00058 theTracker = trackerESH.product();
00059
00060 edm::ESHandle<MagneticField> fieldESH;
00061 es.get<IdealMagneticFieldRecord>().get(fieldESH);
00062 theField = fieldESH.product();
00063
00064 edm::ESHandle<TransientTrackingRecHitBuilder> ttrhbESH;
00065
00066
00067 std::string builderName = theConfig.getParameter<std::string>("TTRHBuilder");
00068 es.get<TransientRecHitRecord>().get(builderName,ttrhbESH);
00069 theTTRecHitBuilder = ttrhbESH.product();
00070
00071 }
00072
00073 for ( vector<const TrackingRecHit*>::const_iterator ih = hits.begin(); ih != hits.end(); ih++) {
00074
00075
00076
00077
00078 TransientTrackingRecHit::RecHitPointer recHit = theTTRecHitBuilder->build(*ih);
00079 points.push_back( recHit->globalPosition());
00080 errors.push_back( recHit->globalPositionError());
00081 isBarrel.push_back( recHit->detUnit()->type().isBarrel() );
00082 }
00083
00084 CircleFromThreePoints circle = (nhits==2) ?
00085 CircleFromThreePoints( GlobalPoint(0.,0.,0.), points[0], points[1]) :
00086 CircleFromThreePoints(points[0],points[1],points[2]);
00087
00088 int charge = PixelFitterByHelixProjections::charge(points);
00089 float curvature = circle.curvature();
00090
00091 float invPt = PixelRecoUtilities::inversePt( circle.curvature(), es);
00092 float valPt = (invPt > 1.e-4) ? 1./invPt : 1.e4;
00093 float errPt = 0.055*valPt + 0.017*valPt*valPt;
00094
00095 CircleFromThreePoints::Vector2D center = circle.center();
00096 float valTip = charge * (center.mag()-1/curvature);
00097 float errTip = sqrt(errTip2(valPt, points.back().eta()));
00098
00099 float valPhi = PixelFitterByHelixProjections::phi(center.x(), center.y(), charge);
00100 float errPhi = 0.002;
00101
00102 float valZip = zip(valTip, curvature, points[0],points[1]);
00103 float errZip = sqrt(errZip2(valPt, points.back().eta()));
00104
00105 float valCotTheta = PixelFitterByHelixProjections::cotTheta(points[0],points[1]);
00106 float errCotTheta = 0.002;
00107
00108 float chi2 = 0;
00109 if (nhits > 2) {
00110 RZLine rzLine(points,errors,isBarrel);
00111 float cottheta, intercept, covss, covii, covsi;
00112 rzLine.fit(cottheta, intercept, covss, covii, covsi);
00113 chi2 = rzLine.chi2(cottheta, intercept);
00114 }
00115
00116 PixelTrackBuilder builder;
00117 Measurement1D pt(valPt, errPt);
00118 Measurement1D phi(valPhi, errPhi);
00119 Measurement1D cotTheta(valCotTheta, errCotTheta);
00120 Measurement1D tip(valTip, errTip);
00121 Measurement1D zip(valZip, errZip);
00122
00123 return builder.build(pt, phi, cotTheta, tip, zip, chi2, charge, hits, theField);
00124 }
00125
00126 int PixelFitterByHelixProjections::charge(const vector<GlobalPoint> & points) const
00127 {
00128 GlobalVector v21 = points[1]-points[0];
00129 GlobalVector v32 = points[2]-points[1];
00130 float dphi = v32.phi() - v21.phi();
00131 while (dphi > M_PI) dphi -= 2*M_PI;
00132 while (dphi < -M_PI) dphi += 2*M_PI;
00133 return (dphi > 0) ? -1 : 1;
00134 }
00135
00136 float PixelFitterByHelixProjections::cotTheta(
00137 const GlobalPoint& inner, const GlobalPoint& outer) const
00138 {
00139 float dr = outer.perp()-inner.perp();
00140 float dz = outer.z()-inner.z();
00141 return (fabs(dr) > 1.e-3) ? dz/dr : 0;
00142 }
00143
00144 float PixelFitterByHelixProjections::phi(float xC, float yC, int charge) const{
00145 float phiC = 0.;
00146
00147 if (charge>0) phiC = atan2(xC,-yC);
00148 else phiC = atan2(-xC,yC);
00149
00150 return phiC;
00151 }
00152
00153 float PixelFitterByHelixProjections::zip(float d0, float curv,
00154 const GlobalPoint& pinner, const GlobalPoint& pouter) const
00155 {
00156
00157 float rho3 = curv*curv*curv;
00158 float r1 = pinner.perp();
00159 double phi1 = r1*curv/2 + pinner.perp2()*r1*rho3/48.;
00160 float r2 = pouter.perp();
00161 double phi2 = r2*curv/2 + pouter.perp2()*r2*rho3/48.;
00162 double z1 = pinner.z();
00163 double z2 = pouter.z();
00164
00165 return z1 - phi1/(phi1-phi2)*(z1-z2);
00166 }
00167
00168
00169 double PixelFitterByHelixProjections::errZip2( float apt, float eta) const
00170 {
00171 double ziperr=0;
00172 float pt = (apt <= 10.) ? apt: 10.;
00173 double p1=0, p2=0,p3=0,p4=0;
00174 float feta = fabs(eta);
00175 if (feta<=0.8){
00176 p1 = 0.12676e-1;
00177 p2 = -0.22411e-2;
00178 p3 = 0.2987e-3;
00179 p4 = -0.12779e-4;
00180 } else if (feta <=1.6){
00181 p1 = 0.24047e-1;
00182 p2 = -0.66935e-2;
00183 p3 = 0.88111e-3;
00184 p4 = -0.38482e-4;
00185 } else {
00186 p1 = 0.56084e-1;
00187 p2 = -0.13960e-1;
00188 p3 = 0.15744e-2;
00189 p4 = -0.60757e-4;
00190 }
00191 ziperr = p1 + p2*pt + p3*pt*pt +p4*pt*pt*pt;
00192 return ziperr*ziperr;
00193 }
00194
00195 double PixelFitterByHelixProjections::errTip2(float apt, float eta) const
00196 {
00197 float pt = (apt <= 10.) ? apt : 10.;
00198 double p1=0, p2=0;
00199 float feta = fabs(eta);
00200 if (feta<=0.8)
00201 {
00202 p1=5.9e-3;
00203 p2=4.7e-3;
00204 }
00205 else if (feta <=1.6){
00206 p1 = 4.9e-3;
00207 p2 = 7.1e-3;
00208 }
00209 else {
00210 p1 = 6.4e-3;
00211 p2 = 1.0e-2;
00212 }
00213 float err=0;
00214 if (pt != 0) err = (p1 + p2/pt);
00215 return err*err;
00216 }
00217
00218