CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CSCSegAlgoDF.cc
Go to the documentation of this file.
1 
7 #include "CSCSegAlgoDF.h"
8 
10 // For clhep Matrix::solve
12 
14 
17 
19 
21 #include "CSCSegAlgoShowering.h"
22 
23 #include <algorithm>
24 #include <cmath>
25 #include <iostream>
26 #include <string>
27 
28 
29 /* Constructor
30  *
31  */
32 CSCSegAlgoDF::CSCSegAlgoDF(const edm::ParameterSet& ps) : CSCSegmentAlgorithm(ps), myName("CSCSegAlgoDF") {
33 
34  debug = ps.getUntrackedParameter<bool>("CSCSegmentDebug");
35  minLayersApart = ps.getParameter<int>("minLayersApart");
36  minHitsPerSegment = ps.getParameter<int>("minHitsPerSegment");
37  dRPhiFineMax = ps.getParameter<double>("dRPhiFineMax");
38  dPhiFineMax = ps.getParameter<double>("dPhiFineMax");
39  tanThetaMax = ps.getParameter<double>("tanThetaMax");
40  tanPhiMax = ps.getParameter<double>("tanPhiMax");
41  chi2Max = ps.getParameter<double>("chi2Max");
42  preClustering = ps.getUntrackedParameter<bool>("preClustering");
43  minHitsForPreClustering= ps.getParameter<int>("minHitsForPreClustering");
44  nHitsPerClusterIsShower= ps.getParameter<int>("nHitsPerClusterIsShower");
45  Pruning = ps.getUntrackedParameter<bool>("Pruning");
46  maxRatioResidual = ps.getParameter<double>("maxRatioResidualPrune");
47 
49  showering_ = new CSCSegAlgoShowering( ps );
50 }
51 
52 
53 /* Destructor
54  *
55  */
57  delete preCluster_;
58  delete showering_;
59 }
60 
61 
62 /* run
63  *
64  */
65 std::vector<CSCSegment> CSCSegAlgoDF::run(const CSCChamber* aChamber, ChamberHitContainer rechits) {
66 
67  // Store chamber info in temp memory
68  theChamber = aChamber;
69 
70  int nHits = rechits.size();
71 
72  // Segments prior to pruning
73  std::vector<CSCSegment> segments_temp;
74 
75  if ( preClustering && nHits > minHitsForPreClustering ) {
76  // This is where the segment origin is in the chamber on avg.
77  std::vector<CSCSegment> testSegments;
78  std::vector<ChamberHitContainer> clusteredHits = preCluster_->clusterHits(theChamber, rechits);
79  // loop over the found clusters:
80  for (std::vector<ChamberHitContainer>::iterator subrechits = clusteredHits.begin(); subrechits != clusteredHits.end(); ++subrechits ) {
81  // build the subset of segments:
82  std::vector<CSCSegment> segs = buildSegments( (*subrechits) );
83  // add the found subset of segments to the collection of all segments in this chamber:
84  segments_temp.insert( segments_temp.end(), segs.begin(), segs.end() );
85  }
86  } else {
87  std::vector<CSCSegment> segs = buildSegments( rechits );
88  // add the found subset of segments to the collection of all segments in this chamber:
89  segments_temp.insert( segments_temp.end(), segs.begin(), segs.end() );
90  }
91 
92  return segments_temp;
93 }
94 
95 
96 /* This builds segments by first creating proto-segments from at least 3 hits.
97  * We intend to try all possible pairs of hits to start segment building. 'All possible'
98  * means each hit lies on different layers in the chamber. Once a hit has been assigned
99  * to a segment, we don't consider it again, THAT IS, FOR THE FIRST PASS ONLY !
100  * In fact, this is one of the possible flaw with the SK algorithms as it sometimes manages
101  * to build segments with the wrong starting points. In the DF algorithm, the endpoints
102  * are tested as the best starting points in a 2nd loop.
103  *
104  * Also, only a certain muonsPerChamberMax maximum number of segments can be produced in the chamber
105  */
107 
108  // Clear buffer for segment vector
109  std::vector<CSCSegment> segmentInChamber;
110  segmentInChamber.clear();
111 
112  unsigned nHitInChamber = rechits.size();
113  if ( nHitInChamber < 3 ) return segmentInChamber;
114 
115  LayerIndex layerIndex( nHitInChamber );
116 
117  unsigned nLayers = 0;
118  int old_layer = -1;
119  for ( unsigned int i = 0; i < nHitInChamber; i++ ) {
120  int this_layer = rechits[i]->cscDetId().layer();
121  layerIndex[i] = this_layer;
122  if ( this_layer != old_layer ) {
123  old_layer = this_layer;
124  nLayers++;
125  }
126  }
127 
128  if ( nLayers < 3 ) return segmentInChamber;
129 
130  double z1 = theChamber->layer(1)->position().z();
131  double z6 = theChamber->layer(6)->position().z();
132 
133  if ( z1 > 0. ) {
134  if ( z1 > z6 ) {
135  reverse( layerIndex.begin(), layerIndex.end() );
136  reverse( rechits.begin(), rechits.end() );
137  }
138  }
139  else if ( z1 < 0. ) {
140  if ( z1 < z6 ) {
141  reverse( layerIndex.begin(), layerIndex.end() );
142  reverse( rechits.begin(), rechits.end() );
143  }
144  }
145 
146  // Showering muon
147  if ( preClustering && int(nHitInChamber) > nHitsPerClusterIsShower && nLayers > 2 ) {
148  CSCSegment segShower = showering_->showerSeg(theChamber, rechits);
149 
150  // Make sure have at least 3 hits...
151  if ( segShower.nRecHits() < 3 ) return segmentInChamber;
152 
153  segmentInChamber.push_back(segShower);
154 
155  return segmentInChamber;
156  }
157 
158 
159  // Initialize flags that a given hit has been allocated to a segment
160  BoolContainer used_ini(rechits.size(), false);
161  usedHits = used_ini;
162 
163  ChamberHitContainerCIt ib = rechits.begin();
164  ChamberHitContainerCIt ie = rechits.end();
165 
166  // Now Loop over hits within the chamber to find 1st seed for segment building
167  for ( ChamberHitContainerCIt i1 = ib; i1 < ie; ++i1 ) {
168  if ( usedHits[i1-ib] ) continue;
169 
170  const CSCRecHit2D* h1 = *i1;
171  int layer1 = layerIndex[i1-ib];
172  const CSCLayer* l1 = theChamber->layer(layer1);
173  GlobalPoint gp1 = l1->toGlobal(h1->localPosition());
174  LocalPoint lp1 = theChamber->toLocal(gp1);
175 
176  // Loop over hits backward to find 2nd seed for segment building
177  for ( ChamberHitContainerCIt i2 = ie-1; i2 > ib; --i2 ) {
178 
179  if ( usedHits[i2-ib] ) continue; // Hit has been used already
180 
181  int layer2 = layerIndex[i2-ib];
182  if ( (layer2 - layer1) < minLayersApart ) continue;
183 
184  const CSCRecHit2D* h2 = *i2;
185  const CSCLayer* l2 = theChamber->layer(layer2);
186  GlobalPoint gp2 = l2->toGlobal(h2->localPosition());
187  LocalPoint lp2 = theChamber->toLocal(gp2);
188 
189  // Clear proto segment so it can be (re)-filled
190  protoSegment.clear();
191 
192  // localPosition is position of hit wrt layer (so local z = 0)
194 
195  // We want hit wrt chamber (and local z will be != 0)
196  float dz = gp2.z()-gp1.z();
197  protoSlope_u = (lp2.x() - lp1.x())/dz ;
198  protoSlope_v = (lp2.y() - lp1.y())/dz ;
199 
200  // Test if entrance angle is roughly pointing towards IP
201  if (fabs(protoSlope_v) > tanThetaMax) continue;
202  if (fabs(protoSlope_u) > tanPhiMax ) continue;
203 
204  protoSegment.push_back(h1);
205  protoSegment.push_back(h2);
206 
207  // Try adding hits to proto segment
208  tryAddingHitsToSegment(rechits, i1, i2, layerIndex);
209 
210  // Check no. of hits on segment to see if segment is large enough
211  bool segok = true;
212  unsigned iadd = 0;
213 
214  if (protoSegment.size() < minHitsPerSegment+iadd) segok = false;
215 
216  if ( Pruning && segok ) pruneFromResidual();
217 
218  // Check if segment satisfies chi2 requirement
219  if (protoChi2 > chi2Max) segok = false;
220 
221  if ( segok ) {
222 
223  // Fill segment properties
224 
225  // Local direction
226  double dz = 1./sqrt(1. + protoSlope_u*protoSlope_u + protoSlope_v*protoSlope_v);
227  double dx = dz * protoSlope_u;
228  double dy = dz * protoSlope_v;
229  LocalVector localDir(dx,dy,dz);
230 
231  // localDir may need sign flip to ensure it points outward from IP
232  double globalZpos = ( theChamber->toGlobal( protoIntercept ) ).z();
233  double globalZdir = ( theChamber->toGlobal( localDir ) ).z();
234  double directionSign = globalZpos * globalZdir;
235  protoDirection = (directionSign * localDir).unit();
236 
237  // Error matrix
238  AlgebraicSymMatrix protoErrors = calculateError();
239  // but reorder components to match what's required by TrackingRecHit interface
240  // i.e. slopes first, then positions
241  flipErrors( protoErrors );
242 
244 
245  segmentInChamber.push_back(temp);
246 
247  if (nHitInChamber-protoSegment.size() < 3) return segmentInChamber;
248  if (segmentInChamber.size() > 4) return segmentInChamber;
249 
250  // Flag used hits
251  flagHitsAsUsed(rechits);
252  }
253  }
254  }
255  return segmentInChamber;
256 }
257 
258 
259 /* Method tryAddingHitsToSegment
260  *
261  * Look at left over hits and try to add them to proto segment by looking how far they
262  * are from the segment in terms of the hit error matrix (so how many sigmas away).
263  *
264  */
266  const ChamberHitContainerCIt i1,
267  const ChamberHitContainerCIt i2,
268  LayerIndex layerIndex ) {
269 
270 /* Iterate over the layers with hits in the chamber
271  * Skip the layers containing the segment endpoints on first pass, but then
272  * try hits on layer containing the segment starting points on 2nd pass
273  * if segment has >2 hits. Once a hit is added to a layer, don't replace it
274  * until 2nd iteration
275  */
276 
277  ChamberHitContainerCIt ib = rechits.begin();
278  ChamberHitContainerCIt ie = rechits.end();
279  closeHits.clear();
280 
281  for ( ChamberHitContainerCIt i = ib; i != ie; ++i ) {
282 
283  if (i == i1 || i == i2 ) continue;
284  if ( usedHits[i-ib] ) continue; // Don't use hits already part of a segment.
285 
286  const CSCRecHit2D* h = *i;
287  int layer = layerIndex[i-ib];
288  int layer1 = layerIndex[i1-ib];
289  int layer2 = layerIndex[i2-ib];
290 
291  // Low multiplicity case
292  if (rechits.size() < 9) {
293  if ( isHitNearSegment( h ) ) {
294  if ( !hasHitOnLayer(layer) ) {
295  addHit(h, layer);
296  } else {
297  closeHits.push_back(h);
298  }
299  }
300 
301  // High multiplicity case
302  } else {
303  if ( isHitNearSegment( h ) ) {
304  if ( !hasHitOnLayer(layer) ) {
305  addHit(h, layer);
307  // Don't change the starting points at this stage !!!
308  } else {
309  closeHits.push_back(h);
310  if (layer != layer1 && layer != layer2 ) compareProtoSegment(h, layer);
311  }
312  }
313  }
314  }
315 
316  if ( int(protoSegment.size()) < 3) return;
317 
319 
320  // 2nd pass to remove biases
321  // This time, also consider changing the endpoints
322  for ( ChamberHitContainerCIt i = closeHits.begin() ; i != closeHits.end(); ++i ) {
323  const CSCRecHit2D* h = *i;
324  int layer = (*i)->cscDetId().layer();
325  compareProtoSegment(h, layer);
326  }
327 
328 }
329 
330 
331 /* isHitNearSegment
332  *
333  * Compare rechit with expected position from proto_segment
334  */
336 
337  const CSCLayer* layer = theChamber->layer(hit->cscDetId().layer());
338 
339  // hit phi position in global coordinates
340  GlobalPoint Hgp = layer->toGlobal(hit->localPosition());
341  double Hphi = Hgp.phi();
342  if (Hphi < 0.) Hphi += 2.*M_PI;
343  LocalPoint Hlp = theChamber->toLocal(Hgp);
344  double z = Hlp.z();
345 
346  double LocalX = protoIntercept.x() + protoSlope_u * z;
347  double LocalY = protoIntercept.y() + protoSlope_v * z;
348  LocalPoint Slp(LocalX, LocalY, z);
349  GlobalPoint Sgp = theChamber->toGlobal(Slp);
350  double Sphi = Sgp.phi();
351  if (Sphi < 0.) Sphi += 2.*M_PI;
352  double R = sqrt(Sgp.x()*Sgp.x() + Sgp.y()*Sgp.y());
353 
354  double deltaPhi = Sphi - Hphi;
355  if (deltaPhi > 2.*M_PI) deltaPhi -= 2.*M_PI;
356  if (deltaPhi < -2.*M_PI) deltaPhi += 2.*M_PI;
357  if (deltaPhi < 0.) deltaPhi = -deltaPhi;
358 
359  double RdeltaPhi = R * deltaPhi;
360 
361  if (RdeltaPhi < dRPhiFineMax && deltaPhi < dPhiFineMax ) return true;
362 
363  return false;
364 }
365 
366 
367 /* Method addHit
368  *
369  * Test if can add hit to proto segment. If so, try to add it.
370  *
371  */
372 bool CSCSegAlgoDF::addHit(const CSCRecHit2D* aHit, int layer) {
373 
374  // Return true if hit was added successfully and then parameters are updated.
375  // Return false if there is already a hit on the same layer, or insert failed.
376 
377  bool ok = true;
378 
379  // Test that we are not trying to add the same hit again
380  for ( ChamberHitContainer::const_iterator it = protoSegment.begin(); it != protoSegment.end(); it++ )
381  if ( aHit == (*it) ) return false;
382 
383  protoSegment.push_back(aHit);
384 
385  return ok;
386 }
387 
388 
389 /* Method updateParameters
390  *
391  * Perform a simple Least Square Fit on proto segment to determine slope and intercept
392  *
393  */
395 
396  // Compute slope from Least Square Fit
397  CLHEP::HepMatrix M(4,4,0);
398  CLHEP::HepVector B(4,0);
399 
400  ChamberHitContainer::const_iterator ih;
401 
402  for (ih = protoSegment.begin(); ih != protoSegment.end(); ++ih) {
403 
404  const CSCRecHit2D& hit = (**ih);
405  const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
406  GlobalPoint gp = layer->toGlobal(hit.localPosition());
407  LocalPoint lp = theChamber->toLocal(gp);
408 
409  double u = lp.x();
410  double v = lp.y();
411  double z = lp.z();
412 
413  // ptc: Covariance matrix of local errors
414  CLHEP::HepMatrix IC(2,2);
415  IC(1,1) = hit.localPositionError().xx();
416  IC(1,2) = hit.localPositionError().xy();
417  IC(2,2) = hit.localPositionError().yy();
418  IC(2,1) = IC(1,2); // since Cov is symmetric
419 
420  // ptc: Invert covariance matrix (and trap if it fails!)
421  int ierr = 0;
422  IC.invert(ierr); // inverts in place
423  if (ierr != 0) {
424  LogDebug("CSC") << "CSCSegment::fitSlopes: failed to invert covariance matrix=\n" << IC << "\n";
425  }
426 
427  M(1,1) += IC(1,1);
428  M(1,2) += IC(1,2);
429  M(1,3) += IC(1,1) * z;
430  M(1,4) += IC(1,2) * z;
431  B(1) += u * IC(1,1) + v * IC(1,2);
432 
433  M(2,1) += IC(2,1);
434  M(2,2) += IC(2,2);
435  M(2,3) += IC(2,1) * z;
436  M(2,4) += IC(2,2) * z;
437  B(2) += u * IC(2,1) + v * IC(2,2);
438 
439  M(3,1) += IC(1,1) * z;
440  M(3,2) += IC(1,2) * z;
441  M(3,3) += IC(1,1) * z * z;
442  M(3,4) += IC(1,2) * z * z;
443  B(3) += ( u * IC(1,1) + v * IC(1,2) ) * z;
444 
445  M(4,1) += IC(2,1) * z;
446  M(4,2) += IC(2,2) * z;
447  M(4,3) += IC(2,1) * z * z;
448  M(4,4) += IC(2,2) * z * z;
449  B(4) += ( u * IC(2,1) + v * IC(2,2) ) * z;
450  }
451 
452  CLHEP::HepVector p = solve(M, B);
453 
454  // Update member variables
455  // Note that origin has local z = 0
456 
457  protoIntercept = LocalPoint(p(1), p(2), 0.);
458  protoSlope_u = p(3);
459  protoSlope_v = p(4);
460 
461 
462  // Determine Chi^2 for the proto wire segment
463 
464  double chsq = 0.;
465 
466  for (ih = protoSegment.begin(); ih != protoSegment.end(); ++ih) {
467 
468  const CSCRecHit2D& hit = (**ih);
469  const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
470  GlobalPoint gp = layer->toGlobal(hit.localPosition());
471  LocalPoint lp = theChamber->toLocal(gp);
472 
473  double u = lp.x();
474  double v = lp.y();
475  double z = lp.z();
476 
477  double du = protoIntercept.x() + protoSlope_u * z - u;
478  double dv = protoIntercept.y() + protoSlope_v * z - v;
479 
480  CLHEP::HepMatrix IC(2,2);
481  IC(1,1) = hit.localPositionError().xx();
482  IC(1,2) = hit.localPositionError().xy();
483  IC(2,2) = hit.localPositionError().yy();
484  IC(2,1) = IC(1,2);
485 
486  // Invert covariance matrix
487  int ierr = 0;
488  IC.invert(ierr);
489  if (ierr != 0) {
490  LogDebug("CSC") << "CSCSegment::fillChiSquared: failed to invert covariance matrix=\n" << IC << "\n";
491  }
492  chsq += du*du*IC(1,1) + 2.*du*dv*IC(1,2) + dv*dv*IC(2,2);
493  }
494  protoChi2 = chsq;
495 }
496 
497 
498 /* hasHitOnLayer
499  *
500  * Just make sure hit to be added to layer comes from different layer than those in proto segment
501  */
502 bool CSCSegAlgoDF::hasHitOnLayer(int layer) const {
503 
504  // Is there already a hit on this layer?
505  for ( ChamberHitContainerCIt it = protoSegment.begin(); it != protoSegment.end(); it++ )
506  if ( (*it)->cscDetId().layer() == layer ) return true;
507 
508  return false;
509 }
510 
511 
512 /* Method compareProtoSegment
513  *
514  * For hit coming from the same layer of an existing hit within the proto segment
515  * test if achieve better chi^2 by using this hit than the other
516  *
517  */
519 
520  // Store old segment first
521  double old_protoChi2 = protoChi2;
522  LocalPoint old_protoIntercept = protoIntercept;
523  float old_protoSlope_u = protoSlope_u;
524  float old_protoSlope_v = protoSlope_v;
525  LocalVector old_protoDirection = protoDirection;
526  ChamberHitContainer old_protoSegment = protoSegment;
527 
528 
529  // Try adding the hit to existing segment, and remove old one existing in same layer
530  ChamberHitContainer::iterator it;
531  for ( it = protoSegment.begin(); it != protoSegment.end(); ) {
532  if ( (*it)->cscDetId().layer() == layer ) {
533  it = protoSegment.erase(it);
534  } else {
535  ++it;
536  }
537  }
538  bool ok = addHit(h, layer);
539 
540  if (ok) updateParameters();
541 
542  if ( (protoChi2 > old_protoChi2) || ( !ok ) ) {
543  protoChi2 = old_protoChi2;
544  protoIntercept = old_protoIntercept;
545  protoSlope_u = old_protoSlope_u;
546  protoSlope_v = old_protoSlope_v;
547  protoDirection = old_protoDirection;
548  protoSegment = old_protoSegment;
549  }
550 }
551 
552 
553 /* Method flagHitsAsUsed
554  *
555  * Flag hits which have entered segment building so we don't reuse them.
556  * Also flag does which were very close to segment to reduce combinatorics
557  */
558 void CSCSegAlgoDF::flagHitsAsUsed(const ChamberHitContainer& rechitsInChamber) {
559 
560  // Flag hits on segment as used
561  ChamberHitContainerCIt ib = rechitsInChamber.begin();
562  ChamberHitContainerCIt hi, iu;
563 
564  for ( hi = protoSegment.begin(); hi != protoSegment.end(); ++hi ) {
565  for ( iu = ib; iu != rechitsInChamber.end(); ++iu ) {
566  if (*hi == *iu) usedHits[iu-ib] = true;
567  }
568  }
569  // Don't reject hits marked as "nearby" for now.
570  // So this is bypassed at all times for now !!!
571  // Perhaps add back to speed up algorithm some more
572  if (closeHits.size() > 0) return;
573  for ( hi = closeHits.begin(); hi != closeHits.end(); ++hi ) {
574  for ( iu = ib; iu != rechitsInChamber.end(); ++iu ) {
575  if (*hi == *iu) usedHits[iu-ib] = true;
576  }
577  }
578 
579 }
580 
581 
583 
584  std::vector<const CSCRecHit2D*>::const_iterator it;
585  int nhits = protoSegment.size();
586  AlgebraicSymMatrix matrix(2*nhits, 0);
587  int row = 0;
588 
589  for (it = protoSegment.begin(); it != protoSegment.end(); ++it) {
590 
591  const CSCRecHit2D& hit = (**it);
592  ++row;
593  matrix(row, row) = hit.localPositionError().xx();
594  matrix(row, row+1) = hit.localPositionError().xy();
595  ++row;
596  matrix(row, row-1) = hit.localPositionError().xy();
597  matrix(row, row) = hit.localPositionError().yy();
598  }
599  int ierr;
600  matrix.invert(ierr);
601  return matrix;
602 }
603 
604 
605 CLHEP::HepMatrix CSCSegAlgoDF::derivativeMatrix() const {
606 
607  ChamberHitContainer::const_iterator it;
608  int nhits = protoSegment.size();
609  CLHEP::HepMatrix matrix(2*nhits, 4);
610  int row = 0;
611 
612  for(it = protoSegment.begin(); it != protoSegment.end(); ++it) {
613 
614  const CSCRecHit2D& hit = (**it);
615  const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
616  GlobalPoint gp = layer->toGlobal(hit.localPosition());
617  LocalPoint lp = theChamber->toLocal(gp);
618  float z = lp.z();
619  ++row;
620  matrix(row, 1) = 1.;
621  matrix(row, 3) = z;
622  ++row;
623  matrix(row, 2) = 1.;
624  matrix(row, 4) = z;
625  }
626  return matrix;
627 }
628 
629 /* calculateError
630  *
631  */
633 
636 
637  // (AT W A)^-1
638  // from http://www.phys.ufl.edu/~avery/fitting.html, part I
639  int ierr;
640  AlgebraicSymMatrix result = weights.similarityT(A);
641  result.invert(ierr);
642 
643  // blithely assuming the inverting never fails...
644  return result;
645 }
646 
648 
649  // The CSCSegment needs the error matrix re-arranged
650 
651  AlgebraicSymMatrix hold( a );
652 
653  // errors on slopes into upper left
654  a(1,1) = hold(3,3);
655  a(1,2) = hold(3,4);
656  a(2,1) = hold(4,3);
657  a(2,2) = hold(4,4);
658 
659  // errors on positions into lower right
660  a(3,3) = hold(1,1);
661  a(3,4) = hold(1,2);
662  a(4,3) = hold(2,1);
663  a(4,4) = hold(2,2);
664 
665  // off-diagonal elements remain unchanged
666 
667 }
668 
669 
670 // Try to clean up segments by quickly looking at residuals
672 
673  // Only prune if have at least 5 hits
674  if ( protoSegment.size() < 5 ) return ;
675 
676 
677  // Now Study residuals
678 
679  float maxResidual = 0.;
680  float sumResidual = 0.;
681  int nHits = 0;
682  int badIndex = -1;
683  int j = 0;
684 
685 
686  ChamberHitContainer::const_iterator ih;
687 
688  for ( ih = protoSegment.begin(); ih != protoSegment.end(); ++ih ) {
689  const CSCRecHit2D& hit = (**ih);
690  const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
691  GlobalPoint gp = layer->toGlobal(hit.localPosition());
692  LocalPoint lp = theChamber->toLocal(gp);
693 
694  double u = lp.x();
695  double v = lp.y();
696  double z = lp.z();
697 
698  double du = protoIntercept.x() + protoSlope_u * z - u;
699  double dv = protoIntercept.y() + protoSlope_v * z - v;
700 
701  float residual = sqrt(du*du + dv*dv);
702 
703  sumResidual += residual;
704  nHits++;
705  if ( residual > maxResidual ) {
706  maxResidual = residual;
707  badIndex = j;
708  }
709  j++;
710  }
711 
712  float corrAvgResidual = (sumResidual - maxResidual)/(nHits -1);
713 
714  // Keep all hits
715  if ( maxResidual/corrAvgResidual < maxRatioResidual ) return;
716 
717 
718  // Drop worse hit and recompute segment properties + fill
719 
720  ChamberHitContainer newProtoSegment;
721 
722  j = 0;
723  for ( ih = protoSegment.begin(); ih != protoSegment.end(); ++ih ) {
724  if ( j != badIndex ) newProtoSegment.push_back(*ih);
725  j++;
726  }
727 
728  protoSegment.clear();
729 
730  for ( ih = newProtoSegment.begin(); ih != newProtoSegment.end(); ++ih ) {
731  protoSegment.push_back(*ih);
732  }
733 
734  // Update segment parameters
736 
737 }
738 
739 
740 /*
741  * Order the hits such that 2nd one is closest in x,y to first seed hit in global coordinates
742  */
744  const ChamberHitContainerCIt i1,
745  const ChamberHitContainerCIt i2,
747  LayerIndex layerIndex ) {
748 
749  secondSeedHits.clear();
750 
751  //ChamberHitContainerCIt ib = rechits.begin();
752  ChamberHitContainerCIt ie = rechits.end();
753 
754  // int layer1 = layerIndex[i1-ib];
755  // int layer2 = layerIndex[i2-ib];
756 
757 
758  // Now fill vector of rechits closest to center of mass:
759  // secondSeedHitsIdx.clear() = 0;
760 
761  // Loop over all hits and find hit closest to 1st seed.
762  for ( ChamberHitContainerCIt i2 = ie-1; i2 > i1; --i2 ) {
763 
764 
765  }
766 
767 
768 }
#define LogDebug(id)
void flipErrors(AlgebraicSymMatrix &) const
std::vector< CSCSegment > run(const CSCChamber *aChamber, ChamberHitContainer rechits)
Definition: CSCSegAlgoDF.cc:65
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
float xx() const
Definition: LocalError.h:24
ChamberHitContainer protoSegment
Definition: CSCSegAlgoDF.h:135
std::vector< const CSCRecHit2D * > ChamberHitContainer
Definition: CSCSegAlgoDF.h:55
std::vector< const CSCRecHit2D * >::const_iterator ChamberHitContainerCIt
Definition: CSCSegAlgoDF.h:56
CSCSegment showerSeg(const CSCChamber *aChamber, ChamberHitContainer rechits)
CSCDetId cscDetId() const
Definition: CSCRecHit2D.h:52
AlgebraicSymMatrix weightMatrix(void) const
CLHEP::HepMatrix derivativeMatrix(void) const
virtual ~CSCSegAlgoDF()
Destructor.
Definition: CSCSegAlgoDF.cc:56
CSCSegAlgoPreClustering * preCluster_
Definition: CSCSegAlgoDF.h:161
double_binary B
Definition: DDStreamer.cc:234
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:47
Geom::Phi< T > phi() const
Definition: PV3DBase.h:68
T y() const
Definition: PV3DBase.h:62
ChamberHitContainer closeHits
Definition: CSCSegAlgoDF.h:133
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:62
bool addHit(const CSCRecHit2D *hit, int layer)
void orderSecondSeed(GlobalPoint gp1, const ChamberHitContainerCIt i1, const ChamberHitContainerCIt i2, const ChamberHitContainer &rechits, LayerIndex layerIndex)
bool isHitNearSegment(const CSCRecHit2D *h) const
CSCSegAlgoDF(const edm::ParameterSet &ps)
Constructor.
Definition: CSCSegAlgoDF.cc:32
CSCSegAlgoShowering * showering_
Definition: CSCSegAlgoDF.h:162
int layer() const
Definition: CSCDetId.h:63
ChamberHitContainer secondSeedHits
Definition: CSCSegAlgoDF.h:136
double double double z
bool preClustering
Definition: CSCSegAlgoDF.h:145
float xy() const
Definition: LocalError.h:25
void updateParameters(void)
std::deque< bool > BoolContainer
Definition: CSCSegAlgoDF.h:57
const Surface::PositionType & position() const
The position (origin of the R.F.)
Definition: GeomDet.h:41
int nRecHits() const
Definition: CSCSegment.h:68
std::vector< std::vector< const CSCRecHit2D * > > clusterHits(const CSCChamber *aChamber, ChamberHitContainer rechits)
clusterize
CLHEP::HepMatrix AlgebraicMatrix
LocalError localPositionError() const
Definition: CSCRecHit2D.h:51
float yy() const
Definition: LocalError.h:26
LocalPoint protoIntercept
Definition: CSCSegAlgoDF.h:139
string unit
Definition: csvLumiCalc.py:46
T sqrt(T t)
Definition: SSEVec.h:46
void compareProtoSegment(const CSCRecHit2D *h, int layer)
T z() const
Definition: PV3DBase.h:63
tuple result
Definition: query.py:137
std::vector< CSCSegment > buildSegments(ChamberHitContainer rechits)
int j
Definition: DBlmapReader.cc:9
const CSCLayer * layer(CSCDetId id) const
Return the layer corresponding to the given id.
Definition: CSCChamber.cc:41
std::vector< int > LayerIndex
Typedefs.
Definition: CSCSegAlgoDF.h:54
float maxRatioResidual
Definition: CSCSegAlgoDF.h:159
int minHitsForPreClustering
Definition: CSCSegAlgoDF.h:146
float protoSlope_v
Definition: CSCSegAlgoDF.h:138
#define M_PI
Definition: BFit3D.cc:3
void flagHitsAsUsed(const ChamberHitContainer &rechitsInChamber)
float tanThetaMax
Definition: CSCSegAlgoDF.h:157
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
double dPhiFineMax
Definition: CSCSegAlgoDF.h:155
float protoSlope_u
Definition: CSCSegAlgoDF.h:137
double dRPhiFineMax
Definition: CSCSegAlgoDF.h:154
double a
Definition: hdecay.h:121
void pruneFromResidual()
CLHEP::HepSymMatrix AlgebraicSymMatrix
double protoChi2
Definition: CSCSegAlgoDF.h:140
Local3DPoint LocalPoint
Definition: LocalPoint.h:11
void tryAddingHitsToSegment(const ChamberHitContainer &rechitsInChamber, const ChamberHitContainerCIt i1, const ChamberHitContainerCIt i2, LayerIndex layerIndex)
Utility functions.
AlgebraicSymMatrix calculateError(void) const
const CSCChamber * theChamber
Definition: CSCSegAlgoDF.h:130
LocalVector protoDirection
Definition: CSCSegAlgoDF.h:141
LocalPoint localPosition() const
Definition: CSCRecHit2D.h:50
int minHitsPerSegment
Definition: CSCSegAlgoDF.h:152
int nHitsPerClusterIsShower
Definition: CSCSegAlgoDF.h:150
T x() const
Definition: PV3DBase.h:61
BoolContainer usedHits
Definition: CSCSegAlgoDF.h:131
mathSSE::Vec4< T > v
bool hasHitOnLayer(int layer) const