Go to the documentation of this file.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 "FWCore/Utilities/interface/Exception.h"
00010
00011 #include "Alignment/KalmanAlignmentAlgorithm/interface/KalmanAlignmentDataCollector.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.getParameter< unsigned int >( "MinNumberOfHits" );
00023 theExtraWeight = config.getParameter< double >( "ExtraWeight" );
00024 theExternalPredictionWeight = config.getParameter< double >( "ExternalPredictionWeight" );
00025 theCovCheckFlag = config.getParameter< bool >( "CheckCovariance" );
00026
00027 theNumberOfPreAlignmentEvts = config.getParameter< unsigned int >( "NumberOfPreAlignmentEvts" );
00028 theNumberOfProcessedEvts = 0;
00029
00030 std::cout << "[SingleTrajectoryUpdator] Use " << theNumberOfPreAlignmentEvts << "events for pre-alignment" << std::endl;
00031 }
00032
00033
00034 SingleTrajectoryUpdator::~SingleTrajectoryUpdator( void ) {}
00035
00036
00037 void SingleTrajectoryUpdator::process( const ReferenceTrajectoryPtr & trajectory,
00038 AlignmentParameterStore* store,
00039 AlignableNavigator* navigator,
00040 KalmanAlignmentMetricsUpdator* metrics,
00041 const MagneticField* magField )
00042 {
00043 if ( !( *trajectory ).isValid() ) return;
00044
00045
00046
00047 vector< AlignableDetOrUnitPtr > currentAlignableDets = navigator->alignablesFromHits( ( *trajectory ).recHits() );
00048 vector< Alignable* > currentAlignables = alignablesFromAlignableDets( currentAlignableDets, store );
00049
00050 if ( nDifferentAlignables( currentAlignables ) < 2 ) return;
00051 if ( currentAlignables.size() < theMinNumberOfHits ) return;
00052
00053 ++theNumberOfProcessedEvts;
00054 bool includeCorrelations = ( theNumberOfPreAlignmentEvts < theNumberOfProcessedEvts );
00055
00056 metrics->update( currentAlignables );
00057
00058 vector< Alignable* > additionalAlignables;
00059 if ( includeCorrelations ) additionalAlignables = metrics->additionalAlignables( currentAlignables );
00060
00061 vector< Alignable* > allAlignables;
00062 allAlignables.reserve( currentAlignables.size() + additionalAlignables.size() );
00063 allAlignables.insert( allAlignables.end(), currentAlignables.begin(), currentAlignables.end() );
00064 allAlignables.insert( allAlignables.end(), additionalAlignables.begin(), additionalAlignables.end() );
00065
00066 CompositeAlignmentParameters alignmentParameters = store->selectParameters( allAlignables );
00067
00068 const AlgebraicVector& allAlignmentParameters = alignmentParameters.parameters();
00069 AlgebraicSymMatrix currentAlignmentCov = alignmentParameters.covarianceSubset( currentAlignables );
00070 AlgebraicSymMatrix additionalAlignmentCov = alignmentParameters.covarianceSubset( additionalAlignables );
00071 AlgebraicMatrix mixedAlignmentCov = alignmentParameters.covarianceSubset( additionalAlignables, currentAlignables );
00072 AlgebraicMatrix alignmentCovSubset = alignmentParameters.covarianceSubset( alignmentParameters.components(), currentAlignables );
00073
00074 CompositeAlignmentDerivativesExtractor extractor( currentAlignables, currentAlignableDets, trajectory->trajectoryStates() );
00075 AlgebraicVector correctionTerm = extractor.correctionTerm();
00076 AlgebraicMatrix alignmentDeriv = extractor.derivatives();
00077 AlgebraicSymMatrix alignmentCov = currentAlignmentCov.similarity( alignmentDeriv );
00078
00079 AlgebraicVector allMeasurements = trajectory->measurements();
00080 AlgebraicSymMatrix measurementCov = trajectory->measurementErrors();
00081 AlgebraicVector referenceTrajectory = trajectory->trajectoryPositions();
00082 AlgebraicMatrix derivatives = trajectory->derivatives();
00083
00084 measurementCov += theExtraWeight*AlgebraicSymMatrix( measurementCov.num_row(), 1 );
00085
00086 AlgebraicSymMatrix misalignedCov = measurementCov + alignmentCov;
00087
00088 int checkInversion = 0;
00089
00090 AlgebraicSymMatrix weightMatrix;
00091 AlgebraicVector residuals;
00092
00093 if ( trajectory->parameterErrorsAvailable() )
00094 {
00095 const AlgebraicSymMatrix& externalParamCov = trajectory->parameterErrors();
00096 AlgebraicSymMatrix externalTrackCov = theExternalPredictionWeight*externalParamCov.similarity( derivatives );
00097 AlgebraicSymMatrix fullCov = misalignedCov + externalTrackCov;
00098 measurementCov += externalTrackCov;
00099
00100 weightMatrix = fullCov.inverse( checkInversion );
00101 if ( checkInversion != 0 )
00102 {
00103 cout << "[KalmanAlignment] WARNING: 'AlgebraicSymMatrix fullCov' not invertible." << endl;
00104 return;
00105 }
00106
00107
00108
00109
00110 residuals = allMeasurements - referenceTrajectory - correctionTerm;
00111 }
00112 else
00113 {
00114 AlgebraicSymMatrix invMisalignedCov = misalignedCov.inverse( checkInversion );
00115 if ( checkInversion != 0 )
00116 {
00117 cout << "[KalmanAlignment] WARNING: 'AlgebraicSymMatrix misalignedCov' not invertible." << endl;
00118 return;
00119 }
00120 AlgebraicSymMatrix weightMatrix1 = ( invMisalignedCov.similarityT( derivatives ) ).inverse( checkInversion );
00121 if ( checkInversion != 0 )
00122 {
00123 cout << "[KalmanAlignment] WARNING: 'AlgebraicSymMatrix weightMatrix1' not computed." << endl;
00124 return;
00125 }
00126 AlgebraicSymMatrix weightMatrix2 = weightMatrix1.similarity( invMisalignedCov*derivatives );
00127
00128 weightMatrix = invMisalignedCov - weightMatrix2;
00129 residuals = allMeasurements - referenceTrajectory - correctionTerm;
00130 }
00131
00132
00133
00134
00135
00136
00137 AlgebraicMatrix fullCovTimesDeriv = alignmentCovSubset*alignmentDeriv.T();
00138 AlgebraicMatrix fullGainMatrix = fullCovTimesDeriv*weightMatrix;
00139 AlgebraicMatrix covTimesDeriv = currentAlignmentCov*alignmentDeriv.T();
00140 AlgebraicMatrix gainMatrix = covTimesDeriv*weightMatrix;
00141
00142
00143
00144 AlgebraicVector updatedAlignmentParameters = allAlignmentParameters + fullGainMatrix*residuals;
00145
00146
00147 int nCRow = currentAlignmentCov.num_row();
00148 int nARow = additionalAlignmentCov.num_row();
00149
00150 AlgebraicSymMatrix updatedAlignmentCov( nCRow + nARow );
00151
00152 AlgebraicMatrix gTimesDeriv = weightMatrix*alignmentDeriv;
00153 AlgebraicMatrix simMat = AlgebraicMatrix( nCRow, nCRow, 1 ) - covTimesDeriv*gTimesDeriv;
00154 AlgebraicSymMatrix updatedCurrentAlignmentCov = currentAlignmentCov.similarity( simMat ) + measurementCov.similarity( gainMatrix );
00155
00156 AlgebraicMatrix mixedUpdateMat = simMat.T()*simMat.T() + measurementCov.similarity( gTimesDeriv.T() )*currentAlignmentCov;
00157 AlgebraicMatrix updatedMixedAlignmentCov = mixedAlignmentCov*mixedUpdateMat;
00158
00159 AlgebraicSymMatrix additionalUpdateMat = misalignedCov.similarity( gTimesDeriv.T() ) - 2.*weightMatrix.similarity( alignmentDeriv.T() );
00160 AlgebraicSymMatrix updatedAdditionalAlignmentCov = additionalAlignmentCov + additionalUpdateMat.similarity( mixedAlignmentCov );
00161
00162 for ( int nRow=0; nRow<nCRow; nRow++ )
00163 {
00164 for ( int nCol=0; nCol<=nRow; nCol++ ) updatedAlignmentCov[nRow][nCol] = updatedCurrentAlignmentCov[nRow][nCol];
00165 }
00166
00167 for ( int nRow=0; nRow<nARow; nRow++ )
00168 {
00169 for ( int nCol=0; nCol<=nRow; nCol++ ) updatedAlignmentCov[nRow+nCRow][nCol+nCRow] = updatedAdditionalAlignmentCov[nRow][nCol];
00170 }
00171
00172 for ( int nRow=0; nRow<nARow; nRow++ )
00173 {
00174 for ( int nCol=0; nCol<nCRow; nCol++ ) updatedAlignmentCov[nRow+nCRow][nCol] = updatedMixedAlignmentCov[nRow][nCol];
00175 }
00176
00177
00178
00179 CompositeAlignmentParameters* updatedParameters;
00180 updatedParameters = alignmentParameters.clone( updatedAlignmentParameters, updatedAlignmentCov );
00181
00182 if ( !checkCovariance( updatedAlignmentCov ) )
00183 {
00184 if ( includeCorrelations ) throw cms::Exception( "BadCovariance" );
00185
00186 delete updatedParameters;
00187 return;
00188 }
00189
00190 store->updateParameters( *updatedParameters, includeCorrelations );
00191 delete updatedParameters;
00192
00193
00194
00195
00196
00197
00198 updateUserVariables( currentAlignables );
00199
00200
00201 static int i = 0;
00202 if ( i%100 == 0 ) KalmanAlignmentDataCollector::fillGraph( "correlation_entries", i, store->numCorrelations() );
00203 ++i;
00204
00205
00206
00207 return;
00208 }
00209
00210
00211 bool SingleTrajectoryUpdator::checkCovariance( const AlgebraicSymMatrix& cov ) const
00212 {
00213 for ( int i = 0; i < cov.num_row(); ++i )
00214 {
00215 if ( cov[i][i] < 0. ) return false;
00216 }
00217
00218 return true;
00219 }
00220
00221
00222 DEFINE_EDM_PLUGIN( KalmanAlignmentUpdatorPlugin, SingleTrajectoryUpdator, "SingleTrajectoryUpdator" );