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
00013
00014
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
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
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
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
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
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
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
00305 const AlignableSurface& surface = theParentAlignable->surface();
00306
00307
00308 const align::RotationType& globalRotation = theParentAlignable->rotation();
00309
00310 align::RotationType localRotation = surface.toLocal( globalRotation );
00311
00312 align::EulerAngles localEulerAngles = align::toAngles( localRotation );
00313
00314
00315 align::GlobalVector globalShifts( globalRotation.multiplyInverse( theParentAlignable->displacement().basicVector() ) );
00316
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
00330 const align::RotationType& globalRotation = theParentAlignable->rotation();
00331
00332 align::EulerAngles globalEulerAngles = align::toAngles( globalRotation );
00333
00334
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
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
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 }