CMS 3D CMS Logo

CSCChamberFitter.cc
Go to the documentation of this file.
1 #include <iostream>
2 
3 #include "CLHEP/Matrix/Matrix.h"
4 #include "TMatrixDEigen.h"
5 
7 
9 
10 const double infinity =
11  0.1; // this is huge because all alignments are angles in radians; but we need a not-too-large value for numerical stability
12  // should become a parameter someday
13 
15  std::vector<CSCPairResidualsConstraint *> &residualsConstraints) {
16  m_name = iConfig.getParameter<std::string>("name");
17  m_alignables = iConfig.getParameter<std::vector<std::string> >("alignables");
18  if (m_alignables.empty()) {
19  throw cms::Exception("BadConfig") << "Fitter " << m_name << " has no alignables!" << std::endl;
20  }
21 
22  int i = 0;
23  for (std::vector<std::string>::const_iterator alignable = m_alignables.begin(); alignable != m_alignables.end();
24  ++alignable) {
25  if (alignableId(*alignable) == -1)
26  m_frames.push_back(i);
27  i++;
28  }
29 
30  m_fixed = -1;
31  std::string fixed = iConfig.getParameter<std::string>("fixed");
32  if (!fixed.empty()) {
33  int i = 0;
34  for (std::vector<std::string>::const_iterator alignable = m_alignables.begin(); alignable != m_alignables.end();
35  ++alignable) {
36  if (fixed == *alignable) {
37  m_fixed = i;
38  }
39  i++;
40  }
41  if (m_fixed == -1)
42  throw cms::Exception("BadConfig") << "Cannot fix unrecognized alignable " << fixed << std::endl;
43  }
44 
45  int numConstraints = 0;
46  std::vector<edm::ParameterSet> constraints = iConfig.getParameter<std::vector<edm::ParameterSet> >("constraints");
47  for (std::vector<edm::ParameterSet>::const_iterator constraint = constraints.begin(); constraint != constraints.end();
48  ++constraint) {
49  int i = index(constraint->getParameter<std::string>("i"));
50  int j = index(constraint->getParameter<std::string>("j"));
51  double value = constraint->getParameter<double>("value");
52  double error = constraint->getParameter<double>("error");
53 
54  if (i < 0)
55  throw cms::Exception("BadConfig") << "Unrecognized alignable " << constraint->getParameter<std::string>("i")
56  << " in constraint " << numConstraints << " of fitter " << m_name << std::endl;
57  if (j < 0)
58  throw cms::Exception("BadConfig") << "Unrecognized alignable " << constraint->getParameter<std::string>("j")
59  << " in constraint " << numConstraints << " of fitter " << m_name << std::endl;
60  if (error <= 0.)
61  throw cms::Exception("BadConfig") << "Non-positive uncertainty in constraint " << numConstraints << " of fitter "
62  << m_name << std::endl;
63  if (i == j)
64  throw cms::Exception("BadConfig") << "Self-connection from " << constraint->getParameter<std::string>("i")
65  << " to " << constraint->getParameter<std::string>("j")
66  << " is not allowed in constraint " << numConstraints << " of fitter " << m_name
67  << std::endl;
68 
69  m_constraints.push_back(new CSCPairConstraint(i, j, value, error));
70  numConstraints++;
71  }
72 
73  // insert CSCPairResidualsConstraints
74  for (unsigned int i = 0; i < m_alignables.size(); i++) {
75  std::string alignable_i = m_alignables[i];
76  long id_i = alignableId(alignable_i);
77  if (id_i != -1) {
78  CSCDetId cscid_i(id_i);
79 
80  for (unsigned int j = 0; j < m_alignables.size(); j++) {
81  std::string alignable_j = m_alignables[j];
82  long id_j = alignableId(alignable_j);
83  if (i != j && id_j != -1) {
84  CSCDetId cscid_j(id_j);
85 
86  if (!(cscid_i.station() == 1 && cscid_i.ring() == 3 && cscid_j.station() == 1 && cscid_j.ring() == 3)) {
87  int next_chamber = cscid_i.chamber() + 1;
88  if (cscid_i.station() > 1 && cscid_i.ring() == 1 && next_chamber == 19)
89  next_chamber = 1;
90  else if (!(cscid_i.station() > 1 && cscid_i.ring() == 1) && next_chamber == 37)
91  next_chamber = 1;
92  if (cscid_i.endcap() == cscid_j.endcap() && cscid_i.station() == cscid_j.station() &&
93  cscid_i.ring() == cscid_j.ring() && next_chamber == cscid_j.chamber()) {
94  CSCPairResidualsConstraint *residualsConstraint =
95  new CSCPairResidualsConstraint(residualsConstraints.size(), i, j, cscid_i, cscid_j);
96  m_constraints.push_back(residualsConstraint);
97  residualsConstraints.push_back(residualsConstraint);
98  numConstraints++;
99  }
100  }
101  }
102  }
103  }
104  }
105 
106  std::map<int, bool> touched;
107  for (unsigned int i = 0; i < m_alignables.size(); i++)
108  touched[i] = false;
109  walk(touched, 0);
110  for (unsigned int i = 0; i < m_alignables.size(); i++) {
111  if (!touched[i])
112  throw cms::Exception("BadConfig") << "Fitter " << m_name << " is not a connected graph (no way to get to "
113  << m_alignables[i] << " from " << m_alignables[0] << ", for instance)"
114  << std::endl;
115  }
116 }
117 
118 int CSCChamberFitter::index(std::string alignable) const {
119  int i = 0;
120  for (std::vector<std::string>::const_iterator a = m_alignables.begin(); a != m_alignables.end(); ++a) {
121  if (*a == alignable)
122  return i;
123  i++;
124  }
125  return -1;
126 }
127 
128 void CSCChamberFitter::walk(std::map<int, bool> &touched, int alignable) const {
129  touched[alignable] = true;
130 
131  for (std::vector<CSCPairConstraint *>::const_iterator constraint = m_constraints.begin();
132  constraint != m_constraints.end();
133  ++constraint) {
134  if (alignable == (*constraint)->i() || alignable == (*constraint)->j()) {
135  if (!touched[(*constraint)->i()])
136  walk(touched, (*constraint)->i());
137  if (!touched[(*constraint)->j()])
138  walk(touched, (*constraint)->j());
139  }
140  }
141 }
142 
144  if (alignable.size() != 9)
145  return -1;
146 
147  if (alignable[0] == 'M' && alignable[1] == 'E') {
148  int endcap = -1;
149  if (alignable[2] == '+')
150  endcap = 1;
151  else if (alignable[2] == '-')
152  endcap = 2;
153 
154  if (endcap != -1) {
155  int station = -1;
156  if (alignable[3] == '1')
157  station = 1;
158  else if (alignable[3] == '2')
159  station = 2;
160  else if (alignable[3] == '3')
161  station = 3;
162  else if (alignable[3] == '4')
163  station = 4;
164 
165  if (alignable[4] == '/' && station != -1) {
166  int ring = -1;
167  if (alignable[5] == '1')
168  ring = 1;
169  else if (alignable[5] == '2')
170  ring = 2;
171  else if (alignable[5] == '3')
172  ring = 3;
173  else if (alignable[5] == '4')
174  ring = 4;
175  if (station > 1 && ring > 2)
176  return -1;
177 
178  if (alignable[6] == '/' && ring != -1) {
179  int chamber = -1;
180  if (alignable[7] == '0' && alignable[8] == '1')
181  chamber = 1;
182  else if (alignable[7] == '0' && alignable[8] == '2')
183  chamber = 2;
184  else if (alignable[7] == '0' && alignable[8] == '3')
185  chamber = 3;
186  else if (alignable[7] == '0' && alignable[8] == '4')
187  chamber = 4;
188  else if (alignable[7] == '0' && alignable[8] == '5')
189  chamber = 5;
190  else if (alignable[7] == '0' && alignable[8] == '6')
191  chamber = 6;
192  else if (alignable[7] == '0' && alignable[8] == '7')
193  chamber = 7;
194  else if (alignable[7] == '0' && alignable[8] == '8')
195  chamber = 8;
196  else if (alignable[7] == '0' && alignable[8] == '9')
197  chamber = 9;
198  else if (alignable[7] == '1' && alignable[8] == '0')
199  chamber = 10;
200  else if (alignable[7] == '1' && alignable[8] == '1')
201  chamber = 11;
202  else if (alignable[7] == '1' && alignable[8] == '2')
203  chamber = 12;
204  else if (alignable[7] == '1' && alignable[8] == '3')
205  chamber = 13;
206  else if (alignable[7] == '1' && alignable[8] == '4')
207  chamber = 14;
208  else if (alignable[7] == '1' && alignable[8] == '5')
209  chamber = 15;
210  else if (alignable[7] == '1' && alignable[8] == '6')
211  chamber = 16;
212  else if (alignable[7] == '1' && alignable[8] == '7')
213  chamber = 17;
214  else if (alignable[7] == '1' && alignable[8] == '8')
215  chamber = 18;
216  else if (alignable[7] == '1' && alignable[8] == '9')
217  chamber = 19;
218  else if (alignable[7] == '2' && alignable[8] == '0')
219  chamber = 20;
220  else if (alignable[7] == '2' && alignable[8] == '1')
221  chamber = 21;
222  else if (alignable[7] == '2' && alignable[8] == '2')
223  chamber = 22;
224  else if (alignable[7] == '2' && alignable[8] == '3')
225  chamber = 23;
226  else if (alignable[7] == '2' && alignable[8] == '4')
227  chamber = 24;
228  else if (alignable[7] == '2' && alignable[8] == '5')
229  chamber = 25;
230  else if (alignable[7] == '2' && alignable[8] == '6')
231  chamber = 26;
232  else if (alignable[7] == '2' && alignable[8] == '7')
233  chamber = 27;
234  else if (alignable[7] == '2' && alignable[8] == '8')
235  chamber = 28;
236  else if (alignable[7] == '2' && alignable[8] == '9')
237  chamber = 29;
238  else if (alignable[7] == '3' && alignable[8] == '0')
239  chamber = 30;
240  else if (alignable[7] == '3' && alignable[8] == '1')
241  chamber = 31;
242  else if (alignable[7] == '3' && alignable[8] == '2')
243  chamber = 32;
244  else if (alignable[7] == '3' && alignable[8] == '3')
245  chamber = 33;
246  else if (alignable[7] == '3' && alignable[8] == '4')
247  chamber = 34;
248  else if (alignable[7] == '3' && alignable[8] == '5')
249  chamber = 35;
250  else if (alignable[7] == '3' && alignable[8] == '6')
251  chamber = 36;
252 
253  if (station > 1 && ring == 1 && chamber > 18)
254  return -1;
255 
256  if (chamber != -1) {
257  return CSCDetId(endcap, station, ring, chamber, 0).rawId();
258  }
259  }
260  }
261  }
262  }
263 
264  return -1;
265 }
266 
267 bool CSCChamberFitter::isFrame(int i) const {
268  for (std::vector<int>::const_iterator frame = m_frames.begin(); frame != m_frames.end(); ++frame) {
269  if (i == *frame)
270  return true;
271  }
272  return false;
273 }
274 
275 double CSCChamberFitter::chi2(const AlgebraicVector &A, double lambda) const {
276  double sumFixed = 0.;
277 
278  if (m_fixed == -1) {
279  for (unsigned int i = 0; i < m_alignables.size(); i++) {
280  if (!isFrame(i)) {
281  sumFixed += A[i];
282  }
283  }
284  } else {
285  sumFixed = A[m_fixed];
286  }
287 
288  double s = lambda * sumFixed * sumFixed;
289  for (std::vector<CSCPairConstraint *>::const_iterator constraint = m_constraints.begin();
290  constraint != m_constraints.end();
291  ++constraint) {
292  if ((*constraint)->valid()) {
293  s += pow((*constraint)->value() - A[(*constraint)->i()] + A[(*constraint)->j()], 2) / (*constraint)->error() /
294  (*constraint)->error();
295  }
296  }
297  return s;
298 }
299 
300 double CSCChamberFitter::lhsVector(int k) const {
301  double s = 0.;
302  for (std::vector<CSCPairConstraint *>::const_iterator constraint = m_constraints.begin();
303  constraint != m_constraints.end();
304  ++constraint) {
305  if ((*constraint)->valid()) {
306  double d = 2. * (*constraint)->value() / (*constraint)->error() / (*constraint)->error();
307  if ((*constraint)->i() == k)
308  s += d;
309  if ((*constraint)->j() == k)
310  s -= d;
311  }
312  }
313  return s;
314 }
315 
316 double CSCChamberFitter::hessian(int k, int l, double lambda) const {
317  double s = 0.;
318 
319  if (m_fixed == -1) {
320  if (!isFrame(k) && !isFrame(l))
321  s += 2. * lambda;
322  } else {
323  if (k == l && l == m_fixed)
324  s += 2. * lambda;
325  }
326 
327  for (std::vector<CSCPairConstraint *>::const_iterator constraint = m_constraints.begin();
328  constraint != m_constraints.end();
329  ++constraint) {
330  double d = 2. / infinity / infinity;
331  if ((*constraint)->valid()) {
332  d = 2. / (*constraint)->error() / (*constraint)->error();
333  }
334 
335  if (k == l && ((*constraint)->i() == k || (*constraint)->j() == k))
336  s += d;
337  if (((*constraint)->i() == k && (*constraint)->j() == l) || ((*constraint)->j() == k && (*constraint)->i() == l))
338  s -= d;
339  }
340  return s;
341 }
342 
343 bool CSCChamberFitter::fit(std::vector<CSCAlignmentCorrections *> &corrections) const {
344  double lambda = 1. / infinity / infinity;
345 
348  AlgebraicMatrix M(m_alignables.size(), m_alignables.size());
349 
350  for (unsigned int k = 0; k < m_alignables.size(); k++) {
351  A[k] = 0.;
352  V[k] = lhsVector(k);
353  for (unsigned int l = 0; l < m_alignables.size(); l++) {
354  M[k][l] = hessian(k, l, lambda);
355  }
356  }
357 
358  double oldchi2 = chi2(A, lambda);
359 
360  int ierr;
361  M.invert(ierr);
362  if (ierr != 0) {
363  edm::LogError("CSCOverlapsAlignmentAlgorithm")
364  << "Matrix inversion failed for fitter " << m_name << " matrix is " << M << std::endl;
365  return false;
366  }
367 
368  A = M * V; // that's the alignment step
369 
372 
373  for (unsigned int i = 0; i < m_alignables.size(); i++) {
374  if (!isFrame(i)) {
375  correction->insertCorrection(m_alignables[i], CSCDetId(alignableId(m_alignables[i])), A[i]);
376  }
377  }
378 
379  // we have to switch to a completely different linear algebrea
380  // package because CLHEP doesn't compute
381  // eigenvectors/diagonalization (?!?)
382  TMatrixD tmatrix(m_alignables.size(), m_alignables.size());
383  for (unsigned int i = 0; i < m_alignables.size(); i++) {
384  for (unsigned int j = 0; j < m_alignables.size(); j++) {
385  tmatrix[i][j] = M[i][j];
386  }
387  }
388  TMatrixDEigen tmatrixdeigen(tmatrix);
389  const TMatrixD &basis = tmatrixdeigen.GetEigenVectors();
390  TMatrixD invbasis = tmatrixdeigen.GetEigenVectors();
391  invbasis.Invert();
392  TMatrixD diagonalized = invbasis * (tmatrix * basis);
393 
394  for (unsigned int i = 0; i < m_alignables.size(); i++) {
395  std::vector<double> coefficient;
396  std::vector<std::string> modename;
397  std::vector<long> modeid;
398  for (unsigned int j = 0; j < m_alignables.size(); j++) {
399  coefficient.push_back(invbasis[i][j]);
400  modename.push_back(m_alignables[j]);
401  modeid.push_back(alignableId(m_alignables[j]));
402  }
403 
404  correction->insertMode(
405  coefficient, modename, modeid, sqrt(2. * fabs(diagonalized[i][i])) * (diagonalized[i][i] >= 0. ? 1. : -1.));
406  }
407 
408  for (std::vector<CSCPairConstraint *>::const_iterator constraint = m_constraints.begin();
409  constraint != m_constraints.end();
410  ++constraint) {
411  if ((*constraint)->valid()) {
412  double residual = (*constraint)->value() - A[(*constraint)->i()] + A[(*constraint)->j()];
413  correction->insertResidual(m_alignables[(*constraint)->i()],
414  m_alignables[(*constraint)->j()],
415  (*constraint)->value(),
416  (*constraint)->error(),
417  residual,
418  residual / (*constraint)->error());
419  }
420  }
421 
422  corrections.push_back(correction);
423  return true;
424 }
425 
427  AlignmentParameterStore *alignmentParameterStore,
428  bool combineME11) const {
429  double sum_phipos_residuals = 0.;
430  double num_valid = 0.;
431  double sum_radius = 0.;
432  double num_total = 0.;
433  for (std::vector<CSCPairConstraint *>::const_iterator constraint = m_constraints.begin();
434  constraint != m_constraints.end();
435  ++constraint) {
436  CSCPairResidualsConstraint *residualsConstraint = dynamic_cast<CSCPairResidualsConstraint *>(*constraint);
437  if (residualsConstraint != nullptr) {
438  if (residualsConstraint->valid()) {
439  sum_phipos_residuals += residualsConstraint->value();
440  num_valid += 1.;
441  }
442 
443  sum_radius += residualsConstraint->radius(true);
444  num_total += 1.;
445  }
446  }
447  if (num_valid == 0. || num_total == 0.)
448  return;
449  double average_phi_residual = sum_phipos_residuals / num_valid;
450  double average_radius = sum_radius / num_total;
451 
452  double radial_correction = average_phi_residual * average_radius * num_total / (2. * M_PI);
453 
454  for (std::vector<CSCPairConstraint *>::const_iterator constraint = m_constraints.begin();
455  constraint != m_constraints.end();
456  ++constraint) {
457  CSCPairResidualsConstraint *residualsConstraint = dynamic_cast<CSCPairResidualsConstraint *>(*constraint);
458  if (residualsConstraint != nullptr) {
459  const DetId id(residualsConstraint->id_i());
460  Alignable *alignable = alignableNavigator->alignableFromDetId(id).alignable();
461  Alignable *also = nullptr;
462  if (combineME11 && residualsConstraint->id_i().station() == 1 && residualsConstraint->id_i().ring() == 1) {
463  CSCDetId alsoid(residualsConstraint->id_i().endcap(), 1, 4, residualsConstraint->id_i().chamber(), 0);
464  const DetId alsoid2(alsoid);
465  also = alignableNavigator->alignableFromDetId(alsoid2).alignable();
466  }
467 
469  AlgebraicSymMatrix cov(6);
470 
472  cov[1][1] = 1e-6;
473 
474  AlignmentParameters *parnew = alignable->alignmentParameters()->cloneFromSelected(params, cov);
475  alignable->setAlignmentParameters(parnew);
476  alignmentParameterStore->applyParameters(alignable);
477  alignable->alignmentParameters()->setValid(true);
478  if (also != nullptr) {
480  also->setAlignmentParameters(parnew2);
481  alignmentParameterStore->applyParameters(also);
482  also->alignmentParameters()->setValid(true);
483  }
484  }
485  }
486 }
std::string m_name
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
AlignmentParameters * alignmentParameters() const
Get the AlignmentParameters.
Definition: Alignable.h:58
void walk(std::map< int, bool > &touched, int alignable) const
std::vector< std::string > m_alignables
void radiusCorrection(AlignableNavigator *alignableNavigator, AlignmentParameterStore *alignmentParameterStore, bool combineME11) const
tuple combineME11
Definition: align_cfg.py:32
CSCChamberFitter(const edm::ParameterSet &iConfig, std::vector< CSCPairResidualsConstraint *> &residualsConstraints)
int index(std::string alignable) const
void applyParameters(void)
Obsolete: Use AlignableNavigator::alignableDetFromDetId and alignableFromAlignableDet.
Log< level::Error, false > LogError
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t V
void setAlignmentParameters(AlignmentParameters *dap)
Set the AlignmentParameters.
Definition: Alignable.cc:123
CLHEP::HepMatrix AlgebraicMatrix
void setValid(bool v)
Set validity flag.
T sqrt(T t)
Definition: SSEVec.h:19
const double infinity
int chamber() const
Definition: CSCDetId.h:62
std::vector< CSCPairConstraint * > m_constraints
Definition: value.py:1
d
Definition: ztail.py:151
double hessian(int k, int l, double lambda) const
double chi2(const AlgebraicVector &A, double lambda) const
bool fit(std::vector< CSCAlignmentCorrections *> &corrections) const
long alignableId(std::string alignable) const
#define M_PI
Definition: DetId.h:17
CLHEP::HepVector AlgebraicVector
int station() const
Definition: CSCDetId.h:79
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
double lhsVector(int k) const
int endcap() const
Definition: CSCDetId.h:85
double a
Definition: hdecay.h:119
CLHEP::HepSymMatrix AlgebraicSymMatrix
Definition: APVGainStruct.h:7
bool isFrame(int i) const
int ring() const
Definition: CSCDetId.h:68
std::vector< int > m_frames
virtual AlignmentParameters * cloneFromSelected(const AlgebraicVector &par, const AlgebraicSymMatrix &cov) const =0
AlignableDetOrUnitPtr alignableFromDetId(const DetId &detid)
Returns AlignableDetOrUnitPtr corresponding to given DetId.
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29