CMS 3D CMS Logo

GEMCSCSegFit.cc
Go to the documentation of this file.
1 // ------------------------- //
2 // --> GEMCSCSegFit.cc
3 // Created: 21.04.2015
4 // --> Based on CSCSegFit.cc
5 // with last mod: 03.02.2015
6 // as found in 750pre2 rel
7 // ------------------------- //
8 
12 
15 
18 
19 
20 void GEMCSCSegFit::fit(void) {
21  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::fit] - start the fitting fun :: nhits = "<<nhits();
22  if ( fitdone() ) return; // don't redo fit unnecessarily
23  short n = nhits();
24  switch ( n ) {
25  case 1:
26  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::fit] - cannot fit just 1 hit!!";
27  break;
28  case 2:
29  fit2();
30  break;
31  case 3:
32  case 4:
33  case 5:
34  case 6:
35  case 7:
36  case 8:
37  fitlsq();
38  break;
39  default:
40  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::fit] - cannot fit more than 8 hits!!";
41  }
42 }
43 
44 void GEMCSCSegFit::fit2(void) {
45 
46  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::fit2] - start fit2()";
47  // Just join the two points
48  // Equation of straight line between (x1, y1) and (x2, y2) in xy-plane is
49  // y = mx + c
50  // with m = (y2-y1)/(x2-x1)
51  // and c = (y1*x2-x2*y1)/(x2-x1)
52 
53 
54  // 1) Check whether hits are on the same layer
55  // -------------------------------------------
56  std::vector<const TrackingRecHit*>::const_iterator ih = hits_.begin();
57  // layer numbering: GEM: (1,2) CSC (3,4,5,6,7,8)
58  int il1 = 0, il2 = 0;
59  DetId d1 = DetId((*ih)->rawId());
60  // check whether first hit is GEM or CSC
61  if (d1.subdetId() == MuonSubdetId::GEM) {
62  il1 = GEMDetId(d1).layer();
63  }
64  else if (d1.subdetId() == MuonSubdetId::CSC) {
65  il1 = CSCDetId(d1).layer() + 2;
66  }
67  else { edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit:fit2] - TrackingRecHit is not in GEM or CSC subdetector"; }
68  const TrackingRecHit& h1 = (**ih);
69  ++ih;
70  DetId d2 = DetId((*ih)->rawId());
71  // check whether second hit is GEM or CSC
72  if (d2.subdetId() == MuonSubdetId::GEM) {
73  il2 = GEMDetId(d2).layer();
74  }
75  else if (d2.subdetId() == MuonSubdetId::CSC) {
76  il2 = GEMDetId(d2).layer() + 2;
77  }
78  else { edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit:fit2] - TrackingRecHit is not in GEM or CSC subdetector"; }
79  const TrackingRecHit& h2 = (**ih);
80  // Skip if on same layer, but should be impossible :)
81  if (il1 == il2) {
82  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit:fit2] - 2 hits on same layer!!";
83  return;
84  }
85 
86 
87  // 2) Global Positions of hit 1 and 2 and
88  // Local Positions of hit 1 and 2 w.r.t. reference CSC Chamber Frame
89  // ---------------------------------------------------------------------
90  GlobalPoint h1glopos, h2glopos;
91  // global position hit 1
92  if(d1.subdetId() == MuonSubdetId::GEM) {
93  const GEMEtaPartition* roll1 = gemetapartition(GEMDetId(d1));
94  h1glopos = roll1->toGlobal(h1.localPosition());
95  }
96  else if(d1.subdetId() == MuonSubdetId::CSC) {
97  const CSCLayer* layer1 = cscchamber(CSCDetId(d1))->layer(CSCDetId(d1).layer());
98  h1glopos = layer1->toGlobal(h1.localPosition());
99  }
100  else { edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit:fit2] - TrackingRecHit is not in GEM or CSC subdetector"; }
101  // global position hit 2
102  if(d2.subdetId() == MuonSubdetId::GEM) {
103  const GEMEtaPartition* roll2 = gemetapartition(GEMDetId(d2));
104  h2glopos = roll2->toGlobal(h2.localPosition());
105  }
106  else if(d2.subdetId() == MuonSubdetId::CSC) {
107  const CSCLayer* layer2 = cscchamber(CSCDetId(d2))->layer(CSCDetId(d2).layer());
108  h2glopos = layer2->toGlobal(h2.localPosition());
109  }
110  else { edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit:fit2] - TrackingRecHit is not in GEM or CSC subdetector"; }
111  // local positions hit 1 and 2 w.r.t. ref CSC Chamber Frame
112  // We want hit wrt chamber (and local z will be != 0)
113  LocalPoint h1pos = refcscchamber()->toLocal(h1glopos);
114  LocalPoint h2pos = refcscchamber()->toLocal(h2glopos);
115 
116 
117  // 3) Now make straight line between the two points in local coords
118  // ----------------------------------------------------------------
119  float dz = h2pos.z()-h1pos.z();
120  if(dz != 0) {
121  uslope_ = ( h2pos.x() - h1pos.x() ) / dz ;
122  vslope_ = ( h2pos.y() - h1pos.y() ) / dz ;
123  }
124  float uintercept = ( h1pos.x()*h2pos.z() - h2pos.x()*h1pos.z() ) / dz;
125  float vintercept = ( h1pos.y()*h2pos.z() - h2pos.y()*h1pos.z() ) / dz;
126  intercept_ = LocalPoint( uintercept, vintercept, 0.);
127 
128  setOutFromIP();
129 
130  //@@ NOT SURE WHAT IS SENSIBLE FOR THESE...
131  chi2_ = 0.;
132  ndof_ = 0;
133 
134  fitdone_ = true;
135 }
136 
137 
139 
140  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::fitlsq] - start fitlsq";
141  // Linear least-squares fit to up to 6 CSC rechits, one per layer in a CSC
142  // and up to 2 GEM rechits in a GEM superchamber
143  // (we can later later on go up to 4 hits in case of an overlapping chamber)
144  // (... and if there is an overlap in the GEM chambers, than maybe we also
145  // have an overlap in the CSC chambers... maybe we can also benefit there)
146 
147  // Comments below taken from CSCSegFit algorithm.
148  // Comments adapted from original CSCSegAlgoSK algorithm.
149 
150  // Fit to the local x, y rechit coordinates in z projection
151  // The CSC & GEM strip measurement controls the precision of x
152  // The CSC wire measurement & GEM eta-partition controls the precision of y.
153  // Typical precision CSC: u (strip, sigma~200um), v (wire, sigma~1cm)
154  // Typical precision GEM: u (strip, sigma~250um), v (eta-part, sigma~10-20cm)
155 
156  // Set up the normal equations for the least-squares fit as a matrix equation
157 
158  // We have a vector of measurements m, which is a 2n x 1 dim matrix
159  // The transpose mT is (u1, v1, u2, v2, ..., un, vn) where
160  // ui is the strip-associated measurement and
161  // vi is the wire-associated measurement
162  // for a given rechit i.
163 
164  // The fit is to
165  // u = u0 + uz * z
166  // v = v0 + vz * z
167  // where u0, uz, v0, vz are the parameters to be obtained from the fit.
168 
169  // These are contained in a vector p which is a 4x1 dim matrix, and
170  // its transpose pT is (u0, v0, uz, vz). Note the ordering!
171 
172  // The covariance matrix for each pair of measurements is 2 x 2 and
173  // the inverse of this is the error matrix E.
174  // The error matrix for the whole set of n measurements is a diagonal
175  // matrix with diagonal elements the individual 2 x 2 error matrices
176  // (because the inverse of a diagonal matrix is a diagonal matrix
177  // with each element the inverse of the original.)
178 
179  // In function 'weightMatrix()', the variable 'matrix' is filled with this
180  // block-diagonal overall covariance matrix. Then 'matrix' is inverted to the
181  // block-diagonal error matrix, and returned.
182 
183  // Define the matrix A as
184  // 1 0 z1 0
185  // 0 1 0 z1
186  // 1 0 z2 0
187  // 0 1 0 z2
188  // .. .. .. ..
189  // 1 0 zn 0
190  // 0 1 0 zn
191 
192  // This matrix A is set up and returned by function 'derivativeMatrix()'.
193 
194  // Then the normal equations are described by the matrix equation
195  //
196  // (AT E A)p = (AT E)m
197  //
198  // where AT is the transpose of A.
199 
200  // Call the combined matrix on the LHS, M, and that on the RHS, B:
201  // M p = B
202 
203  // We solve this for the parameter vector, p.
204  // The elements of M and B then involve sums over the hits
205 
206  // The covariance matrix of the parameters is obtained by
207  // (AT E A)^-1 calculated in 'covarianceMatrix()'.
208 
209 
210  // NOTE
211  // We need local position of a RecHit w.r.t. the CHAMBER
212  // and the RecHit itself only knows its local position w.r.t.
213  // the LAYER, so we must explicitly transform global position.
214 
215 
216  SMatrix4 M; // 4x4, init to 0
217  SVector4 B; // 4x1, init to 0;
218 
219  std::vector<const TrackingRecHit*>::const_iterator ih = hits_.begin();
220 
221  // LogDebug :: Loop over the TrackingRecHits and print the GEM and CSC Hits
222  for (ih = hits_.begin(); ih != hits_.end(); ++ih)
223  {
224  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::fitlsq] - looping over TrackingRecHits";
225  const TrackingRecHit& hit = (**ih);
226  DetId d = DetId(hit.rawId());
227  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::fitlsq] - Tracking RecHit in detid ("<<d.rawId()<<")";
228  if(d.subdetId() == MuonSubdetId::GEM) {
229  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::fitlsq] - Tracking RecHit is a GEM Hit in detid ("<<d.rawId()<<")";
230  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::fitlsq] - GEM DetId ("<<GEMDetId(d.rawId())<<")";
231  }
232  else if(d.subdetId() == MuonSubdetId::CSC) {
233  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::fitlsq] - Tracking RecHit is a CSC Hit in detid ("<<d.rawId()<<")";
234  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::fitlsq] - CSC DetId ("<<CSCDetId(d.rawId())<<")";
235  }
236  else { edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit:fit2] - TrackingRecHit is not in GEM or CSC subdetector"; }
237  }
238 
239  // Loop over the TrackingRecHits and make small (2x2) matrices used to fill the blockdiagonal covariance matrix E^-1
240  for (ih = hits_.begin(); ih != hits_.end(); ++ih)
241  {
242  const TrackingRecHit& hit = (**ih);
243  GlobalPoint gp;
244  DetId d = DetId(hit.rawId());
245  if(d.subdetId() == MuonSubdetId::GEM)
246  {
247  const GEMEtaPartition* roll = gemetapartition(GEMDetId(d));
248  gp = roll->toGlobal(hit.localPosition());
249  }
250  else if(d.subdetId() == MuonSubdetId::CSC)
251  {
252  const CSCLayer* layer = cscchamber(CSCDetId(d))->layer(CSCDetId(d).layer());
253  gp = layer->toGlobal(hit.localPosition());
254  }
255  else { edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit:fit2] - TrackingRecHit is not in GEM or CSC subdetector"; }
256  LocalPoint lp = refcscchamber()->toLocal(gp);
257 
258  // LogDebug
259  std::stringstream lpss; lpss<<lp; std::string lps = lpss.str();
260  std::stringstream gpss; gpss<<gp; std::string gps = gpss.str();
261  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::fitlsq] - Tracking RecHit global position "<<std::setw(30)<<gps<<" and local position "<<std::setw(30)<<lps
262  <<" wrt reference csc chamber "<<refcscchamber()->id().rawId()<<" = "<<refcscchamber()->id();
263 
264  // Local position of hit w.r.t. chamber
265  double u = lp.x();
266  double v = lp.y();
267  double z = lp.z();
268 
269  // Covariance matrix of local errors
270  SMatrixSym2 IC; // 2x2, init to 0
271 
272  IC(0,0) = hit.localPositionError().xx();
273  IC(1,1) = hit.localPositionError().yy();
274  //@@ NOT SURE WHICH OFF-DIAGONAL ELEMENT MUST BE DEFINED BUT (1,0) WORKS
275  //@@ (and SMatrix enforces symmetry)
276  IC(1,0) = hit.localPositionError().xy();
277  // IC(0,1) = IC(1,0);
278 
279  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::fit] 2x2 covariance matrix for this Tracking RecHit :: [[" << IC(0,0) <<", "<< IC(0,1) <<"]["<< IC(1,0) <<","<<IC(1,1)<<"]]";
280 
281  // Invert covariance matrix (and trap if it fails!)
282  bool ok = IC.Invert();
283  if ( !ok )
284  {
285  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::fit] Failed to invert covariance matrix: \n" << IC;
286  return; // MATRIX INVERSION FAILED ... QUIT VOID FUNCTION
287  }
288 
289  // M = (AT E A)
290  // B = (AT E m)
291  // for now fill only with sum of blockdiagonal
292  // elements of (E^-1)_i = IC_i for hit i
293  M(0,0) += IC(0,0);
294  M(0,1) += IC(0,1);
295  M(0,2) += IC(0,0) * z;
296  M(0,3) += IC(0,1) * z;
297  B(0) += u * IC(0,0) + v * IC(0,1);
298 
299  M(1,0) += IC(1,0);
300  M(1,1) += IC(1,1);
301  M(1,2) += IC(1,0) * z;
302  M(1,3) += IC(1,1) * z;
303  B(1) += u * IC(1,0) + v * IC(1,1);
304 
305  M(2,0) += IC(0,0) * z;
306  M(2,1) += IC(0,1) * z;
307  M(2,2) += IC(0,0) * z * z;
308  M(2,3) += IC(0,1) * z * z;
309  B(2) += ( u * IC(0,0) + v * IC(0,1) ) * z;
310 
311  M(3,0) += IC(1,0) * z;
312  M(3,1) += IC(1,1) * z;
313  M(3,2) += IC(1,0) * z * z;
314  M(3,3) += IC(1,1) * z * z;
315  B(3) += ( u * IC(1,0) + v * IC(1,1) ) * z;
316 
317  } // End Loop over the TrackingRecHits to make the block matrices to be filled in M and B
318 
319  SVector4 p;
320  bool ok = M.Invert();
321  if (!ok )
322  {
323  edm::LogVerbatim("GEMCSCSegment|GEMCSCSegFit") << "[GEMCSCSegFit::fit] Failed to invert matrix: \n" << M;
324  return; // MATRIX INVERSION FAILED ... QUIT VOID FUNCTION
325  }
326  else
327  {
328  p = M * B;
329  }
330 
331  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::fit] p = "
332  << p(0) << ", " << p(1) << ", " << p(2) << ", " << p(3);
333 
334  // fill member variables (note origin has local z = 0)
335  // intercept_
336  intercept_ = LocalPoint(p(0), p(1), 0.);
337 
338  // localdir_ - set so segment points outwards from IP
339  uslope_ = p(2);
340  vslope_ = p(3);
341  setOutFromIP();
342 
343  // calculate chi2 of fit
344  setChi2( );
345 
346  // flag fit has been done
347  fitdone_ = true;
348 
349 }
350 
351 
352 
354 
355  double chsq = 0.;
356  bool gem = false;
357 
358  std::vector<const TrackingRecHit*>::const_iterator ih;
359  for (ih = hits_.begin(); ih != hits_.end(); ++ih) {
360 
361  const TrackingRecHit& hit = (**ih);
362  GlobalPoint gp;
363  DetId d = DetId(hit.rawId());
364  if(d.subdetId() == MuonSubdetId::GEM) {
365  const GEMEtaPartition* roll = gemetapartition(GEMDetId(d));
366  gp = roll->toGlobal(hit.localPosition());
367  gem = true;
368  }
369  else if(d.subdetId() == MuonSubdetId::CSC) {
370  const CSCLayer* layer = cscchamber(CSCDetId(d))->layer(CSCDetId(d).layer());
371  gp = layer->toGlobal(hit.localPosition());
372  gem = false;
373  }
374  else { edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit:fit2] - TrackingRecHit is not in GEM or CSC subdetector"; }
375  LocalPoint lp = refcscchamber()->toLocal(gp);
376 
377  // LogDebug
378  std::stringstream lpss; lpss<<lp; std::string lps = lpss.str();
379  std::stringstream gpss; gpss<<gp; std::string gps = gpss.str();
380  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::setChi2] - Tracking RecHit in "<<(gem? "GEM":"CSC")<<" global position "<<std::setw(30)<<gps<<" and local position "<<std::setw(30)<<lps
381  <<" wrt reference csc chamber "<<refcscchamber()->id().rawId()<<" = "<<refcscchamber()->id();
382 
383  double u = lp.x();
384  double v = lp.y();
385  double z = lp.z();
386 
387  double du = intercept_.x() + uslope_ * z - u;
388  double dv = intercept_.y() + vslope_ * z - v;
389 
390  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::setChi2] u, v, z = " << u << ", " << v << ", " << z;
391 
392  SMatrixSym2 IC; // 2x2, init to 0
393 
394  IC(0,0) = hit.localPositionError().xx();
395  // IC(0,1) = hit.localPositionError().xy();
396  IC(1,0) = hit.localPositionError().xy();
397  IC(1,1) = hit.localPositionError().yy();
398  // IC(1,0) = IC(0,1);
399 
400  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::setChi2] IC before = \n" << IC;
401 
402  // Invert covariance matrix
403  bool ok = IC.Invert();
404  if (!ok ){
405  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::setChi2] Failed to invert covariance matrix: \n" << IC;
406  return; // MATRIX INVERSION FAILED ... QUIT VOID FUNCTION
407  }
408  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::setChi2] IC after = \n" << IC;
409  chsq += du*du*IC(0,0) + 2.*du*dv*IC(0,1) + dv*dv*IC(1,1);
410  // LogDebug
411  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::setChi2] Contribution of this Tracking RecHit to Chi2: du^2*D(1,1) + 2*du*dv*D(1,2) + dv^2*D(2,2) = "
412  << du*du <<"*"<<IC(0,0)<<" + 2.*"<<du<<"*"<<dv<<"*"<<IC(0,1)<<" + "<<dv*dv<<"*"<<IC(1,1)<<" = "<<du*du*IC(0,0) + 2.*du*dv*IC(0,1) + dv*dv*IC(1,1);
413  }
414  // LogDebug
415  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::setChi2] Total Chi2 = "<<chsq;
416  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::setChi2] Total NDof = "<<2.*hits_.size() - 4;
417  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::setChi2] Total Chi2/NDof = "<<((hits_.size()>2)?(chsq/(2.*hits_.size() - 4)):(0.0));
418 
419  // fill member variables
420  chi2_ = chsq;
421  ndof_ = 2.*hits_.size() - 4;
422 
423  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::setChi2] chi2 = " << chi2_ << "/" << ndof_ << " dof";
424 
425 }
426 
427 
428 
429 
431 
432  bool ok = true;
433 
434  SMatrixSym16 matrix = ROOT::Math::SMatrixIdentity();
435  // for CSC segment :: max 6 rechits => 12x12,
436  // for GEM-CSC segment :: max 8 rechits => 16x16
437  // for all :: init to 1's on diag
438 
439  int row = 0;
440 
441  for (std::vector<const TrackingRecHit*>::const_iterator it = hits_.begin(); it != hits_.end(); ++it)
442  {
443 
444  const TrackingRecHit& hit = (**it);
445 
446  // Note scaleXError allows rescaling the x error if necessary
447 
448  matrix(row, row) = scaleXError()*hit.localPositionError().xx();
449  matrix(row, row+1) = hit.localPositionError().xy();
450  ++row;
451  matrix(row, row-1) = hit.localPositionError().xy();
452  matrix(row, row) = hit.localPositionError().yy();
453  ++row;
454  }
455 
456  ok = matrix.Invert(); // invert in place
457  if ( !ok )
458  {
459  edm::LogVerbatim("GEMCSCSegment|GEMCSCSegFit") << "[GEMCSCSegFit::weightMatrix] Failed to invert matrix: \n" << matrix;
460  SMatrixSym16 emptymatrix = ROOT::Math::SMatrixIdentity();
461  return emptymatrix; // return (empty) identity matrix if matrix inversion failed
462  }
463  return matrix;
464 }
465 
466 
467 
468 
470 
471  SMatrix16by4 matrix; // 16x4, init to 0
472  int row = 0;
473 
474  for(std::vector<const TrackingRecHit*>::const_iterator it = hits_.begin(); it != hits_.end(); ++it) {
475 
476  const TrackingRecHit& hit = (**it);
477  GlobalPoint gp;
478  DetId d = DetId(hit.rawId());
479  if(d.subdetId() == MuonSubdetId::GEM) {
480  const GEMEtaPartition* roll = gemetapartition(GEMDetId(d));
481  gp = roll->toGlobal(hit.localPosition());
482  }
483  else if(d.subdetId() == MuonSubdetId::CSC) {
484  const CSCLayer* layer = cscchamber(CSCDetId(d))->layer(CSCDetId(d).layer());
485  gp = layer->toGlobal(hit.localPosition());
486  }
487  else { edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit:fit2] - TrackingRecHit is not in GEM or CSC subdetector"; }
488  LocalPoint lp = refcscchamber()->toLocal(gp);
489  float z = lp.z();
490 
491  matrix(row, 0) = 1.;
492  matrix(row, 2) = z;
493  ++row;
494  matrix(row, 1) = 1.;
495  matrix(row, 3) = z;
496  ++row;
497  }
498  return matrix;
499 }
500 
501 
503  // Set direction of segment to point from IP outwards
504  // (Incorrect for particles not coming from IP, of course.)
505 
506  double dxdz = uslope_;
507  double dydz = vslope_;
508  double dz = 1./sqrt(1. + dxdz*dxdz + dydz*dydz);
509  double dx = dz*dxdz;
510  double dy = dz*dydz;
511  LocalVector localDir(dx,dy,dz);
512 
513  // localDir sometimes needs a sign flip
514  // Examine its direction and origin in global z: to point outward
515  // the localDir should always have same sign as global z...
516 
517  double globalZpos = ( refcscchamber()->toGlobal( intercept_ ) ).z();
518  double globalZdir = ( refcscchamber()->toGlobal( localDir ) ).z();
519  double directionSign = globalZpos * globalZdir;
520  localdir_ = (directionSign * localDir ).unit();
521 }
522 
523 
524 
526 
529  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::covarianceMatrix] weights matrix W: \n" << weights;
530  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::covarianceMatrix] derivatives matrix A: \n" << A;
531 
532  // (AT W A)^-1
533  // e.g. See http://www.phys.ufl.edu/~avery/fitting.html, part I
534 
535  bool ok;
536  SMatrixSym4 result = ROOT::Math::SimilarityT(A, weights);
537  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::covarianceMatrix] (AT W A): \n" << result;
538  ok = result.Invert(); // inverts in place
539  if ( !ok ) {
540  edm::LogVerbatim("GEMCSCSegment|GEMCSCSegFit") << "[GEMCSCSegFit::calculateError] Failed to invert matrix: \n" << result;
541  AlgebraicSymMatrix emptymatrix(4, 0. );
542  return emptymatrix; // return empty matrix if matrix inversion failed
543  }
544  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::covarianceMatrix] (AT W A)^-1: \n" << result;
545 
546  // reorder components to match TrackingRecHit interface (GEMCSCSegment isa TrackingRecHit)
547  // i.e. slopes first, then positions
548  AlgebraicSymMatrix flipped = flipErrors( result );
549 
550  return flipped;
551 }
552 
553 
555 
556  // The GEMCSCSegment needs the error matrix re-arranged to match
557  // parameters in order (uz, vz, u0, v0)
558  // where uz, vz = slopes, u0, v0 = intercepts
559 
560  edm::LogVerbatim("GEMCSCSegFit") << "[GEMCSCSegFit::flipErrors] input: \n" << a;
561 
562  AlgebraicSymMatrix hold(4, 0. );
563 
564  for ( short j=0; j!=4; ++j) {
565  for (short i=0; i!=4; ++i) {
566  hold(i+1,j+1) = a(i,j); // SMatrix counts from 0, AlgebraicMatrix from 1
567  }
568  }
569 
570  // LogTrace("GEMCSCSegFit") << "[GEMCSCSegFit::flipErrors] after copy:";
571  // LogTrace("GEMCSCSegFit") << "(" << hold(1,1) << " " << hold(1,2) << " " << hold(1,3) << " " << hold(1,4);
572  // LogTrace("GEMCSCSegFit") << " " << hold(2,1) << " " << hold(2,2) << " " << hold(2,3) << " " << hold(2,4);
573  // LogTrace("GEMCSCSegFit") << " " << hold(3,1) << " " << hold(3,2) << " " << hold(3,3) << " " << hold(3,4);
574  // LogTrace("GEMCSCSegFit") << " " << hold(4,1) << " " << hold(4,2) << " " << hold(4,3) << " " << hold(4,4) << ")";
575 
576  // errors on slopes into upper left
577  hold(1,1) = a(2,2);
578  hold(1,2) = a(2,3);
579  hold(2,1) = a(3,2);
580  hold(2,2) = a(3,3);
581 
582  // errors on positions into lower right
583  hold(3,3) = a(0,0);
584  hold(3,4) = a(0,1);
585  hold(4,3) = a(1,0);
586  hold(4,4) = a(1,1);
587 
588  // must also interchange off-diagonal elements of off-diagonal 2x2 submatrices
589  hold(4,1) = a(1,2);
590  hold(3,2) = a(0,3);
591  hold(2,3) = a(3,0); // = a(0,3)
592  hold(1,4) = a(2,1); // = a(1,2)
593 
594  // LogTrace("GEMCSCSegFit") << "[GEMCSCSegFit::flipErrors] after flip:";
595  // LogTrace("GEMCSCSegFit") << "(" << hold(1,1) << " " << hold(1,2) << " " << hold(1,3) << " " << hold(1,4);
596  // LogTrace("GEMCSCSegFit") << " " << hold(2,1) << " " << hold(2,2) << " " << hold(2,3) << " " << hold(2,4);
597  // LogTrace("GEMCSCSegFit") << " " << hold(3,1) << " " << hold(3,2) << " " << hold(3,3) << " " << hold(3,4);
598  // LogTrace("GEMCSCSegFit") << " " << hold(4,1) << " " << hold(4,2) << " " << hold(4,3) << " " << hold(4,4) << ")";
599 
600  return hold;
601 }
602 
603 float GEMCSCSegFit::xfit( float z ) const {
604  //@@ ADD THIS TO EACH ACCESSOR OF FIT RESULTS?
605  // if ( !fitdone() ) fit();
606  return intercept_.x() + uslope_ * z;
607 }
608 
609 float GEMCSCSegFit::yfit( float z ) const {
610  return intercept_.y() + vslope_ * z;
611 }
612 
613 float GEMCSCSegFit::xdev( float x, float z ) const {
614  return intercept_.x() + uslope_ * z - x;
615 }
616 
617 float GEMCSCSegFit::ydev( float y, float z ) const {
618  return intercept_.y() + vslope_ * z - y;
619 }
620 
621 float GEMCSCSegFit::Rdev(float x, float y, float z) const {
622  return sqrt ( xdev(x,z)*xdev(x,z) + ydev(y,z)*ydev(y,z) );
623 }
624 
void setChi2(void)
SMatrix16by4 derivativeMatrix(void)
float xx() const
Definition: LocalError.h:24
float xdev(float x, float z) const
std::vector< const TrackingRecHit * > hits_
Definition: GEMCSCSegFit.h:189
Point3DBase< Scalar, LocalTag > LocalPoint
Definition: Definitions.h:32
float ydev(float y, float z) const
static constexpr int GEM
Definition: MuonSubdetId.h:15
CSCDetId id() const
Get the (concrete) DetId.
Definition: CSCChamber.h:37
float Rdev(float x, float y, float z) const
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:54
ROOT::Math::SMatrix< double, 4 > SMatrix4
Definition: GEMCSCSegFit.h:60
ROOT::Math::SMatrix< double, 16, 4 > SMatrix16by4
Definition: GEMCSCSegFit.h:57
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:47
T y() const
Definition: PV3DBase.h:63
void fitlsq(void)
float xfit(float z) const
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:69
size_t nhits(void) const
Definition: GEMCSCSegFit.h:125
void fit(void)
Definition: GEMCSCSegFit.cc:20
int layer() const
Definition: CSCDetId.h:61
ROOT::Math::SVector< double, 4 > SVector4
Definition: GEMCSCSegFit.h:67
A class for AMC data.
Definition: AMC13Event.h:6
double scaleXError(void) const
Definition: GEMCSCSegFit.h:124
AlgebraicSymMatrix covarianceMatrix(void)
const CSCChamber * refcscchamber() const
Definition: GEMCSCSegFit.h:154
float xy() const
Definition: LocalError.h:25
ROOT::Math::SMatrix< double, 2, 2, ROOT::Math::MatRepSym< double, 2 > > SMatrixSym2
Definition: GEMCSCSegFit.h:64
float yy() const
Definition: LocalError.h:26
T sqrt(T t)
Definition: SSEVec.h:18
T z() const
Definition: PV3DBase.h:64
int layer() const
Layer id: each station have two layers of chambers: layer 1 is the inner chamber and layer 2 is the o...
Definition: GEMDetId.h:69
LocalVector localdir_
Definition: GEMCSCSegFit.h:193
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:41
const CSCLayer * layer(CSCDetId id) const
Return the layer corresponding to the given id.
Definition: CSCChamber.cc:39
static const std::string B
ROOT::Math::SMatrix< double, 4, 4, ROOT::Math::MatRepSym< double, 4 > > SMatrixSym4
Definition: GEMCSCSegFit.h:61
virtual LocalPoint localPosition() const =0
float yfit(float z) const
Definition: DetId.h:18
AlgebraicSymMatrix flipErrors(const SMatrixSym4 &)
bool fitdone() const
Definition: GEMCSCSegFit.h:160
LocalPoint intercept_
Definition: GEMCSCSegFit.h:192
void setOutFromIP(void)
double a
Definition: hdecay.h:121
CLHEP::HepSymMatrix AlgebraicSymMatrix
SMatrixSym16 weightMatrix(void)
virtual LocalError localPositionError() const =0
static constexpr int CSC
Definition: MuonSubdetId.h:13
T x() const
Definition: PV3DBase.h:62
id_type rawId() const
const CSCChamber * cscchamber(uint32_t id) const
Definition: GEMCSCSegFit.h:131
const GEMEtaPartition * gemetapartition(uint32_t id) const
Definition: GEMCSCSegFit.h:148
ROOT::Math::SMatrix< double, 16, 16, ROOT::Math::MatRepSym< double, 16 > > SMatrixSym16
Definition: GEMCSCSegFit.h:54
void fit2(void)
Definition: GEMCSCSegFit.cc:44