CMS 3D CMS Logo

CSCSegAlgoRU.cc
Go to the documentation of this file.
1 
8 #include "CSCSegAlgoRU.h"
9 #include "CSCSegFit.h"
15 #include <algorithm>
16 #include <cmath>
17 #include <iostream>
18 #include <string>
19 
21  : CSCSegmentAlgorithm(ps), myName("CSCSegAlgoRU"), sfit_(nullptr) {
22  doCollisions = ps.getParameter<bool>("doCollisions");
23  chi2_str_ = ps.getParameter<double>("chi2_str");
24  chi2Norm_2D_ = ps.getParameter<double>("chi2Norm_2D_");
25  dRMax = ps.getParameter<double>("dRMax");
26  dPhiMax = ps.getParameter<double>("dPhiMax");
27  dRIntMax = ps.getParameter<double>("dRIntMax");
28  dPhiIntMax = ps.getParameter<double>("dPhiIntMax");
29  chi2Max = ps.getParameter<double>("chi2Max");
30  wideSeg = ps.getParameter<double>("wideSeg");
31  minLayersApart = ps.getParameter<int>("minLayersApart");
32 
33  LogDebug("CSC") << myName << " has algorithm cuts set to: \n"
34  << "--------------------------------------------------------------------\n"
35  << "dRMax = " << dRMax << '\n'
36  << "dPhiMax = " << dPhiMax << '\n'
37  << "dRIntMax = " << dRIntMax << '\n'
38  << "dPhiIntMax = " << dPhiIntMax << '\n'
39  << "chi2Max = " << chi2Max << '\n'
40  << "wideSeg = " << wideSeg << '\n'
41  << "minLayersApart = " << minLayersApart << std::endl;
42 
43  //reset the thresholds for non-collision data
44  if(!doCollisions){
45  dRMax = 2.0;
46  dPhiMax = 2*dPhiMax;
47  dRIntMax = 2*dRIntMax;
48  dPhiIntMax = 2*dPhiIntMax;
49  chi2Norm_2D_ = 5*chi2Norm_2D_;
50  chi2_str_ = 100;
51  chi2Max = 2*chi2Max;
52  }
53 }
54 
55 std::vector<CSCSegment> CSCSegAlgoRU::run(const CSCChamber* aChamber, const ChamberHitContainer& rechits){
56  theChamber = aChamber;
57  return buildSegments(rechits);
58 }
59 
60 std::vector<CSCSegment> CSCSegAlgoRU::buildSegments(const ChamberHitContainer& urechits) {
61  ChamberHitContainer rechits = urechits;
62  LayerIndex layerIndex(rechits.size());
63  int recHits_per_layer[6] = {0,0,0,0,0,0};
64  //skip events with high multiplicity of hits
65  if (rechits.size()>150){
66  return std::vector<CSCSegment>();
67  }
68  int iadd = 0;
69  for(unsigned int i = 0; i < rechits.size(); i++) {
70  recHits_per_layer[rechits[i]->cscDetId().layer()-1]++;//count rh per chamber
71  layerIndex[i] = rechits[i]->cscDetId().layer();
72  }
73  double z1 = theChamber->layer(1)->position().z();
74  double z6 = theChamber->layer(6)->position().z();
75  if (std::abs(z1) > std::abs(z6)){
76  reverse(layerIndex.begin(), layerIndex.end());
77  reverse(rechits.begin(), rechits.end());
78  }
79  if (rechits.size() < 2) {
80  return std::vector<CSCSegment>();
81  }
82  // We have at least 2 hits. We intend to try all possible pairs of hits to start
83  // segment building. 'All possible' means each hit lies on different layers in the chamber.
84  // after all same size segs are build we get rid of the overcrossed segments using the chi2 criteria
85  // the hits from the segs that are left are marked as used and are not added to segs in future iterations
86  // the hits from 3p segs are marked as used separately in order to try to assamble them in longer segments
87  // in case there is a second pass
88  // Choose first hit (as close to IP as possible) h1 and second hit
89  // (as far from IP as possible) h2 To do this we iterate over hits
90  // in the chamber by layer - pick two layers. Then we
91  // iterate over hits within each of these layers and pick h1 and h2
92  // these. If they are 'close enough' we build an empty
93  // segment. Then try adding hits to this segment.
94  // Initialize flags that a given hit has been allocated to a segment
95  BoolContainer used(rechits.size(), false);
96  BoolContainer used3p(rechits.size(), false);
97  // This is going to point to fits to hits, and its content will be used to create a CSCSegment
98  sfit_ = 0;
99  // Define buffer for segments we build
100  std::vector<CSCSegment> segments;
101  ChamberHitContainerCIt ib = rechits.begin();
102  ChamberHitContainerCIt ie = rechits.end();
103  // Possibly allow 3 passes, second widening scale factor for cuts, third for segments from displaced vertices
104  windowScale = 1.; // scale factor for cuts
105  bool search_disp = false;
106  strip_iadd = 1;
107  chi2D_iadd = 1;
108  int npass = (wideSeg > 1.)? 3 : 2;
109  for (int ipass = 0; ipass < npass; ++ipass) {
110  if(windowScale >1.){
111  iadd = 1;
112  strip_iadd = 2;
113  chi2D_iadd = 2;
114  }
115  int used_rh = 0;
116  for (ChamberHitContainerCIt i1 = ib; i1 != ie; ++i1) {
117  if(used[i1-ib])used_rh++;
118  }
119 
120  //change the tresholds if it's time to look for displaced mu segments
121  if(doCollisions && search_disp && int(rechits.size()-used_rh)>2){//check if there are enough recHits left to build a segment from displaced vertices
122  doCollisions = false;
123  windowScale = 1.; // scale factor for cuts
124  dRMax = 2.0;
125  dPhiMax = 2*dPhiMax;
126  dRIntMax = 2*dRIntMax;
129  chi2_str_ = 100;
130  chi2Max = 2*chi2Max;
131  }else{
132  search_disp = false;//make sure the flag is off
133  }
134 
135  for(unsigned int n_seg_min = 6u; n_seg_min > 2u + iadd; --n_seg_min){
136  BoolContainer common_used(rechits.size(),false);
137  std::array<BoolContainer, 120> common_used_it = {};
138  for (unsigned int i = 0; i < common_used_it.size(); i++) {
139  common_used_it[i] = common_used;
140  }
141  ChamberHitContainer best_proto_segment[120];
142  float min_chi[120] = {9999};
143  int common_it = 0;
144  bool first_proto_segment = true;
145  for (ChamberHitContainerCIt i1 = ib; i1 != ie; ++i1) {
146  bool segok = false;
147  //skip if rh is used and the layer tat has big rh multiplicity(>25RHs)
148  if(used[i1-ib] || recHits_per_layer[int(layerIndex[i1-ib])-1]>25 || (n_seg_min == 3 && used3p[i1-ib])) continue;
149  int layer1 = layerIndex[i1-ib];
150  const CSCRecHit2D* h1 = *i1;
151  for (ChamberHitContainerCIt i2 = ie-1; i2 != i1; --i2) {
152  if(used[i2-ib] || recHits_per_layer[int(layerIndex[i2-ib])-1]>25 || (n_seg_min == 3 && used3p[i2-ib])) continue;
153  int layer2 = layerIndex[i2-ib];
154  if((abs(layer2 - layer1) + 1) < int(n_seg_min)) break;//decrease n_seg_min
155  const CSCRecHit2D* h2 = *i2;
156  if (areHitsCloseInR(h1, h2) && areHitsCloseInGlobalPhi(h1, h2)) {
157  proto_segment.clear();
158  if (!addHit(h1, layer1))continue;
159  if (!addHit(h2, layer2))continue;
160  // Can only add hits if already have a segment
161  if ( sfit_ )tryAddingHitsToSegment(rechits, used, layerIndex, i1, i2);
162  segok = isSegmentGood(rechits);
163  if (segok) {
164  if(proto_segment.size() > n_seg_min){
165  baseline(n_seg_min);
167  }
168  if(sfit_->chi2() > chi2Norm_2D_*chi2D_iadd || proto_segment.size() < n_seg_min) proto_segment.clear();
169  if (!proto_segment.empty()) {
171  //add same-size overcrossed protosegments to the collection
172  if(first_proto_segment){
173  flagHitsAsUsed(rechits, common_used_it[0]);
174  min_chi[0] = sfit_->chi2();
175  best_proto_segment[0] = proto_segment;
176  first_proto_segment = false;
177  }else{ //for the rest of found proto_segments
178  common_it++;
179  flagHitsAsUsed(rechits, common_used_it[common_it]);
180  min_chi[common_it] = sfit_->chi2();
181  best_proto_segment[common_it] = proto_segment;
182  ChamberHitContainerCIt hi, iu, ik;
183  int iter = common_it;
184  for(iu = ib; iu != ie; ++iu) {
185  for(hi = proto_segment.begin(); hi != proto_segment.end(); ++hi) {
186  if(*hi == *iu) {
187  int merge_nr = -1;
188  for(int k = 0; k < iter+1; k++){
189  if(common_used_it[k][iu-ib] == true){
190  if(merge_nr != -1){
191  //merge the k and merge_nr collections of flaged hits into the merge_nr collection and unmark the k collection hits
192  for(ik = ib; ik != ie; ++ik) {
193  if(common_used_it[k][ik-ib] == true){
194  common_used_it[merge_nr][ik-ib] = true;
195  common_used_it[k][ik-ib] = false;
196  }
197  }
198  //change best_protoseg if min_chi_2 is smaller
199  if(min_chi[k] < min_chi[merge_nr]){
200  min_chi[merge_nr] = min_chi[k];
201  best_proto_segment[merge_nr] = best_proto_segment[k];
202  best_proto_segment[k].clear();
203  min_chi[k] = 9999;
204  }
205  common_it--;
206  }
207  else{
208  merge_nr = k;
209  }
210  }//if(common_used[k][iu-ib] == true)
211  }//for k
212  }//if
213  }//for proto_seg
214  }//for rec_hits
215  }//else
216  }//proto seg not empty
217  }
218  } // h1 & h2 close
219  if (segok)
220  break;
221  } // i2
222  } // i1
223 
224 
225  //add the reconstructed segments
226  for(int j = 0;j < common_it+1; j++){
227  proto_segment = best_proto_segment[j];
228  best_proto_segment[j].clear();
229  //SKIP empty proto-segments
230  if(proto_segment.size() == 0) continue;
232  // Create an actual CSCSegment - retrieve all info from the fit
233  CSCSegment temp(sfit_->hits(), sfit_->intercept(),
234  sfit_->localdir(), sfit_->covarianceMatrix(), sfit_->chi2());
235  sfit_ = 0;
236  segments.push_back(temp);
237  //if the segment has 3 hits flag them as used in a particular way
238  if(proto_segment.size() == 3){
239  flagHitsAsUsed(rechits, used3p);
240  }
241  else{
242  flagHitsAsUsed(rechits, used);
243  }
244  proto_segment.clear();
245  }
246  }//for n_seg_min
247 
248  if(search_disp){
249  //reset params and flags for the next chamber
250  search_disp = false;
251  doCollisions = true;
252  dRMax = 2.0;
253  dPhiMax = dPhiMax/2;
254  dRIntMax = dRIntMax/2;
257  chi2_str_ = 100;
258  chi2Max = chi2Max/2;
259  }
260 
261  std::vector<CSCSegment>::iterator it =segments.begin();
262  bool good_segs = false;
263  while(it != segments.end()) {
264  if ((*it).nRecHits() > 3){
265  good_segs = true;
266  break;
267  }
268  ++it;
269  }
270  if (good_segs && doCollisions) { // only change window if not enough good segments were found (bool can be changed to int if a >0 number of good segs is required)
271  search_disp = true;
272  continue;//proceed to search the segs from displaced vertices
273  }
274 
275  // Increase cut windows by factor of wideSeg only for collisions
276  if(!doCollisions && !search_disp) break;
278  } // ipass
279 
280  //get rid of enchansed 3p segments
281  std::vector<CSCSegment>::iterator it =segments.begin();
282  while(it != segments.end()) {
283  if((*it).nRecHits() == 3){
284  bool found_common = false;
285  const std::vector<CSCRecHit2D>& theseRH = (*it).specificRecHits();
286  for (ChamberHitContainerCIt i1 = ib; i1 != ie; ++i1) {
287  if(used[i1-ib] && used3p[i1-ib]){
288  const CSCRecHit2D* sh1 = *i1;
289  CSCDetId id = sh1->cscDetId();
290  int sh1layer = id.layer();
291  int RH_centerid = sh1->nStrips()/2;
292  int RH_centerStrip = sh1->channels(RH_centerid);
293  int RH_wg = sh1->hitWire();
294  std::vector<CSCRecHit2D>::const_iterator sh;
295  for(sh = theseRH.begin(); sh != theseRH.end(); ++sh){
296  CSCDetId idRH = sh->cscDetId();
297  //find segment hit coord
298  int shlayer = idRH.layer();
299  int SegRH_centerid = sh->nStrips()/2;
300  int SegRH_centerStrip = sh->channels(SegRH_centerid);
301  int SegRH_wg = sh->hitWire();
302  if(sh1layer == shlayer && SegRH_centerStrip == RH_centerStrip && SegRH_wg == RH_wg){
303  //remove the enchansed 3p segment
304  segments.erase(it,(it+1));
305  found_common = true;
306  break;
307  }
308  }//theserh
309  }
310  if(found_common) break;//current seg has already been erased
311  }//camber hits
312  if(!found_common)++it;
313  }//its a 3p seg
314  else{
315  ++it;//go to the next seg
316  }
317  }//while
318  // Give the segments to the CSCChamber
319  return segments;
320 }//build segments
321 
323  const BoolContainer& used, const LayerIndex& layerIndex,
324  const ChamberHitContainerCIt i1, const ChamberHitContainerCIt i2) {
325  // Iterate over the layers with hits in the chamber
326  // Skip the layers containing the segment endpoints
327  // Test each hit on the other layers to see if it is near the segment
328  // If it is, see whether there is already a hit on the segment from the same layer
329  // - if so, and there are more than 2 hits on the segment, copy the segment,
330  // replace the old hit with the new hit. If the new segment chi2 is better
331  // then replace the original segment with the new one (by swap)
332  // - if not, copy the segment, add the hit. If the new chi2/dof is still satisfactory
333  // then replace the original segment with the new one (by swap)
334  ChamberHitContainerCIt ib = rechits.begin();
335  ChamberHitContainerCIt ie = rechits.end();
336  for (ChamberHitContainerCIt i = ib; i != ie; ++i) {
337  int layer = layerIndex[i-ib];
338  if (hasHitOnLayer(layer) && proto_segment.size() <= 2)continue;
339  if (layerIndex[i-ib] == layerIndex[i1-ib] || layerIndex[i-ib] == layerIndex[i2-ib] || used[i-ib])continue;
340 
341  const CSCRecHit2D* h = *i;
342  if (isHitNearSegment(h)) {
343  // Don't consider alternate hits on layers holding the two starting points
344  if (hasHitOnLayer(layer)) {
345  if (proto_segment.size() <= 2)continue;
346  compareProtoSegment(h, layer);
347  }
348  else{
349  increaseProtoSegment(h, layer, chi2D_iadd);
350  }
351  } // h & seg close
352  } // i
353 }
354 
355 bool CSCSegAlgoRU::areHitsCloseInR(const CSCRecHit2D* h1, const CSCRecHit2D* h2) const {
356  float maxWG_width[10] = {0, 0, 4.1, 5.69, 2.49, 5.06, 2.49, 5.06, 1.87, 5.06};
357  CSCDetId id = h1->cscDetId();
358  int iStn = id.iChamberType()-1;
359  //find maxWG_width for ME11 (tilt = 29deg)
360  int wg_num = h2->hitWire();
361  if(iStn == 0 || iStn == 1){
362  if (wg_num == 1){
363  maxWG_width[0] = 9.25;
364  maxWG_width[1] = 9.25;
365  }
366  if (wg_num > 1 && wg_num < 48){
367  maxWG_width[0] = 3.14;
368  maxWG_width[1] = 3.14;
369  }
370  if (wg_num == 48){
371  maxWG_width[0] = 10.75;
372  maxWG_width[1] = 10.75;
373  }
374  }
375  const CSCLayer* l1 = theChamber->layer(h1->cscDetId().layer());
376  GlobalPoint gp1 = l1->toGlobal(h1->localPosition());
377  const CSCLayer* l2 = theChamber->layer(h2->cscDetId().layer());
378  GlobalPoint gp2 = l2->toGlobal(h2->localPosition());
379  //find z to understand the direction
380  float h1z = gp1.z();
381  float h2z = gp2.z();
382  //switch off the IP check for non collisions case
383  if (!doCollisions){
384  h1z = 1;
385  h2z = 1;
386  }
387  if (gp2.perp() > ((gp1.perp() - dRMax*maxWG_width[iStn])*h2z)/h1z && gp2.perp() < ((gp1.perp() + dRMax*maxWG_width[iStn])*h2z)/h1z){
388  return true;
389  }
390  else{
391  return false;
392  }
393 }
394 
396  float strip_width[10] = {0.003878509, 0.002958185, 0.002327105, 0.00152552, 0.00465421, 0.002327105, 0.00465421, 0.002327105, 0.00465421, 0.002327105};//in rad
397  const CSCLayer* l1 = theChamber->layer(h1->cscDetId().layer());
398  GlobalPoint gp1 = l1->toGlobal(h1->localPosition());
399  const CSCLayer* l2 = theChamber->layer(h2->cscDetId().layer());
400  GlobalPoint gp2 = l2->toGlobal(h2->localPosition());
401  float err_stpos_h1 = h1->errorWithinStrip();
402  float err_stpos_h2 = h2->errorWithinStrip();
403  CSCDetId id = h1->cscDetId();
404  int iStn = id.iChamberType()-1;
405  float dphi_incr = 0;
406  if(err_stpos_h1>0.25*strip_width[iStn] || err_stpos_h2>0.25*strip_width[iStn])dphi_incr = 0.5*strip_width[iStn];
407  float dphi12 = deltaPhi(gp1.barePhi(),gp2.barePhi());
408  return (fabs(dphi12) < (dPhiMax*strip_iadd+dphi_incr))? true:false; // +v
409 }
410 
412  // Is hit near segment?
413  // Requires deltaphi and deltaR within ranges specified in parameter set.
414  // Note that to make intuitive cuts on delta(phi) one must work in
415  // phi range (-pi, +pi] not [0, 2pi)
416  float strip_width[10] = {0.003878509, 0.002958185, 0.002327105, 0.00152552, 0.00465421, 0.002327105, 0.00465421, 0.002327105, 0.00465421, 0.002327105};//in rad
417  const CSCLayer* l1 = theChamber->layer((*(proto_segment.begin()))->cscDetId().layer());
418  GlobalPoint gp1 = l1->toGlobal((*(proto_segment.begin()))->localPosition());
419  const CSCLayer* l2 = theChamber->layer((*(proto_segment.begin()+1))->cscDetId().layer());
420  GlobalPoint gp2 = l2->toGlobal((*(proto_segment.begin()+1))->localPosition());
421  float err_stpos_h1 = (*(proto_segment.begin()))->errorWithinStrip();
422  float err_stpos_h2 = (*(proto_segment.begin()+1))->errorWithinStrip();
423  const CSCLayer* l = theChamber->layer(h->cscDetId().layer());
425  float err_stpos_h = h->errorWithinStrip();
426  float hphi = hp.phi(); // in (-pi, +pi]
427  if (hphi < 0.)
428  hphi += 2.*M_PI; // into range [0, 2pi)
429  float sphi = phiAtZ(hp.z()); // in [0, 2*pi)
430  float phidif = sphi-hphi;
431  if (phidif < 0.)
432  phidif += 2.*M_PI; // into range [0, 2pi)
433  if (phidif > M_PI)
434  phidif -= 2.*M_PI; // into range (-pi, pi]
435  SVector6 r_glob;
436  CSCDetId id = h->cscDetId();
437  int iStn = id.iChamberType()-1;
438  float dphi_incr = 0;
439  float pos_str = 1;
440  //increase dPhi cut if the hit is on the edge of the strip
441  float stpos = (*h).positionWithinStrip();
442  bool centr_str = false;
443  if(iStn != 0 && iStn != 1){
444  if (stpos > -0.25 && stpos < 0.25) centr_str = true;
445  }
446  if(err_stpos_h1<0.25*strip_width[iStn] || err_stpos_h2<0.25*strip_width[iStn] || err_stpos_h < 0.25*strip_width[iStn]){
447  dphi_incr = 0.5*strip_width[iStn];
448  }else{
449  if(centr_str) pos_str = 1.3;
450  }
451  r_glob((*(proto_segment.begin()))->cscDetId().layer()-1) = gp1.perp();
452  r_glob((*(proto_segment.begin()+1))->cscDetId().layer()-1) = gp2.perp();
453  float R = hp.perp();
454  int layer = h->cscDetId().layer();
455  float r_interpolated = fit_r_phi(r_glob,layer);
456  float dr = fabs(r_interpolated - R);
457  float maxWG_width[10] = {0, 0, 4.1, 5.69, 2.49, 5.06, 2.49, 5.06, 1.87, 5.06};
458  //find maxWG_width for ME11 (tilt = 29deg)
459  int wg_num = h->hitWire();
460  if(iStn == 0 || iStn == 1){
461  if (wg_num == 1){
462  maxWG_width[0] = 9.25;
463  maxWG_width[1] = 9.25;
464  }
465  if (wg_num > 1 && wg_num < 48){
466  maxWG_width[0] = 3.14;
467  maxWG_width[1] = 3.14;
468  }
469  if (wg_num == 48){
470  maxWG_width[0] = 10.75;
471  maxWG_width[1] = 10.75;
472  }
473  }
474  return (fabs(phidif) < dPhiIntMax*strip_iadd*pos_str+dphi_incr && fabs(dr) < dRIntMax*maxWG_width[iStn])? true:false;
475 }
476 
477 float CSCSegAlgoRU::phiAtZ(float z) const {
478  if ( !sfit_ ) return 0.;
479  // Returns a phi in [ 0, 2*pi )
480  const CSCLayer* l1 = theChamber->layer((*(proto_segment.begin()))->cscDetId().layer());
481  GlobalPoint gp = l1->toGlobal(sfit_->intercept());
482  GlobalVector gv = l1->toGlobal(sfit_->localdir());
483  float x = gp.x() + (gv.x()/gv.z())*(z - gp.z());
484  float y = gp.y() + (gv.y()/gv.z())*(z - gp.z());
485  float phi = atan2(y, x);
486  if (phi < 0.f ) phi += 2. * M_PI;
487  return phi ;
488 }
489 
490 bool CSCSegAlgoRU::isSegmentGood(const ChamberHitContainer& rechitsInChamber) const {
491  // If the chamber has 20 hits or fewer, require at least 3 hits on segment
492  // If the chamber has >20 hits require at least 4 hits
493  //@@ THESE VALUES SHOULD BECOME PARAMETERS?
494  bool ok = false;
495  unsigned int iadd = ( rechitsInChamber.size() > 20)? 1 : 0;
496  if (windowScale > 1.)
497  iadd = 1;
498  if (proto_segment.size() >= 3+iadd)
499  ok = true;
500  return ok;
501 }
502 
504  BoolContainer& used ) const {
505  // Flag hits on segment as used
506  ChamberHitContainerCIt ib = rechitsInChamber.begin();
508  for(hi = proto_segment.begin(); hi != proto_segment.end(); ++hi) {
509  for(iu = ib; iu != rechitsInChamber.end(); ++iu) {
510  if(*hi == *iu)
511  used[iu-ib] = true;
512  }
513  }
514 }
515 
516 bool CSCSegAlgoRU::addHit(const CSCRecHit2D* aHit, int layer) {
517  // Return true if hit was added successfully
518  // (and then parameters are updated).
519  // Return false if there is already a hit on the same layer, or insert failed.
520  ChamberHitContainer::const_iterator it;
521  for(it = proto_segment.begin(); it != proto_segment.end(); it++)
522  if (((*it)->cscDetId().layer() == layer) && (aHit != (*it)))
523  return false;
524  proto_segment.push_back(aHit);
525  // make a fit
527  return true;
528 }
529 
531  // Delete input CSCSegFit, create a new one and make the fit
532  // delete sfit_;
533  sfit_.reset(new CSCSegFit( theChamber, proto_segment ));
534  sfit_->fit();
535 }
536 
537 float CSCSegAlgoRU::fit_r_phi(SVector6 points, int layer) const{
538  //find R or Phi on the given layer using the given points for the interpolation
539  float Sx = 0;
540  float Sy = 0;
541  float Sxx = 0;
542  float Sxy = 0;
543  for (int i=1;i<7;i++){
544  if (points(i-1)== 0.) continue;
545  Sy = Sy + (points(i-1));
546  Sx = Sx + i;
547  Sxx = Sxx + (i*i);
548  Sxy = Sxy + ((i)*points(i-1));
549  }
550  float delta = 2*Sxx - Sx*Sx;
551  float intercept = (Sxx*Sy - Sx*Sxy)/delta;
552  float slope = (2*Sxy - Sx*Sy)/delta;
553  return (intercept + slope*layer);
554 }
555 
556 void CSCSegAlgoRU::baseline(int n_seg_min){
557  int nhits = proto_segment.size();
558  ChamberHitContainer::const_iterator iRH_worst;
559  //initialise vectors for strip position and error within strip
560  SVector6 sp;
561  SVector6 se;
562  unsigned int init_size = proto_segment.size();
563  ChamberHitContainer buffer;
564  buffer.clear();
565  buffer.reserve(init_size);
566  while (buffer.size()< init_size){
567  ChamberHitContainer::iterator min;
568  int min_layer = 10;
569  for(ChamberHitContainer::iterator k = proto_segment.begin(); k != proto_segment.end(); k++){
570  const CSCRecHit2D* iRHk = *k;
571  CSCDetId idRHk = iRHk->cscDetId();
572  int kLayer = idRHk.layer();
573  if(kLayer < min_layer){
574  min_layer = kLayer;
575  min = k;
576  }
577  }
578  buffer.push_back(*min);
579  proto_segment.erase(min);
580  }//while
581 
582  proto_segment.clear();
583  for (ChamberHitContainer::const_iterator cand = buffer.begin(); cand != buffer.end(); cand++) {
584  proto_segment.push_back(*cand);
585  }
586 
587  for(ChamberHitContainer::const_iterator iRH = proto_segment.begin(); iRH != proto_segment.end(); iRH++){
588  const CSCRecHit2D* iRHp = *iRH;
589  CSCDetId idRH = iRHp->cscDetId();
590  int kRing = idRH.ring();
591  int kStation = idRH.station();
592  int kLayer = idRH.layer();
593  // Find the strip containing this hit
594  int centerid = iRHp->nStrips()/2;
595  int centerStrip = iRHp->channels(centerid);
596  float stpos = (*iRHp).positionWithinStrip();
597  se(kLayer-1) = (*iRHp).errorWithinStrip();
598  // Take into account half-strip staggering of layers (ME1/1 has no staggering)
599  if (kStation == 1 && (kRing == 1 || kRing == 4)) sp(kLayer-1) = stpos + centerStrip;
600  else{
601  if (kLayer == 1 || kLayer == 3 || kLayer == 5) sp(kLayer-1) = stpos + centerStrip;
602  if (kLayer == 2 || kLayer == 4 || kLayer == 6) sp(kLayer-1) = stpos - 0.5 + centerStrip;
603  }
604  }
605  float chi2_str;
606  fitX(sp, se, -1, -1, chi2_str);
607 
608  //-----------------------------------------------------
609  // Optimal point rejection method
610  //-----------------------------------------------------
611  float minSum = 1000;
612  int i1b = 0;
613  int i2b = 0;
614  int iworst = -1;
615  int bad_layer = -1;
616  ChamberHitContainer::const_iterator rh_to_be_deleted_1;
617  ChamberHitContainer::const_iterator rh_to_be_deleted_2;
618  if ( (chi2_str) > chi2_str_*chi2D_iadd){
619  for (ChamberHitContainer::const_iterator i1 = proto_segment.begin(); i1 != proto_segment.end();++i1) {
620  ++i1b;
621  const CSCRecHit2D* i1_1 = *i1;
622  CSCDetId idRH1 = i1_1->cscDetId();
623  int z1 = idRH1.layer();
624  i2b = i1b;
625  for (ChamberHitContainer::const_iterator i2 = i1+1; i2 != proto_segment.end(); ++i2) {
626  ++i2b;
627  const CSCRecHit2D* i2_1 = *i2;
628  CSCDetId idRH2 = i2_1->cscDetId();
629  int z2 = idRH2.layer();
630  int irej = 0;
631  for ( ChamberHitContainer::const_iterator ir = proto_segment.begin(); ir != proto_segment.end(); ++ir) {
632  ++irej;
633  if (ir == i1 || ir == i2) continue;
634  float dsum = 0;
635  int hit_nr = 0;
636  const CSCRecHit2D* ir_1 = *ir;
637  CSCDetId idRH = ir_1->cscDetId();
638  int worst_layer = idRH.layer();
639  for (ChamberHitContainer::const_iterator i = proto_segment.begin(); i != proto_segment.end(); ++i) {
640  ++hit_nr;
641  const CSCRecHit2D* i_1 = *i;
642  if (i == i1 || i == i2 || i == ir) continue;
643  float slope = (sp(z2-1)-sp(z1-1))/(z2-z1);
644  float intersept = sp(z1-1) - slope*z1;
645  CSCDetId idRH = i_1->cscDetId();
646  int z = idRH.layer();
647  float di = fabs(sp(z-1) - intersept - slope*z);
648  dsum = dsum + di;
649  }//i
650  if (dsum < minSum){
651  minSum = dsum;
652  bad_layer = worst_layer;
653  iworst = irej;
654  rh_to_be_deleted_1 = ir;
655  }
656  }//ir
657  }//i2
658  }//i1
659  fitX(sp, se, bad_layer, -1, chi2_str);
660  }//if chi2prob<1.0e-4
661 
662  //find worst from n-1 hits
663  int iworst2 = -1;
664  int bad_layer2 = -1;
665  if (iworst > -1 && (nhits-1) > n_seg_min && (chi2_str) > chi2_str_*chi2D_iadd){
666  iworst = -1;
667  float minSum = 1000;
668  int i1b = 0;
669  int i2b = 0;
670  for (ChamberHitContainer::const_iterator i1 = proto_segment.begin(); i1 != proto_segment.end();++i1) {
671  ++i1b;
672  const CSCRecHit2D* i1_1 = *i1;
673  CSCDetId idRH1 = i1_1->cscDetId();
674  int z1 = idRH1.layer();
675  i2b = i1b;
676  for ( ChamberHitContainer::const_iterator i2 = i1+1; i2 != proto_segment.end(); ++i2) {
677  ++i2b;
678  const CSCRecHit2D* i2_1 = *i2;
679  CSCDetId idRH2 = i2_1->cscDetId();
680  int z2 = idRH2.layer();
681  int irej = 0;
682  for ( ChamberHitContainer::const_iterator ir = proto_segment.begin(); ir != proto_segment.end(); ++ir) {
683  ++irej;
684  int irej2 = 0;
685  if (ir == i1 || ir == i2 ) continue;
686  const CSCRecHit2D* ir_1 = *ir;
687  CSCDetId idRH = ir_1->cscDetId();
688  int worst_layer = idRH.layer();
689  for ( ChamberHitContainer::const_iterator ir2 = proto_segment.begin(); ir2 != proto_segment.end(); ++ir2) {
690  ++irej2;
691  if (ir2 == i1 || ir2 == i2 || ir2 ==ir ) continue;
692  float dsum = 0;
693  int hit_nr = 0;
694  const CSCRecHit2D* ir2_1 = *ir2;
695  CSCDetId idRH = ir2_1->cscDetId();
696  int worst_layer2 = idRH.layer();
697  for ( ChamberHitContainer::const_iterator i = proto_segment.begin(); i != proto_segment.end(); ++i) {
698  ++hit_nr;
699  const CSCRecHit2D* i_1 = *i;
700  if (i == i1 || i == i2 || i == ir|| i == ir2 ) continue;
701  float slope = (sp(z2-1)-sp(z1-1))/(z2-z1);
702  float intersept = sp(z1-1) - slope*z1;
703  CSCDetId idRH = i_1->cscDetId();
704  int z = idRH.layer();
705  float di = fabs(sp(z-1) - intersept - slope*z);
706  dsum = dsum + di;
707  }//i
708  if (dsum < minSum){
709  minSum = dsum;
710  iworst2 = irej2;
711  iworst = irej;
712  bad_layer = worst_layer;
713  bad_layer2 = worst_layer2;
714  rh_to_be_deleted_1 = ir;
715  rh_to_be_deleted_2 = ir2;
716  }
717  }//ir2
718  }//ir
719  }//i2
720  }//i1
721  fitX(sp, se, bad_layer ,bad_layer2, chi2_str);
722  }//if prob(n-1)<e-4
723 
724  //----------------------------------
725  //erase bad_hits
726  //----------------------------------
727  if( iworst2-1 >= 0 && iworst2 <= int(proto_segment.size()) ) {
728  proto_segment.erase( rh_to_be_deleted_2);
729  }
730  if( iworst-1 >= 0 && iworst <= int(proto_segment.size()) ){
731  proto_segment.erase(rh_to_be_deleted_1);
732  }
733 }
734 
735 float CSCSegAlgoRU::fitX(SVector6 points, SVector6 errors, int ir, int ir2, float &chi2_str){
736  float S = 0;
737  float Sx = 0;
738  float Sy = 0;
739  float Sxx = 0;
740  float Sxy = 0;
741  float sigma2 = 0;
742  for (int i=1;i<7;i++){
743  if (i == ir || i == ir2 || points(i-1) == 0.) continue;
744  sigma2 = errors(i-1)*errors(i-1);
745  float i1 = i - 3.5;
746  S = S + (1/sigma2);
747  Sy = Sy + (points(i-1)/sigma2);
748  Sx = Sx + ((i1)/sigma2);
749  Sxx = Sxx + (i1*i1)/sigma2;
750  Sxy = Sxy + (((i1)*points(i-1))/sigma2);
751  }
752  float delta = S*Sxx - Sx*Sx;
753  float intercept = (Sxx*Sy - Sx*Sxy)/delta;
754  float slope = (S*Sxy - Sx*Sy)/delta;
755  float chi_str = 0;
756  chi2_str = 0;
757  // calculate chi2_str
758  for (int i=1;i<7;i++){
759  if (i == ir || i == ir2 || points(i-1) == 0.) continue;
760  chi_str = (points(i-1) - intercept - slope*(i-3.5))/(errors(i-1));
761  chi2_str = chi2_str + chi_str*chi_str;
762  }
763  return (intercept + slope*0);
764 }
765 
766 bool CSCSegAlgoRU::hasHitOnLayer(int layer) const {
767  // Is there is already a hit on this layer?
769  for(it = proto_segment.begin(); it != proto_segment.end(); it++)
770  if ((*it)->cscDetId().layer() == layer)
771  return true;
772  return false;
773 }
774 
775 bool CSCSegAlgoRU::replaceHit(const CSCRecHit2D* h, int layer) {
776  // replace a hit from a layer
777  ChamberHitContainer::const_iterator it;
778  for (it = proto_segment.begin(); it != proto_segment.end();) {
779  if ((*it)->cscDetId().layer() == layer)
780  it = proto_segment.erase(it);
781  else
782  ++it;
783  }
784  return addHit(h, layer);
785 }
786 
788  // Copy the input CSCSegFit
789  std::unique_ptr<CSCSegFit> oldfit;
790  oldfit.reset(new CSCSegFit( theChamber, proto_segment ));
791  oldfit->fit();
793 
794  // May create a new fit
795  bool ok = replaceHit(h, layer);
796  if ( (sfit_->chi2() >= oldfit->chi2() ) || !ok ) {
797  // keep original fit
798  proto_segment = oldproto;
799  sfit_ = std::move(oldfit); // reset to the original input fit
800  }
801 }
802 
803 void CSCSegAlgoRU::increaseProtoSegment(const CSCRecHit2D* h, int layer, int chi2_factor) {
804  // Creates a new fit
805  std::unique_ptr<CSCSegFit> oldfit;
807  oldfit.reset(new CSCSegFit( theChamber, proto_segment ));
808  oldfit->fit();
809 
810  bool ok = addHit(h, layer);
811  //@@ TEST ON ndof<=0 IS JUST TO ACCEPT nhits=2 CASE??
812  if ( !ok || ( (sfit_->ndof() > 0) && (sfit_->chi2()/sfit_->ndof() >= chi2Max)) ) {
813  // reset to original fit
814  proto_segment = oldproto;
815  sfit_ = std::move(oldfit);
816  }
817 }
#define LogDebug(id)
dbl * delta
Definition: mlp_gen.cc:36
T getParameter(std::string const &) const
bool areHitsCloseInR(const CSCRecHit2D *h1, const CSCRecHit2D *h2) const
Utility functions.
CSCDetId cscDetId() const
Definition: CSCRecHit2D.h:52
float windowScale
Definition: CSCSegAlgoRU.h:138
T perp() const
Definition: PV3DBase.h:72
ROOT::Math::SVector< double, 6 > SVector6
Typedefs.
Definition: CSCSegAlgoRU.h:52
void flagHitsAsUsed(const ChamberHitContainer &rechitsInChamber, BoolContainer &used) const
std::vector< const CSCRecHit2D * >::const_iterator ChamberHitContainerCIt
Definition: CSCSegAlgoRU.h:56
static const double slope[3]
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:54
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
T y() const
Definition: PV3DBase.h:63
bool isSegmentGood(const ChamberHitContainer &rechitsInChamber) const
const std::string myName
Definition: CSCSegAlgoRU.h:132
void updateParameters(void)
#define nullptr
int layer() const
Definition: CSCDetId.h:61
float dPhiIntMax
Definition: CSCSegAlgoRU.h:145
std::vector< CSCSegment > run(const CSCChamber *aChamber, const ChamberHitContainer &rechits)
Definition: CSCSegAlgoRU.cc:55
T barePhi() const
Definition: PV3DBase.h:68
bool isHitNearSegment(const CSCRecHit2D *h) const
int channels(unsigned int i) const
Extracting strip channel numbers comprising the rechit - low.
Definition: CSCRecHit2D.h:55
const Surface::PositionType & position() const
The position (origin of the R.F.)
Definition: GeomDet.h:48
bool replaceHit(const CSCRecHit2D *h, int layer)
ChamberHitContainer proto_segment
Definition: CSCSegAlgoRU.h:131
float fit_r_phi(SVector6 points, int layer) const
susybsm::HSCParticleRefProd hp
Definition: classes.h:27
std::vector< CSCSegment > buildSegments(const ChamberHitContainer &rechits)
Definition: CSCSegAlgoRU.cc:60
const CSCChamber * theChamber
Definition: CSCSegAlgoRU.h:130
T z() const
Definition: PV3DBase.h:64
unsigned int nStrips() const
Definition: CSCRecHit2D.h:56
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void tryAddingHitsToSegment(const ChamberHitContainer &rechitsInChamber, const BoolContainer &used, const LayerIndex &layerIndex, const ChamberHitContainerCIt i1, const ChamberHitContainerCIt i2)
const CSCLayer * layer(CSCDetId id) const
Return the layer corresponding to the given id.
Definition: CSCChamber.cc:39
void compareProtoSegment(const CSCRecHit2D *h, int layer)
double f[11][100]
T min(T a, T b)
Definition: MathUtil.h:58
static const std::string kLayer("layer")
CSCSegAlgoRU(const edm::ParameterSet &ps)
Constructor.
Definition: CSCSegAlgoRU.cc:20
std::vector< const CSCRecHit2D * > ChamberHitContainer
Definition: CSCSegAlgoRU.h:55
std::vector< bool > BoolContainer
Definition: CSCSegAlgoRU.h:63
std::vector< int > LayerIndex
Definition: CSCSegAlgoRU.h:54
#define M_PI
float phiAtZ(float z) const
int k[5][pyjets_maxn]
unsigned short iChamberType()
Definition: CSCDetId.h:107
bool areHitsCloseInGlobalPhi(const CSCRecHit2D *h1, const CSCRecHit2D *h2) const
int ring() const
Definition: CSCDetId.h:75
float chi2Norm_2D_
Definition: CSCSegAlgoRU.h:148
float fitX(SVector6 points, SVector6 errors, int ir, int ir2, float &chi2_str)
bool hasHitOnLayer(int layer) const
double S(const TLorentzVector &, const TLorentzVector &)
Definition: Particle.cc:99
short int hitWire() const
L1A.
Definition: CSCRecHit2D.h:62
void baseline(int n_seg_min)
const int init_size
float errorWithinStrip() const
The uncertainty of the estimated position within the strip.
Definition: CSCRecHit2D.h:79
int station() const
Definition: CSCDetId.h:86
Definition: errors.py:1
Definition: sp.h:21
LocalPoint localPosition() const
Definition: CSCRecHit2D.h:50
bool addHit(const CSCRecHit2D *hit, int layer)
Utility functions.
std::unique_ptr< CSCSegFit > sfit_
Definition: CSCSegAlgoRU.h:153
T x() const
Definition: PV3DBase.h:62
def move(src, dest)
Definition: eostools.py:510
ib
Definition: cuy.py:660
void increaseProtoSegment(const CSCRecHit2D *h, int layer, int chi2_factor)