CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CSCHaloAlgo.cc
Go to the documentation of this file.
3 /*
4  [class]: CSCHaloAlgo
5  [authors]: R. Remington, The University of Florida
6  [description]: See CSCHaloAlgo.h
7  [date]: October 15, 2009
8 */
9 using namespace reco;
10 using namespace std;
11 using namespace edm;
12 #include "TMath.h"
13 
15 {
16  deta_threshold = 0.;
17  min_inner_radius = 0.;
18  max_inner_radius = 9999.;
19  min_outer_radius = 0.;
20  max_outer_radius = 9999.;
21  dphi_threshold = 999.;
22  norm_chi2_threshold = 999.;
23  recHit_t0=0.;
24  recHit_twindow=25.;
25  expected_BX=3;
26  max_dt_muon_segment=-10.0;
27  max_free_inverse_beta=0.0;
28 
29  min_outer_theta = 0.;
30  max_outer_theta = TMath::Pi();
31 
32  matching_dphi_threshold = 0.18; //radians
33  matching_deta_threshold = 0.4;
34  matching_dwire_threshold = 5.;
35 }
36 
38  edm::Handle<reco::MuonCollection>& TheCosmicMuons,
39  const edm::Handle<reco::MuonTimeExtraMap> TheCSCTimeMap,
41  edm::Handle<CSCSegmentCollection>& TheCSCSegments,
44  edm::Handle<edm::TriggerResults>& TheHLTResults,
45  const edm::TriggerNames * triggerNames,
46  const edm::Handle<CSCALCTDigiCollection>& TheALCTs,
47  MuonSegmentMatcher *TheMatcher,
48  const edm::Event& TheEvent)
49 {
50  reco::CSCHaloData TheCSCHaloData;
51  int imucount=0;
52  if( TheCosmicMuons.isValid() )
53  {
54  short int n_tracks_small_beta=0;
55  short int n_tracks_small_dT=0;
56  short int n_tracks_small_dT_and_beta=0;
57  for( reco::MuonCollection::const_iterator iMuon = TheCosmicMuons->begin() ; iMuon != TheCosmicMuons->end() ; iMuon++, imucount++ )
58  {
59  reco::TrackRef Track = iMuon->outerTrack();
60  if(!Track) continue;
61 
62  bool StoreTrack = false;
63  // Calculate global phi coordinate for central most rechit in the track
64  float innermost_global_z = 1500.;
65  float outermost_global_z = 0.;
66  GlobalPoint InnerMostGlobalPosition(0.,0.,0.); // smallest abs(z)
67  GlobalPoint OuterMostGlobalPosition(0.,0.,0.); // largest abs(z)
68  int nCSCHits = 0;
69  for(unsigned int j = 0 ; j < Track->extra()->recHitsSize(); j++ )
70  {
71  auto hit = Track->extra()->recHitRef(j);
72  if( !hit->isValid() ) continue;
73  DetId TheDetUnitId(hit->geographicalId());
74  if( TheDetUnitId.det() != DetId::Muon ) continue;
75  if( TheDetUnitId.subdetId() != MuonSubdetId::CSC ) continue;
76 
77  const GeomDetUnit *TheUnit = TheCSCGeometry.idToDetUnit(TheDetUnitId);
78  LocalPoint TheLocalPosition = hit->localPosition();
79  const BoundPlane& TheSurface = TheUnit->surface();
80  const GlobalPoint TheGlobalPosition = TheSurface.toGlobal(TheLocalPosition);
81 
82  float z = TheGlobalPosition.z();
83  if( TMath::Abs(z) < innermost_global_z )
84  {
85  innermost_global_z = TMath::Abs(z);
86  InnerMostGlobalPosition = GlobalPoint( TheGlobalPosition);
87  }
88  if( TMath::Abs(z) > outermost_global_z )
89  {
90  outermost_global_z = TMath::Abs(z);
91  OuterMostGlobalPosition = GlobalPoint( TheGlobalPosition );
92  }
93  nCSCHits ++;
94  }
95 
96  std::vector<const CSCSegment*> MatchedSegments = TheMatcher->matchCSC(*Track,TheEvent);
97  // Find the inner and outer segments separately in case they don't agree completely with recHits
98  // Plan for the possibility segments in both endcaps
99  float InnerSegmentTime[2] = {0,0};
100  float OuterSegmentTime[2] = {0,0};
101  float innermost_seg_z[2] = {1500,1500};
102  float outermost_seg_z[2] = {0,0};
103  for (std::vector<const CSCSegment*>::const_iterator segment =MatchedSegments.begin();
104  segment != MatchedSegments.end(); ++segment)
105  {
106  CSCDetId TheCSCDetId((*segment)->cscDetId());
107  const CSCChamber* TheCSCChamber = TheCSCGeometry.chamber(TheCSCDetId);
108  LocalPoint TheLocalPosition = (*segment)->localPosition();
109  const GlobalPoint TheGlobalPosition = TheCSCChamber->toGlobal(TheLocalPosition);
110  float z = TheGlobalPosition.z();
111  int TheEndcap = TheCSCDetId.endcap();
112  if( TMath::Abs(z) < innermost_seg_z[TheEndcap-1] )
113  {
114  innermost_seg_z[TheEndcap-1] = TMath::Abs(z);
115  InnerSegmentTime[TheEndcap-1] = (*segment)->time();
116  }
117  if( TMath::Abs(z) > outermost_seg_z[TheEndcap-1] )
118  {
119  outermost_seg_z[TheEndcap-1] = TMath::Abs(z);
120  OuterSegmentTime[TheEndcap-1] = (*segment)->time();
121  }
122  }
123 
124  if( nCSCHits < 3 ) continue; // This needs to be optimized, but is the minimum
125 
126  float dT_Segment = 0; // default safe value, looks like collision muon
127 
128  if( innermost_seg_z[0] < outermost_seg_z[0]) // two segments in ME+
129  dT_Segment = OuterSegmentTime[0]-InnerSegmentTime[0];
130  if( innermost_seg_z[1] < outermost_seg_z[1]) // two segments in ME-
131  {
132  // replace the measurement if there weren't segments in ME+ or
133  // if the track in ME- has timing more consistent with an incoming particle
134  if (dT_Segment == 0.0 || OuterSegmentTime[1]-InnerSegmentTime[1] < dT_Segment)
135  dT_Segment = OuterSegmentTime[1]-InnerSegmentTime[1] ;
136  }
137 
138  if( OuterMostGlobalPosition.x() == 0. || OuterMostGlobalPosition.y() == 0. || OuterMostGlobalPosition.z() == 0. )
139  continue;
140  if( InnerMostGlobalPosition.x() == 0. || InnerMostGlobalPosition.y() == 0. || InnerMostGlobalPosition.z() == 0. )
141  continue;
142 
143  //Its a CSC Track,store it if it passes halo selection
144  StoreTrack = true;
145 
146  float deta = TMath::Abs( OuterMostGlobalPosition.eta() - InnerMostGlobalPosition.eta() );
147  float dphi = TMath::ACos( TMath::Cos( OuterMostGlobalPosition.phi() - InnerMostGlobalPosition.phi() ) ) ;
148  float theta = Track->outerMomentum().theta();
149  float innermost_x = InnerMostGlobalPosition.x() ;
150  float innermost_y = InnerMostGlobalPosition.y();
151  float outermost_x = OuterMostGlobalPosition.x();
152  float outermost_y = OuterMostGlobalPosition.y();
153  float innermost_r = TMath::Sqrt(innermost_x *innermost_x + innermost_y * innermost_y );
154  float outermost_r = TMath::Sqrt(outermost_x *outermost_x + outermost_y * outermost_y );
155 
156  if( deta < deta_threshold )
157  StoreTrack = false;
158  if( theta > min_outer_theta && theta < max_outer_theta )
159  StoreTrack = false;
160  if( dphi > dphi_threshold )
161  StoreTrack = false;
162  if( innermost_r < min_inner_radius )
163  StoreTrack = false;
164  if( innermost_r > max_inner_radius )
165  StoreTrack = false;
166  if( outermost_r < min_outer_radius )
167  StoreTrack = false;
168  if( outermost_r > max_outer_radius )
169  StoreTrack = false;
170  if( Track->normalizedChi2() > norm_chi2_threshold )
171  StoreTrack = false;
172 
173  if( StoreTrack )
174  {
175  TheCSCHaloData.GetCSCTrackImpactPositions().push_back( InnerMostGlobalPosition );
176  TheCSCHaloData.GetTracks().push_back( Track );
177  }
178 
179  // Analyze the MuonTimeExtra information
180  if( TheCSCTimeMap.isValid() )
181  {
182  reco::MuonRef muonR(TheCosmicMuons,imucount);
183  const reco::MuonTimeExtraMap & timeMapCSC = *TheCSCTimeMap;
184  reco::MuonTimeExtra timecsc = timeMapCSC[muonR];
185  float freeInverseBeta = timecsc.freeInverseBeta();
186 
187  if (dT_Segment < max_dt_muon_segment )
188  n_tracks_small_dT++;
189  if (freeInverseBeta < max_free_inverse_beta)
190  n_tracks_small_beta++;
191  if ((dT_Segment < max_dt_muon_segment) && (freeInverseBeta < max_free_inverse_beta))
192  n_tracks_small_dT_and_beta++;
193  }
194  else
195  {
196  static std::atomic<bool> MuonTimeFail{false};
197  bool expected = false;
198  if( MuonTimeFail.compare_exchange_strong(expected,true,std::memory_order_acq_rel) )
199  {
200  edm::LogWarning ("InvalidInputTag") << "The MuonTimeExtraMap does not appear to be in the event. Some beam halo "
201  << " identification variables will be empty" ;
202  }
203  }
204  }
205  TheCSCHaloData.SetNIncomingTracks(n_tracks_small_dT,n_tracks_small_beta,n_tracks_small_dT_and_beta);
206  }
207  else // collection is invalid
208  {
209  static std::atomic<bool> CosmicFail{false};
210  bool expected = false;
211  if( CosmicFail.compare_exchange_strong(expected,true,std::memory_order_acq_rel) )
212  {
213  edm::LogWarning ("InvalidInputTag") << " The Cosmic Muon collection does not appear to be in the event. These beam halo "
214  << " identification variables will be empty" ;
215  }
216  }
217 
218  if( TheHLTResults.isValid() )
219  {
220  bool EventPasses = false;
221  for( unsigned int index = 0 ; index < vIT_HLTBit.size(); index++)
222  {
223  if( vIT_HLTBit[index].label().size() )
224  {
225  //Get the HLT bit and check to make sure it is valid
226  unsigned int bit = triggerNames->triggerIndex( vIT_HLTBit[index].label().c_str());
227  if( bit < TheHLTResults->size() )
228  {
229  //If any of the HLT names given by the user accept, then the event passes
230  if( TheHLTResults->accept( bit ) && !TheHLTResults->error( bit ) )
231  {
232  EventPasses = true;
233  }
234  }
235  }
236  }
237  if( EventPasses )
238  TheCSCHaloData.SetHLTBit(true);
239  else
240  TheCSCHaloData.SetHLTBit(false);
241  }
242  else // HLT results are not valid
243  {
244  static std::atomic<bool> HLTFail{false};
245  bool expected = false;
246  if( HLTFail.compare_exchange_strong(expected,true,std::memory_order_acq_rel) )
247  {
248  edm::LogWarning ("InvalidInputTag") << "The HLT results do not appear to be in the event. The beam halo HLT trigger "
249  << "decision will not be used in the halo identification";
250  }
251  }
252 
253  if( TheL1GMTReadout.isValid() )
254  {
255  L1MuGMTReadoutCollection const *gmtrc = TheL1GMTReadout.product ();
256  std::vector < L1MuGMTReadoutRecord > gmt_records = gmtrc->getRecords ();
257  std::vector < L1MuGMTReadoutRecord >::const_iterator igmtrr;
258 
259  int icsc = 0;
260  int PlusZ = 0 ;
261  int MinusZ = 0 ;
262  // Check to see if CSC BeamHalo trigger is tripped
263  for (igmtrr = gmt_records.begin (); igmtrr != gmt_records.end (); igmtrr++)
264  {
265  std::vector < L1MuRegionalCand >::const_iterator iter1;
266  std::vector < L1MuRegionalCand > rmc;
267  rmc = igmtrr->getCSCCands ();
268  for (iter1 = rmc.begin (); iter1 != rmc.end (); iter1++)
269  {
270  if (!(*iter1).empty ())
271  {
272  if ((*iter1).isFineHalo ())
273  {
274  float halophi = iter1->phiValue();
275  halophi = halophi > TMath::Pi() ? halophi - 2.*TMath::Pi() : halophi;
276  float haloeta = iter1->etaValue();
277  bool HaloIsGood = true;
278  // Check if halo trigger is faked by any collision muons
279  if( TheMuons.isValid() )
280  {
281  float dphi = 9999.;
282  float deta = 9999.;
283  for( reco::MuonCollection::const_iterator mu = TheMuons->begin(); mu != TheMuons->end() && HaloIsGood ; mu++ )
284  {
285  // Don't match with SA-only muons
286  if( mu->isStandAloneMuon() && !mu->isTrackerMuon() && !mu->isGlobalMuon() ) continue;
287 
288  /*
289  if(!mu->isTrackerMuon())
290  {
291  if( mu->isStandAloneMuon() )
292  {
293  //make sure that this SA muon is not actually a halo-like muon
294  float theta = mu->outerTrack()->outerMomentum().theta();
295  float deta = TMath::Abs(mu->outerTrack()->outerPosition().eta() - mu->outerTrack()->innerPosition().eta());
296  if( theta < min_outer_theta || theta > max_outer_theta ) //halo-like
297  continue;
298  else if ( deta > deta_threshold ) //halo-like
299  continue;
300  }
301  }
302  */
303 
304  const std::vector<MuonChamberMatch> chambers = mu->matches();
305  for(std::vector<MuonChamberMatch>::const_iterator iChamber = chambers.begin();
306  iChamber != chambers.end() ; iChamber ++ )
307  {
308  if( iChamber->detector() != MuonSubdetId::CSC ) continue;
309  for( std::vector<reco::MuonSegmentMatch>::const_iterator iSegment = iChamber->segmentMatches.begin() ;
310  iSegment != iChamber->segmentMatches.end(); ++iSegment )
311  {
312  edm::Ref<CSCSegmentCollection> cscSegment = iSegment->cscSegmentRef;
313  std::vector<CSCRecHit2D> hits = cscSegment -> specificRecHits();
314  for( std::vector<CSCRecHit2D>::iterator iHit = hits.begin();
315  iHit != hits.end() ; iHit++ )
316  {
317  DetId TheDetUnitId(iHit->cscDetId());
318  const GeomDetUnit *TheUnit = TheCSCGeometry.idToDetUnit(TheDetUnitId);
319  LocalPoint TheLocalPosition = iHit->localPosition();
320  const BoundPlane& TheSurface = TheUnit->surface();
321  GlobalPoint TheGlobalPosition = TheSurface.toGlobal(TheLocalPosition);
322 
323  float phi_ = TheGlobalPosition.phi();
324  float eta_ = TheGlobalPosition.eta();
325 
326  deta = deta < TMath::Abs( eta_ - haloeta ) ? deta : TMath::Abs( eta_ - haloeta );
327  dphi = dphi < TMath::ACos(TMath::Cos(phi_ - halophi)) ? dphi : TMath::ACos(TMath::Cos(phi_ - halophi));
328  }
329  }
330  }
331  if ( dphi < matching_dphi_threshold && deta < matching_deta_threshold)
332  HaloIsGood = false; // i.e., collision muon likely faked halo trigger
333  }
334  }
335  if( !HaloIsGood )
336  continue;
337  if( (*iter1).etaValue() > 0 )
338  PlusZ++;
339  else
340  MinusZ++;
341  }
342  else
343  icsc++;
344  }
345  }
346  }
347  TheCSCHaloData.SetNumberOfHaloTriggers(PlusZ, MinusZ);
348  }
349  else
350  {
351  static std::atomic<bool> L1Fail{false};
352  bool expected = false;
353  if( L1Fail.compare_exchange_strong(expected,true,std::memory_order_acq_rel) )
354  {
355  edm::LogWarning ("InvalidInputTag") << "The L1MuGMTReadoutCollection does not appear to be in the event. The L1 beam halo trigger "
356  << "decision will not be used in the halo identification";
357  }
358  }
359 
360  // Loop over CSCALCTDigi collection to look for out-of-time chamber triggers
361  // A collision muon in real data should only have ALCTDigi::getBX() = 3 ( in MC, it will be 6 )
362  // Note that there could be two ALCTs per chamber
363  short int n_alctsP=0;
364  short int n_alctsM=0;
365  if(TheALCTs.isValid())
366  {
367  for (CSCALCTDigiCollection::DigiRangeIterator j=TheALCTs->begin(); j!=TheALCTs->end(); j++)
368  {
369  const CSCALCTDigiCollection::Range& range =(*j).second;
370  CSCDetId detId((*j).first.rawId());
371  for (CSCALCTDigiCollection::const_iterator digiIt = range.first; digiIt!=range.second; ++digiIt)
372  {
373  if( (*digiIt).isValid() && ( (*digiIt).getBX() < expected_BX ) )
374  {
375  int digi_endcap = detId.endcap();
376  int digi_station = detId.station();
377  int digi_ring = detId.ring();
378  int digi_chamber = detId.chamber();
379  int digi_wire = digiIt->getKeyWG();
380  if( digi_station == 1 && digi_ring == 4 ) //hack
381  digi_ring = 1;
382 
383  bool DigiIsGood = true;
384  int dwire = 999.;
385  if( TheMuons.isValid() )
386  {
387  //Check if there are any collision muons with hits in the vicinity of the digi
388  for(reco::MuonCollection::const_iterator mu = TheMuons->begin(); mu!= TheMuons->end() && DigiIsGood ; mu++ )
389  {
390  if( !mu->isTrackerMuon() && !mu->isGlobalMuon() && mu->isStandAloneMuon() ) continue;
391 
392  const std::vector<MuonChamberMatch> chambers = mu->matches();
393  for(std::vector<MuonChamberMatch>::const_iterator iChamber = chambers.begin();
394  iChamber != chambers.end(); iChamber ++ )
395  {
396  if( iChamber->detector() != MuonSubdetId::CSC ) continue;
397  for( std::vector<reco::MuonSegmentMatch>::const_iterator iSegment = iChamber->segmentMatches.begin();
398  iSegment != iChamber->segmentMatches.end(); iSegment++ )
399  {
400  edm::Ref<CSCSegmentCollection> cscSegRef = iSegment->cscSegmentRef;
401  std::vector<CSCRecHit2D> hits = cscSegRef->specificRecHits();
402  for( std::vector<CSCRecHit2D>::iterator iHit = hits.begin();
403  iHit != hits.end(); iHit++ )
404  {
405  if( iHit->cscDetId().endcap() != digi_endcap ) continue;
406  if( iHit->cscDetId().station() != digi_station ) continue;
407  if( iHit->cscDetId().ring() != digi_ring ) continue;
408  if( iHit->cscDetId().chamber() != digi_chamber ) continue;
409  int hit_wire = iHit->hitWire();
410  dwire = dwire < TMath::Abs(hit_wire - digi_wire)? dwire : TMath::Abs(hit_wire - digi_wire );
411  }
412  }
413  }
414  if( dwire <= matching_dwire_threshold )
415  DigiIsGood = false; // collision-like muon is close to this digi
416  }
417  }
418  // only count out of time digis if they are not matched to collision muons
419  if( DigiIsGood )
420  {
421  if( detId.endcap() == 1 )
422  n_alctsP++;
423  else if ( detId.endcap() == 2)
424  n_alctsM++;
425  }
426  }
427  }
428  }
429  }
430  else
431  {
432  static std::atomic<bool> DigiFail{false};
433  bool expected = false;
434  if (DigiFail.compare_exchange_strong(expected,true,std::memory_order_acq_rel)){
435  edm::LogWarning ("InvalidInputTag") << "The CSCALCTDigiCollection does not appear to be in the event. The ALCT Digis will "
436  << " not be used in the halo identification";
437  }
438  }
439  TheCSCHaloData.SetNOutOfTimeTriggers(n_alctsP,n_alctsM);
440 
441  // Loop over the CSCRecHit2D collection to look for out-of-time recHits
442  // Out-of-time is defined as tpeak outside [t_0 + TOF - t_window, t_0 + TOF + t_window]
443  // where t_0 and t_window are configurable parameters
444  short int n_recHitsP = 0;
445  short int n_recHitsM = 0;
446  if( TheCSCRecHits.isValid() )
447  {
449  for (dRHIter = TheCSCRecHits->begin(); dRHIter != TheCSCRecHits->end(); dRHIter++)
450  {
451  if ( !((*dRHIter).isValid()) ) continue; // only interested in valid hits
452  CSCDetId idrec = (CSCDetId)(*dRHIter).cscDetId();
453  float RHTime = (*dRHIter).tpeak();
454  LocalPoint rhitlocal = (*dRHIter).localPosition();
455  const CSCChamber* chamber = TheCSCGeometry.chamber(idrec);
456  GlobalPoint globalPosition = chamber->toGlobal(rhitlocal);
457  float globZ = globalPosition.z();
458  if ( RHTime < (recHit_t0 - recHit_twindow) )
459  {
460  if( globZ > 0 )
461  n_recHitsP++;
462  else
463  n_recHitsM++;
464  }
465 
466  /*
467 
468  float globX = globalPosition.x();
469  float globY = globalPosition.y();
470  float globZ = globalPosition.z();
471  float TOF = (sqrt(globX*globX+ globY*globY + globZ*globZ))/29.9792458 ; //cm -> ns
472  if ( (RHTime < (recHit_t0 + TOF - recHit_twindow)) || (RHTime > (recHit_t0 + TOF + recHit_twindow)) )
473  {
474  if( globZ > 0 )
475  n_recHitsP++;
476  else
477  n_recHitsM++;
478  }
479  */
480  }
481  }
482  else
483  {
484  static std::atomic<bool> RecHitFail{false};
485  bool expected = false;
486  if( RecHitFail.compare_exchange_strong(expected,true,std::memory_order_acq_rel) )
487  {
488  edm::LogWarning ("InvalidInputTag") << "The requested CSCRecHit2DCollection does not appear to be in the event. The CSC RecHit "
489  << " variables used for halo identification will not be calculated or stored";
490  }
491  }
492  TheCSCHaloData.SetNOutOfTimeHits(n_recHitsP+n_recHitsM);
493  // MLR
494  // Loop through CSCSegments and count the number of "flat" segments with the same (r,phi),
495  // saving the value in TheCSCHaloData.
496  short int maxNSegments = 0;
497  bool plus_endcap = false;
498  bool minus_endcap = false;
499  bool both_endcaps = false;
500  //float r = 0., phi = 0.;
501  if (TheCSCSegments.isValid()) {
502  for(CSCSegmentCollection::const_iterator iSegment = TheCSCSegments->begin();
503  iSegment != TheCSCSegments->end();
504  iSegment++) {
505 
506  CSCDetId iCscDetID = iSegment->cscDetId();
507  bool SegmentIsGood=true;
508  //avoid segments from collision muons
509  if( TheMuons.isValid() )
510  {
511  for(reco::MuonCollection::const_iterator mu = TheMuons->begin(); mu!= TheMuons->end() && SegmentIsGood ; mu++ )
512  {
513  if( !mu->isTrackerMuon() && !mu->isGlobalMuon() && mu->isStandAloneMuon() ) continue;
514  const std::vector<MuonChamberMatch> chambers = mu->matches();
515  for(std::vector<MuonChamberMatch>::const_iterator kChamber = chambers.begin();
516  kChamber != chambers.end(); kChamber ++ )
517  {
518  if( kChamber->detector() != MuonSubdetId::CSC ) continue;
519  for( std::vector<reco::MuonSegmentMatch>::const_iterator kSegment = kChamber->segmentMatches.begin();
520  kSegment != kChamber->segmentMatches.end(); kSegment++ )
521  {
522  edm::Ref<CSCSegmentCollection> cscSegRef = kSegment->cscSegmentRef;
523  CSCDetId kCscDetID = cscSegRef->cscDetId();
524 
525  if( kCscDetID == iCscDetID )
526  {
527  SegmentIsGood = false;
528  }
529  }
530  }
531  }
532  }
533  if(!SegmentIsGood) continue;
534 
535  // Get local direction vector; if direction runs parallel to beamline,
536  // count this segment as beam halo candidate.
537  LocalPoint iLocalPosition = iSegment->localPosition();
538  LocalVector iLocalDirection = iSegment->localDirection();
539 
540  GlobalPoint iGlobalPosition = TheCSCGeometry.chamber(iCscDetID)->toGlobal(iLocalPosition);
541  GlobalVector iGlobalDirection = TheCSCGeometry.chamber(iCscDetID)->toGlobal(iLocalDirection);
542 
543  float iTheta = iGlobalDirection.theta();
544  if (iTheta > max_segment_theta && iTheta < TMath::Pi() - max_segment_theta) continue;
545 
546  float iPhi = iGlobalPosition.phi();
547  float iR = TMath::Sqrt(iGlobalPosition.x()*iGlobalPosition.x() + iGlobalPosition.y()*iGlobalPosition.y());
548  short int nSegs = 0;
549 
550  // Changed to loop over all Segments (so N^2) to catch as many segments as possible.
551  for (CSCSegmentCollection::const_iterator jSegment = TheCSCSegments->begin();
552  jSegment != TheCSCSegments->end();
553  jSegment++) {
554  if (jSegment == iSegment) continue;
555 
556  LocalPoint jLocalPosition = jSegment->localPosition();
557  LocalVector jLocalDirection = jSegment->localDirection();
558  CSCDetId jCscDetID = jSegment->cscDetId();
559  GlobalPoint jGlobalPosition = TheCSCGeometry.chamber(jCscDetID)->toGlobal(jLocalPosition);
560  GlobalVector jGlobalDirection = TheCSCGeometry.chamber(jCscDetID)->toGlobal(jLocalDirection);
561  float jTheta = jGlobalDirection.theta();
562  float jPhi = jGlobalPosition.phi();
563  float jR = TMath::Sqrt(jGlobalPosition.x()*jGlobalPosition.x() + jGlobalPosition.y()*jGlobalPosition.y());
564 
565  if (TMath::ACos(TMath::Cos(jPhi - iPhi)) <= max_segment_phi_diff
566  && TMath::Abs(jR - iR) <= max_segment_r_diff
567  && (jTheta < max_segment_theta || jTheta > TMath::Pi() - max_segment_theta)) {
569  if( TheMuons.isValid() ) {
570  for(reco::MuonCollection::const_iterator mu = TheMuons->begin(); mu!= TheMuons->end() && SegmentIsGood ; mu++ ) {
571  if( !mu->isTrackerMuon() && !mu->isGlobalMuon() && mu->isStandAloneMuon() ) continue;
572  const std::vector<MuonChamberMatch> chambers = mu->matches();
573  for(std::vector<MuonChamberMatch>::const_iterator kChamber = chambers.begin();
574  kChamber != chambers.end(); kChamber ++ ) {
575  if( kChamber->detector() != MuonSubdetId::CSC ) continue;
576  for( std::vector<reco::MuonSegmentMatch>::const_iterator kSegment = kChamber->segmentMatches.begin();
577  kSegment != kChamber->segmentMatches.end(); kSegment++ ) {
578  edm::Ref<CSCSegmentCollection> cscSegRef = kSegment->cscSegmentRef;
579  CSCDetId kCscDetID = cscSegRef->cscDetId();
580 
581  if( kCscDetID == jCscDetID ) {
582  SegmentIsGood = false;
583  }
584  }
585  }
586  }
587  }
588  if(SegmentIsGood) {
589  nSegs++;
590  minus_endcap = iGlobalPosition.z() < 0 || jGlobalPosition.z() < 0;
591  plus_endcap = iGlobalPosition.z() > 0 || jGlobalPosition.z() > 0;
592  }
593  }
594  }
595  // Correct the fact that the way nSegs counts will always be short by 1
596  if (nSegs > 0) nSegs++;
597  if (nSegs > maxNSegments) {
598  // Use value of r, phi to collect halo CSCSegments for examining timing (not coded yet...)
599  //r = iR;
600  //phi = iPhi;
601  maxNSegments = nSegs;
602  both_endcaps = both_endcaps ? both_endcaps : minus_endcap && plus_endcap;
603  }
604  }
605  }
606  TheCSCHaloData.SetNFlatHaloSegments(maxNSegments);
607  TheCSCHaloData.SetSegmentsBothEndcaps(both_endcaps);
608  // End MLR
609 
610  return TheCSCHaloData;
611 }
612 
const double Pi
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:52
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
Geom::Theta< T > theta() const
T y() const
Definition: PV3DBase.h:63
std::vector< const CSCSegment * > matchCSC(const reco::Track &muon, const edm::Event &event)
reco::CSCHaloData Calculate(const CSCGeometry &TheCSCGeometry, edm::Handle< reco::MuonCollection > &TheCosmicMuons, const edm::Handle< reco::MuonTimeExtraMap > TheCSCTimeMap, edm::Handle< reco::MuonCollection > &TheMuons, edm::Handle< CSCSegmentCollection > &TheCSCSegments, edm::Handle< CSCRecHit2DCollection > &TheCSCRecHits, edm::Handle< L1MuGMTReadoutCollection > &TheL1GMTReadout, edm::Handle< edm::TriggerResults > &TheHLTResults, const edm::TriggerNames *triggerNames, const edm::Handle< CSCALCTDigiCollection > &TheALCTs, MuonSegmentMatcher *TheMatcher, const edm::Event &TheEvent)
Definition: CSCHaloAlgo.cc:37
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:40
float float float z
Geom::Theta< T > theta() const
Definition: PV3DBase.h:75
int endcap() const
Definition: CSCDetId.h:106
static const int CSC
Definition: MuonSubdetId.h:13
unsigned int triggerIndex(std::string const &name) const
Definition: TriggerNames.cc:32
T z() const
Definition: PV3DBase.h:64
T Abs(T a)
Definition: MathUtil.h:49
const std::vector< GlobalPoint > & GetCSCTrackImpactPositions() const
Definition: CSCHaloData.h:78
void SetSegmentsBothEndcaps(bool b)
Definition: CSCHaloData.h:86
int j
Definition: DBlmapReader.cc:9
const int mu
Definition: Constants.h:22
bool isValid() const
Definition: HandleBase.h:76
void SetHLTBit(bool status)
Definition: CSCHaloData.h:74
Definition: DetId.h:18
void SetNFlatHaloSegments(short int nSegments)
Definition: CSCHaloData.h:85
T const * product() const
Definition: Handle.h:81
void SetNIncomingTracks(short int n_small_dT, short int n_small_beta, short int n_small_both)
Definition: CSCHaloData.h:70
const CSCChamber * chamber(CSCDetId id) const
Return the chamber corresponding to given DetId.
Definition: CSCGeometry.cc:118
void SetNumberOfHaloTriggers(int PlusZ, int MinusZ)
Definition: CSCHaloData.h:63
std::vector< CSCALCTDigi >::const_iterator const_iterator
T eta() const
Definition: PV3DBase.h:76
float freeInverseBeta() const
Definition: MuonTimeExtra.h:36
std::vector< L1MuGMTReadoutRecord > const & getRecords() const
void push_back(value_type const &ref)
Add a Ref&lt;C, T&gt; to the RefVector.
Definition: RefVector.h:64
void SetNOutOfTimeHits(short int num)
Definition: CSCHaloData.h:68
std::pair< const_iterator, const_iterator > Range
virtual const GeomDetUnit * idToDetUnit(DetId) const override
Return the pointer to the GeomDetUnit corresponding to a given DetId.
Definition: CSCGeometry.cc:93
void SetNOutOfTimeTriggers(short int PlusZ, short int MinusZ)
Definition: CSCHaloData.h:66
static char chambers[264][20]
Definition: ReadPGInfo.cc:243
T x() const
Definition: PV3DBase.h:62
tuple size
Write out results.
edm::RefVector< reco::TrackCollection > & GetTracks()
Definition: CSCHaloData.h:59