00001
00002
00003
00004
00005
00006 #include "Alignment/ReferenceTrajectories/interface/ReferenceTrajectory.h"
00007 #include "DataFormats/GeometrySurface/interface/Surface.h"
00008
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010
00011 #include "DataFormats/CLHEP/interface/AlgebraicObjects.h"
00012 #include "DataFormats/GeometrySurface/interface/LocalError.h"
00013 #include "DataFormats/GeometryVector/interface/LocalPoint.h"
00014 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00015
00016 #include "DataFormats/TrajectoryState/interface/LocalTrajectoryParameters.h"
00017
00018 #include "TrackingTools/AnalyticalJacobians/interface/AnalyticalCurvilinearJacobian.h"
00019 #include "TrackingTools/AnalyticalJacobians/interface/JacobianLocalToCurvilinear.h"
00020 #include "TrackingTools/AnalyticalJacobians/interface/JacobianCurvilinearToLocal.h"
00021
00022 #include "TrackingTools/GeomPropagators/interface/AnalyticalPropagator.h"
00023
00024 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00025
00026 #include "TrackingTools/MaterialEffects/interface/MultipleScatteringUpdator.h"
00027 #include "TrackingTools/MaterialEffects/interface/EnergyLossUpdator.h"
00028 #include "TrackingTools/MaterialEffects/interface/CombinedMaterialEffectsUpdator.h"
00029
00030
00031
00032
00033 ReferenceTrajectory::ReferenceTrajectory(const TrajectoryStateOnSurface &refTsos,
00034 const TransientTrackingRecHit::ConstRecHitContainer
00035 &recHits, bool hitsAreReverse,
00036 const MagneticField *magField,
00037 MaterialEffects materialEffects,
00038 PropagationDirection propDir,
00039 double mass)
00040 : ReferenceTrajectoryBase( refTsos.localParameters().mixedFormatVector().kSize,
00041 numberOfUsedRecHits(recHits) )
00042 {
00043
00044
00045 theParameters = asHepVector<5>( refTsos.localParameters().mixedFormatVector() );
00046
00047 if (hitsAreReverse) {
00048 TransientTrackingRecHit::ConstRecHitContainer fwdRecHits;
00049 fwdRecHits.reserve(recHits.size());
00050 for (TransientTrackingRecHit::ConstRecHitContainer::const_reverse_iterator it=recHits.rbegin();
00051 it != recHits.rend(); ++it) {
00052 fwdRecHits.push_back(*it);
00053 }
00054 theValidityFlag = this->construct(refTsos, fwdRecHits, mass, materialEffects, propDir, magField);
00055 } else {
00056 theValidityFlag = this->construct(refTsos, recHits, mass, materialEffects, propDir, magField);
00057 }
00058 }
00059
00060
00061
00062
00063 ReferenceTrajectory::ReferenceTrajectory( unsigned int nPar, unsigned int nHits )
00064 : ReferenceTrajectoryBase( nPar, nHits )
00065 {}
00066
00067
00068
00069
00070 bool ReferenceTrajectory::construct(const TrajectoryStateOnSurface &refTsos,
00071 const TransientTrackingRecHit::ConstRecHitContainer &recHits,
00072 double mass, MaterialEffects materialEffects,
00073 const PropagationDirection propDir, const MagneticField *magField)
00074 {
00075 const SurfaceSide surfaceSide = this->surfaceSide(propDir);
00076 MaterialEffectsUpdator *aMaterialEffectsUpdator = this->createUpdator(materialEffects, mass);
00077 if (!aMaterialEffectsUpdator) return false;
00078
00079 AlgebraicMatrix fullJacobian(theParameters.num_row(), theParameters.num_row());
00080 std::vector<AlgebraicMatrix> allJacobians;
00081 allJacobians.reserve(theNumberOfHits);
00082
00083 TransientTrackingRecHit::ConstRecHitPointer previousHitPtr;
00084 TrajectoryStateOnSurface previousTsos;
00085 AlgebraicSymMatrix previousChangeInCurvature(theParameters.num_row(), 1);
00086 std::vector<AlgebraicSymMatrix> allCurvatureChanges;
00087 allCurvatureChanges.reserve(theNumberOfHits);
00088
00089 const LocalTrajectoryError zeroErrors(0., 0., 0., 0., 0.);
00090
00091 std::vector<AlgebraicMatrix> allProjections;
00092 allProjections.reserve(theNumberOfHits);
00093 std::vector<AlgebraicSymMatrix> allDeltaParameterCovs;
00094 allDeltaParameterCovs.reserve(theNumberOfHits);
00095
00096 unsigned int iRow = 0;
00097 TransientTrackingRecHit::ConstRecHitContainer::const_iterator itRecHit;
00098 for ( itRecHit = recHits.begin(); itRecHit != recHits.end(); ++itRecHit ) {
00099
00100 const TransientTrackingRecHit::ConstRecHitPointer &hitPtr = *itRecHit;
00101
00102 if ( !useRecHit( hitPtr ) ) continue;
00103
00104 theRecHits.push_back(hitPtr);
00105
00106 if (0 == iRow) {
00107
00108
00109 fullJacobian = AlgebraicMatrix(theParameters.num_row(), theParameters.num_row(), 1);
00110 allJacobians.push_back(fullJacobian);
00111 theTsosVec.push_back(refTsos);
00112 } else {
00113 AlgebraicMatrix nextJacobian;
00114 TrajectoryStateOnSurface nextTsos;
00115 if (!this->propagate(previousHitPtr->det()->surface(), previousTsos,
00116 hitPtr->det()->surface(), nextTsos,
00117 nextJacobian, propDir, magField)) {
00118 return false;
00119 }
00120
00121 allJacobians.push_back(nextJacobian);
00122 fullJacobian = nextJacobian * previousChangeInCurvature * fullJacobian;
00123 theTsosVec.push_back(nextTsos);
00124 }
00125
00126
00127
00128 const TrajectoryStateOnSurface tmpTsos(theTsosVec.back().localParameters(), zeroErrors,
00129 theTsosVec.back().surface(), magField, surfaceSide);
00130 const TrajectoryStateOnSurface updatedTsos = aMaterialEffectsUpdator->updateState(tmpTsos, propDir);
00131
00132 if ( !updatedTsos.isValid() ) return false;
00133
00134 if ( theTsosVec.back().localParameters().charge() )
00135 {
00136 previousChangeInCurvature[0][0] = updatedTsos.localParameters().signedInverseMomentum()
00137 / theTsosVec.back().localParameters().signedInverseMomentum();
00138 }
00139
00140
00141 allDeltaParameterCovs.push_back( asHepMatrix<5>(updatedTsos.localError().matrix()) );
00142
00143 allCurvatureChanges.push_back(previousChangeInCurvature);
00144
00145
00146 allProjections.push_back(hitPtr->projectionMatrix());
00147
00148
00149
00150 previousHitPtr = hitPtr;
00151 previousTsos = TrajectoryStateOnSurface(updatedTsos.globalParameters(),
00152 updatedTsos.surface(), surfaceSide);
00153
00154 this->fillDerivatives(allProjections.back(), fullJacobian, iRow);
00155
00156 AlgebraicVector mixedLocalParams = asHepVector<5>(theTsosVec.back().localParameters().mixedFormatVector());
00157 this->fillTrajectoryPositions(allProjections.back(), mixedLocalParams, iRow);
00158 this->fillMeasurementAndError(hitPtr, iRow, updatedTsos);
00159
00160 iRow += nMeasPerHit;
00161 }
00162
00163 if (materialEffects != none) {
00164 this->addMaterialEffectsCov(allJacobians, allProjections, allCurvatureChanges, allDeltaParameterCovs);
00165 }
00166
00167 if (refTsos.hasError()) {
00168 AlgebraicSymMatrix parameterCov = asHepMatrix<5>(refTsos.localError().matrix());
00169 theTrajectoryPositionCov = parameterCov.similarity(theDerivatives);
00170 } else {
00171 theTrajectoryPositionCov = AlgebraicSymMatrix(theDerivatives.num_row(), 1);
00172 }
00173
00174 delete aMaterialEffectsUpdator;
00175
00176 return true;
00177 }
00178
00179
00180
00181 MaterialEffectsUpdator*
00182 ReferenceTrajectory::createUpdator(MaterialEffects materialEffects, double mass) const
00183 {
00184 switch (materialEffects) {
00185
00186
00187 case none:
00188 case multipleScattering:
00189 return new MultipleScatteringUpdator(mass);
00190 case energyLoss:
00191 return new EnergyLossUpdator(mass);
00192 case combined:
00193 return new CombinedMaterialEffectsUpdator(mass);
00194 }
00195
00196 return 0;
00197 }
00198
00199
00200
00201 bool ReferenceTrajectory::propagate(const BoundPlane &previousSurface, const TrajectoryStateOnSurface &previousTsos,
00202 const BoundPlane &newSurface, TrajectoryStateOnSurface &newTsos, AlgebraicMatrix &newJacobian,
00203 const PropagationDirection propDir, const MagneticField *magField) const
00204 {
00205
00206 AnalyticalPropagator aPropagator(magField, propDir);
00207 const std::pair<TrajectoryStateOnSurface, double> tsosWithPath =
00208 aPropagator.propagateWithPath(previousTsos, newSurface);
00209
00210
00211 if (!tsosWithPath.first.isValid()) return false;
00212
00213
00214
00215 const AnalyticalCurvilinearJacobian aJacobian(previousTsos.globalParameters(),
00216 tsosWithPath.first.globalPosition(),
00217 tsosWithPath.first.globalMomentum(),
00218 tsosWithPath.second);
00219 const AlgebraicMatrix curvilinearJacobian = asHepMatrix<5,5>(aJacobian.jacobian());
00220
00221
00222
00223 const JacobianLocalToCurvilinear startTrafo(previousSurface, previousTsos.localParameters(), *magField);
00224 const AlgebraicMatrix localToCurvilinear = asHepMatrix<5>(startTrafo.jacobian());
00225
00226
00227 const JacobianCurvilinearToLocal endTrafo(newSurface, tsosWithPath.first.localParameters(), *magField);
00228 const AlgebraicMatrix curvilinearToLocal = asHepMatrix<5>(endTrafo.jacobian());
00229
00230
00231
00232 newJacobian = curvilinearToLocal * curvilinearJacobian * localToCurvilinear;
00233 newTsos = tsosWithPath.first;
00234
00235 return true;
00236 }
00237
00238
00239
00240 void ReferenceTrajectory::fillMeasurementAndError(const TransientTrackingRecHit::ConstRecHitPointer &hitPtr,
00241 unsigned int iRow,
00242 const TrajectoryStateOnSurface &updatedTsos)
00243 {
00244
00245
00246 TransientTrackingRecHit::ConstRecHitPointer newHitPtr(hitPtr->canImproveWithTrack() ?
00247 hitPtr->clone(updatedTsos) : hitPtr);
00248
00249 const LocalPoint localMeasurement = newHitPtr->localPosition();
00250 const LocalError localMeasurementCov = newHitPtr->localPositionError();
00251
00252 theMeasurements[iRow] = localMeasurement.x();
00253 theMeasurements[iRow+1] = localMeasurement.y();
00254 theMeasurementsCov[iRow][iRow] = localMeasurementCov.xx();
00255 theMeasurementsCov[iRow][iRow+1] = localMeasurementCov.xy();
00256 theMeasurementsCov[iRow+1][iRow+1] = localMeasurementCov.yy();
00257 }
00258
00259
00260
00261
00262 void ReferenceTrajectory::fillDerivatives(const AlgebraicMatrix &projection,
00263 const AlgebraicMatrix &fullJacobian,
00264 unsigned int iRow)
00265 {
00266
00267 const AlgebraicMatrix projectedJacobian(projection * fullJacobian);
00268 for (int i = 0; i < parameters().num_row(); ++i) {
00269 theDerivatives[iRow ][i] = projectedJacobian[0][i];
00270 theDerivatives[iRow+1][i] = projectedJacobian[1][i];
00271 }
00272 }
00273
00274
00275
00276 void ReferenceTrajectory::fillTrajectoryPositions(const AlgebraicMatrix &projection,
00277 const AlgebraicVector &mixedLocalParams,
00278 unsigned int iRow)
00279 {
00280
00281 const AlgebraicVector localPosition(projection * mixedLocalParams);
00282 theTrajectoryPositions[iRow] = localPosition[0];
00283 theTrajectoryPositions[iRow+1] = localPosition[1];
00284 }
00285
00286
00287
00288 void ReferenceTrajectory::addMaterialEffectsCov(const std::vector<AlgebraicMatrix> &allJacobians,
00289 const std::vector<AlgebraicMatrix> &allProjections,
00290 const std::vector<AlgebraicSymMatrix> &allCurvatureChanges,
00291 const std::vector<AlgebraicSymMatrix> &allDeltaParameterCovs)
00292 {
00293
00294
00295 AlgebraicSymMatrix materialEffectsCov(nMeasPerHit * allJacobians.size(), 0);
00296
00297
00298 AlgebraicSymMatrix deltaMaterialEffectsCov;
00299
00300
00301 AlgebraicSymMatrix paramMaterialEffectsCov(allDeltaParameterCovs[0]);
00302
00303 AlgebraicMatrix tempParameterCov;
00304 AlgebraicMatrix tempMeasurementCov;
00305
00306 for (unsigned int k = 1; k < allJacobians.size(); ++k) {
00307
00308 paramMaterialEffectsCov = paramMaterialEffectsCov.similarity(allJacobians[k]);
00309
00310
00311 deltaMaterialEffectsCov = paramMaterialEffectsCov.similarity(allProjections[k]);
00312 materialEffectsCov[nMeasPerHit*k ][nMeasPerHit*k ] = deltaMaterialEffectsCov[0][0];
00313 materialEffectsCov[nMeasPerHit*k ][nMeasPerHit*k+1] = deltaMaterialEffectsCov[0][1];
00314 materialEffectsCov[nMeasPerHit*k+1][nMeasPerHit*k ] = deltaMaterialEffectsCov[1][0];
00315 materialEffectsCov[nMeasPerHit*k+1][nMeasPerHit*k+1] = deltaMaterialEffectsCov[1][1];
00316
00317
00318 paramMaterialEffectsCov += allDeltaParameterCovs[k];
00319
00320 tempParameterCov = paramMaterialEffectsCov;
00321
00322
00323 for (unsigned int l = k+1; l < allJacobians.size(); ++l) {
00324 tempParameterCov = allJacobians[l] * allCurvatureChanges[l] * tempParameterCov;
00325 tempMeasurementCov = allProjections[l] * tempParameterCov * allProjections[k].T();
00326
00327 materialEffectsCov[nMeasPerHit*l][nMeasPerHit*k] = tempMeasurementCov[0][0];
00328 materialEffectsCov[nMeasPerHit*k][nMeasPerHit*l] = tempMeasurementCov[0][0];
00329
00330 materialEffectsCov[nMeasPerHit*l][nMeasPerHit*k+1] = tempMeasurementCov[0][1];
00331 materialEffectsCov[nMeasPerHit*k+1][nMeasPerHit*l] = tempMeasurementCov[0][1];
00332
00333 materialEffectsCov[nMeasPerHit*l+1][nMeasPerHit*k] = tempMeasurementCov[1][0];
00334 materialEffectsCov[nMeasPerHit*k][nMeasPerHit*l+1] = tempMeasurementCov[1][0];
00335
00336 materialEffectsCov[nMeasPerHit*l+1][nMeasPerHit*k+1] = tempMeasurementCov[1][1];
00337 materialEffectsCov[nMeasPerHit*k+1][nMeasPerHit*l+1] = tempMeasurementCov[1][1];
00338 }
00339
00340
00341 paramMaterialEffectsCov = paramMaterialEffectsCov.similarity(allCurvatureChanges[k]);
00342 }
00343
00344 theMeasurementsCov += materialEffectsCov;
00345 }