CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/RecoBTag/BTagTools/src/SignedImpactParameter3D.cc

Go to the documentation of this file.
00001 #include "DataFormats/GeometrySurface/interface/Line.h"
00002 
00003 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00004 #include "TrackingTools/GeomPropagators/interface/AnalyticalTrajectoryExtrapolatorToLine.h"
00005 #include "DataFormats/GeometryCommonDetAlgo/interface/Measurement1D.h"
00006 #include "RecoBTag/BTagTools/interface/SignedImpactParameter3D.h"
00007 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00008 
00009 #include "CLHEP/Vector/ThreeVector.h"
00010 #include "CLHEP/Vector/LorentzVector.h"
00011 #include "CLHEP/Matrix/Vector.h"
00012 #include <string>
00013 
00014 using namespace std;
00015 using namespace reco;
00016 
00017 pair<bool,Measurement1D> SignedImpactParameter3D::apply(const TransientTrack & transientTrack, 
00018                  const GlobalVector & direction, const  Vertex & vertex)
00019  const {
00020 
00021   double theValue=0.;
00022   double theError=0.;
00023   bool   theIsValid=false;
00024 
00025   TrajectoryStateOnSurface TSOS = transientTrack.impactPointState();
00026   
00027   if ( !TSOS.isValid() ) {
00028     cout << "====>>>> SignedImpactParameter3D::apply : TSOS not valid = " << TSOS.isValid() << endl ;
00029     return pair<bool,Measurement1D>(theIsValid,Measurement1D(0.,0.)) ;
00030    }
00031   
00032   FreeTrajectoryState * FTS = TSOS.freeTrajectoryState();
00033 
00034   GlobalVector JetDirection(direction);
00035   
00036   TrajectoryStateOnSurface theTSOS = closestApproachToJet(*FTS, vertex, JetDirection,transientTrack.field());
00037   theIsValid= theTSOS.isValid();
00038 
00039   if(theIsValid){
00040     
00041     GlobalVector D = distance(theTSOS, vertex, JetDirection);
00042     GlobalVector J = JetDirection.unit();
00043     GlobalPoint vertexPosition(vertex.x(),vertex.y(),vertex.z());
00044     double theDistanceAlongJetAxis = J.dot(theTSOS.globalPosition()-vertexPosition);
00045     theValue = D.mag()*(theDistanceAlongJetAxis/abs(theDistanceAlongJetAxis));
00046 
00047 
00048     GlobalVector DD = D.unit();
00049     GlobalPoint T0 = theTSOS.globalPosition();
00050     GlobalVector T1 = theTSOS.globalMomentum(); 
00051     GlobalVector TT1 = T1.unit();
00052     GlobalVector Xi(T0.x()-vertex.position().x(),T0.y()-vertex.position().y(),T0.z()-vertex.position().z());
00053 
00054     
00055     AlgebraicVector6 deriv;
00056     AlgebraicVector3 deriv_v;
00057     
00058     deriv_v[0] = - DD.x();
00059     deriv_v[1] = - DD.y();
00060     deriv_v[2] = - DD.z();
00061 
00062     deriv[0] = DD.x();
00063     deriv[1] = DD.y();
00064     deriv[2] = DD.z();
00065     deriv[3] =  - (TT1.dot(Xi)*DD.x())/T1.mag();
00066     deriv[4] =  - (TT1.dot(Xi)*DD.y())/T1.mag();
00067     deriv[5] =  - (TT1.dot(Xi)*DD.z())/T1.mag();
00068 
00069     double E1 = ROOT::Math::Similarity(deriv , theTSOS.cartesianError().matrix());
00070     double E2 = ROOT::Math::Similarity(deriv_v , vertex.covariance());
00071 //    double E2 = RecoVertex::convertError(vertex.covariance()).matrix().similarity(deriv_v);
00072 //    double E2 = 0.; // no vertex error because of stupid use of hundreds of different types for same thing 
00073     theError = sqrt(E1+E2);
00074 
00075     Measurement1D A(theValue, theError);
00076 
00077     return pair<bool,Measurement1D>(theIsValid,A);
00078   }
00079   else {
00080     return pair<bool,Measurement1D>(theIsValid,Measurement1D(0.,0.));
00081   }// endif (isValid)
00082 }
00083 
00084 
00085 
00086 TrajectoryStateOnSurface SignedImpactParameter3D::closestApproachToJet(const FreeTrajectoryState & aFTS,const Vertex & vertex, const GlobalVector& aJetDirection,const MagneticField * field) {
00087   
00088   GlobalVector J =aJetDirection.unit();
00089   
00090   Line::PositionType pos(GlobalPoint(vertex.x(),vertex.y(),vertex.z()));
00091   Line::DirectionType dir(J);
00092   Line Jet(pos,dir);
00093   
00094   AnalyticalTrajectoryExtrapolatorToLine TETL(field);
00095 
00096   return TETL.extrapolate(aFTS, Jet);
00097 }
00098 
00099 GlobalVector SignedImpactParameter3D::distance(const TrajectoryStateOnSurface & aTSOS, const Vertex & vertex, const GlobalVector & aJetDirection)  {
00100 
00101   Line::PositionType pos2(aTSOS.globalPosition());
00102   Line::DirectionType dir2((aTSOS.globalMomentum()).unit());
00103   Line T(pos2,dir2);
00104   
00105   GlobalPoint  X = GlobalPoint(vertex.x(),vertex.y(),vertex.z()); // aVertex.position();
00106 
00107   GlobalVector D = T.distance(X);
00108 
00109   return D;
00110 }
00111 
00112 pair<double,Measurement1D> SignedImpactParameter3D::distanceWithJetAxis(const TransientTrack & track, const GlobalVector & direction, const Vertex & vertex) {
00113   double theDistanceAlongJetAxis(0.);
00114   double theDistanceToJetAxis(0.);
00115   double  theLDist_err(0.);
00116   TrajectoryStateOnSurface TSOS = track.impactPointState();
00117 
00118   if ( !TSOS.isValid() ) {
00119     cout << "====>>>> SignedImpactParameter3D::distanceWithJetAxis : TSOS not valid = " << TSOS.isValid() << endl ;
00120     return pair<double,Measurement1D> (theDistanceAlongJetAxis,Measurement1D(theDistanceToJetAxis,theLDist_err));
00121   }
00122   
00123   FreeTrajectoryState * FTS = TSOS.freeTrajectoryState();
00124 
00125   GlobalVector jetDirection(direction);
00126 
00127   //
00128   // Check whether the track has been used in the vertex
00129   //
00130 
00131   //FIXME
00132   float weight=0.;//vertex.trackWeight(aRecTrack);
00133 
00134   TrajectoryStateOnSurface stateAtOrigin = track.impactPointState(); 
00135   TrajectoryStateOnSurface aTSOS = closestApproachToJet(*FTS, vertex, jetDirection, track.field());
00136   bool isValid= stateAtOrigin.isValid();
00137   //  bool IsValid= aTSOS.isValid();
00138 
00139   if(isValid){
00140     
00141     //get the Track line at origin
00142     Line::PositionType pos(stateAtOrigin.globalPosition());
00143     Line::DirectionType dir((stateAtOrigin.globalMomentum()).unit());
00144     Line track(pos,dir);
00145     // get the Jet  line 
00146    // Vertex vertex(vertex);
00147     GlobalVector jetVector = jetDirection.unit();    
00148     Line::PositionType pos2(GlobalPoint(vertex.x(),vertex.y(),vertex.z()));
00149     Line::DirectionType dir2(jetVector);
00150     Line jet(pos2,dir2);
00151     // now compute the distance between the two lines
00152     // If the track has been used to refit the Primary vertex then sign it positively, otherwise negative
00153 
00154     theDistanceToJetAxis = (jet.distance(track)).mag();
00155     if (weight<1) theDistanceToJetAxis= -theDistanceToJetAxis;
00156 
00157     // ... and the flight distance along the Jet axis.
00158     GlobalPoint  V = jet.position();    
00159     GlobalVector Q = dir - jetVector.dot(dir) * jetVector;
00160     GlobalVector P = jetVector - jetVector.dot(dir) * dir;
00161     theDistanceAlongJetAxis = P.dot(V-pos)/Q.dot(dir);
00162 
00163     //
00164     // get the covariance matrix of the vertex and compute the error on theDistanceToJetAxis
00165     //
00166     
00168 
00169     // build the vector of closest approach between lines
00170 
00171     GlobalVector H((jetVector.cross(dir).unit()));
00172     
00173     CLHEP::HepVector Hh(3);
00174     Hh[0] = H.x();
00175     Hh[1] = H.y();
00176     Hh[2] = H.z();
00177     
00178   //  theLDist_err = sqrt(vertexError.similarity(Hh));
00179 
00180     //    cout << "distance to jet axis : "<< theDistanceToJetAxis <<" and error : "<< theLDist_err<<endl;
00181     // Now the impact parameter ...
00182 
00183 /*    GlobalPoint T0 = track.position();
00184     GlobalVector D = (T0-V)- (T0-V).dot(dir) * dir;
00185     double IP = D.mag();    
00186     GlobalVector Dold = distance(aTSOS, aJet.vertex(), jetDirection);
00187     double IPold = Dold.mag();
00188 */
00189 
00190 
00191 
00192   }
00193   Measurement1D DTJA(theDistanceToJetAxis,theLDist_err);
00194   
00195   return pair<double,Measurement1D> (theDistanceAlongJetAxis,DTJA);
00196 }