CMS 3D CMS Logo

SingleTrajectoryUpdator.cc

Go to the documentation of this file.
00001 
00002 //#include "Alignment/KalmanAlignmentAlgorithm/plugins/SingleTrajectoryUpdator.h"
00003 #include "SingleTrajectoryUpdator.h"
00004 
00005 #include "Alignment/KalmanAlignmentAlgorithm/interface/KalmanAlignmentUpdatorPlugin.h"
00006 
00007 #include "Alignment/CommonAlignmentParametrization/interface/CompositeAlignmentDerivativesExtractor.h"
00008 
00009 #include "Utilities/Timing/interface/TimingReport.h"
00010 
00011 #include "FWCore/Utilities/interface/Exception.h"
00012 
00013 #include <algorithm>
00014 
00015 
00016 using namespace std;
00017 
00018 
00019 SingleTrajectoryUpdator::SingleTrajectoryUpdator( const edm::ParameterSet & config ) :
00020   KalmanAlignmentUpdator( config )
00021 {
00022   theMinNumberOfHits = config.getUntrackedParameter< unsigned int >( "MinNumberOfHits", 1 );
00023   theExtraWeight = config.getUntrackedParameter< double >( "ExtraWeight", 1e-4 );
00024   theExternalPredictionWeight = config.getUntrackedParameter< double >( "ExternalPredictionWeight", 1. );
00025   theCovCheckFlag = config.getUntrackedParameter< bool >( "CheckCovariance", true );
00026 }
00027 
00028 
00029 SingleTrajectoryUpdator::~SingleTrajectoryUpdator( void ) {}
00030 
00031 
00032 void SingleTrajectoryUpdator::process( const ReferenceTrajectoryPtr & trajectory,
00033                                        AlignmentParameterStore* store,
00034                                        AlignableNavigator* navigator,
00035                                        KalmanAlignmentMetricsUpdator* metrics )
00036 {
00037   if ( !( *trajectory ).isValid() ) return;
00038 
00039   TimeMe* timer;
00040   timer = new TimeMe( "Retrieve_Alignables" );
00041 
00042   vector< AlignableDetOrUnitPtr > currentAlignableDets = navigator->alignablesFromHits( ( *trajectory ).recHits() );
00043   vector< Alignable* > currentAlignables = alignablesFromAlignableDets( currentAlignableDets, store );
00044 
00045   if ( currentAlignables.size() < theMinNumberOfHits ) return;
00046 
00047   delete timer;
00048   timer = new TimeMe( "Update_Metrics" );
00049 
00050   metrics->update( currentAlignables );
00051 
00052   delete timer;
00053   timer = new TimeMe( "Retrieve_Alignables" );
00054 
00055   vector< Alignable* > additionalAlignables = metrics->additionalAlignables( currentAlignables );
00056 
00057   vector< Alignable* > allAlignables;
00058   allAlignables.reserve( currentAlignables.size() + additionalAlignables.size() );
00059   allAlignables.insert( allAlignables.end(), currentAlignables.begin(), currentAlignables.end() );
00060   allAlignables.insert( allAlignables.end(), additionalAlignables.begin(), additionalAlignables.end() );
00061 
00062   delete timer;
00063   timer = new TimeMe( "Retrieve_Parameters" );
00064 
00065   CompositeAlignmentParameters alignmentParameters = store->selectParameters( allAlignables );
00066 
00067   delete timer;
00068   timer = new TimeMe( "Retrieve_Matrices" );
00069 
00070   const AlgebraicVector& allAlignmentParameters = alignmentParameters.parameters();
00071   AlgebraicSymMatrix currentAlignmentCov = alignmentParameters.covarianceSubset( currentAlignables );
00072   AlgebraicSymMatrix additionalAlignmentCov = alignmentParameters.covarianceSubset( additionalAlignables );
00073   AlgebraicMatrix mixedAlignmentCov = alignmentParameters.covarianceSubset( additionalAlignables, currentAlignables );
00074   AlgebraicMatrix alignmentCovSubset = alignmentParameters.covarianceSubset( alignmentParameters.components(), currentAlignables );
00075 
00076   CompositeAlignmentDerivativesExtractor extractor( currentAlignables, currentAlignableDets, trajectory->trajectoryStates() );
00077   AlgebraicVector correctionTerm = extractor.correctionTerm();
00078   AlgebraicMatrix alignmentDeriv = extractor.derivatives();
00079   AlgebraicSymMatrix alignmentCov = currentAlignmentCov.similarity( alignmentDeriv );
00080 
00081   AlgebraicVector allMeasurements = trajectory->measurements();
00082   AlgebraicSymMatrix measurementCov = trajectory->measurementErrors();
00083   AlgebraicVector referenceTrajectory = trajectory->trajectoryPositions();
00084   AlgebraicMatrix derivatives = trajectory->derivatives();
00085 
00086   measurementCov += theExtraWeight*AlgebraicSymMatrix( measurementCov.num_row(), 1 );
00087 
00088   delete timer;
00089   timer = new TimeMe( "Update_Algo" );
00090 
00091   AlgebraicSymMatrix misalignedCov = measurementCov + alignmentCov;
00092 
00093   int checkInversion = 0;
00094 
00095   AlgebraicSymMatrix weightMatrix;
00096   AlgebraicVector residuals;
00097 
00098   if ( trajectory->parameterErrorsAvailable() ) // Make an update using an external prediction for the track parameters.
00099   {
00100     const AlgebraicSymMatrix& externalParamCov = trajectory->parameterErrors();
00101     AlgebraicSymMatrix externalTrackCov = theExternalPredictionWeight*externalParamCov.similarity( derivatives );
00102     AlgebraicSymMatrix fullCov = misalignedCov + externalTrackCov;
00103 
00104     weightMatrix = fullCov.inverse( checkInversion );
00105     if ( checkInversion != 0 )
00106     {
00107       cout << "[KalmanAlignment] WARNING: 'AlgebraicSymMatrix fullCov' not invertible." << endl;
00108       return;
00109     }
00110 
00111     //const AlgebraicVector& trackParameters = trajectory->parameters();
00112     //const AlgebraicVector& externalTrackParameters = trajectory->externalPrediction();
00113     //AlgebraicVector trackCorrectionTerm = derivatives*( externalTrackParameters - trackParameters );
00114     residuals = allMeasurements - referenceTrajectory - correctionTerm;// - trackCorrectionTerm;
00115   }
00116   else // No external prediction for the track parameters available --> give the track parameters weight 0.
00117   {
00118     AlgebraicSymMatrix invMisalignedCov = misalignedCov.inverse( checkInversion );
00119     if ( checkInversion != 0 )
00120     {
00121       cout << "[KalmanAlignment] WARNING: 'AlgebraicSymMatrix misalignedCov' not invertible." << endl;
00122       return;
00123     }
00124     AlgebraicSymMatrix weightMatrix1 = ( invMisalignedCov.similarityT( derivatives ) ).inverse( checkInversion );
00125     if ( checkInversion != 0 )
00126     {
00127       cout << "[KalmanAlignment] WARNING: 'AlgebraicSymMatrix weightMatrix1' not computed." << endl;
00128       return;
00129     }
00130     AlgebraicSymMatrix weightMatrix2 = weightMatrix1.similarity( invMisalignedCov*derivatives );
00131 
00132     weightMatrix = invMisalignedCov - weightMatrix2;
00133     residuals = allMeasurements - referenceTrajectory - correctionTerm;
00134   }
00135 
00136   AlgebraicMatrix fullCovTimesDeriv = alignmentCovSubset*alignmentDeriv.T();
00137   AlgebraicMatrix fullGainMatrix = fullCovTimesDeriv*weightMatrix;
00138   AlgebraicMatrix covTimesDeriv = currentAlignmentCov*alignmentDeriv.T();
00139   AlgebraicMatrix gainMatrix = covTimesDeriv*weightMatrix;
00140 
00141   // make updates for the kalman-filter
00142   // update of parameters
00143   AlgebraicVector updatedAlignmentParameters = allAlignmentParameters + fullGainMatrix*residuals;
00144 
00145   // update of covariance
00146   int nCRow = currentAlignmentCov.num_row();
00147   int nARow = additionalAlignmentCov.num_row();
00148 
00149   AlgebraicSymMatrix updatedAlignmentCov( nCRow + nARow );
00150 
00151   AlgebraicMatrix gTimesDeriv = weightMatrix*alignmentDeriv;
00152   AlgebraicMatrix simMat = AlgebraicMatrix( nCRow, nCRow, 1 ) - covTimesDeriv*gTimesDeriv;
00153   AlgebraicSymMatrix updatedCurrentAlignmentCov = currentAlignmentCov.similarity( simMat ) + measurementCov.similarity( gainMatrix );
00154 
00155   AlgebraicMatrix mixedUpdateMat = simMat.T()*simMat.T() + measurementCov.similarity( gTimesDeriv.T() )*currentAlignmentCov;
00156   AlgebraicMatrix updatedMixedAlignmentCov = mixedAlignmentCov*mixedUpdateMat;
00157 
00158   AlgebraicSymMatrix additionalUpdateMat = misalignedCov.similarity( gTimesDeriv.T() ) - 2.*weightMatrix.similarity( alignmentDeriv.T() );
00159   AlgebraicSymMatrix updatedAdditionalAlignmentCov = additionalAlignmentCov + additionalUpdateMat.similarity( mixedAlignmentCov );
00160 
00161   for ( int nRow=0; nRow<nCRow; nRow++ )
00162   {
00163     for ( int nCol=0; nCol<=nRow; nCol++ ) updatedAlignmentCov[nRow][nCol] = updatedCurrentAlignmentCov[nRow][nCol];
00164   }
00165 
00166   for ( int nRow=0; nRow<nARow; nRow++ )
00167   {
00168      for ( int nCol=0; nCol<=nRow; nCol++ ) updatedAlignmentCov[nRow+nCRow][nCol+nCRow] = updatedAdditionalAlignmentCov[nRow][nCol];
00169   }
00170 
00171   for ( int nRow=0; nRow<nARow; nRow++ )
00172   {
00173     for ( int nCol=0; nCol<nCRow; nCol++ ) updatedAlignmentCov[nRow+nCRow][nCol] = updatedMixedAlignmentCov[nRow][nCol];
00174   }
00175 
00176 
00177   delete timer;
00178   timer = new TimeMe( "Clone_Parameters" );
00179 
00180   // update in alignment-interface
00181   CompositeAlignmentParameters* updatedParameters;
00182   updatedParameters = alignmentParameters.clone( updatedAlignmentParameters, updatedAlignmentCov );
00183 
00184   delete timer;
00185   timer = new TimeMe( "Update_Parameters" );
00186 
00187   store->updateParameters( *updatedParameters );
00188   delete updatedParameters;
00189 
00190   if ( !checkCovariance( updatedAlignmentCov ) ) throw cms::Exception( "BadLogic" );
00191 
00192   delete timer;
00193   timer = new TimeMe( "Update_UserVariables" );
00194 
00195   // update user variables for debugging
00196   //updateUserVariables( alignmentParameters.components() );
00197   updateUserVariables( currentAlignables );
00198 
00199   delete timer;
00200 
00201   return;
00202 }
00203 
00204 
00205 bool SingleTrajectoryUpdator::checkCovariance( const AlgebraicSymMatrix& cov ) const
00206 {
00207   for ( int i = 0; i < cov.num_row(); ++i )
00208   {
00209     if ( cov[i][i] < 0. ) return false;
00210   }
00211 
00212   return true;
00213 }
00214 
00215 
00216 DEFINE_EDM_PLUGIN( KalmanAlignmentUpdatorPlugin, SingleTrajectoryUpdator, "SingleTrajectoryUpdator" );

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