CMS 3D CMS Logo

SurveyResidual.cc

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

Generated on Tue Jun 9 17:23:46 2009 for CMSSW by  doxygen 1.5.4