00001 #include "RecoPixelVertexing/PixelLowPtUtilities/interface/TrackFitter.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 "RecoPixelVertexing/PixelTrackFitting/src/RZLine.h"
00033 #include "RecoPixelVertexing/PixelTrackFitting/src/CircleFromThreePoints.h"
00034 #include "RecoPixelVertexing/PixelTrackFitting/src/PixelTrackBuilder.h"
00035
00036 using namespace std;
00037
00038
00039 TrackFitter::TrackFitter
00040 (const edm::ParameterSet& cfg) :
00041 theConfig(cfg), theTracker(0), theField(0), theTTRecHitBuilder(0)
00042 {
00043 }
00044
00045
00046 reco::Track* TrackFitter::run
00047 (const edm::EventSetup& es,
00048 const std::vector<const TrackingRecHit *> & hits,
00049 const TrackingRegion & region) const
00050 {
00051 int nhits = hits.size();
00052 if(nhits <2) return 0;
00053
00054 vector<GlobalPoint> points;
00055 vector<GlobalError> errors;
00056 vector<bool> isBarrel;
00057
00058 if (!theField || !theTracker || !theTTRecHitBuilder)
00059 {
00060 edm::ESHandle<TrackerGeometry> trackerESH;
00061 es.get<TrackerDigiGeometryRecord>().get(trackerESH);
00062 theTracker = trackerESH.product();
00063
00064 edm::ESHandle<MagneticField> fieldESH;
00065 es.get<IdealMagneticFieldRecord>().get(fieldESH);
00066 theField = fieldESH.product();
00067
00068 edm::ESHandle<TransientTrackingRecHitBuilder> ttrhbESH;
00069 std::string builderName = theConfig.getParameter<std::string>("TTRHBuilder");
00070 es.get<TransientRecHitRecord>().get(builderName,ttrhbESH);
00071 theTTRecHitBuilder = ttrhbESH.product();
00072 }
00073
00074 for (vector<const TrackingRecHit*>::const_iterator ih = hits.begin();
00075 ih!= hits.end(); ih++)
00076 {
00077 TransientTrackingRecHit::RecHitPointer recHit =
00078 theTTRecHitBuilder->build(*ih);
00079
00080 points.push_back(recHit->globalPosition());
00081 errors.push_back(recHit->globalPositionError());
00082 isBarrel.push_back(recHit->detUnit()->type().isBarrel() );
00083 }
00084
00085 CircleFromThreePoints circle = (nhits==2) ?
00086 CircleFromThreePoints(GlobalPoint(0.,0.,0.), points[0], points[1]) :
00087 CircleFromThreePoints(points[0],points[1],points[2]);
00088
00089 int charge = getCharge(points);
00090 float curvature = circle.curvature();
00091
00092
00093 float invPt = PixelRecoUtilities::inversePt(curvature, es);
00094 float valPt = (invPt > 1.e-4) ? 1./invPt : 1.e4;
00095 float errPt = 0.055*valPt + 0.017*valPt*valPt;
00096
00097 CircleFromThreePoints::Vector2D center = circle.center();
00098
00099
00100 float valTip = charge * (center.mag()-1/curvature);
00101
00102 float valZip = getZip(valTip, curvature, points[0],points[1]);
00103
00104 float valPhi = getPhi(center.x(), center.y(), charge);
00105
00106 float valCotTheta =
00107 getCotThetaAndUpdateZip(points[0],points[1], 1/curvature,
00108 valPhi,valTip,valZip);
00109
00110
00111 float errTip, errZip;
00112 getErrTipAndErrZip(valPt, points.back().eta(), errTip,errZip);
00113 float errPhi = 0.002;
00114 float errCotTheta = 0.002;
00115
00116 float chi2 = 0;
00117 if(nhits > 2)
00118 {
00119 RZLine rzLine(points,errors,isBarrel);
00120 float cotTheta, intercept, covss, covii, covsi;
00121 rzLine.fit(cotTheta, intercept, covss, covii, covsi);
00122 chi2 = rzLine.chi2(cotTheta, intercept);
00123
00124 }
00125
00126
00127 PixelTrackBuilder builder;
00128
00129 Measurement1D pt (valPt, errPt);
00130 Measurement1D phi (valPhi, errPhi);
00131 Measurement1D cotTheta(valCotTheta, errCotTheta);
00132 Measurement1D tip (valTip, errTip);
00133 Measurement1D zip (valZip, errZip);
00134
00135 return builder.build(pt, phi, cotTheta, tip, zip, chi2,
00136 charge, hits, theField);
00137 }
00138
00139
00140 int TrackFitter::getCharge
00141 (const vector<GlobalPoint> & points) const
00142 {
00143 GlobalVector v21 = points[1]-points[0];
00144 GlobalVector v32 = points[2]-points[1];
00145 float dphi = v32.phi() - v21.phi();
00146 while (dphi > M_PI) dphi -= 2*M_PI;
00147 while (dphi < -M_PI) dphi += 2*M_PI;
00148 return (dphi > 0) ? -1 : 1;
00149 }
00150
00151
00152 float TrackFitter::getCotThetaAndUpdateZip
00153 (const GlobalPoint& inner, const GlobalPoint& outer,
00154 float radius, float phi, float d0, float& zip) const
00155 {
00156 float chi = phi - M_PI_2;
00157 GlobalPoint IP(d0*cos(chi), d0*sin(chi),zip);
00158
00159 float phi1 = 2*asin(0.5*(inner - IP).perp()/radius);
00160 float phi2 = 2*asin(0.5*(outer - IP).perp()/radius);
00161
00162 float dr = radius*(phi2 - phi1);
00163 float dz = outer.z()-inner.z();
00164
00165
00166 zip = (inner.z()*phi2 - outer.z()*phi1)/(phi2 - phi1);
00167
00168 return (fabs(dr) > 1.e-3) ? dz/dr : 0;
00169 }
00170
00171
00172 float TrackFitter::getPhi
00173 (float xC, float yC, int charge) const
00174 {
00175 float phiC;
00176
00177 if (charge>0) phiC = atan2(xC,-yC);
00178 else phiC = atan2(-xC,yC);
00179
00180 return phiC;
00181 }
00182
00183
00184 float TrackFitter::getZip
00185 (float d0, float curv,
00186 const GlobalPoint& inner, const GlobalPoint& outer) const
00187 {
00188
00189 float rho3 = curv*curv*curv;
00190
00191 float r1 = inner.perp();
00192 double phi1 = r1*curv/2 + inner.perp2()*r1*rho3/48.;
00193
00194 float r2 = outer.perp();
00195 double phi2 = r2*curv/2 + outer.perp2()*r2*rho3/48.;
00196
00197 double z1 = inner.z();
00198 double z2 = outer.z();
00199
00200 return z1 - phi1/(phi1-phi2)*(z1-z2);
00201 }
00202
00203
00204 void TrackFitter::getErrTipAndErrZip
00205 (float pt, float eta, float & errZip, float & errTip) const
00206 {
00207 float coshEta = cosh(eta);
00208
00209 {
00210 float c_ms = 0.0115;
00211 float s_le = 0.0123;
00212 float s_ms2 = c_ms*c_ms / (pt*pt) * coshEta;
00213
00214 errTip = sqrt(s_le*s_le + s_ms2 );
00215 }
00216
00217 {
00218 float c_ms = 0.0072;
00219 float s_le = 0.0115;
00220 float s_ms2 = c_ms*c_ms / (pt*pt) * coshEta;
00221
00222 errZip = sqrt(s_le*s_le + s_ms2 * coshEta*coshEta);
00223 }
00224 }
00225