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.
1 
4 /*
5  [class]: CSCHaloAlgo
6  [authors]: R. Remington, The University of Florida
7  [description]: See CSCHaloAlgo.h
8  [date]: October 15, 2009
9 */
10 using namespace reco;
11 using namespace std;
12 using namespace edm;
13 #include "TMath.h"
14 
16 {
17  deta_threshold = 0.;
18  min_inner_radius = 0.;
19  max_inner_radius = 9999.;
20  min_outer_radius = 0.;
21  max_outer_radius = 9999.;
22  dphi_threshold = 999.;
23  norm_chi2_threshold = 999.;
24  recHit_t0=0.;
25  recHit_twindow=25.;
26  expected_BX=3;
27  max_dt_muon_segment=-10.0;
28  max_free_inverse_beta=0.0;
29 
30  min_outer_theta = 0.;
31  max_outer_theta = TMath::Pi();
32 
33  matching_dphi_threshold = 0.18; //radians
34  matching_deta_threshold = 0.4;
35  matching_dwire_threshold = 5.;
36 
37 
38  et_thresh_rh_hbhe=25; //GeV
39  et_thresh_rh_ee=10;
40  et_thresh_rh_eb=10;
41 
42  dphi_thresh_segvsrh_hbhe=0.05; //radians
43  dphi_thresh_segvsrh_eb=0.05;
44  dphi_thresh_segvsrh_ee=0.05;
45 
46  dr_lowthresh_segvsrh_hbhe=-20; //cm
47  dr_lowthresh_segvsrh_eb=-20;
48  dr_lowthresh_segvsrh_ee=-20;
49 
50  dr_highthresh_segvsrh_hbhe=20; //cm
51  dr_highthresh_segvsrh_eb=20;
52  dr_highthresh_segvsrh_ee=20;
53 
54  dt_lowthresh_segvsrh_hbhe=5;//ns
55  dt_lowthresh_segvsrh_eb=5;
56  dt_lowthresh_segvsrh_ee=5;
57 
58  dt_highthresh_segvsrh_hbhe=30;//ns
59  dt_highthresh_segvsrh_eb=30;
60  dt_highthresh_segvsrh_ee=30;
61 
62  geo = 0;
63 
64 
65 
66 }
67 
69  edm::Handle<reco::MuonCollection>& TheCosmicMuons,
70  const edm::Handle<reco::MuonTimeExtraMap> TheCSCTimeMap,
72  edm::Handle<CSCSegmentCollection>& TheCSCSegments,
78  edm::Handle<edm::TriggerResults>& TheHLTResults,
79  const edm::TriggerNames * triggerNames,
80  const edm::Handle<CSCALCTDigiCollection>& TheALCTs,
81  MuonSegmentMatcher *TheMatcher,
82  const edm::Event& TheEvent,
83  const edm::EventSetup& TheSetup)
84 {
85  reco::CSCHaloData TheCSCHaloData;
86  int imucount=0;
87 
88  bool calomatched =false;
89  bool ECALBmatched =false;
90  bool ECALEmatched =false;
91  bool HCALmatched =false;
92 
93  // if(!geo){
94  geo = 0;
96  TheSetup.get<CaloGeometryRecord>().get(pGeo);
97  geo = pGeo.product();
98  //}
99  bool trkmuunvetoisdefault = false; //Pb with low pt tracker muons that veto good csc segments/halo triggers.
100  //Test to "unveto" low pt trk muons.
101  //For now, we just recalculate everything without the veto and add an extra set of variables to the class CSCHaloData.
102  //If this is satisfactory, these variables can become the default ones by setting trkmuunvetoisdefault to true.
103  if( TheCosmicMuons.isValid() )
104  {
105  short int n_tracks_small_beta=0;
106  short int n_tracks_small_dT=0;
107  short int n_tracks_small_dT_and_beta=0;
108  for( reco::MuonCollection::const_iterator iMuon = TheCosmicMuons->begin() ; iMuon != TheCosmicMuons->end() ; iMuon++, imucount++ )
109  {
110  reco::TrackRef Track = iMuon->outerTrack();
111  if(!Track) continue;
112 
113  bool StoreTrack = false;
114  // Calculate global phi coordinate for central most rechit in the track
115  float innermost_global_z = 1500.;
116  float outermost_global_z = 0.;
117  GlobalPoint InnerMostGlobalPosition(0.,0.,0.); // smallest abs(z)
118  GlobalPoint OuterMostGlobalPosition(0.,0.,0.); // largest abs(z)
119  int nCSCHits = 0;
120  for(unsigned int j = 0 ; j < Track->extra()->recHitsSize(); j++ )
121  {
122  auto hit = Track->extra()->recHitRef(j);
123  if( !hit->isValid() ) continue;
124  DetId TheDetUnitId(hit->geographicalId());
125  if( TheDetUnitId.det() != DetId::Muon ) continue;
126  if( TheDetUnitId.subdetId() != MuonSubdetId::CSC ) continue;
127 
128  const GeomDetUnit *TheUnit = TheCSCGeometry.idToDetUnit(TheDetUnitId);
129  LocalPoint TheLocalPosition = hit->localPosition();
130  const BoundPlane& TheSurface = TheUnit->surface();
131  const GlobalPoint TheGlobalPosition = TheSurface.toGlobal(TheLocalPosition);
132 
133  float z = TheGlobalPosition.z();
134  if( abs(z) < innermost_global_z )
135  {
136  innermost_global_z = abs(z);
137  InnerMostGlobalPosition = GlobalPoint( TheGlobalPosition);
138  }
139  if( abs(z) > outermost_global_z )
140  {
141  outermost_global_z = abs(z);
142  OuterMostGlobalPosition = GlobalPoint( TheGlobalPosition );
143  }
144  nCSCHits ++;
145  }
146 
147  std::vector<const CSCSegment*> MatchedSegments = TheMatcher->matchCSC(*Track,TheEvent);
148  // Find the inner and outer segments separately in case they don't agree completely with recHits
149  // Plan for the possibility segments in both endcaps
150  float InnerSegmentTime[2] = {0,0};
151  float OuterSegmentTime[2] = {0,0};
152  float innermost_seg_z[2] = {1500,1500};
153  float outermost_seg_z[2] = {0,0};
154  for (std::vector<const CSCSegment*>::const_iterator segment =MatchedSegments.begin();
155  segment != MatchedSegments.end(); ++segment)
156  {
157  CSCDetId TheCSCDetId((*segment)->cscDetId());
158  const CSCChamber* TheCSCChamber = TheCSCGeometry.chamber(TheCSCDetId);
159  LocalPoint TheLocalPosition = (*segment)->localPosition();
160  const GlobalPoint TheGlobalPosition = TheCSCChamber->toGlobal(TheLocalPosition);
161  float z = TheGlobalPosition.z();
162  int TheEndcap = TheCSCDetId.endcap();
163  if( abs(z) < innermost_seg_z[TheEndcap-1] )
164  {
165  innermost_seg_z[TheEndcap-1] = abs(z);
166  InnerSegmentTime[TheEndcap-1] = (*segment)->time();
167  }
168  if( abs(z) > outermost_seg_z[TheEndcap-1] )
169  {
170  outermost_seg_z[TheEndcap-1] = abs(z);
171  OuterSegmentTime[TheEndcap-1] = (*segment)->time();
172  }
173  }
174 
175  if( nCSCHits < 3 ) continue; // This needs to be optimized, but is the minimum
176 
177  float dT_Segment = 0; // default safe value, looks like collision muon
178 
179  if( innermost_seg_z[0] < outermost_seg_z[0]) // two segments in ME+
180  dT_Segment = OuterSegmentTime[0]-InnerSegmentTime[0];
181  if( innermost_seg_z[1] < outermost_seg_z[1]) // two segments in ME-
182  {
183  // replace the measurement if there weren't segments in ME+ or
184  // if the track in ME- has timing more consistent with an incoming particle
185  if (dT_Segment == 0.0 || OuterSegmentTime[1]-InnerSegmentTime[1] < dT_Segment)
186  dT_Segment = OuterSegmentTime[1]-InnerSegmentTime[1] ;
187  }
188 
189  if( OuterMostGlobalPosition.x() == 0. || OuterMostGlobalPosition.y() == 0. || OuterMostGlobalPosition.z() == 0. )
190  continue;
191  if( InnerMostGlobalPosition.x() == 0. || InnerMostGlobalPosition.y() == 0. || InnerMostGlobalPosition.z() == 0. )
192  continue;
193 
194  //Its a CSC Track,store it if it passes halo selection
195  StoreTrack = true;
196 
197  float deta = abs( OuterMostGlobalPosition.eta() - InnerMostGlobalPosition.eta() );
198  float dphi = abs(deltaPhi( OuterMostGlobalPosition.phi() , InnerMostGlobalPosition.phi() )) ;
199  float theta = Track->outerMomentum().theta();
200  float innermost_x = InnerMostGlobalPosition.x() ;
201  float innermost_y = InnerMostGlobalPosition.y();
202  float outermost_x = OuterMostGlobalPosition.x();
203  float outermost_y = OuterMostGlobalPosition.y();
204  float innermost_r = TMath::Sqrt(innermost_x *innermost_x + innermost_y * innermost_y );
205  float outermost_r = TMath::Sqrt(outermost_x *outermost_x + outermost_y * outermost_y );
206 
207  if( deta < deta_threshold )
208  StoreTrack = false;
209  if( theta > min_outer_theta && theta < max_outer_theta )
210  StoreTrack = false;
211  if( dphi > dphi_threshold )
212  StoreTrack = false;
213  if( innermost_r < min_inner_radius )
214  StoreTrack = false;
215  if( innermost_r > max_inner_radius )
216  StoreTrack = false;
217  if( outermost_r < min_outer_radius )
218  StoreTrack = false;
219  if( outermost_r > max_outer_radius )
220  StoreTrack = false;
221  if( Track->normalizedChi2() > norm_chi2_threshold )
222  StoreTrack = false;
223 
224  if( StoreTrack )
225  {
226  TheCSCHaloData.GetCSCTrackImpactPositions().push_back( InnerMostGlobalPosition );
227  TheCSCHaloData.GetTracks().push_back( Track );
228  }
229 
230  // Analyze the MuonTimeExtra information
231  if( TheCSCTimeMap.isValid() )
232  {
233  reco::MuonRef muonR(TheCosmicMuons,imucount);
234  const reco::MuonTimeExtraMap & timeMapCSC = *TheCSCTimeMap;
235  reco::MuonTimeExtra timecsc = timeMapCSC[muonR];
236  float freeInverseBeta = timecsc.freeInverseBeta();
237 
238  if (dT_Segment < max_dt_muon_segment )
239  n_tracks_small_dT++;
240  if (freeInverseBeta < max_free_inverse_beta)
241  n_tracks_small_beta++;
242  if ((dT_Segment < max_dt_muon_segment) && (freeInverseBeta < max_free_inverse_beta))
243  n_tracks_small_dT_and_beta++;
244  }
245  else
246  {
247  static std::atomic<bool> MuonTimeFail{false};
248  bool expected = false;
249  if( MuonTimeFail.compare_exchange_strong(expected,true,std::memory_order_acq_rel) )
250  {
251  edm::LogWarning ("InvalidInputTag") << "The MuonTimeExtraMap does not appear to be in the event. Some beam halo "
252  << " identification variables will be empty" ;
253  }
254  }
255  }
256  TheCSCHaloData.SetNIncomingTracks(n_tracks_small_dT,n_tracks_small_beta,n_tracks_small_dT_and_beta);
257  }
258  else // collection is invalid
259  {
260  static std::atomic<bool> CosmicFail{false};
261  bool expected = false;
262  if( CosmicFail.compare_exchange_strong(expected,true,std::memory_order_acq_rel) )
263  {
264  edm::LogWarning ("InvalidInputTag") << " The Cosmic Muon collection does not appear to be in the event. These beam halo "
265  << " identification variables will be empty" ;
266  }
267  }
268 
269  if( TheHLTResults.isValid() )
270  {
271  bool EventPasses = false;
272  for( unsigned int index = 0 ; index < vIT_HLTBit.size(); index++)
273  {
274  if( vIT_HLTBit[index].label().size() )
275  {
276  //Get the HLT bit and check to make sure it is valid
277  unsigned int bit = triggerNames->triggerIndex( vIT_HLTBit[index].label().c_str());
278  if( bit < TheHLTResults->size() )
279  {
280  //If any of the HLT names given by the user accept, then the event passes
281  if( TheHLTResults->accept( bit ) && !TheHLTResults->error( bit ) )
282  {
283  EventPasses = true;
284  }
285  }
286  }
287  }
288  if( EventPasses )
289  TheCSCHaloData.SetHLTBit(true);
290  else
291  TheCSCHaloData.SetHLTBit(false);
292  }
293  else // HLT results are not valid
294  {
295  static std::atomic<bool> HLTFail{false};
296  bool expected = false;
297  if( HLTFail.compare_exchange_strong(expected,true,std::memory_order_acq_rel) )
298  {
299  edm::LogWarning ("InvalidInputTag") << "The HLT results do not appear to be in the event. The beam halo HLT trigger "
300  << "decision will not be used in the halo identification";
301  }
302  }
303 
304  if( TheL1GMTReadout.isValid() )
305  {
306  L1MuGMTReadoutCollection const *gmtrc = TheL1GMTReadout.product ();
307  std::vector < L1MuGMTReadoutRecord > gmt_records = gmtrc->getRecords ();
308  std::vector < L1MuGMTReadoutRecord >::const_iterator igmtrr;
309 
310  int icsc = 0;
311  int PlusZ = 0 ;
312  int MinusZ = 0 ;
313  int PlusZ_alt = 0 ;
314  int MinusZ_alt = 0 ;
315 
316  // Check to see if CSC BeamHalo trigger is tripped
317  for (igmtrr = gmt_records.begin (); igmtrr != gmt_records.end (); igmtrr++)
318  {
319  std::vector < L1MuRegionalCand >::const_iterator iter1;
320  std::vector < L1MuRegionalCand > rmc;
321  rmc = igmtrr->getCSCCands ();
322  for (iter1 = rmc.begin (); iter1 != rmc.end (); iter1++)
323  {
324  if (!(*iter1).empty ())
325  {
326  if ((*iter1).isFineHalo ())
327  {
328  float halophi = iter1->phiValue();
329  halophi = halophi > TMath::Pi() ? halophi - 2.*TMath::Pi() : halophi;
330  float haloeta = iter1->etaValue();
331  bool HaloIsGood = true;
332  bool HaloIsGood_alt = true;
333  // Check if halo trigger is faked by any collision muons
334  if( TheMuons.isValid() )
335  {
336  float dphi = 9999.;
337  float deta = 9999.;
338  for( reco::MuonCollection::const_iterator mu = TheMuons->begin(); mu != TheMuons->end() && (HaloIsGood ||!trkmuunvetoisdefault) ; mu++ )
339  {
340  // Don't match with SA-only muons
341  bool lowpttrackmu =false;
342  if( mu->isStandAloneMuon() && !mu->isTrackerMuon() && !mu->isGlobalMuon() ) continue;
343  if( !mu->isGlobalMuon() && mu->isTrackerMuon() && mu->pt()<3 && trkmuunvetoisdefault) continue;
344  if( !mu->isGlobalMuon() && mu->isTrackerMuon() && mu->pt()<3 ) lowpttrackmu = true;
345 
346  /*
347  if(!mu->isTrackerMuon())
348  {
349  if( mu->isStandAloneMuon() )
350  {
351  //make sure that this SA muon is not actually a halo-like muon
352  float theta = mu->outerTrack()->outerMomentum().theta();
353  float deta = abs(mu->outerTrack()->outerPosition().eta() - mu->outerTrack()->innerPosition().eta());
354  if( theta < min_outer_theta || theta > max_outer_theta ) //halo-like
355  continue;
356  else if ( deta > deta_threshold ) //halo-like
357  continue;
358  }
359  }
360  */
361 
362  const std::vector<MuonChamberMatch> chambers = mu->matches();
363  for(std::vector<MuonChamberMatch>::const_iterator iChamber = chambers.begin();
364  iChamber != chambers.end() ; iChamber ++ )
365  {
366  if( iChamber->detector() != MuonSubdetId::CSC ) continue;
367  for( std::vector<reco::MuonSegmentMatch>::const_iterator iSegment = iChamber->segmentMatches.begin() ;
368  iSegment != iChamber->segmentMatches.end(); ++iSegment )
369  {
370  edm::Ref<CSCSegmentCollection> cscSegment = iSegment->cscSegmentRef;
371  std::vector<CSCRecHit2D> hits = cscSegment -> specificRecHits();
372  for( std::vector<CSCRecHit2D>::iterator iHit = hits.begin();
373  iHit != hits.end() ; iHit++ )
374  {
375  DetId TheDetUnitId(iHit->cscDetId());
376  const GeomDetUnit *TheUnit = TheCSCGeometry.idToDetUnit(TheDetUnitId);
377  LocalPoint TheLocalPosition = iHit->localPosition();
378  const BoundPlane& TheSurface = TheUnit->surface();
379  GlobalPoint TheGlobalPosition = TheSurface.toGlobal(TheLocalPosition);
380 
381  float phi_ = TheGlobalPosition.phi();
382  float eta_ = TheGlobalPosition.eta();
383 
384  deta = deta < abs( eta_ - haloeta ) ? deta : abs( eta_ - haloeta );
385  dphi = dphi < abs(deltaPhi(phi_, halophi)) ? dphi : abs(deltaPhi(phi_, halophi));
386  }
387  }
388  }
389  if ( dphi < matching_dphi_threshold && deta < matching_deta_threshold){
390  HaloIsGood = false; // i.e., collision muon likely faked halo trigger
391  if(!lowpttrackmu)HaloIsGood_alt = false;
392  }
393  }
394  }
395  if( HaloIsGood ){
396  if( (*iter1).etaValue() > 0 )
397  PlusZ++;
398  else
399  MinusZ++;
400  }
401  if( HaloIsGood_alt ){
402  if( (*iter1).etaValue() > 0 )
403  PlusZ_alt++;
404  else
405  MinusZ_alt++;
406  }
407 
408  }
409  else
410  icsc++;
411  }
412  }
413  }
414  TheCSCHaloData.SetNumberOfHaloTriggers(PlusZ, MinusZ);
415  TheCSCHaloData.SetNumberOfHaloTriggers_TrkMuUnVeto(PlusZ_alt, MinusZ_alt);
416  }
417  else
418  {
419  static std::atomic<bool> L1Fail{false};
420  bool expected = false;
421  if( L1Fail.compare_exchange_strong(expected,true,std::memory_order_acq_rel) )
422  {
423  edm::LogWarning ("InvalidInputTag") << "The L1MuGMTReadoutCollection does not appear to be in the event. The L1 beam halo trigger "
424  << "decision will not be used in the halo identification";
425  }
426  }
427 
428  // Loop over CSCALCTDigi collection to look for out-of-time chamber triggers
429  // A collision muon in real data should only have ALCTDigi::getBX() = 3 ( in MC, it will be 6 )
430  // Note that there could be two ALCTs per chamber
431  short int n_alctsP=0;
432  short int n_alctsM=0;
433  if(TheALCTs.isValid())
434  {
435  for (CSCALCTDigiCollection::DigiRangeIterator j=TheALCTs->begin(); j!=TheALCTs->end(); j++)
436  {
437  const CSCALCTDigiCollection::Range& range =(*j).second;
438  CSCDetId detId((*j).first.rawId());
439  for (CSCALCTDigiCollection::const_iterator digiIt = range.first; digiIt!=range.second; ++digiIt)
440  {
441  if( (*digiIt).isValid() && ( (*digiIt).getBX() < expected_BX ) )
442  {
443  int digi_endcap = detId.endcap();
444  int digi_station = detId.station();
445  int digi_ring = detId.ring();
446  int digi_chamber = detId.chamber();
447  int digi_wire = digiIt->getKeyWG();
448  if( digi_station == 1 && digi_ring == 4 ) //hack
449  digi_ring = 1;
450 
451  bool DigiIsGood = true;
452  int dwire = 999.;
453  if( TheMuons.isValid() )
454  {
455  //Check if there are any collision muons with hits in the vicinity of the digi
456  for(reco::MuonCollection::const_iterator mu = TheMuons->begin(); mu!= TheMuons->end() && DigiIsGood ; mu++ )
457  {
458 
459  if( !mu->isTrackerMuon() && !mu->isGlobalMuon() && mu->isStandAloneMuon() ) continue;
460  if( !mu->isGlobalMuon() && mu->isTrackerMuon() && mu->pt()<3 &&trkmuunvetoisdefault) continue;
461  const std::vector<MuonChamberMatch> chambers = mu->matches();
462  for(std::vector<MuonChamberMatch>::const_iterator iChamber = chambers.begin();
463  iChamber != chambers.end(); iChamber ++ )
464  {
465  if( iChamber->detector() != MuonSubdetId::CSC ) continue;
466  for( std::vector<reco::MuonSegmentMatch>::const_iterator iSegment = iChamber->segmentMatches.begin();
467  iSegment != iChamber->segmentMatches.end(); iSegment++ )
468  {
469  edm::Ref<CSCSegmentCollection> cscSegRef = iSegment->cscSegmentRef;
470  std::vector<CSCRecHit2D> hits = cscSegRef->specificRecHits();
471  for( std::vector<CSCRecHit2D>::iterator iHit = hits.begin();
472  iHit != hits.end(); iHit++ )
473  {
474  if( iHit->cscDetId().endcap() != digi_endcap ) continue;
475  if( iHit->cscDetId().station() != digi_station ) continue;
476  if( iHit->cscDetId().ring() != digi_ring ) continue;
477  if( iHit->cscDetId().chamber() != digi_chamber ) continue;
478  int hit_wire = iHit->hitWire();
479  dwire = dwire < abs(hit_wire - digi_wire)? dwire : abs(hit_wire - digi_wire );
480  }
481  }
482  }
483  if( dwire <= matching_dwire_threshold )
484  DigiIsGood = false; // collision-like muon is close to this digi
485  }
486  }
487  // only count out of time digis if they are not matched to collision muons
488  if( DigiIsGood )
489  {
490  if( detId.endcap() == 1 )
491  n_alctsP++;
492  else if ( detId.endcap() == 2)
493  n_alctsM++;
494  }
495  }
496  }
497  }
498  }
499  else
500  {
501  static std::atomic<bool> DigiFail{false};
502  bool expected = false;
503  if (DigiFail.compare_exchange_strong(expected,true,std::memory_order_acq_rel)){
504  edm::LogWarning ("InvalidInputTag") << "The CSCALCTDigiCollection does not appear to be in the event. The ALCT Digis will "
505  << " not be used in the halo identification";
506  }
507  }
508  TheCSCHaloData.SetNOutOfTimeTriggers(n_alctsP,n_alctsM);
509 
510  // Loop over the CSCRecHit2D collection to look for out-of-time recHits
511  // Out-of-time is defined as tpeak outside [t_0 + TOF - t_window, t_0 + TOF + t_window]
512  // where t_0 and t_window are configurable parameters
513  short int n_recHitsP = 0;
514  short int n_recHitsM = 0;
515  if( TheCSCRecHits.isValid() )
516  {
518  for (dRHIter = TheCSCRecHits->begin(); dRHIter != TheCSCRecHits->end(); dRHIter++)
519  {
520  if ( !((*dRHIter).isValid()) ) continue; // only interested in valid hits
521  CSCDetId idrec = (CSCDetId)(*dRHIter).cscDetId();
522  float RHTime = (*dRHIter).tpeak();
523  LocalPoint rhitlocal = (*dRHIter).localPosition();
524  const CSCChamber* chamber = TheCSCGeometry.chamber(idrec);
525  GlobalPoint globalPosition = chamber->toGlobal(rhitlocal);
526  float globZ = globalPosition.z();
527  if ( RHTime < (recHit_t0 - recHit_twindow) )
528  {
529  if( globZ > 0 )
530  n_recHitsP++;
531  else
532  n_recHitsM++;
533  }
534 
535  /*
536 
537  float globX = globalPosition.x();
538  float globY = globalPosition.y();
539  float globZ = globalPosition.z();
540  float TOF = (sqrt(globX*globX+ globY*globY + globZ*globZ))/29.9792458 ; //cm -> ns
541  if ( (RHTime < (recHit_t0 + TOF - recHit_twindow)) || (RHTime > (recHit_t0 + TOF + recHit_twindow)) )
542  {
543  if( globZ > 0 )
544  n_recHitsP++;
545  else
546  n_recHitsM++;
547  }
548  */
549  }
550  }
551  else
552  {
553  static std::atomic<bool> RecHitFail{false};
554  bool expected = false;
555  if( RecHitFail.compare_exchange_strong(expected,true,std::memory_order_acq_rel) )
556  {
557  edm::LogWarning ("InvalidInputTag") << "The requested CSCRecHit2DCollection does not appear to be in the event. The CSC RecHit "
558  << " variables used for halo identification will not be calculated or stored";
559  }
560  }
561  TheCSCHaloData.SetNOutOfTimeHits(n_recHitsP+n_recHitsM);
562  // MLR
563  // Loop through CSCSegments and count the number of "flat" segments with the same (r,phi),
564  // saving the value in TheCSCHaloData.
565  short int maxNSegments = 0;
566  bool plus_endcap = false;
567  bool minus_endcap = false;
568  bool both_endcaps = false;
569  bool both_endcaps_loose = false;
570  // bool both_endcaps_dtcut = false;
571 
572  short int maxNSegments_alt = 0;
573  bool both_endcaps_alt = false;
574  bool both_endcaps_loose_alt = false;
575  bool both_endcaps_loose_dtcut_alt = false;
576 
577  //float r = 0., phi = 0.;
578  if (TheCSCSegments.isValid()) {
579  for(CSCSegmentCollection::const_iterator iSegment = TheCSCSegments->begin();
580  iSegment != TheCSCSegments->end();
581  iSegment++) {
582 
583  CSCDetId iCscDetID = iSegment->cscDetId();
584  bool Segment1IsGood=true;
585  bool Segment1IsGood_alt=true;
586 
587  //avoid segments from collision muons
588  if( TheMuons.isValid() )
589  {
590  for(reco::MuonCollection::const_iterator mu = TheMuons->begin(); mu!= TheMuons->end() && (Segment1IsGood||!trkmuunvetoisdefault) ; mu++ )
591  {
592  bool lowpttrackmu=false;
593  if( !mu->isTrackerMuon() && !mu->isGlobalMuon() && mu->isStandAloneMuon() ) continue;
594  if( !mu->isTrackerMuon() && !mu->isGlobalMuon() && mu->isStandAloneMuon()&&trkmuunvetoisdefault) continue;
595  if( !mu->isGlobalMuon() && mu->isTrackerMuon() && mu->pt()<3) lowpttrackmu=true;
596  const std::vector<MuonChamberMatch> chambers = mu->matches();
597  for(std::vector<MuonChamberMatch>::const_iterator kChamber = chambers.begin();
598  kChamber != chambers.end(); kChamber ++ )
599  {
600  if( kChamber->detector() != MuonSubdetId::CSC ) continue;
601  for( std::vector<reco::MuonSegmentMatch>::const_iterator kSegment = kChamber->segmentMatches.begin();
602  kSegment != kChamber->segmentMatches.end(); kSegment++ )
603  {
604  edm::Ref<CSCSegmentCollection> cscSegRef = kSegment->cscSegmentRef;
605  CSCDetId kCscDetID = cscSegRef->cscDetId();
606 
607  if( kCscDetID == iCscDetID )
608  {
609  Segment1IsGood = false;
610  if(!lowpttrackmu) Segment1IsGood_alt=false;
611  }
612  }
613  }
614  }
615  }
616  if(!Segment1IsGood&&!Segment1IsGood_alt) continue;
617 
618  // Get local direction vector; if direction runs parallel to beamline,
619  // count this segment as beam halo candidate.
620  LocalPoint iLocalPosition = iSegment->localPosition();
621  LocalVector iLocalDirection = iSegment->localDirection();
622 
623  GlobalPoint iGlobalPosition = TheCSCGeometry.chamber(iCscDetID)->toGlobal(iLocalPosition);
624  GlobalVector iGlobalDirection = TheCSCGeometry.chamber(iCscDetID)->toGlobal(iLocalDirection);
625 
626  float iTheta = iGlobalDirection.theta();
627  if (iTheta > max_segment_theta && iTheta < TMath::Pi() - max_segment_theta) continue;
628 
629  float iPhi = iGlobalPosition.phi();
630  float iR = TMath::Sqrt(iGlobalPosition.x()*iGlobalPosition.x() + iGlobalPosition.y()*iGlobalPosition.y());
631  float iZ = iGlobalPosition.z();
632  float iT = iSegment->time();
633  //Timing condition, helps removing random segments from next collisions
634  if(iT>15) continue;
635  // if(abs(iZ)<650&& TheEvent.id().run()< 251737) iT-= 25;
636  //Calo matching:
637 
638  bool hbhematched = HCALSegmentMatching(hbhehits,et_thresh_rh_hbhe,dphi_thresh_segvsrh_hbhe,dr_lowthresh_segvsrh_hbhe,dr_highthresh_segvsrh_hbhe,dt_lowthresh_segvsrh_hbhe,dt_highthresh_segvsrh_hbhe,iZ,iR,iT,iPhi);
639  bool ebmatched = ECALSegmentMatching(ecalebhits,et_thresh_rh_eb,dphi_thresh_segvsrh_eb,dr_lowthresh_segvsrh_eb,dr_highthresh_segvsrh_eb,dt_lowthresh_segvsrh_eb,dt_highthresh_segvsrh_eb,iZ,iR,iT,iPhi);
640  bool eematched = ECALSegmentMatching(ecaleehits,et_thresh_rh_ee,dphi_thresh_segvsrh_ee,dr_lowthresh_segvsrh_ee,dr_highthresh_segvsrh_ee,dt_lowthresh_segvsrh_ee,dt_highthresh_segvsrh_ee,iZ,iR,iT,iPhi);
641  calomatched = calomatched? true : (hbhematched|| ebmatched|| eematched);
642  HCALmatched = HCALmatched? true :hbhematched;
643  ECALBmatched = ECALBmatched? true :ebmatched;
644  ECALEmatched = ECALEmatched? true :eematched;
645 
646  short int nSegs = 0;
647  short int nSegs_alt = 0;
648  // Changed to loop over all Segments (so N^2) to catch as many segments as possible.
649  for (CSCSegmentCollection::const_iterator jSegment = TheCSCSegments->begin();
650  jSegment != TheCSCSegments->end();
651  jSegment++) {
652  if (jSegment == iSegment) continue;
653  bool Segment2IsGood = true;
654  bool Segment2IsGood_alt = true;
655  LocalPoint jLocalPosition = jSegment->localPosition();
656  LocalVector jLocalDirection = jSegment->localDirection();
657  CSCDetId jCscDetID = jSegment->cscDetId();
658  GlobalPoint jGlobalPosition = TheCSCGeometry.chamber(jCscDetID)->toGlobal(jLocalPosition);
659  GlobalVector jGlobalDirection = TheCSCGeometry.chamber(jCscDetID)->toGlobal(jLocalDirection);
660  float jTheta = jGlobalDirection.theta();
661  float jPhi = jGlobalPosition.phi();
662  float jR = TMath::Sqrt(jGlobalPosition.x()*jGlobalPosition.x() + jGlobalPosition.y()*jGlobalPosition.y());
663  float jZ = jGlobalPosition.z() ;
664  float jT = jSegment->time();
665  //Timing condition, helps removing random segments from next collisions
666  if(jT>15) continue;
667  // if(abs(jZ)<650&& TheEvent.id().run() < 251737)jT-= 25;
668  if ( abs(deltaPhi(jPhi , iPhi)) <= 0.1//max_segment_phi_diff
669  //&& abs(jR - iR) <= max_segment_r_diff
670  && (abs(jR - iR)<0.03*abs(jZ - iZ))
671  && (abs(jR - iR) <= max_segment_r_diff || jZ*iZ < 0)
672  && (jTheta < max_segment_theta || jTheta > TMath::Pi() - max_segment_theta)) {
674  if( TheMuons.isValid() ) {
675  for(reco::MuonCollection::const_iterator mu = TheMuons->begin(); mu!= TheMuons->end() && (Segment2IsGood||!trkmuunvetoisdefault) ; mu++ ) {
676  bool lowpttrackmu=false;
677  if( !mu->isTrackerMuon() && !mu->isGlobalMuon() && mu->isStandAloneMuon() ) continue;
678  if( !mu->isGlobalMuon() && mu->isTrackerMuon() && mu->pt()<3) lowpttrackmu= true;
679  const std::vector<MuonChamberMatch> chambers = mu->matches();
680  for(std::vector<MuonChamberMatch>::const_iterator kChamber = chambers.begin();
681  kChamber != chambers.end(); kChamber ++ ) {
682  if( kChamber->detector() != MuonSubdetId::CSC ) continue;
683  for( std::vector<reco::MuonSegmentMatch>::const_iterator kSegment = kChamber->segmentMatches.begin();
684  kSegment != kChamber->segmentMatches.end(); kSegment++ ) {
685  edm::Ref<CSCSegmentCollection> cscSegRef = kSegment->cscSegmentRef;
686  CSCDetId kCscDetID = cscSegRef->cscDetId();
687 
688  if( kCscDetID == jCscDetID ) {
689  Segment2IsGood = false;
690  if(!lowpttrackmu) Segment2IsGood_alt=false;
691  }
692  }
693  }
694  }
695  }
696  if(Segment1IsGood && Segment2IsGood) {
697  nSegs++;
698  minus_endcap = iGlobalPosition.z() < 0 || jGlobalPosition.z() < 0;
699  plus_endcap = iGlobalPosition.z() > 0 || jGlobalPosition.z() > 0;
700  // if( abs(jT-iT)/sqrt( (jR-iR)*(jR-iR)+(jZ-iZ)*(jZ-iZ) )<0.05 && abs(jT-iT)/sqrt( (jR-iR)*(jR-iR)+(jZ-iZ)*(jZ-iZ) )>0.02 && minus_endcap&&plus_endcap ) both_endcaps_dtcut =true;
701  }
702  if(Segment1IsGood_alt && Segment2IsGood_alt) {
703  nSegs_alt++;
704  minus_endcap = iGlobalPosition.z() < 0 || jGlobalPosition.z() < 0;
705  plus_endcap = iGlobalPosition.z() > 0 || jGlobalPosition.z() > 0;
706  if(
707  abs(jT-iT)<0.05*sqrt( (jR-iR)*(jR-iR)+(jZ-iZ)*(jZ-iZ) ) &&
708  abs(jT-iT)> 0.02*sqrt( (jR-iR)*(jR-iR)+(jZ-iZ)*(jZ-iZ) ) &&
709  (iT>-15 || jT>-15)&&
710  minus_endcap&&plus_endcap ) both_endcaps_loose_dtcut_alt =true;
711  }
712 
713  }
714  }
715  // Correct the fact that the way nSegs counts will always be short by 1
716  if (nSegs > 0) nSegs++;
717 
718  // The opposite endcaps segments do not need to belong to the longest chain.
719  if (nSegs > 0) both_endcaps_loose = both_endcaps_loose ? both_endcaps_loose : minus_endcap && plus_endcap;
720  if (nSegs_alt > 0) nSegs_alt++;
721  if (nSegs_alt > 0) both_endcaps_loose_alt = both_endcaps_loose_alt ? both_endcaps_loose_alt : minus_endcap && plus_endcap;
722 
723  // if (nSegs > 0) both_endcaps_dt20ns = both_endcaps_dt20ns ? both_endcaps_dt20ns : minus_endcap && plus_endcap &&dt20ns;
724  if (nSegs > maxNSegments) {
725  // Use value of r, phi to collect halo CSCSegments for examining timing (not coded yet...)
726  //r = iR;
727  //phi = iPhi;
728  maxNSegments = nSegs;
729  both_endcaps = both_endcaps ? both_endcaps : minus_endcap && plus_endcap;
730  }
731 
732  if (nSegs_alt > maxNSegments_alt) {
733  maxNSegments_alt = nSegs_alt;
734  both_endcaps_alt = both_endcaps_alt ? both_endcaps_alt : minus_endcap && plus_endcap;
735  }
736 
737  }
738  }
739  TheCSCHaloData.SetNFlatHaloSegments(maxNSegments);
740  TheCSCHaloData.SetSegmentsBothEndcaps(both_endcaps);
741  TheCSCHaloData.SetNFlatHaloSegments_TrkMuUnVeto(maxNSegments_alt);
742  TheCSCHaloData.SetSegmentsBothEndcaps_Loose_TrkMuUnVeto(both_endcaps_loose_alt);
743  TheCSCHaloData.SetSegmentsBothEndcaps_Loose_dTcut_TrkMuUnVeto(both_endcaps_loose_dtcut_alt);
744  TheCSCHaloData.SetSegmentIsCaloMatched(calomatched);
745  TheCSCHaloData.SetSegmentIsHCaloMatched(HCALmatched);
746  TheCSCHaloData.SetSegmentIsEBCaloMatched(ECALBmatched);
747  TheCSCHaloData.SetSegmentIsEECaloMatched(ECALEmatched);
748 
749  return TheCSCHaloData;
750 }
751 
753 
754  const GlobalPoint& pos=geo->getPosition(id);
755  math::XYZPoint posV(pos.x() - vtx.x(),pos.y() - vtx.y(),pos.z() - vtx.z());
756  return posV;
757 }
758 
759 
760 bool CSCHaloAlgo::HCALSegmentMatching(edm::Handle<HBHERecHitCollection>& rechitcoll, float et_thresh_rh, float dphi_thresh_segvsrh, float dr_lowthresh_segvsrh, float dr_highthresh_segvsrh, float dt_lowthresh_segvsrh, float dt_highthresh_segvsrh, float iZ, float iR, float iT, float iPhi){
761  reco::Vertex::Point vtx(0,0,0);
762  for(size_t ihit = 0; ihit< rechitcoll->size(); ++ ihit){
763  const HBHERecHit & rechit = (*rechitcoll)[ ihit ];
764  math::XYZPoint rhpos = getPosition(rechit.id(),vtx);
765  double rhet = rechit.energy()/cosh(rhpos.eta());
766  double dphi_rhseg = abs(deltaPhi(rhpos.phi(),iPhi));
767  double dr_rhseg = sqrt(rhpos.x()*rhpos.x()+rhpos.y()*rhpos.y()) - iR;
768  double dtcorr_rhseg = rechit.time()- abs(rhpos.z()-iZ)/30- iT;
769  if(
770  (rechit.time()<-3)&&
771  (rhpos.z()*iZ<0|| abs(rhpos.z())<200)&&
772  rhet> et_thresh_rh&&
773  dphi_rhseg < dphi_thresh_segvsrh &&
774  dr_rhseg < dr_highthresh_segvsrh && dr_rhseg> dr_lowthresh_segvsrh && //careful: asymmetric cut might not be the most appropriate thing
775  dtcorr_rhseg> dt_lowthresh_segvsrh && dtcorr_rhseg< dt_highthresh_segvsrh
776  ) return true;
777  }
778  return false;
779 }
780 
781 bool CSCHaloAlgo::ECALSegmentMatching(edm::Handle<EcalRecHitCollection>& rechitcoll, float et_thresh_rh, float dphi_thresh_segvsrh, float dr_lowthresh_segvsrh, float dr_highthresh_segvsrh, float dt_lowthresh_segvsrh,float dt_highthresh_segvsrh, float iZ, float iR, float iT, float iPhi ){
782  reco::Vertex::Point vtx(0,0,0);
783  for(size_t ihit = 0; ihit<rechitcoll->size(); ++ ihit){
784  const EcalRecHit & rechit = (*rechitcoll)[ ihit ];
785  math::XYZPoint rhpos = getPosition(rechit.id(),vtx);
786  double rhet = rechit.energy()/cosh(rhpos.eta());
787  double dphi_rhseg = abs(deltaPhi(rhpos.phi(),iPhi));
788  double dr_rhseg = sqrt(rhpos.x()*rhpos.x()+rhpos.y()*rhpos.y()) - iR;
789  double dtcorr_rhseg = rechit.time()- abs(rhpos.z()-iZ)/30- iT;
790  if(
791  ( rechit.time()<-1)&&
792  (rhpos.z()*iZ<0|| abs(rhpos.z())<200)&&
793  rhet> et_thresh_rh&&
794  dphi_rhseg < dphi_thresh_segvsrh &&
795  dr_rhseg < dr_highthresh_segvsrh && dr_rhseg> dr_lowthresh_segvsrh && //careful: asymmetric cut might not be the most appropriate thing
796  dtcorr_rhseg> dt_lowthresh_segvsrh && dtcorr_rhseg< dr_highthresh_segvsrh
797  ) return true;
798  }
799  return false;
800 }
const double Pi
void SetNFlatHaloSegments_TrkMuUnVeto(short int nSegments)
Definition: CSCHaloData.h:98
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< HBHERecHitCollection > &hbhehits, edm::Handle< EcalRecHitCollection > &ecalebhits, edm::Handle< EcalRecHitCollection > &ecaleehits, edm::Handle< edm::TriggerResults > &TheHLTResults, const edm::TriggerNames *triggerNames, const edm::Handle< CSCALCTDigiCollection > &TheALCTs, MuonSegmentMatcher *TheMatcher, const edm::Event &TheEvent, const edm::EventSetup &TheEventSetup)
Definition: CSCHaloAlgo.cc:68
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:52
void SetSegmentIsEECaloMatched(bool b)
Definition: CSCHaloData.h:104
HcalDetId id() const
get the id
Definition: HBHERecHit.h:23
void SetSegmentsBothEndcaps_Loose_TrkMuUnVeto(bool b)
Definition: CSCHaloData.h:99
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)
float time() const
Definition: EcalRecHit.h:70
float time() const
Definition: CaloRecHit.h:19
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:40
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
float energy() const
Definition: CaloRecHit.h:17
T sqrt(T t)
Definition: SSEVec.h:48
void SetSegmentIsCaloMatched(bool b)
Definition: CSCHaloData.h:101
T z() const
Definition: PV3DBase.h:64
const std::vector< GlobalPoint > & GetCSCTrackImpactPositions() const
Definition: CSCHaloData.h:88
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void SetSegmentsBothEndcaps(bool b)
Definition: CSCHaloData.h:96
int j
Definition: DBlmapReader.cc:9
float energy() const
Definition: EcalRecHit.h:68
math::XYZPoint Point
point in the space
Definition: Vertex.h:39
const int mu
Definition: Constants.h:22
bool isValid() const
Definition: HandleBase.h:75
void SetHLTBit(bool status)
Definition: CSCHaloData.h:84
double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:12
Definition: DetId.h:18
void SetNFlatHaloSegments(short int nSegments)
Definition: CSCHaloData.h:95
DetId id() const
get the id
Definition: EcalRecHit.h:76
T const * product() const
Definition: Handle.h:81
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
void SetNIncomingTracks(short int n_small_dT, short int n_small_beta, short int n_small_both)
Definition: CSCHaloData.h:80
const T & get() const
Definition: EventSetup.h:56
const CSCChamber * chamber(CSCDetId id) const
Return the chamber corresponding to given DetId.
Definition: CSCGeometry.cc:118
T const * product() const
Definition: ESHandle.h:86
void SetNumberOfHaloTriggers(int PlusZ, int MinusZ)
Definition: CSCHaloData.h:73
std::vector< CSCALCTDigi >::const_iterator const_iterator
void SetSegmentIsHCaloMatched(bool b)
Definition: CSCHaloData.h:102
T eta() const
Definition: PV3DBase.h:76
math::XYZPoint getPosition(const DetId &id, reco::Vertex::Point vtx)
Definition: CSCHaloAlgo.cc:752
float freeInverseBeta() const
Definition: MuonTimeExtra.h:36
std::vector< L1MuGMTReadoutRecord > const & getRecords() const
void SetSegmentsBothEndcaps_Loose_dTcut_TrkMuUnVeto(bool b)
Definition: CSCHaloData.h:100
void push_back(value_type const &ref)
Add a Ref&lt;C, T&gt; to the RefVector.
Definition: RefVector.h:62
bool ECALSegmentMatching(edm::Handle< EcalRecHitCollection > &rechitcoll, float et_thresh_rh, float dphi_thresh_segvsrh, float dr_lowthresh_segvsrh, float dr_highthresh_segvsrh, float dt_lowthresh_segvsrh, float dt_highthresh_segvsrh, float iZ, float iR, float iT, float iPhi)
Definition: CSCHaloAlgo.cc:781
void SetNOutOfTimeHits(short int num)
Definition: CSCHaloData.h:78
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 SetNumberOfHaloTriggers_TrkMuUnVeto(int PlusZ, int MinusZ)
Definition: CSCHaloData.h:74
void SetNOutOfTimeTriggers(short int PlusZ, short int MinusZ)
Definition: CSCHaloData.h:76
static char chambers[264][20]
Definition: ReadPGInfo.cc:243
bool HCALSegmentMatching(edm::Handle< HBHERecHitCollection > &rechitcoll, float et_thresh_rh, float dphi_thresh_segvsrh, float dr_lowthresh_segvsrh, float dr_highthresh_segvsrh, float dt_lowthresh_segvsrh, float dt_highthresh_segvsrh, float iZ, float iR, float iT, float iPhi)
Definition: CSCHaloAlgo.cc:760
void SetSegmentIsEBCaloMatched(bool b)
Definition: CSCHaloData.h:103
T x() const
Definition: PV3DBase.h:62
tuple size
Write out results.
edm::RefVector< reco::TrackCollection > & GetTracks()
Definition: CSCHaloData.h:69