00001 #include <cmath> 00002 00003 #include <Math/SMatrix.h> 00004 #include <Math/MatrixFunctions.h> 00005 00006 #include "DataFormats/GeometryVector/interface/GlobalPoint.h" 00007 #include "DataFormats/GeometryVector/interface/GlobalVector.h" 00008 #include "DataFormats/GeometryCommonDetAlgo/interface/GlobalError.h" 00009 #include "DataFormats/TrackReco/interface/Track.h" 00010 00011 #include "TrackingTools/TrajectoryParametrization/interface/CurvilinearTrajectoryParameters.h" 00012 #include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h" 00013 #include "TrackingTools/TrajectoryParametrization/interface/CurvilinearTrajectoryError.h" 00014 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h" 00015 00016 #include "RecoVertex/GhostTrackFitter/interface/GhostTrackPrediction.h" 00017 00018 using namespace reco; 00019 00020 namespace { 00021 static inline double sqr(double arg) { return arg * arg; } 00022 00023 using namespace ROOT::Math; 00024 00025 typedef SMatrix<double, 3, 4> Matrix34; 00026 typedef SMatrix<double, 4, 5> Matrix45; 00027 typedef SMatrix<double, 5, 4> Matrix54; 00028 typedef SMatrix<double, 4, 6> Matrix46; 00029 typedef SMatrix<double, 6, 4> Matrix64; 00030 typedef SMatrix<double, 6, 6, MatRepSym<double, 6> > Matrix6S; 00031 } 00032 00033 static GhostTrackPrediction::Vector convert( 00034 const CurvilinearTrajectoryParameters &trajectory) 00035 { 00036 return GhostTrackPrediction::Vector( 00037 trajectory.yT() / std::cos(trajectory.lambda()), 00038 trajectory.xT(), 00039 std::tan(trajectory.lambda()), 00040 trajectory.phi()); 00041 } 00042 00043 static inline GhostTrackPrediction::Vector convert( 00044 const GlobalTrajectoryParameters &trajectory) 00045 { 00046 return convert(CurvilinearTrajectoryParameters( 00047 trajectory.position(), trajectory.momentum(), 0)); 00048 } 00049 00050 static GhostTrackPrediction::Error convert( 00051 const GhostTrackPrediction::Vector &pred, 00052 const CurvilinearTrajectoryError &error) 00053 { 00054 using namespace ROOT::Math; 00055 00056 double rho2 = pred[2] * pred[2] + 1.; 00057 double rho = std::sqrt(rho2); 00058 00059 Matrix45 jacobian; 00060 jacobian(0, 1) = pred[0] * pred[2]; 00061 jacobian(0, 4) = rho; 00062 jacobian(1, 3) = 1.; 00063 jacobian(2, 1) = rho2; 00064 jacobian(3, 2) = 1.; 00065 00066 return Similarity(jacobian, error.matrix()); 00067 } 00068 00069 void GhostTrackPrediction::init( 00070 const GlobalPoint &priorPosition, 00071 const GlobalError &priorError, 00072 const GlobalVector &direction, 00073 const GlobalError &directionError) 00074 { 00075 using namespace ROOT::Math; 00076 00077 double perp2 = direction.perp2(); 00078 GlobalVector dir = direction / std::sqrt(perp2); 00079 double tip = priorPosition.y() * dir.x() - priorPosition.x() * dir.y(); 00080 double l = priorPosition.x() * dir.x() + priorPosition.y() * dir.y(); 00081 00082 prediction_[0] = priorPosition.z() - dir.z() * l; 00083 prediction_[1] = tip; 00084 prediction_[2] = dir.z(); 00085 prediction_[3] = dir.phi(); 00086 00087 Matrix46 jacobian; 00088 jacobian(0, 0) = -dir.x() * dir.z(); 00089 jacobian(1, 0) = -dir.y(); 00090 jacobian(0, 1) = -dir.y() * dir.z(); 00091 jacobian(1, 1) = dir.x(); 00092 jacobian(0, 2) = 1.; 00093 jacobian(0, 3) = -dir.z() * priorPosition.x(); 00094 jacobian(1, 3) = priorPosition.y(); 00095 jacobian(3, 3) = -dir.y(); 00096 jacobian(0, 4) = -dir.z() * priorPosition.y(); 00097 jacobian(1, 4) = -priorPosition.x(); 00098 jacobian(3, 4) = dir.x(); 00099 jacobian(0, 5) = -l; 00100 jacobian(2, 5) = 1.; 00101 00102 Matrix6S origCov; 00103 origCov.Place_at(priorError.matrix_new(), 0, 0); 00104 origCov.Place_at(directionError.matrix_new() / perp2, 3, 3); 00105 00106 covariance_ = Similarity(jacobian, origCov); 00107 } 00108 00109 GhostTrackPrediction::GhostTrackPrediction( 00110 const GlobalPoint &priorPosition, 00111 const GlobalError &priorError, 00112 const GlobalVector &direction, 00113 double coneRadius) 00114 { 00115 double dTheta = std::cosh((double)direction.eta()) * coneRadius; 00116 00117 double r2 = direction.mag2(); 00118 double r = std::sqrt(r2); 00119 double perp = direction.perp(); 00120 double P = direction.x() / perp; 00121 double p = direction.y() / perp; 00122 double T = direction.z() / r; 00123 double t = perp / r; 00124 double h2 = dTheta * dTheta; 00125 double d2 = coneRadius * coneRadius; 00126 00127 GlobalError cov(r2 * (T*T * P*P * h2 + t*t * p*p * d2), 00128 r2 * p*P * (T*T * h2 - t*t * d2), 00129 r2 * (T*T * p*p * h2 + t*t * P*P * d2), 00130 -r2 * t*T * P * h2, 00131 -r2 * t*T * p * h2, 00132 r2 * t*t * h2); 00133 00134 init(priorPosition, priorError, direction, cov); 00135 } 00136 00137 GhostTrackPrediction::GhostTrackPrediction( 00138 const CurvilinearTrajectoryParameters &trajectory, 00139 const CurvilinearTrajectoryError &error) : 00140 prediction_(convert(trajectory)), 00141 covariance_(convert(prediction_, error)) 00142 { 00143 } 00144 00145 GhostTrackPrediction::GhostTrackPrediction( 00146 const GlobalTrajectoryParameters &trajectory, 00147 const CurvilinearTrajectoryError &error) : 00148 prediction_(convert(trajectory)), 00149 covariance_(convert(prediction_, error)) 00150 { 00151 } 00152 00153 GhostTrackPrediction::GhostTrackPrediction(const Track &track) : 00154 prediction_(convert( 00155 GlobalTrajectoryParameters( 00156 GlobalPoint(track.vx(), track.vy(), track.vz()), 00157 GlobalVector(track.px(), track.py(), track.pz()), 00158 0, 0))), 00159 covariance_(convert(prediction_, track.covariance())) 00160 { 00161 } 00162 00163 GlobalError GhostTrackPrediction::positionError(double lambda) const 00164 { 00165 using namespace ROOT::Math; 00166 00167 double x = std::cos(phi()); 00168 double y = std::sin(phi()); 00169 00170 Matrix34 jacobian; 00171 jacobian(0, 1) = -y; 00172 jacobian(0, 3) = -y * lambda - x * ip(); 00173 jacobian(1, 1) = x; 00174 jacobian(1, 3) = x * lambda - y * ip(); 00175 jacobian(2, 0) = 1.; 00176 jacobian(2, 2) = lambda; 00177 00178 return Similarity(jacobian, covariance()); 00179 } 00180 00181 Matrix6S GhostTrackPrediction::cartesianError(double lambda) const 00182 { 00183 using namespace ROOT::Math; 00184 00185 double x = std::cos(phi()); 00186 double y = std::sin(phi()); 00187 00188 Matrix64 jacobian; 00189 jacobian(0, 1) = -y; 00190 jacobian(0, 3) = -y * lambda - x * ip(); 00191 jacobian(1, 1) = x; 00192 jacobian(1, 3) = x * lambda - y * ip(); 00193 jacobian(2, 0) = 1.; 00194 jacobian(2, 2) = lambda; 00195 jacobian(3, 3) = -y; 00196 jacobian(4, 3) = x; 00197 jacobian(5, 2) = 1.; 00198 00199 return Similarity(jacobian, covariance()); 00200 } 00201 00202 CurvilinearTrajectoryParameters 00203 GhostTrackPrediction::curvilinearTrajectory() const 00204 { 00205 return CurvilinearTrajectoryParameters(0., std::atan(cotTheta()), 00206 phi(), ip(), sz(), false); 00207 } 00208 00209 GlobalTrajectoryParameters GhostTrackPrediction::globalTrajectory( 00210 const MagneticField *fieldProvider) const 00211 { 00212 return GlobalTrajectoryParameters(origin(), direction(), 00213 0, fieldProvider); 00214 } 00215 00216 CurvilinearTrajectoryError GhostTrackPrediction::curvilinearError() const 00217 { 00218 double rho2I = 1. / rho2(); 00219 double rhoI = std::sqrt(rho2I); 00220 00221 Matrix54 jacobian; 00222 jacobian(1, 2) = rho2I; 00223 jacobian(2, 3) = 1.; 00224 jacobian(3, 1) = 1.; 00225 jacobian(4, 0) = rhoI; 00226 jacobian(4, 2) = - z() * rhoI * cotTheta() * rho2I; 00227 00228 AlgebraicSymMatrix55 err = Similarity(jacobian, covariance()); 00229 err(0, 0) = 1.; 00230 00231 return CurvilinearTrajectoryError(err); 00232 } 00233 00234 FreeTrajectoryState GhostTrackPrediction::fts( 00235 const MagneticField *fieldProvider) const 00236 { 00237 return FreeTrajectoryState(globalTrajectory(fieldProvider), 00238 curvilinearError()); 00239 } 00240 00241 Track GhostTrackPrediction::track(double ndof, double chi2) const 00242 { 00243 GlobalPoint origin = this->origin(); 00244 GlobalVector dir = direction().unit(); 00245 00246 Track::Point point(origin.x(), origin.y(), origin.z()); 00247 Track::Vector vector(dir.x(), dir.y(), dir.z()); 00248 00249 return Track(chi2, ndof, point, vector, 0, curvilinearError()); 00250 }