CMS 3D CMS Logo

MuonMesh.cc
Go to the documentation of this file.
5 
6 #include <utility>
7 #include <algorithm>
8 
9 MuonMesh::MuonMesh(const edm::ParameterSet& parm) : doME1a(parm.getParameter<bool>("ME1a")),
10  doOverlaps(parm.getParameter<bool>("Overlap")),
11  doClustering(parm.getParameter<bool>("Clustering")),
12  OverlapDPhi(parm.getParameter<double>("OverlapDPhi")),
13  OverlapDTheta(parm.getParameter<double>("OverlapDTheta")),
14  ClusterDPhi(parm.getParameter<double>("ClusterDPhi")),
15  ClusterDTheta(parm.getParameter<double>("ClusterDTheta")) {
16 }
17 
18 void MuonMesh::fillMesh(std::vector<reco::Muon>* inputMuons) {
19 
20  for(std::vector<reco::Muon>::iterator muonIter1 = inputMuons->begin();
21  muonIter1 != inputMuons->end();
22  ++muonIter1) {
23  if(muonIter1->isTrackerMuon()){
24 
25  mesh_[&*muonIter1]; // create this entry if it's a tracker muon
26  for(std::vector<reco::Muon>::iterator muonIter2 = inputMuons->begin();
27  muonIter2 != inputMuons->end();
28  ++muonIter2) {
29  if(muonIter2->isTrackerMuon()) {
30  if(muonIter2 != muonIter1) {
31 
32  // now fill all the edges for muon1 based on overlaps with muon2
33  for(std::vector<reco::MuonChamberMatch>::iterator chamberIter1 = muonIter1->matches().begin();
34  chamberIter1 != muonIter1->matches().end();
35  ++chamberIter1) {
36  for(std::vector<reco::MuonSegmentMatch>::iterator segmentIter1 = chamberIter1->segmentMatches.begin();
37  segmentIter1 != chamberIter1->segmentMatches.end();
38  ++segmentIter1) {
39  for(std::vector<reco::MuonChamberMatch>::iterator chamberIter2 = muonIter2->matches().begin();
40  chamberIter2 != muonIter2->matches().end();
41  ++chamberIter2) {
42  for(std::vector<reco::MuonSegmentMatch>::iterator segmentIter2 = chamberIter2->segmentMatches.begin();
43  segmentIter2 != chamberIter2->segmentMatches.end();
44  ++segmentIter2) {
45 
46 
47  //if(segmentIter1->mask & 0x1e0000 && segmentIter2->mask &0x1e0000) {
48 
49  bool addsegment(false);
50 
51  if( segmentIter1->cscSegmentRef.isNonnull() && segmentIter2->cscSegmentRef.isNonnull() ) {
52 
53  if( doME1a &&
54  isDuplicateOf(segmentIter1->cscSegmentRef,segmentIter2->cscSegmentRef) &&
55  CSCDetId(chamberIter1->id).ring() == 4 && CSCDetId(chamberIter2->id).ring() == 4 &&
56  chamberIter1->id == chamberIter2->id ) {
57  addsegment = true;
58  //std::cout << "\tME1/a sharing detected." << std::endl;
59  }
60 
61  if( doOverlaps &&
62  isDuplicateOf(std::make_pair(CSCDetId(chamberIter1->id),segmentIter1->cscSegmentRef),
63  std::make_pair(CSCDetId(chamberIter2->id),segmentIter2->cscSegmentRef)) ) {
64  addsegment = true;
65  //std::cout << "\tChamber Overlap sharing detected." << std::endl;
66  }
67 
68  if( doClustering &&
69  isClusteredWith(std::make_pair(CSCDetId(chamberIter1->id),segmentIter1->cscSegmentRef),
70  std::make_pair(CSCDetId(chamberIter2->id),segmentIter2->cscSegmentRef)) ) {
71  addsegment = true;
72  //std::cout << "\tCluster sharing detected." << std::endl;
73  }
74  //std::cout << std::endl;
75  } // has valid csc segment ref
76 
77  if(addsegment) { // add segment if clusters/overlaps/replicant and doesn't already exist
78 
79  if(find(mesh_[&*muonIter1].begin(),
80  mesh_[&*muonIter1].end(),
81  std::make_pair(&*muonIter2,
82  std::make_pair(&*chamberIter2,
83  &*segmentIter2)
84  )
85  ) == mesh_[&*muonIter1].end()) {
86  mesh_[&*muonIter1].push_back(std::make_pair(&*muonIter2,
87  std::make_pair(&*chamberIter2,
88  &*segmentIter2)
89  )
90  );
91  } // find
92  } // add segment?
93  //} // both segments won arbitration
94  } // segmentIter 2
95  } // chamberIter2
96  } //segmentIter1
97  } // chamberIter1
98 
99  } // if different muon
100  } // is tracker muon
101  } // muonIter2
102 
103  } // is tracker muon
104  } // muonIter1
105 
106  // special cases
107 
108  // one muon: mark all segments belonging to a muon as cleaned as there are no other muons to fight with
109  if(mesh_.size() == 1) {
110  for(std::vector<reco::MuonChamberMatch>::iterator chamberIter1 = mesh_.begin()->first->matches().begin();
111  chamberIter1 != mesh_.begin()->first->matches().end();
112  ++chamberIter1) {
113  for(std::vector<reco::MuonSegmentMatch>::iterator segmentIter1 = chamberIter1->segmentMatches.begin();
114  segmentIter1 != chamberIter1->segmentMatches.end();
115  ++segmentIter1) {
116  segmentIter1->setMask(reco::MuonSegmentMatch::BelongsToTrackByCleaning);
117  } // segmentIter1
118  } // chamberIter1
119  } // if only one tracker muon set winner bit boosted arbitration
120 
121  // segments that are not shared amongst muons and the have won all segment arbitration flags need to be promoted
122  // also promote DT segments
123  if(mesh_.size() > 1) {
124  for( MeshType::iterator i = mesh_.begin(); i != mesh_.end(); ++i ) {
125  for( std::vector<reco::MuonChamberMatch>::iterator chamberIter1 = i->first->matches().begin();
126  chamberIter1 != i->first->matches().end();
127  ++chamberIter1 ) {
128  for(std::vector<reco::MuonSegmentMatch>::iterator segmentIter1 = chamberIter1->segmentMatches.begin();
129  segmentIter1 != chamberIter1->segmentMatches.end();
130  ++segmentIter1) {
131 
132  bool shared(false);
133 
134  for( AssociationType::iterator j = i->second.begin();
135  j != i->second.end();
136  ++j ) {
137 
138  if( segmentIter1->cscSegmentRef.isNonnull() &&
139  j->second.second->cscSegmentRef.isNonnull() ) {
140  if(chamberIter1->id.subdetId() == MuonSubdetId::CSC &&
141  j->second.first->id.subdetId() == MuonSubdetId::CSC ) {
142  CSCDetId segIterId(chamberIter1->id), shareId(j->second.first->id);
143 
144  if( doOverlaps &&
145  isDuplicateOf(std::make_pair(segIterId,segmentIter1->cscSegmentRef),
146  std::make_pair(shareId,j->second.second->cscSegmentRef)) )
147  shared = true;
148 
149  if( doME1a &&
150  isDuplicateOf(segmentIter1->cscSegmentRef,j->second.second->cscSegmentRef) &&
151  segIterId.ring() == 4 && shareId.ring() == 4 &&
152  segIterId == segIterId)
153  shared = true;
154 
155  if( doClustering &&
156  isClusteredWith(std::make_pair(CSCDetId(chamberIter1->id),segmentIter1->cscSegmentRef),
157  std::make_pair(CSCDetId(j->second.first->id),j->second.second->cscSegmentRef)) )
158  shared = true;
159  } // in CSCs?
160  } // cscSegmentRef non null?
161  } // j
162 
163  // Promote segments which have won all arbitration and are not shared or are DT segments
164  if( ((segmentIter1->mask&0x1e0000) == 0x1e0000 && !shared) ||
165  (chamberIter1->id.subdetId() == MuonSubdetId::DT && (segmentIter1->mask&0x1e0000)) )
167 
168  } // segmentIter1
169  } // chamberIter1
170  }// i
171  } // if non-trivial case
172 
173 }
174 
176 
177  for( MeshType::iterator i = mesh_.begin(); i != mesh_.end(); ++i ) {
178 
179  for( AssociationType::iterator j = i->second.begin();
180  j != i->second.end();
181  ++j ) {
182 
183  for( std::vector<reco::MuonChamberMatch>::iterator chamberIter1 = i->first->matches().begin();
184  chamberIter1 != i->first->matches().end();
185  ++chamberIter1 ) {
186  for(std::vector<reco::MuonSegmentMatch>::iterator segmentIter1 = chamberIter1->segmentMatches.begin();
187  segmentIter1 != chamberIter1->segmentMatches.end();
188  ++segmentIter1) {
189 
190  if(j->second.second->cscSegmentRef.isNonnull() && segmentIter1->cscSegmentRef.isNonnull()) {
191 
192  //UNUSED: bool me1a(false), overlap(false), cluster(false);
193 
194  // remove physical overlap duplicates first
195  if( doOverlaps &&
196  isDuplicateOf(std::make_pair(CSCDetId(chamberIter1->id),segmentIter1->cscSegmentRef),
197  std::make_pair(CSCDetId(j->second.first->id),j->second.second->cscSegmentRef)) ) {
198 
199  if ( i->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) >
200  j->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) ) {
201 
204 
205  //UNUSED: overlap = true;
206  } else if ( i->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) ==
207  j->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) ) { // muon with more matched stations wins
208 
209  if((segmentIter1->mask & 0x1e0000) > (j->second.second->mask & 0x1e0000)) { // segment with better match wins
210 
213 
214  //UNUSED: overlap = true;
215  } else { // ??
216  // leave this available for later
217  }
218  } // overlap duplicate resolution
219  } // is overlap duplicate
220 
221  // do ME1/a arbitration second since the tie breaker depends on other stations
222  // Unlike the other cleanings this one removes the bits from segments associated to tracks which
223  // fail cleaning. (Instead of setting bits for the segments which win.)
224  if( doME1a &&
225  isDuplicateOf(segmentIter1->cscSegmentRef,j->second.second->cscSegmentRef) &&
226  CSCDetId(chamberIter1->id).ring() == 4 && CSCDetId(j->second.first->id).ring() == 4 &&
227  chamberIter1->id == j->second.first->id ) {
228 
229  if( j->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) <
230  i->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) ) {
231 
232  for(AssociationType::iterator AsscIter1 = i->second.begin();
233  AsscIter1 != i->second.end();
234  ++AsscIter1) {
235  if(AsscIter1->second.second->cscSegmentRef.isNonnull())
236  if(j->first == AsscIter1->first &&
237  j->second.first == AsscIter1->second.first &&
238  isDuplicateOf(segmentIter1->cscSegmentRef,AsscIter1->second.second->cscSegmentRef)) {
239  AsscIter1->second.second->mask &= ~reco::MuonSegmentMatch::BelongsToTrackByME1aClean;
240  }
241  }
242 
243  //UNUSED: me1a = true;
244  } else if ( j->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) ==
245  i->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) ) { // muon with best arbitration wins
246 
247  bool bestArb(true);
248 
249  for(AssociationType::iterator AsscIter1 = i->second.begin();
250  AsscIter1 != i->second.end();
251  ++AsscIter1) {
252  if(AsscIter1->second.second->cscSegmentRef.isNonnull())
253  if(j->first == AsscIter1->first &&
254  j->second.first == AsscIter1->second.first &&
255  isDuplicateOf(segmentIter1->cscSegmentRef,AsscIter1->second.second->cscSegmentRef) &&
256  (segmentIter1->mask & 0x1e0000) < (AsscIter1->second.second->mask & 0x1e0000))
257  bestArb = false;
258  }
259 
260  if(bestArb) {
261 
262  for(AssociationType::iterator AsscIter1 = i->second.begin();
263  AsscIter1 != i->second.end();
264  ++AsscIter1) {
265  if(AsscIter1->second.second->cscSegmentRef.isNonnull())
266  if(j->first == AsscIter1->first &&
267  j->second.first == AsscIter1->second.first &&
268  isDuplicateOf(segmentIter1->cscSegmentRef,AsscIter1->second.second->cscSegmentRef)) {
269  AsscIter1->second.second->mask &= ~reco::MuonSegmentMatch::BelongsToTrackByME1aClean;
270  }
271  }
272 
273  }
274  //UNUSED me1a = true;
275 
276  } // ME1/a duplicate resolution
277  } // is ME1/aduplicate?
278 
279  if(doClustering &&
280  isClusteredWith(std::make_pair(CSCDetId(chamberIter1->id),segmentIter1->cscSegmentRef),
281  std::make_pair(CSCDetId(j->second.first->id),j->second.second->cscSegmentRef))) {
282 
283  if (i->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) >
284  j->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) ) {
285 
288 
289  //UNUSED: cluster = true;
290  } else if (i->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000) <
291  j->first->numberOfMatches((reco::Muon::ArbitrationType)0x1e0000)) {
292 
293  j->second.second->setMask(reco::MuonSegmentMatch::BelongsToTrackByClusClean);
294  j->second.second->setMask(reco::MuonSegmentMatch::BelongsToTrackByCleaning);
295 
296  //UNUSED: cluster = true;
297  } else { // muon with more matched stations wins
298 
299  if((segmentIter1->mask & 0x1e0000) > (j->second.second->mask & 0x1e0000)) { // segment with better match wins
300 
303 
304  //UNUSED: cluster = true;
305  } else if ((segmentIter1->mask & 0x1e0000) < (j->second.second->mask & 0x1e0000)){ //
306 
307  j->second.second->setMask(reco::MuonSegmentMatch::BelongsToTrackByClusClean);
308  j->second.second->setMask(reco::MuonSegmentMatch::BelongsToTrackByCleaning);
309 
310  //UNUSED: cluster = true;
311  } else {
312  }
313  } // cluster sharing resolution
314 
315  } // is clustered with?
316 
317  } // csc ref nonnull
318  } // segmentIter1
319  } // chamberIter1
320  } // j, associated segments iterator
321  } // i, map iterator
322 
323  // final step: make sure everything that's won a cleaning flag has the "BelongsToTrackByCleaning" flag
324 
325  for( MeshType::iterator i = mesh_.begin(); i != mesh_.end(); ++i ) {
326  for( std::vector<reco::MuonChamberMatch>::iterator chamberIter1 = i->first->matches().begin();
327  chamberIter1 != i->first->matches().end();
328  ++chamberIter1 ) {
329  for(std::vector<reco::MuonSegmentMatch>::iterator segmentIter1 = chamberIter1->segmentMatches.begin();
330  segmentIter1 != chamberIter1->segmentMatches.end();
331  ++segmentIter1) {
332  // set cleaning bit if initial no cleaning bit but there are cleaning algorithm bits set.
333  if( !segmentIter1->isMask(reco::MuonSegmentMatch::BelongsToTrackByCleaning) &&
334  segmentIter1->isMask(0xe00000) )
335  segmentIter1->setMask(reco::MuonSegmentMatch::BelongsToTrackByCleaning);
336  }// segmentIter1
337  } // chamberIter1
338  } // i
339 
340 }
341 
342 bool MuonMesh::isDuplicateOf(const CSCSegmentRef& lhs, const CSCSegmentRef& rhs) const // this isDuplicateOf() deals with duplicate segments in ME1/a
343 {
344  bool result(false);
345 
346  if(!lhs->isME11a_duplicate())
347  return result;
348 
349  std::vector<CSCSegment> lhs_duplicates = lhs->duplicateSegments();
350 
351  if(fabs(lhs->localPosition().x() - rhs->localPosition().x() ) < 1E-3 &&
352  fabs(lhs->localPosition().y() - rhs->localPosition().y() ) < 1E-3 &&
353  fabs(lhs->localDirection().x()/lhs->localDirection().z() - rhs->localDirection().x()/rhs->localDirection().z() ) < 1E-3 &&
354  fabs(lhs->localDirection().y()/lhs->localDirection().z() - rhs->localDirection().y()/rhs->localDirection().z() ) < 1E-3 &&
355  fabs(lhs->localPositionError().xx() - rhs->localPositionError().xx() ) < 1E-3 &&
356  fabs(lhs->localPositionError().yy() - rhs->localPositionError().yy() ) < 1E-3 &&
357  fabs(lhs->localDirectionError().xx() - rhs->localDirectionError().xx()) < 1E-3 &&
358  fabs(lhs->localDirectionError().yy() - rhs->localDirectionError().yy()) < 1E-3)
359  result = true;
360 
361  for( std::vector<CSCSegment>::const_iterator segIter1 = lhs_duplicates.begin();
362  segIter1 != lhs_duplicates.end();
363  ++segIter1 ) { // loop over lhs duplicates
364 
365  if(fabs(segIter1->localPosition().x() - rhs->localPosition().x() ) < 1E-3 &&
366  fabs(segIter1->localPosition().y() - rhs->localPosition().y() ) < 1E-3 &&
367  fabs(segIter1->localDirection().x()/segIter1->localDirection().z() - rhs->localDirection().x()/rhs->localDirection().z() ) < 1E-3 &&
368  fabs(segIter1->localDirection().y()/segIter1->localDirection().z() - rhs->localDirection().y()/rhs->localDirection().z() ) < 1E-3 &&
369  fabs(segIter1->localPositionError().xx() - rhs->localPositionError().xx() ) < 1E-3 &&
370  fabs(segIter1->localPositionError().yy() - rhs->localPositionError().yy() ) < 1E-3 &&
371  fabs(segIter1->localDirectionError().xx() - rhs->localDirectionError().xx()) < 1E-3 &&
372  fabs(segIter1->localDirectionError().yy() - rhs->localDirectionError().yy()) < 1E-3)
373  result = true;
374  /*
375  if(fabs(segIter1->localPosition().x() - rhs->localPosition().x() ) < 2*sqrt(segIter1->localPositionError().xx()) &&
376  fabs(segIter1->localPosition().y() - rhs->localPosition().y() ) < 2*sqrt(segIter1->localPositionError().yy()) &&
377  fabs(segIter1->localDirection().x()/segIter1->localDirection().z() - rhs->localDirection().x()/rhs->localDirection().z() )
378  < 2*std::sqrt(std::max(segIter1->localDirectionError().yy(),rhs->localDirectionError().xx())) &&
379  fabs(segIter1->localDirection().y()/segIter1->localDirection().z() - rhs->localDirection().y()/rhs->localDirection().z() )
380  < 2*std::sqrt(std::max(segIter1->localDirectionError().yy(),rhs->localDirectionError().yy())))
381  result = true;
382  */
383 
384  } // loop over duplicates
385 
386  return result;
387 }
388 
389 bool MuonMesh::isDuplicateOf(const std::pair<CSCDetId,CSCSegmentRef>& rhs,
390  const std::pair<CSCDetId,CSCSegmentRef>& lhs) const // this isDuplicateOf() deals with "overlapping chambers" duplicates
391 {
392  bool result(false);
393 
394  // try to implement the simple case first just back-to-back segments without treatment of ME1/a ganging
395  // ME1a should be a simple extension of this
396 
397  if(rhs.first.endcap() == lhs.first.endcap() &&
398  rhs.first.station() == lhs.first.station() &&
399  rhs.first.ring() == lhs.first.ring()) { // if same endcap,station,ring (minimal requirement for ovl candidate)
400  /*
401  std::cout << "Chamber 1: " << rhs.first << std::endl
402  << "Chamber 2: " << lhs.first << std::endl;
403 
404  std::cout << "Same endcap,ring,station." << std::endl;
405  */
406  //create neighboring chamber labels, treat ring as (Z mod 36 or 18) + 1 number line: left, right defined accordingly.
407  unsigned modulus = ((rhs.first.ring() != 1 || rhs.first.station() == 1) ? 36 : 18);
408  int left_neighbor = (((rhs.first.chamber() - 1 + modulus)%modulus == 0 ) ? modulus : (rhs.first.chamber() - 1 + modulus)%modulus ); // + modulus to ensure positivity
409  int right_neighbor = (((rhs.first.chamber() + 1)%modulus == 0 ) ? modulus : (rhs.first.chamber() + 1)%modulus );
410 
411  if(lhs.first.chamber() == left_neighbor ||
412  lhs.first.chamber() == right_neighbor) { // if this is a neighboring chamber then it can be an overlap
413 
414  std::vector<CSCSegment> thesegments;
415  thesegments.push_back(*(lhs.second));
416  /*
417  if(lhs.second->isME11a_duplicate())
418  thesegments.insert(thesegments.begin(),
419  lhs.second->duplicateSegments().begin(),
420  lhs.second->duplicateSegments().end());
421  */
422 
423  //std::cout << "lhs is in neighoring chamber of rhs." << std::endl;
424 
425  // rhs local direction info
426  /*
427  double rhs_dydz = geometry_->chamber(rhs.first)->toGlobal(rhs.second->localDirection()).y()/
428  geometry_->chamber(rhs.first)->toGlobal(rhs.second->localDirection()).z();
429  double rhs_dxdz = geometry_->chamber(rhs.first)->toGlobal(rhs.second->localDirection()).x()/
430  geometry_->chamber(rhs.first)->toGlobal(rhs.second->localDirection()).z();
431  double rhs_dydz_err = rhs.second->localDirectionError().yy();
432  double rhs_dxdz_err = rhs.second->localDirectionError().xx();
433  */
434 
435  //rhs global position info
436  double rhs_phi = geometry_->chamber(rhs.first)->toGlobal(rhs.second->localPosition()).phi();
437  double rhs_theta = geometry_->chamber(rhs.first)->toGlobal(rhs.second->localPosition()).theta();
438  double rhs_z = geometry_->chamber(rhs.first)->toGlobal(rhs.second->localPosition()).z();
439 
440  for(std::vector<CSCSegment>::const_iterator ilhs = thesegments.begin(); ilhs != thesegments.end(); ++ilhs) {
441 
442  // lhs local direction info
443  /*
444  double lhs_dydz = geometry_->chamber(lhs.first)->toGlobal(ilhs->localDirection()).y()/
445  geometry_->chamber(lhs.first)->toGlobal(ilhs->localDirection()).z();
446  double lhs_dxdz = geometry_->chamber(lhs.first)->toGlobal(ilhs->localDirection()).x()/
447  geometry_->chamber(lhs.first)->toGlobal(ilhs->localDirection()).z();
448  double lhs_dydz_err = ilhs->localDirectionError().yy();
449  double lhs_dxdz_err = ilhs->localDirectionError().xx();
450  */
451 
452  //lhs global position info
453  double lhs_phi = geometry_->chamber(lhs.first)->toGlobal(ilhs->localPosition()).phi();
454  double lhs_theta = geometry_->chamber(lhs.first)->toGlobal(ilhs->localPosition()).theta();
455  double lhs_z = geometry_->chamber(lhs.first)->toGlobal(ilhs->localPosition()).z();
456  /*
457  std::cout << "RHS Segment Parameters:" << std::endl
458  << "\t RHS Phi : " << rhs_phi << std::endl
459  << "\t RHS Theta : " << rhs_theta << std::endl
460  << "\t RHS dx/dz : " << rhs_dxdz << " +- " << rhs_dxdz_err << std::endl
461  << "\t RHS dy/dz : " << rhs_dydz << " +- " << rhs_dydz_err << std::endl;
462 
463  std::cout << "LHS Segment Parameters:" << std::endl
464  << "\t LHS Phi : " << lhs_phi << std::endl
465  << "\t LHS Theta : " << lhs_theta << std::endl
466  << "\t LHS dx/dz : " << lhs_dxdz << " +- " << lhs_dxdz_err << std::endl
467  << "\t LHS dy/dz : " << lhs_dydz << " +- " << lhs_dydz_err << std::endl;
468  */
469 
470  double phidiff = (fabs(rhs_phi - lhs_phi) > 2*M_PI ? fabs(rhs_phi - lhs_phi) - 2*M_PI : fabs(rhs_phi - lhs_phi));
471 
472  if(phidiff < OverlapDPhi && fabs(rhs_theta - lhs_theta) < OverlapDTheta &&
473  fabs(rhs_z) < fabs(lhs_z) && rhs_z*lhs_z > 0) // phi overlap region is 3.5 degrees and rhs is infront of lhs
474  result = true;
475  } // loop over duplicate segments
476  }// neighboring chamber
477  } // same endcap,station,ring
478 
479  return result;
480 }
481 
482 bool MuonMesh::isClusteredWith(const std::pair<CSCDetId,CSCSegmentRef>& lhs,
483  const std::pair<CSCDetId,CSCSegmentRef>& rhs) const
484 {
485  bool result(false);
486 
487  // try to implement the simple case first just back-to-back segments without treatment of ME1/a ganging
488  // ME1a should be a simple extension of this
489 
490  //std::cout << lhs.first << ' ' << rhs.first << std::endl;
491 
492  if(rhs.first.endcap() == lhs.first.endcap() && lhs.first.station() < rhs.first.station()) {
493 
494  std::vector<CSCSegment> thesegments;
495  thesegments.push_back(*(lhs.second));
496  /*
497  if(lhs.second->isME11a_duplicate())
498  thesegments.insert(thesegments.begin(),
499  lhs.second->duplicateSegments().begin(),
500  lhs.second->duplicateSegments().end());
501  */
502  //std::cout << "lhs is in neighoring chamber of rhs." << std::endl;
503 
504  // rhs local direction info
505  /*
506  double rhs_dydz = geometry_->chamber(rhs.first)->toGlobal(rhs.second->localDirection()).y()/
507  geometry_->chamber(rhs.first)->toGlobal(rhs.second->localDirection()).z();
508  double rhs_dxdz = geometry_->chamber(rhs.first)->toGlobal(rhs.second->localDirection()).x()/
509  geometry_->chamber(rhs.first)->toGlobal(rhs.second->localDirection()).z();
510  double rhs_dydz_err = rhs.second->localDirectionError().yy();
511  double rhs_dxdz_err = rhs.second->localDirectionError().xx();
512  */
513 
514  //rhs global position info
515  double rhs_phi = geometry_->chamber(rhs.first)->toGlobal(rhs.second->localPosition()).phi();
516  double rhs_theta = geometry_->chamber(rhs.first)->toGlobal(rhs.second->localPosition()).theta();
517 
518  for(std::vector<CSCSegment>::const_iterator ilhs = thesegments.begin(); ilhs != thesegments.end(); ++ilhs) {
519 
520  // lhs local direction info
521  /*
522  double lhs_dydz = geometry_->chamber(lhs.first)->toGlobal(ilhs->localDirection()).y()/
523  geometry_->chamber(lhs.first)->toGlobal(ilhs->localDirection()).z();
524  double lhs_dxdz = geometry_->chamber(lhs.first)->toGlobal(ilhs->localDirection()).x()/
525  geometry_->chamber(lhs.first)->toGlobal(ilhs->localDirection()).z();
526  double lhs_dydz_err = ilhs->localDirectionError().yy();
527  double lhs_dxdz_err = ilhs->localDirectionError().xx();
528  */
529 
530  //lhs global position info
531  double lhs_phi = geometry_->chamber(lhs.first)->toGlobal(ilhs->localPosition()).phi();
532  double lhs_theta = geometry_->chamber(lhs.first)->toGlobal(ilhs->localPosition()).theta();
533  /*
534  std::cout << "RHS Segment Parameters:" << std::endl
535  << "\t RHS Phi : " << rhs_phi << std::endl
536  << "\t RHS Theta : " << rhs_theta << std::endl
537  << "\t RHS dx/dz : " << rhs_dxdz << " +- " << rhs_dxdz_err << std::endl
538  << "\t RHS dy/dz : " << rhs_dydz << " +- " << rhs_dydz_err << std::endl;
539 
540  std::cout << "LHS Segment Parameters:" << std::endl
541  << "\t LHS Phi : " << lhs_phi << std::endl
542  << "\t LHS Theta : " << lhs_theta << std::endl
543  << "\t LHS dx/dz : " << lhs_dxdz << " +- " << lhs_dxdz_err << std::endl
544  << "\t LHS dy/dz : " << lhs_dydz << " +- " << lhs_dydz_err << std::endl;
545  */
546 
547  double phidiff = (fabs(rhs_phi - lhs_phi) > 2*M_PI ? fabs(rhs_phi - lhs_phi) - 2*M_PI : fabs(rhs_phi - lhs_phi));
548 
549  if(phidiff < ClusterDPhi && fabs(rhs_theta - lhs_theta) < ClusterDTheta) // phi overlap region is 37 degrees
550  result = true;
551  } // loop over duplicate segments
552  } // same endcap,station,ring
553 
554  return result;
555 }
const double ClusterDTheta
Definition: MuonMesh.h:75
const CSCGeometry * geometry_
Definition: MuonMesh.h:70
const double OverlapDPhi
Definition: MuonMesh.h:75
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:54
const bool doClustering
Definition: MuonMesh.h:73
Geom::Theta< T > theta() const
const bool doOverlaps
Definition: MuonMesh.h:73
const double OverlapDTheta
Definition: MuonMesh.h:75
double phidiff(double phi)
Normalized difference in azimuthal angles to a range between .
Definition: fourvec.cc:230
const double ClusterDPhi
Definition: MuonMesh.h:75
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
void pruneMesh()
Definition: MuonMesh.cc:175
bool isClusteredWith(const std::pair< CSCDetId, CSCSegmentRef > &lhs, const std::pair< CSCDetId, CSCSegmentRef > &rhs) const
Definition: MuonMesh.cc:482
MuonMesh(const edm::ParameterSet &)
Definition: MuonMesh.cc:9
ArbitrationType
define arbitration schemes
Definition: Muon.h:186
#define end
Definition: vmac.h:39
void fillMesh(std::vector< reco::Muon > *)
Definition: MuonMesh.cc:18
static const unsigned int BelongsToTrackByCleaning
#define M_PI
int ring() const
Definition: CSCDetId.h:75
static const unsigned int BelongsToTrackByOvlClean
MeshType mesh_
Definition: MuonMesh.h:67
bool isDuplicateOf(const CSCSegmentRef &lhs, const CSCSegmentRef &rhs) const
Definition: MuonMesh.cc:342
const CSCChamber * chamber(CSCDetId id) const
Return the chamber corresponding to given DetId.
Definition: CSCGeometry.cc:133
const bool doME1a
Definition: MuonMesh.h:73
fixed size matrix
#define begin
Definition: vmac.h:32
static constexpr int DT
Definition: MuonSubdetId.h:12
static const unsigned int BelongsToTrackByClusClean
static constexpr int CSC
Definition: MuonSubdetId.h:13