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