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
00017
00018 theMother = &ali;
00019
00020 while (theMother->alignableObjectId() != type)
00021 {
00022 theMother = theMother->mother();
00023
00024 if (!theMother) return;
00025
00026
00027
00028
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
00057
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];
00065 currentVs[j] -= theCurrentVs[0];
00066 }
00067
00068 RotationType rot = diffRot(nominalVs, currentVs);
00069
00070 EulerAngles deltaW = toAngles( theSurface.toLocal(rot) );
00071
00072 AlgebraicVector deltaRW(6);
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
00128 }
00129 }
00130
00131 void SurveyResidual::calculate(const Alignable& ali)
00132 {
00133 unsigned int nSister = theSisters.size();
00134
00135
00136
00137 std::vector<const PositionType*> nominalSisPos;
00138 std::vector<const PositionType*> currentSisPos;
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
00160
00161 PositionType nominalMomPos = motherPosition(nominalSisPos);
00162 PositionType currentMomPos = motherPosition(currentSisPos);
00163
00164
00165
00166 GlobalVectors nominalSisVs;
00167 GlobalVectors currentSisVs;
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
00181
00182 }
00183 }
00184
00185 RotationType toCurrent = diffRot(currentSisVs, nominalSisVs);
00186
00187
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
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;
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
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
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