CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CSCSegAlgoHitPruning.cc
Go to the documentation of this file.
1 
13 
19 
22 
23 #include <algorithm>
24 #include <cmath>
25 #include <iostream>
26 #include <string>
27 
28 
29 /* Constructor
30  *
31  */
33  BrutePruning = ps.getParameter<bool>("BrutePruning");
34 
35 }
36 
37 
38 /* Destructor:
39  *
40  */
42 
43 }
44 
45 
46 /* pruneBadHits
47  *
48  */
49 std::vector<CSCSegment> CSCSegAlgoHitPruning::pruneBadHits(const CSCChamber* aChamber, const std::vector<CSCSegment>& _segments) {
50 
51  theChamber = aChamber;
52 
53  std::vector<CSCSegment> segments_temp;
54  std::vector<ChamberHitContainer> rechits_clusters;
55  std::vector<CSCSegment> segments = _segments;
56  const float chi2ndfProbMin = 1.0e-4;
57  bool use_brute_force = BrutePruning;
58 
59  int hit_nr = 0;
60  int hit_nr_worst = -1;
61  //int hit_nr_2ndworst = -1;
62 
63  for (std::vector<CSCSegment>::iterator it=segments.begin(); it != segments.end(); it++) {
64 
65  if ( !use_brute_force ) {// find worst hit
66 
67  float chisq = (*it).chi2();
68  int nhits = (*it).nRecHits();
69  LocalPoint localPos = (*it).localPosition();
70  LocalVector segDir = (*it).localDirection();
71  const CSCChamber* cscchamber = theChamber;
72  float globZ ;
73 
74  GlobalPoint globalPosition = cscchamber->toGlobal(localPos);
75  globZ = globalPosition.z();
76 
77 
78  if ( ChiSquaredProbability((double)chisq,(double)(2*nhits-4)) < chi2ndfProbMin ) {
79 
80  // find (rough) "residuals" (NOT excluding the hit from the fit - speed!) of hits on segment
81  std::vector<CSCRecHit2D> theseRecHits = (*it).specificRecHits();
82  std::vector<CSCRecHit2D>::const_iterator iRH_worst;
83  //float xdist_local = -99999.;
84 
85  float xdist_local_worst_sig = -99999.;
86  float xdist_local_2ndworst_sig = -99999.;
87  float xdist_local_sig = -99999.;
88 
89  hit_nr = 0;
90  hit_nr_worst = -1;
91  //hit_nr_2ndworst = -1;
92 
93  for ( std::vector<CSCRecHit2D>::const_iterator iRH = theseRecHits.begin(); iRH != theseRecHits.end(); iRH++ ) {
94  //mark "worst" hit:
95 
96  //float z_at_target ;
97  //float radius ;
98  float loc_x_at_target ;
99  //float loc_y_at_target ;
100  //float loc_z_at_target ;
101 
102  //z_at_target = 0.;
103  loc_x_at_target = 0.;
104  //loc_y_at_target = 0.;
105  //loc_z_at_target = 0.;
106  //radius = 0.;
107 
108  // set the z target in CMS global coordinates:
109  const CSCLayer* csclayerRH = theChamber->layer((*iRH).cscDetId().layer());
110  LocalPoint localPositionRH = (*iRH).localPosition();
111  GlobalPoint globalPositionRH = csclayerRH->toGlobal(localPositionRH);
112 
113  LocalError rerrlocal = (*iRH).localPositionError();
114  float xxerr = rerrlocal.xx();
115 
116  float target_z = globalPositionRH.z(); // target z position in cm (z pos of the hit)
117 
118  loc_x_at_target = localPos.x() + (segDir.x()*( target_z - globZ ));
119  //loc_y_at_target = localPos.y() + (segDir.y()*( target_z - globZ ));
120  //loc_z_at_target = target_z;
121 
122  // have to transform the segments coordinates back to the local frame... how?!!!!!!!!!!!!
123 
124  //xdist_local = fabs(localPositionRH.x() - loc_x_at_target);
125  xdist_local_sig = fabs((localPositionRH.x() -loc_x_at_target)/(xxerr));
126 
127  if( xdist_local_sig > xdist_local_worst_sig ) {
128  xdist_local_2ndworst_sig = xdist_local_worst_sig;
129  xdist_local_worst_sig = xdist_local_sig;
130  iRH_worst = iRH;
131  //hit_nr_2ndworst = hit_nr_worst;
132  hit_nr_worst = hit_nr;
133  }
134  else if(xdist_local_sig > xdist_local_2ndworst_sig) {
135  xdist_local_2ndworst_sig = xdist_local_sig;
136  //hit_nr_2ndworst = hit_nr;
137  }
138  ++hit_nr;
139  }
140 
141  // reset worst hit number if certain criteria apply.
142  // Criteria: 2nd worst hit must be at least a factor of
143  // 1.5 better than the worst in terms of sigma:
144  if ( xdist_local_worst_sig / xdist_local_2ndworst_sig < 1.5 ) {
145  hit_nr_worst = -1;
146  //hit_nr_2ndworst = -1;
147  }
148  }
149  }
150 
151  // if worst hit was found, refit without worst hit and select if considerably better than original fit.
152  // Can also use brute force: refit all n-1 hit segments and choose one over the n hit if considerably "better"
153 
154  std::vector< CSCRecHit2D > buffer;
155  std::vector< std::vector< CSCRecHit2D > > reduced_segments;
156  std::vector< CSCRecHit2D > theseRecHits = (*it).specificRecHits();
157  float best_red_seg_prob = 0.0;
158  // usefor chi2 1 diff float best_red_seg_prob = 99999.;
159  buffer.clear();
160  if( ChiSquaredProbability((double)(*it).chi2(),(double)((2*(*it).nRecHits())-4)) < chi2ndfProbMin ) {
161 
162  buffer = theseRecHits;
163 
164  // Dirty switch: here one can select to refit all possible subsets or just the one without the
165  // tagged worst hit:
166  if( use_brute_force ) { // Brute force method: loop over all possible segments:
167  for(size_t bi = 0; bi < buffer.size(); bi++) {
168  reduced_segments.push_back(buffer);
169  reduced_segments[bi].erase(reduced_segments[bi].begin()+(bi),reduced_segments[bi].begin()+(bi+1));
170  }
171  }
172  else { // More elegant but still biased: erase only worst hit
173  // Comment: There is not a very strong correlation of the worst hit with the one that one should remove...
174  if( hit_nr_worst >= 0 && hit_nr_worst <= int(buffer.size()) ) {
175  // fill segment in buffer, delete worst hit
176  buffer.erase(buffer.begin()+(hit_nr_worst),buffer.begin()+(hit_nr_worst+1));
177  reduced_segments.push_back(buffer);
178  }
179  else {
180  // only fill segment in array, do not delete anything
181  reduced_segments.push_back(buffer);
182  }
183  }
184  }
185 
186  // Loop over the subsegments and fit (only one segment if "use_brute_force" is false):
187  for (size_t iSegment=0; iSegment<reduced_segments.size(); iSegment++ ) {
188  // loop over hits on given segment and push pointers to hits into protosegment
189  protoSegment.clear();
190  for (size_t m = 0; m<reduced_segments[iSegment].size(); ++m ) {
191  protoSegment.push_back(&reduced_segments[iSegment][m]);
192  }
193  fitSlopes();
194  fillChiSquared();
196  // calculate error matrix
197  AlgebraicSymMatrix protoErrors = calculateError();
198  // but reorder components to match what's required by TrackingRecHit interface
199  // i.e. slopes first, then positions
200  flipErrors( protoErrors );
201  //
203 
204  // replace n hit segment with n-1 hit segment, if segment probability is 1e3 better:
205  if( ( ChiSquaredProbability((double)(*it).chi2(),(double)((2*(*it).nRecHits())-4))
206  <
207  (1.e-3)*(ChiSquaredProbability((double)temp.chi2(),(double)(2*temp.nRecHits()-4))) )
208  &&
209  ( (ChiSquaredProbability((double)temp.chi2(),(double)(2*temp.nRecHits()-4)))
210  > best_red_seg_prob
211  )
212  &&
213  ( (ChiSquaredProbability((double)temp.chi2(),(double)(2*temp.nRecHits()-4))) > 1e-10 )
214  ) {
215  best_red_seg_prob = ChiSquaredProbability((double)temp.chi2(),(double)(2*temp.nRecHits()-4));
216  // exchange current n hit segment (*it) with better n-1 hit segment:
217  (*it) = temp;
218  }
219  }
220  }
221 
222  return segments;
223 
224 }
225 
226 
227 /* Method fitSlopes
228  *
229  * Perform a Least Square Fit on a segment as per SK algo
230  *
231  */
233  CLHEP::HepMatrix M(4,4,0);
234  CLHEP::HepVector B(4,0);
235  ChamberHitContainer::const_iterator ih = protoSegment.begin();
236  for (ih = protoSegment.begin(); ih != protoSegment.end(); ++ih) {
237  const CSCRecHit2D& hit = (**ih);
238  const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
239  GlobalPoint gp = layer->toGlobal(hit.localPosition());
240  LocalPoint lp = theChamber->toLocal(gp);
241  // ptc: Local position of hit w.r.t. chamber
242  double u = lp.x();
243  double v = lp.y();
244  double z = lp.z();
245  // ptc: Covariance matrix of local errors
246  CLHEP::HepMatrix IC(2,2);
247  IC(1,1) = hit.localPositionError().xx();
248  IC(1,2) = hit.localPositionError().xy();
249  IC(2,2) = hit.localPositionError().yy();
250  IC(2,1) = IC(1,2); // since Cov is symmetric
251  // ptc: Invert covariance matrix (and trap if it fails!)
252  int ierr = 0;
253  IC.invert(ierr); // inverts in place
254  if (ierr != 0) {
255  LogDebug("CSC") << "CSCSegment::fitSlopes: failed to invert covariance matrix=\n" << IC << "\n";
256 // std::cout<< "CSCSegment::fitSlopes: failed to invert covariance matrix=\n" << IC << "\n"<<std::endl;
257  }
258 
259  M(1,1) += IC(1,1);
260  M(1,2) += IC(1,2);
261  M(1,3) += IC(1,1) * z;
262  M(1,4) += IC(1,2) * z;
263  B(1) += u * IC(1,1) + v * IC(1,2);
264 
265  M(2,1) += IC(2,1);
266  M(2,2) += IC(2,2);
267  M(2,3) += IC(2,1) * z;
268  M(2,4) += IC(2,2) * z;
269  B(2) += u * IC(2,1) + v * IC(2,2);
270 
271  M(3,1) += IC(1,1) * z;
272  M(3,2) += IC(1,2) * z;
273  M(3,3) += IC(1,1) * z * z;
274  M(3,4) += IC(1,2) * z * z;
275  B(3) += ( u * IC(1,1) + v * IC(1,2) ) * z;
276 
277  M(4,1) += IC(2,1) * z;
278  M(4,2) += IC(2,2) * z;
279  M(4,3) += IC(2,1) * z * z;
280  M(4,4) += IC(2,2) * z * z;
281  B(4) += ( u * IC(2,1) + v * IC(2,2) ) * z;
282  }
283  CLHEP::HepVector p = solve(M, B);
284 
285  // Update member variables
286  // Note that origin has local z = 0
287  protoIntercept = LocalPoint(p(1), p(2), 0.);
288  protoSlope_u = p(3);
289  protoSlope_v = p(4);
290 }
291 
292 
293 /* Method fillChiSquared
294  *
295  * Determine Chi^2 for the proto wire segment
296  *
297  */
299 
300  double chsq = 0.;
301 
302  ChamberHitContainer::const_iterator ih;
303  for (ih = protoSegment.begin(); ih != protoSegment.end(); ++ih) {
304 
305  const CSCRecHit2D& hit = (**ih);
306  const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
307  GlobalPoint gp = layer->toGlobal(hit.localPosition());
308  LocalPoint lp = theChamber->toLocal(gp);
309 
310  double u = lp.x();
311  double v = lp.y();
312  double z = lp.z();
313 
314  double du = protoIntercept.x() + protoSlope_u * z - u;
315  double dv = protoIntercept.y() + protoSlope_v * z - v;
316 
317  CLHEP::HepMatrix IC(2,2);
318  IC(1,1) = hit.localPositionError().xx();
319  IC(1,2) = hit.localPositionError().xy();
320  IC(2,2) = hit.localPositionError().yy();
321  IC(2,1) = IC(1,2);
322 
323  // Invert covariance matrix
324  int ierr = 0;
325  IC.invert(ierr);
326  if (ierr != 0) {
327  LogDebug("CSC") << "CSCSegment::fillChiSquared: failed to invert covariance matrix=\n" << IC << "\n";
328 // std::cout << "CSCSegment::fillChiSquared: failed to invert covariance matrix=\n" << IC << "\n";
329 
330  }
331 
332  chsq += du*du*IC(1,1) + 2.*du*dv*IC(1,2) + dv*dv*IC(2,2);
333  }
334 
335  protoChi2 = chsq;
336 }
337 
338 
339 /* fillLocalDirection
340  *
341  */
343  // Always enforce direction of segment to point from IP outwards
344  // (Incorrect for particles not coming from IP, of course.)
345 
346  double dxdz = protoSlope_u;
347  double dydz = protoSlope_v;
348  double dz = 1./sqrt(1. + dxdz*dxdz + dydz*dydz);
349  double dx = dz*dxdz;
350  double dy = dz*dydz;
351  LocalVector localDir(dx,dy,dz);
352 
353  // localDir may need sign flip to ensure it points outward from IP
354  // ptc: Examine its direction and origin in global z: to point outward
355  // the localDir should always have same sign as global z...
356 
357  double globalZpos = ( theChamber->toGlobal( protoIntercept ) ).z();
358  double globalZdir = ( theChamber->toGlobal( localDir ) ).z();
359  double directionSign = globalZpos * globalZdir;
360  protoDirection = (directionSign * localDir).unit();
361 }
362 
363 
364 /* weightMatrix
365  *
366  */
368 
369  std::vector<const CSCRecHit2D*>::const_iterator it;
370  int nhits = protoSegment.size();
371  AlgebraicSymMatrix matrix(2*nhits, 0);
372  int row = 0;
373 
374  for (it = protoSegment.begin(); it != protoSegment.end(); ++it) {
375 
376  const CSCRecHit2D& hit = (**it);
377  ++row;
378  matrix(row, row) = hit.localPositionError().xx();
379  matrix(row, row+1) = hit.localPositionError().xy();
380  ++row;
381  matrix(row, row-1) = hit.localPositionError().xy();
382  matrix(row, row) = hit.localPositionError().yy();
383  }
384  int ierr;
385  matrix.invert(ierr);
386  return matrix;
387 }
388 
389 
390 /* derivativeMatrix
391  *
392  */
393 CLHEP::HepMatrix CSCSegAlgoHitPruning::derivativeMatrix() const {
394 
395  ChamberHitContainer::const_iterator it;
396  int nhits = protoSegment.size();
397  CLHEP::HepMatrix matrix(2*nhits, 4);
398  int row = 0;
399 
400  for(it = protoSegment.begin(); it != protoSegment.end(); ++it) {
401 
402  const CSCRecHit2D& hit = (**it);
403  const CSCLayer* layer = theChamber->layer(hit.cscDetId().layer());
404  GlobalPoint gp = layer->toGlobal(hit.localPosition());
405  LocalPoint lp = theChamber->toLocal(gp);
406  float z = lp.z();
407  ++row;
408  matrix(row, 1) = 1.;
409  matrix(row, 3) = z;
410  ++row;
411  matrix(row, 2) = 1.;
412  matrix(row, 4) = z;
413  }
414  return matrix;
415 }
416 
417 
418 /* calculateError
419  *
420  */
422 
425 
426  // (AT W A)^-1
427  // from http://www.phys.ufl.edu/~avery/fitting.html, part I
428  int ierr;
429  AlgebraicSymMatrix result = weights.similarityT(A);
430  result.invert(ierr);
431 
432  // blithely assuming the inverting never fails...
433  return result;
434 }
435 
436 
438 
439  // The CSCSegment needs the error matrix re-arranged
440 
441  AlgebraicSymMatrix hold( a );
442 
443  // errors on slopes into upper left
444  a(1,1) = hold(3,3);
445  a(1,2) = hold(3,4);
446  a(2,1) = hold(4,3);
447  a(2,2) = hold(4,4);
448 
449  // errors on positions into lower right
450  a(3,3) = hold(1,1);
451  a(3,4) = hold(1,2);
452  a(4,3) = hold(2,1);
453  a(4,4) = hold(2,2);
454 
455  // off-diagonal elements remain unchanged
456 
457 }
458 
#define LogDebug(id)
T getParameter(std::string const &) const
float xx() const
Definition: LocalError.h:24
CLHEP::HepMatrix derivativeMatrix(void) const
CSCDetId cscDetId() const
Definition: CSCRecHit2D.h:52
double_binary B
Definition: DDStreamer.cc:234
const CSCChamber * theChamber
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:52
T y() const
Definition: PV3DBase.h:63
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:67
~CSCSegAlgoHitPruning()
destructor
int layer() const
Definition: CSCDetId.h:74
float float float z
float xy() const
Definition: LocalError.h:25
int nRecHits() const
Definition: CSCSegment.h:67
CLHEP::HepMatrix AlgebraicMatrix
LocalError localPositionError() const
Definition: CSCRecHit2D.h:51
float yy() const
Definition: LocalError.h:26
string unit
Definition: csvLumiCalc.py:46
T sqrt(T t)
Definition: SSEVec.h:48
T z() const
Definition: PV3DBase.h:64
tuple result
Definition: query.py:137
const CSCLayer * layer(CSCDetId id) const
Return the layer corresponding to the given id.
Definition: CSCChamber.cc:39
ChamberHitContainer protoSegment
float ChiSquaredProbability(double chiSquared, double nrDOF)
void flipErrors(AlgebraicSymMatrix &) const
CSCSegAlgoHitPruning(const edm::ParameterSet &ps)
constructor
AlgebraicSymMatrix weightMatrix(void) const
AlgebraicSymMatrix calculateError(void) const
#define begin
Definition: vmac.h:30
double chi2() const
Chi2 of the segment fit.
Definition: CSCSegment.h:57
double a
Definition: hdecay.h:121
CLHEP::HepSymMatrix AlgebraicSymMatrix
Local3DPoint LocalPoint
Definition: LocalPoint.h:11
std::vector< CSCSegment > pruneBadHits(const CSCChamber *aChamber, const std::vector< CSCSegment > &segments)
clusterize
LocalPoint localPosition() const
Definition: CSCRecHit2D.h:50
T x() const
Definition: PV3DBase.h:62