CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SurveyResidual.cc
Go to the documentation of this file.
6 
8 
9 using namespace align;
10 
12  : theMother(nullptr), theSurface(ali.surface()), theSelector(ali.alignmentParameters()->selector()) {
13  // Find mother matching given type
14 
15  theMother = &ali; // start finding from this alignable
16 
17  while (theMother->alignableObjectId() != type) {
18  theMother = theMother->mother(); // move up a level
19 
20  if (!theMother)
21  return;
22  // {
23  // throw cms::Exception("ConfigError")
24  // << "Alignable (id = " << ali.geomDetId().rawId()
25  // << ") does not belong to a composite of type " << type;
26  // }
27  }
28 
29  if (!theMother->mother()) {
30  throw cms::Exception("ConfigError") << "The type " << type << " does not have a survey residual defined!\n"
31  << "You have probably set the highest hierarchy. Choose a lower level.";
32  }
33 
34  findSisters(theMother, bias);
35 
36  if (theSisters.empty()) {
37  throw cms::Exception("ConfigError") << "You are finding an unbiased residual of an alignable "
38  << " (id = " << ali.geomDetId().rawId() << ") which has no sister. Abort!";
39  }
40 
41  calculate(ali);
42 }
43 
45  std::vector<Scalar> pars; // selected parameters
46 
47  pars.reserve(AlignParams::kSize);
48 
49  // Find linear displacements.
50 
52 
53  if (theSelector[0])
54  pars.push_back(deltaR.x());
55  if (theSelector[1])
56  pars.push_back(deltaR.y());
57  if (theSelector[2])
58  pars.push_back(deltaR.z());
59 
60  // Match the centers of current and nominal surfaces to find the angular
61  // displacements about the center. Only do this if angular dof are selected.
62 
63  if (theSelector[3] || theSelector[4] || theSelector[5]) {
64  GlobalVectors nominalVs = theNominalVs;
65  GlobalVectors currentVs = theCurrentVs;
66 
67  for (unsigned int j = 0; j < nominalVs.size(); ++j) {
68  nominalVs[j] -= theNominalVs[0]; // move to nominal pos
69  currentVs[j] -= theCurrentVs[0]; // move to current pos
70  }
71 
72  RotationType rot = diffRot(nominalVs, currentVs); // frame rotation
73 
74  EulerAngles deltaW = toAngles(theSurface.toLocal(rot));
75 
76  if (theSelector[3])
77  pars.push_back(deltaW(1));
78  if (theSelector[4])
79  pars.push_back(deltaW(2));
80  if (theSelector[5])
81  pars.push_back(deltaW(3));
82  }
83 
84  AlgebraicVector deltaRW(pars.size()); // (deltaR, deltaW)
85 
86  for (unsigned int j = 0; j < pars.size(); ++j)
87  deltaRW(j + 1) = pars[j];
88 
89  return deltaRW;
90 }
91 
93  LocalVectors residuals;
94 
95  unsigned int nPoint = theNominalVs.size();
96 
97  residuals.reserve(nPoint);
98 
99  for (unsigned int j = 0; j < nPoint; ++j) {
100  residuals.push_back(theSurface.toLocal(theCurrentVs[j] - theNominalVs[j]));
101  }
102 
103  return residuals;
104 }
105 
107  if (theSelector.size() != ErrorMatrix::kRows) {
108  throw cms::Exception("LogicError") << "Mismatched number of dof between ErrorMatrix and Selector.";
109  }
110 
111  std::vector<unsigned int> indices; // selected indices
112 
113  indices.reserve(ErrorMatrix::kRows);
114 
115  for (unsigned int i = 0; i < ErrorMatrix::kRows; ++i)
116  if (theSelector[i])
117  indices.push_back(i);
118 
119  AlgebraicSymMatrix invCov(indices.size());
120 
121  for (unsigned int i = 0; i < indices.size(); ++i)
122  for (unsigned int j = 0; j <= i; ++j)
123  invCov.fast(i + 1, j + 1) = theCovariance(indices[i], indices[j]);
124 
125  int fail(0);
126  invCov.invert(fail);
127 
128  if (fail) {
129  throw cms::Exception("ConfigError") << "Cannot invert survey error " << invCov;
130  }
131 
132  return invCov;
133 }
134 
135 void SurveyResidual::findSisters(const Alignable* ali, bool bias) {
136  theSisters.clear();
137  theSisters.reserve(1000);
138 
139  const auto& comp = ali->mother()->components();
140 
141  unsigned int nComp = comp.size();
142 
143  for (unsigned int i = 0; i < nComp; ++i) {
144  const Alignable* dau = comp[i];
145 
146  if (dau != ali || bias)
147  theSisters.insert(theSisters.end(), dau->deepComponents().begin(), dau->deepComponents().end());
148  // if (dau != ali || bias) theSisters.push_back(dau);
149  }
150 }
151 
153  unsigned int nSister = theSisters.size();
154 
155  // First get sisters' positions
156 
157  std::vector<const PositionType*> nominalSisPos; // nominal sisters' pos
158  std::vector<const PositionType*> currentSisPos; // current sisters' pos
159 
160  nominalSisPos.reserve(nSister);
161  currentSisPos.reserve(nSister);
162 
163  for (unsigned int i = 0; i < nSister; ++i) {
164  const Alignable* sis = theSisters[i];
165  const SurveyDet* survey = sis->survey();
166 
167  if (!survey) {
168  throw cms::Exception("ConfigError") << "No survey info is found for Alignable "
169  << " (id = " << sis->geomDetId().rawId() << "). Abort!";
170  }
171 
172  nominalSisPos.push_back(&survey->position());
173  currentSisPos.push_back(&sis->globalPosition());
174  }
175 
176  // Then find mother's position using sisters' positions
177 
178  PositionType nominalMomPos = motherPosition(nominalSisPos);
179  PositionType currentMomPos = motherPosition(currentSisPos);
180 
181  // Now find rotation from nominal mother to current mother
182 
183  GlobalVectors nominalSisVs; // nominal sisters' pos from mother's pos
184  GlobalVectors currentSisVs; // current sisters' pos from mother's pos
185 
186  for (unsigned int i = 0; i < nSister; ++i) {
187  const Alignable* sis = theSisters[i];
188 
189  const GlobalPoints& nominalSisPoints = sis->survey()->globalPoints();
190  const GlobalPoints& currentSisPoints = sis->surface().toGlobal(sis->survey()->localPoints());
191 
192  for (unsigned int j = 0; j < nominalSisPoints.size(); ++j) {
193  nominalSisVs.push_back(nominalSisPoints[j] - *nominalSisPos[i]);
194  currentSisVs.push_back(currentSisPoints[j] - *currentSisPos[i]);
195  // nominalSisVs.push_back(nominalSisPoints[j] - nominalMomPos);
196  // currentSisVs.push_back(currentSisPoints[j] - currentMomPos);
197  }
198  }
199 
200  RotationType toCurrent = diffRot(currentSisVs, nominalSisVs);
201 
202  // Finally shift and rotate nominal sensor to current sensor
203 
204  const SurveyDet* survey = ali.survey();
205 
206  if (!survey) {
207  throw cms::Exception("ConfigError") << "No survey info is found for Alignable "
208  << " (id = " << ali.geomDetId().rawId() << "). Abort!";
209  }
210 
211  const GlobalPoints& nominalPoints = survey->globalPoints();
212  const GlobalPoints& currentPoints = theSurface.toGlobal(survey->localPoints());
213 
214  for (unsigned int j = 0; j < nominalPoints.size(); ++j) {
215  align::GlobalVector nv = nominalPoints[j] - nominalMomPos;
216 
217  theNominalVs.push_back(align::GlobalVector(toCurrent * nv.basicVector()));
218  theCurrentVs.push_back(currentPoints[j] - currentMomPos);
219  }
220 
221  // Find the covariance
222 
223  const RotationType& currentFrame = ali.globalRotation();
224 
225  for (const Alignable* a = &ali; a != theMother->mother(); a = a->mother()) {
226  RotationType deltaR = currentFrame * a->survey()->rotation().transposed();
227 
228  math::Matrix<6, 6>::type jac; // 6 by 6 Jacobian init to 0
229 
230  jac(0, 0) = deltaR.xx();
231  jac(0, 1) = deltaR.xy();
232  jac(0, 2) = deltaR.xz();
233  jac(1, 0) = deltaR.yx();
234  jac(1, 1) = deltaR.yy();
235  jac(1, 2) = deltaR.yz();
236  jac(2, 0) = deltaR.zx();
237  jac(2, 1) = deltaR.zy();
238  jac(2, 2) = deltaR.zz();
239  jac(3, 3) = deltaR.xx();
240  jac(3, 4) = deltaR.xy();
241  jac(3, 5) = deltaR.xz();
242  jac(4, 3) = deltaR.yx();
243  jac(4, 4) = deltaR.yy();
244  jac(4, 5) = deltaR.yz();
245  jac(5, 3) = deltaR.zx();
246  jac(5, 4) = deltaR.zy();
247  jac(5, 5) = deltaR.zz();
248 
249  theCovariance += ROOT::Math::Similarity(jac, a->survey()->errors());
250  }
251 }
252 
253 // AlgebraicMatrix SurveyResidual::errorTransform(const RotationType& initialFrame,
254 // const RotationType& currentFrame) const
255 // {
256 // // align::EulerAngles angles = align::toAngles(r);
257 
258 // // align::Scalar s1 = std::sin(angles[0]), c1 = std::cos(angles[0]);
259 // // align::Scalar s2 = std::sin(angles[1]), c2 = std::cos(angles[1]);
260 // // align::Scalar s3 = std::sin(angles[2]), c3 = std::cos(angles[2]);
261 
262 // AlgebraicMatrix drdw(9, 3, 0); // 9 by 3 Jacobian init to 0
263 
264 // // drdw(1, 1) = 0;
265 // // drdw(1, 2) = -s2 * c3;
266 // // drdw(1, 3) = c2 * -s3;
267 // // drdw(2, 1) = -s1 * s3 + c1 * s2 * c3;
268 // // drdw(2, 2) = s1 * c2 * c3;
269 // // drdw(2, 3) = c1 * c3 - s1 * s2 * s3;
270 // // drdw(3, 1) = c1 * s3 + s1 * s2 * c3;
271 // // drdw(3, 2) = -c1 * c2 * c3;
272 // // drdw(3, 3) = s1 * c3 + c1 * s2 * s3;
273 // // drdw(4, 1) = 0;
274 // // drdw(4, 2) = s2 * s3;
275 // // drdw(4, 3) = -c2 * c3;
276 // // drdw(5, 1) = -s1 * c3 - c1 * s2 * s3;
277 // // drdw(5, 2) = -s1 * c2 * s3;
278 // // drdw(5, 3) = c1 * -s3 - s1 * s2 * c3;
279 // // drdw(6, 1) = c1 * c3 - s1 * s2 * s3;
280 // // drdw(6, 2) = c1 * c2 * s3;
281 // // drdw(6, 3) = s1 * -s3 + c1 * s2 * c3;
282 // // drdw(7, 1) = 0;
283 // // drdw(7, 2) = c2;
284 // // drdw(7, 3) = 0;
285 // // drdw(8, 1) = -c1 * c2;
286 // // drdw(8, 2) = s1 * s2;
287 // // drdw(8, 3) = 0;
288 // // drdw(9, 1) = -s1 * c2;
289 // // drdw(9, 2) = c1 * -s2;
290 // // drdw(9, 3) = 0;
291 // drdw(2, 3) = drdw(6, 1) = drdw(7, 2) = 1;
292 // drdw(3, 2) = drdw(4, 3) = drdw(8, 1) = -1;
293 
294 // align::RotationType deltaR = initialFrame * currentFrame.transposed();
295 
296 // AlgebraicMatrix dRdr(9, 9, 0); // 9 by 9 Jacobian init to 0
297 
298 // dRdr(1, 1) = deltaR.xx(); dRdr(1, 2) = deltaR.yx(); dRdr(1, 3) = deltaR.zx();
299 // dRdr(2, 1) = deltaR.xy(); dRdr(2, 2) = deltaR.yy(); dRdr(2, 3) = deltaR.zy();
300 // dRdr(3, 1) = deltaR.xz(); dRdr(3, 2) = deltaR.yz(); dRdr(3, 3) = deltaR.zz();
301 // dRdr(4, 4) = deltaR.xx(); dRdr(4, 5) = deltaR.yx(); dRdr(4, 6) = deltaR.zx();
302 // dRdr(5, 4) = deltaR.xy(); dRdr(5, 5) = deltaR.yy(); dRdr(5, 6) = deltaR.zy();
303 // dRdr(6, 4) = deltaR.xz(); dRdr(6, 5) = deltaR.yz(); dRdr(6, 6) = deltaR.zz();
304 // dRdr(7, 7) = deltaR.xx(); dRdr(7, 8) = deltaR.yx(); dRdr(7, 9) = deltaR.zx();
305 // dRdr(8, 7) = deltaR.xy(); dRdr(8, 8) = deltaR.yy(); dRdr(8, 9) = deltaR.zy();
306 // dRdr(9, 7) = deltaR.xz(); dRdr(9, 8) = deltaR.yz(); dRdr(9, 9) = deltaR.zz();
307 
308 // // align::RotationType R = r * deltaR;
309 
310 // AlgebraicMatrix dWdR(3, 9, 0); // 3 by 9 Jacobian init to 0
311 
312 // align::Scalar R11 = deltaR.xx(), R21 = deltaR.yx();
313 // align::Scalar R31 = deltaR.zx(), R32 = deltaR.zy(), R33 = deltaR.zz();
314 
315 // align::Scalar den1 = R32 * R32 + R33 * R33;
316 // align::Scalar den3 = R11 * R11 + R21 * R21;
317 
318 // dWdR(1, 8) = -R33 / den1; dWdR(1, 9) = R32 / den1;
319 // dWdR(2, 7) = 1 / std::sqrt(1 - R31 * R31);
320 // dWdR(3, 1) = R21 / den3; dWdR(3, 4) = -R11 / den3;
321 
322 // AlgebraicMatrix dPdp(6, 6, 0);
323 
324 // dPdp(1, 1) = deltaR.xx(); dPdp(1, 2) = deltaR.xy(); dPdp(1, 3) = deltaR.xz();
325 // dPdp(2, 1) = deltaR.yx(); dPdp(2, 2) = deltaR.yy(); dPdp(2, 3) = deltaR.yz();
326 // dPdp(3, 1) = deltaR.zx(); dPdp(3, 2) = deltaR.zy(); dPdp(3, 3) = deltaR.zz();
327 
328 // dPdp.sub(4, 4, dWdR * dRdr * drdw);
329 
330 // return dPdp;
331 // }
T xx() const
std::vector< const Alignable * > theSisters
const SurveyDet * survey() const
Return survey info.
Definition: Alignable.h:216
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
T y() const
Definition: PV3DBase.h:60
T yx() const
const RotationType & globalRotation() const
Return the global orientation of the object.
Definition: Alignable.h:138
void calculate(const Alignable &)
Find the nominal and current vectors.
RotationType diffRot(const GlobalVectors &current, const GlobalVectors &nominal)
Definition: Utilities.cc:68
std::vector< GlobalPoint > GlobalPoints
Definition: Utilities.h:27
T zx() const
T xy() const
const align::PositionType & position() const
Definition: SurveyDet.h:58
const std::vector< bool > & theSelector
T zz() const
align::GlobalVectors theCurrentVs
align::RotationType toLocal(const align::RotationType &) const
Return in local frame a rotation given in global frame.
align::GlobalVectors theNominalVs
T z() const
Definition: PV3DBase.h:61
SurveyResidual(const Alignable &, align::StructureType, bool bias=false)
virtual StructureType alignableObjectId() const =0
Return the alignable type identifier.
T zy() const
EulerAngles toAngles(const RotationType &)
Convert rotation matrix to angles about x-, y-, z-axes (frame rotation).
Definition: Utilities.cc:8
virtual const Alignables & components() const =0
Return vector of all direct components.
T yy() const
void findSisters(const Alignable *, bool bias)
const AlignableSurface & surface() const
Return the Surface (global position and orientation) of the object.
Definition: Alignable.h:132
ROOT::Math::SMatrix< double, N, M > type
Definition: Matrix.h:9
CLHEP::HepVector AlgebraicVector
AlgebraicVector EulerAngles
Definition: Definitions.h:34
const Alignables & deepComponents() const
Definition: Alignable.h:72
align::LocalVectors pointsResidual() const
AlgebraicSymMatrix inverseCovariance() const
Get inverse of survey covariance wrt given structure type in constructor.
std::vector< GlobalVector > GlobalVectors
Definition: Utilities.h:28
std::vector< LocalVector > LocalVectors
Definition: Utilities.h:30
const Alignable * theMother
align::GlobalPoints globalPoints() const
Definition: SurveyDet.h:66
AlgebraicVector sensorResidual() const
double a
Definition: hdecay.h:119
T xz() const
align::GlobalPoints toGlobal(const align::LocalPoints &) const
Return in global coord given a set of local points.
CLHEP::HepSymMatrix AlgebraicSymMatrix
const PositionType & globalPosition() const
Return the global position of the object.
Definition: Alignable.h:135
PositionType motherPosition(const std::vector< const PositionType * > &dauPos)
Find mother&#39;s position from the average of its daughters&#39; positions.
Definition: Utilities.cc:50
const AlignableSurface & theSurface
list indices
Definition: dqmdumpme.py:50
T x() const
Definition: PV3DBase.h:59
const BasicVectorType & basicVector() const
Definition: PV3DBase.h:53
const align::LocalPoints & localPoints() const
Definition: SurveyDet.h:64
Alignable * mother() const
Return pointer to container alignable (if any)
Definition: Alignable.h:91
T yz() const
const DetId & geomDetId() const
Definition: Alignable.h:177
align::ErrorMatrix theCovariance