00001
00002
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() )
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
00112
00113
00114 residuals = allMeasurements - referenceTrajectory - correctionTerm;
00115 }
00116 else
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
00142
00143 AlgebraicVector updatedAlignmentParameters = allAlignmentParameters + fullGainMatrix*residuals;
00144
00145
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
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
00196
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" );