CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MuonShowerInformationFiller.cc
Go to the documentation of this file.
1 
13 
14 // system include files
15 #include <memory>
16 #include <algorithm>
17 #include <iostream>
18 
19 // user include files
52 
55 
61 
62 using namespace std;
63 using namespace edm;
64 
65 //
66 // Constructor
67 //
69  theService(0),
70  theDTRecHitLabel(par.getParameter<InputTag>("DTRecSegmentLabel")),
71  theCSCRecHitLabel(par.getParameter<InputTag>("CSCRecSegmentLabel")),
72  theCSCSegmentsLabel(par.getParameter<InputTag>("CSCSegmentLabel")),
73  theDT4DRecSegmentLabel(par.getParameter<InputTag>("DT4DRecSegmentLabel"))
74 {
75 
80 
81 
82  edm::ParameterSet serviceParameters = par.getParameter<edm::ParameterSet>("ServiceParameters");
83  theService = new MuonServiceProxy(serviceParameters);
84 
85  theTrackerRecHitBuilderName = par.getParameter<string>("TrackerRecHitBuilder");
86  theMuonRecHitBuilderName = par.getParameter<string>("MuonRecHitBuilder");
87 
88  theCacheId_TRH = 0;
89  theCacheId_MT = 0;
90 
91  category_ = "MuonShowerInformationFiller";
92 
93  for (int istat = 0; istat < 4; istat++) {
94  theStationShowerDeltaR.push_back(0.);
95  theStationShowerTSize.push_back(0.);
96  theAllStationHits.push_back(0);
97  theCorrelatedStationHits.push_back(0);
98  }
99 
100 }
101 
102 //
103 // Destructor
104 //
106  if (theService) delete theService;
107 }
108 
109 //
110 //Fill the MuonShower struct
111 //
113 
114  reco::MuonShower returnShower;
115 
116  // Update the services
117  theService->update(iSetup);
118  setEvent(iEvent);
119  setServices(theService->eventSetup());
120 
121  fillHitsByStation(muon);
122  std::vector<int> nStationHits = theAllStationHits;
123  std::vector<int> nStationCorrelatedHits = theCorrelatedStationHits;
124  std::vector<float> stationShowerSizeT = theStationShowerTSize;
125  std::vector<float> stationShowerDeltaR = theStationShowerDeltaR;
126 
127  returnShower.nStationHits = nStationHits;
128  returnShower.nStationCorrelatedHits = nStationCorrelatedHits;
129  returnShower.stationShowerSizeT = stationShowerSizeT;
130  returnShower.stationShowerDeltaR = stationShowerDeltaR;
131 
132  return returnShower;
133 
134 }
135 
136 //
137 // Set Event
138 //
140 
141  // get all the necesary products
142  event.getByToken(theDTRecHitToken, theDTRecHits);
143  event.getByToken(theCSCRecHitToken, theCSCRecHits);
144  event.getByToken(theCSCSegmentsToken, theCSCSegments);
145  event.getByToken(theDT4DRecSegmentToken, theDT4DRecSegments);
146 
147  for (int istat = 0; istat < 4; istat++) {
148  theStationShowerDeltaR.at(istat) = 0.;
149  theStationShowerTSize.at(istat) = 0.;
150  theAllStationHits.at(istat) = 0;
151  theCorrelatedStationHits.at(istat) = 0;
152  }
153 }
154 
155 
156 //
157 // Set services
158 //
160 
161  // DetLayer Geometry
163  setup.get<IdealMagneticFieldRecord>().get(theField);
165  setup.get<MuonGeometryRecord>().get(theCSCGeometry);
166  setup.get<MuonGeometryRecord>().get(theDTGeometry);
167 
168  // Transient Rechit Builders
169  unsigned long long newCacheId_TRH = setup.get<TransientRecHitRecord>().cacheIdentifier();
170  if ( newCacheId_TRH != theCacheId_TRH ) {
173  }
174 
175 }
176 
177 //
178 // Get hits owned by segments
179 //
184 
186 
187  DetId geoId = geomDet->geographicalId();
188 
189  if (geoId.subdetId() == MuonSubdetId::DT) {
190 
191  DTChamberId chamberId(geoId.rawId());
192 
193  // loop on segments 4D
194  DTRecSegment4DCollection::id_iterator chamberIdIt;
195  for (chamberIdIt = dtSegments->id_begin();
196  chamberIdIt != dtSegments->id_end();
197  ++chamberIdIt){
198 
199  if (*chamberIdIt != chamberId) continue;
200 
201  // Get the range for the corresponding ChamberId
202  DTRecSegment4DCollection::range range = dtSegments->get((*chamberIdIt));
203 
204  for (DTRecSegment4DCollection::const_iterator iseg = range.first;
205  iseg!=range.second;++iseg) {
206  if (iseg->dimension() != 4) continue;
207  segments.push_back(MuonTransientTrackingRecHit::specificBuild(geomDet,&*iseg));
208  }
209  }
210  }
211  else if (geoId.subdetId() == MuonSubdetId::CSC) {
212 
213  CSCDetId did(geoId.rawId());
214 
215  for ( CSCSegmentCollection::id_iterator chamberId = cscSegments->id_begin();
216  chamberId != cscSegments->id_end(); ++chamberId) {
217 
218  if ((*chamberId).chamber() != did.chamber()) continue;
219 
220  // Get the range for the corresponding ChamberId
221  CSCSegmentCollection::range range = cscSegments->get((*chamberId));
222 
223  for (CSCSegmentCollection::const_iterator iseg = range.first;
224  iseg!=range.second;++iseg) {
225  if (iseg->dimension() != 3) continue;
226  segments.push_back(MuonTransientTrackingRecHit::specificBuild(geomDet,&*iseg));
227  }
228  }
229  }
230  else {
231  LogTrace(category_) << "Segments are not built in RPCs" << endl;
232  }
233 
235 
236  if (segments.empty()) return allhitscorrelated;
237 
238  TransientTrackingRecHit::ConstRecHitPointer muonRecHit(segments.front());
239  allhitscorrelated = MuonTransientTrackingRecHitBreaker::breakInSubRecHits(muonRecHit,2);
240 
241  if (segments.size() == 1) return allhitscorrelated;
242 
243  for (MuonTransientTrackingRecHit::MuonRecHitContainer::const_iterator iseg = segments.begin() + 1;
244  iseg != segments.end(); ++iseg) {
245 
248 
249  for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator ihit1 = hits1.begin();
250  ihit1 != hits1.end(); ++ihit1 ) {
251 
252  bool usedbefore = false;
253  //unused DetId thisID = (*ihit1)->geographicalId();
254  //LocalPoint lp1dinsegHit = (*ihit1)->localPosition();
255  GlobalPoint gp1dinsegHit = (*ihit1)->globalPosition();
256 
257  for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator ihit2 = allhitscorrelated.begin();
258  ihit2 != allhitscorrelated.end(); ++ihit2 ) {
259 
260  //unused DetId thisID2 = (*ihit2)->geographicalId();
261  //LocalPoint lp1dinsegHit2 = (*ihit2)->localPosition();
262  GlobalPoint gp1dinsegHit2 = (*ihit2)->globalPosition();
263 
264  if ( (gp1dinsegHit2 - gp1dinsegHit).mag() < 1.0 ) usedbefore = true;
265 
266  }
267  if ( !usedbefore ) allhitscorrelated.push_back(*ihit1);
268  }
269  }
270 
271  return allhitscorrelated;
272 
273 }
274 
275 
276 //
277 // Find cluster
278 //
279 
282  const GlobalPoint& refpoint) const {
283 
284  if ( muonRecHits.empty() ) return muonRecHits;
285 
286  //clustering step by theta
287  float step = 0.05;
289 
290  stable_sort(muonRecHits.begin(), muonRecHits.end(), AbsLessDTheta(refpoint));
291 
292  for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator ihit = muonRecHits.begin(); ihit != muonRecHits.end() - 1; ++ihit) {
293  if (fabs((*(ihit+1))->globalPosition().theta() - (*ihit)->globalPosition().theta() ) < step) {
294  result.push_back(*ihit);
295  } else {
296  break;
297  }
298  }
299 
300  return result;
301 
302 }
303 
304 //
305 //Used to treat overlap region
306 //
309 
310  if ( muonRecHits.empty() ) return muonRecHits;
311 
312  stable_sort(muonRecHits.begin(), muonRecHits.end(), LessPerp());
313 
314  MuonTransientTrackingRecHit::MuonRecHitContainer::const_iterator
315  seedhit = min_element(muonRecHits.begin(), muonRecHits.end(), LessPerp());
316 
317  MuonTransientTrackingRecHit::MuonRecHitContainer::const_iterator ihigh = seedhit;
318  MuonTransientTrackingRecHit::MuonRecHitContainer::const_iterator ilow = seedhit;
319 
320  float step = 0.1;
321  while (ihigh != muonRecHits.end()-1 && ( fabs((*(ihigh+1))->globalPosition().perp() - (*ihigh)->globalPosition().perp() ) < step) ) {
322  ihigh++;
323  }
324  while (ilow != muonRecHits.begin() && ( fabs((*ilow)->globalPosition().perp() - (*(ilow -1))->globalPosition().perp()) < step ) ) {
325  ilow--;
326  }
327 
329 
330  return result;
331 
332 }
333 
334 //
335 // Get compatible dets
336 //
337 vector<const GeomDet*> MuonShowerInformationFiller::getCompatibleDets(const reco::Track& track) const {
338 
339  vector<const GeomDet*> total;
340  total.reserve(1000);
341 
342  LogTrace(category_) << "Consider a track " << track.p() << " eta: " << track.eta() << " phi " << track.phi() << endl;
343 
344 
345  TrajectoryStateOnSurface innerTsos = trajectoryStateTransform::innerStateOnSurface(track, *theService->trackingGeometry(), &*theService->magneticField());
346  TrajectoryStateOnSurface outerTsos = trajectoryStateTransform::outerStateOnSurface(track, *theService->trackingGeometry(), &*theService->magneticField());
347 
348  GlobalPoint innerPos = innerTsos.globalPosition();
349  GlobalPoint outerPos = outerTsos.globalPosition();
350 
351  vector<GlobalPoint> allCrossingPoints;
352 
353  const vector<const DetLayer*>& dtlayers = theService->detLayerGeometry()->allDTLayers();
354 
355  for (auto iLayer = dtlayers.begin(); iLayer != dtlayers.end(); ++iLayer) {
356 
357  // crossing points of track with cylinder
358  GlobalPoint xPoint = crossingPoint(innerPos, outerPos, dynamic_cast<const BarrelDetLayer*>(*iLayer));
359 
360  // check if point is inside the detector
361  if ((fabs(xPoint.y()) < 1000.0) && (fabs(xPoint.z()) < 1500 ) &&
362  (!(xPoint.y() == 0 && xPoint.x() == 0 && xPoint.z() == 0))) allCrossingPoints.push_back(xPoint);
363  }
364 
365  stable_sort(allCrossingPoints.begin(), allCrossingPoints.end(), LessMag(innerPos) );
366 
367  vector<const GeomDet*> tempDT;
368 
369  for (vector<GlobalPoint>::const_iterator ipos = allCrossingPoints.begin(); ipos != allCrossingPoints.end(); ++ipos) {
370 
371  tempDT = dtPositionToDets(*ipos);
372  vector<const GeomDet*>::const_iterator begin = tempDT.begin();
373  vector<const GeomDet*>::const_iterator end = tempDT.end();
374 
375  for (; begin!=end;++begin) {
376  total.push_back(*begin);
377  }
378 
379  }
380  allCrossingPoints.clear();
381 
382  const vector<const DetLayer*>& csclayers = theService->detLayerGeometry()->allCSCLayers();
383  for (auto iLayer = csclayers.begin(); iLayer != csclayers.end(); ++iLayer) {
384 
385  GlobalPoint xPoint = crossingPoint(innerPos, outerPos, dynamic_cast<const ForwardDetLayer*>(*iLayer));
386 
387  // check if point is inside the detector
388  if ((fabs(xPoint.y()) < 1000.0) && (fabs(xPoint.z()) < 1500.0)
389  && (!(xPoint.y() == 0 && xPoint.x() == 0 && xPoint.z() == 0))) allCrossingPoints.push_back(xPoint);
390  }
391  stable_sort(allCrossingPoints.begin(), allCrossingPoints.end(), LessMag(innerPos) );
392 
393  vector<const GeomDet*> tempCSC;
394  for (vector<GlobalPoint>::const_iterator ipos = allCrossingPoints.begin(); ipos != allCrossingPoints.end(); ++ipos) {
395 
396  tempCSC = cscPositionToDets(*ipos);
397  vector<const GeomDet*>::const_iterator begin = tempCSC.begin();
398  vector<const GeomDet*>::const_iterator end = tempCSC.end();
399 
400  for (; begin!=end;++begin) {
401  total.push_back(*begin);
402  }
403 
404  }
405 
406  return total;
407 
408 }
409 
410 
411 //
412 // Intersection point of track with barrel layer
413 //
415  const GlobalPoint& p2,
416  const BarrelDetLayer* dl) const {
417 
418  const BoundCylinder& bc = dl->specificSurface();
419  return crossingPoint(p1, p2, bc);
420 
421 }
422 
424  const GlobalPoint& p2,
425  const Cylinder& cyl) const {
426 
427  float radius = cyl.radius();
428 
429  GlobalVector dp = p1 - p2;
430  float slope = dp.x()/dp.y();
431  float a = p1.x() - slope * p1.y();
432 
433  float n2 = (1 + slope * slope);
434  float n1 = 2*a*slope;
435  float n0 = a*a - radius*radius;
436 
437  float y1 = 9999;
438  float y2 = 9999;
439  if ( n1*n1 - 4*n2*n0 > 0 ) {
440  y1 = (-n1 + sqrt(n1*n1 - 4*n2*n0) ) / (2 * n2);
441  y2 = (-n1 - sqrt(n1*n1 - 4*n2*n0) ) / (2 * n2);
442  }
443 
444  float x1 = p1.x() + slope * (y1 - p1.y());
445  float x2 = p1.x() + slope * (y2 - p1.y());
446 
447  float slopeZ = dp.z()/dp.y();
448 
449  float z1 = p1.z() + slopeZ * (y1 - p1.y());
450  float z2 = p1.z() + slopeZ * (y2 - p1.y());
451 
452  // there are two crossing points, return the one that is in the same quadrant as point of extrapolation
453  if ((p2.x()*x1 > 0) && (y1*p2.y() > 0) && (z1*p2.z() > 0)) {
454  return GlobalPoint(x1, y1, z1);
455  } else {
456  return GlobalPoint(x2, y2, z2);
457  }
458 
459 }
460 
461 
462 //
463 // Intersection point of track with a forward layer
464 //
466  const GlobalPoint& p2,
467  const ForwardDetLayer* dl) const {
468 
469  const BoundDisk& bc = dl->specificSurface();
470  return crossingPoint(p1, p2, bc);
471 
472 }
473 
475  const GlobalPoint& p2,
476  const BoundDisk& disk) const {
477 
478  float diskZ = disk.position().z();
479  int endcap = diskZ > 0 ? 1 : (diskZ < 0 ? -1 : 0);
480  diskZ = diskZ + endcap*dynamic_cast<const SimpleDiskBounds&>(disk.bounds()).thickness()/2.;
481 
482  GlobalVector dp = p1 - p2;
483 
484  float slopeZ = dp.z()/dp.y();
485  float y1 = diskZ / slopeZ;
486 
487  float slopeX = dp.z()/dp.x();
488  float x1 = diskZ / slopeX;
489 
490  float z1 = diskZ;
491 
492  if (p2.z()*z1 > 0) {
493  return GlobalPoint(x1, y1, z1);
494  } else {
495  return GlobalPoint(0, 0, 0);
496  }
497 
498 }
499 
500 
501 //
502 // GeomDets along the track in DT
503 //
504 vector<const GeomDet*> MuonShowerInformationFiller::dtPositionToDets(const GlobalPoint& gp) const {
505 
506  int minwheel = -3;
507  int maxwheel = -3;
508  if ( gp.z() < -680.0 ) { minwheel = -3; maxwheel = -3;}
509  else if ( gp.z() < -396.0 ) { minwheel = -2; maxwheel = -1;}
510  else if (gp.z() < -126.8) { minwheel = -2; maxwheel = 0; }
511  else if (gp.z() < 126.8) { minwheel = -1; maxwheel = 1; }
512  else if (gp.z() < 396.0) { minwheel = 0; maxwheel = 2; }
513  else if (gp.z() < 680.0) { minwheel = 1; maxwheel = 2; }
514  else { minwheel = 3; maxwheel = 3; }
515 
516  int station = 5;
517  if ( gp.perp() > 680.0 && gp.perp() < 755.0 ) station = 4;
518  else if ( gp.perp() > 580.0 ) station = 3;
519  else if ( gp.perp() > 480.0 ) station = 2;
520  else if ( gp.perp() > 380.0 ) station = 1;
521  else station = 0;
522 
523  vector<int> sectors;
524 
525  float phistep = M_PI/6;
526 
527  float phigp = (float)gp.barePhi();
528 
529  if ( fabs(deltaPhi(phigp, 0*phistep)) < phistep ) sectors.push_back(1);
530  if ( fabs(deltaPhi(phigp, phistep)) < phistep ) sectors.push_back(2);
531  if ( fabs(deltaPhi(phigp, 2*phistep)) < phistep ) sectors.push_back(3);
532  if ( fabs(deltaPhi(phigp, 3*phistep)) < phistep ) {
533  sectors.push_back(4);
534  if (station == 4) sectors.push_back(13);
535  }
536  if ( fabs(deltaPhi(phigp, 4*phistep)) < phistep ) sectors.push_back(5);
537  if ( fabs(deltaPhi(phigp, 5*phistep)) < phistep ) sectors.push_back(6);
538  if ( fabs(deltaPhi(phigp, 6*phistep)) < phistep ) sectors.push_back(7);
539  if ( fabs(deltaPhi(phigp, 7*phistep)) < phistep ) sectors.push_back(8);
540  if ( fabs(deltaPhi(phigp, 8*phistep)) < phistep ) sectors.push_back(9);
541  if ( fabs(deltaPhi(phigp, 9*phistep)) < phistep ) {
542  sectors.push_back(10);
543  if (station == 4) sectors.push_back(14);
544  }
545  if ( fabs(deltaPhi(phigp, 10*phistep)) < phistep ) sectors.push_back(11);
546  if ( fabs(deltaPhi(phigp, 11*phistep)) < phistep ) sectors.push_back(12);
547 
548  LogTrace(category_) << "DT position to dets" << endl;
549  LogTrace(category_) << "number of sectors to consider: " << sectors.size() << endl;
550  LogTrace(category_) << "station: " << station << " wheels: " << minwheel << " " << maxwheel << endl;
551 
552  vector<const GeomDet*> result;
553  if (station > 4 || station < 1) return result;
554  if (minwheel > 2 || maxwheel < -2) return result;
555 
556  for (vector<int>::const_iterator isector = sectors.begin(); isector != sectors.end(); ++isector ) {
557  for (int iwheel = minwheel; iwheel != maxwheel + 1; ++iwheel) {
558  DTChamberId chamberid(iwheel, station, (*isector));
559  result.push_back(theService->trackingGeometry()->idToDet(chamberid));
560  }
561  }
562 
563  LogTrace(category_) << "number of GeomDets for this track: " << result.size() << endl;
564 
565  return result;
566 
567 }
568 
569 
570 //
571 // GeomDets along the track in CSC
572 //
573 vector<const GeomDet*> MuonShowerInformationFiller::cscPositionToDets(const GlobalPoint& gp) const {
574 
575  // determine the endcap side
576  int endcap = 0;
577  if (gp.z() > 0) {endcap = 1;} else {endcap = 2;}
578 
579  // determine the csc station and range of rings
580  int station = 5;
581 
582  // check all rings in a station
583  if ( fabs(gp.z()) > 1000. && fabs(gp.z()) < 1055.0 ) {
584  station = 4;
585  }
586  else if ( fabs(gp.z()) > 910.0 && fabs(gp.z()) < 965.0) {
587  station = 3;
588  }
589  else if ( fabs(gp.z()) > 800.0 && fabs(gp.z()) < 860.0) {
590  station = 2;
591  }
592  else if ( fabs(gp.z()) > 570.0 && fabs(gp.z()) < 730.0) {
593  station = 1;
594  }
595 
596  vector<int> sectors;
597 
598  float phistep1 = M_PI/18.; //for all the rings except first rings for stations > 1
599  float phistep2 = M_PI/9.;
600  float phigp = (float)gp.barePhi();
601 
602  int ring = -1;
603 
604  // determine the ring
605  if (station == 1) {
606 
607 //FIX ME!!!
608  if (gp.perp() > 100 && gp.perp() < 270) ring = 1;
609  else if (gp.perp() > 270 && gp.perp() < 450) ring = 2;
610  else if (gp.perp() > 450 && gp.perp() < 695) ring = 3;
611  else if (gp.perp() > 100 && gp.perp() < 270) ring = 4;
612 
613  }
614  else if (station == 2) {
615 
616  if (gp.perp() > 140 && gp.perp() < 350) ring = 1;
617  else if (gp.perp() > 350 && gp.perp() < 700) ring = 2;
618 
619  }
620  else if (station == 3) {
621 
622  if (gp.perp() > 160 && gp.perp() < 350) ring = 1;
623  else if (gp.perp() > 350 && gp.perp() < 700) ring = 2;
624 
625  }
626  else if (station == 4) {
627 
628  if (gp.perp() > 175 && gp.perp() < 350) ring = 1;
629  else if (gp.perp() > 350 && gp.perp() < 700) ring = 2;
630 
631  }
632 
633  if (station > 1 && ring == 1) {
634 
635  // we have 18 sectors in that case
636  for (int i = 0; i < 18; i++) {
637  if ( fabs(deltaPhi(phigp, i*phistep2)) < phistep2 ) sectors.push_back(i+1);
638  }
639 
640  } else {
641 
642  // we have 36 sectors in that case
643  for (int i = 0; i < 36; i++) {
644  if ( fabs(deltaPhi(phigp, i*phistep1)) < phistep1 ) sectors.push_back(i+1);
645  }
646 }
647 
648  LogTrace(category_) << "CSC position to dets" << endl;
649  LogTrace(category_) << "ring: " << ring << endl;
650  LogTrace(category_) << "endcap: " << endcap << endl;
651  LogTrace(category_) << "station: " << station << endl;
652  LogTrace(category_) << "CSC number of sectors to consider: " << sectors.size() << endl;
653 
654 
655  // check exceptional cases
656  vector<const GeomDet*> result;
657  if (station > 4 || station < 1) return result;
658  if (endcap == 0) return result;
659  if (ring == -1) return result;
660 
661  int minlayer = 1;
662  int maxlayer = 6;
663 
664  for (vector<int>::const_iterator isector = sectors.begin(); isector != sectors.end(); ++isector) {
665  for (int ilayer = minlayer; ilayer != maxlayer + 1; ++ ilayer) {
666  CSCDetId cscid(endcap, station, ring, (*isector), ilayer);
667  result.push_back(theService->trackingGeometry()->idToDet(cscid));
668  }
669  }
670 
671  return result;
672 
673 }
674 
675 //
676 //Set class members
677 //
679 
680  reco::TrackRef track;
681  if ( muon.isGlobalMuon() ) track = muon.globalTrack();
682  else if ( muon.isStandAloneMuon() ) track = muon.outerTrack();
683  else return;
684 
685  // split 1D rechits by station
686  vector<MuonRecHitContainer> muonRecHits(4);
687 
688  // split rechits from segs by station
689  vector<TransientTrackingRecHit::ConstRecHitContainer> muonCorrelatedHits(4);
690 
691  // get vector of GeomDets compatible with a track
692  vector<const GeomDet*> compatibleLayers = getCompatibleDets(*track);
693 
694  // for special cases: CSC station 1
695  MuonRecHitContainer tmpCSC1;
696  bool dtOverlapToCheck = false;
697  bool cscOverlapToCheck = false;
698 
699  for (vector<const GeomDet*>::const_iterator igd = compatibleLayers.begin(); igd != compatibleLayers.end(); igd++ ) {
700 
701  // get det id
702  DetId geoId = (*igd)->geographicalId();
703 
704  // skip tracker hits
705  if (geoId.det()!= DetId::Muon) continue;
706 
707  // DT
708  if ( geoId.subdetId() == MuonSubdetId::DT ) {
709 
710  // get station
711  DTChamberId detid(geoId.rawId());
712  int station = detid.station();
713  int wheel = detid.wheel();
714 
715  // get rechits from segments per station
717  TransientTrackingRecHit::ConstRecHitContainer::const_iterator hits_begin = muonCorrelatedHitsTmp.begin();
718  TransientTrackingRecHit::ConstRecHitContainer::const_iterator hits_end = muonCorrelatedHitsTmp.end();
719 
720  for (; hits_begin!= hits_end;++hits_begin) {
721  muonCorrelatedHits.at(station-1).push_back(*hits_begin);
722  }
723 
724  //check overlap certain wheels and stations
725  if (abs(wheel) == 2 && station != 4 && station != 1) dtOverlapToCheck = true;
726 
727  // loop over all superlayers of a DT chamber
728  for (int isuperlayer = DTChamberId::minSuperLayerId; isuperlayer != DTChamberId::maxSuperLayerId + 1; ++isuperlayer) {
729  // loop over all layers inside the superlayer
730  for (int ilayer = DTChamberId::minLayerId; ilayer != DTChamberId::maxLayerId+1; ++ilayer) {
731  DTLayerId lid(detid, isuperlayer, ilayer);
732  DTRecHitCollection::range dRecHits = theDTRecHits->get(lid);
733  for (DTRecHitCollection::const_iterator rechit = dRecHits.first; rechit != dRecHits.second;++rechit) {
734  vector<const TrackingRecHit*> subrechits = (*rechit).recHits();
735  for (vector<const TrackingRecHit*>::iterator irechit = subrechits.begin(); irechit != subrechits.end(); ++irechit) {
736  muonRecHits.at(station-1).push_back(MuonTransientTrackingRecHit::specificBuild((&**igd),&**irechit));
737  }
738  }
739  }
740  }
741  }
742  else if (geoId.subdetId() == MuonSubdetId::CSC) {
743 
744  // get station
745  CSCDetId did(geoId.rawId());
746  int station = did.station();
747  int ring = did.ring();
748 
749  //get rechits from segments by station
751  TransientTrackingRecHit::ConstRecHitContainer::const_iterator hits_begin = muonCorrelatedHitsTmp.begin();
752  TransientTrackingRecHit::ConstRecHitContainer::const_iterator hits_end = muonCorrelatedHitsTmp.end();
753 
754  for (; hits_begin!= hits_end;++hits_begin) {
755  muonCorrelatedHits.at(station-1).push_back(*hits_begin);
756  }
757 
758  if ((station == 1 && ring == 3) && dtOverlapToCheck) cscOverlapToCheck = true;
759 
760  // split 1D rechits by station
761  CSCRecHit2DCollection::range dRecHits = theCSCRecHits->get(did);
762  for (CSCRecHit2DCollection::const_iterator rechit = dRecHits.first; rechit != dRecHits.second; ++rechit) {
763 
764  if (!cscOverlapToCheck) {
765  muonRecHits.at(station-1).push_back(MuonTransientTrackingRecHit::specificBuild((&**igd),&*rechit));
766  } else {
767  tmpCSC1.push_back(MuonTransientTrackingRecHit::specificBuild((&**igd),&*rechit));
768 
769  //sort by perp, then insert to appropriate container
771  if (temp.empty()) continue;
772 
773  float center;
774  if (temp.size() > 1) {
775  center = (temp.front()->globalPosition().perp() + temp.back()->globalPosition().perp())/2.;
776  } else {
777  center = temp.front()->globalPosition().perp();
778  }
779  temp.clear();
780 
781  if (center > 550.) {
782  muonRecHits.at(2).insert(muonRecHits.at(2).end(),tmpCSC1.begin(),tmpCSC1.end());
783  } else {
784  muonRecHits.at(1).insert(muonRecHits.at(1).end(),tmpCSC1.begin(),tmpCSC1.end());
785  }
786  tmpCSC1.clear();
787  }
788  }
789  } else if (geoId.subdetId() == MuonSubdetId::RPC) {
790  LogTrace(category_) << "Wrong subdet id" << endl;
791  }
792  }//loop over GeomDets compatible with a track
793 
794  // calculate number of all and correlated hits
795  for (int stat = 0; stat < 4; stat++) {
796  theCorrelatedStationHits[stat] = muonCorrelatedHits.at(stat).size();
797  theAllStationHits[stat] = muonRecHits[stat].size();
798  }
799  LogTrace(category_) << "Hits used by the segments, by station "
800  << theCorrelatedStationHits.at(0) << " "
801  << theCorrelatedStationHits.at(1) << " "
802  << theCorrelatedStationHits.at(2) << " "
803  << theCorrelatedStationHits.at(3) << endl;
804 
805  LogTrace(category_) << "All DT 1D/CSC 2D hits, by station "
806  << theAllStationHits.at(0) << " "
807  << theAllStationHits.at(1) << " "
808  << theAllStationHits.at(2) << " "
809  << theAllStationHits.at(3) << endl;
810 
811  //station shower sizes
813  TransientTrackingRecHit::ConstRecHitContainer muonRecHitsThetaTemp, muonRecHitsThetaBest;
814  // send station hits to the clustering algorithm
815  for ( int stat = 0; stat != 4; stat++ ) {
816  const size_t nhit = muonRecHits[stat].size();
817  if (nhit < 2) continue; // Require at least 2 hits
818  muonRecHitsPhiBest.clear();
819  muonRecHitsPhiBest.reserve(nhit);
820 
821  // Cluster seeds by global position phi. Best cluster is chosen to give greatest dphi
822  // Sort by phi (complexity = NLogN with enough memory, or = NLog^2N for insufficient mem)
823  stable_sort(muonRecHits[stat].begin(), muonRecHits[stat].end(), LessPhi());
824 
825  // Search for gaps (complexity = N)
826  std::vector<size_t> clUppers;
827  for ( size_t ihit = 0; ihit < nhit; ++ihit ) {
828  const size_t jhit = (ihit+1)%nhit;
829  const double phi1 = muonRecHits[stat].at(ihit)->globalPosition().barePhi();
830  const double phi2 = muonRecHits[stat].at(jhit)->globalPosition().barePhi();
831 
832  const double dphi = std::abs(deltaPhi(phi1, phi2));
833  if ( dphi >= 0.05 ) clUppers.push_back(ihit);
834  }
835 
836  //station shower sizes
837  double dphimax = 0;
838  if ( clUppers.empty() ) {
839  // No gaps - there is only one cluster. Take all of them
840  const double refPhi = muonRecHits[stat].at(0)->globalPosition().barePhi();
841  double dphilo = 0, dphihi = 0;
842  for ( auto& hit : muonRecHits[stat] ) {
843  muonRecHitsPhiBest.push_back(hit);
844  const double phi = hit->globalPosition().barePhi();
845  dphilo = std::min(dphilo, deltaPhi(refPhi, phi));
846  dphihi = std::max(dphihi, deltaPhi(refPhi, phi));
847  }
848  dphimax = std::abs(dphihi+dphilo);
849  } else {
850  // Loop over gaps to find the one with maximum dphi(begin, end)
851  // By construction, number of gap must be greater than 1.
852  size_t bestUpper = 0, bestLower = 0;
853  for ( auto icl = clUppers.begin(); icl != clUppers.end(); ++icl ) {
854  // upper bound of this cluster
855  const size_t upper = *icl;
856  // lower bound is +1 of preceeding upper bound
857  const auto prevCl = (icl == clUppers.begin()) ? clUppers.end() : icl;
858  const size_t lower = (*(prevCl-1)+1)%nhit;
859 
860  // At least two hit for a cluster
861  if ( upper == lower ) continue;
862 
863  const double phi1 = muonRecHits[stat].at(upper)->globalPosition().barePhi();
864  const double phi2 = muonRecHits[stat].at(lower)->globalPosition().barePhi();
865 
866  const double dphi = std::abs(deltaPhi(phi1, phi2));
867  if ( dphimax < dphi ) {
868  dphimax = dphi;
869  bestUpper = upper;
870  bestLower = lower;
871  }
872  }
873 
874  if ( bestUpper > bestLower ) {
875  muonRecHitsPhiBest.reserve(bestUpper-bestLower+1);
876  std::copy(muonRecHits[stat].begin()+bestLower,
877  muonRecHits[stat].begin()+bestUpper+1,
878  std::back_inserter(muonRecHitsPhiBest));
879  } else if ( bestUpper < bestLower ) {
880  muonRecHitsPhiBest.reserve(bestUpper+(nhit-bestLower)+1);
881  std::copy(muonRecHits[stat].begin(),
882  muonRecHits[stat].begin()+bestUpper+1,
883  std::back_inserter(muonRecHitsPhiBest));
884  std::copy(muonRecHits[stat].begin()+bestLower,
885  muonRecHits[stat].end(),
886  std::back_inserter(muonRecHitsPhiBest));
887  }
888  }
889 
890  //fill showerTs
891  if (!muonRecHitsPhiBest.empty()) {
892  muonRecHits[stat] = muonRecHitsPhiBest;
893  stable_sort(muonRecHits[stat].begin(), muonRecHits[stat].end(), LessAbsMag());
894  muonRecHits[stat].front();
895  GlobalPoint refpoint = muonRecHits[stat].front()->globalPosition();
896  theStationShowerTSize.at(stat) = refpoint.mag() * dphimax;
897  }
898 
899  //for theta
900  if (!muonCorrelatedHits.at(stat).empty()) {
901 
902  float dthetamax = 0;
903  for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator iseed = muonCorrelatedHits.at(stat).begin(); iseed != muonCorrelatedHits.at(stat).end(); ++iseed) {
904  if (!(*iseed)->isValid()) continue;
905  GlobalPoint refpoint = (*iseed)->globalPosition(); //starting from the one with smallest value of phi
906  muonRecHitsThetaTemp.clear();
907  muonRecHitsThetaTemp = findThetaCluster(muonCorrelatedHits.at(stat), refpoint);
908  }//loop over seeds
909  if (muonRecHitsThetaTemp.size() > 1) {
910  float dtheta = fabs((float)muonRecHitsThetaTemp.back()->globalPosition().theta() - (float)muonRecHitsThetaTemp.front()->globalPosition().theta());
911  if (dtheta > dthetamax) {
912  dthetamax = dtheta;
913  muonRecHitsThetaBest = muonRecHitsThetaTemp;
914  }
915  } //at least two hits
916  }//not empty container2
917 
918  //fill deltaRs
919  if (muonRecHitsThetaBest.size() > 1 && muonRecHitsPhiBest.size() > 1)
920  theStationShowerDeltaR.at(stat) = sqrt(pow(deltaPhi(muonRecHitsPhiBest.front()->globalPosition().barePhi(),muonRecHitsPhiBest.back()->globalPosition().barePhi()),2)+pow(muonRecHitsThetaBest.front()->globalPosition().theta()-muonRecHitsThetaBest.back()->globalPosition().theta(),2));
921 
922  }//loop over station
923 
924  LogTrace(category_) << "deltaR around a track containing all the station hits, by station "
925  << theStationShowerDeltaR.at(0) << " "
926  << theStationShowerDeltaR.at(1) << " "
927  << theStationShowerDeltaR.at(2) << " "
928  << theStationShowerDeltaR.at(3) << endl;
929 
930 
931  LogTrace(category_) << "Transverse cluster size, by station "
932  << theStationShowerTSize.at(0) << " "
933  << theStationShowerTSize.at(1) << " "
934  << theStationShowerTSize.at(2) << " "
935  << theStationShowerTSize.at(3) << endl;
936 
937  return;
938 
939 }
940 
MuonTransientTrackingRecHit::MuonRecHitContainer MuonRecHitContainer
double p() const
momentum vector magnitude
Definition: TrackBase.h:610
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
virtual void setEvent(const edm::Event &)
pass the Event to the algorithm at each event
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
std::pair< const_iterator, const_iterator > range
iterator range
Definition: RangeMap.h:50
T perp() const
Definition: PV3DBase.h:72
edm::ESHandle< MagneticField > theField
reco::MuonShower fillShowerInformation(const reco::Muon &muon, const edm::Event &, const edm::EventSetup &)
fill muon shower variables
TrajectoryStateOnSurface outerStateOnSurface(const reco::Track &tk, const TrackingGeometry &geom, const MagneticField *field, bool withErr=true)
void setServices(const edm::EventSetup &)
set the services needed
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
static const double slope[3]
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
Geom::Theta< T > theta() const
T y() const
Definition: PV3DBase.h:63
bool isGlobalMuon() const
Definition: Muon.h:222
GlobalPoint globalPosition() const
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:640
edm::EDGetTokenT< CSCSegmentCollection > theCSCSegmentsToken
edm::ESHandle< GeometricSearchTracker > theTracker
edm::ESHandle< CSCGeometry > theCSCGeometry
edm::ESHandle< DTGeometry > theDTGeometry
std::vector< int > nStationHits
number of all the muon RecHits per chamber crossed by a track (1D hits)
Definition: MuonShower.h:8
bool isStandAloneMuon() const
Definition: Muon.h:224
edm::EDGetTokenT< CSCRecHit2DCollection > theCSCRecHitToken
tuple result
Definition: mps_fire.py:95
virtual ~MuonShowerInformationFiller()
destructor
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
static TransientTrackingRecHit::ConstRecHitContainer breakInSubRecHits(TransientTrackingRecHit::ConstRecHitPointer, int granularity)
takes a muon rechit and returns its sub-rechits given a certain granularity
T barePhi() const
Definition: PV3DBase.h:68
std::vector< const GeomDet * > dtPositionToDets(const GlobalPoint &) const
std::vector< int > nStationCorrelatedHits
number of the muon RecHits used by segments per chamber crossed by a track
Definition: MuonShower.h:10
int iEvent
Definition: GenABIO.cc:230
static const int CSC
Definition: MuonSubdetId.h:13
T mag() const
Definition: PV3DBase.h:67
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:646
void fillHitsByStation(const reco::Muon &)
Scalar radius() const
Radius of the cylinder.
Definition: Cylinder.h:67
int n0
Definition: AMPTWrapper.h:34
static const int maxLayerId
highest layer id
Definition: DTChamberId.h:85
std::shared_ptr< TrackingRecHit const > ConstRecHitPointer
T sqrt(T t)
Definition: SSEVec.h:18
T z() const
Definition: PV3DBase.h:64
edm::Handle< DTRecHitCollection > theDTRecHits
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static const int minLayerId
lowest layer id. 0 indicates a full SL
Definition: DTChamberId.h:83
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:77
GlobalPoint crossingPoint(const GlobalPoint &, const GlobalPoint &, const BarrelDetLayer *) const
#define end
Definition: vmac.h:37
T min(T a, T b)
Definition: MathUtil.h:58
static const int maxSuperLayerId
highest superlayer id
Definition: DTChamberId.h:81
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
double p2[4]
Definition: TauolaWrapper.h:90
#define LogTrace(id)
edm::Handle< CSCSegmentCollection > theCSCSegments
virtual TrackRef outerTrack() const
reference to Track reconstructed in the muon detector only
Definition: Muon.h:51
TransientTrackingRecHit::ConstRecHitContainer findThetaCluster(TransientTrackingRecHit::ConstRecHitContainer &, const GlobalPoint &) const
edm::ESHandle< TransientTrackingRecHitBuilder > theTrackerRecHitBuilder
#define M_PI
std::vector< ConstRecHitPointer > ConstRecHitContainer
Definition: DetId.h:18
TransientTrackingRecHit::ConstRecHitContainer hitsFromSegments(const GeomDet *, edm::Handle< DTRecSegment4DCollection >, edm::Handle< CSCSegmentCollection >) const
edm::EDGetTokenT< DTRecSegment4DCollection > theDT4DRecSegmentToken
int iseed
Definition: AMPTWrapper.h:124
std::vector< const GeomDet * > getCompatibleDets(const reco::Track &) const
auto dp
Definition: deltaR.h:22
edm::Handle< CSCRecHit2DCollection > theCSCRecHits
const T & get() const
Definition: EventSetup.h:56
virtual const BoundCylinder & specificSurface() const final
Extension of the interface.
static const int minSuperLayerId
loweset super layer id. 0 indicates a full chamber
Definition: DTChamberId.h:79
edm::ESHandle< TransientTrackingRecHitBuilder > theMuonRecHitBuilder
std::vector< const GeomDet * > cscPositionToDets(const GlobalPoint &) const
T perp() const
Magnitude of transverse component.
#define begin
Definition: vmac.h:30
double p1[4]
Definition: TauolaWrapper.h:89
static const int RPC
Definition: MuonSubdetId.h:14
double a
Definition: hdecay.h:121
std::vector< float > stationShowerSizeT
the transverse size of the hit cluster
Definition: MuonShower.h:12
virtual const BoundDisk & specificSurface() const final
static const int DT
Definition: MuonSubdetId.h:12
edm::EDGetTokenT< DTRecHitCollection > theDTRecHitToken
edm::ESHandle< GlobalTrackingGeometry > theTrackingGeometry
Detector det() const
get the detector field from this detid
Definition: DetId.h:35
T x() const
Definition: PV3DBase.h:62
MuonRecHitContainer findPerpCluster(MuonRecHitContainer &muonRecHits) const
static MuonRecHitPointer specificBuild(const GeomDet *geom, const TrackingRecHit *rh)
std::vector< MuonRecHitPointer > MuonRecHitContainer
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
edm::Handle< DTRecSegment4DCollection > theDT4DRecSegments
TrajectoryStateOnSurface innerStateOnSurface(const reco::Track &tk, const TrackingGeometry &geom, const MagneticField *field, bool withErr=true)
virtual TrackRef globalTrack() const
reference to Track reconstructed in both tracked and muon detector
Definition: Muon.h:54
std::vector< float > stationShowerDeltaR
the radius of the cone containing the all the hits around the track
Definition: MuonShower.h:14