CMS 3D CMS Logo

GlobalMuonRefitter.cc
Go to the documentation of this file.
1 
18 
19 //---------------
20 // C++ Headers --
21 //---------------
22 
23 #include <iostream>
24 #include <iomanip>
25 #include <algorithm>
26 
27 //-------------------------------
28 // Collaborating Class Headers --
29 //-------------------------------
30 
32 
42 
57 
67 
68 using namespace std;
69 using namespace edm;
70 
71 //----------------
72 // Constructors --
73 //----------------
74 
78  : theCosmicFlag(par.getParameter<bool>("PropDirForCosmics")),
79  theDTRecHitLabel(par.getParameter<InputTag>("DTRecSegmentLabel")),
80  theCSCRecHitLabel(par.getParameter<InputTag>("CSCRecSegmentLabel")),
81  theGEMRecHitLabel(par.getParameter<InputTag>("GEMRecHitLabel")),
82  theME0RecHitLabel(par.getParameter<InputTag>("ME0RecHitLabel")),
83  theService(service),
84  theDynamicTruncationConfig(iC) {
85  theCategory = par.getUntrackedParameter<string>("Category", "Muon|RecoMuon|GlobalMuon|GlobalMuonRefitter");
86 
87  theHitThreshold = par.getParameter<int>("HitThreshold");
88  theDTChi2Cut = par.getParameter<double>("Chi2CutDT");
89  theCSCChi2Cut = par.getParameter<double>("Chi2CutCSC");
90  theRPCChi2Cut = par.getParameter<double>("Chi2CutRPC");
91  theGEMChi2Cut = par.getParameter<double>("Chi2CutGEM");
92  theME0Chi2Cut = par.getParameter<double>("Chi2CutME0");
93 
94  // Refit direction
95  string refitDirectionName = par.getParameter<string>("RefitDirection");
96 
97  if (refitDirectionName == "insideOut")
99  else if (refitDirectionName == "outsideIn")
101  else
102  throw cms::Exception("TrackTransformer constructor")
103  << "Wrong refit direction chosen in TrackTransformer ParameterSet"
104  << "\n"
105  << "Possible choices are:"
106  << "\n"
107  << "RefitDirection = insideOut or RefitDirection = outsideIn";
108 
109  theFitterToken = iC.esConsumes(edm::ESInputTag("", par.getParameter<string>("Fitter")));
110  thePropagatorName = par.getParameter<string>("Propagator");
111 
112  theSkipStation = par.getParameter<int>("SkipStation");
113  theTrackerSkipSystem = par.getParameter<int>("TrackerSkipSystem");
114  theTrackerSkipSection = par.getParameter<int>("TrackerSkipSection"); //layer, wheel, or disk depending on the system
115 
116  theTrackerRecHitBuilderToken = iC.esConsumes(edm::ESInputTag("", par.getParameter<string>("TrackerRecHitBuilder")));
117  theMuonRecHitBuilderToken = iC.esConsumes(edm::ESInputTag("", par.getParameter<string>("MuonRecHitBuilder")));
118 
119  theRPCInTheFit = par.getParameter<bool>("RefitRPCHits");
120 
121  theDYTthrs = par.getParameter<std::vector<int> >("DYTthrs");
122  theDYTselector = par.getParameter<int>("DYTselector");
123  theDYTupdator = par.getParameter<bool>("DYTupdator");
124  theDYTuseAPE = par.getParameter<bool>("DYTuseAPE");
125  theDYTParThrsMode = par.getParameter<bool>("DYTuseThrsParametrization");
126  if (theDYTParThrsMode)
127  theDYTthrsParameters = par.getParameter<edm::ParameterSet>("DYTthrsParameters");
128  dytInfo = new reco::DYTInfo();
129 
130  if (par.existsAs<double>("RescaleErrorFactor")) {
131  theRescaleErrorFactor = par.getParameter<double>("RescaleErrorFactor");
132  edm::LogWarning("GlobalMuonRefitter") << "using error rescale factor " << theRescaleErrorFactor;
133  } else
134  theRescaleErrorFactor = 1000.;
135 
136  theCacheId_TRH = 0;
143 }
144 
145 //--------------
146 // Destructor --
147 //--------------
148 
150 
151 //
152 // set Event
153 //
155  event.getByToken(theDTRecHitToken, theDTRecHits);
156  event.getByToken(theCSCRecHitToken, theCSCRecHits);
157  event.getByToken(theGEMRecHitToken, theGEMRecHits);
158  event.getByToken(theME0RecHitToken, theME0RecHits);
159  event.getByToken(CSCSegmentsToken, CSCSegments);
160  event.getByToken(all4DSegmentsToken, all4DSegments);
161 }
162 
164  theFitter = setup.getData(theFitterToken).clone();
165 
166  // Transient Rechit Builders
167  unsigned long long newCacheId_TRH = setup.get<TransientRecHitRecord>().cacheIdentifier();
168  if (newCacheId_TRH != theCacheId_TRH) {
169  LogDebug(theCategory) << "TransientRecHitRecord changed!";
173  }
174  theFitter->setHitCloner(&hitCloner);
175  theEventSetup = &setup;
176 }
177 
178 //
179 // build a combined tracker-muon trajectory
180 //
182  const int theMuonHitsOption,
183  const TrackerTopology* tTopo) const {
184  LogTrace(theCategory) << " *** GlobalMuonRefitter *** option " << theMuonHitsOption << endl;
185 
186  ConstRecHitContainer allRecHitsTemp; // all muon rechits temp
187 
188  reco::TransientTrack track(globalTrack, &*(theService->magneticField()), theService->trackingGeometry());
189 
190  auto tkbuilder = static_cast<TkTransientTrackingRecHitBuilder const*>(theTrackerRecHitBuilder);
191 
192  for (trackingRecHit_iterator hit = track.recHitsBegin(); hit != track.recHitsEnd(); ++hit)
193  if ((*hit)->isValid()) {
194  if ((*hit)->geographicalId().det() == DetId::Tracker)
195  allRecHitsTemp.push_back((**hit).cloneForFit(*tkbuilder->geometry()->idToDet((**hit).geographicalId())));
196  else if ((*hit)->geographicalId().det() == DetId::Muon) {
197  if ((*hit)->geographicalId().subdetId() == 3 && !theRPCInTheFit) {
198  LogTrace(theCategory) << "RPC Rec Hit discarged";
199  continue;
200  }
201  allRecHitsTemp.push_back(theMuonRecHitBuilder->build(&**hit));
202  }
203  }
204  vector<Trajectory> refitted = refit(globalTrack, track, allRecHitsTemp, theMuonHitsOption, tTopo);
205  return refitted;
206 }
207 
208 //
209 // build a combined tracker-muon trajectory
210 //
213  const TransientTrackingRecHit::ConstRecHitContainer& allRecHitsTemp,
214  const int theMuonHitsOption,
215  const TrackerTopology* tTopo) const {
216  // MuonHitsOption: 0 - tracker only
217  // 1 - include all muon hits
218  // 2 - include only first muon hit(s)
219  // 3 - include only selected muon hits
220  // 4 - redo pattern recognition with dynamic truncation
221 
222  vector<int> stationHits(4, 0);
223  map<DetId, int> hitMap;
224 
225  ConstRecHitContainer allRecHits; // all muon rechits
226  ConstRecHitContainer fmsRecHits; // only first muon rechits
227  ConstRecHitContainer selectedRecHits; // selected muon rechits
228  ConstRecHitContainer DYTRecHits; // rec hits from dynamic truncation algorithm
229 
230  LogTrace(theCategory) << " *** GlobalMuonRefitter *** option " << theMuonHitsOption << endl;
231  LogTrace(theCategory) << " Track momentum before refit: " << globalTrack.pt() << endl;
232  LogTrace(theCategory) << " Hits size before : " << allRecHitsTemp.size() << endl;
233 
234  allRecHits = getRidOfSelectStationHits(allRecHitsTemp, tTopo);
235  // printHits(allRecHits);
236  LogTrace(theCategory) << " Hits size: " << allRecHits.size() << endl;
237 
238  vector<Trajectory> outputTraj;
239 
240  if ((theMuonHitsOption == 1) || (theMuonHitsOption == 3) || (theMuonHitsOption == 4)) {
241  // refit the full track with all muon hits
242  vector<Trajectory> globalTraj = transform(globalTrack, track, allRecHits);
243 
244  if (globalTraj.empty()) {
245  LogTrace(theCategory) << "No trajectory from the TrackTransformer!" << endl;
246  return vector<Trajectory>();
247  }
248 
249  LogTrace(theCategory) << " Initial trajectory state: "
250  << globalTraj.front().lastMeasurement().updatedState().freeState()->parameters() << endl;
251 
252  if (theMuonHitsOption == 1)
253  outputTraj.push_back(globalTraj.front());
254 
255  if (theMuonHitsOption == 3) {
256  checkMuonHits(globalTrack, allRecHits, hitMap);
257  selectedRecHits = selectMuonHits(globalTraj.front(), hitMap);
258  LogTrace(theCategory) << " Selected hits size: " << selectedRecHits.size() << endl;
259  outputTraj = transform(globalTrack, track, selectedRecHits);
260  }
261 
262  if (theMuonHitsOption == 4) {
263  //
264  // DYT 2.0
265  //
267  dytRefit.setProd(all4DSegments, CSCSegments);
268  dytRefit.setSelector(theDYTselector);
269  dytRefit.setThr(theDYTthrs);
270  dytRefit.setUpdateState(theDYTupdator);
271  dytRefit.setUseAPE(theDYTuseAPE);
272  if (theDYTParThrsMode) {
275  dytRefit.setRecoP(globalTrack.p());
276  dytRefit.setRecoEta(globalTrack.eta());
277  }
278  DYTRecHits = dytRefit.filter(globalTraj.front());
279  dytInfo->CopyFrom(dytRefit.getDYTInfo());
280  if ((DYTRecHits.size() > 1) &&
281  (DYTRecHits.front()->globalPosition().mag() > DYTRecHits.back()->globalPosition().mag()))
282  stable_sort(DYTRecHits.begin(), DYTRecHits.end(), RecHitLessByDet(alongMomentum));
283  outputTraj = transform(globalTrack, track, DYTRecHits);
284  }
285 
286  } else if (theMuonHitsOption == 2) {
287  getFirstHits(globalTrack, allRecHits, fmsRecHits);
288  outputTraj = transform(globalTrack, track, fmsRecHits);
289  }
290 
291  if (!outputTraj.empty()) {
292  LogTrace(theCategory) << "Refitted pt: "
293  << outputTraj.front().firstMeasurement().updatedState().globalParameters().momentum().perp()
294  << endl;
295  return outputTraj;
296  } else {
297  LogTrace(theCategory) << "No refitted Tracks... " << endl;
298  return vector<Trajectory>();
299  }
300 }
301 
302 //
303 //
304 //
307  map<DetId, int>& hitMap) const {
308  LogTrace(theCategory) << " GlobalMuonRefitter::checkMuonHits " << endl;
309 
310  float coneSize = 20.0;
311 
312  // loop through all muon hits and calculate the maximum # of hits in each chamber
313  for (ConstRecHitContainer::const_iterator imrh = all.begin(); imrh != all.end(); imrh++) {
314  if ((*imrh != nullptr) && !(*imrh)->isValid())
315  continue;
316 
317  int detRecHits = 0;
318  MuonRecHitContainer dRecHits;
319 
320  DetId id = (*imrh)->geographicalId();
321  DetId chamberId;
322 
323  // Skip tracker hits
324  if (id.det() != DetId::Muon)
325  continue;
326 
327  if (id.subdetId() == MuonSubdetId::DT) {
328  DTChamberId did(id.rawId());
329  chamberId = did;
330 
331  if ((*imrh)->dimension() > 1) {
332  std::vector<const TrackingRecHit*> hits2d = (*imrh)->recHits();
333  for (std::vector<const TrackingRecHit*>::const_iterator hit2d = hits2d.begin(); hit2d != hits2d.end();
334  hit2d++) {
335  if ((*hit2d)->dimension() > 1) {
336  std::vector<const TrackingRecHit*> hits1d = (*hit2d)->recHits();
337  for (std::vector<const TrackingRecHit*>::const_iterator hit1d = hits1d.begin(); hit1d != hits1d.end();
338  hit1d++) {
339  DetId id1 = (*hit1d)->geographicalId();
340  DTLayerId lid(id1.rawId());
341  // Get the 1d DT RechHits from this layer
342  DTRecHitCollection::range dRecHits = theDTRecHits->get(lid);
343  int layerHits = 0;
344  for (DTRecHitCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++) {
345  double rhitDistance = fabs(ir->localPosition().x() - (**hit1d).localPosition().x());
346  if (rhitDistance < coneSize)
347  layerHits++;
348  LogTrace(theCategory) << " " << (ir)->localPosition() << " " << (**hit1d).localPosition()
349  << " Distance: " << rhitDistance << " recHits: " << layerHits
350  << " SL: " << lid.superLayer() << endl;
351  }
352  if (layerHits > detRecHits)
353  detRecHits = layerHits;
354  }
355  } else {
356  DTLayerId lid(id.rawId());
357  // Get the 1d DT RechHits from this layer
358  DTRecHitCollection::range dRecHits = theDTRecHits->get(lid);
359  for (DTRecHitCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++) {
360  double rhitDistance = fabs(ir->localPosition().x() - (**imrh).localPosition().x());
361  if (rhitDistance < coneSize)
362  detRecHits++;
363  LogTrace(theCategory) << " " << (ir)->localPosition() << " " << (**imrh).localPosition()
364  << " Distance: " << rhitDistance << " recHits: " << detRecHits << endl;
365  }
366  }
367  }
368 
369  } else {
370  DTLayerId lid(id.rawId());
371 
372  // Get the 1d DT RechHits from this layer
373  DTRecHitCollection::range dRecHits = theDTRecHits->get(lid);
374 
375  for (DTRecHitCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++) {
376  double rhitDistance = fabs(ir->localPosition().x() - (**imrh).localPosition().x());
377  if (rhitDistance < coneSize)
378  detRecHits++;
379  LogTrace(theCategory) << " " << (ir)->localPosition() << " " << (**imrh).localPosition()
380  << " Distance: " << rhitDistance << " recHits: " << detRecHits << endl;
381  }
382  }
383  } // end of if DT
384  else if (id.subdetId() == MuonSubdetId::CSC) {
385  CSCDetId did(id.rawId());
386  chamberId = did.chamberId();
387 
388  if ((*imrh)->recHits().size() > 1) {
389  std::vector<const TrackingRecHit*> hits2d = (*imrh)->recHits();
390  for (std::vector<const TrackingRecHit*>::const_iterator hit2d = hits2d.begin(); hit2d != hits2d.end();
391  hit2d++) {
392  DetId id1 = (*hit2d)->geographicalId();
393  CSCDetId lid(id1.rawId());
394 
395  // Get the CSC Rechits from this layer
396  CSCRecHit2DCollection::range dRecHits = theCSCRecHits->get(lid);
397  int layerHits = 0;
398 
399  for (CSCRecHit2DCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++) {
400  double rhitDistance = (ir->localPosition() - (**hit2d).localPosition()).mag();
401  if (rhitDistance < coneSize)
402  layerHits++;
403  LogTrace(theCategory) << ir->localPosition() << " " << (**hit2d).localPosition()
404  << " Distance: " << rhitDistance << " recHits: " << layerHits << endl;
405  }
406  if (layerHits > detRecHits)
407  detRecHits = layerHits;
408  }
409  } else {
410  // Get the CSC Rechits from this layer
411  CSCRecHit2DCollection::range dRecHits = theCSCRecHits->get(did);
412 
413  for (CSCRecHit2DCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++) {
414  double rhitDistance = (ir->localPosition() - (**imrh).localPosition()).mag();
415  if (rhitDistance < coneSize)
416  detRecHits++;
417  LogTrace(theCategory) << ir->localPosition() << " " << (**imrh).localPosition()
418  << " Distance: " << rhitDistance << " recHits: " << detRecHits << endl;
419  }
420  }
421  } //end of CSC if
422  else if (id.subdetId() == MuonSubdetId::GEM) {
423  GEMDetId did(id.rawId());
424  chamberId = did.chamberId();
425 
426  if ((*imrh)->recHits().size() > 1) {
427  std::vector<const TrackingRecHit*> hits2d = (*imrh)->recHits();
428  for (std::vector<const TrackingRecHit*>::const_iterator hit2d = hits2d.begin(); hit2d != hits2d.end();
429  hit2d++) {
430  DetId id1 = (*hit2d)->geographicalId();
431  GEMDetId lid(id1.rawId());
432 
433  // Get the GEM Rechits from this layer
434  GEMRecHitCollection::range dRecHits = theGEMRecHits->get(lid);
435  int layerHits = 0;
436 
437  for (GEMRecHitCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++) {
438  double rhitDistance = (ir->localPosition() - (**hit2d).localPosition()).mag();
439  if (rhitDistance < coneSize)
440  layerHits++;
441  LogTrace(theCategory) << ir->localPosition() << " " << (**hit2d).localPosition()
442  << " Distance: " << rhitDistance << " recHits: " << layerHits << endl;
443  }
444  if (layerHits > detRecHits)
445  detRecHits = layerHits;
446  }
447  } else {
448  // Get the GEM Rechits from this layer
449  GEMRecHitCollection::range dRecHits = theGEMRecHits->get(did);
450 
451  for (GEMRecHitCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++) {
452  double rhitDistance = (ir->localPosition() - (**imrh).localPosition()).mag();
453  if (rhitDistance < coneSize)
454  detRecHits++;
455  LogTrace(theCategory) << ir->localPosition() << " " << (**imrh).localPosition()
456  << " Distance: " << rhitDistance << " recHits: " << detRecHits << endl;
457  }
458  }
459  } //end of GEM if
460  else if (id.subdetId() == MuonSubdetId::ME0) {
461  ME0DetId did(id.rawId());
462  chamberId = did.chamberId();
463 
464  if ((*imrh)->recHits().size() > 1) {
465  std::vector<const TrackingRecHit*> hits2d = (*imrh)->recHits();
466  for (std::vector<const TrackingRecHit*>::const_iterator hit2d = hits2d.begin(); hit2d != hits2d.end();
467  hit2d++) {
468  DetId id1 = (*hit2d)->geographicalId();
469  ME0DetId lid(id1.rawId());
470 
471  // Get the ME0 Rechits from this layer
472  ME0SegmentCollection::range dRecHits = theME0RecHits->get(lid);
473  int layerHits = 0;
474 
475  for (ME0SegmentCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++) {
476  double rhitDistance = (ir->localPosition() - (**hit2d).localPosition()).mag();
477  if (rhitDistance < coneSize)
478  layerHits++;
479  LogTrace(theCategory) << ir->localPosition() << " " << (**hit2d).localPosition()
480  << " Distance: " << rhitDistance << " recHits: " << layerHits << endl;
481  }
482  if (layerHits > detRecHits)
483  detRecHits = layerHits;
484  }
485  } else {
486  // Get the ME0 Rechits from this layer
487  ME0SegmentCollection::range dRecHits = theME0RecHits->get(did);
488 
489  for (ME0SegmentCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++) {
490  double rhitDistance = (ir->localPosition() - (**imrh).localPosition()).mag();
491  if (rhitDistance < coneSize)
492  detRecHits++;
493  LogTrace(theCategory) << ir->localPosition() << " " << (**imrh).localPosition()
494  << " Distance: " << rhitDistance << " recHits: " << detRecHits << endl;
495  }
496  }
497  } //end of ME0 if
498  else {
499  if (id.subdetId() != MuonSubdetId::RPC)
500  LogError(theCategory) << " Wrong Hit Type ";
501  continue;
502  }
503 
504  map<DetId, int>::iterator imap = hitMap.find(chamberId);
505  if (imap != hitMap.end()) {
506  if (detRecHits > imap->second)
507  imap->second = detRecHits;
508  } else
509  hitMap[chamberId] = detRecHits;
510 
511  } // end of loop over muon rechits
512 
513  for (map<DetId, int>::iterator imap = hitMap.begin(); imap != hitMap.end(); imap++)
514  LogTrace(theCategory) << " Station " << imap->first.rawId() << ": " << imap->second << endl;
515 
516  LogTrace(theCategory) << "CheckMuonHits: " << all.size();
517 
518  // check order of muon measurements
519  if ((all.size() > 1) && (all.front()->globalPosition().mag() > all.back()->globalPosition().mag())) {
520  LogTrace(theCategory) << "reverse order: ";
521  stable_sort(all.begin(), all.end(), RecHitLessByDet(alongMomentum));
522  }
523 }
524 
525 //
526 // Get the hits from the first muon station (containing hits)
527 //
530  ConstRecHitContainer& first) const {
531  LogTrace(theCategory) << " GlobalMuonRefitter::getFirstHits\nall rechits length:" << all.size() << endl;
532  first.clear();
533 
534  int station_to_keep = 999;
535  vector<int> stations;
536  for (ConstRecHitContainer::const_iterator ihit = all.begin(); ihit != all.end(); ++ihit) {
537  int station = 0;
538  bool use_it = true;
539  DetId id = (*ihit)->geographicalId();
540  unsigned raw_id = id.rawId();
541  if (!(*ihit)->isValid())
542  station = -1;
543  else {
544  if (id.det() == DetId::Muon) {
545  switch (id.subdetId()) {
546  case MuonSubdetId::DT:
547  station = DTChamberId(raw_id).station();
548  break;
549  case MuonSubdetId::CSC:
550  station = CSCDetId(raw_id).station();
551  break;
552  case MuonSubdetId::GEM:
553  station = GEMDetId(raw_id).station();
554  break;
555  case MuonSubdetId::ME0:
556  station = ME0DetId(raw_id).station();
557  break;
558  case MuonSubdetId::RPC:
559  station = RPCDetId(raw_id).station();
560  use_it = false;
561  break;
562  }
563  }
564  }
565 
566  if (use_it && station > 0 && station < station_to_keep)
567  station_to_keep = station;
568  stations.push_back(station);
569  LogTrace(theCategory) << "rawId: " << raw_id << " station = " << station << " station_to_keep is now "
570  << station_to_keep;
571  }
572 
573  if (station_to_keep <= 0 || station_to_keep > 4 || stations.size() != all.size())
574  LogInfo(theCategory) << "failed to getFirstHits (all muon hits are outliers/bad ?)! station_to_keep = "
575  << station_to_keep << " stations.size " << stations.size() << " all.size " << all.size();
576 
577  for (unsigned i = 0; i < stations.size(); ++i)
578  if (stations[i] >= 0 && stations[i] <= station_to_keep)
579  first.push_back(all[i]);
580 
581  return;
582 }
583 
584 //
585 // select muon hits compatible with trajectory;
586 // check hits in chambers with showers
587 //
589  const map<DetId, int>& hitMap) const {
590  ConstRecHitContainer muonRecHits;
591  const double globalChi2Cut = 200.0;
592 
593  vector<TrajectoryMeasurement> muonMeasurements = traj.measurements();
594 
595  // loop through all muon hits and skip hits with bad chi2 in chambers with high occupancy
596  for (std::vector<TrajectoryMeasurement>::const_iterator im = muonMeasurements.begin(); im != muonMeasurements.end();
597  im++) {
598  if (!(*im).recHit()->isValid())
599  continue;
600  if ((*im).recHit()->det()->geographicalId().det() != DetId::Muon) {
601  // if ( ( chi2ndf < globalChi2Cut ) )
602  muonRecHits.push_back((*im).recHit());
603  continue;
604  }
605  const MuonTransientTrackingRecHit* immrh = dynamic_cast<const MuonTransientTrackingRecHit*>((*im).recHit().get());
606 
607  DetId id = immrh->geographicalId();
608  DetId chamberId;
609  int threshold = 0;
610  double chi2Cut = 0.0;
611 
612  // get station of hit if it is in DT
613  if ((*immrh).isDT()) {
614  DTChamberId did(id.rawId());
615  chamberId = did;
618  }
619  // get station of hit if it is in CSC
620  else if ((*immrh).isCSC()) {
621  CSCDetId did(id.rawId());
622  chamberId = did.chamberId();
625  }
626  // get station of hit if it is in GEM
627  else if ((*immrh).isGEM()) {
628  GEMDetId did(id.rawId());
629  chamberId = did.chamberId();
632  }
633  // get station of hit if it is in ME0
634  else if ((*immrh).isME0()) {
635  ME0DetId did(id.rawId());
636  chamberId = did.chamberId();
639  }
640  // get station of hit if it is in RPC
641  else if ((*immrh).isRPC()) {
642  RPCDetId rpcid(id.rawId());
643  chamberId = rpcid;
646  } else
647  continue;
648 
649  double chi2ndf = (*im).estimate() / (*im).recHit()->dimension();
650 
651  bool keep = true;
652  map<DetId, int>::const_iterator imap = hitMap.find(chamberId);
653  if (imap != hitMap.end())
654  if (imap->second > threshold)
655  keep = false;
656 
657  if ((keep || (chi2ndf < chi2Cut)) && (chi2ndf < globalChi2Cut)) {
658  muonRecHits.push_back((*im).recHit());
659  } else {
660  LogTrace(theCategory) << "Skip hit: " << id.rawId() << " chi2=" << chi2ndf << " ( threshold: " << chi2Cut
661  << ") Det: " << imap->second << endl;
662  }
663  }
664 
665  // check order of rechits
666  reverse(muonRecHits.begin(), muonRecHits.end());
667  return muonRecHits;
668 }
669 
670 //
671 // print RecHits
672 //
674  LogTrace(theCategory) << "Used RecHits: " << hits.size();
675  for (ConstRecHitContainer::const_iterator ir = hits.begin(); ir != hits.end(); ir++) {
676  if (!(*ir)->isValid()) {
677  LogTrace(theCategory) << "invalid RecHit";
678  continue;
679  }
680 
681  const GlobalPoint& pos = (*ir)->globalPosition();
682 
683  LogTrace(theCategory) << "r = " << sqrt(pos.x() * pos.x() + pos.y() * pos.y()) << " z = " << pos.z()
684  << " dimension = " << (*ir)->dimension()
685  << " det = " << (*ir)->det()->geographicalId().det()
686  << " subdet = " << (*ir)->det()->subDetector()
687  << " raw id = " << (*ir)->det()->geographicalId().rawId();
688  }
689 }
690 
691 //
692 // add Trajectory* to TrackCand if not already present
693 //
696  if (!recHits.empty()) {
697  ConstRecHitContainer::const_iterator frontHit = recHits.begin();
698  ConstRecHitContainer::const_iterator backHit = recHits.end() - 1;
699  while (!(*frontHit)->isValid() && frontHit != backHit) {
700  frontHit++;
701  }
702  while (!(*backHit)->isValid() && backHit != frontHit) {
703  backHit--;
704  }
705 
706  double rFirst = (*frontHit)->globalPosition().mag();
707  double rLast = (*backHit)->globalPosition().mag();
708 
709  if (rFirst < rLast)
710  return insideOut;
711  else if (rFirst > rLast)
712  return outsideIn;
713  else {
714  LogError(theCategory) << "Impossible determine the rechits order" << endl;
715  return undetermined;
716  }
717  } else {
718  LogError(theCategory) << "Impossible determine the rechits order" << endl;
719  return undetermined;
720  }
721 }
722 
723 //
724 // Convert Tracks into Trajectories with a given set of hits
725 //
726 vector<Trajectory> GlobalMuonRefitter::transform(
727  const reco::Track& newTrack,
729  const TransientTrackingRecHit::ConstRecHitContainer& urecHitsForReFit) const {
730  TransientTrackingRecHit::ConstRecHitContainer recHitsForReFit = urecHitsForReFit;
731  LogTrace(theCategory) << "GlobalMuonRefitter::transform: " << recHitsForReFit.size() << " hits:";
732  printHits(recHitsForReFit);
733 
734  if (recHitsForReFit.size() < 2)
735  return vector<Trajectory>();
736 
737  // Check the order of the rechits
738  RefitDirection recHitsOrder = checkRecHitsOrdering(recHitsForReFit);
739 
740  LogTrace(theCategory) << "checkRecHitsOrdering() returned " << recHitsOrder << ", theRefitDirection is "
741  << theRefitDirection << " (insideOut == " << insideOut << ", outsideIn == " << outsideIn << ")";
742 
743  // Reverse the order in the case of inconsistency between the fit direction and the rechit order
744  if (theRefitDirection != recHitsOrder)
745  reverse(recHitsForReFit.begin(), recHitsForReFit.end());
746 
747  // Even though we checked the rechits' ordering above, we may have
748  // already flipped them elsewhere (getFirstHits() is such a
749  // culprit). Use the global positions of the states and the desired
750  // refit direction to find the starting TSOS.
751  TrajectoryStateOnSurface firstTSOS, lastTSOS;
752  unsigned int innerId; //UNUSED: outerId;
753  bool order_swapped = track.outermostMeasurementState().globalPosition().mag() <
754  track.innermostMeasurementState().globalPosition().mag();
755  bool inner_is_first;
756  LogTrace(theCategory) << "order swapped? " << order_swapped;
757 
758  // Fill the starting state, depending on the ordering above.
759  if ((theRefitDirection == insideOut && !order_swapped) || (theRefitDirection == outsideIn && order_swapped)) {
760  innerId = newTrack.innerDetId();
761  //UNUSED: outerId = newTrack.outerDetId();
762  firstTSOS = track.innermostMeasurementState();
763  lastTSOS = track.outermostMeasurementState();
764  inner_is_first = true;
765  } else {
766  innerId = newTrack.outerDetId();
767  //UNUSED: outerId = newTrack.innerDetId();
768  firstTSOS = track.outermostMeasurementState();
769  lastTSOS = track.innermostMeasurementState();
770  inner_is_first = false;
771  }
772 
773  LogTrace(theCategory) << "firstTSOS: inner_is_first? " << inner_is_first << " globalPosition is "
774  << firstTSOS.globalPosition() << " innerId is " << innerId;
775 
776  if (!firstTSOS.isValid()) {
777  LogWarning(theCategory) << "Error wrong initial state!" << endl;
778  return vector<Trajectory>();
779  }
780 
781  firstTSOS.rescaleError(theRescaleErrorFactor);
782 
783  // This is the only way to get a TrajectorySeed with settable propagation direction
784  PTrajectoryStateOnDet garbage1;
786 
787  // These lines cause the code to ignore completely what was set
788  // above, and force propDir for tracks from collisions!
789  // if(propDir == alongMomentum && theRefitDirection == outsideIn) propDir=oppositeToMomentum;
790  // if(propDir == oppositeToMomentum && theRefitDirection == insideOut) propDir=alongMomentum;
791 
792  const TrajectoryStateOnSurface& tsosForDir = inner_is_first ? lastTSOS : firstTSOS;
793  PropagationDirection propDir =
794  (tsosForDir.globalPosition().basicVector().dot(tsosForDir.globalMomentum().basicVector()) > 0)
795  ? alongMomentum
797  LogTrace(theCategory) << "propDir based on firstTSOS x dot p is " << propDir << " (alongMomentum == " << alongMomentum
798  << ", oppositeToMomentum == " << oppositeToMomentum << ")";
799 
800  // Additional propagation diretcion determination logic for cosmic muons
801  if (theCosmicFlag) {
802  PropagationDirection propDir_first =
803  (firstTSOS.globalPosition().basicVector().dot(firstTSOS.globalMomentum().basicVector()) > 0)
804  ? alongMomentum
806  PropagationDirection propDir_last =
807  (lastTSOS.globalPosition().basicVector().dot(lastTSOS.globalMomentum().basicVector()) > 0) ? alongMomentum
809  LogTrace(theCategory) << "propDir_first " << propDir_first << ", propdir_last " << propDir_last << " : they "
810  << (propDir_first == propDir_last ? "agree" : "disagree");
811 
812  int y_count = 0;
813  for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator it = recHitsForReFit.begin();
814  it != recHitsForReFit.end();
815  ++it) {
816  if ((*it)->globalPosition().y() > 0)
817  ++y_count;
818  else
819  --y_count;
820  }
821 
822  PropagationDirection propDir_ycount = alongMomentum;
823  if (y_count > 0) {
825  propDir_ycount = oppositeToMomentum;
826  else if (theRefitDirection == outsideIn)
827  propDir_ycount = alongMomentum;
828  } else {
830  propDir_ycount = alongMomentum;
831  else if (theRefitDirection == outsideIn)
832  propDir_ycount = oppositeToMomentum;
833  }
834 
835  LogTrace(theCategory) << "y_count = " << y_count << "; based on geometrically-outermost TSOS, propDir is "
836  << propDir << ": " << (propDir == propDir_ycount ? "agrees" : "disagrees")
837  << " with ycount determination";
838 
839  if (propDir_first != propDir_last) {
840  LogTrace(theCategory) << "since first/last disagreed, using y_count propDir";
841  propDir = propDir_ycount;
842  }
843  }
844 
845  TrajectorySeed seed(garbage1, garbage2, propDir);
846 
847  if (recHitsForReFit.front()->geographicalId() != DetId(innerId)) {
848  LogDebug(theCategory) << "Propagation occured" << endl;
849  LogTrace(theCategory) << "propagating firstTSOS at " << firstTSOS.globalPosition()
850  << " to first rechit with surface pos "
851  << recHitsForReFit.front()->det()->surface().toGlobal(LocalPoint(0, 0, 0));
852  firstTSOS =
853  theService->propagator(thePropagatorName)->propagate(firstTSOS, recHitsForReFit.front()->det()->surface());
854  if (!firstTSOS.isValid()) {
855  LogDebug(theCategory) << "Propagation error!" << endl;
856  return vector<Trajectory>();
857  }
858  }
859 
860  LogDebug(theCategory) << " GlobalMuonRefitter : theFitter " << propDir << endl;
861  LogDebug(theCategory) << " First TSOS: " << firstTSOS.globalPosition()
862  << " p=" << firstTSOS.globalMomentum() << " = " << firstTSOS.globalMomentum().mag() << endl;
863 
864  LogDebug(theCategory) << " Starting seed: "
865  << " nHits= " << seed.nHits() << " tsos: " << seed.startingState().parameters().position()
866  << " p=" << seed.startingState().parameters().momentum() << endl;
867 
868  LogDebug(theCategory) << " RecHits: " << recHitsForReFit.size() << endl;
869 
870  vector<Trajectory> trajectories = theFitter->fit(seed, recHitsForReFit, firstTSOS);
871 
872  if (trajectories.empty()) {
873  LogDebug(theCategory) << "No Track refitted!" << endl;
874  return vector<Trajectory>();
875  }
876  return trajectories;
877 }
878 
879 //
880 // Remove Selected Station Rec Hits
881 //
883  const ConstRecHitContainer& hits, const TrackerTopology* tTopo) const {
885  ConstRecHitContainer::const_iterator it = hits.begin();
886  for (; it != hits.end(); it++) {
887  DetId id = (*it)->geographicalId();
888 
889  //Check that this is a Muon hit that we're toying with -- else pass on this because the hacker is a moron / not careful
890 
891  if (id.det() == DetId::Tracker && theTrackerSkipSystem > 0) {
892  int layer = -999;
893  int disk = -999;
894  int wheel = -999;
895  if (id.subdetId() == theTrackerSkipSystem) {
896  // continue; //caveat that just removes the whole system from refitting
897 
898  if (theTrackerSkipSystem == PXB) {
899  layer = tTopo->pxbLayer(id);
900  }
901  if (theTrackerSkipSystem == TIB) {
902  layer = tTopo->tibLayer(id);
903  }
904 
905  if (theTrackerSkipSystem == TOB) {
906  layer = tTopo->tobLayer(id);
907  }
908  if (theTrackerSkipSystem == PXF) {
909  disk = tTopo->pxfDisk(id);
910  }
911  if (theTrackerSkipSystem == TID) {
912  wheel = tTopo->tidWheel(id);
913  }
914  if (theTrackerSkipSystem == TEC) {
915  wheel = tTopo->tecWheel(id);
916  }
918  continue;
919  if (theTrackerSkipSection >= 0 && disk == theTrackerSkipSection)
920  continue;
922  continue;
923  }
924  }
925 
926  if (id.det() == DetId::Muon && theSkipStation) {
927  int station = -999;
928  //UNUSED: int wheel = -999;
929  if (id.subdetId() == MuonSubdetId::DT) {
930  DTChamberId did(id.rawId());
931  station = did.station();
932  //UNUSED: wheel = did.wheel();
933  } else if (id.subdetId() == MuonSubdetId::CSC) {
934  CSCDetId did(id.rawId());
935  station = did.station();
936  } else if (id.subdetId() == MuonSubdetId::GEM) {
937  GEMDetId did(id.rawId());
938  station = did.station();
939  } else if (id.subdetId() == MuonSubdetId::ME0) {
940  ME0DetId did(id.rawId());
941  station = did.station();
942  } else if (id.subdetId() == MuonSubdetId::RPC) {
943  RPCDetId rpcid(id.rawId());
944  station = rpcid.station();
945  }
946  if (station == theSkipStation)
947  continue;
948  }
949  results.push_back(*it);
950  }
951  return results;
952 }
DynamicTruncation::Config theDynamicTruncationConfig
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
int station() const
Return the station number.
Definition: DTChamberId.h:45
edm::Handle< DTRecHitCollection > theDTRecHits
constexpr int station() const
Definition: GEMDetId.h:179
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
unsigned int tobLayer(const DetId &id) const
unsigned int pxbLayer(const DetId &id) const
void setProd(const edm::Handle< DTRecSegment4DCollection > &DTSegProd, const edm::Handle< CSCSegmentCollection > &CSCSegProd)
edm::ESGetToken< TransientTrackingRecHitBuilder, TransientRecHitRecord > theMuonRecHitBuilderToken
std::pair< const_iterator, const_iterator > range
iterator range
Definition: RangeMap.h:50
Point3DBase< Scalar, LocalTag > LocalPoint
Definition: Definitions.h:30
static constexpr int GEM
Definition: MuonSubdetId.h:14
const MuonServiceProxy * theService
RefitDirection theRefitDirection
def all(container)
workaround iterator generators for ROOT classes
Definition: cmstools.py:25
edm::Handle< CSCSegmentCollection > CSCSegments
std::string thePropagatorName
unsigned int tidWheel(const DetId &id) const
unsigned int tecWheel(const DetId &id) const
edm::Handle< GEMRecHitCollection > theGEMRecHits
void setServices(const edm::EventSetup &)
set the services needed by the TrackTransformer
void CopyFrom(const DYTInfo &)
copy from another DYTInfo
Definition: DYTInfo.cc:14
PropagationDirection
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:172
TransientTrackingRecHit::ConstRecHitContainer ConstRecHitContainer
edm::EDGetTokenT< CSCSegmentCollection > CSCSegmentsToken
Log< level::Error, false > LogError
void printHits(const ConstRecHitContainer &) const
print all RecHits of a trajectory
std::unique_ptr< TrajectoryFitter > theFitter
edm::Handle< ME0SegmentCollection > theME0RecHits
int station() const
Definition: ME0DetId.h:58
#define LogTrace(id)
std::vector< int > theDYTthrs
DataContainer const & measurements() const
Definition: Trajectory.h:178
T getUntrackedParameter(std::string const &, T const &) const
edm::ESGetToken< TransientTrackingRecHitBuilder, TransientRecHitRecord > theTrackerRecHitBuilderToken
void setRecoEta(double eta)
C::const_iterator const_iterator
constant access iterator type
Definition: RangeMap.h:43
ME0DetId chamberId() const
Return the corresponding ChamberId (mask layers)
Definition: ME0DetId.h:53
GlobalPoint globalPosition() const
edm::Handle< DTRecSegment4DCollection > all4DSegments
const TransientTrackingRecHitBuilder * theMuonRecHitBuilder
const TransientTrackingRecHitBuilder * theTrackerRecHitBuilder
T sqrt(T t)
Definition: SSEVec.h:23
virtual RecHitPointer build(const TrackingRecHit *p) const =0
build a tracking rechit from an existing rechit
ConstRecHitContainer selectMuonHits(const Trajectory &, const std::map< DetId, int > &) const
select muon hits compatible with trajectory; check hits in chambers with showers
MuonTransientTrackingRecHit::MuonRecHitContainer MuonRecHitContainer
unsigned int pxfDisk(const DetId &id) const
edm::EDGetTokenT< ME0SegmentCollection > theME0RecHitToken
edm::ParameterSet theDYTthrsParameters
edm::Handle< CSCRecHit2DCollection > theCSCRecHits
static constexpr int ME0
Definition: MuonSubdetId.h:15
edm::EDGetTokenT< DTRecHitCollection > theDTRecHitToken
edm::EDGetTokenT< CSCRecHit2DCollection > theCSCRecHitToken
unsigned int innerDetId() const
DetId of the detector on which surface the innermost state is located.
Definition: Track.h:82
TransientTrackingRecHit::ConstRecHitContainer filter(const Trajectory &)
const BasicVectorType & basicVector() const
Definition: PV3DBase.h:53
std::vector< Trajectory > transform(const reco::Track &newTrack, const reco::TransientTrack track, const TransientTrackingRecHit::ConstRecHitContainer &recHitsForReFit) const
refit the track with a new set of RecHits
edm::InputTag theDTRecHitLabel
std::vector< ConstRecHitPointer > ConstRecHitContainer
const edm::EventSetup * theEventSetup
edm::InputTag theGEMRecHitLabel
Log< level::Info, false > LogInfo
virtual void setEvent(const edm::Event &)
pass the Event to the algo at each event
void setThrsMap(const edm::ParameterSet &)
void setParThrsMode(bool dytParThrsMode)
RefitDirection checkRecHitsOrdering(const ConstRecHitContainer &) const
Definition: DetId.h:17
edm::ESGetToken< TrajectoryFitter, TrajectoryFitterRecord > theFitterToken
edm::InputTag theME0RecHitLabel
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
GlobalMuonRefitter(const edm::ParameterSet &, const MuonServiceProxy *, edm::ConsumesCollector &)
constructor with Parameter Set and MuonServiceProxy
edm::EDGetTokenT< DTRecSegment4DCollection > all4DSegmentsToken
int station() const
Definition: CSCDetId.h:79
DetId geographicalId() const
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
CSCDetId chamberId() const
Definition: CSCDetId.h:47
ConstRecHitContainer getRidOfSelectStationHits(const ConstRecHitContainer &hits, const TrackerTopology *tTopo) const
static constexpr int RPC
Definition: MuonSubdetId.h:13
unsigned int outerDetId() const
DetId of the detector on which surface the outermost state is located.
Definition: Track.h:79
GlobalVector globalMomentum() const
int station() const
Definition: RPCDetId.h:78
reco::DYTInfo getDYTInfo()
reco::DYTInfo * dytInfo
HLT enums.
results
Definition: mysort.py:8
void getFirstHits(const reco::Track &, ConstRecHitContainer &, ConstRecHitContainer &) const
get the RecHits in the tracker and the first muon chamber with hits
std::vector< Trajectory > refit(const reco::Track &globalTrack, const int theMuonHitsOption, const TrackerTopology *tTopo) const
build combined trajectory from sta Track and tracker RecHits
constexpr GEMDetId chamberId() const
Definition: GEMDetId.h:204
virtual ~GlobalMuonRefitter()
destructor
unsigned int tibLayer(const DetId &id) const
static constexpr int DT
Definition: MuonSubdetId.h:11
Log< level::Warning, false > LogWarning
unsigned long long theCacheId_TRH
T dot(const Basic3DVector &rh) const
Scalar product, or "dot" product, with a vector of same type.
static constexpr int CSC
Definition: MuonSubdetId.h:12
void setThr(const std::vector< int > &)
void setRecoP(double p)
Definition: event.py:1
edm::InputTag theCSCRecHitLabel
void checkMuonHits(const reco::Track &, ConstRecHitContainer &, std::map< DetId, int > &) const
check muon RecHits, calculate chamber occupancy and select hits to be used in the final fit ...
#define LogDebug(id)
edm::EDGetTokenT< GEMRecHitCollection > theGEMRecHitToken