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