CMS 3D CMS Logo

ReferenceTrajectory.cc

Go to the documentation of this file.
00001 //  Author     : Gero Flucke (based on code by Edmund Widl replacing ORCA's TkReferenceTrack)
00002 //  date       : 2006/09/17
00003 //  last update: $Date: 2008/07/10 15:24:37 $
00004 //  by         : $Author: ewidl $
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   // no check against magField == 0
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       // compute the derivatives of the reference-track's parameters w.r.t. the initial ones
00108       // derivative of the initial reference-track parameters w.r.t. themselves is of course the identity 
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; // stop if problem...
00119       }
00120 
00121       allJacobians.push_back(nextJacobian);
00122       fullJacobian = nextJacobian * previousChangeInCurvature * fullJacobian;
00123       theTsosVec.push_back(nextTsos);
00124     }
00125 
00126     // take material effects into account. since trajectory-state is constructed with errors equal zero,
00127     // the updated state contains only the uncertainties due to interactions in the current layer.
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     // get multiple-scattering covariance-matrix
00141     allDeltaParameterCovs.push_back( asHepMatrix<5>(updatedTsos.localError().matrix()) );
00142 
00143     allCurvatureChanges.push_back(previousChangeInCurvature);
00144 
00145     // projection-matrix tsos-parameters -> measurement-coordinates
00146     allProjections.push_back(hitPtr->projectionMatrix());
00147 
00148     // set start-parameters for next propagation. trajectory-state without error
00149     //  - no error propagation needed here.
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   } // end of loop on hits
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     // MultipleScatteringUpdator doesn't change the trajectory-state
00186     // during update and can therefore be used if material effects should be ignored:
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   // propagate to next layer
00206   AnalyticalPropagator aPropagator(magField, propDir);
00207   const std::pair<TrajectoryStateOnSurface, double> tsosWithPath =
00208     aPropagator.propagateWithPath(previousTsos, newSurface);
00209 
00210   // stop if propagation wasn't successful
00211   if (!tsosWithPath.first.isValid())  return false;
00212 
00213   // calculate derivative of reference-track parameters on the actual layer w.r.t. the ones
00214   // on the previous layer (both in global coordinates)
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   // jacobian of the track parameters on the previous layer for local->global transformation
00223   const JacobianLocalToCurvilinear startTrafo(previousSurface, previousTsos.localParameters(), *magField);
00224   const AlgebraicMatrix localToCurvilinear = asHepMatrix<5>(startTrafo.jacobian());
00225 
00226   // jacobian of the track parameters on the actual layer for global->local transformation
00227   const JacobianCurvilinearToLocal endTrafo(newSurface, tsosWithPath.first.localParameters(), *magField);
00228   const AlgebraicMatrix curvilinearToLocal = asHepMatrix<5>(endTrafo.jacobian());
00229 
00230   // compute derivative of reference-track parameters on the actual layer w.r.t. the ones on
00231   // the previous layer (both in their local representation)
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   // get the measurements and their errors, use information updated with tsos if improving
00245   // (GF: Also for measurements or only for errors or do the former not change?)
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   // derivatives of the local coordinates of the reference track w.r.t. to the inital track-parameters
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   // get the local coordinates of the reference trajectory
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   // the uncertainty due to multiple scattering is 'transferred' to the error matrix of the hits
00294 
00295   AlgebraicSymMatrix materialEffectsCov(nMeasPerHit * allJacobians.size(), 0);
00296 
00297   // additional covariance-matrix of the measurements due to material-effects (single measurement)
00298   AlgebraicSymMatrix deltaMaterialEffectsCov;
00299 
00300   // additional covariance-matrix of the parameters due to material-effects
00301   AlgebraicSymMatrix paramMaterialEffectsCov(allDeltaParameterCovs[0]); //initialization
00302 
00303   AlgebraicMatrix tempParameterCov;
00304   AlgebraicMatrix tempMeasurementCov;
00305 
00306   for (unsigned int k = 1; k < allJacobians.size(); ++k) {
00307     // error-propagation to next layer
00308     paramMaterialEffectsCov = paramMaterialEffectsCov.similarity(allJacobians[k]);
00309 
00310     // get dependences for the measurements
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     // add uncertainties for the following layers due to scattering at this layer
00318     paramMaterialEffectsCov += allDeltaParameterCovs[k];
00319 
00320     tempParameterCov = paramMaterialEffectsCov;
00321 
00322     // compute "inter-layer-dependencies"
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     // error-propagation to state after energy loss
00341     paramMaterialEffectsCov = paramMaterialEffectsCov.similarity(allCurvatureChanges[k]);
00342   }
00343 
00344   theMeasurementsCov += materialEffectsCov;
00345 }

Generated on Tue Jun 9 17:24:59 2009 for CMSSW by  doxygen 1.5.4