CMS 3D CMS Logo

MuonIdProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: MuonIdentification
4 // Class: MuonIdProducer
5 //
6 //
7 // Original Author: Dmytro Kovalskyi
8 //
9 //
10 
11 // user include files
13 
27 
30 
33 
35  : geomTokenRun_(esConsumes<edm::Transition::BeginRun>()),
36  propagatorToken_(esConsumes(edm::ESInputTag("", "SteppingHelixPropagatorAny"))) {
37  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: Constructor called";
38 
39  produces<reco::MuonCollection>();
40  produces<reco::CaloMuonCollection>();
41  produces<reco::MuonTimeExtraMap>("combined");
42  produces<reco::MuonTimeExtraMap>("dt");
43  produces<reco::MuonTimeExtraMap>("csc");
44 
45  minPt_ = iConfig.getParameter<double>("minPt");
46  minP_ = iConfig.getParameter<double>("minP");
47  minPCaloMuon_ = iConfig.getParameter<double>("minPCaloMuon");
48  minNumberOfMatches_ = iConfig.getParameter<int>("minNumberOfMatches");
49  addExtraSoftMuons_ = iConfig.getParameter<bool>("addExtraSoftMuons");
50  maxAbsEta_ = iConfig.getParameter<double>("maxAbsEta");
51  maxAbsDx_ = iConfig.getParameter<double>("maxAbsDx");
52  maxAbsPullX2_ = iConfig.getParameter<double>("maxAbsPullX");
54  maxAbsDy_ = iConfig.getParameter<double>("maxAbsDy");
55  maxAbsPullY2_ = iConfig.getParameter<double>("maxAbsPullY");
57  fillCaloCompatibility_ = iConfig.getParameter<bool>("fillCaloCompatibility");
58  fillEnergy_ = iConfig.getParameter<bool>("fillEnergy");
59  storeCrossedHcalRecHits_ = iConfig.getParameter<bool>("storeCrossedHcalRecHits");
60  fillMatching_ = iConfig.getParameter<bool>("fillMatching");
61  fillIsolation_ = iConfig.getParameter<bool>("fillIsolation");
62  fillShowerDigis_ = iConfig.getParameter<bool>("fillShowerDigis");
63  writeIsoDeposits_ = iConfig.getParameter<bool>("writeIsoDeposits");
64  fillGlobalTrackQuality_ = iConfig.getParameter<bool>("fillGlobalTrackQuality");
65  fillGlobalTrackRefits_ = iConfig.getParameter<bool>("fillGlobalTrackRefits");
66  arbitrateTrackerMuons_ = iConfig.getParameter<bool>("arbitrateTrackerMuons");
67  selectHighPurity_ = iConfig.getParameter<bool>("selectHighPurity");
68  //SK: (maybe temporary) run it only if the global is also run
69  fillTrackerKink_ = false;
71  fillTrackerKink_ = iConfig.getParameter<bool>("fillTrackerKink");
72 
74  iConfig.getParameter<double>("ptThresholdToFillCandidateP4WithGlobalFit");
76  iConfig.getParameter<double>("sigmaThresholdToFillCandidateP4WithGlobalFit");
77  caloCut_ = iConfig.getParameter<double>("minCaloCompatibility"); //CaloMuons
78  arbClean_ = iConfig.getParameter<bool>("runArbitrationCleaner"); // muon mesh
79 
80  // Load TrackDetectorAssociator parameters
81  const edm::ParameterSet parameters = iConfig.getParameter<edm::ParameterSet>("TrackAssociatorParameters");
82  edm::ConsumesCollector iC = consumesCollector();
84 
85  // Load parameters for the TimingFiller
86  edm::ParameterSet timingParameters = iConfig.getParameter<edm::ParameterSet>("TimingFillerParameters");
87  theTimingFiller_ = std::make_unique<MuonTimingFiller>(timingParameters, consumesCollector());
88 
89  // Load parameters for the ShowerDigiFiller
91  edm::ParameterSet showerDigiParameters = iConfig.getParameter<edm::ParameterSet>("ShowerDigiFillerParameters");
92  theShowerDigiFiller_ = std::make_unique<MuonShowerDigiFiller>(showerDigiParameters, consumesCollector());
93  } else {
94  theShowerDigiFiller_ = std::make_unique<MuonShowerDigiFiller>(); // to be used to call fillDefault only
95  }
96 
98  // Load MuonCaloCompatibility parameters
99  const auto caloParams = iConfig.getParameter<edm::ParameterSet>("MuonCaloCompatibility");
101  }
102 
103  if (fillIsolation_) {
104  // Load MuIsoExtractor parameters
105  edm::ParameterSet caloExtractorPSet = iConfig.getParameter<edm::ParameterSet>("CaloExtractorPSet");
106  std::string caloExtractorName = caloExtractorPSet.getParameter<std::string>("ComponentName");
108  IsoDepositExtractorFactory::get()->create(caloExtractorName, caloExtractorPSet, consumesCollector());
109 
110  edm::ParameterSet trackExtractorPSet = iConfig.getParameter<edm::ParameterSet>("TrackExtractorPSet");
111  std::string trackExtractorName = trackExtractorPSet.getParameter<std::string>("ComponentName");
113  IsoDepositExtractorFactory::get()->create(trackExtractorName, trackExtractorPSet, consumesCollector());
114 
115  edm::ParameterSet jetExtractorPSet = iConfig.getParameter<edm::ParameterSet>("JetExtractorPSet");
116  std::string jetExtractorName = jetExtractorPSet.getParameter<std::string>("ComponentName");
118  IsoDepositExtractorFactory::get()->create(jetExtractorName, jetExtractorPSet, consumesCollector());
119  }
121  trackDepositName_ = iConfig.getParameter<std::string>("trackDepositName");
122  produces<reco::IsoDepositMap>(trackDepositName_);
123  ecalDepositName_ = iConfig.getParameter<std::string>("ecalDepositName");
124  produces<reco::IsoDepositMap>(ecalDepositName_);
125  hcalDepositName_ = iConfig.getParameter<std::string>("hcalDepositName");
126  produces<reco::IsoDepositMap>(hcalDepositName_);
127  hoDepositName_ = iConfig.getParameter<std::string>("hoDepositName");
128  produces<reco::IsoDepositMap>(hoDepositName_);
129  jetDepositName_ = iConfig.getParameter<std::string>("jetDepositName");
130  produces<reco::IsoDepositMap>(jetDepositName_);
131  }
132 
133  inputCollectionLabels_ = iConfig.getParameter<std::vector<edm::InputTag> >("inputCollectionLabels");
134  const auto inputCollectionTypes = iConfig.getParameter<std::vector<std::string> >("inputCollectionTypes");
135  if (inputCollectionLabels_.size() != inputCollectionTypes.size())
136  throw cms::Exception("ConfigurationError")
137  << "Number of input collection labels is different from number of types. "
138  << "For each collection label there should be exactly one collection type specified.";
139  if (inputCollectionLabels_.size() > 8 || inputCollectionLabels_.empty())
140  throw cms::Exception("ConfigurationError") << "Number of input collections should be from 1 to 8.";
141 
142  debugWithTruthMatching_ = iConfig.getParameter<bool>("debugWithTruthMatching");
144  edm::LogWarning("MuonIdentification")
145  << "========================================================================\n"
146  << "Debugging mode with truth matching is turned on!!! Make sure you understand what you are doing!\n"
147  << "========================================================================\n";
148 
150  }
152  const auto& glbQualTag = iConfig.getParameter<edm::InputTag>("globalTrackQualityInputTag");
153  glbQualToken_ = consumes<edm::ValueMap<reco::MuonQuality> >(glbQualTag);
154  }
155 
156  if (fillTrackerKink_) {
158  std::make_unique<MuonKinkFinder>(iConfig.getParameter<edm::ParameterSet>("TrackerKinkFinderParameters"), iC);
159  }
160 
161  if (selectHighPurity_) {
162  const auto& pvTag = iConfig.getParameter<edm::InputTag>("pvInputTag");
163  pvToken_ = mayConsume<reco::VertexCollection>(pvTag);
164  }
165 
166  //create mesh holder
167  meshAlgo_ = std::make_unique<MuonMesh>(iConfig.getParameter<edm::ParameterSet>("arbitrationCleanerOptions"));
168 
169  edm::InputTag rpcHitTag("rpcRecHits");
170  rpcHitToken_ = consumes<RPCRecHitCollection>(rpcHitTag);
171 
172  edm::InputTag gemHitTag("gemRecHits");
173  gemHitToken_ = consumes<GEMRecHitCollection>(gemHitTag);
174 
175  //Consumes... UGH
177  for (unsigned int i = 0; i < inputCollectionLabels_.size(); ++i) {
178  const auto inputLabel = inputCollectionLabels_[i];
179  const auto inputType = ICTypes::toKey(inputCollectionTypes[i]); // Note: thorws exception if type is undefined.
180 
181  if (inputType == ICTypes::INNER_TRACKS) {
182  innerTrackCollectionToken_ = consumes<reco::TrackCollection>(inputLabel);
184  outerTrackCollectionToken_ = consumes<reco::TrackCollection>(inputLabel);
185  } else if (inputType == ICTypes::OUTER_TRACKS) {
186  outerTrackSecondaryCollectionToken_ = consumes<reco::TrackCollection>(inputLabel);
187  } else if (inputType == ICTypes::LINKS) {
188  linkCollectionToken_ = consumes<reco::MuonTrackLinksCollection>(inputLabel);
189  } else if (inputType == ICTypes::MUONS) {
190  muonCollectionToken_ = consumes<reco::MuonCollection>(inputLabel);
191  } else if (inputType == ICTypes::TEV_FIRSTHIT) {
192  tpfmsCollectionToken_ = consumes<reco::TrackToTrackMap>(inputLabel);
193  } else if (fillGlobalTrackRefits_ && inputType == ICTypes::TEV_PICKY) {
194  pickyCollectionToken_ = consumes<reco::TrackToTrackMap>(inputLabel);
195  } else if (fillGlobalTrackRefits_ && inputType == ICTypes::TEV_DYT) {
196  dytCollectionToken_ = consumes<reco::TrackToTrackMap>(inputCollectionLabels_.at(i));
197  }
198 
199  inputCollectionTypes_[i] = inputType;
200  }
201 }
202 
204  // TimingReport::current()->dump(std::cout);
205 }
206 
213 
214  tpfmsCollectionHandle_.clear();
215  pickyCollectionHandle_.clear();
216  dytCollectionHandle_.clear();
217 
219 
220  if (fillTrackerKink_)
221  trackerKinkFinder_->init(iSetup);
222 
223  for (unsigned int i = 0; i < inputCollectionLabels_.size(); ++i) {
224  const auto& inputLabel = inputCollectionLabels_[i];
225  const auto inputType = inputCollectionTypes_[i];
226  if (inputType == ICTypes::INNER_TRACKS) {
229  throw cms::Exception("FatalError") << "Failed to get input track collection with label: " << inputLabel;
230  LogTrace("MuonIdentification") << "Number of input inner tracks: " << innerTrackCollectionHandle_->size();
231  } else if (inputType == ICTypes::OUTER_TRACKS && !outerTrackCollectionHandle_.isValid()) {
234  throw cms::Exception("FatalError") << "Failed to get input track collection with label: " << inputLabel;
235  LogTrace("MuonIdentification") << "Number of input outer tracks: " << outerTrackCollectionHandle_->size();
236  } else if (inputType == ICTypes::OUTER_TRACKS) {
239  throw cms::Exception("FatalError") << "Failed to get input track collection with label: " << inputLabel;
240  LogTrace("MuonIdentification") << "Number of input outer secondary tracks: "
242  } else if (inputType == ICTypes::LINKS) {
245  throw cms::Exception("FatalError") << "Failed to get input link collection with label: " << inputLabel;
246  LogTrace("MuonIdentification") << "Number of input links: " << linkCollectionHandle_->size();
247  } else if (inputType == ICTypes::MUONS) {
250  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
251  LogTrace("MuonIdentification") << "Number of input muons: " << muonCollectionHandle_->size();
252  } else if (fillGlobalTrackRefits_ && inputType == ICTypes::TEV_FIRSTHIT) {
254  if (!tpfmsCollectionHandle_.isValid())
255  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
256  LogTrace("MuonIdentification") << "Number of input muons: " << tpfmsCollectionHandle_->size();
257  } else if (fillGlobalTrackRefits_ && inputType == ICTypes::TEV_PICKY) {
259  if (!pickyCollectionHandle_.isValid())
260  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
261  LogTrace("MuonIdentification") << "Number of input muons: " << pickyCollectionHandle_->size();
262  } else if (fillGlobalTrackRefits_ && inputType == ICTypes::TEV_DYT) {
264  if (!dytCollectionHandle_.isValid())
265  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
266  LogTrace("MuonIdentification") << "Number of input muons: " << dytCollectionHandle_->size();
267  } else
268  throw cms::Exception("FatalError") << "Unknown input collection type: #" << ICTypes::toStr(inputType);
269  }
270 
271  iEvent.getByToken(rpcHitToken_, rpcHitHandle_);
272  iEvent.getByToken(gemHitToken_, gemHitHandle_);
274  iEvent.getByToken(glbQualToken_, glbQualHandle_);
275  if (selectHighPurity_)
276  iEvent.getByToken(pvToken_, pvHandle_);
277 }
278 
280  const edm::EventSetup& iSetup,
281  const reco::TrackRef& track,
283  LogTrace("MuonIdentification") << "Creating a muon from a track " << track.get()->pt()
284  << " Pt (GeV), eta: " << track.get()->eta();
285  reco::Muon aMuon(makeMuon(*(track.get())));
286 
287  LogTrace("MuonIdentification") << "Muon created from a track ";
288 
289  aMuon.setMuonTrack(type, track);
290  aMuon.setBestTrack(type);
291  aMuon.setTunePBestTrack(type);
292 
293  LogTrace("MuonIdentification")
294  << "Muon created from a track and setMuonBestTrack, setBestTrack and setTunePBestTrack called";
295 
296  return aMuon;
297 }
298 
300  LogTrace("MuonIdentification") << "Creating a CaloMuon from a Muon";
301 
302  reco::CaloMuon aMuon;
303  aMuon.setInnerTrack(muon.innerTrack());
304 
305  if (muon.isEnergyValid())
306  aMuon.setCalEnergy(muon.calEnergy());
307  // get calo compatibility
310  return aMuon;
311 }
312 
314  LogTrace("MuonIdentification") << "Creating a muon from a link to tracks object";
315 
316  reco::Muon aMuon;
317  reco::Muon::MuonTrackTypePair chosenTrack;
318  reco::TrackRef tpfmsRef;
319  reco::TrackRef pickyRef;
320  reco::TrackRef dytRef;
321  bool useSigmaSwitch = false;
322 
323  if (tpfmsCollectionHandle_.isValid() && !tpfmsCollectionHandle_.failedToGet() && pickyCollectionHandle_.isValid() &&
324  !pickyCollectionHandle_.failedToGet()) {
325  tpfmsRef = muon::getTevRefitTrack(links.globalTrack(), *tpfmsCollectionHandle_);
326  pickyRef = muon::getTevRefitTrack(links.globalTrack(), *pickyCollectionHandle_);
327  dytRef = muon::getTevRefitTrack(links.globalTrack(), *dytCollectionHandle_);
328 
329  if (tpfmsRef.isNull() && pickyRef.isNull() && dytRef.isNull()) {
330  edm::LogWarning("MakeMuonWithTEV") << "Failed to get TEV refits, fall back to sigma switch.";
331  useSigmaSwitch = true;
332  }
333  } else {
334  useSigmaSwitch = true;
335  }
336 
337  if (useSigmaSwitch) {
338  chosenTrack = muon::sigmaSwitch(links.globalTrack(),
339  links.trackerTrack(),
342  } else {
343  chosenTrack = muon::tevOptimized(links.globalTrack(),
344  links.trackerTrack(),
345  tpfmsRef,
346  pickyRef,
347  dytRef,
349  }
350  aMuon = makeMuon(*chosenTrack.first);
351  aMuon.setInnerTrack(links.trackerTrack());
352  aMuon.setOuterTrack(links.standAloneTrack());
353  aMuon.setGlobalTrack(links.globalTrack());
354  aMuon.setBestTrack(chosenTrack.second);
355  aMuon.setTunePBestTrack(chosenTrack.second);
356 
358  if (tpfmsCollectionHandle_.isValid() && !tpfmsCollectionHandle_.failedToGet()) {
360  if (it != tpfmsCollectionHandle_->end())
361  aMuon.setMuonTrack(reco::Muon::TPFMS, (it->val));
362  }
363  if (pickyCollectionHandle_.isValid() && !pickyCollectionHandle_.failedToGet()) {
365  if (it != pickyCollectionHandle_->end())
366  aMuon.setMuonTrack(reco::Muon::Picky, (it->val));
367  }
368  if (dytCollectionHandle_.isValid() && !dytCollectionHandle_.failedToGet()) {
370  if (it != dytCollectionHandle_->end())
371  aMuon.setMuonTrack(reco::Muon::DYT, (it->val));
372  }
373  }
374  return aMuon;
375 }
376 
378  // Pt and absolute momentum requirement
379  const double p = track.p();
380  const double pt = track.pt();
381  if (pt < minPt_ || (p < minP_ && p < minPCaloMuon_)) {
382  LogTrace("MuonIdentification") << "Skipped low momentum track (Pt,P): " << pt << ", " << track.p() << " GeV";
383  return false;
384  }
385 
386  // Eta requirement
387  const double eta = track.eta();
388  const double absEta = std::abs(eta);
389  if (absEta > maxAbsEta_) {
390  LogTrace("MuonIdentification") << "Skipped track with large pseudo rapidity (Eta: " << track.eta() << " )";
391  return false;
392  }
393 
394  return true;
395 }
396 
397 unsigned int MuonIdProducer::chamberId(const DetId& id) {
398  if (id.det() != DetId::Muon)
399  return 0;
400 
401  const auto subdetId = id.subdetId();
402  if (subdetId == MuonSubdetId::DT) {
403  return DTChamberId(id.rawId()).rawId();
404  } else if (subdetId == MuonSubdetId::CSC) {
405  return CSCDetId(id.rawId()).chamberId().rawId();
406  }
407 
408  return 0;
409 }
410 
412  if (!muon.isMatchesValid() || track.extra().isNull() || track.extra()->recHitsSize() == 0)
413  return 0;
414 
415  int numberOfCommonDetIds = 0;
416  const std::vector<reco::MuonChamberMatch>& matches(muon.matches());
417  for (const auto& match : matches) {
418  if (match.segmentMatches.empty())
419  continue;
420 
421  bool foundCommonDetId = false;
422  for (auto hit = track.extra()->recHitsBegin(); hit != track.extra()->recHitsEnd(); ++hit) {
423  // LogTrace("MuonIdentification") << "hit DetId: " << std::hex << hit->get()->geographicalId().rawId() <<
424  // "\t hit chamber DetId: " << getChamberId(hit->get()->geographicalId()) <<
425  // "\t segment DetId: " << match->id.rawId() << std::dec;
426 
427  if (chamberId((*hit)->geographicalId()) == match.id.rawId()) {
428  foundCommonDetId = true;
429  break;
430  }
431  }
432  if (foundCommonDetId) {
433  ++numberOfCommonDetIds;
434  break;
435  }
436  }
437  return numberOfCommonDetIds;
438 }
439 
440 void MuonIdProducer::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {
441  meshAlgo_->setCSCGeometry(&iSetup.getData(geomTokenRun_));
442 
444  theShowerDigiFiller_->getES(iSetup);
445 }
446 
447 bool validateGlobalMuonPair(const reco::MuonTrackLinks& goodMuon, const reco::MuonTrackLinks& badMuon) {
448  const int nHitsGood = goodMuon.globalTrack()->hitPattern().numberOfValidMuonHits();
449  const int nHitsBad = badMuon.globalTrack()->hitPattern().numberOfValidMuonHits();
450  if (std::min(nHitsGood, nHitsBad) > 10) {
451  const double chi2Good = goodMuon.globalTrack()->normalizedChi2();
452  const double chi2Bad = badMuon.globalTrack()->normalizedChi2();
453  return (chi2Good <= chi2Bad);
454  }
455 
456  return (nHitsGood >= nHitsBad);
457 }
458 
460  auto outputMuons = std::make_unique<reco::MuonCollection>();
461  auto caloMuons = std::make_unique<reco::CaloMuonCollection>();
462 
463  init(iEvent, iSetup);
464 
466  theShowerDigiFiller_->getDigis(iEvent);
467 
468  // loop over input collections
469 
470  // muons first - no cleaning, take as is.
472  for (const auto& muon : *muonCollectionHandle_) {
473  outputMuons->push_back(muon);
474  }
475  }
476 
477  // links second ( assume global muon type )
479  const auto nLink = linkCollectionHandle_->size();
480  std::vector<bool> goodmuons(nLink, true);
481  if (nLink > 1) {
482  // check for shared tracker tracks
483  for (unsigned int i = 0; i < nLink - 1; ++i) {
484  const auto& iLink = linkCollectionHandle_->at(i);
485  if (iLink.trackerTrack().isNull() || !checkLinks(&iLink))
486  continue;
487  for (unsigned int j = i + 1; j < nLink; ++j) {
488  const auto& jLink = linkCollectionHandle_->at(j);
489  if (!checkLinks(&jLink))
490  continue;
491  if (iLink.trackerTrack() == jLink.trackerTrack()) {
492  // Tracker track is the essential part that dominates muon resolution
493  // so taking either muon is fine. All that is important is to preserve
494  // the muon identification information. If number of hits is small,
495  // keep the one with large number of hits, otherwise take the smalest chi2/ndof
496  if (validateGlobalMuonPair(iLink, jLink))
497  goodmuons[j] = false;
498  else
499  goodmuons[i] = false;
500  }
501  }
502  }
503  // check for shared stand-alone muons.
504  for (unsigned int i = 0; i < nLink - 1; ++i) {
505  if (!goodmuons[i])
506  continue;
507  const auto& iLink = linkCollectionHandle_->at(i);
508  if (iLink.standAloneTrack().isNull() || !checkLinks(&iLink))
509  continue;
510  for (unsigned int j = i + 1; j < nLink; ++j) {
511  if (!goodmuons[j])
512  continue;
513  const auto& jLink = linkCollectionHandle_->at(j);
514  if (!checkLinks(&jLink))
515  continue;
516  if (iLink.standAloneTrack() == jLink.standAloneTrack()) {
517  if (validateGlobalMuonPair(iLink, jLink))
518  goodmuons[j] = false;
519  else
520  goodmuons[i] = false;
521  }
522  }
523  }
524  }
525  for (unsigned int i = 0; i < nLink; ++i) {
526  if (!goodmuons[i])
527  continue;
528  const auto& iLink = linkCollectionHandle_->at(i);
529  if (!checkLinks(&iLink))
530  continue;
531  // check if this muon is already in the list
532  bool newMuon = true;
533  for (const auto& muon : *outputMuons) {
534  if (muon.track() == iLink.trackerTrack() && muon.standAloneMuon() == iLink.standAloneTrack() &&
535  muon.combinedMuon() == iLink.globalTrack()) {
536  newMuon = false;
537  break;
538  }
539  }
540  if (newMuon) {
541  outputMuons->push_back(makeMuon(iLink));
542  outputMuons->back().setType(reco::Muon::GlobalMuon | reco::Muon::StandAloneMuon);
543  }
544  }
545  }
546 
547  // tracker and calo muons are next
549  LogTrace("MuonIdentification") << "Creating tracker muons";
550  std::vector<TrackDetectorAssociator::Direction> directions1, directions2;
551  directions1.push_back(TrackDetectorAssociator::InsideOut);
552  directions1.push_back(TrackDetectorAssociator::OutsideIn);
553  directions2.push_back(TrackDetectorAssociator::Any);
554 
555  const GlobalTrackingGeometry* geometry = nullptr;
557  geometry = &iSetup.getData(globalGeomToken_);
558  }
559 
560  for (unsigned int i = 0; i < innerTrackCollectionHandle_->size(); ++i) {
562  if (!isGoodTrack(track))
563  continue;
565  const reco::VertexCollection* recoVertices = pvHandle_.product();
566  if (!(*recoVertices)[0].isFake())
567  continue;
568  }
569  const auto& trackRef = reco::TrackRef(innerTrackCollectionHandle_, i);
570  bool splitTrack = false;
571  if (track.extra().isAvailable() && TrackDetectorAssociator::crossedIP(track))
572  splitTrack = true;
573  const auto& directions = splitTrack ? directions1 : directions2;
574  for (const auto direction : directions) {
575  // make muon
577  fillMuonId(iEvent, iSetup, trackerMuon, direction);
578 
580  // add MC hits to a list of matched segments.
581  // Since it's debugging mode - code is slow
583  }
584 
585  // check if this muon is already in the list
586  // have to check where muon hits are really located
587  // to match properly
588  bool newMuon = true;
589  const bool goodTrackerMuon = isGoodTrackerMuon(trackerMuon);
590  const bool goodRPCMuon = isGoodRPCMuon(trackerMuon);
591  const bool goodGEMMuon = isGoodGEMMuon(trackerMuon);
592  const bool goodME0Muon = isGoodME0Muon(trackerMuon);
593  if (goodTrackerMuon)
595  if (goodRPCMuon)
596  trackerMuon.setType(trackerMuon.type() | reco::Muon::RPCMuon);
597  if (goodGEMMuon)
598  trackerMuon.setType(trackerMuon.type() | reco::Muon::GEMMuon);
599  if (goodME0Muon)
600  trackerMuon.setType(trackerMuon.type() | reco::Muon::ME0Muon);
601 
602  for (auto& muon : *outputMuons) {
603  if (muon.innerTrack().get() == trackerMuon.innerTrack().get() &&
605  M_PI_2) {
606  newMuon = false;
607  muon.setMatches(trackerMuon.matches());
608  if (trackerMuon.isTimeValid())
609  muon.setTime(trackerMuon.time());
610  if (trackerMuon.isEnergyValid())
611  muon.setCalEnergy(trackerMuon.calEnergy());
612  if (goodTrackerMuon)
613  muon.setType(muon.type() | reco::Muon::TrackerMuon);
614  if (goodRPCMuon)
615  muon.setType(muon.type() | reco::Muon::RPCMuon);
616  if (goodGEMMuon)
617  muon.setType(muon.type() | reco::Muon::GEMMuon);
618  if (goodME0Muon)
619  muon.setType(muon.type() | reco::Muon::ME0Muon);
620  LogTrace("MuonIdentification") << "Found a corresponding global muon. Set energy, matches and move on";
621  break;
622  }
623  }
624  if (newMuon) {
625  if (goodTrackerMuon || goodRPCMuon || goodGEMMuon || goodME0Muon) {
626  outputMuons->push_back(trackerMuon);
627  } else {
628  LogTrace("MuonIdentification") << "track failed minimal number of muon matches requirement";
629  const reco::CaloMuon& caloMuon = makeCaloMuon(trackerMuon);
630  if (isGoodCaloMuon(caloMuon))
631  caloMuons->push_back(caloMuon);
632  }
633  }
634  }
635  }
636  }
637 
638  // and at last the stand alone muons
640  LogTrace("MuonIdentification") << "Looking for new muons among stand alone muon tracks";
641  const unsigned int nouter = outerTrackCollectionHandle_->size();
642  const unsigned int nsecond =
644  for (unsigned int i = 0; i < nouter + nsecond; ++i) {
645  const auto& outerTrack =
646  (i < nouter) ? outerTrackCollectionHandle_->at(i) : outerTrackSecondaryCollectionHandle_->at(i - nouter);
647  reco::TrackRef refToTrack = (i < nouter) ? reco::TrackRef(outerTrackCollectionHandle_, i)
649 
650  // check if this muon is already in the list of global muons
651  bool newMuon = true;
652  for (auto& muon : *outputMuons) {
653  if (!muon.standAloneMuon().isNull()) {
654  // global muon
655  if (muon.standAloneMuon().get() == &outerTrack ||
656  (muon.standAloneMuon()->extra().isNonnull() &&
657  muon.standAloneMuon()->extra().get() == outerTrack.extra().get())) {
658  newMuon = false;
659  break;
660  }
661  } else {
662  // tracker muon - no direct links to the standalone muon
663  // since we have only a few real muons in an event, matching
664  // the stand alone muon to the tracker muon by DetIds should
665  // be good enough for association. At the end it's up to a
666  // user to redefine the association and what it means. Here
667  // we would like to avoid obvious double counting and we
668  // tolerate a potential miss association
669  if (overlap(muon, outerTrack) > 0) {
670  LogTrace("MuonIdentification") << "Found associated tracker muon. Set a reference and move on";
671  newMuon = false;
672  muon.setOuterTrack(refToTrack);
673  muon.setType(muon.type() | reco::Muon::StandAloneMuon);
674  break;
675  }
676  }
677  }
678  if (newMuon) {
679  LogTrace("MuonIdentification") << "No associated stand alone track is found. Making a muon";
680  outputMuons->push_back(makeMuon(iEvent, iSetup, refToTrack, reco::Muon::OuterTrack));
681  outputMuons->back().setType(reco::Muon::StandAloneMuon);
682  }
683  }
684  }
685 
687  fillArbitrationInfo(outputMuons.get());
688  arbitrateMuons(outputMuons.get(), caloMuons.get());
689  }
690 
691  LogTrace("MuonIdentification") << "Dress up muons if it's necessary";
692 
693  const int nMuons = outputMuons->size();
694 
695  std::vector<reco::MuonTimeExtra> dtTimeColl(nMuons);
696  std::vector<reco::MuonTimeExtra> cscTimeColl(nMuons);
697  std::vector<reco::MuonTimeExtra> combinedTimeColl(nMuons);
698  std::vector<reco::IsoDeposit> trackDepColl(nMuons);
699  std::vector<reco::IsoDeposit> ecalDepColl(nMuons);
700  std::vector<reco::IsoDeposit> hcalDepColl(nMuons);
701  std::vector<reco::IsoDeposit> hoDepColl(nMuons);
702  std::vector<reco::IsoDeposit> jetDepColl(nMuons);
703 
704  // Fill various information
705  for (unsigned int i = 0; i < outputMuons->size(); ++i) {
706  auto& muon = outputMuons->at(i);
707 
708  // Fill muonID
709  if ((fillMatching_ && !muon.isMatchesValid()) || (fillEnergy_ && !muon.isEnergyValid())) {
710  // predict direction based on the muon interaction region location
711  // if it's available
712  if (muon.isStandAloneMuon()) {
715  } else {
717  }
718  } else {
719  LogTrace("MuonIdentification") << "THIS SHOULD NEVER HAPPEN";
720  fillMuonId(iEvent, iSetup, muon);
721  }
722  }
723 
725  // Fill global quality information
726  fillGlbQuality(iEvent, iSetup, muon);
727  }
728  LogDebug("MuonIdentification") << "";
729 
730  if (fillTrackerKink_) {
732  }
733 
735  muon.setCaloCompatibility(muonCaloCompatibility_.evaluate(muon));
736 
737  if (fillIsolation_) {
739  iEvent, iSetup, muon, trackDepColl[i], ecalDepColl[i], hcalDepColl[i], hoDepColl[i], jetDepColl[i]);
740  }
741 
742  // fill timing information
743  reco::MuonTime muonTime;
744  reco::MuonTimeExtra dtTime;
745  reco::MuonTimeExtra cscTime;
746  reco::MuonTime rpcTime;
747  reco::MuonTimeExtra combinedTime;
748 
749  theTimingFiller_->fillTiming(muon, dtTime, cscTime, rpcTime, combinedTime, iEvent, iSetup);
750 
751  muonTime.nDof = combinedTime.nDof();
752  muonTime.timeAtIpInOut = combinedTime.timeAtIpInOut();
753  muonTime.timeAtIpInOutErr = combinedTime.timeAtIpInOutErr();
754  muonTime.timeAtIpOutIn = combinedTime.timeAtIpOutIn();
755  muonTime.timeAtIpOutInErr = combinedTime.timeAtIpOutInErr();
756 
757  muon.setTime(muonTime);
758  muon.setRPCTime(rpcTime);
759  dtTimeColl[i] = dtTime;
760  cscTimeColl[i] = cscTime;
761  combinedTimeColl[i] = combinedTime;
762  }
763 
764  LogTrace("MuonIdentification") << "number of muons produced: " << outputMuons->size();
765  if (fillMatching_) {
766  fillArbitrationInfo(outputMuons.get(), reco::Muon::TrackerMuon);
767  fillArbitrationInfo(outputMuons.get(), reco::Muon::ME0Muon);
768  fillArbitrationInfo(outputMuons.get(), reco::Muon::GEMMuon);
769  }
770  edm::OrphanHandle<reco::MuonCollection> muonHandle = iEvent.put(std::move(outputMuons));
771 
772  auto fillMap = [](auto refH, auto& vec, edm::Event& ev, const std::string& cAl = "") {
774  auto oMap = std::make_unique<MapType>();
775  {
776  typename MapType::Filler filler(*oMap);
777  filler.insert(refH, vec.begin(), vec.end());
778  vec.clear();
779  filler.fill();
780  }
781  ev.put(std::move(oMap), cAl);
782  };
783  fillMap(muonHandle, combinedTimeColl, iEvent, "combined");
784  fillMap(muonHandle, dtTimeColl, iEvent, "dt");
785  fillMap(muonHandle, cscTimeColl, iEvent, "csc");
786 
788  fillMap(muonHandle, trackDepColl, iEvent, trackDepositName_);
789  fillMap(muonHandle, ecalDepColl, iEvent, ecalDepositName_);
790  fillMap(muonHandle, hcalDepColl, iEvent, hcalDepositName_);
791  fillMap(muonHandle, hoDepColl, iEvent, hoDepositName_);
792  fillMap(muonHandle, jetDepColl, iEvent, jetDepositName_);
793  }
794 
795  iEvent.put(std::move(caloMuons));
796 }
797 
799  if (muon.track()->pt() < minPt_ || muon.track()->p() < minP_)
800  return false;
801  if (addExtraSoftMuons_ && muon.pt() < 5 && std::abs(muon.eta()) < 1.5 &&
802  muon.numberOfMatches(reco::Muon::NoArbitration) >= 1)
803  return true;
804  return (muon.numberOfMatches(reco::Muon::NoArbitration) >= minNumberOfMatches_);
805 }
806 
808  if (!caloMuon.isCaloCompatibilityValid() || caloMuon.caloCompatibility() < caloCut_ || caloMuon.p() < minPCaloMuon_)
809  return false;
810  return true;
811 }
812 
814  if (muon.track()->pt() < minPt_ || muon.track()->p() < minP_)
815  return false;
816  if (addExtraSoftMuons_ && muon.pt() < 5 && std::abs(muon.eta()) < 1.5 &&
817  muon.numberOfMatchedRPCLayers(reco::Muon::RPCHitAndTrackArbitration) > 1)
818  return true;
819  return (muon.numberOfMatchedRPCLayers(reco::Muon::RPCHitAndTrackArbitration) > minNumberOfMatches_);
820 }
821 
823  // require GEMMuon to be a TrackerMuon
824  if (!isGoodTrackerMuon(muon))
825  return false;
826  if (muon.track()->pt() < minPt_ || muon.track()->p() < minP_)
827  return false;
828  return (muon.numberOfMatches(reco::Muon::GEMSegmentAndTrackArbitration) +
829  muon.numberOfMatches(reco::Muon::GEMHitAndTrackArbitration)) >= 1;
830 }
831 
833  // need to update min cuts on pt
834  if (muon.track()->p() < minP_)
835  return false;
836  return (muon.numberOfMatches(reco::Muon::ME0SegmentAndTrackArbitration) >= 1);
837 }
838 
840  const edm::EventSetup& iSetup,
841  reco::Muon& aMuon,
843  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId";
844 
845  // perform track - detector association
846  const reco::Track* track = nullptr;
847  if (aMuon.track().isNonnull())
848  track = aMuon.track().get();
849  else if (aMuon.standAloneMuon().isNonnull())
850  track = aMuon.standAloneMuon().get();
851  else
852  throw cms::Exception("FatalError")
853  << "Failed to fill muon id information for a muon with undefined references to tracks";
854 
856 
857  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId :: fillEnergy = " << fillEnergy_;
858 
859  if (fillEnergy_) {
860  reco::MuonEnergy muonEnergy;
861  muonEnergy.em = info.crossedEnergy(TrackDetMatchInfo::EcalRecHits);
862  muonEnergy.had = info.crossedEnergy(TrackDetMatchInfo::HcalRecHits);
863  muonEnergy.ho = info.crossedEnergy(TrackDetMatchInfo::HORecHits);
864  muonEnergy.tower = info.crossedEnergy(TrackDetMatchInfo::TowerTotal);
865  muonEnergy.emS9 = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits, 1); // 3x3 energy
866  muonEnergy.emS25 = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits, 2); // 5x5 energy
867  muonEnergy.hadS9 = info.nXnEnergy(TrackDetMatchInfo::HcalRecHits, 1); // 3x3 energy
868  muonEnergy.hoS9 = info.nXnEnergy(TrackDetMatchInfo::HORecHits, 1); // 3x3 energy
869  muonEnergy.towerS9 = info.nXnEnergy(TrackDetMatchInfo::TowerTotal, 1); // 3x3 energy
871  muonEnergy.crossedHadRecHits.clear();
872  for (auto hit : info.crossedHcalRecHits) {
874  mhit.energy = hit->energy();
875  mhit.chi2 = hit->chi2();
876  mhit.time = hit->time();
877  mhit.detId = hit->id();
878  muonEnergy.crossedHadRecHits.push_back(mhit);
879  }
880  }
881  muonEnergy.ecal_position = info.trkGlobPosAtEcal;
882  muonEnergy.hcal_position = info.trkGlobPosAtHcal;
883  if (!info.crossedEcalIds.empty())
884  muonEnergy.ecal_id = info.crossedEcalIds.front();
885  if (!info.crossedHcalIds.empty())
886  muonEnergy.hcal_id = info.crossedHcalIds.front();
887  // find maximal energy depositions and their time
888  DetId emMaxId = info.findMaxDeposition(TrackDetMatchInfo::EcalRecHits, 2); // max energy deposit in 5x5 shape
889  for (const auto& hit : info.ecalRecHits) {
890  if (hit->id() != emMaxId)
891  continue;
892  muonEnergy.emMax = hit->energy();
893  muonEnergy.ecal_time = hit->time();
894  }
895  DetId hadMaxId = info.findMaxDeposition(TrackDetMatchInfo::HcalRecHits, 1); // max energy deposit in 3x3 shape
896  for (const auto& hit : info.hcalRecHits) {
897  if (hit->id() != hadMaxId)
898  continue;
899  muonEnergy.hadMax = hit->energy();
900  muonEnergy.hcal_time = hit->time();
901  }
902  aMuon.setCalEnergy(muonEnergy);
903  }
904  if (!fillMatching_ && !aMuon.isTrackerMuon() && !aMuon.isRPCMuon() && !aMuon.isGEMMuon())
905  return;
906 
907  // fill muon match info
908  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId :: fill muon match info ";
909  std::vector<reco::MuonChamberMatch> muonChamberMatches;
910  unsigned int nubmerOfMatchesAccordingToTrackAssociator = 0;
911  for (const auto& chamber : info.chambers) {
912  if (chamber.id.subdetId() == MuonSubdetId::RPC && rpcHitHandle_.isValid())
913  continue; // Skip RPC chambers, they are taken care of below)
914  if (chamber.id.subdetId() == MuonSubdetId::GEM && gemHitHandle_.isValid() &&
915  GEMDetId(chamber.id.rawId()).station() != 0)
916  continue; // Skip GE1/1 and 2/1 chambers, they are taken care of below)
917  reco::MuonChamberMatch matchedChamber;
918 
919  const auto& lErr = chamber.tState.localError();
920  const auto& lPos = chamber.tState.localPosition();
921  const auto& lDir = chamber.tState.localDirection();
922 
923  const auto& localError = lErr.positionError();
924  matchedChamber.x = lPos.x();
925  matchedChamber.y = lPos.y();
926  matchedChamber.xErr = sqrt(localError.xx());
927  matchedChamber.yErr = sqrt(localError.yy());
928 
929  matchedChamber.dXdZ = lDir.z() != 0 ? lDir.x() / lDir.z() : 9999;
930  matchedChamber.dYdZ = lDir.z() != 0 ? lDir.y() / lDir.z() : 9999;
931  // DANGEROUS - compiler cannot guaranty parameters ordering
932  AlgebraicSymMatrix55 trajectoryCovMatrix = lErr.matrix();
933  matchedChamber.dXdZErr = trajectoryCovMatrix(1, 1) > 0 ? sqrt(trajectoryCovMatrix(1, 1)) : 0;
934  matchedChamber.dYdZErr = trajectoryCovMatrix(2, 2) > 0 ? sqrt(trajectoryCovMatrix(2, 2)) : 0;
935 
936  matchedChamber.edgeX = chamber.localDistanceX;
937  matchedChamber.edgeY = chamber.localDistanceY;
938 
939  matchedChamber.id = chamber.id;
940 
942  theShowerDigiFiller_->fill(matchedChamber);
943  } else {
944  theShowerDigiFiller_->fillDefault(matchedChamber);
945  }
946 
947  if (!chamber.segments.empty())
948  ++nubmerOfMatchesAccordingToTrackAssociator;
949 
950  // fill segments
951  for (const auto& segment : chamber.segments) {
952  reco::MuonSegmentMatch matchedSegment;
953  matchedSegment.x = segment.segmentLocalPosition.x();
954  matchedSegment.y = segment.segmentLocalPosition.y();
955  matchedSegment.dXdZ =
956  segment.segmentLocalDirection.z() ? segment.segmentLocalDirection.x() / segment.segmentLocalDirection.z() : 0;
957  matchedSegment.dYdZ =
958  segment.segmentLocalDirection.z() ? segment.segmentLocalDirection.y() / segment.segmentLocalDirection.z() : 0;
959  matchedSegment.xErr = segment.segmentLocalErrorXX > 0 ? sqrt(segment.segmentLocalErrorXX) : 0;
960  matchedSegment.yErr = segment.segmentLocalErrorYY > 0 ? sqrt(segment.segmentLocalErrorYY) : 0;
961  matchedSegment.dXdZErr = segment.segmentLocalErrorDxDz > 0 ? sqrt(segment.segmentLocalErrorDxDz) : 0;
962  matchedSegment.dYdZErr = segment.segmentLocalErrorDyDz > 0 ? sqrt(segment.segmentLocalErrorDyDz) : 0;
963  matchedSegment.t0 = segment.t0;
964  matchedSegment.mask = 0;
965  matchedSegment.dtSegmentRef = segment.dtSegmentRef;
966  matchedSegment.cscSegmentRef = segment.cscSegmentRef;
967  matchedSegment.gemSegmentRef = segment.gemSegmentRef;
968  matchedSegment.me0SegmentRef = segment.me0SegmentRef;
969  matchedSegment.hasZed_ = segment.hasZed;
970  matchedSegment.hasPhi_ = segment.hasPhi;
971  // test segment
972  bool matchedX = false;
973  bool matchedY = false;
974  LogTrace("MuonIdentification") << " matching local x, segment x: " << matchedSegment.x
975  << ", chamber x: " << matchedChamber.x << ", max: " << maxAbsDx_;
976  LogTrace("MuonIdentification") << " matching local y, segment y: " << matchedSegment.y
977  << ", chamber y: " << matchedChamber.y << ", max: " << maxAbsDy_;
978  const double matchedSegChDx = std::abs(matchedSegment.x - matchedChamber.x);
979  const double matchedSegChDy = std::abs(matchedSegment.y - matchedChamber.y);
980  if (matchedSegment.xErr > 0 && matchedChamber.xErr > 0)
981  LogTrace("MuonIdentification") << " xpull: "
982  << matchedSegChDx / std::sqrt(std::pow(matchedSegment.xErr, 2) +
983  std::pow(matchedChamber.xErr, 2));
984  if (matchedSegment.yErr > 0 && matchedChamber.yErr > 0)
985  LogTrace("MuonIdentification") << " ypull: "
986  << matchedSegChDy / std::sqrt(std::pow(matchedSegment.yErr, 2) +
987  std::pow(matchedChamber.yErr, 2));
988 
989  if (matchedSegChDx < maxAbsDx_)
990  matchedX = true;
991  else if (matchedSegment.xErr > 0 && matchedChamber.xErr > 0) {
992  const double invMatchedSegChPullX2 = std::pow(matchedSegment.xErr, 2) + std::pow(matchedChamber.xErr, 2);
993  if (matchedSegChDx * matchedSegChDx < maxAbsPullX2_ * invMatchedSegChPullX2)
994  matchedX = true;
995  }
996  if (matchedSegChDy < maxAbsDy_)
997  matchedY = true;
998  else if (matchedSegment.yErr > 0 && matchedChamber.yErr > 0) {
999  const double invMatchedSegChPullY2 = std::pow(matchedSegment.yErr, 2) + std::pow(matchedChamber.yErr, 2);
1000  if (matchedSegChDy * matchedSegChDy < maxAbsPullY2_ * invMatchedSegChPullY2)
1001  matchedY = true;
1002  }
1003  if (matchedX && matchedY) {
1004  if (matchedChamber.id.subdetId() == MuonSubdetId::ME0)
1005  matchedChamber.me0Matches.push_back(matchedSegment);
1006  else if (matchedChamber.id.subdetId() == MuonSubdetId::GEM)
1007  matchedChamber.gemMatches.push_back(matchedSegment);
1008  else
1009  matchedChamber.segmentMatches.push_back(matchedSegment);
1010  }
1011  }
1012  muonChamberMatches.push_back(matchedChamber);
1013  }
1014 
1015  // Fill RPC info
1016  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId :: fill RPC info";
1017  if (rpcHitHandle_.isValid()) {
1018  for (const auto& chamber : info.chambers) {
1019  if (chamber.id.subdetId() != MuonSubdetId::RPC)
1020  continue; // Consider RPC chambers only
1021  const auto& lErr = chamber.tState.localError();
1022  const auto& lPos = chamber.tState.localPosition();
1023  const auto& lDir = chamber.tState.localDirection();
1024 
1025  reco::MuonChamberMatch matchedChamber;
1026 
1027  LocalError localError = lErr.positionError();
1028  matchedChamber.x = lPos.x();
1029  matchedChamber.y = lPos.y();
1030  matchedChamber.xErr = sqrt(localError.xx());
1031  matchedChamber.yErr = sqrt(localError.yy());
1032 
1033  matchedChamber.dXdZ = lDir.z() != 0 ? lDir.x() / lDir.z() : 9999;
1034  matchedChamber.dYdZ = lDir.z() != 0 ? lDir.y() / lDir.z() : 9999;
1035  // DANGEROUS - compiler cannot guaranty parameters ordering
1036  AlgebraicSymMatrix55 trajectoryCovMatrix = lErr.matrix();
1037  matchedChamber.dXdZErr = trajectoryCovMatrix(1, 1) > 0 ? sqrt(trajectoryCovMatrix(1, 1)) : 0;
1038  matchedChamber.dYdZErr = trajectoryCovMatrix(2, 2) > 0 ? sqrt(trajectoryCovMatrix(2, 2)) : 0;
1039 
1040  matchedChamber.edgeX = chamber.localDistanceX;
1041  matchedChamber.edgeY = chamber.localDistanceY;
1042 
1043  theShowerDigiFiller_->fillDefault(matchedChamber);
1044 
1045  matchedChamber.id = chamber.id;
1046 
1047  for (const auto& rpcRecHit : *rpcHitHandle_) {
1048  reco::MuonRPCHitMatch rpcHitMatch;
1049 
1050  if (rpcRecHit.rawId() != chamber.id.rawId())
1051  continue;
1052 
1053  rpcHitMatch.x = rpcRecHit.localPosition().x();
1054  rpcHitMatch.mask = 0;
1055  rpcHitMatch.bx = rpcRecHit.BunchX();
1056 
1057  const double absDx = std::abs(rpcRecHit.localPosition().x() - chamber.tState.localPosition().x());
1058  if (absDx <= 20 or absDx * absDx <= 16 * localError.xx())
1059  matchedChamber.rpcMatches.push_back(rpcHitMatch);
1060  }
1061 
1062  muonChamberMatches.push_back(matchedChamber);
1063  }
1064  }
1065 
1066  // Fill GEM info
1067  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId :: fill GEM info";
1068  if (gemHitHandle_.isValid()) {
1069  for (const auto& chamber : info.chambers) {
1070  // only GE1/1 and 2/1 are for rechits, reject station 0 and segments (layer==0 for GEMSegment)
1071  if (chamber.id.subdetId() != MuonSubdetId::GEM || GEMDetId(chamber.id.rawId()).station() == 0 ||
1072  GEMDetId(chamber.id.rawId()).layer() == 0)
1073  continue; // Consider GEM chambers only
1074  const auto& lErr = chamber.tState.localError();
1075  const auto& lPos = chamber.tState.localPosition();
1076  const auto& lDir = chamber.tState.localDirection();
1077 
1078  reco::MuonChamberMatch matchedChamber;
1079 
1080  LocalError localError = lErr.positionError();
1081  matchedChamber.x = lPos.x();
1082  matchedChamber.y = lPos.y();
1083  matchedChamber.xErr = sqrt(localError.xx());
1084  matchedChamber.yErr = sqrt(localError.yy());
1085 
1086  matchedChamber.dXdZ = lDir.z() != 0 ? lDir.x() / lDir.z() : 9999;
1087  matchedChamber.dYdZ = lDir.z() != 0 ? lDir.y() / lDir.z() : 9999;
1088  // DANGEROUS - compiler cannot guaranty parameters ordering
1089  AlgebraicSymMatrix55 trajectoryCovMatrix = lErr.matrix();
1090  matchedChamber.dXdZErr = trajectoryCovMatrix(1, 1) > 0 ? sqrt(trajectoryCovMatrix(1, 1)) : 0;
1091  matchedChamber.dYdZErr = trajectoryCovMatrix(2, 2) > 0 ? sqrt(trajectoryCovMatrix(2, 2)) : 0;
1092 
1093  matchedChamber.edgeX = chamber.localDistanceX;
1094  matchedChamber.edgeY = chamber.localDistanceY;
1095 
1096  theShowerDigiFiller_->fillDefault(matchedChamber);
1097 
1098  matchedChamber.id = chamber.id;
1099 
1100  for (const auto& gemRecHit : *gemHitHandle_) {
1101  reco::MuonGEMHitMatch gemHitMatch;
1102 
1103  if (GEMDetId(gemRecHit.gemId().region(),
1104  gemRecHit.gemId().ring(),
1105  gemRecHit.gemId().station(),
1106  gemRecHit.gemId().layer(),
1107  gemRecHit.gemId().chamber(),
1108  0)
1109  .rawId() != chamber.id.rawId())
1110  continue;
1111 
1112  gemHitMatch.x = gemRecHit.localPosition().x();
1113  gemHitMatch.mask = 0;
1114  gemHitMatch.bx = gemRecHit.BunchX();
1115 
1116  const double absDx = std::abs(gemRecHit.localPosition().x() - chamber.tState.localPosition().x());
1117  if (absDx <= 5 or absDx * absDx <= 16 * localError.xx())
1118  matchedChamber.gemHitMatches.push_back(gemHitMatch);
1119  }
1120 
1121  muonChamberMatches.push_back(matchedChamber);
1122  }
1123  }
1124 
1125  aMuon.setMatches(muonChamberMatches);
1126 
1127  LogTrace("MuonIdentification") << "number of muon chambers: " << aMuon.matches().size() << "\n"
1128  << "number of chambers with segments according to the associator requirements: "
1129  << nubmerOfMatchesAccordingToTrackAssociator;
1130  LogTrace("MuonIdentification") << "number of segment matches with the producer requirements: "
1132 
1133  // fillTime( iEvent, iSetup, aMuon );
1134 }
1135 
1138  // arbitrate TrackerMuons
1139  // if a muon was exclusively TrackerMuon check if it can be a calo muon
1140  for (reco::MuonCollection::iterator muon = muons->begin(); muon != muons->end();) {
1141  if (muon->isTrackerMuon()) {
1142  if (muon->numberOfMatches(arbitration) < minNumberOfMatches_) {
1143  // TrackerMuon failed arbitration
1144  // If not any other base type - erase the element
1145  // (PFMuon is not a base type)
1146  // GEMMuon should be a subset of TrackerMuon, so don't count it either
1148  if ((muon->type() & (~mask)) == 0) {
1149  const reco::CaloMuon& caloMuon = makeCaloMuon(*muon);
1150  if (isGoodCaloMuon(caloMuon))
1151  caloMuons->push_back(caloMuon);
1152  muon = muons->erase(muon);
1153  continue;
1154  } else {
1155  muon->setType(muon->type() & (~(reco::Muon::TrackerMuon | reco::Muon::GEMMuon)));
1156  }
1157  }
1158  }
1159  muon++;
1160  }
1161 }
1162 
1163 void MuonIdProducer::fillArbitrationInfo(reco::MuonCollection* pOutputMuons, unsigned int muonType) {
1164  //
1165  // apply segment flags
1166  //
1167  std::vector<std::pair<reco::MuonChamberMatch*, reco::MuonSegmentMatch*> > chamberPairs; // for chamber segment sorting
1168  std::vector<std::pair<reco::MuonChamberMatch*, reco::MuonSegmentMatch*> > stationPairs; // for station segment sorting
1169  std::vector<std::pair<reco::MuonChamberMatch*, reco::MuonSegmentMatch*> >
1170  arbitrationPairs; // for muon segment arbitration
1171 
1172  // muonIndex1
1173  for (unsigned int muonIndex1 = 0; muonIndex1 < pOutputMuons->size(); ++muonIndex1) {
1174  auto& muon1 = pOutputMuons->at(muonIndex1);
1175  // chamberIter1
1176  for (auto& chamber1 : muon1.matches()) {
1177  // segmentIter1
1178  std::vector<reco::MuonSegmentMatch>* segmentMatches1 = getSegmentMatches(chamber1, muonType);
1179 
1180  if (segmentMatches1->empty())
1181  continue;
1182  chamberPairs.clear();
1183 
1184  for (auto& segment1 : *segmentMatches1) {
1185  chamberPairs.push_back(std::make_pair(&chamber1, &segment1));
1186  if (!segment1.isMask()) // has not yet been arbitrated
1187  {
1188  arbitrationPairs.clear();
1189  arbitrationPairs.push_back(std::make_pair(&chamber1, &segment1));
1190 
1191  // find identical segments with which to arbitrate
1192  // tracker muons only
1193  if (muon1.type() & muonType) {
1194  // muonIndex2
1195  for (unsigned int muonIndex2 = muonIndex1 + 1; muonIndex2 < pOutputMuons->size(); ++muonIndex2) {
1196  auto& muon2 = pOutputMuons->at(muonIndex2);
1197  // tracker muons only
1198  if (!(muon2.type() & muonType))
1199  continue;
1200  // chamberIter2
1201  for (auto& chamber2 : muon2.matches()) {
1202  // segmentIter2
1203  std::vector<reco::MuonSegmentMatch>* segmentMatches2 = getSegmentMatches(chamber2, muonType);
1204  for (auto& segment2 : *segmentMatches2) {
1205  if (segment2.isMask())
1206  continue; // has already been arbitrated
1207  if (approxEqual(segment2.x, segment1.x) && approxEqual(segment2.y, segment1.y) &&
1208  approxEqual(segment2.dXdZ, segment1.dXdZ) && approxEqual(segment2.dYdZ, segment1.dYdZ) &&
1209  approxEqual(segment2.xErr, segment1.xErr) && approxEqual(segment2.yErr, segment1.yErr) &&
1210  approxEqual(segment2.dXdZErr, segment1.dXdZErr) &&
1211  approxEqual(segment2.dYdZErr, segment1.dYdZErr)) {
1212  arbitrationPairs.push_back(std::make_pair(&chamber2, &segment2));
1213  }
1214  } // segmentIter2
1215  } // chamberIter2
1216  } // muonIndex2
1217  }
1218 
1219  // arbitration segment sort
1220  if (arbitrationPairs.empty())
1221  continue; // this should never happen
1222  if (arbitrationPairs.size() == 1) {
1223  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDRSlope);
1224  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDXSlope);
1225  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDR);
1226  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDX);
1227  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::Arbitrated);
1228  } else {
1229  sort(arbitrationPairs.begin(),
1230  arbitrationPairs.end(),
1232  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDRSlope);
1233  sort(arbitrationPairs.begin(),
1234  arbitrationPairs.end(),
1236  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDXSlope);
1237  sort(arbitrationPairs.begin(),
1238  arbitrationPairs.end(),
1240  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDR);
1241  sort(arbitrationPairs.begin(),
1242  arbitrationPairs.end(),
1244  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDX);
1245  for (auto& ap : arbitrationPairs) {
1246  ap.second->setMask(reco::MuonSegmentMatch::Arbitrated);
1247  }
1248  }
1249  }
1250 
1251  // setup me1a cleaning for later
1252  if (muonType == reco::Muon::TrackerMuon && chamber1.id.subdetId() == MuonSubdetId::CSC && arbClean_ &&
1253  CSCDetId(chamber1.id).ring() == 4) {
1254  for (auto& segment2 : chamber1.segmentMatches) {
1255  if (segment1.cscSegmentRef.isNull() || segment2.cscSegmentRef.isNull())
1256  continue;
1257  if (meshAlgo_->isDuplicateOf(segment1.cscSegmentRef, segment2.cscSegmentRef) &&
1258  (segment2.mask & 0x1e0000) && (segment1.mask & 0x1e0000)) {
1260  //if the track has lost the segment already through normal arbitration no need to do it again.
1261  }
1262  }
1263  } // mark all ME1/a duplicates that this track owns
1264 
1265  } // segmentIter1
1266 
1267  // chamber segment sort
1268  if (chamberPairs.empty())
1269  continue; // this should never happen
1270  if (chamberPairs.size() == 1) {
1271  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDRSlope);
1272  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDXSlope);
1273  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDR);
1274  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDX);
1275  } else {
1276  sort(chamberPairs.begin(),
1277  chamberPairs.end(),
1279  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDRSlope);
1280  sort(chamberPairs.begin(),
1281  chamberPairs.end(),
1283  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDXSlope);
1284  sort(chamberPairs.begin(),
1285  chamberPairs.end(),
1287  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDR);
1288  sort(chamberPairs.begin(),
1289  chamberPairs.end(),
1291  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDX);
1292  }
1293  } // chamberIter1
1294 
1295  // station segment sort
1296  for (int stationIndex = 1; stationIndex < 5; ++stationIndex) {
1297  for (int detectorIndex = 1; detectorIndex <= 5;
1298  ++detectorIndex) // 1-5, as in DataFormats/MuonDetId/interface/MuonSubdetId.h
1299  {
1300  stationPairs.clear();
1301 
1302  // chamberIter
1303  for (auto& chamber : muon1.matches()) {
1304  if (!(chamber.station() == stationIndex && chamber.detector() == detectorIndex))
1305  continue;
1306  std::vector<reco::MuonSegmentMatch>* segmentMatches = getSegmentMatches(chamber, muonType);
1307  if (segmentMatches->empty())
1308  continue;
1309 
1310  for (auto& segment : *segmentMatches) {
1311  stationPairs.push_back(std::make_pair(&chamber, &segment));
1312  }
1313  } // chamberIter
1314 
1315  if (stationPairs.empty())
1316  continue; // this may very well happen
1317  if (stationPairs.size() == 1) {
1318  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDRSlope);
1319  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDXSlope);
1320  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDR);
1321  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDX);
1322  } else {
1323  sort(stationPairs.begin(),
1324  stationPairs.end(),
1326  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDRSlope);
1327  sort(stationPairs.begin(),
1328  stationPairs.end(),
1330  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDXSlope);
1331  sort(stationPairs.begin(),
1332  stationPairs.end(),
1334  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDR);
1335  sort(stationPairs.begin(),
1336  stationPairs.end(),
1338  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDX);
1339  }
1340  }
1341  }
1342 
1343  } // muonIndex1
1344 
1345  if (arbClean_) {
1346  // clear old mesh, create and prune new mesh!
1347  meshAlgo_->clearMesh();
1348  meshAlgo_->runMesh(pOutputMuons);
1349  }
1350 }
1351 
1353  const edm::EventSetup& iSetup,
1354  reco::Muon& aMuon,
1355  reco::IsoDeposit& trackDep,
1356  reco::IsoDeposit& ecalDep,
1357  reco::IsoDeposit& hcalDep,
1358  reco::IsoDeposit& hoDep,
1359  reco::IsoDeposit& jetDep) {
1360  const reco::Track* track = nullptr;
1361  if (aMuon.track().isNonnull())
1362  track = aMuon.track().get();
1363  else if (aMuon.standAloneMuon().isNonnull())
1364  track = aMuon.standAloneMuon().get();
1365  else
1366  throw cms::Exception("FatalError")
1367  << "Failed to compute muon isolation information for a muon with undefined references to tracks";
1368 
1369  reco::MuonIsolation isoR03, isoR05;
1370 
1371  // get deposits
1372  reco::IsoDeposit depTrk = muIsoExtractorTrack_->deposit(iEvent, iSetup, *track);
1373  std::vector<reco::IsoDeposit> caloDeps = muIsoExtractorCalo_->deposits(iEvent, iSetup, *track);
1374  reco::IsoDeposit depJet = muIsoExtractorJet_->deposit(iEvent, iSetup, *track);
1375 
1376  if (caloDeps.size() != 3) {
1377  LogTrace("MuonIdentification") << "Failed to fill vector of calorimeter isolation deposits!";
1378  return;
1379  }
1380 
1381  reco::IsoDeposit depEcal = caloDeps.at(0);
1382  reco::IsoDeposit depHcal = caloDeps.at(1);
1383  reco::IsoDeposit depHo = caloDeps.at(2);
1384 
1385  //no need to copy outside if we don't write them
1386  if (writeIsoDeposits_) {
1387  trackDep = depTrk;
1388  ecalDep = depEcal;
1389  hcalDep = depHcal;
1390  hoDep = depHo;
1391  jetDep = depJet;
1392  }
1393 
1394  isoR03.sumPt = depTrk.depositWithin(0.3);
1395  isoR03.emEt = depEcal.depositWithin(0.3);
1396  isoR03.hadEt = depHcal.depositWithin(0.3);
1397  isoR03.hoEt = depHo.depositWithin(0.3);
1398  isoR03.nTracks = depTrk.depositAndCountWithin(0.3).second;
1399  isoR03.nJets = depJet.depositAndCountWithin(0.3).second;
1400  isoR03.trackerVetoPt = depTrk.candEnergy();
1401  isoR03.emVetoEt = depEcal.candEnergy();
1402  isoR03.hadVetoEt = depHcal.candEnergy();
1403  isoR03.hoVetoEt = depHo.candEnergy();
1404 
1405  isoR05.sumPt = depTrk.depositWithin(0.5);
1406  isoR05.emEt = depEcal.depositWithin(0.5);
1407  isoR05.hadEt = depHcal.depositWithin(0.5);
1408  isoR05.hoEt = depHo.depositWithin(0.5);
1409  isoR05.nTracks = depTrk.depositAndCountWithin(0.5).second;
1410  isoR05.nJets = depJet.depositAndCountWithin(0.5).second;
1411  isoR05.trackerVetoPt = depTrk.candEnergy();
1412  isoR05.emVetoEt = depEcal.candEnergy();
1413  isoR05.hadVetoEt = depHcal.candEnergy();
1414  isoR05.hoVetoEt = depHo.candEnergy();
1415 
1416  aMuon.setIsolation(isoR03, isoR05);
1417 }
1418 
1420  const double energy = std::sqrt(track.p() * track.p() + 0.105658369 * 0.105658369);
1421  const math::XYZTLorentzVector p4(track.px(), track.py(), track.pz(), energy);
1422  return reco::Muon(track.charge(), p4, track.vertex());
1423 }
1424 
1426  double phi = 0;
1427  if (id.subdetId() == MuonSubdetId::DT) { // DT
1428  DTChamberId muonId(id.rawId());
1429  if (muonId.sector() <= 12)
1430  phi = (muonId.sector() - 1) / 6. * M_PI;
1431  if (muonId.sector() == 13)
1432  phi = 3 / 6. * M_PI;
1433  if (muonId.sector() == 14)
1434  phi = 9 / 6. * M_PI;
1435  }
1436  if (id.subdetId() == MuonSubdetId::CSC) { // CSC
1437  CSCDetId muonId(id.rawId());
1438  phi = M_PI / 4 + (muonId.triggerSector() - 1) / 3. * M_PI;
1439  }
1440  if (phi > M_PI)
1441  phi -= 2 * M_PI;
1442  return phi;
1443 }
1444 
1446  if (muon.isStandAloneMuon())
1447  return muon.standAloneMuon()->innerPosition().phi();
1448  // the rest is tracker muon only
1449  if (muon.matches().empty()) {
1450  if (muon.innerTrack().isAvailable() && muon.innerTrack()->extra().isAvailable())
1451  return muon.innerTrack()->outerPosition().phi();
1452  else
1453  return muon.phi(); // makes little sense, but what else can I use
1454  }
1455  return sectorPhi(muon.matches().at(0).id);
1456 }
1457 
1460  aMuon.setCombinedQuality((*glbQualHandle_)[aMuon.combinedMuon()]);
1461  }
1462 
1463  LogDebug("MuonIdentification") << "tkChiVal " << aMuon.combinedQuality().trkRelChi2;
1464 }
1465 
1467  // skip muons with no tracks
1468  if (aMuon.innerTrack().isNull())
1469  return;
1470  // get quality from muon if already there, otherwise make empty one
1472  // fill it
1473  const bool filled = trackerKinkFinder_->fillTrkKink(quality, *aMuon.innerTrack());
1474  // if quality was there, or if we filled it, commit to the muon
1475  if (filled || aMuon.isQualityValid())
1476  aMuon.setCombinedQuality(quality);
1477 }
1478 
1480  const bool trackBAD = links->trackerTrack().isNull();
1481  const bool staBAD = links->standAloneTrack().isNull();
1482  const bool glbBAD = links->globalTrack().isNull();
1483  if (trackBAD || staBAD || glbBAD) {
1484  edm::LogWarning("muonIDbadLinks") << "Global muon links to constituent tracks are invalid: trkBad " << trackBAD
1485  << " standaloneBad " << staBAD << " globalBad " << glbBAD
1486  << ". There should be no such object. Muon is skipped.";
1487  return false;
1488  }
1489  return true;
1490 }
1491 
1494  desc.setAllowAnything();
1495 
1496  desc.add<bool>("arbitrateTrackerMuons", false);
1497  desc.add<bool>("storeCrossedHcalRecHits", false);
1498  desc.add<bool>("fillShowerDigis", false);
1499  desc.ifValue(
1500  edm::ParameterDescription<bool>("selectHighPurity", false, true),
1501  true >> (edm::ParameterDescription<edm::InputTag>("pvInputTag", edm::InputTag("offlinePrimaryVertices"), true)) or
1502  false >> (edm::ParameterDescription<edm::InputTag>("pvInputTag", edm::InputTag(""), true)));
1503 
1504  edm::ParameterSetDescription descTrkAsoPar;
1505  descTrkAsoPar.add<edm::InputTag>("GEMSegmentCollectionLabel", edm::InputTag("gemSegments"));
1506  descTrkAsoPar.add<edm::InputTag>("ME0SegmentCollectionLabel", edm::InputTag("me0Segments"));
1507  descTrkAsoPar.add<bool>("useGEM", false);
1508  descTrkAsoPar.add<bool>("useME0", false);
1509  descTrkAsoPar.add<bool>("preselectMuonTracks", false);
1510  descTrkAsoPar.add<edm::InputTag>("RPCHitCollectionLabel", edm::InputTag("rpcRecHits"));
1511  descTrkAsoPar.add<edm::InputTag>("GEMHitCollectionLabel", edm::InputTag("gemRecHits"));
1512  descTrkAsoPar.add<edm::InputTag>("ME0HitCollectionLabel", edm::InputTag("me0RecHits"));
1513  descTrkAsoPar.setAllowAnything();
1514  desc.add<edm::ParameterSetDescription>("TrackAssociatorParameters", descTrkAsoPar);
1515 
1517  descJet.setAllowAnything();
1518  descJet.add<edm::ParameterSetDescription>("TrackAssociatorParameters", descTrkAsoPar);
1519  desc.add<edm::ParameterSetDescription>("JetExtractorPSet", descJet);
1520 
1522  descCalo.setAllowAnything();
1523  descCalo.add<edm::ParameterSetDescription>("TrackAssociatorParameters", descTrkAsoPar);
1524  desc.add<edm::ParameterSetDescription>("CaloExtractorPSet", descCalo);
1525 
1526  descriptions.addDefault(desc);
1527 }
std::string hoDepositName_
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
float hadEt
hcal sum-Et
Definition: MuonIsolation.h:8
MuonQuality combinedQuality() const
get energy deposition information
Definition: Muon.h:119
static const unsigned int BelongsToTrackByME1aClean
std::string jetDepositName_
bool isGoodRPCMuon(const reco::Muon &muon)
bool approxEqual(const double a, const double b, const double tol=1E-3) const
edm::EDGetTokenT< reco::TrackCollection > innerTrackCollectionToken_
reco::Muon makeMuon(edm::Event &iEvent, const edm::EventSetup &iSetup, const reco::TrackRef &track, TrackType type)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
GEMSegmentRef gemSegmentRef
static const unsigned int GlobalMuon
Definition: Muon.h:289
void fillMuonIsolation(edm::Event &, const edm::EventSetup &, reco::Muon &aMuon, reco::IsoDeposit &trackDep, reco::IsoDeposit &ecalDep, reco::IsoDeposit &hcalDep, reco::IsoDeposit &hoDep, reco::IsoDeposit &jetDep)
edm::EDGetTokenT< edm::ValueMap< reco::MuonQuality > > glbQualToken_
DTRecSegment4DRef dtSegmentRef
static const TGPicture * info(bool iBackgroundIsBlack)
TrackRef combinedMuon() const override
reference to a stand-alone muon Track
Definition: Muon.h:52
static constexpr int GEM
Definition: MuonSubdetId.h:14
std::vector< reco::MuonSegmentMatch > gemMatches
static bool crossedIP(const reco::Track &track)
float sumPt
sum-pt of tracks
Definition: MuonIsolation.h:6
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
static void truthMatchMuon(const edm::Event &iEvent, const GlobalTrackingGeometry &iGeometry, reco::Muon &aMuon)
TrackDetectorAssociator trackAssociator_
CSCSegmentRef cscSegmentRef
std::unique_ptr< MuonKinkFinder > trackerKinkFinder_
static const unsigned int Arbitrated
segment mask flags
void fillMuonId(edm::Event &, const edm::EventSetup &, reco::Muon &, TrackDetectorAssociator::Direction direction=TrackDetectorAssociator::InsideOut)
void setAllowAnything()
allow any parameter label/value pairs
edm::Handle< reco::MuonTrackLinksCollection > linkCollectionHandle_
edm::EDGetTokenT< RPCRecHitCollection > rpcHitToken_
const edm::ESGetToken< Propagator, TrackingComponentsRecord > propagatorToken_
bool isGoodGEMMuon(const reco::Muon &muon)
int overlap(const reco::Muon &muon, const reco::Track &track)
bool fillCaloCompatibility_
std::string trackDepositName_
void fillArbitrationInfo(reco::MuonCollection *, unsigned int muonType=reco::Muon::TrackerMuon)
T const * product() const
Definition: Handle.h:70
constexpr bool isUninitialized() const noexcept
Definition: EDGetToken.h:104
std::vector< reco::MuonGEMHitMatch > gemHitMatches
std::vector< CaloMuon > CaloMuonCollection
collection of Muon objects
Definition: MuonFwd.h:27
const edm::ESGetToken< CSCGeometry, MuonGeometryRecord > geomTokenRun_
void loadParameters(const edm::ParameterSet &, edm::ConsumesCollector &)
void produce(edm::Event &, const edm::EventSetup &) override
float hadVetoEt
hcal sum-et in the veto region in r-phi
Definition: MuonIsolation.h:14
float emS9
energy deposited in 3x3 ECAL crystal shape around central crystal
Definition: MuonEnergy.h:28
double p() const
momentum vector magnitude
Definition: CaloMuon.h:54
double evaluate(const reco::Muon &)
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
#define M_PI_2
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
constexpr int pow(int x)
Definition: conifer.h:24
MuonCaloCompatibility muonCaloCompatibility_
static const unsigned int BestInStationByDRSlope
float timeAtIpOutInErr() const
Definition: MuonTimeExtra.h:49
edm::EDGetTokenT< reco::TrackToTrackMap > pickyCollectionToken_
static std::string toStr(const ICTypeKey k)
bool arbitrateTrackerMuons_
static const unsigned int BelongsToTrackByDXSlope
void setCalEnergy(const MuonEnergy &calEnergy)
set energy deposition information
Definition: Muon.h:108
void fillGlbQuality(edm::Event &, const edm::EventSetup &, reco::Muon &aMuon)
TrackRef track() const override
reference to a Track
Definition: Muon.h:46
float timeAtIpOutInErr
Definition: MuonTime.h:17
float trkRelChi2
chi2 value for the inner track stub with respect to the global track
Definition: MuonQuality.h:15
std::unique_ptr< reco::isodeposit::IsoDepositExtractor > muIsoExtractorTrack_
float towerS9
total energy in 3x3 tower shape
Definition: MuonEnergy.h:22
static const unsigned int BestInStationByDR
constexpr uint32_t mask
Definition: gpuClustering.h:26
float timeAtIpInOutErr() const
Definition: MuonTimeExtra.h:44
float timeAtIpInOut() const
Definition: MuonTimeExtra.h:43
std::vector< Muon > MuonCollection
collection of Muon objects
Definition: MuonFwd.h:9
bool isTrackerMuon() const override
Definition: Muon.h:304
std::unique_ptr< MuonTimingFiller > theTimingFiller_
#define LogTrace(id)
float ecal_time
Calorimeter timing.
Definition: MuonEnergy.h:47
float ho
energy deposited in crossed HO towers
Definition: MuonEnergy.h:42
virtual void setTunePBestTrack(MuonTrackType muonType)
Definition: Muon.h:88
double phiOfMuonInteractionRegion(const reco::Muon &muon) const
edm::ESGetToken< GlobalTrackingGeometry, GlobalTrackingGeometryRecord > globalGeomToken_
std::unique_ptr< reco::isodeposit::IsoDepositExtractor > muIsoExtractorCalo_
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
void init(edm::Event &, const edm::EventSetup &)
virtual void setInnerTrack(const TrackRef &t)
set reference to Track
bool failedToGet() const
Definition: HandleBase.h:72
float caloCompatibility() const
Definition: CaloMuon.h:45
string quality
DetId hcal_id
DetId of the central HCAL tower with smallest depth.
Definition: MuonEnergy.h:60
float yy() const
Definition: LocalError.h:24
edm::EDGetTokenT< reco::TrackToTrackMap > tpfmsCollectionToken_
std::vector< reco::MuonSegmentMatch > me0Matches
int iEvent
Definition: GenABIO.cc:224
std::unique_ptr< MuonShowerDigiFiller > theShowerDigiFiller_
edm::Handle< reco::VertexCollection > pvHandle_
double ptThresholdToFillCandidateP4WithGlobalFit_
void addDefault(ParameterSetDescription const &psetDescription)
reco::Muon::MuonTrackTypePair sigmaSwitch(const reco::TrackRef &combinedTrack, const reco::TrackRef &trackerTrack, const double nSigma=2., const double ptThreshold=200.)
TrackAssociatorParameters parameters_
bool isGoodME0Muon(const reco::Muon &muon)
reco::Muon::MuonTrackTypePair tevOptimized(const reco::TrackRef &combinedTrack, const reco::TrackRef &trackerTrack, const reco::TrackRef &tpfmsTrack, const reco::TrackRef &pickyTrack, const reco::TrackRef &dytTrack, const double ptThreshold=200., const double tune1=17., const double tune2=40., const double dptcut=0.25)
Definition: MuonCocktails.cc:9
void fillTrackerKink(reco::Muon &aMuon)
void setPropagator(const Propagator *)
use a user configured propagator
float emS25
energy deposited in 5x5 ECAL crystal shape around central crystal
Definition: MuonEnergy.h:30
static const unsigned int ME0Muon
Definition: Muon.h:296
ArbitrationType
define arbitration schemes
Definition: Muon.h:187
T sqrt(T t)
Definition: SSEVec.h:19
bool isGoodTrackerMuon(const reco::Muon &muon)
double candEnergy() const
Get energy or pT attached to cand trajectory.
Definition: IsoDeposit.h:129
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
float emEt
ecal sum-Et
Definition: MuonIsolation.h:7
float timeAtIpInOutErr
Definition: MuonTime.h:14
int nJets
number of jets in the cone
Definition: MuonIsolation.h:11
static const unsigned int BestInChamberByDX
std::string ecalDepositName_
bool checkLinks(const reco::MuonTrackLinks *) const
float timeAtIpOutIn
b) particle is moving from outside in
Definition: MuonTime.h:16
int nDof
number of muon stations used
Definition: MuonTime.h:9
bool isCaloCompatibilityValid() const
Definition: CaloMuon.h:47
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
edm::EDGetTokenT< reco::MuonCollection > muonCollectionToken_
Transition
Definition: Transition.h:12
float hoEt
ho sum-Et
Definition: MuonIsolation.h:9
int nDof() const
number of measurements used in timing calculation
Definition: MuonTimeExtra.h:22
edm::EDGetTokenT< reco::TrackCollection > outerTrackCollectionToken_
def stationIndex(name)
Definition: plotscripts.py:355
edm::Handle< RPCRecHitCollection > rpcHitHandle_
float hoS9
energy deposited in 3x3 HO tower shape around central tower
Definition: MuonEnergy.h:44
std::vector< reco::MuonRPCHitMatch > rpcMatches
static constexpr int ME0
Definition: MuonSubdetId.h:15
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
static const unsigned int BestInChamberByDR
TrackRef standAloneMuon() const override
reference to a stand-alone muon Track
Definition: Muon.h:49
ME0SegmentRef me0SegmentRef
virtual TrackRef innerTrack() const
Definition: Muon.h:45
ParameterDescriptionBase * add(U const &iLabel, T const &value)
edm::Handle< reco::TrackToTrackMap > dytCollectionHandle_
bool isNull() const
Checks for null.
Definition: Ref.h:235
edm::Handle< reco::TrackCollection > outerTrackCollectionHandle_
edm::EDGetTokenT< reco::MuonTrackLinksCollection > linkCollectionToken_
static const unsigned int BestInStationByDXSlope
bool isRPCMuon() const
Definition: Muon.h:308
math::XYZPointF hcal_position
Definition: MuonEnergy.h:54
bool fillGlobalTrackRefits_
static double sectorPhi(const DetId &id)
void setMuonTrack(const MuonTrackType &, const TrackRef &)
float hoVetoEt
ho sum-et in the veto region in r-phi
Definition: MuonIsolation.h:15
double depositWithin(double coneSize, const Vetos &vetos=Vetos(), bool skipDepositVeto=false) const
Get deposit.
Definition: IsoDeposit.cc:29
#define M_PI
edm::EDGetTokenT< GEMRecHitCollection > gemHitToken_
reco::CaloMuon makeCaloMuon(const reco::Muon &)
unsigned int id
int nTracks
number of tracks in the cone (excluding veto region)
Definition: MuonIsolation.h:10
static const unsigned int BestInChamberByDXSlope
float emMax
maximal energy of ECAL crystal in the 5x5 shape
Definition: MuonEnergy.h:32
void setCaloCompatibility(float input)
Definition: CaloMuon.h:46
Definition: DetId.h:17
static const unsigned int RPCMuon
Definition: Muon.h:294
bool isGEMMuon() const
Definition: Muon.h:309
int numberOfMatches(ArbitrationType type=SegmentAndTrackArbitration) const
get number of chambers with matched segments
static ICTypeKey toKey(const std::string &s)
std::vector< reco::MuonSegmentMatch > * getSegmentMatches(reco::MuonChamberMatch &chamber, unsigned int muonType) const
get the segment matches of the appropriate type
static const unsigned int TrackerMuon
Definition: Muon.h:290
float emVetoEt
ecal sum-et in the veto region in r-phi
Definition: MuonIsolation.h:13
void configure(const edm::ParameterSet &)
bool isQualityValid() const
Definition: Muon.h:117
std::vector< ICTypes::ICTypeKey > inputCollectionTypes_
float hadMax
maximal energy of HCAL tower in the 3x3 shape
Definition: MuonEnergy.h:40
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
CSCDetId chamberId() const
Definition: CSCDetId.h:47
static const unsigned int BelongsToTrackByDRSlope
edm::Handle< GEMRecHitCollection > gemHitHandle_
virtual void setInnerTrack(const TrackRef &t)
set reference to Track
Definition: CaloMuon.h:30
edm::Ref< TrackCollection > TrackRef
persistent reference to a Track
Definition: TrackFwd.h:20
static constexpr int RPC
Definition: MuonSubdetId.h:13
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
void setCombinedQuality(const MuonQuality &combinedQuality)
set energy deposition information
Definition: Muon.h:121
std::vector< edm::InputTag > inputCollectionLabels_
static const unsigned int PFMuon
Definition: Muon.h:293
std::vector< MuonChamberMatch > & matches()
get muon matching information
Definition: Muon.h:145
std::unique_ptr< reco::isodeposit::IsoDepositExtractor > muIsoExtractorJet_
void setCalEnergy(const MuonEnergy &calEnergy)
set energy deposition information
Definition: CaloMuon.h:37
MuonIdProducer(const edm::ParameterSet &)
void arbitrateMuons(reco::MuonCollection *, reco::CaloMuonCollection *)
std::vector< reco::MuonSegmentMatch > segmentMatches
bool fillGlobalTrackQuality_
bool isValid() const
Definition: HandleBase.h:70
DetId ecal_id
DetId of the central ECAL crystal.
Definition: MuonEnergy.h:57
float timeAtIpOutIn() const
b) particle is moving from outside in
Definition: MuonTimeExtra.h:48
virtual void setOuterTrack(const TrackRef &t)
set reference to Track
static const unsigned int BelongsToTrackByDR
std::string hcalDepositName_
~MuonIdProducer() override
unsigned int chamberId(const DetId &)
reco::TrackRef getTevRefitTrack(const reco::TrackRef &combinedTrack, const reco::TrackToTrackMap &map)
static const unsigned int BelongsToTrackByDX
void setIsolation(const MuonIsolation &isoR03, const MuonIsolation &isoR05)
virtual void setBestTrack(MuonTrackType muonType)
Definition: Muon.h:86
HLT enums.
int sector() const
Definition: DTChamberId.h:49
functor predicate for standard library sort algorithm
static const unsigned int GEMMuon
Definition: Muon.h:295
edm::EDGetTokenT< reco::TrackCollection > outerTrackSecondaryCollectionToken_
edm::Handle< reco::TrackToTrackMap > tpfmsCollectionHandle_
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:232
static const unsigned int BestInStationByDX
TrackDetMatchInfo associate(const edm::Event &, const edm::EventSetup &, const FreeTrajectoryState &, const AssociatorParameters &)
bool storeCrossedHcalRecHits_
edm::Handle< reco::TrackCollection > innerTrackCollectionHandle_
bool isGoodTrack(const reco::Track &track)
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
edm::EDGetTokenT< reco::VertexCollection > pvToken_
int triggerSector() const
Definition: CSCDetId.cc:3
MuonTrackType
map for Global Muon refitters
Definition: Muon.h:36
double sigmaThresholdToFillCandidateP4WithGlobalFit_
#define get
static const unsigned int StandAloneMuon
Definition: Muon.h:291
edm::Handle< reco::TrackCollection > outerTrackSecondaryCollectionHandle_
std::vector< HcalMuonRecHit > crossedHadRecHits
Definition: MuonEnergy.h:66
static constexpr int DT
Definition: MuonSubdetId.h:11
int ring() const
Definition: CSCDetId.h:68
Log< level::Warning, false > LogWarning
std::pair< TrackRef, Muon::MuonTrackType > MuonTrackTypePair
Definition: Muon.h:38
void setMatches(const std::vector< MuonChamberMatch > &matches)
set muon matching information
Definition: Muon.h:148
math::XYZPointF ecal_position
Trajectory position at the calorimeter.
Definition: MuonEnergy.h:53
static constexpr int CSC
Definition: MuonSubdetId.h:12
static const unsigned int BestInChamberByDRSlope
bool validateGlobalMuonPair(const reco::MuonTrackLinks &goodMuon, const reco::MuonTrackLinks &badMuon)
bool debugWithTruthMatching_
float timeAtIpInOut
Definition: MuonTime.h:13
bool isGoodCaloMuon(const reco::CaloMuon &muon)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
bool isGlobalMuon() const override
Definition: Muon.h:303
virtual void setGlobalTrack(const TrackRef &t)
set reference to Track
float trackerVetoPt
(sum-)pt inside the veto region in r-phi
Definition: MuonIsolation.h:12
float xx() const
Definition: LocalError.h:22
float hadS9
energy deposited in 3x3 HCAL tower shape around central tower
Definition: MuonEnergy.h:38
def move(src, dest)
Definition: eostools.py:511
edm::Handle< reco::MuonCollection > muonCollectionHandle_
Definition: Run.h:45
std::pair< double, int > depositAndCountWithin(double coneSize, const Vetos &vetos=Vetos(), double threshold=-1e+36, bool skipDepositVeto=false) const
Get deposit.
Definition: IsoDeposit.cc:37
edm::Handle< edm::ValueMap< reco::MuonQuality > > glbQualHandle_
void beginRun(const edm::Run &, const edm::EventSetup &) override
edm::Handle< reco::TrackToTrackMap > pickyCollectionHandle_
std::unique_ptr< MuonMesh > meshAlgo_
#define LogDebug(id)
edm::EDGetTokenT< reco::TrackToTrackMap > dytCollectionToken_