CMS 3D CMS Logo

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