00001 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00002
00003 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00004 #include "DataFormats/GeometrySurface/interface/Surface.h"
00005 #include "Alignment/ReferenceTrajectories/interface/TwoBodyDecayTrajectory.h"
00006 #include "DataFormats/CLHEP/interface/AlgebraicObjects.h"
00007 #include "DataFormats/Math/interface/Error.h"
00008 #include "Alignment/TwoBodyDecay/interface/TwoBodyDecayParameters.h"
00009
00010 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00011
00012
00013 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00014
00015 TwoBodyDecayTrajectory::TwoBodyDecayTrajectory( const TwoBodyDecayTrajectoryState& trajectoryState,
00016 const ConstRecHitCollection & recHits,
00017 const MagneticField* magField,
00018 MaterialEffects materialEffects,
00019 PropagationDirection propDir,
00020 bool hitsAreReverse,
00021 const reco::BeamSpot &beamSpot,
00022 bool useRefittedState,
00023 bool constructTsosWithErrors )
00024
00025 : ReferenceTrajectoryBase(
00026 TwoBodyDecayParameters::dimension, recHits.first.size() + recHits.second.size(),
00027 (materialEffects >= breakPoints) ? 2*(recHits.first.size() + recHits.second.size())-4 : 0,
00028 (materialEffects >= breakPoints) ? 2*(recHits.first.size() + recHits.second.size())-3 : 1 )
00029 {
00030 if ( hitsAreReverse )
00031 {
00032 TransientTrackingRecHit::ConstRecHitContainer::const_reverse_iterator itRecHits;
00033 ConstRecHitCollection fwdRecHits;
00034
00035 fwdRecHits.first.reserve( recHits.first.size() );
00036 for ( itRecHits = recHits.first.rbegin(); itRecHits != recHits.first.rend(); ++itRecHits )
00037 {
00038 fwdRecHits.first.push_back( *itRecHits );
00039 }
00040
00041 fwdRecHits.second.reserve( recHits.second.size() );
00042 for ( itRecHits = recHits.second.rbegin(); itRecHits != recHits.second.rend(); ++itRecHits )
00043 {
00044 fwdRecHits.second.push_back( *itRecHits );
00045 }
00046
00047 theValidityFlag = this->construct( trajectoryState, fwdRecHits, magField, materialEffects, propDir,
00048 beamSpot, useRefittedState, constructTsosWithErrors );
00049 }
00050 else
00051 {
00052 theValidityFlag = this->construct( trajectoryState, recHits, magField, materialEffects, propDir,
00053 beamSpot, useRefittedState, constructTsosWithErrors );
00054 }
00055 }
00056
00057
00058 TwoBodyDecayTrajectory::TwoBodyDecayTrajectory( void )
00059 : ReferenceTrajectoryBase( 0, 0, 0, 0)
00060 {}
00061
00062
00063 bool TwoBodyDecayTrajectory::construct( const TwoBodyDecayTrajectoryState& state,
00064 const ConstRecHitCollection& recHits,
00065 const MagneticField* field,
00066 MaterialEffects materialEffects,
00067 PropagationDirection propDir,
00068 const reco::BeamSpot &beamSpot,
00069 bool useRefittedState,
00070 bool constructTsosWithErrors )
00071 {
00072 const TwoBodyDecayTrajectoryState::TsosContainer& tsos = state.trajectoryStates( useRefittedState );
00073 const TwoBodyDecayTrajectoryState::Derivatives& deriv = state.derivatives();
00074 double mass = state.particleMass();
00075
00076
00077
00078
00079
00080
00081 ReferenceTrajectory trajectory1( tsos.first, recHits.first, false, field, materialEffects,
00082 propDir, mass, false, beamSpot);
00083
00084
00085 if ( !trajectory1.isValid() ) return false;
00086
00087 int nLocal = deriv.first.num_row();
00088 int nTbd = deriv.first.num_col();
00089 unsigned int nHitMeas1 = trajectory1.numberOfHitMeas();
00090 unsigned int nVirtualMeas1 = trajectory1.numberOfVirtualMeas();
00091 unsigned int nPar1 = trajectory1.numberOfPar();
00092 unsigned int nVirtualPar1 = trajectory1.numberOfVirtualPar();
00093
00094
00095 AlgebraicMatrix fullDeriv1 = trajectory1.derivatives().sub(1,nHitMeas1+nVirtualMeas1,1,nLocal) * trajectory1.localToTrajectory() * deriv.first;
00096
00097
00098
00099
00100
00101 ReferenceTrajectory trajectory2( tsos.second, recHits.second, false, field, materialEffects,
00102 propDir, mass, false, beamSpot );
00103
00104 if ( !trajectory2.isValid() ) return false;
00105
00106 unsigned int nHitMeas2 = trajectory2.numberOfHitMeas();
00107 unsigned int nVirtualMeas2 = trajectory2.numberOfVirtualMeas();
00108 unsigned int nPar2 = trajectory2.numberOfPar();
00109 unsigned int nVirtualPar2 = trajectory2.numberOfVirtualPar();
00110
00111 AlgebraicMatrix fullDeriv2 = trajectory2.derivatives().sub(1,nHitMeas2+nVirtualMeas2,1,nLocal) * trajectory2.localToTrajectory() * deriv.second;
00112
00113
00114
00115
00116
00117 theNumberOfRecHits.first = recHits.first.size();
00118 theNumberOfRecHits.second = recHits.second.size();
00119
00120 theNumberOfHits = trajectory1.numberOfHits() + trajectory2.numberOfHits();
00121 theNumberOfPars = nPar1 + nPar2;
00122 theNumberOfVirtualPars = nVirtualPar1 + nVirtualPar2;
00123 theNumberOfVirtualMeas = nVirtualMeas1 + nVirtualMeas2 + 1;
00124
00125
00126 int rowOffset = 1;
00127 int colOffset = 1;
00128 theDerivatives.sub( rowOffset, colOffset, fullDeriv1.sub( 1, nHitMeas1, 1, nTbd ) );
00129 colOffset += nTbd;
00130 theDerivatives.sub( rowOffset, colOffset, trajectory1.derivatives().sub( 1, nHitMeas1, nLocal + 1, nPar1 + nVirtualPar1 ) );
00131
00132 rowOffset += nHitMeas1;
00133 colOffset = 1;
00134 theDerivatives.sub( rowOffset, colOffset, fullDeriv2.sub( 1, nHitMeas2, 1, nTbd ) );
00135 colOffset += (nPar1 + nVirtualPar1 + nTbd - nLocal);
00136 theDerivatives.sub( rowOffset, colOffset, trajectory2.derivatives().sub( 1, nHitMeas2, nLocal + 1, nPar2 + nVirtualPar2 ) );
00137
00138 rowOffset += nHitMeas2;
00139 colOffset = 1;
00140 theDerivatives.sub( rowOffset, colOffset, fullDeriv1.sub(nHitMeas1 + 1, nHitMeas1 + nVirtualMeas1, 1, nTbd ) );
00141 colOffset += nTbd;
00142 theDerivatives.sub( rowOffset, colOffset, trajectory1.derivatives().sub(nHitMeas1 + 1, nHitMeas1 + nVirtualMeas1, nLocal + 1, nPar1 + nVirtualPar1 ) );
00143
00144 rowOffset += nVirtualMeas1;
00145 colOffset = 1;
00146 theDerivatives.sub( rowOffset, colOffset, fullDeriv2.sub(nHitMeas2 + 1, nHitMeas2 + nVirtualMeas2, 1, nTbd ) );
00147 colOffset += (nPar1 + nVirtualPar1 + nTbd - nLocal);
00148 theDerivatives.sub( rowOffset, colOffset, trajectory2.derivatives().sub(nHitMeas2 + 1, nHitMeas2 + nVirtualMeas2, nLocal + 1, nPar2 + nVirtualPar2 ) );
00149
00150 theMeasurements.sub( 1, trajectory1.measurements().sub( 1, nHitMeas1 ) );
00151 theMeasurements.sub( nHitMeas1 + 1, trajectory2.measurements().sub( 1, nHitMeas2 ) );
00152 theMeasurements.sub( nHitMeas1 + nHitMeas2 + 1, trajectory1.measurements().sub(nHitMeas1 + 1, nHitMeas1 + nVirtualMeas1 ) );
00153 theMeasurements.sub( nHitMeas1 + nHitMeas2 + nVirtualMeas1 + 1, trajectory2.measurements().sub(nHitMeas2 + 1, nHitMeas2 + nVirtualMeas2 ) );
00154
00155 theMeasurementsCov.sub( 1, trajectory1.measurementErrors().sub( 1, nHitMeas1 ) );
00156 theMeasurementsCov.sub( nHitMeas1 + 1, trajectory2.measurementErrors().sub( 1, nHitMeas2 ) );
00157 theMeasurementsCov.sub( nHitMeas1 + nHitMeas2 + 1, trajectory1.measurementErrors().sub(nHitMeas1 + 1, nHitMeas1 + nVirtualMeas1 ) );
00158 theMeasurementsCov.sub( nHitMeas1 + nHitMeas2 + nVirtualMeas1 + 1, trajectory2.measurementErrors().sub(nHitMeas2 + 1, nHitMeas2 + nVirtualMeas2 ) );
00159
00160 theTrajectoryPositions.sub( 1, trajectory1.trajectoryPositions() );
00161 theTrajectoryPositions.sub( nHitMeas1 + 1, trajectory2.trajectoryPositions() );
00162
00163 theTrajectoryPositionCov = state.decayParameters().covariance().similarity( theDerivatives.sub(1, nHitMeas1 + nHitMeas2, 1, 9) );
00164
00165 theParameters = state.decayParameters().parameters();
00166
00167 theRecHits.insert( theRecHits.end(), recHits.first.begin(), recHits.first.end() );
00168 theRecHits.insert( theRecHits.end(), recHits.second.begin(), recHits.second.end() );
00169
00170
00171 rowOffset += nVirtualMeas2;
00172 int indMass = rowOffset-1;
00173 theMeasurements[indMass] = state.primaryMass() - state.decayParameters()[TwoBodyDecayParameters::mass];
00174 theMeasurementsCov[indMass][indMass] = state.primaryWidth() * state.primaryWidth();
00175 theDerivatives[indMass][TwoBodyDecayParameters::mass] = 1.0;
00176
00177 if ( constructTsosWithErrors )
00178 {
00179 constructTsosVecWithErrors( trajectory1, trajectory2, field );
00180 }
00181 else
00182 {
00183 theTsosVec.insert( theTsosVec.end(),
00184 trajectory1.trajectoryStates().begin(),
00185 trajectory1.trajectoryStates().end() );
00186
00187 theTsosVec.insert( theTsosVec.end(),
00188 trajectory2.trajectoryStates().begin(),
00189 trajectory2.trajectoryStates().end() );
00190 }
00191
00192 return true;
00193 }
00194
00195
00196 void TwoBodyDecayTrajectory::constructTsosVecWithErrors( const ReferenceTrajectory& traj1,
00197 const ReferenceTrajectory& traj2,
00198 const MagneticField* field )
00199 {
00200 int iTsos = 0;
00201
00202 std::vector< TrajectoryStateOnSurface >::const_iterator itTsos;
00203
00204 for ( itTsos = traj1.trajectoryStates().begin(); itTsos != traj1.trajectoryStates().end(); itTsos++ )
00205 {
00206 constructSingleTsosWithErrors( *itTsos, iTsos, field );
00207 iTsos++;
00208 }
00209
00210 for ( itTsos = traj2.trajectoryStates().begin(); itTsos != traj2.trajectoryStates().end(); itTsos++ )
00211 {
00212 constructSingleTsosWithErrors( *itTsos, iTsos, field );
00213 iTsos++;
00214 }
00215 }
00216
00217
00218 void TwoBodyDecayTrajectory::constructSingleTsosWithErrors( const TrajectoryStateOnSurface& tsos,
00219 int iTsos,
00220 const MagneticField* field )
00221 {
00222 AlgebraicSymMatrix55 localErrors;
00223 const double coeff = 1e-2;
00224
00225 double invP = tsos.localParameters().signedInverseMomentum();
00226 LocalVector p = tsos.localParameters().momentum();
00227
00228
00229
00230 float dpinv = coeff*( fabs(p.x()) + fabs(p.y()) + fabs(p.z()) )*invP*invP;
00231 float dxdir = coeff*( fabs(p.x()) + fabs(p.z()) )/p.z()/p.z();
00232 float dydir = coeff*( fabs(p.y()) + fabs(p.z()) )/p.z()/p.z();
00233 localErrors[0][0] = dpinv*dpinv;
00234 localErrors[1][1] = dxdir*dxdir;
00235 localErrors[2][2] = dydir*dydir;
00236
00237
00238 localErrors[3][3] = theTrajectoryPositionCov[nMeasPerHit*iTsos][nMeasPerHit*iTsos];
00239 localErrors[3][4] = theTrajectoryPositionCov[nMeasPerHit*iTsos][nMeasPerHit*iTsos+1];
00240 localErrors[4][4] = theTrajectoryPositionCov[nMeasPerHit*iTsos+1][nMeasPerHit*iTsos+1];
00241
00242
00243 theTsosVec[iTsos] = TrajectoryStateOnSurface( tsos.localParameters(),
00244 LocalTrajectoryError( localErrors ),
00245 tsos.surface(),
00246 field,
00247 tsos.surfaceSide() );
00248 }