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