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