Go to the documentation of this file.00001 #include "Alignment/CommonAlignment/interface/Alignable.h"
00002 #include "Alignment/CommonAlignment/interface/AlignmentParameters.h"
00003 #include "Alignment/CommonAlignment/interface/SurveyDet.h"
00004 #include "DataFormats/Math/interface/Matrix.h"
00005 #include "FWCore/Utilities/interface/Exception.h"
00006
00007 #include "Alignment/CommonAlignment/interface/SurveyResidual.h"
00008
00009 using namespace align;
00010
00011 SurveyResidual::SurveyResidual(const Alignable& ali,
00012 StructureType type,
00013 bool bias):
00014 theMother(0),
00015 theSurface( ali.surface() ),
00016 theSelector( ali.alignmentParameters()->selector() )
00017 {
00018
00019
00020 theMother = &ali;
00021
00022 while (theMother->alignableObjectId() != type)
00023 {
00024 theMother = theMother->mother();
00025
00026 if (!theMother) return;
00027
00028
00029
00030
00031
00032 }
00033
00034 if ( !theMother->mother() )
00035 {
00036 throw cms::Exception("ConfigError")
00037 << "The type " << type << " does not have a survey residual defined!\n"
00038 << "You have probably set the highest hierarchy. Choose a lower level.";
00039 }
00040
00041 findSisters(theMother, bias);
00042
00043 if (theSisters.size() == 0)
00044 {
00045 throw cms::Exception("ConfigError")
00046 << "You are finding an unbiased residual of an alignable "
00047 << " (id = " << ali.geomDetId().rawId()
00048 << ") which has no sister. Abort!";
00049 }
00050
00051 calculate(ali);
00052 }
00053
00054 AlgebraicVector SurveyResidual::sensorResidual() const
00055 {
00056 std::vector<Scalar> pars;
00057
00058 pars.reserve(AlignParams::kSize);
00059
00060
00061
00062 align::LocalVector deltaR = theSurface.toLocal(theCurrentVs[0] - theNominalVs[0]);
00063
00064 if (theSelector[0]) pars.push_back( deltaR.x() );
00065 if (theSelector[1]) pars.push_back( deltaR.y() );
00066 if (theSelector[2]) pars.push_back( deltaR.z() );
00067
00068
00069
00070
00071 if (theSelector[3] || theSelector[4] || theSelector[5])
00072 {
00073 GlobalVectors nominalVs = theNominalVs;
00074 GlobalVectors currentVs = theCurrentVs;
00075
00076 for (unsigned int j = 0; j < nominalVs.size(); ++j)
00077 {
00078 nominalVs[j] -= theNominalVs[0];
00079 currentVs[j] -= theCurrentVs[0];
00080 }
00081
00082 RotationType rot = diffRot(nominalVs, currentVs);
00083
00084 EulerAngles deltaW = toAngles( theSurface.toLocal(rot) );
00085
00086 if (theSelector[3]) pars.push_back( deltaW(1) );
00087 if (theSelector[4]) pars.push_back( deltaW(2) );
00088 if (theSelector[5]) pars.push_back( deltaW(3) );
00089 }
00090
00091 AlgebraicVector deltaRW( pars.size() );
00092
00093 for (unsigned int j = 0; j < pars.size(); ++j) deltaRW(j + 1) = pars[j];
00094
00095 return deltaRW;
00096 }
00097
00098 LocalVectors SurveyResidual::pointsResidual() const
00099 {
00100 LocalVectors residuals;
00101
00102 unsigned int nPoint = theNominalVs.size();
00103
00104 residuals.reserve(nPoint);
00105
00106 for (unsigned int j = 0; j < nPoint; ++j)
00107 {
00108 residuals.push_back( theSurface.toLocal(theCurrentVs[j] - theNominalVs[j]) );
00109 }
00110
00111 return residuals;
00112 }
00113
00114 AlgebraicSymMatrix SurveyResidual::inverseCovariance() const
00115 {
00116 if (theSelector.size() != ErrorMatrix::kRows)
00117 {
00118 throw cms::Exception("LogicError")
00119 << "Mismatched number of dof between ErrorMatrix and Selector.";
00120 }
00121
00122 std::vector<unsigned int> indices;
00123
00124 indices.reserve(ErrorMatrix::kRows);
00125
00126 for (unsigned int i = 0; i < ErrorMatrix::kRows; ++i)
00127 if (theSelector[i]) indices.push_back(i);
00128
00129 AlgebraicSymMatrix invCov( indices.size() );
00130
00131 for (unsigned int i = 0; i < indices.size(); ++i)
00132 for (unsigned int j = 0; j <= i; ++j)
00133 invCov.fast(i + 1, j + 1) = theCovariance(indices[i], indices[j]);
00134
00135 int fail(0); invCov.invert(fail);
00136
00137 if (fail)
00138 {
00139 throw cms::Exception("ConfigError")
00140 << "Cannot invert survey error " << invCov;
00141 }
00142
00143 return invCov;
00144 }
00145
00146 void SurveyResidual::findSisters(const Alignable* ali,
00147 bool bias)
00148 {
00149 theSisters.clear();
00150 theSisters.reserve(1000);
00151
00152 const std::vector<Alignable*>& comp = ali->mother()->components();
00153
00154 unsigned int nComp = comp.size();
00155
00156 for (unsigned int i = 0; i < nComp; ++i)
00157 {
00158 const Alignable* dau = comp[i];
00159
00160 if (dau != ali || bias)
00161 theSisters.insert( theSisters.end(), dau->deepComponents().begin(), dau->deepComponents().end() );
00162
00163 }
00164 }
00165
00166 void SurveyResidual::calculate(const Alignable& ali)
00167 {
00168 unsigned int nSister = theSisters.size();
00169
00170
00171
00172 std::vector<const PositionType*> nominalSisPos;
00173 std::vector<const PositionType*> currentSisPos;
00174
00175 nominalSisPos.reserve(nSister);
00176 currentSisPos.reserve(nSister);
00177
00178 for (unsigned int i = 0; i < nSister; ++i)
00179 {
00180 const Alignable* sis = theSisters[i];
00181 const SurveyDet* survey = sis->survey();
00182
00183 if (!survey)
00184 {
00185 throw cms::Exception("ConfigError")
00186 << "No survey info is found for Alignable "
00187 << " (id = " << sis->geomDetId().rawId() << "). Abort!";
00188 }
00189
00190 nominalSisPos.push_back( &survey->position() );
00191 currentSisPos.push_back( &sis->globalPosition() );
00192 }
00193
00194
00195
00196 PositionType nominalMomPos = motherPosition(nominalSisPos);
00197 PositionType currentMomPos = motherPosition(currentSisPos);
00198
00199
00200
00201 GlobalVectors nominalSisVs;
00202 GlobalVectors currentSisVs;
00203
00204 for (unsigned int i = 0; i < nSister; ++i)
00205 {
00206 const Alignable* sis = theSisters[i];
00207
00208 const GlobalPoints& nominalSisPoints = sis->survey()->globalPoints();
00209 const GlobalPoints& currentSisPoints = sis->surface().toGlobal( sis->survey()->localPoints() );
00210
00211 for (unsigned int j = 0; j < nominalSisPoints.size(); ++j)
00212 {
00213 nominalSisVs.push_back(nominalSisPoints[j] - *nominalSisPos[i]);
00214 currentSisVs.push_back(currentSisPoints[j] - *currentSisPos[i]);
00215
00216
00217 }
00218 }
00219
00220 RotationType toCurrent = diffRot(currentSisVs, nominalSisVs);
00221
00222
00223
00224 const SurveyDet* survey = ali.survey();
00225
00226 if (!survey)
00227 {
00228 throw cms::Exception("ConfigError")
00229 << "No survey info is found for Alignable "
00230 << " (id = " << ali.geomDetId().rawId() << "). Abort!";
00231 }
00232
00233 const GlobalPoints& nominalPoints = survey->globalPoints();
00234 const GlobalPoints& currentPoints = theSurface.toGlobal( survey->localPoints() );
00235
00236 for (unsigned int j = 0; j < nominalPoints.size(); ++j)
00237 {
00238 align::GlobalVector nv = nominalPoints[j] - nominalMomPos;
00239
00240 theNominalVs.push_back( align::GlobalVector( toCurrent * nv.basicVector() ) );
00241 theCurrentVs.push_back(currentPoints[j] - currentMomPos);
00242 }
00243
00244
00245
00246 const RotationType& currentFrame = ali.globalRotation();
00247
00248 for ( const Alignable* a = &ali; a != theMother->mother(); a = a->mother() )
00249 {
00250 RotationType deltaR = currentFrame * a->survey()->rotation().transposed();
00251
00252 math::Matrix<6, 6>::type jac;
00253
00254 jac(0, 0) = deltaR.xx(); jac(0, 1) = deltaR.xy(); jac(0, 2) = deltaR.xz();
00255 jac(1, 0) = deltaR.yx(); jac(1, 1) = deltaR.yy(); jac(1, 2) = deltaR.yz();
00256 jac(2, 0) = deltaR.zx(); jac(2, 1) = deltaR.zy(); jac(2, 2) = deltaR.zz();
00257 jac(3, 3) = deltaR.xx(); jac(3, 4) = deltaR.xy(); jac(3, 5) = deltaR.xz();
00258 jac(4, 3) = deltaR.yx(); jac(4, 4) = deltaR.yy(); jac(4, 5) = deltaR.yz();
00259 jac(5, 3) = deltaR.zx(); jac(5, 4) = deltaR.zy(); jac(5, 5) = deltaR.zz();
00260
00261 theCovariance += ROOT::Math::Similarity( jac, a->survey()->errors() );
00262 }
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343