00001
00002 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00003 #include "DataFormats/GeometrySurface/interface/Surface.h"
00004 #include "Alignment/ReferenceTrajectories/interface/TwoBodyDecayTrajectory.h"
00005 #include "DataFormats/CLHEP/interface/AlgebraicObjects.h"
00006 #include "DataFormats/Math/interface/Error.h"
00007
00008 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00009
00010
00011 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00012
00013
00014 TwoBodyDecayTrajectory::TwoBodyDecayTrajectory( const TwoBodyDecayTrajectoryState& trajectoryState,
00015 const ConstRecHitCollection & recHits,
00016 const MagneticField* magField,
00017 MaterialEffects materialEffects,
00018 PropagationDirection propDir,
00019 bool hitsAreReverse,
00020 bool useRefittedState,
00021 bool constructTsosWithErrors )
00022
00023 : ReferenceTrajectoryBase( TwoBodyDecayParameters::dimension, recHits.first.size() + recHits.second.size() )
00024 {
00025 if ( hitsAreReverse )
00026 {
00027 TransientTrackingRecHit::ConstRecHitContainer::const_reverse_iterator itRecHits;
00028 ConstRecHitCollection fwdRecHits;
00029
00030 fwdRecHits.first.reserve( recHits.first.size() );
00031 for ( itRecHits = recHits.first.rbegin(); itRecHits != recHits.first.rend(); ++itRecHits )
00032 {
00033 fwdRecHits.first.push_back( *itRecHits );
00034 }
00035
00036 fwdRecHits.second.reserve( recHits.second.size() );
00037 for ( itRecHits = recHits.second.rbegin(); itRecHits != recHits.second.rend(); ++itRecHits )
00038 {
00039 fwdRecHits.second.push_back( *itRecHits );
00040 }
00041
00042 theValidityFlag = this->construct( trajectoryState, fwdRecHits, magField, materialEffects, propDir,
00043 useRefittedState, constructTsosWithErrors );
00044 }
00045 else
00046 {
00047 theValidityFlag = this->construct( trajectoryState, recHits, magField, materialEffects, propDir,
00048 useRefittedState, constructTsosWithErrors );
00049 }
00050 }
00051
00052
00053 TwoBodyDecayTrajectory::TwoBodyDecayTrajectory( void )
00054 : ReferenceTrajectoryBase( 0, 0 )
00055 {}
00056
00057
00058 bool TwoBodyDecayTrajectory::construct( const TwoBodyDecayTrajectoryState& state,
00059 const ConstRecHitCollection& recHits,
00060 const MagneticField* field,
00061 MaterialEffects materialEffects,
00062 PropagationDirection propDir,
00063 bool useRefittedState,
00064 bool constructTsosWithErrors )
00065 {
00066 const TwoBodyDecayTrajectoryState::TsosContainer& tsos = state.trajectoryStates( useRefittedState );
00067 const TwoBodyDecayTrajectoryState::Derivatives& deriv = state.derivatives();
00068 double mass = state.particleMass();
00069
00070
00071
00072
00073
00074
00075 ReferenceTrajectory trajectory1( tsos.first, recHits.first, false, field, materialEffects, propDir, mass );
00076
00077
00078 if ( !trajectory1.isValid() ) return false;
00079
00080
00081 AlgebraicMatrix fullDeriv1 = trajectory1.derivatives()*deriv.first;
00082
00083
00084
00085
00086
00087 ReferenceTrajectory trajectory2( tsos.second, recHits.second, false, field, materialEffects, propDir, mass );
00088
00089 if ( !trajectory2.isValid() ) return false;
00090
00091 AlgebraicMatrix fullDeriv2 = trajectory2.derivatives()*deriv.second;
00092
00093
00094
00095
00096
00097 theNumberOfRecHits.first = recHits.first.size();
00098 theNumberOfRecHits.second = recHits.second.size();
00099
00100 int nMeasurements1 = nMeasPerHit*theNumberOfRecHits.first;
00101
00102
00103
00104 theDerivatives.sub( 1, 1, fullDeriv1 );
00105 theDerivatives.sub( nMeasurements1 + 1, 1, fullDeriv2 );
00106
00107 theMeasurements.sub( 1, trajectory1.measurements() );
00108 theMeasurements.sub( nMeasurements1 + 1, trajectory2.measurements() );
00109
00110 theMeasurementsCov.sub( 1, trajectory1.measurementErrors() );
00111 theMeasurementsCov.sub( nMeasurements1 + 1, trajectory2.measurementErrors() );
00112
00113 theTrajectoryPositions.sub( 1, trajectory1.trajectoryPositions() );
00114 theTrajectoryPositions.sub( nMeasurements1 + 1, trajectory2.trajectoryPositions() );
00115
00116 theTrajectoryPositionCov = state.decayParameters().covariance().similarity( theDerivatives );
00117
00118 theParameters = state.decayParameters().parameters();
00119
00120 theRecHits.insert( theRecHits.end(), recHits.first.begin(), recHits.first.end() );
00121 theRecHits.insert( theRecHits.end(), recHits.second.begin(), recHits.second.end() );
00122
00123 if ( constructTsosWithErrors )
00124 {
00125 constructTsosVecWithErrors( trajectory1, trajectory2, field );
00126 }
00127 else
00128 {
00129 theTsosVec.insert( theTsosVec.end(),
00130 trajectory1.trajectoryStates().begin(),
00131 trajectory1.trajectoryStates().end() );
00132
00133 theTsosVec.insert( theTsosVec.end(),
00134 trajectory2.trajectoryStates().begin(),
00135 trajectory2.trajectoryStates().end() );
00136 }
00137
00138 return true;
00139 }
00140
00141
00142 void TwoBodyDecayTrajectory::constructTsosVecWithErrors( const ReferenceTrajectory& traj1,
00143 const ReferenceTrajectory& traj2,
00144 const MagneticField* field )
00145 {
00146 int iTsos = 0;
00147
00148 std::vector< TrajectoryStateOnSurface >::const_iterator itTsos;
00149
00150 for ( itTsos = traj1.trajectoryStates().begin(); itTsos != traj1.trajectoryStates().end(); itTsos++ )
00151 {
00152 constructSingleTsosWithErrors( *itTsos, iTsos, field );
00153 iTsos++;
00154 }
00155
00156 for ( itTsos = traj2.trajectoryStates().begin(); itTsos != traj2.trajectoryStates().end(); itTsos++ )
00157 {
00158 constructSingleTsosWithErrors( *itTsos, iTsos, field );
00159 iTsos++;
00160 }
00161 }
00162
00163
00164 void TwoBodyDecayTrajectory::constructSingleTsosWithErrors( const TrajectoryStateOnSurface& tsos,
00165 int iTsos,
00166 const MagneticField* field )
00167 {
00168 AlgebraicSymMatrix localErrors( 5, 0 );
00169 const double coeff = 1e-2;
00170
00171 double invP = tsos.localParameters().signedInverseMomentum();
00172 LocalVector p = tsos.localParameters().momentum();
00173
00174
00175
00176 float dpinv = coeff*( fabs(p.x()) + fabs(p.y()) + fabs(p.z()) )*invP*invP;
00177 float dxdir = coeff*( fabs(p.x()) + fabs(p.z()) )/p.z()/p.z();
00178 float dydir = coeff*( fabs(p.y()) + fabs(p.z()) )/p.z()/p.z();
00179 localErrors[0][0] = dpinv*dpinv;
00180 localErrors[1][1] = dxdir*dxdir;
00181 localErrors[2][2] = dydir*dydir;
00182
00183
00184 localErrors[3][3] = theTrajectoryPositionCov[nMeasPerHit*iTsos][nMeasPerHit*iTsos];
00185 localErrors[3][4] = theTrajectoryPositionCov[nMeasPerHit*iTsos][nMeasPerHit*iTsos+1];
00186 localErrors[4][4] = theTrajectoryPositionCov[nMeasPerHit*iTsos+1][nMeasPerHit*iTsos+1];
00187
00188
00189 theTsosVec[iTsos] = TrajectoryStateOnSurface( tsos.localParameters(),
00190 LocalTrajectoryError( localErrors ),
00191 tsos.surface(),
00192 field,
00193 tsos.surfaceSide() );
00194 }