CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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");
53  maxAbsPullX2_ *= maxAbsPullX2_;
54  maxAbsDy_ = iConfig.getParameter<double>("maxAbsDy");
55  maxAbsPullY2_ = iConfig.getParameter<double>("maxAbsPullY");
56  maxAbsPullY2_ *= maxAbsPullY2_;
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;
70  if (fillGlobalTrackQuality_)
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();
83  parameters_.loadParameters(parameters, iC);
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
90  if (fillShowerDigis_ && fillMatching_) {
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  }
120  if (fillIsolation_ && writeIsoDeposits_) {
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  }
151  if (fillGlobalTrackQuality_) {
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  //Consumes... UGH
174  for (unsigned int i = 0; i < inputCollectionLabels_.size(); ++i) {
175  const auto inputLabel = inputCollectionLabels_[i];
176  const auto inputType = ICTypes::toKey(inputCollectionTypes[i]); // Note: thorws exception if type is undefined.
177 
178  if (inputType == ICTypes::INNER_TRACKS) {
179  innerTrackCollectionToken_ = consumes<reco::TrackCollection>(inputLabel);
180  } else if (inputType == ICTypes::OUTER_TRACKS) {
181  outerTrackCollectionToken_ = consumes<reco::TrackCollection>(inputLabel);
182  } else if (inputType == ICTypes::LINKS) {
183  linkCollectionToken_ = consumes<reco::MuonTrackLinksCollection>(inputLabel);
184  } else if (inputType == ICTypes::MUONS) {
185  muonCollectionToken_ = consumes<reco::MuonCollection>(inputLabel);
186  } else if (inputType == ICTypes::TEV_FIRSTHIT) {
187  tpfmsCollectionToken_ = consumes<reco::TrackToTrackMap>(inputLabel);
188  } else if (fillGlobalTrackRefits_ && inputType == ICTypes::TEV_PICKY) {
189  pickyCollectionToken_ = consumes<reco::TrackToTrackMap>(inputLabel);
190  } else if (fillGlobalTrackRefits_ && inputType == ICTypes::TEV_DYT) {
191  dytCollectionToken_ = consumes<reco::TrackToTrackMap>(inputCollectionLabels_.at(i));
192  }
193 
194  inputCollectionTypes_[i] = inputType;
195  }
196 }
197 
199  // TimingReport::current()->dump(std::cout);
200 }
201 
207 
211 
213 
214  if (fillTrackerKink_)
215  trackerKinkFinder_->init(iSetup);
216 
217  for (unsigned int i = 0; i < inputCollectionLabels_.size(); ++i) {
218  const auto& inputLabel = inputCollectionLabels_[i];
219  const auto inputType = inputCollectionTypes_[i];
220  if (inputType == ICTypes::INNER_TRACKS) {
223  throw cms::Exception("FatalError") << "Failed to get input track collection with label: " << inputLabel;
224  LogTrace("MuonIdentification") << "Number of input inner tracks: " << innerTrackCollectionHandle_->size();
225  } else if (inputType == ICTypes::OUTER_TRACKS) {
228  throw cms::Exception("FatalError") << "Failed to get input track collection with label: " << inputLabel;
229  LogTrace("MuonIdentification") << "Number of input outer tracks: " << outerTrackCollectionHandle_->size();
230  } else if (inputType == ICTypes::LINKS) {
233  throw cms::Exception("FatalError") << "Failed to get input link collection with label: " << inputLabel;
234  LogTrace("MuonIdentification") << "Number of input links: " << linkCollectionHandle_->size();
235  } else if (inputType == ICTypes::MUONS) {
238  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
239  LogTrace("MuonIdentification") << "Number of input muons: " << muonCollectionHandle_->size();
240  } else if (fillGlobalTrackRefits_ && inputType == ICTypes::TEV_FIRSTHIT) {
243  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
244  LogTrace("MuonIdentification") << "Number of input muons: " << tpfmsCollectionHandle_->size();
245  } else if (fillGlobalTrackRefits_ && inputType == ICTypes::TEV_PICKY) {
248  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
249  LogTrace("MuonIdentification") << "Number of input muons: " << pickyCollectionHandle_->size();
250  } else if (fillGlobalTrackRefits_ && inputType == ICTypes::TEV_DYT) {
253  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
254  LogTrace("MuonIdentification") << "Number of input muons: " << dytCollectionHandle_->size();
255  } else
256  throw cms::Exception("FatalError") << "Unknown input collection type: #" << ICTypes::toStr(inputType);
257  }
258 
262  if (selectHighPurity_)
263  iEvent.getByToken(pvToken_, pvHandle_);
264 }
265 
267  const edm::EventSetup& iSetup,
268  const reco::TrackRef& track,
270  LogTrace("MuonIdentification") << "Creating a muon from a track " << track.get()->pt()
271  << " Pt (GeV), eta: " << track.get()->eta();
272  reco::Muon aMuon(makeMuon(*(track.get())));
273 
274  LogTrace("MuonIdentification") << "Muon created from a track ";
275 
276  aMuon.setMuonTrack(type, track);
277  aMuon.setBestTrack(type);
278  aMuon.setTunePBestTrack(type);
279 
280  LogTrace("MuonIdentification")
281  << "Muon created from a track and setMuonBestTrack, setBestTrack and setTunePBestTrack called";
282 
283  return aMuon;
284 }
285 
287  LogTrace("MuonIdentification") << "Creating a CaloMuon from a Muon";
288 
289  reco::CaloMuon aMuon;
290  aMuon.setInnerTrack(muon.innerTrack());
291 
292  if (muon.isEnergyValid())
293  aMuon.setCalEnergy(muon.calEnergy());
294  // get calo compatibility
297  return aMuon;
298 }
299 
301  LogTrace("MuonIdentification") << "Creating a muon from a link to tracks object";
302 
303  reco::Muon aMuon;
304  reco::Muon::MuonTrackTypePair chosenTrack;
305  reco::TrackRef tpfmsRef;
306  reco::TrackRef pickyRef;
307  reco::TrackRef dytRef;
308  bool useSigmaSwitch = false;
309 
315 
316  if (tpfmsRef.isNull() && pickyRef.isNull() && dytRef.isNull()) {
317  edm::LogWarning("MakeMuonWithTEV") << "Failed to get TEV refits, fall back to sigma switch.";
318  useSigmaSwitch = true;
319  }
320  } else {
321  useSigmaSwitch = true;
322  }
323 
324  if (useSigmaSwitch) {
325  chosenTrack = muon::sigmaSwitch(links.globalTrack(),
326  links.trackerTrack(),
329  } else {
330  chosenTrack = muon::tevOptimized(links.globalTrack(),
331  links.trackerTrack(),
332  tpfmsRef,
333  pickyRef,
334  dytRef,
336  }
337  aMuon = makeMuon(*chosenTrack.first);
338  aMuon.setInnerTrack(links.trackerTrack());
339  aMuon.setOuterTrack(links.standAloneTrack());
340  aMuon.setGlobalTrack(links.globalTrack());
341  aMuon.setBestTrack(chosenTrack.second);
342  aMuon.setTunePBestTrack(chosenTrack.second);
343 
347  if (it != tpfmsCollectionHandle_->end())
348  aMuon.setMuonTrack(reco::Muon::TPFMS, (it->val));
349  }
352  if (it != pickyCollectionHandle_->end())
353  aMuon.setMuonTrack(reco::Muon::Picky, (it->val));
354  }
357  if (it != dytCollectionHandle_->end())
358  aMuon.setMuonTrack(reco::Muon::DYT, (it->val));
359  }
360  }
361  return aMuon;
362 }
363 
365  // Pt and absolute momentum requirement
366  const double p = track.p();
367  const double pt = track.pt();
368  if (pt < minPt_ || (p < minP_ && p < minPCaloMuon_)) {
369  LogTrace("MuonIdentification") << "Skipped low momentum track (Pt,P): " << pt << ", " << track.p() << " GeV";
370  return false;
371  }
372 
373  // Eta requirement
374  const double eta = track.eta();
375  const double absEta = std::abs(eta);
376  if (absEta > maxAbsEta_) {
377  LogTrace("MuonIdentification") << "Skipped track with large pseudo rapidity (Eta: " << track.eta() << " )";
378  return false;
379  }
380 
381  return true;
382 }
383 
384 unsigned int MuonIdProducer::chamberId(const DetId& id) {
385  if (id.det() != DetId::Muon)
386  return 0;
387 
388  const auto subdetId = id.subdetId();
389  if (subdetId == MuonSubdetId::DT) {
390  return DTChamberId(id.rawId()).rawId();
391  } else if (subdetId == MuonSubdetId::CSC) {
392  return CSCDetId(id.rawId()).chamberId().rawId();
393  }
394 
395  return 0;
396 }
397 
399  if (!muon.isMatchesValid() || track.extra().isNull() || track.extra()->recHitsSize() == 0)
400  return 0;
401 
402  int numberOfCommonDetIds = 0;
403  const std::vector<reco::MuonChamberMatch>& matches(muon.matches());
404  for (const auto& match : matches) {
405  if (match.segmentMatches.empty())
406  continue;
407 
408  bool foundCommonDetId = false;
409  for (auto hit = track.extra()->recHitsBegin(); hit != track.extra()->recHitsEnd(); ++hit) {
410  // LogTrace("MuonIdentification") << "hit DetId: " << std::hex << hit->get()->geographicalId().rawId() <<
411  // "\t hit chamber DetId: " << getChamberId(hit->get()->geographicalId()) <<
412  // "\t segment DetId: " << match->id.rawId() << std::dec;
413 
414  if (chamberId((*hit)->geographicalId()) == match.id.rawId()) {
415  foundCommonDetId = true;
416  break;
417  }
418  }
419  if (foundCommonDetId) {
420  ++numberOfCommonDetIds;
421  break;
422  }
423  }
424  return numberOfCommonDetIds;
425 }
426 
427 void MuonIdProducer::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {
428  meshAlgo_->setCSCGeometry(&iSetup.getData(geomTokenRun_));
429 
431  theShowerDigiFiller_->getES(iSetup);
432 }
433 
434 bool validateGlobalMuonPair(const reco::MuonTrackLinks& goodMuon, const reco::MuonTrackLinks& badMuon) {
435  const int nHitsGood = goodMuon.globalTrack()->hitPattern().numberOfValidMuonHits();
436  const int nHitsBad = badMuon.globalTrack()->hitPattern().numberOfValidMuonHits();
437  if (std::min(nHitsGood, nHitsBad) > 10) {
438  const double chi2Good = goodMuon.globalTrack()->normalizedChi2();
439  const double chi2Bad = badMuon.globalTrack()->normalizedChi2();
440  return (chi2Good <= chi2Bad);
441  }
442 
443  return (nHitsGood >= nHitsBad);
444 }
445 
447  auto outputMuons = std::make_unique<reco::MuonCollection>();
448  auto caloMuons = std::make_unique<reco::CaloMuonCollection>();
449 
450  init(iEvent, iSetup);
451 
453  theShowerDigiFiller_->getDigis(iEvent);
454 
455  // loop over input collections
456 
457  // muons first - no cleaning, take as is.
459  for (const auto& muon : *muonCollectionHandle_) {
460  outputMuons->push_back(muon);
461  }
462  }
463 
464  // links second ( assume global muon type )
466  const auto nLink = linkCollectionHandle_->size();
467  std::vector<bool> goodmuons(nLink, true);
468  if (nLink > 1) {
469  // check for shared tracker tracks
470  for (unsigned int i = 0; i < nLink - 1; ++i) {
471  const auto& iLink = linkCollectionHandle_->at(i);
472  if (iLink.trackerTrack().isNull() || !checkLinks(&iLink))
473  continue;
474  for (unsigned int j = i + 1; j < nLink; ++j) {
475  const auto& jLink = linkCollectionHandle_->at(j);
476  if (!checkLinks(&jLink))
477  continue;
478  if (iLink.trackerTrack() == jLink.trackerTrack()) {
479  // Tracker track is the essential part that dominates muon resolution
480  // so taking either muon is fine. All that is important is to preserve
481  // the muon identification information. If number of hits is small,
482  // keep the one with large number of hits, otherwise take the smalest chi2/ndof
483  if (validateGlobalMuonPair(iLink, jLink))
484  goodmuons[j] = false;
485  else
486  goodmuons[i] = false;
487  }
488  }
489  }
490  // check for shared stand-alone muons.
491  for (unsigned int i = 0; i < nLink - 1; ++i) {
492  if (!goodmuons[i])
493  continue;
494  const auto& iLink = linkCollectionHandle_->at(i);
495  if (iLink.standAloneTrack().isNull() || !checkLinks(&iLink))
496  continue;
497  for (unsigned int j = i + 1; j < nLink; ++j) {
498  if (!goodmuons[j])
499  continue;
500  const auto& jLink = linkCollectionHandle_->at(j);
501  if (!checkLinks(&jLink))
502  continue;
503  if (iLink.standAloneTrack() == jLink.standAloneTrack()) {
504  if (validateGlobalMuonPair(iLink, jLink))
505  goodmuons[j] = false;
506  else
507  goodmuons[i] = false;
508  }
509  }
510  }
511  }
512  for (unsigned int i = 0; i < nLink; ++i) {
513  if (!goodmuons[i])
514  continue;
515  const auto& iLink = linkCollectionHandle_->at(i);
516  if (!checkLinks(&iLink))
517  continue;
518  // check if this muon is already in the list
519  bool newMuon = true;
520  for (const auto& muon : *outputMuons) {
521  if (muon.track() == iLink.trackerTrack() && muon.standAloneMuon() == iLink.standAloneTrack() &&
522  muon.combinedMuon() == iLink.globalTrack()) {
523  newMuon = false;
524  break;
525  }
526  }
527  if (newMuon) {
528  outputMuons->push_back(makeMuon(iLink));
529  outputMuons->back().setType(reco::Muon::GlobalMuon | reco::Muon::StandAloneMuon);
530  }
531  }
532  }
533 
534  // tracker and calo muons are next
536  LogTrace("MuonIdentification") << "Creating tracker muons";
537  std::vector<TrackDetectorAssociator::Direction> directions1, directions2;
538  directions1.push_back(TrackDetectorAssociator::InsideOut);
539  directions1.push_back(TrackDetectorAssociator::OutsideIn);
540  directions2.push_back(TrackDetectorAssociator::Any);
541 
542  const GlobalTrackingGeometry* geometry = nullptr;
544  geometry = &iSetup.getData(globalGeomToken_);
545  }
546 
547  for (unsigned int i = 0; i < innerTrackCollectionHandle_->size(); ++i) {
549  if (!isGoodTrack(track))
550  continue;
552  const reco::VertexCollection* recoVertices = pvHandle_.product();
553  if (!(*recoVertices)[0].isFake())
554  continue;
555  }
556  const auto& trackRef = reco::TrackRef(innerTrackCollectionHandle_, i);
557  bool splitTrack = false;
558  if (track.extra().isAvailable() && TrackDetectorAssociator::crossedIP(track))
559  splitTrack = true;
560  const auto& directions = splitTrack ? directions1 : directions2;
561  for (const auto direction : directions) {
562  // make muon
563  reco::Muon trackerMuon(makeMuon(iEvent, iSetup, trackRef, reco::Muon::InnerTrack));
564  fillMuonId(iEvent, iSetup, trackerMuon, direction);
565 
567  // add MC hits to a list of matched segments.
568  // Since it's debugging mode - code is slow
569  MuonIdTruthInfo::truthMatchMuon(iEvent, *geometry, trackerMuon);
570  }
571 
572  // check if this muon is already in the list
573  // have to check where muon hits are really located
574  // to match properly
575  bool newMuon = true;
576  const bool goodTrackerMuon = isGoodTrackerMuon(trackerMuon);
577  const bool goodRPCMuon = isGoodRPCMuon(trackerMuon);
578  const bool goodGEMMuon = isGoodGEMMuon(trackerMuon);
579  const bool goodME0Muon = isGoodME0Muon(trackerMuon);
580  if (goodTrackerMuon)
581  trackerMuon.setType(trackerMuon.type() | reco::Muon::TrackerMuon);
582  if (goodRPCMuon)
583  trackerMuon.setType(trackerMuon.type() | reco::Muon::RPCMuon);
584  if (goodGEMMuon)
585  trackerMuon.setType(trackerMuon.type() | reco::Muon::GEMMuon);
586  if (goodME0Muon)
587  trackerMuon.setType(trackerMuon.type() | reco::Muon::ME0Muon);
588 
589  for (auto& muon : *outputMuons) {
590  if (muon.innerTrack().get() == trackerMuon.innerTrack().get() &&
592  M_PI_2) {
593  newMuon = false;
594  muon.setMatches(trackerMuon.matches());
595  if (trackerMuon.isTimeValid())
596  muon.setTime(trackerMuon.time());
597  if (trackerMuon.isEnergyValid())
598  muon.setCalEnergy(trackerMuon.calEnergy());
599  if (goodTrackerMuon)
600  muon.setType(muon.type() | reco::Muon::TrackerMuon);
601  if (goodRPCMuon)
602  muon.setType(muon.type() | reco::Muon::RPCMuon);
603  if (goodGEMMuon)
604  muon.setType(muon.type() | reco::Muon::GEMMuon);
605  if (goodME0Muon)
606  muon.setType(muon.type() | reco::Muon::ME0Muon);
607  LogTrace("MuonIdentification") << "Found a corresponding global muon. Set energy, matches and move on";
608  break;
609  }
610  }
611  if (newMuon) {
612  if (goodTrackerMuon || goodRPCMuon || goodGEMMuon || goodME0Muon) {
613  outputMuons->push_back(trackerMuon);
614  } else {
615  LogTrace("MuonIdentification") << "track failed minimal number of muon matches requirement";
616  const reco::CaloMuon& caloMuon = makeCaloMuon(trackerMuon);
617  if (isGoodCaloMuon(caloMuon))
618  caloMuons->push_back(caloMuon);
619  }
620  }
621  }
622  }
623  }
624 
625  // and at last the stand alone muons
627  LogTrace("MuonIdentification") << "Looking for new muons among stand alone muon tracks";
628  for (unsigned int i = 0; i < outerTrackCollectionHandle_->size(); ++i) {
629  const auto& outerTrack = outerTrackCollectionHandle_->at(i);
630 
631  // check if this muon is already in the list of global muons
632  bool newMuon = true;
633  for (auto& muon : *outputMuons) {
634  if (!muon.standAloneMuon().isNull()) {
635  // global muon
636  if (muon.standAloneMuon().get() == &outerTrack) {
637  newMuon = false;
638  break;
639  }
640  } else {
641  // tracker muon - no direct links to the standalone muon
642  // since we have only a few real muons in an event, matching
643  // the stand alone muon to the tracker muon by DetIds should
644  // be good enough for association. At the end it's up to a
645  // user to redefine the association and what it means. Here
646  // we would like to avoid obvious double counting and we
647  // tolerate a potential miss association
648  if (overlap(muon, outerTrack) > 0) {
649  LogTrace("MuonIdentification") << "Found associated tracker muon. Set a reference and move on";
650  newMuon = false;
652  muon.setType(muon.type() | reco::Muon::StandAloneMuon);
653  break;
654  }
655  }
656  }
657  if (newMuon) {
658  LogTrace("MuonIdentification") << "No associated stand alone track is found. Making a muon";
659  outputMuons->push_back(
661  outputMuons->back().setType(reco::Muon::StandAloneMuon);
662  }
663  }
664  }
665 
667  fillArbitrationInfo(outputMuons.get());
668  arbitrateMuons(outputMuons.get(), caloMuons.get());
669  }
670 
671  LogTrace("MuonIdentification") << "Dress up muons if it's necessary";
672 
673  const int nMuons = outputMuons->size();
674 
675  std::vector<reco::MuonTimeExtra> dtTimeColl(nMuons);
676  std::vector<reco::MuonTimeExtra> cscTimeColl(nMuons);
677  std::vector<reco::MuonTimeExtra> combinedTimeColl(nMuons);
678  std::vector<reco::IsoDeposit> trackDepColl(nMuons);
679  std::vector<reco::IsoDeposit> ecalDepColl(nMuons);
680  std::vector<reco::IsoDeposit> hcalDepColl(nMuons);
681  std::vector<reco::IsoDeposit> hoDepColl(nMuons);
682  std::vector<reco::IsoDeposit> jetDepColl(nMuons);
683 
684  // Fill various information
685  for (unsigned int i = 0; i < outputMuons->size(); ++i) {
686  auto& muon = outputMuons->at(i);
687 
688  // Fill muonID
689  if ((fillMatching_ && !muon.isMatchesValid()) || (fillEnergy_ && !muon.isEnergyValid())) {
690  // predict direction based on the muon interaction region location
691  // if it's available
692  if (muon.isStandAloneMuon()) {
695  } else {
697  }
698  } else {
699  LogTrace("MuonIdentification") << "THIS SHOULD NEVER HAPPEN";
700  fillMuonId(iEvent, iSetup, muon);
701  }
702  }
703 
705  // Fill global quality information
706  fillGlbQuality(iEvent, iSetup, muon);
707  }
708  LogDebug("MuonIdentification") << "";
709 
710  if (fillTrackerKink_) {
712  }
713 
715  muon.setCaloCompatibility(muonCaloCompatibility_.evaluate(muon));
716 
717  if (fillIsolation_) {
719  iEvent, iSetup, muon, trackDepColl[i], ecalDepColl[i], hcalDepColl[i], hoDepColl[i], jetDepColl[i]);
720  }
721 
722  // fill timing information
723  reco::MuonTime muonTime;
724  reco::MuonTimeExtra dtTime;
725  reco::MuonTimeExtra cscTime;
726  reco::MuonTime rpcTime;
727  reco::MuonTimeExtra combinedTime;
728 
729  theTimingFiller_->fillTiming(muon, dtTime, cscTime, rpcTime, combinedTime, iEvent, iSetup);
730 
731  muonTime.nDof = combinedTime.nDof();
732  muonTime.timeAtIpInOut = combinedTime.timeAtIpInOut();
733  muonTime.timeAtIpInOutErr = combinedTime.timeAtIpInOutErr();
734  muonTime.timeAtIpOutIn = combinedTime.timeAtIpOutIn();
735  muonTime.timeAtIpOutInErr = combinedTime.timeAtIpOutInErr();
736 
737  muon.setTime(muonTime);
738  muon.setRPCTime(rpcTime);
739  dtTimeColl[i] = dtTime;
740  cscTimeColl[i] = cscTime;
741  combinedTimeColl[i] = combinedTime;
742  }
743 
744  LogTrace("MuonIdentification") << "number of muons produced: " << outputMuons->size();
745  if (fillMatching_) {
746  fillArbitrationInfo(outputMuons.get(), reco::Muon::TrackerMuon);
747  fillArbitrationInfo(outputMuons.get(), reco::Muon::ME0Muon);
748  fillArbitrationInfo(outputMuons.get(), reco::Muon::GEMMuon);
749  }
750  edm::OrphanHandle<reco::MuonCollection> muonHandle = iEvent.put(std::move(outputMuons));
751 
752  auto fillMap = [](auto refH, auto& vec, edm::Event& ev, const std::string& cAl = "") {
754  auto oMap = std::make_unique<MapType>();
755  {
756  typename MapType::Filler filler(*oMap);
757  filler.insert(refH, vec.begin(), vec.end());
758  vec.clear();
759  filler.fill();
760  }
761  ev.put(std::move(oMap), cAl);
762  };
763  fillMap(muonHandle, combinedTimeColl, iEvent, "combined");
764  fillMap(muonHandle, dtTimeColl, iEvent, "dt");
765  fillMap(muonHandle, cscTimeColl, iEvent, "csc");
766 
768  fillMap(muonHandle, trackDepColl, iEvent, trackDepositName_);
769  fillMap(muonHandle, ecalDepColl, iEvent, ecalDepositName_);
770  fillMap(muonHandle, hcalDepColl, iEvent, hcalDepositName_);
771  fillMap(muonHandle, hoDepColl, iEvent, hoDepositName_);
772  fillMap(muonHandle, jetDepColl, iEvent, jetDepositName_);
773  }
774 
775  iEvent.put(std::move(caloMuons));
776 }
777 
779  if (muon.track()->pt() < minPt_ || muon.track()->p() < minP_)
780  return false;
781  if (addExtraSoftMuons_ && muon.pt() < 5 && std::abs(muon.eta()) < 1.5 &&
783  return true;
785 }
786 
788  if (!caloMuon.isCaloCompatibilityValid() || caloMuon.caloCompatibility() < caloCut_ || caloMuon.p() < minPCaloMuon_)
789  return false;
790  return true;
791 }
792 
794  if (muon.track()->pt() < minPt_ || muon.track()->p() < minP_)
795  return false;
796  if (addExtraSoftMuons_ && muon.pt() < 5 && std::abs(muon.eta()) < 1.5 &&
798  return true;
800 }
801 
803  if (muon.track()->pt() < minPt_ || muon.track()->p() < minP_)
804  return false;
806 }
807 
809  // need to update min cuts on pt
810  if (muon.track()->p() < minP_)
811  return false;
813 }
814 
816  const edm::EventSetup& iSetup,
817  reco::Muon& aMuon,
819  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId";
820 
821  // perform track - detector association
822  const reco::Track* track = nullptr;
823  if (aMuon.track().isNonnull())
824  track = aMuon.track().get();
825  else if (aMuon.standAloneMuon().isNonnull())
826  track = aMuon.standAloneMuon().get();
827  else
828  throw cms::Exception("FatalError")
829  << "Failed to fill muon id information for a muon with undefined references to tracks";
830 
831  TrackDetMatchInfo info = trackAssociator_.associate(iEvent, iSetup, *track, parameters_, direction);
832 
833  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId :: fillEnergy = " << fillEnergy_;
834 
835  if (fillEnergy_) {
836  reco::MuonEnergy muonEnergy;
839  muonEnergy.ho = info.crossedEnergy(TrackDetMatchInfo::HORecHits);
841  muonEnergy.emS9 = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits, 1); // 3x3 energy
842  muonEnergy.emS25 = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits, 2); // 5x5 energy
843  muonEnergy.hadS9 = info.nXnEnergy(TrackDetMatchInfo::HcalRecHits, 1); // 3x3 energy
844  muonEnergy.hoS9 = info.nXnEnergy(TrackDetMatchInfo::HORecHits, 1); // 3x3 energy
845  muonEnergy.towerS9 = info.nXnEnergy(TrackDetMatchInfo::TowerTotal, 1); // 3x3 energy
847  muonEnergy.crossedHadRecHits.clear();
848  for (auto hit : info.crossedHcalRecHits) {
850  mhit.energy = hit->energy();
851  mhit.chi2 = hit->chi2();
852  mhit.time = hit->time();
853  mhit.detId = hit->id();
854  muonEnergy.crossedHadRecHits.push_back(mhit);
855  }
856  }
857  muonEnergy.ecal_position = info.trkGlobPosAtEcal;
858  muonEnergy.hcal_position = info.trkGlobPosAtHcal;
859  if (!info.crossedEcalIds.empty())
860  muonEnergy.ecal_id = info.crossedEcalIds.front();
861  if (!info.crossedHcalIds.empty())
862  muonEnergy.hcal_id = info.crossedHcalIds.front();
863  // find maximal energy depositions and their time
864  DetId emMaxId = info.findMaxDeposition(TrackDetMatchInfo::EcalRecHits, 2); // max energy deposit in 5x5 shape
865  for (const auto& hit : info.ecalRecHits) {
866  if (hit->id() != emMaxId)
867  continue;
868  muonEnergy.emMax = hit->energy();
869  muonEnergy.ecal_time = hit->time();
870  }
871  DetId hadMaxId = info.findMaxDeposition(TrackDetMatchInfo::HcalRecHits, 1); // max energy deposit in 3x3 shape
872  for (const auto& hit : info.hcalRecHits) {
873  if (hit->id() != hadMaxId)
874  continue;
875  muonEnergy.hadMax = hit->energy();
876  muonEnergy.hcal_time = hit->time();
877  }
878  aMuon.setCalEnergy(muonEnergy);
879  }
880  if (!fillMatching_ && !aMuon.isTrackerMuon() && !aMuon.isRPCMuon())
881  return;
882 
883  // fill muon match info
884  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId :: fill muon match info ";
885  std::vector<reco::MuonChamberMatch> muonChamberMatches;
886  unsigned int nubmerOfMatchesAccordingToTrackAssociator = 0;
887  for (const auto& chamber : info.chambers) {
888  if (chamber.id.subdetId() == MuonSubdetId::RPC && rpcHitHandle_.isValid())
889  continue; // Skip RPC chambers, they are taken care of below)
890  reco::MuonChamberMatch matchedChamber;
891 
892  const auto& lErr = chamber.tState.localError();
893  const auto& lPos = chamber.tState.localPosition();
894  const auto& lDir = chamber.tState.localDirection();
895 
896  const auto& localError = lErr.positionError();
897  matchedChamber.x = lPos.x();
898  matchedChamber.y = lPos.y();
899  matchedChamber.xErr = sqrt(localError.xx());
900  matchedChamber.yErr = sqrt(localError.yy());
901 
902  matchedChamber.dXdZ = lDir.z() != 0 ? lDir.x() / lDir.z() : 9999;
903  matchedChamber.dYdZ = lDir.z() != 0 ? lDir.y() / lDir.z() : 9999;
904  // DANGEROUS - compiler cannot guaranty parameters ordering
905  AlgebraicSymMatrix55 trajectoryCovMatrix = lErr.matrix();
906  matchedChamber.dXdZErr = trajectoryCovMatrix(1, 1) > 0 ? sqrt(trajectoryCovMatrix(1, 1)) : 0;
907  matchedChamber.dYdZErr = trajectoryCovMatrix(2, 2) > 0 ? sqrt(trajectoryCovMatrix(2, 2)) : 0;
908 
909  matchedChamber.edgeX = chamber.localDistanceX;
910  matchedChamber.edgeY = chamber.localDistanceY;
911 
912  matchedChamber.id = chamber.id;
913 
915  theShowerDigiFiller_->fill(matchedChamber);
916  } else {
917  theShowerDigiFiller_->fillDefault(matchedChamber);
918  }
919 
920  if (!chamber.segments.empty())
921  ++nubmerOfMatchesAccordingToTrackAssociator;
922 
923  // fill segments
924  for (const auto& segment : chamber.segments) {
925  reco::MuonSegmentMatch matchedSegment;
926  matchedSegment.x = segment.segmentLocalPosition.x();
927  matchedSegment.y = segment.segmentLocalPosition.y();
928  matchedSegment.dXdZ =
929  segment.segmentLocalDirection.z() ? segment.segmentLocalDirection.x() / segment.segmentLocalDirection.z() : 0;
930  matchedSegment.dYdZ =
931  segment.segmentLocalDirection.z() ? segment.segmentLocalDirection.y() / segment.segmentLocalDirection.z() : 0;
932  matchedSegment.xErr = segment.segmentLocalErrorXX > 0 ? sqrt(segment.segmentLocalErrorXX) : 0;
933  matchedSegment.yErr = segment.segmentLocalErrorYY > 0 ? sqrt(segment.segmentLocalErrorYY) : 0;
934  matchedSegment.dXdZErr = segment.segmentLocalErrorDxDz > 0 ? sqrt(segment.segmentLocalErrorDxDz) : 0;
935  matchedSegment.dYdZErr = segment.segmentLocalErrorDyDz > 0 ? sqrt(segment.segmentLocalErrorDyDz) : 0;
936  matchedSegment.t0 = segment.t0;
937  matchedSegment.mask = 0;
938  matchedSegment.dtSegmentRef = segment.dtSegmentRef;
939  matchedSegment.cscSegmentRef = segment.cscSegmentRef;
940  matchedSegment.gemSegmentRef = segment.gemSegmentRef;
941  matchedSegment.me0SegmentRef = segment.me0SegmentRef;
942  matchedSegment.hasZed_ = segment.hasZed;
943  matchedSegment.hasPhi_ = segment.hasPhi;
944  // test segment
945  bool matchedX = false;
946  bool matchedY = false;
947  LogTrace("MuonIdentification") << " matching local x, segment x: " << matchedSegment.x
948  << ", chamber x: " << matchedChamber.x << ", max: " << maxAbsDx_;
949  LogTrace("MuonIdentification") << " matching local y, segment y: " << matchedSegment.y
950  << ", chamber y: " << matchedChamber.y << ", max: " << maxAbsDy_;
951  const double matchedSegChDx = std::abs(matchedSegment.x - matchedChamber.x);
952  const double matchedSegChDy = std::abs(matchedSegment.y - matchedChamber.y);
953  if (matchedSegment.xErr > 0 && matchedChamber.xErr > 0)
954  LogTrace("MuonIdentification") << " xpull: "
955  << matchedSegChDx / std::sqrt(std::pow(matchedSegment.xErr, 2) +
956  std::pow(matchedChamber.xErr, 2));
957  if (matchedSegment.yErr > 0 && matchedChamber.yErr > 0)
958  LogTrace("MuonIdentification") << " ypull: "
959  << matchedSegChDy / std::sqrt(std::pow(matchedSegment.yErr, 2) +
960  std::pow(matchedChamber.yErr, 2));
961 
962  if (matchedSegChDx < maxAbsDx_)
963  matchedX = true;
964  else if (matchedSegment.xErr > 0 && matchedChamber.xErr > 0) {
965  const double invMatchedSegChPullX2 = std::pow(matchedSegment.xErr, 2) + std::pow(matchedChamber.xErr, 2);
966  if (matchedSegChDx * matchedSegChDx < maxAbsPullX2_ * invMatchedSegChPullX2)
967  matchedX = true;
968  }
969  if (matchedSegChDy < maxAbsDy_)
970  matchedY = true;
971  else if (matchedSegment.yErr > 0 && matchedChamber.yErr > 0) {
972  const double invMatchedSegChPullY2 = std::pow(matchedSegment.yErr, 2) + std::pow(matchedChamber.yErr, 2);
973  if (matchedSegChDy * matchedSegChDy < maxAbsPullY2_ * invMatchedSegChPullY2)
974  matchedY = true;
975  }
976  if (matchedX && matchedY) {
977  if (matchedChamber.id.subdetId() == MuonSubdetId::ME0)
978  matchedChamber.me0Matches.push_back(matchedSegment);
979  else if (matchedChamber.id.subdetId() == MuonSubdetId::GEM)
980  matchedChamber.gemMatches.push_back(matchedSegment);
981  else
982  matchedChamber.segmentMatches.push_back(matchedSegment);
983  }
984  }
985  muonChamberMatches.push_back(matchedChamber);
986  }
987 
988  // Fill RPC info
989  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId :: fill RPC info";
990  if (rpcHitHandle_.isValid()) {
991  for (const auto& chamber : info.chambers) {
992  if (chamber.id.subdetId() != MuonSubdetId::RPC)
993  continue; // Consider RPC chambers only
994  const auto& lErr = chamber.tState.localError();
995  const auto& lPos = chamber.tState.localPosition();
996  const auto& lDir = chamber.tState.localDirection();
997 
998  reco::MuonChamberMatch matchedChamber;
999 
1000  LocalError localError = lErr.positionError();
1001  matchedChamber.x = lPos.x();
1002  matchedChamber.y = lPos.y();
1003  matchedChamber.xErr = sqrt(localError.xx());
1004  matchedChamber.yErr = sqrt(localError.yy());
1005 
1006  matchedChamber.dXdZ = lDir.z() != 0 ? lDir.x() / lDir.z() : 9999;
1007  matchedChamber.dYdZ = lDir.z() != 0 ? lDir.y() / lDir.z() : 9999;
1008  // DANGEROUS - compiler cannot guaranty parameters ordering
1009  AlgebraicSymMatrix55 trajectoryCovMatrix = lErr.matrix();
1010  matchedChamber.dXdZErr = trajectoryCovMatrix(1, 1) > 0 ? sqrt(trajectoryCovMatrix(1, 1)) : 0;
1011  matchedChamber.dYdZErr = trajectoryCovMatrix(2, 2) > 0 ? sqrt(trajectoryCovMatrix(2, 2)) : 0;
1012 
1013  matchedChamber.edgeX = chamber.localDistanceX;
1014  matchedChamber.edgeY = chamber.localDistanceY;
1015 
1016  theShowerDigiFiller_->fillDefault(matchedChamber);
1017 
1018  matchedChamber.id = chamber.id;
1019 
1020  for (const auto& rpcRecHit : *rpcHitHandle_) {
1021  reco::MuonRPCHitMatch rpcHitMatch;
1022 
1023  if (rpcRecHit.rawId() != chamber.id.rawId())
1024  continue;
1025 
1026  rpcHitMatch.x = rpcRecHit.localPosition().x();
1027  rpcHitMatch.mask = 0;
1028  rpcHitMatch.bx = rpcRecHit.BunchX();
1029 
1030  const double absDx = std::abs(rpcRecHit.localPosition().x() - chamber.tState.localPosition().x());
1031  if (absDx <= 20 or absDx * absDx <= 16 * localError.xx())
1032  matchedChamber.rpcMatches.push_back(rpcHitMatch);
1033  }
1034 
1035  muonChamberMatches.push_back(matchedChamber);
1036  }
1037  }
1038 
1039  aMuon.setMatches(muonChamberMatches);
1040 
1041  LogTrace("MuonIdentification") << "number of muon chambers: " << aMuon.matches().size() << "\n"
1042  << "number of chambers with segments according to the associator requirements: "
1043  << nubmerOfMatchesAccordingToTrackAssociator;
1044  LogTrace("MuonIdentification") << "number of segment matches with the producer requirements: "
1046 
1047  // fillTime( iEvent, iSetup, aMuon );
1048 }
1049 
1052  // arbitrate TrackerMuons
1053  // if a muon was exclusively TrackerMuon check if it can be a calo muon
1054  for (reco::MuonCollection::iterator muon = muons->begin(); muon != muons->end();) {
1055  if (muon->isTrackerMuon()) {
1056  if (muon->numberOfMatches(arbitration) < minNumberOfMatches_) {
1057  // TrackerMuon failed arbitration
1058  // If not any other base type - erase the element
1059  // (PFMuon is not a base type)
1060  unsigned int mask = reco::Muon::TrackerMuon | reco::Muon::PFMuon;
1061  if ((muon->type() & (~mask)) == 0) {
1062  const reco::CaloMuon& caloMuon = makeCaloMuon(*muon);
1063  if (isGoodCaloMuon(caloMuon))
1064  caloMuons->push_back(caloMuon);
1065  muon = muons->erase(muon);
1066  continue;
1067  } else {
1068  muon->setType(muon->type() & (~reco::Muon::TrackerMuon));
1069  }
1070  }
1071  }
1072  muon++;
1073  }
1074 }
1075 
1076 void MuonIdProducer::fillArbitrationInfo(reco::MuonCollection* pOutputMuons, unsigned int muonType) {
1077  //
1078  // apply segment flags
1079  //
1080  std::vector<std::pair<reco::MuonChamberMatch*, reco::MuonSegmentMatch*> > chamberPairs; // for chamber segment sorting
1081  std::vector<std::pair<reco::MuonChamberMatch*, reco::MuonSegmentMatch*> > stationPairs; // for station segment sorting
1082  std::vector<std::pair<reco::MuonChamberMatch*, reco::MuonSegmentMatch*> >
1083  arbitrationPairs; // for muon segment arbitration
1084 
1085  // muonIndex1
1086  for (unsigned int muonIndex1 = 0; muonIndex1 < pOutputMuons->size(); ++muonIndex1) {
1087  auto& muon1 = pOutputMuons->at(muonIndex1);
1088  // chamberIter1
1089  for (auto& chamber1 : muon1.matches()) {
1090  // segmentIter1
1091  std::vector<reco::MuonSegmentMatch>* segmentMatches1 = getSegmentMatches(chamber1, muonType);
1092 
1093  if (segmentMatches1->empty())
1094  continue;
1095  chamberPairs.clear();
1096 
1097  for (auto& segment1 : *segmentMatches1) {
1098  chamberPairs.push_back(std::make_pair(&chamber1, &segment1));
1099  if (!segment1.isMask()) // has not yet been arbitrated
1100  {
1101  arbitrationPairs.clear();
1102  arbitrationPairs.push_back(std::make_pair(&chamber1, &segment1));
1103 
1104  // find identical segments with which to arbitrate
1105  // tracker muons only
1106  if (muon1.type() & muonType) {
1107  // muonIndex2
1108  for (unsigned int muonIndex2 = muonIndex1 + 1; muonIndex2 < pOutputMuons->size(); ++muonIndex2) {
1109  auto& muon2 = pOutputMuons->at(muonIndex2);
1110  // tracker muons only
1111  if (!(muon2.type() & muonType))
1112  continue;
1113  // chamberIter2
1114  for (auto& chamber2 : muon2.matches()) {
1115  // segmentIter2
1116  std::vector<reco::MuonSegmentMatch>* segmentMatches2 = getSegmentMatches(chamber2, muonType);
1117  for (auto& segment2 : *segmentMatches2) {
1118  if (segment2.isMask())
1119  continue; // has already been arbitrated
1120  if (approxEqual(segment2.x, segment1.x) && approxEqual(segment2.y, segment1.y) &&
1121  approxEqual(segment2.dXdZ, segment1.dXdZ) && approxEqual(segment2.dYdZ, segment1.dYdZ) &&
1122  approxEqual(segment2.xErr, segment1.xErr) && approxEqual(segment2.yErr, segment1.yErr) &&
1123  approxEqual(segment2.dXdZErr, segment1.dXdZErr) &&
1124  approxEqual(segment2.dYdZErr, segment1.dYdZErr)) {
1125  arbitrationPairs.push_back(std::make_pair(&chamber2, &segment2));
1126  }
1127  } // segmentIter2
1128  } // chamberIter2
1129  } // muonIndex2
1130  }
1131 
1132  // arbitration segment sort
1133  if (arbitrationPairs.empty())
1134  continue; // this should never happen
1135  if (arbitrationPairs.size() == 1) {
1136  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDRSlope);
1137  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDXSlope);
1138  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDR);
1139  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDX);
1140  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::Arbitrated);
1141  } else {
1142  sort(arbitrationPairs.begin(),
1143  arbitrationPairs.end(),
1145  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDRSlope);
1146  sort(arbitrationPairs.begin(),
1147  arbitrationPairs.end(),
1149  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDXSlope);
1150  sort(arbitrationPairs.begin(),
1151  arbitrationPairs.end(),
1153  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDR);
1154  sort(arbitrationPairs.begin(),
1155  arbitrationPairs.end(),
1157  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDX);
1158  for (auto& ap : arbitrationPairs) {
1159  ap.second->setMask(reco::MuonSegmentMatch::Arbitrated);
1160  }
1161  }
1162  }
1163 
1164  // setup me1a cleaning for later
1165  if (muonType == reco::Muon::TrackerMuon && chamber1.id.subdetId() == MuonSubdetId::CSC && arbClean_ &&
1166  CSCDetId(chamber1.id).ring() == 4) {
1167  for (auto& segment2 : chamber1.segmentMatches) {
1168  if (segment1.cscSegmentRef.isNull() || segment2.cscSegmentRef.isNull())
1169  continue;
1170  if (meshAlgo_->isDuplicateOf(segment1.cscSegmentRef, segment2.cscSegmentRef) &&
1171  (segment2.mask & 0x1e0000) && (segment1.mask & 0x1e0000)) {
1173  //if the track has lost the segment already through normal arbitration no need to do it again.
1174  }
1175  }
1176  } // mark all ME1/a duplicates that this track owns
1177 
1178  } // segmentIter1
1179 
1180  // chamber segment sort
1181  if (chamberPairs.empty())
1182  continue; // this should never happen
1183  if (chamberPairs.size() == 1) {
1184  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDRSlope);
1185  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDXSlope);
1186  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDR);
1187  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDX);
1188  } else {
1189  sort(chamberPairs.begin(),
1190  chamberPairs.end(),
1192  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDRSlope);
1193  sort(chamberPairs.begin(),
1194  chamberPairs.end(),
1196  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDXSlope);
1197  sort(chamberPairs.begin(),
1198  chamberPairs.end(),
1200  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDR);
1201  sort(chamberPairs.begin(),
1202  chamberPairs.end(),
1204  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDX);
1205  }
1206  } // chamberIter1
1207 
1208  // station segment sort
1209  for (int stationIndex = 1; stationIndex < 5; ++stationIndex) {
1210  for (int detectorIndex = 1; detectorIndex <= 5;
1211  ++detectorIndex) // 1-5, as in DataFormats/MuonDetId/interface/MuonSubdetId.h
1212  {
1213  stationPairs.clear();
1214 
1215  // chamberIter
1216  for (auto& chamber : muon1.matches()) {
1217  if (!(chamber.station() == stationIndex && chamber.detector() == detectorIndex))
1218  continue;
1219  std::vector<reco::MuonSegmentMatch>* segmentMatches = getSegmentMatches(chamber, muonType);
1220  if (segmentMatches->empty())
1221  continue;
1222 
1223  for (auto& segment : *segmentMatches) {
1224  stationPairs.push_back(std::make_pair(&chamber, &segment));
1225  }
1226  } // chamberIter
1227 
1228  if (stationPairs.empty())
1229  continue; // this may very well happen
1230  if (stationPairs.size() == 1) {
1231  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDRSlope);
1232  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDXSlope);
1233  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDR);
1234  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDX);
1235  } else {
1236  sort(stationPairs.begin(),
1237  stationPairs.end(),
1239  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDRSlope);
1240  sort(stationPairs.begin(),
1241  stationPairs.end(),
1243  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDXSlope);
1244  sort(stationPairs.begin(),
1245  stationPairs.end(),
1247  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDR);
1248  sort(stationPairs.begin(),
1249  stationPairs.end(),
1251  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDX);
1252  }
1253  }
1254  }
1255 
1256  } // muonIndex1
1257 
1258  if (arbClean_) {
1259  // clear old mesh, create and prune new mesh!
1260  meshAlgo_->clearMesh();
1261  meshAlgo_->runMesh(pOutputMuons);
1262  }
1263 }
1264 
1266  const edm::EventSetup& iSetup,
1267  reco::Muon& aMuon,
1268  reco::IsoDeposit& trackDep,
1269  reco::IsoDeposit& ecalDep,
1270  reco::IsoDeposit& hcalDep,
1271  reco::IsoDeposit& hoDep,
1272  reco::IsoDeposit& jetDep) {
1273  const reco::Track* track = nullptr;
1274  if (aMuon.track().isNonnull())
1275  track = aMuon.track().get();
1276  else if (aMuon.standAloneMuon().isNonnull())
1277  track = aMuon.standAloneMuon().get();
1278  else
1279  throw cms::Exception("FatalError")
1280  << "Failed to compute muon isolation information for a muon with undefined references to tracks";
1281 
1282  reco::MuonIsolation isoR03, isoR05;
1283 
1284  // get deposits
1285  reco::IsoDeposit depTrk = muIsoExtractorTrack_->deposit(iEvent, iSetup, *track);
1286  std::vector<reco::IsoDeposit> caloDeps = muIsoExtractorCalo_->deposits(iEvent, iSetup, *track);
1287  reco::IsoDeposit depJet = muIsoExtractorJet_->deposit(iEvent, iSetup, *track);
1288 
1289  if (caloDeps.size() != 3) {
1290  LogTrace("MuonIdentification") << "Failed to fill vector of calorimeter isolation deposits!";
1291  return;
1292  }
1293 
1294  reco::IsoDeposit depEcal = caloDeps.at(0);
1295  reco::IsoDeposit depHcal = caloDeps.at(1);
1296  reco::IsoDeposit depHo = caloDeps.at(2);
1297 
1298  //no need to copy outside if we don't write them
1299  if (writeIsoDeposits_) {
1300  trackDep = depTrk;
1301  ecalDep = depEcal;
1302  hcalDep = depHcal;
1303  hoDep = depHo;
1304  jetDep = depJet;
1305  }
1306 
1307  isoR03.sumPt = depTrk.depositWithin(0.3);
1308  isoR03.emEt = depEcal.depositWithin(0.3);
1309  isoR03.hadEt = depHcal.depositWithin(0.3);
1310  isoR03.hoEt = depHo.depositWithin(0.3);
1311  isoR03.nTracks = depTrk.depositAndCountWithin(0.3).second;
1312  isoR03.nJets = depJet.depositAndCountWithin(0.3).second;
1313  isoR03.trackerVetoPt = depTrk.candEnergy();
1314  isoR03.emVetoEt = depEcal.candEnergy();
1315  isoR03.hadVetoEt = depHcal.candEnergy();
1316  isoR03.hoVetoEt = depHo.candEnergy();
1317 
1318  isoR05.sumPt = depTrk.depositWithin(0.5);
1319  isoR05.emEt = depEcal.depositWithin(0.5);
1320  isoR05.hadEt = depHcal.depositWithin(0.5);
1321  isoR05.hoEt = depHo.depositWithin(0.5);
1322  isoR05.nTracks = depTrk.depositAndCountWithin(0.5).second;
1323  isoR05.nJets = depJet.depositAndCountWithin(0.5).second;
1324  isoR05.trackerVetoPt = depTrk.candEnergy();
1325  isoR05.emVetoEt = depEcal.candEnergy();
1326  isoR05.hadVetoEt = depHcal.candEnergy();
1327  isoR05.hoVetoEt = depHo.candEnergy();
1328 
1329  aMuon.setIsolation(isoR03, isoR05);
1330 }
1331 
1333  const double energy = std::sqrt(track.p() * track.p() + 0.105658369 * 0.105658369);
1334  const math::XYZTLorentzVector p4(track.px(), track.py(), track.pz(), energy);
1335  return reco::Muon(track.charge(), p4, track.vertex());
1336 }
1337 
1339  double phi = 0;
1340  if (id.subdetId() == MuonSubdetId::DT) { // DT
1341  DTChamberId muonId(id.rawId());
1342  if (muonId.sector() <= 12)
1343  phi = (muonId.sector() - 1) / 6. * M_PI;
1344  if (muonId.sector() == 13)
1345  phi = 3 / 6. * M_PI;
1346  if (muonId.sector() == 14)
1347  phi = 9 / 6. * M_PI;
1348  }
1349  if (id.subdetId() == MuonSubdetId::CSC) { // CSC
1350  CSCDetId muonId(id.rawId());
1351  phi = M_PI / 4 + (muonId.triggerSector() - 1) / 3. * M_PI;
1352  }
1353  if (phi > M_PI)
1354  phi -= 2 * M_PI;
1355  return phi;
1356 }
1357 
1359  if (muon.isStandAloneMuon())
1360  return muon.standAloneMuon()->innerPosition().phi();
1361  // the rest is tracker muon only
1362  if (muon.matches().empty()) {
1363  if (muon.innerTrack().isAvailable() && muon.innerTrack()->extra().isAvailable())
1364  return muon.innerTrack()->outerPosition().phi();
1365  else
1366  return muon.phi(); // makes little sense, but what else can I use
1367  }
1368  return sectorPhi(muon.matches().at(0).id);
1369 }
1370 
1373  aMuon.setCombinedQuality((*glbQualHandle_)[aMuon.combinedMuon()]);
1374  }
1375 
1376  LogDebug("MuonIdentification") << "tkChiVal " << aMuon.combinedQuality().trkRelChi2;
1377 }
1378 
1380  // skip muons with no tracks
1381  if (aMuon.innerTrack().isNull())
1382  return;
1383  // get quality from muon if already there, otherwise make empty one
1385  // fill it
1386  const bool filled = trackerKinkFinder_->fillTrkKink(quality, *aMuon.innerTrack());
1387  // if quality was there, or if we filled it, commit to the muon
1388  if (filled || aMuon.isQualityValid())
1389  aMuon.setCombinedQuality(quality);
1390 }
1391 
1393  const bool trackBAD = links->trackerTrack().isNull();
1394  const bool staBAD = links->standAloneTrack().isNull();
1395  const bool glbBAD = links->globalTrack().isNull();
1396  if (trackBAD || staBAD || glbBAD) {
1397  edm::LogWarning("muonIDbadLinks") << "Global muon links to constituent tracks are invalid: trkBad " << trackBAD
1398  << " standaloneBad " << staBAD << " globalBad " << glbBAD
1399  << ". There should be no such object. Muon is skipped.";
1400  return false;
1401  }
1402  return true;
1403 }
1404 
1407  desc.setAllowAnything();
1408 
1409  desc.add<bool>("arbitrateTrackerMuons", false);
1410  desc.add<bool>("storeCrossedHcalRecHits", false);
1411  desc.add<bool>("fillShowerDigis", false);
1412  desc.ifValue(
1413  edm::ParameterDescription<bool>("selectHighPurity", false, true),
1414  true >> (edm::ParameterDescription<edm::InputTag>("pvInputTag", edm::InputTag("offlinePrimaryVertices"), true)) or
1415  false >> (edm::ParameterDescription<edm::InputTag>("pvInputTag", edm::InputTag(""), true)));
1416 
1417  edm::ParameterSetDescription descTrkAsoPar;
1418  descTrkAsoPar.add<edm::InputTag>("GEMSegmentCollectionLabel", edm::InputTag("gemSegments"));
1419  descTrkAsoPar.add<edm::InputTag>("ME0SegmentCollectionLabel", edm::InputTag("me0Segments"));
1420  descTrkAsoPar.add<bool>("useGEM", false);
1421  descTrkAsoPar.add<bool>("useME0", false);
1422  descTrkAsoPar.setAllowAnything();
1423  desc.add<edm::ParameterSetDescription>("TrackAssociatorParameters", descTrkAsoPar);
1424 
1426  descJet.setAllowAnything();
1427  descJet.add<edm::ParameterSetDescription>("TrackAssociatorParameters", descTrkAsoPar);
1428  desc.add<edm::ParameterSetDescription>("JetExtractorPSet", descJet);
1429 
1431  descCalo.setAllowAnything();
1432  descCalo.add<edm::ParameterSetDescription>("TrackAssociatorParameters", descTrkAsoPar);
1433  desc.add<edm::ParameterSetDescription>("CaloExtractorPSet", descCalo);
1434 
1435  descriptions.addDefault(desc);
1436 }
std::string hoDepositName_
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
double p() const
momentum vector magnitude
Definition: TrackBase.h:631
bool isAvailable() const
Definition: Ref.h:537
float hadEt
hcal sum-Et
Definition: MuonIsolation.h:8
static const unsigned int BelongsToTrackByME1aClean
std::string jetDepositName_
double candEnergy() const
Get energy or pT attached to cand trajectory.
Definition: IsoDeposit.h:129
bool isGoodRPCMuon(const reco::Muon &muon)
ParameterDescriptionNode * ifValue(ParameterDescription< T > const &switchParameter, std::unique_ptr< ParameterDescriptionCases< T >> cases)
int numberOfMatchedRPCLayers(ArbitrationType type=RPCHitAndTrackArbitration) const
float xx() const
Definition: LocalError.h:22
edm::EDGetTokenT< reco::TrackCollection > innerTrackCollectionToken_
reco::Muon makeMuon(edm::Event &iEvent, const edm::EventSetup &iSetup, const reco::TrackRef &track, TrackType type)
GEMSegmentRef gemSegmentRef
static const unsigned int GlobalMuon
Definition: Muon.h:287
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)
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:133
TrackRef combinedMuon() const override
reference to a stand-alone muon Track
Definition: Muon.h:52
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
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
double pt() const final
transverse momentum
void setType(unsigned int type)
Definition: Muon.h:296
static void truthMatchMuon(const edm::Event &iEvent, const GlobalTrackingGeometry &iGeometry, reco::Muon &aMuon)
TrackDetectorAssociator trackAssociator_
CSCSegmentRef cscSegmentRef
std::unique_ptr< MuonKinkFinder > trackerKinkFinder_
const TrackExtraRef & extra() const
reference to &quot;extra&quot; object
Definition: Track.h:139
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::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
static const unsigned int Arbitrated
segment mask flags
void fillMuonId(edm::Event &, const edm::EventSetup &, reco::Muon &, TrackDetectorAssociator::Direction direction=TrackDetectorAssociator::InsideOut)
std::vector< const HBHERecHit * > crossedHcalRecHits
virtual TrackRef innerTrack() const
Definition: Muon.h:45
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:539
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::vector< const EcalRecHit * > ecalRecHits
hits in the cone
std::vector< DetId > crossedEcalIds
std::string trackDepositName_
void fillArbitrationInfo(reco::MuonCollection *, unsigned int muonType=reco::Muon::TrackerMuon)
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 &)
std::vector< reco::MuonSegmentMatch > * getSegmentMatches(reco::MuonChamberMatch &chamber, unsigned int muonType) const
get the segment matches of the appropriate type
DetId findMaxDeposition(EnergyType)
Find detector elements with highest energy deposition.
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 evaluate(const reco::Muon &)
#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
bool isMatchesValid() const
Definition: Muon.h:143
tuple inputCollectionTypes
string quality
edm::EDGetTokenT< reco::TrackToTrackMap > pickyCollectionToken_
static std::string toStr(const ICTypeKey k)
double px() const
x coordinate of momentum vector
Definition: TrackBase.h:640
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)
int nDof() const
number of measurements used in timing calculation
Definition: MuonTimeExtra.h:22
TrackRef track() const override
reference to a Track
Definition: Muon.h:46
float timeAtIpOutInErr
Definition: MuonTime.h:17
std::vector< DetId > crossedHcalIds
float trkRelChi2
chi2 value for the inner track stub with respect to the global track
Definition: MuonQuality.h:15
double nXnEnergy(const DetId &, EnergyType, int gridSize=1)
get energy of the NxN shape (N = 2*gridSize + 1) around given detector element
std::unique_ptr< reco::isodeposit::IsoDepositExtractor > muIsoExtractorTrack_
float towerS9
total energy in 3x3 tower shape
Definition: MuonEnergy.h:22
static const unsigned int BestInStationByDR
MuonTime time() const
get DT/CSC combined timing information
Definition: Muon.h:132
std::vector< Muon > MuonCollection
collection of Muon objects
Definition: MuonFwd.h:9
bool isTrackerMuon() const override
Definition: Muon.h:302
std::unique_ptr< MuonTimingFiller > theTimingFiller_
#define LogTrace(id)
math::XYZPoint trkGlobPosAtHcal
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 depositWithin(double coneSize, const Vetos &vetos=Vetos(), bool skipDepositVeto=false) const
Get deposit.
Definition: IsoDeposit.cc:29
bool approxEqual(const double a, const double b, const double tol=1E-3) const
edm::ESGetToken< GlobalTrackingGeometry, GlobalTrackingGeometryRecord > globalGeomToken_
bool getData(T &iHolder) const
Definition: EventSetup.h:122
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 isRPCMuon() const
Definition: Muon.h:306
DetId hcal_id
DetId of the central HCAL tower with smallest depth.
Definition: MuonEnergy.h:60
edm::EDGetTokenT< reco::TrackToTrackMap > tpfmsCollectionToken_
const Point & vertex() const
reference point on the track. This method is DEPRECATED, please use referencePoint() instead ...
Definition: TrackBase.h:676
std::vector< reco::MuonSegmentMatch > me0Matches
int iEvent
Definition: GenABIO.cc:224
std::unique_ptr< MuonShowerDigiFiller > theShowerDigiFiller_
edm::Handle< reco::VertexCollection > pvHandle_
double ptThresholdToFillCandidateP4WithGlobalFit_
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:652
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 isCaloCompatibilityValid() const
Definition: CaloMuon.h:47
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 yy() const
Definition: LocalError.h:24
float emS25
energy deposited in 5x5 ECAL crystal shape around central crystal
Definition: MuonEnergy.h:30
double p() const
momentum vector magnitude
Definition: CaloMuon.h:54
static const unsigned int ME0Muon
Definition: Muon.h:294
ArbitrationType
define arbitration schemes
Definition: Muon.h:187
T sqrt(T t)
Definition: SSEVec.h:19
bool isGoodTrackerMuon(const reco::Muon &muon)
double pt() const
track transverse momentum
Definition: TrackBase.h:637
float emEt
ecal sum-Et
Definition: MuonIsolation.h:7
bool checkLinks(const reco::MuonTrackLinks *) const
float timeAtIpInOutErr
Definition: MuonTime.h:14
std::vector< TAMuonChamberMatch > chambers
int nJets
number of jets in the cone
Definition: MuonIsolation.h:11
def move
Definition: eostools.py:511
std::vector< const HBHERecHit * > hcalRecHits
static const unsigned int BestInChamberByDX
std::string ecalDepositName_
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
MuonQuality combinedQuality() const
get energy deposition information
Definition: Muon.h:119
float timeAtIpOutIn
b) particle is moving from outside in
Definition: MuonTime.h:16
int nDof
number of muon stations used
Definition: MuonTime.h:9
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
float timeAtIpInOutErr() const
Definition: MuonTimeExtra.h:44
edm::EDGetTokenT< reco::MuonCollection > muonCollectionToken_
Transition
Definition: Transition.h:12
float hoEt
ho sum-Et
Definition: MuonIsolation.h:9
edm::EDGetTokenT< reco::TrackCollection > outerTrackCollectionToken_
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
static const unsigned int BestInChamberByDR
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:232
TrackRef standAloneMuon() const override
reference to a stand-alone muon Track
Definition: Muon.h:49
ME0SegmentRef me0SegmentRef
bool isQualityValid() const
Definition: Muon.h:117
ParameterDescriptionBase * add(U const &iLabel, T const &value)
edm::Handle< reco::TrackToTrackMap > dytCollectionHandle_
bool isValid() const
Definition: HandleBase.h:70
edm::Handle< reco::TrackCollection > outerTrackCollectionHandle_
edm::EDGetTokenT< reco::MuonTrackLinksCollection > linkCollectionToken_
double crossedEnergy(EnergyType)
energy in detector elements crossed by the track by types
bool isNull() const
Checks for null.
Definition: Ref.h:235
static const unsigned int BestInStationByDXSlope
math::XYZPointF hcal_position
Definition: MuonEnergy.h:54
bool fillGlobalTrackRefits_
static double sectorPhi(const DetId &id)
void setMuonTrack(const MuonTrackType &, const TrackRef &)
bool isEnergyValid() const
Definition: Muon.h:104
float hoVetoEt
ho sum-et in the veto region in r-phi
Definition: MuonIsolation.h:15
#define M_PI
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:646
double phiOfMuonInteractionRegion(const reco::Muon &muon) const
MuonEnergy calEnergy() const
get energy deposition information
Definition: Muon.h:106
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
bool failedToGet() const
Definition: HandleBase.h:72
void setCaloCompatibility(float input)
Definition: CaloMuon.h:46
Definition: DetId.h:17
static const unsigned int RPCMuon
Definition: Muon.h:292
static ICTypeKey toKey(const std::string &s)
bool isTimeValid() const
Definition: Muon.h:130
static const unsigned int TrackerMuon
Definition: Muon.h:288
float emVetoEt
ecal sum-et in the veto region in r-phi
Definition: MuonIsolation.h:13
void configure(const edm::ParameterSet &)
T const * product() const
Definition: Handle.h:70
std::vector< ICTypes::ICTypeKey > inputCollectionTypes_
float timeAtIpInOut() const
Definition: MuonTimeExtra.h:43
float hadMax
maximal energy of HCAL tower in the 3x3 shape
Definition: MuonEnergy.h:40
static const unsigned int BelongsToTrackByDRSlope
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
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
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:291
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
int triggerSector() const
Definition: CSCDetId.cc:3
MuonIdProducer(const edm::ParameterSet &)
void arbitrateMuons(reco::MuonCollection *, reco::CaloMuonCollection *)
std::vector< reco::MuonSegmentMatch > segmentMatches
bool quality(const TrackQuality) const
Track quality.
Definition: TrackBase.h:552
bool fillGlobalTrackQuality_
int numberOfMatches(ArbitrationType type=SegmentAndTrackArbitration) const
get number of chambers with matched segments
DetId ecal_id
DetId of the central ECAL crystal.
Definition: MuonEnergy.h:57
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
tuple muons
Definition: patZpeak.py:41
functor predicate for standard library sort algorithm
static const unsigned int GEMMuon
Definition: Muon.h:293
int sector() const
Definition: DTChamberId.h:49
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< reco::TrackToTrackMap > tpfmsCollectionHandle_
def stationIndex
Definition: plotscripts.py:355
static const unsigned int BestInStationByDX
TrackDetMatchInfo associate(const edm::Event &, const edm::EventSetup &, const FreeTrajectoryState &, const AssociatorParameters &)
bool storeCrossedHcalRecHits_
edm::Handle< reco::TrackCollection > innerTrackCollectionHandle_
unsigned int type() const
Definition: Muon.h:297
math::XYZPoint trkGlobPosAtEcal
Track position at different parts of the calorimeter.
int charge() const
track electric charge
Definition: TrackBase.h:596
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_
MuonTrackType
map for Global Muon refitters
Definition: Muon.h:36
double sigmaThresholdToFillCandidateP4WithGlobalFit_
#define get
static const unsigned int StandAloneMuon
Definition: Muon.h:289
std::vector< HcalMuonRecHit > crossedHadRecHits
Definition: MuonEnergy.h:66
static constexpr int DT
Definition: MuonSubdetId.h:11
Log< level::Warning, false > LogWarning
float timeAtIpOutIn() const
b) particle is moving from outside in
Definition: MuonTimeExtra.h:48
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
double phi() const final
momentum azimuthal angle
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
float caloCompatibility() const
Definition: CaloMuon.h:45
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:301
ESGetTokenH3DDVariant esConsumes(std::string const &Reccord, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
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 hadS9
energy deposited in 3x3 HCAL tower shape around central tower
Definition: MuonEnergy.h:38
edm::Handle< reco::MuonCollection > muonCollectionHandle_
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:643
Definition: Run.h:45
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_
bool isStandAloneMuon() const override
Definition: Muon.h:303
double eta() const final
momentum pseudorapidity