CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/Alignment/CommonAlignment/src/SurveyResidual.cc

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 // Find mother matching given type
00019 
00020   theMother = &ali; // start finding from this alignable
00021 
00022   while (theMother->alignableObjectId() != type)
00023   {
00024     theMother = theMother->mother(); // move up a level
00025 
00026     if (!theMother) return;
00027 //     {
00028 //       throw cms::Exception("ConfigError")
00029 //      << "Alignable (id = " << ali.geomDetId().rawId()
00030 //      << ") does not belong to a composite of type " << type;
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; // selected parameters
00057 
00058   pars.reserve(AlignParams::kSize);
00059 
00060 // Find linear displacements.
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 // Match the centers of current and nominal surfaces to find the angular
00069 // displacements about the center. Only do this if angular dof are selected.
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]; // move to nominal pos
00079       currentVs[j] -= theCurrentVs[0]; // move to current pos
00080     }
00081 
00082     RotationType rot = diffRot(nominalVs, currentVs); // frame rotation
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() ); // (deltaR, deltaW)
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; // selected 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 //     if (dau != ali || bias) theSisters.push_back(dau);
00163   }
00164 }
00165 
00166 void SurveyResidual::calculate(const Alignable& ali)
00167 {
00168   unsigned int nSister = theSisters.size();
00169 
00170 // First get sisters' positions
00171 
00172   std::vector<const PositionType*> nominalSisPos; // nominal sisters' pos
00173   std::vector<const PositionType*> currentSisPos; // current sisters' pos
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 // Then find mother's position using sisters' positions
00195 
00196   PositionType nominalMomPos = motherPosition(nominalSisPos);
00197   PositionType currentMomPos = motherPosition(currentSisPos);
00198 
00199 // Now find rotation from nominal mother to current mother
00200 
00201   GlobalVectors nominalSisVs; // nominal sisters' pos from mother's pos
00202   GlobalVectors currentSisVs; // current sisters' pos from mother's pos
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 //       nominalSisVs.push_back(nominalSisPoints[j] - nominalMomPos);
00216 //       currentSisVs.push_back(currentSisPoints[j] - currentMomPos);
00217     }
00218   }
00219 
00220   RotationType toCurrent = diffRot(currentSisVs, nominalSisVs);
00221 
00222 // Finally shift and rotate nominal sensor to current sensor
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 // Find the covariance
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; // 6 by 6 Jacobian init to 0
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 // AlgebraicMatrix SurveyResidual::errorTransform(const RotationType& initialFrame,
00266 //                                             const RotationType& currentFrame) const
00267 // {
00268 // //   align::EulerAngles angles = align::toAngles(r);
00269 
00270 // //   align::Scalar s1 = std::sin(angles[0]), c1 = std::cos(angles[0]);
00271 // //   align::Scalar s2 = std::sin(angles[1]), c2 = std::cos(angles[1]);
00272 // //   align::Scalar s3 = std::sin(angles[2]), c3 = std::cos(angles[2]);
00273 
00274 //   AlgebraicMatrix drdw(9, 3, 0); // 9 by 3 Jacobian init to 0
00275 
00276 // //   drdw(1, 1) =  0;
00277 // //   drdw(1, 2) =  -s2 * c3;
00278 // //   drdw(1, 3) =  c2 * -s3;
00279 // //   drdw(2, 1) =  -s1 * s3 + c1 * s2 * c3;
00280 // //   drdw(2, 2) =  s1 * c2 * c3;
00281 // //   drdw(2, 3) =  c1 * c3 - s1 * s2 * s3;
00282 // //   drdw(3, 1) =  c1 * s3 + s1 * s2 * c3;
00283 // //   drdw(3, 2) =  -c1 * c2 * c3;
00284 // //   drdw(3, 3) =  s1 * c3 + c1 * s2 * s3;
00285 // //   drdw(4, 1) =  0;
00286 // //   drdw(4, 2) =  s2 * s3;
00287 // //   drdw(4, 3) =  -c2 * c3;
00288 // //   drdw(5, 1) =  -s1 * c3 - c1 * s2 * s3;
00289 // //   drdw(5, 2) =  -s1 * c2 * s3;
00290 // //   drdw(5, 3) =  c1 * -s3 - s1 * s2 * c3;
00291 // //   drdw(6, 1) =  c1 * c3 - s1 * s2 * s3;
00292 // //   drdw(6, 2) =  c1 * c2 * s3;
00293 // //   drdw(6, 3) =  s1 * -s3 + c1 * s2 * c3;
00294 // //   drdw(7, 1) =  0;
00295 // //   drdw(7, 2) =  c2;
00296 // //   drdw(7, 3) =  0;
00297 // //   drdw(8, 1) =  -c1 * c2;
00298 // //   drdw(8, 2) =  s1 * s2;
00299 // //   drdw(8, 3) =  0;
00300 // //   drdw(9, 1) =  -s1 * c2;
00301 // //   drdw(9, 2) =  c1 * -s2;
00302 // //   drdw(9, 3) =  0;
00303 //   drdw(2, 3) = drdw(6, 1) = drdw(7, 2) =  1;
00304 //   drdw(3, 2) = drdw(4, 3) = drdw(8, 1) = -1;
00305 
00306 //   align::RotationType deltaR = initialFrame * currentFrame.transposed();
00307 
00308 //   AlgebraicMatrix dRdr(9, 9, 0); // 9 by 9 Jacobian init to 0
00309 
00310 //   dRdr(1, 1) = deltaR.xx(); dRdr(1, 2) = deltaR.yx(); dRdr(1, 3) = deltaR.zx();
00311 //   dRdr(2, 1) = deltaR.xy(); dRdr(2, 2) = deltaR.yy(); dRdr(2, 3) = deltaR.zy();
00312 //   dRdr(3, 1) = deltaR.xz(); dRdr(3, 2) = deltaR.yz(); dRdr(3, 3) = deltaR.zz();
00313 //   dRdr(4, 4) = deltaR.xx(); dRdr(4, 5) = deltaR.yx(); dRdr(4, 6) = deltaR.zx();
00314 //   dRdr(5, 4) = deltaR.xy(); dRdr(5, 5) = deltaR.yy(); dRdr(5, 6) = deltaR.zy();
00315 //   dRdr(6, 4) = deltaR.xz(); dRdr(6, 5) = deltaR.yz(); dRdr(6, 6) = deltaR.zz();
00316 //   dRdr(7, 7) = deltaR.xx(); dRdr(7, 8) = deltaR.yx(); dRdr(7, 9) = deltaR.zx();
00317 //   dRdr(8, 7) = deltaR.xy(); dRdr(8, 8) = deltaR.yy(); dRdr(8, 9) = deltaR.zy();
00318 //   dRdr(9, 7) = deltaR.xz(); dRdr(9, 8) = deltaR.yz(); dRdr(9, 9) = deltaR.zz();
00319 
00320 // //   align::RotationType R = r * deltaR;
00321 
00322 //   AlgebraicMatrix dWdR(3, 9, 0); // 3 by 9 Jacobian init to 0
00323 
00324 //   align::Scalar R11 = deltaR.xx(), R21 = deltaR.yx();
00325 //   align::Scalar R31 = deltaR.zx(), R32 = deltaR.zy(), R33 = deltaR.zz();
00326 
00327 //   align::Scalar den1 = R32 * R32 + R33 * R33;
00328 //   align::Scalar den3 = R11 * R11 + R21 * R21;
00329 
00330 //   dWdR(1, 8) = -R33 / den1; dWdR(1, 9) = R32 / den1;
00331 //   dWdR(2, 7) = 1 / std::sqrt(1 - R31 * R31);
00332 //   dWdR(3, 1) = R21 / den3; dWdR(3, 4) = -R11 / den3;
00333 
00334 //   AlgebraicMatrix dPdp(6, 6, 0);
00335 
00336 //   dPdp(1, 1) = deltaR.xx(); dPdp(1, 2) = deltaR.xy(); dPdp(1, 3) = deltaR.xz();
00337 //   dPdp(2, 1) = deltaR.yx(); dPdp(2, 2) = deltaR.yy(); dPdp(2, 3) = deltaR.yz();
00338 //   dPdp(3, 1) = deltaR.zx(); dPdp(3, 2) = deltaR.zy(); dPdp(3, 3) = deltaR.zz();
00339 
00340 //   dPdp.sub(4, 4, dWdR * dRdr * drdw);
00341 
00342 //   return dPdp;
00343 // }