CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/Alignment/KalmanAlignmentAlgorithm/src/KalmanAlignmentUserVariables.cc

Go to the documentation of this file.
00001 
00002 #include "Alignment/KalmanAlignmentAlgorithm/interface/KalmanAlignmentUserVariables.h"
00003 #include "Alignment/KalmanAlignmentAlgorithm/interface/KalmanAlignmentDataCollector.h"
00004 
00005 #include "Alignment/CommonAlignment/interface/AlignmentParameters.h"
00006 #include "Alignment/CommonAlignment/interface/Utilities.h"
00007 
00008 #include "FWCore/Utilities/interface/Exception.h"
00009 
00010 using namespace std;
00011 
00012 // Uncomment to plot the evolution of the alignment
00013 // parameters in the local rather than the global frame.
00014 //#define USE_LOCAL_PARAMETERS
00015 
00016 
00017 const TrackerAlignableId* KalmanAlignmentUserVariables::theAlignableId = new TrackerAlignableId;
00018 
00019 KalmanAlignmentUserVariables::KalmanAlignmentUserVariables( Alignable* parent,
00020                                                             const TrackerTopology* tTopo,
00021                                                             int frequency ) :
00022     theParentAlignable( parent ),
00023     theNumberOfHits( 0 ),
00024     theNumberOfUpdates( 0 ),
00025     theUpdateFrequency( frequency ),
00026     theFirstUpdate( true ),
00027     theAlignmentFlag( false )
00028 {
00029   if ( parent )
00030   {
00031     pair< int, int > typeAndLayer = theAlignableId->typeAndLayerFromDetId( parent->geomDetId(), tTopo );
00032 
00033     int iType = typeAndLayer.first;
00034     int iLayer = typeAndLayer.second;
00035     int iId = parent->id();
00036 
00037     string strName = AlignableObjectId::idToString( parent->alignableObjectId() ) + string( "_" );
00038     string strType = string( "Type" ) + toString( iType ) + string( "_" );
00039     string strLayer = string( "Layer" ) + toString( iLayer ) + string( "_" );
00040     string strId =  string( "Id" ) + toString( iId );
00041 
00042     theTypeAndLayer = strType + strLayer;
00043     theIdentifier = theTypeAndLayer + strName + strId;
00044     
00045   }
00046   else theIdentifier = string( "NoAlignable" );
00047 }
00048 
00049 
00050 //KalmanAlignmentUserVariables::~KalmanAlignmentUserVariables( void ) {}
00051 
00052 
00053 void KalmanAlignmentUserVariables::update( bool enforceUpdate )
00054 {
00055   if ( theParentAlignable )
00056   {
00057     ++theNumberOfUpdates;
00058 
00059     if ( ( ( theNumberOfUpdates % theUpdateFrequency == 0  ) || enforceUpdate ) )
00060     {
00061 
00062 #ifdef USE_LOCAL_PARAMETERS
00063 
00064       const AlgebraicVector parameters = theParentAlignable->alignmentParameters()->selectedParameters();
00065       const AlgebraicSymMatrix covariance = theParentAlignable->alignmentParameters()->selectedCovariance();
00066       const vector< bool >& selector = theParentAlignable->alignmentParameters()->selector();
00067 
00068       AlgebraicVector trueParameters( extractTrueParameters() );
00069 
00070       const int nParameter = 6;
00071       int selected = 0;
00072       
00073       for ( int i = 0; i < nParameter; ++i )
00074       {
00075         if ( selector[i] )
00076         {
00077           string parameterId = selectedParameter( i ) + string( "_" ) + theIdentifier;
00078 
00079           if ( theFirstUpdate )
00080           {
00081             KalmanAlignmentDataCollector::fillGraph( string("LocalDelta") + parameterId, 0, -trueParameters[i]/selectedScaling(i) );
00082             KalmanAlignmentDataCollector::fillGraph( string("LocalSigma") + parameterId, 0, sqrt(covariance[selected][selected])/selectedScaling(i) );
00083           }
00084 
00085           KalmanAlignmentDataCollector::fillGraph( string("LocalDelta") + parameterId, theNumberOfUpdates/theUpdateFrequency, (parameters[selected]-trueParameters[i])/selectedScaling(i) );
00086           KalmanAlignmentDataCollector::fillGraph( string("LocalSigma") + parameterId, theNumberOfUpdates/theUpdateFrequency, sqrt(covariance[selected][selected])/selectedScaling(i) );
00087 
00088           selected++;
00089         }
00090       }
00091 
00092       if ( theFirstUpdate ) theFirstUpdate = false;
00093 
00094 #else
00095 
00096       const AlgebraicVector& parameters = theParentAlignable->alignmentParameters()->parameters();
00097       const AlgebraicSymMatrix& covariance = theParentAlignable->alignmentParameters()->covariance();
00098 
00099       const AlignableSurface& surface = theParentAlignable->surface();
00100 
00101       // Get global euler angles.
00102       align::EulerAngles localEulerAngles( parameters.sub( 4, 6 ) );
00103       const align::RotationType localRotation = align::toMatrix( localEulerAngles );
00104       const align::RotationType globalRotation = surface.toGlobal( localRotation );
00105       align::EulerAngles globalEulerAngles = align::toAngles( globalRotation );
00106 
00107       // Get global shifts.
00108       align::LocalVector localShifts( parameters[0], parameters[1], parameters[2] );
00109       align::GlobalVector globalShifts( surface.toGlobal( localShifts ) );
00110 
00111       const int nParameter = 6;
00112       AlgebraicVector globalParameters( nParameter );
00113       globalParameters[0] = globalShifts.x();
00114       globalParameters[1] = globalShifts.y();
00115       globalParameters[2] = globalShifts.z();
00116       globalParameters[3] = globalEulerAngles[0];
00117       globalParameters[4] = globalEulerAngles[1];
00118       globalParameters[5] = globalEulerAngles[2];
00119 
00120       AlgebraicVector trueParameters( extractTrueParameters() );
00121       
00122       for ( int i = 0; i < nParameter; ++i )
00123       {
00124         string parameterId = selectedParameter( i ) + string( "_" ) + theIdentifier;
00125 
00126         if ( theFirstUpdate )
00127         {
00128           KalmanAlignmentDataCollector::fillGraph( string("GlobalDelta") + parameterId, 0, -trueParameters[i]/selectedScaling(i) );
00129           KalmanAlignmentDataCollector::fillGraph( string("LocalSigma") + parameterId, 0, sqrt(covariance[i][i])/selectedScaling(i) );
00130         }
00131 
00132         KalmanAlignmentDataCollector::fillGraph( string("GlobalDelta") + parameterId, theNumberOfUpdates/theUpdateFrequency, (globalParameters[i]-trueParameters[i])/selectedScaling(i) );
00133         KalmanAlignmentDataCollector::fillGraph( string("LocalSigma") + parameterId, theNumberOfUpdates/theUpdateFrequency, sqrt(covariance[i][i])/selectedScaling(i) );
00134       }
00135 
00136       if ( theFirstUpdate ) theFirstUpdate = false;
00137 
00138 #endif
00139 
00140     }
00141   }
00142 }
00143 
00144 
00145 void KalmanAlignmentUserVariables::update( const AlignmentParameters* param )
00146 {
00147   if ( theParentAlignable )
00148   {
00149     ++theNumberOfUpdates;
00150 
00151     const AlgebraicVector& parameters = param->selectedParameters();
00152     const AlgebraicSymMatrix& covariance = param->selectedCovariance();
00153     const vector< bool >& selector = param->selector();
00154 
00155     AlgebraicVector trueParameters( extractTrueParameters() );
00156 
00157     const int nParameter = 6;
00158     int selected = 0;
00159       
00160     for ( int i = 0; i < nParameter; ++i )
00161     {
00162       if ( selector[i] )
00163       {
00164         string parameterId = selectedParameter( i ) + string( "_" ) + theIdentifier;
00165 
00166         KalmanAlignmentDataCollector::fillGraph( string("Delta") + parameterId, theNumberOfUpdates/theUpdateFrequency, (parameters[selected]-trueParameters[i])/selectedScaling(i) );
00167         KalmanAlignmentDataCollector::fillGraph( string("Sigma") + parameterId, theNumberOfUpdates/theUpdateFrequency, sqrt(covariance[selected][selected])/selectedScaling(i) );
00168 
00169         selected++;
00170       }
00171     }
00172 
00173     if ( theFirstUpdate ) theFirstUpdate = false;
00174   }
00175 }
00176 
00177 
00178 void KalmanAlignmentUserVariables::histogramParameters( string histoNamePrefix )
00179 {
00180   if ( theParentAlignable )
00181   {
00182 
00183 #ifdef USE_LOCAL_PARAMETERS
00184 
00185     AlgebraicVector parameters = theParentAlignable->alignmentParameters()->selectedParameters();
00186     AlgebraicSymMatrix covariance = theParentAlignable->alignmentParameters()->selectedCovariance();
00187     vector< bool > selector = theParentAlignable->alignmentParameters()->selector();
00188 
00189     AlgebraicVector trueParameters = extractTrueParameters();
00190 
00191     const int nParameter = 6;
00192     int selected = 0;
00193 
00194     //histoNamePrefix += theTypeAndLayer;
00195       
00196     for ( int i = 0; i < nParameter; ++i )
00197     {
00198       if ( selector[i] )
00199       {
00200         string startHistoName = histoNamePrefix + theTypeAndLayer + string( "_Start" ) + selectedParameter( i );
00201         KalmanAlignmentDataCollector::fillHistogram( startHistoName, -trueParameters[i]/selectedScaling(i) );
00202 
00203         string deltaHistoName = histoNamePrefix + theTypeAndLayer + string( "_Delta" ) + selectedParameter( i );
00204         KalmanAlignmentDataCollector::fillHistogram( deltaHistoName, (parameters[selected]-trueParameters[i])/selectedScaling(i) );
00205 
00206         string pullsHistoName = histoNamePrefix + theTypeAndLayer + string( "_Pulls" ) + selectedParameter( i );
00207         KalmanAlignmentDataCollector::fillHistogram( pullsHistoName, (parameters[selected]-trueParameters[i])/sqrt(covariance[selected][selected]) );
00208 
00209         startHistoName = histoNamePrefix + string( "_Start" ) + selectedParameter( i );
00210         KalmanAlignmentDataCollector::fillHistogram( startHistoName, -trueParameters[i]/selectedScaling(i) );
00211 
00212         deltaHistoName = histoNamePrefix + string( "_Delta" ) + selectedParameter( i );
00213         KalmanAlignmentDataCollector::fillHistogram( deltaHistoName, (parameters[selected]-trueParameters[i])/selectedScaling(i) );
00214 
00215         pullsHistoName = histoNamePrefix + string( "_Pulls" ) + selectedParameter( i );
00216         KalmanAlignmentDataCollector::fillHistogram( pullsHistoName, (parameters[selected]-trueParameters[i])/sqrt(covariance[selected][selected]) );
00217 
00218         selected++;
00219       }
00220     }
00221 
00222 #else
00223 
00224     const AlgebraicVector& parameters = theParentAlignable->alignmentParameters()->parameters();
00225 
00226     const AlignableSurface& surface = theParentAlignable->surface();
00227 
00228     // Get global euler angles.
00229     align::EulerAngles localEulerAngles( parameters.sub( 4, 6 ) );
00230     const align::RotationType localRotation = align::toMatrix( localEulerAngles );
00231     const align::RotationType globalRotation = surface.toGlobal( localRotation );
00232     align::EulerAngles globalEulerAngles = align::toAngles( globalRotation );
00233 
00234     // Get global shifts.
00235     align::LocalVector localShifts( parameters[0], parameters[1], parameters[2] );
00236     align::GlobalVector globalShifts( surface.toGlobal( localShifts ) );
00237 
00238     const int nParameter = 6;
00239     AlgebraicVector globalParameters( nParameter );
00240     globalParameters[0] = globalShifts.x();
00241     globalParameters[1] = globalShifts.y();
00242     globalParameters[2] = globalShifts.z();
00243     globalParameters[3] = globalEulerAngles[0];
00244     globalParameters[4] = globalEulerAngles[1];
00245     globalParameters[5] = globalEulerAngles[2];
00246 
00247     AlgebraicVector trueParameters( extractTrueParameters() );
00248 
00249     KalmanAlignmentDataCollector::fillGraph( "y_vs_dx", theParentAlignable->globalPosition().y(), trueParameters[0]-globalParameters[0] );
00250     KalmanAlignmentDataCollector::fillGraph( "r_vs_dx", theParentAlignable->globalPosition().perp(), trueParameters[0]-globalParameters[0] );
00251     KalmanAlignmentDataCollector::fillGraph( "y_vs_dx_true", theParentAlignable->globalPosition().y(), trueParameters[0] );
00252       
00253     for ( int i = 0; i < nParameter; ++i )
00254     {
00255       string startHistoName = histoNamePrefix + string( "_Start" ) + selectedParameter( i );
00256       KalmanAlignmentDataCollector::fillHistogram( startHistoName, -trueParameters[i]/selectedScaling(i) );
00257 
00258       string deltaHistoName = histoNamePrefix + string( "_Delta" ) + selectedParameter( i );
00259       KalmanAlignmentDataCollector::fillHistogram( deltaHistoName, (globalParameters[i]-trueParameters[i])/selectedScaling(i) );
00260 
00261       string valueHistoName = histoNamePrefix + string( "_Value" ) + selectedParameter( i );
00262       KalmanAlignmentDataCollector::fillHistogram( valueHistoName, globalParameters[i]/selectedScaling(i) );
00263 
00264       startHistoName = histoNamePrefix + theTypeAndLayer + string( "_Start" ) + selectedParameter( i );
00265       KalmanAlignmentDataCollector::fillHistogram( startHistoName, -trueParameters[i]/selectedScaling(i) );
00266 
00267       deltaHistoName = histoNamePrefix + theTypeAndLayer + string( "_Delta" ) + selectedParameter( i );
00268       KalmanAlignmentDataCollector::fillHistogram( deltaHistoName, (globalParameters[i]-trueParameters[i])/selectedScaling(i) );
00269 
00270       valueHistoName = histoNamePrefix + theTypeAndLayer + string( "_Value" ) + selectedParameter( i );
00271       KalmanAlignmentDataCollector::fillHistogram( valueHistoName, globalParameters[i]/selectedScaling(i) );
00272     }
00273 
00274 #endif
00275 
00276   }
00277 }
00278 
00279 
00280 void KalmanAlignmentUserVariables::fixAlignable( void )
00281 {
00282   AlignmentParameters* oldParameters = theParentAlignable->alignmentParameters();
00283   AlgebraicSymMatrix fixedCovariance = 1e-6*oldParameters->covariance();
00284   AlignmentParameters* newParameters = oldParameters->clone( oldParameters->parameters(), fixedCovariance );
00285   theParentAlignable->setAlignmentParameters( newParameters );
00286 }
00287 
00288 
00289 void KalmanAlignmentUserVariables::unfixAlignable( void )
00290 {
00291   AlignmentParameters* oldParameters = theParentAlignable->alignmentParameters();
00292   AlgebraicSymMatrix fixedCovariance = 1e6*oldParameters->covariance();
00293   AlignmentParameters* newParameters = oldParameters->clone( oldParameters->parameters(), fixedCovariance );
00294   theParentAlignable->setAlignmentParameters( newParameters );
00295 }
00296 
00297 
00298 const AlgebraicVector KalmanAlignmentUserVariables::extractTrueParameters( void ) const
00299 {
00300 
00301 #ifdef USE_LOCAL_PARAMETERS
00302 
00303   // get surface of alignable
00304   const AlignableSurface& surface = theParentAlignable->surface();
00305 
00306   // get global rotation
00307   const align::RotationType& globalRotation = theParentAlignable->rotation();
00308   // get local rotation
00309   align::RotationType localRotation = surface.toLocal( globalRotation );
00310   // get euler angles (local frame)
00311   align::EulerAngles localEulerAngles = align::toAngles( localRotation );
00312 
00313   // get global shifts
00314   align::GlobalVector globalShifts( globalRotation.multiplyInverse( theParentAlignable->displacement().basicVector() ) );
00315   // get local shifts
00316   align::LocalVector localShifts = surface.toLocal( globalShifts );
00317 
00318   AlgebraicVector trueParameters( 6 );
00319   trueParameters[0] = -localShifts.x();
00320   trueParameters[1] = -localShifts.y();
00321   trueParameters[2] = -localShifts.z();
00322   trueParameters[3] = -localEulerAngles[0];
00323   trueParameters[4] = -localEulerAngles[1];
00324   trueParameters[5] = -localEulerAngles[2];
00325 
00326 #else
00327 
00328   // get global rotation
00329   const align::RotationType& globalRotation = theParentAlignable->rotation();
00330   // get euler angles (global frame)
00331   align::EulerAngles globalEulerAngles = align::toAngles( globalRotation );
00332 
00333   // get global shifts
00334   align::GlobalVector globalShifts( globalRotation.multiplyInverse( theParentAlignable->displacement().basicVector() ) );
00335 
00336   AlgebraicVector trueParameters( 6 );
00337   trueParameters[0] = -globalShifts.x();
00338   trueParameters[1] = -globalShifts.y();
00339   trueParameters[2] = -globalShifts.z();
00340   trueParameters[3] = -globalEulerAngles[0];
00341   trueParameters[4] = -globalEulerAngles[1];
00342   trueParameters[5] = -globalEulerAngles[2];
00343 
00344 #endif
00345 
00346   return trueParameters;
00347 }
00348 
00349 
00350 const string KalmanAlignmentUserVariables::selectedParameter( const int& selected ) const
00351 {
00352   switch ( selected )
00353   {
00354   case 0:
00355     return string( "X" );
00356     break;
00357   case 1:
00358     return string( "Y" );
00359     break;
00360   case 2:
00361     return string( "Z" );
00362     break;
00363   case 3:
00364     return string( "Alpha" );
00365     break;
00366   case 4:
00367     return string( "Beta" );
00368     break;
00369   case 5:
00370     return string( "Gamma" );
00371     break;
00372   default:
00373     throw cms::Exception( "OutOfRange" ) << "[KalmanAlignmentUserVariables::selectedParameter] "
00374                                          << "Index out of range (selector = " << selected << ")";
00375   }
00376 }
00377 
00378 
00379 float KalmanAlignmentUserVariables::selectedScaling( const int& selected ) const
00380 {
00381   const float micron = 1e-4;
00382   const float millirad = 1e-3;
00383   //const float murad = 1e-6;
00384 
00385   switch ( selected )
00386   {
00387   case 0:
00388   case 1:
00389   case 2:
00390     return micron;
00391     break;
00392   case 3:
00393   case 4:
00394   case 5:
00395     return millirad;
00396     //return murad;
00397     break;
00398   default:
00399     throw cms::Exception( "LogicError" ) << "@SUB=KalmanAlignmentUserVariables::selectedScaling"
00400                                          << "Index out of range (selector = " << selected << ")\n";
00401   }
00402 }
00403 
00404 
00405 const string KalmanAlignmentUserVariables::toString( const int& i ) const
00406 {
00407   char temp[10];
00408   snprintf( temp, sizeof(temp), "%u", i );
00409 
00410   return string( temp );
00411 }