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() > 7 || inputCollectionLabels_.empty())
140  throw cms::Exception("ConfigurationError") << "Number of input collections should be from 1 to 7.";
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);
183  } else if (inputType == ICTypes::OUTER_TRACKS) {
184  outerTrackCollectionToken_ = consumes<reco::TrackCollection>(inputLabel);
185  } else if (inputType == ICTypes::LINKS) {
186  linkCollectionToken_ = consumes<reco::MuonTrackLinksCollection>(inputLabel);
187  } else if (inputType == ICTypes::MUONS) {
188  muonCollectionToken_ = consumes<reco::MuonCollection>(inputLabel);
189  } else if (inputType == ICTypes::TEV_FIRSTHIT) {
190  tpfmsCollectionToken_ = consumes<reco::TrackToTrackMap>(inputLabel);
191  } else if (fillGlobalTrackRefits_ && inputType == ICTypes::TEV_PICKY) {
192  pickyCollectionToken_ = consumes<reco::TrackToTrackMap>(inputLabel);
193  } else if (fillGlobalTrackRefits_ && inputType == ICTypes::TEV_DYT) {
194  dytCollectionToken_ = consumes<reco::TrackToTrackMap>(inputCollectionLabels_.at(i));
195  }
196 
197  inputCollectionTypes_[i] = inputType;
198  }
199 }
200 
202  // TimingReport::current()->dump(std::cout);
203 }
204 
210 
211  tpfmsCollectionHandle_.clear();
212  pickyCollectionHandle_.clear();
213  dytCollectionHandle_.clear();
214 
216 
217  if (fillTrackerKink_)
218  trackerKinkFinder_->init(iSetup);
219 
220  for (unsigned int i = 0; i < inputCollectionLabels_.size(); ++i) {
221  const auto& inputLabel = inputCollectionLabels_[i];
222  const auto inputType = inputCollectionTypes_[i];
223  if (inputType == ICTypes::INNER_TRACKS) {
226  throw cms::Exception("FatalError") << "Failed to get input track collection with label: " << inputLabel;
227  LogTrace("MuonIdentification") << "Number of input inner tracks: " << innerTrackCollectionHandle_->size();
228  } else if (inputType == ICTypes::OUTER_TRACKS) {
231  throw cms::Exception("FatalError") << "Failed to get input track collection with label: " << inputLabel;
232  LogTrace("MuonIdentification") << "Number of input outer tracks: " << outerTrackCollectionHandle_->size();
233  } else if (inputType == ICTypes::LINKS) {
236  throw cms::Exception("FatalError") << "Failed to get input link collection with label: " << inputLabel;
237  LogTrace("MuonIdentification") << "Number of input links: " << linkCollectionHandle_->size();
238  } else if (inputType == ICTypes::MUONS) {
241  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
242  LogTrace("MuonIdentification") << "Number of input muons: " << muonCollectionHandle_->size();
243  } else if (fillGlobalTrackRefits_ && inputType == ICTypes::TEV_FIRSTHIT) {
245  if (!tpfmsCollectionHandle_.isValid())
246  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
247  LogTrace("MuonIdentification") << "Number of input muons: " << tpfmsCollectionHandle_->size();
248  } else if (fillGlobalTrackRefits_ && inputType == ICTypes::TEV_PICKY) {
250  if (!pickyCollectionHandle_.isValid())
251  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
252  LogTrace("MuonIdentification") << "Number of input muons: " << pickyCollectionHandle_->size();
253  } else if (fillGlobalTrackRefits_ && inputType == ICTypes::TEV_DYT) {
255  if (!dytCollectionHandle_.isValid())
256  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
257  LogTrace("MuonIdentification") << "Number of input muons: " << dytCollectionHandle_->size();
258  } else
259  throw cms::Exception("FatalError") << "Unknown input collection type: #" << ICTypes::toStr(inputType);
260  }
261 
262  iEvent.getByToken(rpcHitToken_, rpcHitHandle_);
263  iEvent.getByToken(gemHitToken_, gemHitHandle_);
265  iEvent.getByToken(glbQualToken_, glbQualHandle_);
266  if (selectHighPurity_)
267  iEvent.getByToken(pvToken_, pvHandle_);
268 }
269 
271  const edm::EventSetup& iSetup,
272  const reco::TrackRef& track,
274  LogTrace("MuonIdentification") << "Creating a muon from a track " << track.get()->pt()
275  << " Pt (GeV), eta: " << track.get()->eta();
276  reco::Muon aMuon(makeMuon(*(track.get())));
277 
278  LogTrace("MuonIdentification") << "Muon created from a track ";
279 
280  aMuon.setMuonTrack(type, track);
281  aMuon.setBestTrack(type);
282  aMuon.setTunePBestTrack(type);
283 
284  LogTrace("MuonIdentification")
285  << "Muon created from a track and setMuonBestTrack, setBestTrack and setTunePBestTrack called";
286 
287  return aMuon;
288 }
289 
291  LogTrace("MuonIdentification") << "Creating a CaloMuon from a Muon";
292 
293  reco::CaloMuon aMuon;
294  aMuon.setInnerTrack(muon.innerTrack());
295 
296  if (muon.isEnergyValid())
297  aMuon.setCalEnergy(muon.calEnergy());
298  // get calo compatibility
301  return aMuon;
302 }
303 
305  LogTrace("MuonIdentification") << "Creating a muon from a link to tracks object";
306 
307  reco::Muon aMuon;
308  reco::Muon::MuonTrackTypePair chosenTrack;
309  reco::TrackRef tpfmsRef;
310  reco::TrackRef pickyRef;
311  reco::TrackRef dytRef;
312  bool useSigmaSwitch = false;
313 
314  if (tpfmsCollectionHandle_.isValid() && !tpfmsCollectionHandle_.failedToGet() && pickyCollectionHandle_.isValid() &&
315  !pickyCollectionHandle_.failedToGet()) {
316  tpfmsRef = muon::getTevRefitTrack(links.globalTrack(), *tpfmsCollectionHandle_);
317  pickyRef = muon::getTevRefitTrack(links.globalTrack(), *pickyCollectionHandle_);
318  dytRef = muon::getTevRefitTrack(links.globalTrack(), *dytCollectionHandle_);
319 
320  if (tpfmsRef.isNull() && pickyRef.isNull() && dytRef.isNull()) {
321  edm::LogWarning("MakeMuonWithTEV") << "Failed to get TEV refits, fall back to sigma switch.";
322  useSigmaSwitch = true;
323  }
324  } else {
325  useSigmaSwitch = true;
326  }
327 
328  if (useSigmaSwitch) {
329  chosenTrack = muon::sigmaSwitch(links.globalTrack(),
330  links.trackerTrack(),
333  } else {
334  chosenTrack = muon::tevOptimized(links.globalTrack(),
335  links.trackerTrack(),
336  tpfmsRef,
337  pickyRef,
338  dytRef,
340  }
341  aMuon = makeMuon(*chosenTrack.first);
342  aMuon.setInnerTrack(links.trackerTrack());
343  aMuon.setOuterTrack(links.standAloneTrack());
344  aMuon.setGlobalTrack(links.globalTrack());
345  aMuon.setBestTrack(chosenTrack.second);
346  aMuon.setTunePBestTrack(chosenTrack.second);
347 
349  if (tpfmsCollectionHandle_.isValid() && !tpfmsCollectionHandle_.failedToGet()) {
351  if (it != tpfmsCollectionHandle_->end())
352  aMuon.setMuonTrack(reco::Muon::TPFMS, (it->val));
353  }
354  if (pickyCollectionHandle_.isValid() && !pickyCollectionHandle_.failedToGet()) {
356  if (it != pickyCollectionHandle_->end())
357  aMuon.setMuonTrack(reco::Muon::Picky, (it->val));
358  }
359  if (dytCollectionHandle_.isValid() && !dytCollectionHandle_.failedToGet()) {
361  if (it != dytCollectionHandle_->end())
362  aMuon.setMuonTrack(reco::Muon::DYT, (it->val));
363  }
364  }
365  return aMuon;
366 }
367 
369  // Pt and absolute momentum requirement
370  const double p = track.p();
371  const double pt = track.pt();
372  if (pt < minPt_ || (p < minP_ && p < minPCaloMuon_)) {
373  LogTrace("MuonIdentification") << "Skipped low momentum track (Pt,P): " << pt << ", " << track.p() << " GeV";
374  return false;
375  }
376 
377  // Eta requirement
378  const double eta = track.eta();
379  const double absEta = std::abs(eta);
380  if (absEta > maxAbsEta_) {
381  LogTrace("MuonIdentification") << "Skipped track with large pseudo rapidity (Eta: " << track.eta() << " )";
382  return false;
383  }
384 
385  return true;
386 }
387 
388 unsigned int MuonIdProducer::chamberId(const DetId& id) {
389  if (id.det() != DetId::Muon)
390  return 0;
391 
392  const auto subdetId = id.subdetId();
393  if (subdetId == MuonSubdetId::DT) {
394  return DTChamberId(id.rawId()).rawId();
395  } else if (subdetId == MuonSubdetId::CSC) {
396  return CSCDetId(id.rawId()).chamberId().rawId();
397  }
398 
399  return 0;
400 }
401 
403  if (!muon.isMatchesValid() || track.extra().isNull() || track.extra()->recHitsSize() == 0)
404  return 0;
405 
406  int numberOfCommonDetIds = 0;
407  const std::vector<reco::MuonChamberMatch>& matches(muon.matches());
408  for (const auto& match : matches) {
409  if (match.segmentMatches.empty())
410  continue;
411 
412  bool foundCommonDetId = false;
413  for (auto hit = track.extra()->recHitsBegin(); hit != track.extra()->recHitsEnd(); ++hit) {
414  // LogTrace("MuonIdentification") << "hit DetId: " << std::hex << hit->get()->geographicalId().rawId() <<
415  // "\t hit chamber DetId: " << getChamberId(hit->get()->geographicalId()) <<
416  // "\t segment DetId: " << match->id.rawId() << std::dec;
417 
418  if (chamberId((*hit)->geographicalId()) == match.id.rawId()) {
419  foundCommonDetId = true;
420  break;
421  }
422  }
423  if (foundCommonDetId) {
424  ++numberOfCommonDetIds;
425  break;
426  }
427  }
428  return numberOfCommonDetIds;
429 }
430 
431 void MuonIdProducer::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {
432  meshAlgo_->setCSCGeometry(&iSetup.getData(geomTokenRun_));
433 
435  theShowerDigiFiller_->getES(iSetup);
436 }
437 
438 bool validateGlobalMuonPair(const reco::MuonTrackLinks& goodMuon, const reco::MuonTrackLinks& badMuon) {
439  const int nHitsGood = goodMuon.globalTrack()->hitPattern().numberOfValidMuonHits();
440  const int nHitsBad = badMuon.globalTrack()->hitPattern().numberOfValidMuonHits();
441  if (std::min(nHitsGood, nHitsBad) > 10) {
442  const double chi2Good = goodMuon.globalTrack()->normalizedChi2();
443  const double chi2Bad = badMuon.globalTrack()->normalizedChi2();
444  return (chi2Good <= chi2Bad);
445  }
446 
447  return (nHitsGood >= nHitsBad);
448 }
449 
451  auto outputMuons = std::make_unique<reco::MuonCollection>();
452  auto caloMuons = std::make_unique<reco::CaloMuonCollection>();
453 
454  init(iEvent, iSetup);
455 
457  theShowerDigiFiller_->getDigis(iEvent);
458 
459  // loop over input collections
460 
461  // muons first - no cleaning, take as is.
463  for (const auto& muon : *muonCollectionHandle_) {
464  outputMuons->push_back(muon);
465  }
466  }
467 
468  // links second ( assume global muon type )
470  const auto nLink = linkCollectionHandle_->size();
471  std::vector<bool> goodmuons(nLink, true);
472  if (nLink > 1) {
473  // check for shared tracker tracks
474  for (unsigned int i = 0; i < nLink - 1; ++i) {
475  const auto& iLink = linkCollectionHandle_->at(i);
476  if (iLink.trackerTrack().isNull() || !checkLinks(&iLink))
477  continue;
478  for (unsigned int j = i + 1; j < nLink; ++j) {
479  const auto& jLink = linkCollectionHandle_->at(j);
480  if (!checkLinks(&jLink))
481  continue;
482  if (iLink.trackerTrack() == jLink.trackerTrack()) {
483  // Tracker track is the essential part that dominates muon resolution
484  // so taking either muon is fine. All that is important is to preserve
485  // the muon identification information. If number of hits is small,
486  // keep the one with large number of hits, otherwise take the smalest chi2/ndof
487  if (validateGlobalMuonPair(iLink, jLink))
488  goodmuons[j] = false;
489  else
490  goodmuons[i] = false;
491  }
492  }
493  }
494  // check for shared stand-alone muons.
495  for (unsigned int i = 0; i < nLink - 1; ++i) {
496  if (!goodmuons[i])
497  continue;
498  const auto& iLink = linkCollectionHandle_->at(i);
499  if (iLink.standAloneTrack().isNull() || !checkLinks(&iLink))
500  continue;
501  for (unsigned int j = i + 1; j < nLink; ++j) {
502  if (!goodmuons[j])
503  continue;
504  const auto& jLink = linkCollectionHandle_->at(j);
505  if (!checkLinks(&jLink))
506  continue;
507  if (iLink.standAloneTrack() == jLink.standAloneTrack()) {
508  if (validateGlobalMuonPair(iLink, jLink))
509  goodmuons[j] = false;
510  else
511  goodmuons[i] = false;
512  }
513  }
514  }
515  }
516  for (unsigned int i = 0; i < nLink; ++i) {
517  if (!goodmuons[i])
518  continue;
519  const auto& iLink = linkCollectionHandle_->at(i);
520  if (!checkLinks(&iLink))
521  continue;
522  // check if this muon is already in the list
523  bool newMuon = true;
524  for (const auto& muon : *outputMuons) {
525  if (muon.track() == iLink.trackerTrack() && muon.standAloneMuon() == iLink.standAloneTrack() &&
526  muon.combinedMuon() == iLink.globalTrack()) {
527  newMuon = false;
528  break;
529  }
530  }
531  if (newMuon) {
532  outputMuons->push_back(makeMuon(iLink));
533  outputMuons->back().setType(reco::Muon::GlobalMuon | reco::Muon::StandAloneMuon);
534  }
535  }
536  }
537 
538  // tracker and calo muons are next
540  LogTrace("MuonIdentification") << "Creating tracker muons";
541  std::vector<TrackDetectorAssociator::Direction> directions1, directions2;
542  directions1.push_back(TrackDetectorAssociator::InsideOut);
543  directions1.push_back(TrackDetectorAssociator::OutsideIn);
544  directions2.push_back(TrackDetectorAssociator::Any);
545 
546  const GlobalTrackingGeometry* geometry = nullptr;
548  geometry = &iSetup.getData(globalGeomToken_);
549  }
550 
551  for (unsigned int i = 0; i < innerTrackCollectionHandle_->size(); ++i) {
553  if (!isGoodTrack(track))
554  continue;
556  const reco::VertexCollection* recoVertices = pvHandle_.product();
557  if (!(*recoVertices)[0].isFake())
558  continue;
559  }
560  const auto& trackRef = reco::TrackRef(innerTrackCollectionHandle_, i);
561  bool splitTrack = false;
562  if (track.extra().isAvailable() && TrackDetectorAssociator::crossedIP(track))
563  splitTrack = true;
564  const auto& directions = splitTrack ? directions1 : directions2;
565  for (const auto direction : directions) {
566  // make muon
568  fillMuonId(iEvent, iSetup, trackerMuon, direction);
569 
571  // add MC hits to a list of matched segments.
572  // Since it's debugging mode - code is slow
574  }
575 
576  // check if this muon is already in the list
577  // have to check where muon hits are really located
578  // to match properly
579  bool newMuon = true;
580  const bool goodTrackerMuon = isGoodTrackerMuon(trackerMuon);
581  const bool goodRPCMuon = isGoodRPCMuon(trackerMuon);
582  const bool goodGEMMuon = isGoodGEMMuon(trackerMuon);
583  const bool goodME0Muon = isGoodME0Muon(trackerMuon);
584  if (goodTrackerMuon)
586  if (goodRPCMuon)
587  trackerMuon.setType(trackerMuon.type() | reco::Muon::RPCMuon);
588  if (goodGEMMuon)
589  trackerMuon.setType(trackerMuon.type() | reco::Muon::GEMMuon);
590  if (goodME0Muon)
591  trackerMuon.setType(trackerMuon.type() | reco::Muon::ME0Muon);
592 
593  for (auto& muon : *outputMuons) {
594  if (muon.innerTrack().get() == trackerMuon.innerTrack().get() &&
596  M_PI_2) {
597  newMuon = false;
598  muon.setMatches(trackerMuon.matches());
599  if (trackerMuon.isTimeValid())
600  muon.setTime(trackerMuon.time());
601  if (trackerMuon.isEnergyValid())
602  muon.setCalEnergy(trackerMuon.calEnergy());
603  if (goodTrackerMuon)
604  muon.setType(muon.type() | reco::Muon::TrackerMuon);
605  if (goodRPCMuon)
606  muon.setType(muon.type() | reco::Muon::RPCMuon);
607  if (goodGEMMuon)
608  muon.setType(muon.type() | reco::Muon::GEMMuon);
609  if (goodME0Muon)
610  muon.setType(muon.type() | reco::Muon::ME0Muon);
611  LogTrace("MuonIdentification") << "Found a corresponding global muon. Set energy, matches and move on";
612  break;
613  }
614  }
615  if (newMuon) {
616  if (goodTrackerMuon || goodRPCMuon || goodGEMMuon || goodME0Muon) {
617  outputMuons->push_back(trackerMuon);
618  } else {
619  LogTrace("MuonIdentification") << "track failed minimal number of muon matches requirement";
620  const reco::CaloMuon& caloMuon = makeCaloMuon(trackerMuon);
621  if (isGoodCaloMuon(caloMuon))
622  caloMuons->push_back(caloMuon);
623  }
624  }
625  }
626  }
627  }
628 
629  // and at last the stand alone muons
631  LogTrace("MuonIdentification") << "Looking for new muons among stand alone muon tracks";
632  for (unsigned int i = 0; i < outerTrackCollectionHandle_->size(); ++i) {
633  const auto& outerTrack = outerTrackCollectionHandle_->at(i);
634 
635  // check if this muon is already in the list of global muons
636  bool newMuon = true;
637  for (auto& muon : *outputMuons) {
638  if (!muon.standAloneMuon().isNull()) {
639  // global muon
640  if (muon.standAloneMuon().get() == &outerTrack) {
641  newMuon = false;
642  break;
643  }
644  } else {
645  // tracker muon - no direct links to the standalone muon
646  // since we have only a few real muons in an event, matching
647  // the stand alone muon to the tracker muon by DetIds should
648  // be good enough for association. At the end it's up to a
649  // user to redefine the association and what it means. Here
650  // we would like to avoid obvious double counting and we
651  // tolerate a potential miss association
652  if (overlap(muon, outerTrack) > 0) {
653  LogTrace("MuonIdentification") << "Found associated tracker muon. Set a reference and move on";
654  newMuon = false;
656  muon.setType(muon.type() | reco::Muon::StandAloneMuon);
657  break;
658  }
659  }
660  }
661  if (newMuon) {
662  LogTrace("MuonIdentification") << "No associated stand alone track is found. Making a muon";
663  outputMuons->push_back(
665  outputMuons->back().setType(reco::Muon::StandAloneMuon);
666  }
667  }
668  }
669 
671  fillArbitrationInfo(outputMuons.get());
672  arbitrateMuons(outputMuons.get(), caloMuons.get());
673  }
674 
675  LogTrace("MuonIdentification") << "Dress up muons if it's necessary";
676 
677  const int nMuons = outputMuons->size();
678 
679  std::vector<reco::MuonTimeExtra> dtTimeColl(nMuons);
680  std::vector<reco::MuonTimeExtra> cscTimeColl(nMuons);
681  std::vector<reco::MuonTimeExtra> combinedTimeColl(nMuons);
682  std::vector<reco::IsoDeposit> trackDepColl(nMuons);
683  std::vector<reco::IsoDeposit> ecalDepColl(nMuons);
684  std::vector<reco::IsoDeposit> hcalDepColl(nMuons);
685  std::vector<reco::IsoDeposit> hoDepColl(nMuons);
686  std::vector<reco::IsoDeposit> jetDepColl(nMuons);
687 
688  // Fill various information
689  for (unsigned int i = 0; i < outputMuons->size(); ++i) {
690  auto& muon = outputMuons->at(i);
691 
692  // Fill muonID
693  if ((fillMatching_ && !muon.isMatchesValid()) || (fillEnergy_ && !muon.isEnergyValid())) {
694  // predict direction based on the muon interaction region location
695  // if it's available
696  if (muon.isStandAloneMuon()) {
699  } else {
701  }
702  } else {
703  LogTrace("MuonIdentification") << "THIS SHOULD NEVER HAPPEN";
704  fillMuonId(iEvent, iSetup, muon);
705  }
706  }
707 
709  // Fill global quality information
710  fillGlbQuality(iEvent, iSetup, muon);
711  }
712  LogDebug("MuonIdentification") << "";
713 
714  if (fillTrackerKink_) {
716  }
717 
719  muon.setCaloCompatibility(muonCaloCompatibility_.evaluate(muon));
720 
721  if (fillIsolation_) {
723  iEvent, iSetup, muon, trackDepColl[i], ecalDepColl[i], hcalDepColl[i], hoDepColl[i], jetDepColl[i]);
724  }
725 
726  // fill timing information
727  reco::MuonTime muonTime;
728  reco::MuonTimeExtra dtTime;
729  reco::MuonTimeExtra cscTime;
730  reco::MuonTime rpcTime;
731  reco::MuonTimeExtra combinedTime;
732 
733  theTimingFiller_->fillTiming(muon, dtTime, cscTime, rpcTime, combinedTime, iEvent, iSetup);
734 
735  muonTime.nDof = combinedTime.nDof();
736  muonTime.timeAtIpInOut = combinedTime.timeAtIpInOut();
737  muonTime.timeAtIpInOutErr = combinedTime.timeAtIpInOutErr();
738  muonTime.timeAtIpOutIn = combinedTime.timeAtIpOutIn();
739  muonTime.timeAtIpOutInErr = combinedTime.timeAtIpOutInErr();
740 
741  muon.setTime(muonTime);
742  muon.setRPCTime(rpcTime);
743  dtTimeColl[i] = dtTime;
744  cscTimeColl[i] = cscTime;
745  combinedTimeColl[i] = combinedTime;
746  }
747 
748  LogTrace("MuonIdentification") << "number of muons produced: " << outputMuons->size();
749  if (fillMatching_) {
750  fillArbitrationInfo(outputMuons.get(), reco::Muon::TrackerMuon);
751  fillArbitrationInfo(outputMuons.get(), reco::Muon::ME0Muon);
752  fillArbitrationInfo(outputMuons.get(), reco::Muon::GEMMuon);
753  }
754  edm::OrphanHandle<reco::MuonCollection> muonHandle = iEvent.put(std::move(outputMuons));
755 
756  auto fillMap = [](auto refH, auto& vec, edm::Event& ev, const std::string& cAl = "") {
758  auto oMap = std::make_unique<MapType>();
759  {
760  typename MapType::Filler filler(*oMap);
761  filler.insert(refH, vec.begin(), vec.end());
762  vec.clear();
763  filler.fill();
764  }
765  ev.put(std::move(oMap), cAl);
766  };
767  fillMap(muonHandle, combinedTimeColl, iEvent, "combined");
768  fillMap(muonHandle, dtTimeColl, iEvent, "dt");
769  fillMap(muonHandle, cscTimeColl, iEvent, "csc");
770 
772  fillMap(muonHandle, trackDepColl, iEvent, trackDepositName_);
773  fillMap(muonHandle, ecalDepColl, iEvent, ecalDepositName_);
774  fillMap(muonHandle, hcalDepColl, iEvent, hcalDepositName_);
775  fillMap(muonHandle, hoDepColl, iEvent, hoDepositName_);
776  fillMap(muonHandle, jetDepColl, iEvent, jetDepositName_);
777  }
778 
779  iEvent.put(std::move(caloMuons));
780 }
781 
783  if (muon.track()->pt() < minPt_ || muon.track()->p() < minP_)
784  return false;
785  if (addExtraSoftMuons_ && muon.pt() < 5 && std::abs(muon.eta()) < 1.5 &&
786  muon.numberOfMatches(reco::Muon::NoArbitration) >= 1)
787  return true;
788  return (muon.numberOfMatches(reco::Muon::NoArbitration) >= minNumberOfMatches_);
789 }
790 
792  if (!caloMuon.isCaloCompatibilityValid() || caloMuon.caloCompatibility() < caloCut_ || caloMuon.p() < minPCaloMuon_)
793  return false;
794  return true;
795 }
796 
798  if (muon.track()->pt() < minPt_ || muon.track()->p() < minP_)
799  return false;
800  if (addExtraSoftMuons_ && muon.pt() < 5 && std::abs(muon.eta()) < 1.5 &&
801  muon.numberOfMatchedRPCLayers(reco::Muon::RPCHitAndTrackArbitration) > 1)
802  return true;
803  return (muon.numberOfMatchedRPCLayers(reco::Muon::RPCHitAndTrackArbitration) > minNumberOfMatches_);
804 }
805 
807  // require GEMMuon to be a TrackerMuon
808  if (!isGoodTrackerMuon(muon))
809  return false;
810  if (muon.track()->pt() < minPt_ || muon.track()->p() < minP_)
811  return false;
812  return (muon.numberOfMatches(reco::Muon::GEMSegmentAndTrackArbitration) +
813  muon.numberOfMatches(reco::Muon::GEMHitAndTrackArbitration)) >= 1;
814 }
815 
817  // need to update min cuts on pt
818  if (muon.track()->p() < minP_)
819  return false;
820  return (muon.numberOfMatches(reco::Muon::ME0SegmentAndTrackArbitration) >= 1);
821 }
822 
824  const edm::EventSetup& iSetup,
825  reco::Muon& aMuon,
827  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId";
828 
829  // perform track - detector association
830  const reco::Track* track = nullptr;
831  if (aMuon.track().isNonnull())
832  track = aMuon.track().get();
833  else if (aMuon.standAloneMuon().isNonnull())
834  track = aMuon.standAloneMuon().get();
835  else
836  throw cms::Exception("FatalError")
837  << "Failed to fill muon id information for a muon with undefined references to tracks";
838 
840 
841  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId :: fillEnergy = " << fillEnergy_;
842 
843  if (fillEnergy_) {
844  reco::MuonEnergy muonEnergy;
845  muonEnergy.em = info.crossedEnergy(TrackDetMatchInfo::EcalRecHits);
846  muonEnergy.had = info.crossedEnergy(TrackDetMatchInfo::HcalRecHits);
847  muonEnergy.ho = info.crossedEnergy(TrackDetMatchInfo::HORecHits);
848  muonEnergy.tower = info.crossedEnergy(TrackDetMatchInfo::TowerTotal);
849  muonEnergy.emS9 = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits, 1); // 3x3 energy
850  muonEnergy.emS25 = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits, 2); // 5x5 energy
851  muonEnergy.hadS9 = info.nXnEnergy(TrackDetMatchInfo::HcalRecHits, 1); // 3x3 energy
852  muonEnergy.hoS9 = info.nXnEnergy(TrackDetMatchInfo::HORecHits, 1); // 3x3 energy
853  muonEnergy.towerS9 = info.nXnEnergy(TrackDetMatchInfo::TowerTotal, 1); // 3x3 energy
855  muonEnergy.crossedHadRecHits.clear();
856  for (auto hit : info.crossedHcalRecHits) {
858  mhit.energy = hit->energy();
859  mhit.chi2 = hit->chi2();
860  mhit.time = hit->time();
861  mhit.detId = hit->id();
862  muonEnergy.crossedHadRecHits.push_back(mhit);
863  }
864  }
865  muonEnergy.ecal_position = info.trkGlobPosAtEcal;
866  muonEnergy.hcal_position = info.trkGlobPosAtHcal;
867  if (!info.crossedEcalIds.empty())
868  muonEnergy.ecal_id = info.crossedEcalIds.front();
869  if (!info.crossedHcalIds.empty())
870  muonEnergy.hcal_id = info.crossedHcalIds.front();
871  // find maximal energy depositions and their time
872  DetId emMaxId = info.findMaxDeposition(TrackDetMatchInfo::EcalRecHits, 2); // max energy deposit in 5x5 shape
873  for (const auto& hit : info.ecalRecHits) {
874  if (hit->id() != emMaxId)
875  continue;
876  muonEnergy.emMax = hit->energy();
877  muonEnergy.ecal_time = hit->time();
878  }
879  DetId hadMaxId = info.findMaxDeposition(TrackDetMatchInfo::HcalRecHits, 1); // max energy deposit in 3x3 shape
880  for (const auto& hit : info.hcalRecHits) {
881  if (hit->id() != hadMaxId)
882  continue;
883  muonEnergy.hadMax = hit->energy();
884  muonEnergy.hcal_time = hit->time();
885  }
886  aMuon.setCalEnergy(muonEnergy);
887  }
888  if (!fillMatching_ && !aMuon.isTrackerMuon() && !aMuon.isRPCMuon() && !aMuon.isGEMMuon())
889  return;
890 
891  // fill muon match info
892  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId :: fill muon match info ";
893  std::vector<reco::MuonChamberMatch> muonChamberMatches;
894  unsigned int nubmerOfMatchesAccordingToTrackAssociator = 0;
895  for (const auto& chamber : info.chambers) {
896  if (chamber.id.subdetId() == MuonSubdetId::RPC && rpcHitHandle_.isValid())
897  continue; // Skip RPC chambers, they are taken care of below)
898  if (chamber.id.subdetId() == MuonSubdetId::GEM && gemHitHandle_.isValid() &&
899  GEMDetId(chamber.id.rawId()).station() != 0)
900  continue; // Skip GE1/1 and 2/1 chambers, they are taken care of below)
901  reco::MuonChamberMatch matchedChamber;
902 
903  const auto& lErr = chamber.tState.localError();
904  const auto& lPos = chamber.tState.localPosition();
905  const auto& lDir = chamber.tState.localDirection();
906 
907  const auto& localError = lErr.positionError();
908  matchedChamber.x = lPos.x();
909  matchedChamber.y = lPos.y();
910  matchedChamber.xErr = sqrt(localError.xx());
911  matchedChamber.yErr = sqrt(localError.yy());
912 
913  matchedChamber.dXdZ = lDir.z() != 0 ? lDir.x() / lDir.z() : 9999;
914  matchedChamber.dYdZ = lDir.z() != 0 ? lDir.y() / lDir.z() : 9999;
915  // DANGEROUS - compiler cannot guaranty parameters ordering
916  AlgebraicSymMatrix55 trajectoryCovMatrix = lErr.matrix();
917  matchedChamber.dXdZErr = trajectoryCovMatrix(1, 1) > 0 ? sqrt(trajectoryCovMatrix(1, 1)) : 0;
918  matchedChamber.dYdZErr = trajectoryCovMatrix(2, 2) > 0 ? sqrt(trajectoryCovMatrix(2, 2)) : 0;
919 
920  matchedChamber.edgeX = chamber.localDistanceX;
921  matchedChamber.edgeY = chamber.localDistanceY;
922 
923  matchedChamber.id = chamber.id;
924 
926  theShowerDigiFiller_->fill(matchedChamber);
927  } else {
928  theShowerDigiFiller_->fillDefault(matchedChamber);
929  }
930 
931  if (!chamber.segments.empty())
932  ++nubmerOfMatchesAccordingToTrackAssociator;
933 
934  // fill segments
935  for (const auto& segment : chamber.segments) {
936  reco::MuonSegmentMatch matchedSegment;
937  matchedSegment.x = segment.segmentLocalPosition.x();
938  matchedSegment.y = segment.segmentLocalPosition.y();
939  matchedSegment.dXdZ =
940  segment.segmentLocalDirection.z() ? segment.segmentLocalDirection.x() / segment.segmentLocalDirection.z() : 0;
941  matchedSegment.dYdZ =
942  segment.segmentLocalDirection.z() ? segment.segmentLocalDirection.y() / segment.segmentLocalDirection.z() : 0;
943  matchedSegment.xErr = segment.segmentLocalErrorXX > 0 ? sqrt(segment.segmentLocalErrorXX) : 0;
944  matchedSegment.yErr = segment.segmentLocalErrorYY > 0 ? sqrt(segment.segmentLocalErrorYY) : 0;
945  matchedSegment.dXdZErr = segment.segmentLocalErrorDxDz > 0 ? sqrt(segment.segmentLocalErrorDxDz) : 0;
946  matchedSegment.dYdZErr = segment.segmentLocalErrorDyDz > 0 ? sqrt(segment.segmentLocalErrorDyDz) : 0;
947  matchedSegment.t0 = segment.t0;
948  matchedSegment.mask = 0;
949  matchedSegment.dtSegmentRef = segment.dtSegmentRef;
950  matchedSegment.cscSegmentRef = segment.cscSegmentRef;
951  matchedSegment.gemSegmentRef = segment.gemSegmentRef;
952  matchedSegment.me0SegmentRef = segment.me0SegmentRef;
953  matchedSegment.hasZed_ = segment.hasZed;
954  matchedSegment.hasPhi_ = segment.hasPhi;
955  // test segment
956  bool matchedX = false;
957  bool matchedY = false;
958  LogTrace("MuonIdentification") << " matching local x, segment x: " << matchedSegment.x
959  << ", chamber x: " << matchedChamber.x << ", max: " << maxAbsDx_;
960  LogTrace("MuonIdentification") << " matching local y, segment y: " << matchedSegment.y
961  << ", chamber y: " << matchedChamber.y << ", max: " << maxAbsDy_;
962  const double matchedSegChDx = std::abs(matchedSegment.x - matchedChamber.x);
963  const double matchedSegChDy = std::abs(matchedSegment.y - matchedChamber.y);
964  if (matchedSegment.xErr > 0 && matchedChamber.xErr > 0)
965  LogTrace("MuonIdentification") << " xpull: "
966  << matchedSegChDx / std::sqrt(std::pow(matchedSegment.xErr, 2) +
967  std::pow(matchedChamber.xErr, 2));
968  if (matchedSegment.yErr > 0 && matchedChamber.yErr > 0)
969  LogTrace("MuonIdentification") << " ypull: "
970  << matchedSegChDy / std::sqrt(std::pow(matchedSegment.yErr, 2) +
971  std::pow(matchedChamber.yErr, 2));
972 
973  if (matchedSegChDx < maxAbsDx_)
974  matchedX = true;
975  else if (matchedSegment.xErr > 0 && matchedChamber.xErr > 0) {
976  const double invMatchedSegChPullX2 = std::pow(matchedSegment.xErr, 2) + std::pow(matchedChamber.xErr, 2);
977  if (matchedSegChDx * matchedSegChDx < maxAbsPullX2_ * invMatchedSegChPullX2)
978  matchedX = true;
979  }
980  if (matchedSegChDy < maxAbsDy_)
981  matchedY = true;
982  else if (matchedSegment.yErr > 0 && matchedChamber.yErr > 0) {
983  const double invMatchedSegChPullY2 = std::pow(matchedSegment.yErr, 2) + std::pow(matchedChamber.yErr, 2);
984  if (matchedSegChDy * matchedSegChDy < maxAbsPullY2_ * invMatchedSegChPullY2)
985  matchedY = true;
986  }
987  if (matchedX && matchedY) {
988  if (matchedChamber.id.subdetId() == MuonSubdetId::ME0)
989  matchedChamber.me0Matches.push_back(matchedSegment);
990  else if (matchedChamber.id.subdetId() == MuonSubdetId::GEM)
991  matchedChamber.gemMatches.push_back(matchedSegment);
992  else
993  matchedChamber.segmentMatches.push_back(matchedSegment);
994  }
995  }
996  muonChamberMatches.push_back(matchedChamber);
997  }
998 
999  // Fill RPC info
1000  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId :: fill RPC info";
1001  if (rpcHitHandle_.isValid()) {
1002  for (const auto& chamber : info.chambers) {
1003  if (chamber.id.subdetId() != MuonSubdetId::RPC)
1004  continue; // Consider RPC chambers only
1005  const auto& lErr = chamber.tState.localError();
1006  const auto& lPos = chamber.tState.localPosition();
1007  const auto& lDir = chamber.tState.localDirection();
1008 
1009  reco::MuonChamberMatch matchedChamber;
1010 
1011  LocalError localError = lErr.positionError();
1012  matchedChamber.x = lPos.x();
1013  matchedChamber.y = lPos.y();
1014  matchedChamber.xErr = sqrt(localError.xx());
1015  matchedChamber.yErr = sqrt(localError.yy());
1016 
1017  matchedChamber.dXdZ = lDir.z() != 0 ? lDir.x() / lDir.z() : 9999;
1018  matchedChamber.dYdZ = lDir.z() != 0 ? lDir.y() / lDir.z() : 9999;
1019  // DANGEROUS - compiler cannot guaranty parameters ordering
1020  AlgebraicSymMatrix55 trajectoryCovMatrix = lErr.matrix();
1021  matchedChamber.dXdZErr = trajectoryCovMatrix(1, 1) > 0 ? sqrt(trajectoryCovMatrix(1, 1)) : 0;
1022  matchedChamber.dYdZErr = trajectoryCovMatrix(2, 2) > 0 ? sqrt(trajectoryCovMatrix(2, 2)) : 0;
1023 
1024  matchedChamber.edgeX = chamber.localDistanceX;
1025  matchedChamber.edgeY = chamber.localDistanceY;
1026 
1027  theShowerDigiFiller_->fillDefault(matchedChamber);
1028 
1029  matchedChamber.id = chamber.id;
1030 
1031  for (const auto& rpcRecHit : *rpcHitHandle_) {
1032  reco::MuonRPCHitMatch rpcHitMatch;
1033 
1034  if (rpcRecHit.rawId() != chamber.id.rawId())
1035  continue;
1036 
1037  rpcHitMatch.x = rpcRecHit.localPosition().x();
1038  rpcHitMatch.mask = 0;
1039  rpcHitMatch.bx = rpcRecHit.BunchX();
1040 
1041  const double absDx = std::abs(rpcRecHit.localPosition().x() - chamber.tState.localPosition().x());
1042  if (absDx <= 20 or absDx * absDx <= 16 * localError.xx())
1043  matchedChamber.rpcMatches.push_back(rpcHitMatch);
1044  }
1045 
1046  muonChamberMatches.push_back(matchedChamber);
1047  }
1048  }
1049 
1050  // Fill GEM info
1051  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId :: fill GEM info";
1052  if (gemHitHandle_.isValid()) {
1053  for (const auto& chamber : info.chambers) {
1054  // only GE1/1 and 2/1 are for rechits, reject station 0 and segments (layer==0 for GEMSegment)
1055  if (chamber.id.subdetId() != MuonSubdetId::GEM || GEMDetId(chamber.id.rawId()).station() == 0 ||
1056  GEMDetId(chamber.id.rawId()).layer() == 0)
1057  continue; // Consider GEM chambers only
1058  const auto& lErr = chamber.tState.localError();
1059  const auto& lPos = chamber.tState.localPosition();
1060  const auto& lDir = chamber.tState.localDirection();
1061 
1062  reco::MuonChamberMatch matchedChamber;
1063 
1064  LocalError localError = lErr.positionError();
1065  matchedChamber.x = lPos.x();
1066  matchedChamber.y = lPos.y();
1067  matchedChamber.xErr = sqrt(localError.xx());
1068  matchedChamber.yErr = sqrt(localError.yy());
1069 
1070  matchedChamber.dXdZ = lDir.z() != 0 ? lDir.x() / lDir.z() : 9999;
1071  matchedChamber.dYdZ = lDir.z() != 0 ? lDir.y() / lDir.z() : 9999;
1072  // DANGEROUS - compiler cannot guaranty parameters ordering
1073  AlgebraicSymMatrix55 trajectoryCovMatrix = lErr.matrix();
1074  matchedChamber.dXdZErr = trajectoryCovMatrix(1, 1) > 0 ? sqrt(trajectoryCovMatrix(1, 1)) : 0;
1075  matchedChamber.dYdZErr = trajectoryCovMatrix(2, 2) > 0 ? sqrt(trajectoryCovMatrix(2, 2)) : 0;
1076 
1077  matchedChamber.edgeX = chamber.localDistanceX;
1078  matchedChamber.edgeY = chamber.localDistanceY;
1079 
1080  theShowerDigiFiller_->fillDefault(matchedChamber);
1081 
1082  matchedChamber.id = chamber.id;
1083 
1084  for (const auto& gemRecHit : *gemHitHandle_) {
1085  reco::MuonGEMHitMatch gemHitMatch;
1086 
1087  if (GEMDetId(gemRecHit.gemId().region(),
1088  gemRecHit.gemId().ring(),
1089  gemRecHit.gemId().station(),
1090  gemRecHit.gemId().layer(),
1091  gemRecHit.gemId().chamber(),
1092  0)
1093  .rawId() != chamber.id.rawId())
1094  continue;
1095 
1096  gemHitMatch.x = gemRecHit.localPosition().x();
1097  gemHitMatch.mask = 0;
1098  gemHitMatch.bx = gemRecHit.BunchX();
1099 
1100  const double absDx = std::abs(gemRecHit.localPosition().x() - chamber.tState.localPosition().x());
1101  if (absDx <= 5 or absDx * absDx <= 16 * localError.xx())
1102  matchedChamber.gemHitMatches.push_back(gemHitMatch);
1103  }
1104 
1105  muonChamberMatches.push_back(matchedChamber);
1106  }
1107  }
1108 
1109  aMuon.setMatches(muonChamberMatches);
1110 
1111  LogTrace("MuonIdentification") << "number of muon chambers: " << aMuon.matches().size() << "\n"
1112  << "number of chambers with segments according to the associator requirements: "
1113  << nubmerOfMatchesAccordingToTrackAssociator;
1114  LogTrace("MuonIdentification") << "number of segment matches with the producer requirements: "
1116 
1117  // fillTime( iEvent, iSetup, aMuon );
1118 }
1119 
1122  // arbitrate TrackerMuons
1123  // if a muon was exclusively TrackerMuon check if it can be a calo muon
1124  for (reco::MuonCollection::iterator muon = muons->begin(); muon != muons->end();) {
1125  if (muon->isTrackerMuon()) {
1126  if (muon->numberOfMatches(arbitration) < minNumberOfMatches_) {
1127  // TrackerMuon failed arbitration
1128  // If not any other base type - erase the element
1129  // (PFMuon is not a base type)
1130  // GEMMuon should be a subset of TrackerMuon, so don't count it either
1132  if ((muon->type() & (~mask)) == 0) {
1133  const reco::CaloMuon& caloMuon = makeCaloMuon(*muon);
1134  if (isGoodCaloMuon(caloMuon))
1135  caloMuons->push_back(caloMuon);
1136  muon = muons->erase(muon);
1137  continue;
1138  } else {
1139  muon->setType(muon->type() & (~(reco::Muon::TrackerMuon | reco::Muon::GEMMuon)));
1140  }
1141  }
1142  }
1143  muon++;
1144  }
1145 }
1146 
1147 void MuonIdProducer::fillArbitrationInfo(reco::MuonCollection* pOutputMuons, unsigned int muonType) {
1148  //
1149  // apply segment flags
1150  //
1151  std::vector<std::pair<reco::MuonChamberMatch*, reco::MuonSegmentMatch*> > chamberPairs; // for chamber segment sorting
1152  std::vector<std::pair<reco::MuonChamberMatch*, reco::MuonSegmentMatch*> > stationPairs; // for station segment sorting
1153  std::vector<std::pair<reco::MuonChamberMatch*, reco::MuonSegmentMatch*> >
1154  arbitrationPairs; // for muon segment arbitration
1155 
1156  // muonIndex1
1157  for (unsigned int muonIndex1 = 0; muonIndex1 < pOutputMuons->size(); ++muonIndex1) {
1158  auto& muon1 = pOutputMuons->at(muonIndex1);
1159  // chamberIter1
1160  for (auto& chamber1 : muon1.matches()) {
1161  // segmentIter1
1162  std::vector<reco::MuonSegmentMatch>* segmentMatches1 = getSegmentMatches(chamber1, muonType);
1163 
1164  if (segmentMatches1->empty())
1165  continue;
1166  chamberPairs.clear();
1167 
1168  for (auto& segment1 : *segmentMatches1) {
1169  chamberPairs.push_back(std::make_pair(&chamber1, &segment1));
1170  if (!segment1.isMask()) // has not yet been arbitrated
1171  {
1172  arbitrationPairs.clear();
1173  arbitrationPairs.push_back(std::make_pair(&chamber1, &segment1));
1174 
1175  // find identical segments with which to arbitrate
1176  // tracker muons only
1177  if (muon1.type() & muonType) {
1178  // muonIndex2
1179  for (unsigned int muonIndex2 = muonIndex1 + 1; muonIndex2 < pOutputMuons->size(); ++muonIndex2) {
1180  auto& muon2 = pOutputMuons->at(muonIndex2);
1181  // tracker muons only
1182  if (!(muon2.type() & muonType))
1183  continue;
1184  // chamberIter2
1185  for (auto& chamber2 : muon2.matches()) {
1186  // segmentIter2
1187  std::vector<reco::MuonSegmentMatch>* segmentMatches2 = getSegmentMatches(chamber2, muonType);
1188  for (auto& segment2 : *segmentMatches2) {
1189  if (segment2.isMask())
1190  continue; // has already been arbitrated
1191  if (approxEqual(segment2.x, segment1.x) && approxEqual(segment2.y, segment1.y) &&
1192  approxEqual(segment2.dXdZ, segment1.dXdZ) && approxEqual(segment2.dYdZ, segment1.dYdZ) &&
1193  approxEqual(segment2.xErr, segment1.xErr) && approxEqual(segment2.yErr, segment1.yErr) &&
1194  approxEqual(segment2.dXdZErr, segment1.dXdZErr) &&
1195  approxEqual(segment2.dYdZErr, segment1.dYdZErr)) {
1196  arbitrationPairs.push_back(std::make_pair(&chamber2, &segment2));
1197  }
1198  } // segmentIter2
1199  } // chamberIter2
1200  } // muonIndex2
1201  }
1202 
1203  // arbitration segment sort
1204  if (arbitrationPairs.empty())
1205  continue; // this should never happen
1206  if (arbitrationPairs.size() == 1) {
1207  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDRSlope);
1208  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDXSlope);
1209  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDR);
1210  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDX);
1211  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::Arbitrated);
1212  } else {
1213  sort(arbitrationPairs.begin(),
1214  arbitrationPairs.end(),
1216  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDRSlope);
1217  sort(arbitrationPairs.begin(),
1218  arbitrationPairs.end(),
1220  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDXSlope);
1221  sort(arbitrationPairs.begin(),
1222  arbitrationPairs.end(),
1224  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDR);
1225  sort(arbitrationPairs.begin(),
1226  arbitrationPairs.end(),
1228  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDX);
1229  for (auto& ap : arbitrationPairs) {
1230  ap.second->setMask(reco::MuonSegmentMatch::Arbitrated);
1231  }
1232  }
1233  }
1234 
1235  // setup me1a cleaning for later
1236  if (muonType == reco::Muon::TrackerMuon && chamber1.id.subdetId() == MuonSubdetId::CSC && arbClean_ &&
1237  CSCDetId(chamber1.id).ring() == 4) {
1238  for (auto& segment2 : chamber1.segmentMatches) {
1239  if (segment1.cscSegmentRef.isNull() || segment2.cscSegmentRef.isNull())
1240  continue;
1241  if (meshAlgo_->isDuplicateOf(segment1.cscSegmentRef, segment2.cscSegmentRef) &&
1242  (segment2.mask & 0x1e0000) && (segment1.mask & 0x1e0000)) {
1244  //if the track has lost the segment already through normal arbitration no need to do it again.
1245  }
1246  }
1247  } // mark all ME1/a duplicates that this track owns
1248 
1249  } // segmentIter1
1250 
1251  // chamber segment sort
1252  if (chamberPairs.empty())
1253  continue; // this should never happen
1254  if (chamberPairs.size() == 1) {
1255  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDRSlope);
1256  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDXSlope);
1257  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDR);
1258  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDX);
1259  } else {
1260  sort(chamberPairs.begin(),
1261  chamberPairs.end(),
1263  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDRSlope);
1264  sort(chamberPairs.begin(),
1265  chamberPairs.end(),
1267  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDXSlope);
1268  sort(chamberPairs.begin(),
1269  chamberPairs.end(),
1271  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDR);
1272  sort(chamberPairs.begin(),
1273  chamberPairs.end(),
1275  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDX);
1276  }
1277  } // chamberIter1
1278 
1279  // station segment sort
1280  for (int stationIndex = 1; stationIndex < 5; ++stationIndex) {
1281  for (int detectorIndex = 1; detectorIndex <= 5;
1282  ++detectorIndex) // 1-5, as in DataFormats/MuonDetId/interface/MuonSubdetId.h
1283  {
1284  stationPairs.clear();
1285 
1286  // chamberIter
1287  for (auto& chamber : muon1.matches()) {
1288  if (!(chamber.station() == stationIndex && chamber.detector() == detectorIndex))
1289  continue;
1290  std::vector<reco::MuonSegmentMatch>* segmentMatches = getSegmentMatches(chamber, muonType);
1291  if (segmentMatches->empty())
1292  continue;
1293 
1294  for (auto& segment : *segmentMatches) {
1295  stationPairs.push_back(std::make_pair(&chamber, &segment));
1296  }
1297  } // chamberIter
1298 
1299  if (stationPairs.empty())
1300  continue; // this may very well happen
1301  if (stationPairs.size() == 1) {
1302  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDRSlope);
1303  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDXSlope);
1304  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDR);
1305  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDX);
1306  } else {
1307  sort(stationPairs.begin(),
1308  stationPairs.end(),
1310  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDRSlope);
1311  sort(stationPairs.begin(),
1312  stationPairs.end(),
1314  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDXSlope);
1315  sort(stationPairs.begin(),
1316  stationPairs.end(),
1318  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDR);
1319  sort(stationPairs.begin(),
1320  stationPairs.end(),
1322  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDX);
1323  }
1324  }
1325  }
1326 
1327  } // muonIndex1
1328 
1329  if (arbClean_) {
1330  // clear old mesh, create and prune new mesh!
1331  meshAlgo_->clearMesh();
1332  meshAlgo_->runMesh(pOutputMuons);
1333  }
1334 }
1335 
1337  const edm::EventSetup& iSetup,
1338  reco::Muon& aMuon,
1339  reco::IsoDeposit& trackDep,
1340  reco::IsoDeposit& ecalDep,
1341  reco::IsoDeposit& hcalDep,
1342  reco::IsoDeposit& hoDep,
1343  reco::IsoDeposit& jetDep) {
1344  const reco::Track* track = nullptr;
1345  if (aMuon.track().isNonnull())
1346  track = aMuon.track().get();
1347  else if (aMuon.standAloneMuon().isNonnull())
1348  track = aMuon.standAloneMuon().get();
1349  else
1350  throw cms::Exception("FatalError")
1351  << "Failed to compute muon isolation information for a muon with undefined references to tracks";
1352 
1353  reco::MuonIsolation isoR03, isoR05;
1354 
1355  // get deposits
1356  reco::IsoDeposit depTrk = muIsoExtractorTrack_->deposit(iEvent, iSetup, *track);
1357  std::vector<reco::IsoDeposit> caloDeps = muIsoExtractorCalo_->deposits(iEvent, iSetup, *track);
1358  reco::IsoDeposit depJet = muIsoExtractorJet_->deposit(iEvent, iSetup, *track);
1359 
1360  if (caloDeps.size() != 3) {
1361  LogTrace("MuonIdentification") << "Failed to fill vector of calorimeter isolation deposits!";
1362  return;
1363  }
1364 
1365  reco::IsoDeposit depEcal = caloDeps.at(0);
1366  reco::IsoDeposit depHcal = caloDeps.at(1);
1367  reco::IsoDeposit depHo = caloDeps.at(2);
1368 
1369  //no need to copy outside if we don't write them
1370  if (writeIsoDeposits_) {
1371  trackDep = depTrk;
1372  ecalDep = depEcal;
1373  hcalDep = depHcal;
1374  hoDep = depHo;
1375  jetDep = depJet;
1376  }
1377 
1378  isoR03.sumPt = depTrk.depositWithin(0.3);
1379  isoR03.emEt = depEcal.depositWithin(0.3);
1380  isoR03.hadEt = depHcal.depositWithin(0.3);
1381  isoR03.hoEt = depHo.depositWithin(0.3);
1382  isoR03.nTracks = depTrk.depositAndCountWithin(0.3).second;
1383  isoR03.nJets = depJet.depositAndCountWithin(0.3).second;
1384  isoR03.trackerVetoPt = depTrk.candEnergy();
1385  isoR03.emVetoEt = depEcal.candEnergy();
1386  isoR03.hadVetoEt = depHcal.candEnergy();
1387  isoR03.hoVetoEt = depHo.candEnergy();
1388 
1389  isoR05.sumPt = depTrk.depositWithin(0.5);
1390  isoR05.emEt = depEcal.depositWithin(0.5);
1391  isoR05.hadEt = depHcal.depositWithin(0.5);
1392  isoR05.hoEt = depHo.depositWithin(0.5);
1393  isoR05.nTracks = depTrk.depositAndCountWithin(0.5).second;
1394  isoR05.nJets = depJet.depositAndCountWithin(0.5).second;
1395  isoR05.trackerVetoPt = depTrk.candEnergy();
1396  isoR05.emVetoEt = depEcal.candEnergy();
1397  isoR05.hadVetoEt = depHcal.candEnergy();
1398  isoR05.hoVetoEt = depHo.candEnergy();
1399 
1400  aMuon.setIsolation(isoR03, isoR05);
1401 }
1402 
1404  const double energy = std::sqrt(track.p() * track.p() + 0.105658369 * 0.105658369);
1405  const math::XYZTLorentzVector p4(track.px(), track.py(), track.pz(), energy);
1406  return reco::Muon(track.charge(), p4, track.vertex());
1407 }
1408 
1410  double phi = 0;
1411  if (id.subdetId() == MuonSubdetId::DT) { // DT
1412  DTChamberId muonId(id.rawId());
1413  if (muonId.sector() <= 12)
1414  phi = (muonId.sector() - 1) / 6. * M_PI;
1415  if (muonId.sector() == 13)
1416  phi = 3 / 6. * M_PI;
1417  if (muonId.sector() == 14)
1418  phi = 9 / 6. * M_PI;
1419  }
1420  if (id.subdetId() == MuonSubdetId::CSC) { // CSC
1421  CSCDetId muonId(id.rawId());
1422  phi = M_PI / 4 + (muonId.triggerSector() - 1) / 3. * M_PI;
1423  }
1424  if (phi > M_PI)
1425  phi -= 2 * M_PI;
1426  return phi;
1427 }
1428 
1430  if (muon.isStandAloneMuon())
1431  return muon.standAloneMuon()->innerPosition().phi();
1432  // the rest is tracker muon only
1433  if (muon.matches().empty()) {
1434  if (muon.innerTrack().isAvailable() && muon.innerTrack()->extra().isAvailable())
1435  return muon.innerTrack()->outerPosition().phi();
1436  else
1437  return muon.phi(); // makes little sense, but what else can I use
1438  }
1439  return sectorPhi(muon.matches().at(0).id);
1440 }
1441 
1444  aMuon.setCombinedQuality((*glbQualHandle_)[aMuon.combinedMuon()]);
1445  }
1446 
1447  LogDebug("MuonIdentification") << "tkChiVal " << aMuon.combinedQuality().trkRelChi2;
1448 }
1449 
1451  // skip muons with no tracks
1452  if (aMuon.innerTrack().isNull())
1453  return;
1454  // get quality from muon if already there, otherwise make empty one
1456  // fill it
1457  const bool filled = trackerKinkFinder_->fillTrkKink(quality, *aMuon.innerTrack());
1458  // if quality was there, or if we filled it, commit to the muon
1459  if (filled || aMuon.isQualityValid())
1460  aMuon.setCombinedQuality(quality);
1461 }
1462 
1464  const bool trackBAD = links->trackerTrack().isNull();
1465  const bool staBAD = links->standAloneTrack().isNull();
1466  const bool glbBAD = links->globalTrack().isNull();
1467  if (trackBAD || staBAD || glbBAD) {
1468  edm::LogWarning("muonIDbadLinks") << "Global muon links to constituent tracks are invalid: trkBad " << trackBAD
1469  << " standaloneBad " << staBAD << " globalBad " << glbBAD
1470  << ". There should be no such object. Muon is skipped.";
1471  return false;
1472  }
1473  return true;
1474 }
1475 
1478  desc.setAllowAnything();
1479 
1480  desc.add<bool>("arbitrateTrackerMuons", false);
1481  desc.add<bool>("storeCrossedHcalRecHits", false);
1482  desc.add<bool>("fillShowerDigis", false);
1483  desc.ifValue(
1484  edm::ParameterDescription<bool>("selectHighPurity", false, true),
1485  true >> (edm::ParameterDescription<edm::InputTag>("pvInputTag", edm::InputTag("offlinePrimaryVertices"), true)) or
1486  false >> (edm::ParameterDescription<edm::InputTag>("pvInputTag", edm::InputTag(""), true)));
1487 
1488  edm::ParameterSetDescription descTrkAsoPar;
1489  descTrkAsoPar.add<edm::InputTag>("GEMSegmentCollectionLabel", edm::InputTag("gemSegments"));
1490  descTrkAsoPar.add<edm::InputTag>("ME0SegmentCollectionLabel", edm::InputTag("me0Segments"));
1491  descTrkAsoPar.add<bool>("useGEM", false);
1492  descTrkAsoPar.add<bool>("useME0", false);
1493  descTrkAsoPar.setAllowAnything();
1494  desc.add<edm::ParameterSetDescription>("TrackAssociatorParameters", descTrkAsoPar);
1495 
1497  descJet.setAllowAnything();
1498  descJet.add<edm::ParameterSetDescription>("TrackAssociatorParameters", descTrkAsoPar);
1499  desc.add<edm::ParameterSetDescription>("JetExtractorPSet", descJet);
1500 
1502  descCalo.setAllowAnything();
1503  descCalo.add<edm::ParameterSetDescription>("TrackAssociatorParameters", descTrkAsoPar);
1504  desc.add<edm::ParameterSetDescription>("CaloExtractorPSet", descCalo);
1505 
1506  descriptions.addDefault(desc);
1507 }
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:303
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
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
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
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:24
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
constexpr std::array< uint8_t, layerIndexSize > layer
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
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
bool getData(T &iHolder) const
Definition: EventSetup.h:122
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::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
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
string quality
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
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
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_