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