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