CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/Alignment/KalmanAlignmentAlgorithm/plugins/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 "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 //   std::cout << "[SingleTrajectoryUpdator::process] START" << std::endl;
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() ) // Make an update using an external prediction for the track parameters.
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     //const AlgebraicVector& trackParameters = trajectory->parameters();
00108     //const AlgebraicVector& externalTrackParameters = trajectory->externalPrediction();
00109     //AlgebraicVector trackCorrectionTerm = derivatives*( externalTrackParameters - trackParameters );
00110     residuals = allMeasurements - referenceTrajectory - correctionTerm;// - trackCorrectionTerm;
00111   }
00112   else // No external prediction for the track parameters available --> give the track parameters weight 0.
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 //   AlgebraicVector deltaR = allMeasurements - referenceTrajectory;
00133 //   for ( int i = 0; i < deltaR.num_row()/2; ++i )
00134 //     KalmanAlignmentDataCollector::fillHistogram( "DeltaR_", i, deltaR[2*i] );
00135 //   return;
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   // make updates for the kalman-filter
00143   // update of parameters
00144   AlgebraicVector updatedAlignmentParameters = allAlignmentParameters + fullGainMatrix*residuals;
00145 
00146   // update of covariance
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   // update in alignment-interface
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   // update user variables for debugging
00195   //updateUserVariables( alignmentParameters.components() );
00196 
00197   //std::cout << "update user variables now" << std::endl;
00198   updateUserVariables( currentAlignables );
00199   //std::cout << "done." << std::endl;
00200 
00201   static int i = 0;
00202   if ( i%100 == 0 ) KalmanAlignmentDataCollector::fillGraph( "correlation_entries", i, store->numCorrelations() );
00203   ++i;
00204 
00205   //std::cout << "[SingleTrajectoryUpdator::process] DONE" << std::endl;
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" );