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 
12 // user include files
14 
21 
24 
31 
33 
35 
37 muIsoExtractorCalo_(nullptr),muIsoExtractorTrack_(nullptr),muIsoExtractorJet_(nullptr)
38 {
39 
40  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: Constructor called";
41 
42  produces<reco::MuonCollection>();
43  produces<reco::CaloMuonCollection>();
44  produces<reco::MuonTimeExtraMap>("combined");
45  produces<reco::MuonTimeExtraMap>("dt");
46  produces<reco::MuonTimeExtraMap>("csc");
47 
48  minPt_ = iConfig.getParameter<double>("minPt");
49  minP_ = iConfig.getParameter<double>("minP");
50  minPCaloMuon_ = iConfig.getParameter<double>("minPCaloMuon");
51  minNumberOfMatches_ = iConfig.getParameter<int>("minNumberOfMatches");
52  addExtraSoftMuons_ = iConfig.getParameter<bool>("addExtraSoftMuons");
53  maxAbsEta_ = iConfig.getParameter<double>("maxAbsEta");
54  maxAbsDx_ = iConfig.getParameter<double>("maxAbsDx");
55  maxAbsPullX_ = iConfig.getParameter<double>("maxAbsPullX");
56  maxAbsDy_ = iConfig.getParameter<double>("maxAbsDy");
57  maxAbsPullY_ = iConfig.getParameter<double>("maxAbsPullY");
58  fillCaloCompatibility_ = iConfig.getParameter<bool>("fillCaloCompatibility");
59  fillEnergy_ = iConfig.getParameter<bool>("fillEnergy");
60  fillMatching_ = iConfig.getParameter<bool>("fillMatching");
61  fillIsolation_ = iConfig.getParameter<bool>("fillIsolation");
62  writeIsoDeposits_ = iConfig.getParameter<bool>("writeIsoDeposits");
63  fillGlobalTrackQuality_ = iConfig.getParameter<bool>("fillGlobalTrackQuality");
64  fillGlobalTrackRefits_ = iConfig.getParameter<bool>("fillGlobalTrackRefits");
65  arbitrateTrackerMuons_ = iConfig.getParameter<bool>("arbitrateTrackerMuons");
66  //SK: (maybe temporary) run it only if the global is also run
67  fillTrackerKink_ = false;
68  if (fillGlobalTrackQuality_) fillTrackerKink_ = iConfig.getParameter<bool>("fillTrackerKink");
69 
70  ptThresholdToFillCandidateP4WithGlobalFit_ = iConfig.getParameter<double>("ptThresholdToFillCandidateP4WithGlobalFit");
71  sigmaThresholdToFillCandidateP4WithGlobalFit_ = iConfig.getParameter<double>("sigmaThresholdToFillCandidateP4WithGlobalFit");
72  caloCut_ = iConfig.getParameter<double>("minCaloCompatibility"); //CaloMuons
73  arbClean_ = iConfig.getParameter<bool>("runArbitrationCleaner"); // muon mesh
74 
75  // Load TrackDetectorAssociator parameters
76  const edm::ParameterSet parameters = iConfig.getParameter<edm::ParameterSet>("TrackAssociatorParameters");
77  edm::ConsumesCollector iC = consumesCollector();
78  parameters_.loadParameters( parameters, iC );
79 
80  // Load parameters for the TimingFiller
81  edm::ParameterSet timingParameters = iConfig.getParameter<edm::ParameterSet>("TimingFillerParameters");
82  theTimingFiller_ = new MuonTimingFiller(timingParameters,consumesCollector());
83 
84 
85  if (fillCaloCompatibility_){
86  // Load MuonCaloCompatibility parameters
87  const auto caloParams = iConfig.getParameter<edm::ParameterSet>("MuonCaloCompatibility");
88  muonCaloCompatibility_.configure( caloParams );
89  }
90 
91  if (fillIsolation_){
92  // Load MuIsoExtractor parameters
93  edm::ParameterSet caloExtractorPSet = iConfig.getParameter<edm::ParameterSet>("CaloExtractorPSet");
94  std::string caloExtractorName = caloExtractorPSet.getParameter<std::string>("ComponentName");
95  muIsoExtractorCalo_ = IsoDepositExtractorFactory::get()->create( caloExtractorName, caloExtractorPSet,consumesCollector());
96 
97  edm::ParameterSet trackExtractorPSet = iConfig.getParameter<edm::ParameterSet>("TrackExtractorPSet");
98  std::string trackExtractorName = trackExtractorPSet.getParameter<std::string>("ComponentName");
99  muIsoExtractorTrack_ = IsoDepositExtractorFactory::get()->create( trackExtractorName, trackExtractorPSet,consumesCollector());
100 
101  edm::ParameterSet jetExtractorPSet = iConfig.getParameter<edm::ParameterSet>("JetExtractorPSet");
102  std::string jetExtractorName = jetExtractorPSet.getParameter<std::string>("ComponentName");
103  muIsoExtractorJet_ = IsoDepositExtractorFactory::get()->create( jetExtractorName, jetExtractorPSet,consumesCollector());
104  }
105  if (fillIsolation_ && writeIsoDeposits_){
106  trackDepositName_ = iConfig.getParameter<std::string>("trackDepositName");
107  produces<reco::IsoDepositMap>(trackDepositName_);
108  ecalDepositName_ = iConfig.getParameter<std::string>("ecalDepositName");
109  produces<reco::IsoDepositMap>(ecalDepositName_);
110  hcalDepositName_ = iConfig.getParameter<std::string>("hcalDepositName");
111  produces<reco::IsoDepositMap>(hcalDepositName_);
112  hoDepositName_ = iConfig.getParameter<std::string>("hoDepositName");
113  produces<reco::IsoDepositMap>(hoDepositName_);
114  jetDepositName_ = iConfig.getParameter<std::string>("jetDepositName");
115  produces<reco::IsoDepositMap>(jetDepositName_);
116  }
117 
118  inputCollectionLabels_ = iConfig.getParameter<std::vector<edm::InputTag> >("inputCollectionLabels");
119  const auto inputCollectionTypes = iConfig.getParameter<std::vector<std::string> >("inputCollectionTypes");
120  if (inputCollectionLabels_.size() != inputCollectionTypes.size())
121  throw cms::Exception("ConfigurationError") << "Number of input collection labels is different from number of types. " <<
122  "For each collection label there should be exactly one collection type specified.";
123  if (inputCollectionLabels_.size()>7 ||inputCollectionLabels_.empty())
124  throw cms::Exception("ConfigurationError") << "Number of input collections should be from 1 to 7.";
125 
126  debugWithTruthMatching_ = iConfig.getParameter<bool>("debugWithTruthMatching");
127  if (debugWithTruthMatching_) edm::LogWarning("MuonIdentification")
128  << "========================================================================\n"
129  << "Debugging mode with truth matching is turned on!!! Make sure you understand what you are doing!\n"
130  << "========================================================================\n";
131  if (fillGlobalTrackQuality_){
132  const auto& glbQualTag = iConfig.getParameter<edm::InputTag>("globalTrackQualityInputTag");
133  glbQualToken_ = consumes<edm::ValueMap<reco::MuonQuality> >(glbQualTag);
134  }
135 
136  if (fillTrackerKink_) {
137  trackerKinkFinder_ = std::make_unique<MuonKinkFinder>(iConfig.getParameter<edm::ParameterSet>("TrackerKinkFinderParameters"));
138  }
139 
140  //create mesh holder
141  meshAlgo_ = new MuonMesh(iConfig.getParameter<edm::ParameterSet>("arbitrationCleanerOptions"));
142 
143 
144  edm::InputTag rpcHitTag("rpcRecHits");
145  rpcHitToken_ = consumes<RPCRecHitCollection>(rpcHitTag);
146 
147 
148  //Consumes... UGH
149  inputCollectionTypes_.resize(inputCollectionLabels_.size());
150  for ( unsigned int i = 0; i < inputCollectionLabels_.size(); ++i ) {
151  const auto inputLabel = inputCollectionLabels_[i];
152  const auto inputType = ICTypes::toKey(inputCollectionTypes[i]); // Note: thorws exception if type is undefined.
153 
154  if ( inputType == ICTypes::INNER_TRACKS ) {
155  innerTrackCollectionToken_ = consumes<reco::TrackCollection>(inputLabel);
156  }
157  else if ( inputType == ICTypes::OUTER_TRACKS ) {
158  outerTrackCollectionToken_ = consumes<reco::TrackCollection>(inputLabel);
159  }
160  else if ( inputType == ICTypes::LINKS ) {
161  linkCollectionToken_ = consumes<reco::MuonTrackLinksCollection>(inputLabel);
162  }
163  else if ( inputType == ICTypes::MUONS ) {
164  muonCollectionToken_ = consumes<reco::MuonCollection>(inputLabel);
165  }
166  else if ( inputType == ICTypes::TEV_FIRSTHIT ) {
167  tpfmsCollectionToken_ = consumes<reco::TrackToTrackMap>(inputLabel);
168  }
169  else if ( fillGlobalTrackRefits_ && inputType == ICTypes::TEV_PICKY ) {
170  pickyCollectionToken_ = consumes<reco::TrackToTrackMap>(inputLabel);
171  }
172  else if ( fillGlobalTrackRefits_ && inputType == ICTypes::TEV_DYT ) {
173  dytCollectionToken_ = consumes<reco::TrackToTrackMap>(inputCollectionLabels_.at(i));
174  }
175 
176  inputCollectionTypes_[i] = inputType;
177  }
178 }
179 
180 
181 
183 {
188  if (meshAlgo_) delete meshAlgo_;
189  // TimingReport::current()->dump(std::cout);
190 }
191 
193 {
198 
202 
203 
205  iSetup.get<TrackingComponentsRecord>().get("SteppingHelixPropagatorAny", propagator);
206  trackAssociator_.setPropagator(propagator.product());
207 
208  if (fillTrackerKink_) trackerKinkFinder_->init(iSetup);
209 
210  for ( unsigned int i = 0; i < inputCollectionLabels_.size(); ++i ) {
211  const auto& inputLabel = inputCollectionLabels_[i];
212  const auto inputType = inputCollectionTypes_[i];
213  if ( inputType == ICTypes::INNER_TRACKS ) {
216  throw cms::Exception("FatalError") << "Failed to get input track collection with label: " << inputLabel;
217  LogTrace("MuonIdentification") << "Number of input inner tracks: " << innerTrackCollectionHandle_->size();
218  }
219  else if ( inputType == ICTypes::OUTER_TRACKS ) {
222  throw cms::Exception("FatalError") << "Failed to get input track collection with label: " << inputLabel;
223  LogTrace("MuonIdentification") << "Number of input outer tracks: " << outerTrackCollectionHandle_->size();
224  }
225  else if ( inputType == ICTypes::LINKS ) {
228  throw cms::Exception("FatalError") << "Failed to get input link collection with label: " << inputLabel;
229  LogTrace("MuonIdentification") << "Number of input links: " << linkCollectionHandle_->size();
230  }
231  else if ( inputType == ICTypes::MUONS ) {
234  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
235  LogTrace("MuonIdentification") << "Number of input muons: " << muonCollectionHandle_->size();
236  }
237  else if ( fillGlobalTrackRefits_ && inputType == ICTypes::TEV_FIRSTHIT ) {
240  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
241  LogTrace("MuonIdentification") << "Number of input muons: " << tpfmsCollectionHandle_->size();
242  }
243  else if ( fillGlobalTrackRefits_ && inputType == ICTypes::TEV_PICKY ) {
246  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
247  LogTrace("MuonIdentification") << "Number of input muons: " << pickyCollectionHandle_->size();
248  }
249  else if ( fillGlobalTrackRefits_ && inputType == ICTypes::TEV_DYT ) {
251  if (! dytCollectionHandle_.isValid())
252  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputLabel;
253  LogTrace("MuonIdentification") << "Number of input muons: " << dytCollectionHandle_->size();
254  }
255  else throw cms::Exception("FatalError") << "Unknown input collection type: #" << ICTypes::toStr(inputType);
256  }
257 
260 
261 }
262 
265 {
266  LogTrace("MuonIdentification") << "Creating a muon from a track " << track.get()->pt() <<
267  " Pt (GeV), eta: " << track.get()->eta();
268  reco::Muon aMuon( makeMuon( *(track.get()) ) );
269 
270  LogTrace("MuonIdentification") << "Muon created from a track ";
271 
272  aMuon.setMuonTrack(type,track);
273  aMuon.setBestTrack(type);
274  aMuon.setTunePBestTrack(type);
275 
276  LogTrace("MuonIdentification") << "Muon created from a track and setMuonBestTrack, setBestTrack and setTunePBestTrack called";
277 
278  return aMuon;
279 }
280 
282 {
283 
284  LogTrace("MuonIdentification") << "Creating a CaloMuon from a Muon";
285 
286  reco::CaloMuon aMuon;
287  aMuon.setInnerTrack( muon.innerTrack() );
288 
289  if (muon.isEnergyValid()) aMuon.setCalEnergy( muon.calEnergy() );
290  // get calo compatibility
292  return aMuon;
293 }
294 
295 
297 {
298  LogTrace("MuonIdentification") << "Creating a muon from a link to tracks object";
299 
300  reco::Muon aMuon;
301  reco::Muon::MuonTrackTypePair chosenTrack;
302  reco::TrackRef tpfmsRef;
303  reco::TrackRef pickyRef;
304  reco::TrackRef dytRef;
305  bool useSigmaSwitch = false;
306 
309 
313 
314  if (tpfmsRef.isNull() && pickyRef.isNull() && dytRef.isNull()){
315  edm::LogWarning("MakeMuonWithTEV")<<"Failed to get TEV refits, fall back to sigma switch.";
316  useSigmaSwitch = true;
317  }
318  } else {
319  useSigmaSwitch = true;
320  }
321 
322  if (useSigmaSwitch){
323  chosenTrack = muon::sigmaSwitch( links.globalTrack(), links.trackerTrack(),
326  } else {
327  chosenTrack = muon::tevOptimized( links.globalTrack(), links.trackerTrack(),
328  tpfmsRef, pickyRef, dytRef,
330  }
331  aMuon = makeMuon(*chosenTrack.first);
332  aMuon.setInnerTrack( links.trackerTrack() );
333  aMuon.setOuterTrack( links.standAloneTrack() );
334  aMuon.setGlobalTrack( links.globalTrack() );
335  aMuon.setBestTrack(chosenTrack.second);
336  aMuon.setTunePBestTrack(chosenTrack.second);
337 
341  if (it != tpfmsCollectionHandle_->end()) aMuon.setMuonTrack(reco::Muon::TPFMS, (it->val));
342  }
345  if (it != pickyCollectionHandle_->end()) aMuon.setMuonTrack(reco::Muon::Picky, (it->val));
346  }
349  if (it != dytCollectionHandle_->end()) aMuon.setMuonTrack(reco::Muon::DYT, (it->val));
350  }
351  }
352  return aMuon;
353 }
354 
355 
357 {
358  // Pt and absolute momentum requirement
359  const double p = track.p();
360  const double pt = track.pt();
361  if (pt < minPt_ || (p < minP_ && p < minPCaloMuon_)){
362  LogTrace("MuonIdentification") << "Skipped low momentum track (Pt,P): " << pt
363  << ", " << track.p() << " GeV";
364  return false;
365  }
366 
367  // Eta requirement
368  const double eta = track.eta();
369  const double absEta = std::abs(eta);
370  if ( absEta > maxAbsEta_ ){
371  LogTrace("MuonIdentification") << "Skipped track with large pseudo rapidity (Eta: " << track.eta() << " )";
372  return false;
373  }
374 
375  return true;
376 }
377 
378 unsigned int MuonIdProducer::chamberId( const DetId& id )
379 {
380  if ( id.det() != DetId::Muon ) return 0;
381 
382  const auto subdetId = id.subdetId();
383  if ( subdetId == MuonSubdetId::DT ) {
384  return DTChamberId(id.rawId()).rawId();
385  }
386  else if ( subdetId == MuonSubdetId::CSC ) {
387  return CSCDetId(id.rawId()).chamberId().rawId();
388  }
389 
390  return 0;
391 }
392 
393 
395 {
396  if ( ! muon.isMatchesValid() ||
397  track.extra().isNull() ||
398  track.extra()->recHitsSize()==0 ) return 0;
399 
400  int numberOfCommonDetIds = 0;
401  const std::vector<reco::MuonChamberMatch>& matches( muon.matches() );
402  for ( const auto& match : matches )
403  {
404  if ( match.segmentMatches.empty() ) continue;
405 
406  bool foundCommonDetId = false;
407  for ( auto hit = track.extra()->recHitsBegin();
408  hit != track.extra()->recHitsEnd(); ++hit )
409  {
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 {
429  edm::ESHandle<CSCGeometry> geomHandle;
430  iSetup.get<MuonGeometryRecord>().get(geomHandle);
431 
432  meshAlgo_->setCSCGeometry(geomHandle.product());
433 
434 }
435 
437  const reco::MuonTrackLinks& badMuon )
438 {
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 {
452 
453  auto outputMuons = std::make_unique<reco::MuonCollection>();
454  auto caloMuons = std::make_unique<reco::CaloMuonCollection>();
455 
456  init(iEvent, iSetup);
457 
458  // loop over input collections
459 
460  // muons first - no cleaning, take as is.
461  if ( muonCollectionHandle_.isValid() ) {
462  for ( const auto muon : *muonCollectionHandle_ ) {
463  outputMuons->push_back(muon);
464  }
465  }
466 
467  // links second ( assume global muon type )
468  if ( linkCollectionHandle_.isValid() ) {
469  const auto nLink = linkCollectionHandle_->size();
470  std::vector<bool> goodmuons(nLink, true);
471  if ( nLink > 1 ) {
472  // check for shared tracker tracks
473  for ( unsigned int i=0; i<nLink-1; ++i ) {
474  const auto& iLink = linkCollectionHandle_->at(i);
475  if ( iLink.trackerTrack().isNull() || !checkLinks(&iLink) ) continue;
476  for ( unsigned int j=i+1; j<nLink; ++j ){
477  const auto& jLink = linkCollectionHandle_->at(j);
478  if (!checkLinks(&jLink)) continue;
479  if ( iLink.trackerTrack() == jLink.trackerTrack() ) {
480  // Tracker track is the essential part that dominates muon resolution
481  // so taking either muon is fine. All that is important is to preserve
482  // the muon identification information. If number of hits is small,
483  // keep the one with large number of hits, otherwise take the smalest chi2/ndof
484  if ( validateGlobalMuonPair(iLink, jLink) ) goodmuons[j] = false;
485  else goodmuons[i] = false;
486  }
487  }
488  }
489  // check for shared stand-alone muons.
490  for ( unsigned int i=0; i<nLink-1; ++i ) {
491  if ( !goodmuons[i] ) continue;
492  const auto& iLink = linkCollectionHandle_->at(i);
493  if ( iLink.standAloneTrack().isNull() || !checkLinks(&iLink)) continue;
494  for ( unsigned int j=i+1; j<nLink; ++j ) {
495  if ( !goodmuons[j] ) continue;
496  const auto& jLink = linkCollectionHandle_->at(j);
497  if (!checkLinks(&jLink)) continue;
498  if ( iLink.standAloneTrack() == jLink.standAloneTrack() ) {
499  if ( validateGlobalMuonPair(iLink, jLink) ) goodmuons[j] = false;
500  else goodmuons[i] = false;
501  }
502  }
503  }
504  }
505  for ( unsigned int i=0; i<nLink; ++i ) {
506  if ( !goodmuons[i] ) continue;
507  const auto& iLink = linkCollectionHandle_->at(i);
508  if ( ! checkLinks(&iLink) ) continue;
509  // check if this muon is already in the list
510  bool newMuon = true;
511  for ( auto muon : *outputMuons ) {
512  if ( muon.track() == iLink.trackerTrack() &&
513  muon.standAloneMuon() == iLink.standAloneTrack() &&
514  muon.combinedMuon() == iLink.globalTrack() ) {
515  newMuon = false;
516  break;
517  }
518  }
519  if ( newMuon ) {
520  outputMuons->push_back( makeMuon(iLink) );
521  outputMuons->back().setType(reco::Muon::GlobalMuon | reco::Muon::StandAloneMuon);
522  }
523  }
524  }
525 
526  // tracker and calo muons are next
528  LogTrace("MuonIdentification") << "Creating tracker muons";
529  std::vector<TrackDetectorAssociator::Direction> directions1, directions2;
530  directions1.push_back(TrackDetectorAssociator::InsideOut);
531  directions1.push_back(TrackDetectorAssociator::OutsideIn);
532  directions2.push_back(TrackDetectorAssociator::Any);
533 
534  for ( unsigned int i = 0; i < innerTrackCollectionHandle_->size(); ++i )
535  {
537  if ( ! isGoodTrack( track ) ) continue;
538  const auto& trackRef = reco::TrackRef(innerTrackCollectionHandle_, i);
539  bool splitTrack = false;
540  if ( track.extra().isAvailable() &&
541  TrackDetectorAssociator::crossedIP( track ) ) splitTrack = true;
542  const auto& directions = splitTrack ? directions1 : directions2;
543  for ( const auto direction : directions ) {
544  // make muon
545  reco::Muon trackerMuon( makeMuon(iEvent, iSetup, trackRef, reco::Muon::InnerTrack) );
546  fillMuonId(iEvent, iSetup, trackerMuon, direction);
547 
548  if ( debugWithTruthMatching_ ) {
549  // add MC hits to a list of matched segments.
550  // Since it's debugging mode - code is slow
551  MuonIdTruthInfo::truthMatchMuon(iEvent, iSetup, trackerMuon);
552  }
553 
554  // check if this muon is already in the list
555  // have to check where muon hits are really located
556  // to match properly
557  bool newMuon = true;
558  const bool goodTrackerMuon = isGoodTrackerMuon( trackerMuon );
559  const bool goodRPCMuon = isGoodRPCMuon( trackerMuon );
560  const bool goodGEMMuon = isGoodGEMMuon( trackerMuon );
561  const bool goodME0Muon = isGoodME0Muon( trackerMuon );
562  if ( goodTrackerMuon ) trackerMuon.setType( trackerMuon.type() | reco::Muon::TrackerMuon );
563  if ( goodRPCMuon ) trackerMuon.setType( trackerMuon.type() | reco::Muon::RPCMuon );
564  if ( goodGEMMuon ) trackerMuon.setType( trackerMuon.type() | reco::Muon::GEMMuon );
565  if ( goodME0Muon ) trackerMuon.setType( trackerMuon.type() | reco::Muon::ME0Muon );
566 
567  for ( auto& muon : *outputMuons )
568  {
569  if ( muon.innerTrack().get() == trackerMuon.innerTrack().get() &&
571  {
572  newMuon = false;
573  muon.setMatches( trackerMuon.matches() );
574  if (trackerMuon.isTimeValid()) muon.setTime( trackerMuon.time() );
575  if (trackerMuon.isEnergyValid()) muon.setCalEnergy( trackerMuon.calEnergy() );
576  if (goodTrackerMuon) muon.setType( muon.type() | reco::Muon::TrackerMuon );
577  if (goodRPCMuon) muon.setType( muon.type() | reco::Muon::RPCMuon );
578  if (goodGEMMuon) muon.setType( muon.type() | reco::Muon::GEMMuon );
579  if (goodME0Muon) muon.setType( muon.type() | reco::Muon::ME0Muon );
580  LogTrace("MuonIdentification") << "Found a corresponding global muon. Set energy, matches and move on";
581  break;
582  }
583  }
584  if ( newMuon ) {
585  if ( goodTrackerMuon || goodRPCMuon || goodGEMMuon || goodME0Muon){
586  outputMuons->push_back( trackerMuon );
587  } else {
588  LogTrace("MuonIdentification") << "track failed minimal number of muon matches requirement";
589  const reco::CaloMuon& caloMuon = makeCaloMuon(trackerMuon);
590  if (isGoodCaloMuon(caloMuon)) caloMuons->push_back( caloMuon );
591  }
592  }
593  }
594  }
595  }
596 
597  // and at last the stand alone muons
599  LogTrace("MuonIdentification") << "Looking for new muons among stand alone muon tracks";
600  for ( unsigned int i = 0; i < outerTrackCollectionHandle_->size(); ++i )
601  {
602  const auto& outerTrack = outerTrackCollectionHandle_->at(i);
603 
604  // check if this muon is already in the list of global muons
605  bool newMuon = true;
606  for ( auto& muon : *outputMuons )
607  {
608  if ( ! muon.standAloneMuon().isNull() ) {
609  // global muon
610  if ( muon.standAloneMuon().get() == &outerTrack ) {
611  newMuon = false;
612  break;
613  }
614  } else {
615  // tracker muon - no direct links to the standalone muon
616  // since we have only a few real muons in an event, matching
617  // the stand alone muon to the tracker muon by DetIds should
618  // be good enough for association. At the end it's up to a
619  // user to redefine the association and what it means. Here
620  // we would like to avoid obvious double counting and we
621  // tolerate a potential miss association
622  if ( overlap(muon, outerTrack) > 0 ) {
623  LogTrace("MuonIdentification") << "Found associated tracker muon. Set a reference and move on";
624  newMuon = false;
625  muon.setOuterTrack( reco::TrackRef( outerTrackCollectionHandle_, i ) );
626  muon.setType( muon.type() | reco::Muon::StandAloneMuon );
627  break;
628  }
629  }
630  }
631  if ( newMuon ) {
632  LogTrace("MuonIdentification") << "No associated stand alone track is found. Making a muon";
633  outputMuons->push_back( makeMuon(iEvent, iSetup,
635  outputMuons->back().setType( reco::Muon::StandAloneMuon );
636  }
637  }
638  }
639 
641  fillArbitrationInfo( outputMuons.get() );
642  arbitrateMuons( outputMuons.get(), caloMuons.get() );
643  }
644 
645  LogTrace("MuonIdentification") << "Dress up muons if it's necessary";
646 
647  const int nMuons=outputMuons->size();
648 
649  std::vector<reco::MuonTimeExtra> dtTimeColl(nMuons);
650  std::vector<reco::MuonTimeExtra> cscTimeColl(nMuons);
651  std::vector<reco::MuonTimeExtra> combinedTimeColl(nMuons);
652  std::vector<reco::IsoDeposit> trackDepColl(nMuons);
653  std::vector<reco::IsoDeposit> ecalDepColl(nMuons);
654  std::vector<reco::IsoDeposit> hcalDepColl(nMuons);
655  std::vector<reco::IsoDeposit> hoDepColl(nMuons);
656  std::vector<reco::IsoDeposit> jetDepColl(nMuons);
657 
658  // Fill various information
659  for ( unsigned int i=0; i<outputMuons->size(); ++i )
660  {
661  auto& muon = outputMuons->at(i);
662 
663  // Fill muonID
664  if ( ( fillMatching_ && ! muon.isMatchesValid() ) ||
665  ( fillEnergy_ && !muon.isEnergyValid() ) )
666  {
667  // predict direction based on the muon interaction region location
668  // if it's available
669  if ( muon.isStandAloneMuon() ) {
670  if ( cos(phiOfMuonIneteractionRegion(muon) - muon.phi()) > 0 ) {
672  } else {
674  }
675  } else {
676  LogTrace("MuonIdentification") << "THIS SHOULD NEVER HAPPEN";
677  fillMuonId(iEvent, iSetup, muon);
678  }
679  }
680 
682  // Fill global quality information
683  fillGlbQuality(iEvent, iSetup, muon);
684  }
685  LogDebug("MuonIdentification");
686 
687  if (fillTrackerKink_) {
689  }
690 
691  if ( fillCaloCompatibility_ ) muon.setCaloCompatibility( muonCaloCompatibility_.evaluate(muon) );
692 
693  if ( fillIsolation_ ) {
694  fillMuonIsolation(iEvent, iSetup, muon,
695  trackDepColl[i], ecalDepColl[i], hcalDepColl[i], hoDepColl[i], jetDepColl[i]);
696  }
697 
698  // fill timing information
699  reco::MuonTime muonTime;
700  reco::MuonTimeExtra dtTime;
701  reco::MuonTimeExtra cscTime;
702  reco::MuonTime rpcTime;
703  reco::MuonTimeExtra combinedTime;
704 
705  theTimingFiller_->fillTiming(muon, dtTime, cscTime, rpcTime, combinedTime, iEvent, iSetup);
706 
707  muonTime.nDof=combinedTime.nDof();
708  muonTime.timeAtIpInOut=combinedTime.timeAtIpInOut();
709  muonTime.timeAtIpInOutErr=combinedTime.timeAtIpInOutErr();
710  muonTime.timeAtIpOutIn=combinedTime.timeAtIpOutIn();
711  muonTime.timeAtIpOutInErr=combinedTime.timeAtIpOutInErr();
712 
713  muon.setTime(muonTime);
714  muon.setRPCTime(rpcTime);
715  dtTimeColl[i] = dtTime;
716  cscTimeColl[i] = cscTime;
717  combinedTimeColl[i] = combinedTime;
718  }
719 
720  LogTrace("MuonIdentification") << "number of muons produced: " << outputMuons->size();
721  if ( fillMatching_ ) {
722  fillArbitrationInfo( outputMuons.get(), reco::Muon::TrackerMuon );
723  fillArbitrationInfo( outputMuons.get(), reco::Muon::ME0Muon );
724  fillArbitrationInfo( outputMuons.get(), reco::Muon::GEMMuon );
725  }
726  edm::OrphanHandle<reco::MuonCollection> muonHandle = iEvent.put(std::move(outputMuons));
727 
728  auto fillMap = [](auto refH, auto& vec, edm::Event& ev, const std::string& cAl = ""){
730  auto oMap = std::make_unique<MapType>();
731  {
732  typename MapType::Filler filler(*oMap);
733  filler.insert(refH, vec.begin(), vec.end());
734  vec.clear();
735  filler.fill();
736  }
737  ev.put(std::move(oMap), cAl);
738  };
739  fillMap(muonHandle, combinedTimeColl, iEvent, "combined");
740  fillMap(muonHandle, dtTimeColl, iEvent, "dt");
741  fillMap(muonHandle, cscTimeColl, iEvent, "csc");
742 
744  fillMap(muonHandle, trackDepColl, iEvent, trackDepositName_);
745  fillMap(muonHandle, ecalDepColl, iEvent, ecalDepositName_);
746  fillMap(muonHandle, hcalDepColl, iEvent, hcalDepositName_);
747  fillMap(muonHandle, hoDepColl, iEvent, hoDepositName_);
748  fillMap(muonHandle, jetDepColl, iEvent, jetDepositName_);
749  }
750 
751  iEvent.put(std::move(caloMuons));
752 }
753 
754 
756 {
757  if(muon.track()->pt() < minPt_ || muon.track()->p() < minP_) return false;
758  if ( addExtraSoftMuons_ &&
759  muon.pt()<5 && std::abs(muon.eta())<1.5 &&
760  muon.numberOfMatches( reco::Muon::NoArbitration ) >= 1 ) return true;
762 }
763 
765 {
766  if ( ! caloMuon.isCaloCompatibilityValid() || caloMuon.caloCompatibility() < caloCut_ || caloMuon.p() < minPCaloMuon_) return false;
767  return true;
768 }
769 
771 {
772  if(muon.track()->pt() < minPt_ || muon.track()->p() < minP_) return false;
773  if ( addExtraSoftMuons_ &&
774  muon.pt()<5 && std::abs(muon.eta())<1.5 &&
777 }
778 
780 {
781  if(muon.track()->pt() < minPt_ || muon.track()->p() < minP_) return false;
783 }
784 
786 {
787  // need to update min cuts on pt
788  if(muon.track()->p() < minP_) return false;
790 }
791 
793  reco::Muon& aMuon,
795 {
796 
797  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId";
798 
799  // perform track - detector association
800  const reco::Track* track = nullptr;
801  if ( aMuon.track().isNonnull() ) track = aMuon.track().get();
802  else if ( aMuon.standAloneMuon().isNonnull() ) track = aMuon.standAloneMuon().get();
803  else throw cms::Exception("FatalError") << "Failed to fill muon id information for a muon with undefined references to tracks";
804 
805 
806  TrackDetMatchInfo info = trackAssociator_.associate(iEvent, iSetup, *track, parameters_, direction);
807 
808  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId :: fillEnergy = "<<fillEnergy_;
809 
810  if ( fillEnergy_ ) {
811 
812  reco::MuonEnergy muonEnergy;
815  muonEnergy.ho = info.crossedEnergy(TrackDetMatchInfo::HORecHits);
817  muonEnergy.emS9 = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits,1); // 3x3 energy
818  muonEnergy.emS25 = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits,2); // 5x5 energy
819  muonEnergy.hadS9 = info.nXnEnergy(TrackDetMatchInfo::HcalRecHits,1); // 3x3 energy
820  muonEnergy.hoS9 = info.nXnEnergy(TrackDetMatchInfo::HORecHits,1); // 3x3 energy
821  muonEnergy.towerS9 = info.nXnEnergy(TrackDetMatchInfo::TowerTotal,1); // 3x3 energy
822  muonEnergy.ecal_position = info.trkGlobPosAtEcal;
823  muonEnergy.hcal_position = info.trkGlobPosAtHcal;
824  if (! info.crossedEcalIds.empty() ) muonEnergy.ecal_id = info.crossedEcalIds.front();
825  if (! info.crossedHcalIds.empty() ) muonEnergy.hcal_id = info.crossedHcalIds.front();
826  // find maximal energy depositions and their time
827  DetId emMaxId = info.findMaxDeposition(TrackDetMatchInfo::EcalRecHits,2); // max energy deposit in 5x5 shape
828  for ( const auto& hit : info.ecalRecHits ) {
829  if (hit->id() != emMaxId) continue;
830  muonEnergy.emMax = hit->energy();
831  muonEnergy.ecal_time = hit->time();
832  }
833  DetId hadMaxId = info.findMaxDeposition(TrackDetMatchInfo::HcalRecHits,1); // max energy deposit in 3x3 shape
834  for ( const auto& hit : info.hcalRecHits ) {
835  if (hit->id() != hadMaxId) continue;
836  muonEnergy.hadMax = hit->energy();
837  muonEnergy.hcal_time = hit->time();
838  }
839  aMuon.setCalEnergy( muonEnergy );
840  }
841  if ( ! fillMatching_ && ! aMuon.isTrackerMuon() && ! aMuon.isRPCMuon() ) return;
842 
843  // fill muon match info
844  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId :: fill muon match info ";
845  std::vector<reco::MuonChamberMatch> muonChamberMatches;
846  unsigned int nubmerOfMatchesAccordingToTrackAssociator = 0;
847  for ( const auto& chamber : info.chambers )
848  {
849  if (chamber.id.subdetId() == 3 && rpcHitHandle_.isValid() ) continue; // Skip RPC chambers, they are taken care of below)
850  reco::MuonChamberMatch matchedChamber;
851 
852  const auto& lErr = chamber.tState.localError();
853  const auto& lPos = chamber.tState.localPosition();
854  const auto& lDir = chamber.tState.localDirection();
855 
856  const auto& localError = lErr.positionError();
857  matchedChamber.x = lPos.x();
858  matchedChamber.y = lPos.y();
859  matchedChamber.xErr = sqrt( localError.xx() );
860  matchedChamber.yErr = sqrt( localError.yy() );
861 
862  matchedChamber.dXdZ = lDir.z()!=0?lDir.x()/lDir.z():9999;
863  matchedChamber.dYdZ = lDir.z()!=0?lDir.y()/lDir.z():9999;
864  // DANGEROUS - compiler cannot guaranty parameters ordering
865  AlgebraicSymMatrix55 trajectoryCovMatrix = lErr.matrix();
866  matchedChamber.dXdZErr = trajectoryCovMatrix(1,1)>0?sqrt(trajectoryCovMatrix(1,1)):0;
867  matchedChamber.dYdZErr = trajectoryCovMatrix(2,2)>0?sqrt(trajectoryCovMatrix(2,2)):0;
868 
869  matchedChamber.edgeX = chamber.localDistanceX;
870  matchedChamber.edgeY = chamber.localDistanceY;
871 
872  matchedChamber.id = chamber.id;
873  if ( ! chamber.segments.empty() ) ++nubmerOfMatchesAccordingToTrackAssociator;
874 
875  // fill segments
876  for ( const auto& segment : chamber.segments )
877  {
878  reco::MuonSegmentMatch matchedSegment;
879  matchedSegment.x = segment.segmentLocalPosition.x();
880  matchedSegment.y = segment.segmentLocalPosition.y();
881  matchedSegment.dXdZ = segment.segmentLocalDirection.z()?segment.segmentLocalDirection.x()/segment.segmentLocalDirection.z():0;
882  matchedSegment.dYdZ = segment.segmentLocalDirection.z()?segment.segmentLocalDirection.y()/segment.segmentLocalDirection.z():0;
883  matchedSegment.xErr = segment.segmentLocalErrorXX>0?sqrt(segment.segmentLocalErrorXX):0;
884  matchedSegment.yErr = segment.segmentLocalErrorYY>0?sqrt(segment.segmentLocalErrorYY):0;
885  matchedSegment.dXdZErr = segment.segmentLocalErrorDxDz>0?sqrt(segment.segmentLocalErrorDxDz):0;
886  matchedSegment.dYdZErr = segment.segmentLocalErrorDyDz>0?sqrt(segment.segmentLocalErrorDyDz):0;
887  matchedSegment.t0 = segment.t0;
888  matchedSegment.mask = 0;
889  matchedSegment.dtSegmentRef = segment.dtSegmentRef;
890  matchedSegment.cscSegmentRef = segment.cscSegmentRef;
891  matchedSegment.gemSegmentRef = segment.gemSegmentRef;
892  matchedSegment.me0SegmentRef = segment.me0SegmentRef;
893  matchedSegment.hasZed_ = segment.hasZed;
894  matchedSegment.hasPhi_ = segment.hasPhi;
895  // test segment
896  bool matchedX = false;
897  bool matchedY = false;
898  LogTrace("MuonIdentification") << " matching local x, segment x: " << matchedSegment.x <<
899  ", chamber x: " << matchedChamber.x << ", max: " << maxAbsDx_;
900  LogTrace("MuonIdentification") << " matching local y, segment y: " << matchedSegment.y <<
901  ", chamber y: " << matchedChamber.y << ", max: " << maxAbsDy_;
902  const double matchedSegChDx = std::abs(matchedSegment.x - matchedChamber.x);
903  const double matchedSegChDy = std::abs(matchedSegment.y - matchedChamber.y);
904  const double matchedSegChPullX = matchedSegChDx/std::hypot(matchedSegment.xErr, matchedChamber.xErr);
905  const double matchedSegChPullY = matchedSegChDy/std::hypot(matchedSegment.yErr, matchedChamber.yErr);
906  if (matchedSegment.xErr>0 && matchedChamber.xErr>0 )
907  LogTrace("MuonIdentification") << " xpull: " << matchedSegChPullX;
908  if (matchedSegment.yErr>0 && matchedChamber.yErr>0 )
909  LogTrace("MuonIdentification") << " ypull: " << matchedSegChPullY;
910 
911  if (matchedSegChDx < maxAbsDx_) matchedX = true;
912  if (matchedSegChDy < maxAbsDy_) matchedY = true;
913  if (matchedSegment.xErr>0 && matchedChamber.xErr>0 && matchedSegChPullX < maxAbsPullX_) matchedX = true;
914  if (matchedSegment.yErr>0 && matchedChamber.yErr>0 && matchedSegChPullY < maxAbsPullY_) matchedY = true;
915  if (matchedX && matchedY){
916  if (matchedChamber.id.subdetId() == MuonSubdetId::ME0)
917  matchedChamber.me0Matches.push_back(matchedSegment);
918  else if (matchedChamber.id.subdetId() == MuonSubdetId::GEM)
919  matchedChamber.gemMatches.push_back(matchedSegment);
920  else matchedChamber.segmentMatches.push_back(matchedSegment);
921  }
922  }
923  muonChamberMatches.push_back(matchedChamber);
924  }
925 
926  // Fill RPC info
927  LogTrace("MuonIdentification") << "RecoMuon/MuonIdProducer :: fillMuonId :: fill RPC info";
928  if ( rpcHitHandle_.isValid() )
929  {
930  for ( const auto& chamber : info.chambers )
931  {
932  if ( chamber.id.subdetId() != 3 ) continue; // Consider RPC chambers only
933  const auto& lErr = chamber.tState.localError();
934  const auto& lPos = chamber.tState.localPosition();
935  const auto& lDir = chamber.tState.localDirection();
936 
937  reco::MuonChamberMatch matchedChamber;
938 
939  LocalError localError = lErr.positionError();
940  matchedChamber.x = lPos.x();
941  matchedChamber.y = lPos.y();
942  matchedChamber.xErr = sqrt( localError.xx() );
943  matchedChamber.yErr = sqrt( localError.yy() );
944 
945  matchedChamber.dXdZ = lDir.z()!=0?lDir.x()/lDir.z():9999;
946  matchedChamber.dYdZ = lDir.z()!=0?lDir.y()/lDir.z():9999;
947  // DANGEROUS - compiler cannot guaranty parameters ordering
948  AlgebraicSymMatrix55 trajectoryCovMatrix = lErr.matrix();
949  matchedChamber.dXdZErr = trajectoryCovMatrix(1,1)>0?sqrt(trajectoryCovMatrix(1,1)):0;
950  matchedChamber.dYdZErr = trajectoryCovMatrix(2,2)>0?sqrt(trajectoryCovMatrix(2,2)):0;
951 
952  matchedChamber.edgeX = chamber.localDistanceX;
953  matchedChamber.edgeY = chamber.localDistanceY;
954 
955  matchedChamber.id = chamber.id;
956 
957  for ( const auto& rpcRecHit : *rpcHitHandle_ )
958  {
959  reco::MuonRPCHitMatch rpcHitMatch;
960 
961  if ( rpcRecHit.rawId() != chamber.id.rawId() ) continue;
962 
963  rpcHitMatch.x = rpcRecHit.localPosition().x();
964  rpcHitMatch.mask = 0;
965  rpcHitMatch.bx = rpcRecHit.BunchX();
966 
967  const double absDx = std::abs(rpcRecHit.localPosition().x()-chamber.tState.localPosition().x());
968  if( absDx <= 20 or absDx/sqrt(localError.xx()) <= 4 ) matchedChamber.rpcMatches.push_back(rpcHitMatch);
969  }
970 
971  muonChamberMatches.push_back(matchedChamber);
972  }
973  }
974 
975  aMuon.setMatches(muonChamberMatches);
976 
977  LogTrace("MuonIdentification") << "number of muon chambers: " << aMuon.matches().size() << "\n"
978  << "number of chambers with segments according to the associator requirements: " <<
979  nubmerOfMatchesAccordingToTrackAssociator;
980  LogTrace("MuonIdentification") << "number of segment matches with the producer requirements: " <<
982 
983  // fillTime( iEvent, iSetup, aMuon );
984 }
985 
987 {
989  // arbitrate TrackerMuons
990  // if a muon was exclusively TrackerMuon check if it can be a calo muon
991  for (reco::MuonCollection::iterator muon=muons->begin(); muon!=muons->end();){
992  if (muon->isTrackerMuon()){
993  if (muon->numberOfMatches(arbitration)<minNumberOfMatches_){
994  // TrackerMuon failed arbitration
995  // If not any other base type - erase the element
996  // (PFMuon is not a base type)
998  if ((muon->type() & (~mask))==0){
999  const reco::CaloMuon& caloMuon = makeCaloMuon(*muon);
1000  if (isGoodCaloMuon(caloMuon)) caloMuons->push_back( caloMuon );
1001  muon = muons->erase(muon);
1002  continue;
1003  } else {
1004  muon->setType(muon->type()&(~reco::Muon::TrackerMuon));
1005  }
1006  }
1007  }
1008  muon++;
1009  }
1010 }
1011 
1012 void MuonIdProducer::fillArbitrationInfo( reco::MuonCollection* pOutputMuons, unsigned int muonType )
1013 {
1014  //
1015  // apply segment flags
1016  //
1017  std::vector<std::pair<reco::MuonChamberMatch*,reco::MuonSegmentMatch*> > chamberPairs; // for chamber segment sorting
1018  std::vector<std::pair<reco::MuonChamberMatch*,reco::MuonSegmentMatch*> > stationPairs; // for station segment sorting
1019  std::vector<std::pair<reco::MuonChamberMatch*,reco::MuonSegmentMatch*> > arbitrationPairs; // for muon segment arbitration
1020 
1021  // muonIndex1
1022  for( unsigned int muonIndex1 = 0; muonIndex1 < pOutputMuons->size(); ++muonIndex1 )
1023  {
1024  auto& muon1 = pOutputMuons->at(muonIndex1);
1025  // chamberIter1
1026  for ( auto& chamber1 : muon1.matches() )
1027  {
1028  // segmentIter1
1029  std::vector<reco::MuonSegmentMatch> * segmentMatches1 = getSegmentMatches(chamber1, muonType);
1030 
1031  if(segmentMatches1->empty()) continue;
1032  chamberPairs.clear();
1033 
1034  for ( auto& segment1 : *segmentMatches1 )
1035  {
1036  chamberPairs.push_back(std::make_pair(&chamber1, &segment1));
1037  if(!segment1.isMask()) // has not yet been arbitrated
1038  {
1039  arbitrationPairs.clear();
1040  arbitrationPairs.push_back(std::make_pair(&chamber1, &segment1));
1041 
1042  // find identical segments with which to arbitrate
1043  // tracker muons only
1044  if (muon1.type() & muonType) {
1045  // muonIndex2
1046  for( unsigned int muonIndex2 = muonIndex1+1; muonIndex2 < pOutputMuons->size(); ++muonIndex2 )
1047  {
1048  auto& muon2 = pOutputMuons->at(muonIndex2);
1049  // tracker muons only
1050  if ( !(muon2.type() & muonType) ) continue;
1051  // chamberIter2
1052  for ( auto& chamber2 : muon2.matches() )
1053  {
1054  // segmentIter2
1055  std::vector<reco::MuonSegmentMatch> * segmentMatches2 = getSegmentMatches(chamber2, muonType);
1056  for ( auto& segment2 : *segmentMatches2 )
1057  {
1058  if(segment2.isMask()) continue; // has already been arbitrated
1059  if(approxEqual(segment2.x , segment1.x ) &&
1060  approxEqual(segment2.y , segment1.y ) &&
1061  approxEqual(segment2.dXdZ , segment1.dXdZ ) &&
1062  approxEqual(segment2.dYdZ , segment1.dYdZ ) &&
1063  approxEqual(segment2.xErr , segment1.xErr ) &&
1064  approxEqual(segment2.yErr , segment1.yErr ) &&
1065  approxEqual(segment2.dXdZErr, segment1.dXdZErr) &&
1066  approxEqual(segment2.dYdZErr, segment1.dYdZErr))
1067  {
1068  arbitrationPairs.push_back(std::make_pair(&chamber2, &segment2));
1069  }
1070  } // segmentIter2
1071  } // chamberIter2
1072  } // muonIndex2
1073  }
1074 
1075  // arbitration segment sort
1076  if(arbitrationPairs.empty()) continue; // this should never happen
1077  if(arbitrationPairs.size()==1) {
1078  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDRSlope);
1079  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDXSlope);
1080  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDR);
1081  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDX);
1082  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::Arbitrated);
1083  } else {
1084  sort(arbitrationPairs.begin(), arbitrationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BelongsToTrackByDRSlope));
1085  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDRSlope);
1086  sort(arbitrationPairs.begin(), arbitrationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BelongsToTrackByDXSlope));
1087  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDXSlope);
1088  sort(arbitrationPairs.begin(), arbitrationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BelongsToTrackByDR));
1089  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDR);
1090  sort(arbitrationPairs.begin(), arbitrationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BelongsToTrackByDX));
1091  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDX);
1092  for ( auto& ap : arbitrationPairs ) {
1093  ap.second->setMask(reco::MuonSegmentMatch::Arbitrated);
1094  }
1095  }
1096  }
1097 
1098  // setup me1a cleaning for later
1099  if( muonType == reco::Muon::TrackerMuon && chamber1.id.subdetId() == MuonSubdetId::CSC && arbClean_ &&
1100  CSCDetId(chamber1.id).ring() == 4) {
1101  for ( auto& segment2 : chamber1.segmentMatches ) {
1102  if( segment1.cscSegmentRef.isNull() || segment2.cscSegmentRef.isNull() ) continue;
1103  if( meshAlgo_->isDuplicateOf(segment1.cscSegmentRef,segment2.cscSegmentRef) &&
1104  (segment2.mask & 0x1e0000) &&
1105  (segment1.mask & 0x1e0000) ) {
1107  //if the track has lost the segment already through normal arbitration no need to do it again.
1108  }
1109  }
1110  }// mark all ME1/a duplicates that this track owns
1111 
1112  } // segmentIter1
1113 
1114  // chamber segment sort
1115  if(chamberPairs.empty()) continue; // this should never happen
1116  if(chamberPairs.size()==1) {
1117  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDRSlope);
1118  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDXSlope);
1119  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDR);
1120  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDX);
1121  } else {
1122  sort(chamberPairs.begin(), chamberPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInChamberByDRSlope));
1123  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDRSlope);
1124  sort(chamberPairs.begin(), chamberPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInChamberByDXSlope));
1125  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDXSlope);
1126  sort(chamberPairs.begin(), chamberPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInChamberByDR));
1127  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDR);
1128  sort(chamberPairs.begin(), chamberPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInChamberByDX));
1129  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDX);
1130  }
1131  } // chamberIter1
1132 
1133  // station segment sort
1134  for( int stationIndex = 1; stationIndex < 5; ++stationIndex )
1135  {
1136  for( int detectorIndex = 1; detectorIndex <= 5; ++detectorIndex ) // 1-5, as in DataFormats/MuonDetId/interface/MuonSubdetId.h
1137  {
1138  stationPairs.clear();
1139 
1140  // chamberIter
1141  for ( auto& chamber : muon1.matches() )
1142  {
1143  if(!(chamber.station()==stationIndex && chamber.detector()==detectorIndex)) continue;
1144  std::vector<reco::MuonSegmentMatch> * segmentMatches = getSegmentMatches(chamber, muonType);
1145  if (segmentMatches->empty()) continue;
1146 
1147  for ( auto& segment : *segmentMatches ) {
1148  stationPairs.push_back(std::make_pair(&chamber, &segment));
1149  }
1150  } // chamberIter
1151 
1152  if(stationPairs.empty()) continue; // this may very well happen
1153  if(stationPairs.size()==1) {
1154  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDRSlope);
1155  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDXSlope);
1156  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDR);
1157  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDX);
1158  } else {
1159  sort(stationPairs.begin(), stationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInStationByDRSlope));
1160  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDRSlope);
1161  sort(stationPairs.begin(), stationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInStationByDXSlope));
1162  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDXSlope);
1163  sort(stationPairs.begin(), stationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInStationByDR));
1164  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDR);
1165  sort(stationPairs.begin(), stationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInStationByDX));
1166  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDX);
1167  }
1168  }
1169  }
1170 
1171  } // muonIndex1
1172 
1173  if(arbClean_) {
1174  // clear old mesh, create and prune new mesh!
1175  meshAlgo_->clearMesh();
1176  meshAlgo_->runMesh(pOutputMuons);
1177  }
1178 }
1179 
1181  reco::IsoDeposit& trackDep, reco::IsoDeposit& ecalDep, reco::IsoDeposit& hcalDep, reco::IsoDeposit& hoDep,
1182  reco::IsoDeposit& jetDep)
1183 {
1184  const reco::Track* track = nullptr;
1185  if ( aMuon.track().isNonnull() ) track = aMuon.track().get();
1186  else if ( aMuon.standAloneMuon().isNonnull() ) track = aMuon.standAloneMuon().get();
1187  else throw cms::Exception("FatalError") << "Failed to compute muon isolation information for a muon with undefined references to tracks";
1188 
1189  reco::MuonIsolation isoR03, isoR05;
1190 
1191  // get deposits
1192  reco::IsoDeposit depTrk = muIsoExtractorTrack_->deposit(iEvent, iSetup, *track );
1193  std::vector<reco::IsoDeposit> caloDeps = muIsoExtractorCalo_->deposits(iEvent, iSetup, *track);
1194  reco::IsoDeposit depJet = muIsoExtractorJet_->deposit(iEvent, iSetup, *track );
1195 
1196  if(caloDeps.size()!=3) {
1197  LogTrace("MuonIdentification") << "Failed to fill vector of calorimeter isolation deposits!";
1198  return;
1199  }
1200 
1201  reco::IsoDeposit depEcal = caloDeps.at(0);
1202  reco::IsoDeposit depHcal = caloDeps.at(1);
1203  reco::IsoDeposit depHo = caloDeps.at(2);
1204 
1205  //no need to copy outside if we don't write them
1206  if (writeIsoDeposits_){
1207  trackDep = depTrk;
1208  ecalDep = depEcal;
1209  hcalDep = depHcal;
1210  hoDep = depHo;
1211  jetDep = depJet;
1212  }
1213 
1214  isoR03.sumPt = depTrk.depositWithin(0.3);
1215  isoR03.emEt = depEcal.depositWithin(0.3);
1216  isoR03.hadEt = depHcal.depositWithin(0.3);
1217  isoR03.hoEt = depHo.depositWithin(0.3);
1218  isoR03.nTracks = depTrk.depositAndCountWithin(0.3).second;
1219  isoR03.nJets = depJet.depositAndCountWithin(0.3).second;
1220  isoR03.trackerVetoPt = depTrk.candEnergy();
1221  isoR03.emVetoEt = depEcal.candEnergy();
1222  isoR03.hadVetoEt = depHcal.candEnergy();
1223  isoR03.hoVetoEt = depHo.candEnergy();
1224 
1225  isoR05.sumPt = depTrk.depositWithin(0.5);
1226  isoR05.emEt = depEcal.depositWithin(0.5);
1227  isoR05.hadEt = depHcal.depositWithin(0.5);
1228  isoR05.hoEt = depHo.depositWithin(0.5);
1229  isoR05.nTracks = depTrk.depositAndCountWithin(0.5).second;
1230  isoR05.nJets = depJet.depositAndCountWithin(0.5).second;
1231  isoR05.trackerVetoPt = depTrk.candEnergy();
1232  isoR05.emVetoEt = depEcal.candEnergy();
1233  isoR05.hadVetoEt = depHcal.candEnergy();
1234  isoR05.hoVetoEt = depHo.candEnergy();
1235 
1236 
1237  aMuon.setIsolation(isoR03, isoR05);
1238 
1239 }
1240 
1242 {
1243  const double energy = hypot(track.p(), 0.105658369);
1244  const math::XYZTLorentzVector p4(track.px(), track.py(), track.pz(), energy);
1245  return reco::Muon( track.charge(), p4, track.vertex() );
1246 }
1247 
1249 {
1250  double phi = 0;
1251  if( id.subdetId() == MuonSubdetId::DT ) { // DT
1252  DTChamberId muonId(id.rawId());
1253  if ( muonId.sector() <= 12 )
1254  phi = (muonId.sector()-1)/6.*M_PI;
1255  if ( muonId.sector() == 13 ) phi = 3/6.*M_PI;
1256  if ( muonId.sector() == 14 ) phi = 9/6.*M_PI;
1257  }
1258  if( id.subdetId() == MuonSubdetId::CSC ) { // CSC
1259  CSCDetId muonId(id.rawId());
1260  phi = M_PI/4+(muonId.triggerSector()-1)/3.*M_PI;
1261  }
1262  if ( phi > M_PI ) phi -= 2*M_PI;
1263  return phi;
1264 }
1265 
1267 {
1268  if ( muon.isStandAloneMuon() ) return muon.standAloneMuon()->innerPosition().phi();
1269  // the rest is tracker muon only
1270  if ( muon.matches().empty() ) {
1271  if ( muon.innerTrack().isAvailable() &&
1272  muon.innerTrack()->extra().isAvailable() )
1273  return muon.innerTrack()->outerPosition().phi();
1274  else
1275  return muon.phi(); // makes little sense, but what else can I use
1276  }
1277  return sectorPhi(muon.matches().at(0).id);
1278 }
1279 
1281 {
1283  aMuon.setCombinedQuality((*glbQualHandle_)[aMuon.combinedMuon()]);
1284  }
1285 
1286  LogDebug("MuonIdentification") << "tkChiVal " << aMuon.combinedQuality().trkRelChi2;
1287 
1288 }
1289 
1291  // skip muons with no tracks
1292  if (aMuon.innerTrack().isNull()) return;
1293  // get quality from muon if already there, otherwise make empty one
1295  // fill it
1296  const bool filled = trackerKinkFinder_->fillTrkKink(quality, *aMuon.innerTrack());
1297  // if quality was there, or if we filled it, commit to the muon
1298  if (filled || aMuon.isQualityValid()) aMuon.setCombinedQuality(quality);
1299 }
1300 
1302  const bool trackBAD = links->trackerTrack().isNull();
1303  const bool staBAD = links->standAloneTrack().isNull();
1304  const bool glbBAD = links->globalTrack().isNull();
1305  if (trackBAD || staBAD || glbBAD )
1306  {
1307  edm::LogWarning("muonIDbadLinks") << "Global muon links to constituent tracks are invalid: trkBad "
1308  <<trackBAD <<" standaloneBad "<<staBAD<<" globalBad "<<glbBAD
1309  <<". There should be no such object. Muon is skipped.";
1310  return false;
1311  }
1312  return true;
1313 }
1314 
1317  desc.setAllowAnything();
1318 
1319  desc.add<bool>("arbitrateTrackerMuons",false);
1320 
1321  edm::ParameterSetDescription descTrkAsoPar;
1322  descTrkAsoPar.add<edm::InputTag>("GEMSegmentCollectionLabel",edm::InputTag("gemSegments"));
1323  descTrkAsoPar.add<edm::InputTag>("ME0SegmentCollectionLabel",edm::InputTag("me0Segments"));
1324  descTrkAsoPar.add<bool>("useGEM", false);
1325  descTrkAsoPar.add<bool>("useME0", false);
1326  descTrkAsoPar.setAllowAnything();
1327  desc.add<edm::ParameterSetDescription>("TrackAssociatorParameters", descTrkAsoPar);
1328 
1330  descJet.setAllowAnything();
1331  descJet.add<edm::ParameterSetDescription>("TrackAssociatorParameters", descTrkAsoPar);
1332  desc.add<edm::ParameterSetDescription>("JetExtractorPSet", descJet);
1333 
1335  descCalo.setAllowAnything();
1336  descCalo.add<edm::ParameterSetDescription>("TrackAssociatorParameters", descTrkAsoPar);
1337  desc.add<edm::ParameterSetDescription>("CaloExtractorPSet", descCalo);
1338 
1339  descriptions.addDefault(desc);
1340 }
#define LogDebug(id)
std::string hoDepositName_
double p() const
momentum vector magnitude
Definition: TrackBase.h:615
bool isAvailable() const
Definition: Ref.h:577
type
Definition: HCALResponse.h:21
float hadEt
hcal sum-Et
Definition: MuonIsolation.h:9
T getParameter(std::string const &) const
static const unsigned int BelongsToTrackByME1aClean
std::string jetDepositName_
double candEnergy() const
Get energy or pT attached to cand trajectory.
Definition: IsoDeposit.h:136
bool isGoodRPCMuon(const reco::Muon &muon)
int numberOfMatchedRPCLayers(ArbitrationType type=RPCHitAndTrackArbitration) const
float xx() const
Definition: LocalError.h:24
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:263
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_
static void truthMatchMuon(const edm::Event &iEvent, const edm::EventSetup &iSetup, reco::Muon &aMuon)
DTRecSegment4DRef dtSegmentRef
static const TGPicture * info(bool iBackgroundIsBlack)
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:137
TrackRef track() const override
reference to a Track
Definition: Muon.h:49
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:253
double eta() const final
momentum pseudorapidity
bool isStandAloneMuon() const override
Definition: Muon.h:278
void runMesh(std::vector< reco::Muon > *p)
Definition: MuonMesh.h:39
std::vector< reco::MuonSegmentMatch > gemMatches
static bool crossedIP(const reco::Track &track)
float sumPt
sum-pt of tracks
Definition: MuonIsolation.h:7
void setType(unsigned int type)
Definition: Muon.h:272
TrackDetectorAssociator trackAssociator_
CSCSegmentRef cscSegmentRef
std::unique_ptr< MuonKinkFinder > trackerKinkFinder_
const TrackExtraRef & extra() const
reference to "extra" object
Definition: Track.h:189
static const unsigned int Arbitrated
segment mask flags
void fillMuonId(edm::Event &, const edm::EventSetup &, reco::Muon &, TrackDetectorAssociator::Direction direction=TrackDetectorAssociator::InsideOut)
const_iterator end() const
last iterator over the map (read only)
reco::isodeposit::IsoDepositExtractor * muIsoExtractorCalo_
virtual TrackRef innerTrack() const
Definition: Muon.h:48
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:579
void setAllowAnything()
allow any parameter label/value pairs
edm::Handle< reco::MuonTrackLinksCollection > linkCollectionHandle_
edm::EDGetTokenT< RPCRecHitCollection > rpcHitToken_
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_
static const int GEM
Definition: MuonSubdetId.h:15
void fillArbitrationInfo(reco::MuonCollection *, unsigned int muonType=reco::Muon::TrackerMuon)
const_iterator find(const key_type &k) const
find element with specified reference key
void fillTiming(const reco::Muon &muon, reco::MuonTimeExtra &dtTime, reco::MuonTimeExtra &cscTime, reco::MuonTime &rpcTime, reco::MuonTimeExtra &combinedTime, edm::Event &iEvent, const edm::EventSetup &iSetup)
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:47
double phiOfMuonIneteractionRegion(const reco::Muon &muon) const
std::vector< CaloMuon > CaloMuonCollection
collection of Muon objects
Definition: MuonFwd.h:27
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:15
float emS9
energy deposited in 3x3 ECAL crystal shape around central crystal
Definition: MuonEnergy.h:18
double evaluate(const reco::Muon &)
double pt() const final
transverse momentum
MuonCaloCompatibility muonCaloCompatibility_
static const unsigned int BestInStationByDRSlope
float timeAtIpOutInErr() const
Definition: MuonTimeExtra.h:49
bool isMatchesValid() const
Definition: Muon.h:142
bool ev
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
edm::EDGetTokenT< reco::TrackToTrackMap > pickyCollectionToken_
static std::string toStr(const ICTypeKey k)
double px() const
x coordinate of momentum vector
Definition: TrackBase.h:627
bool arbitrateTrackerMuons_
static const unsigned int BelongsToTrackByDXSlope
void setCalEnergy(const MuonEnergy &calEnergy)
set energy deposition information
Definition: Muon.h:113
#define nullptr
void fillGlbQuality(edm::Event &, const edm::EventSetup &, reco::Muon &aMuon)
int nDof() const
number of measurements used in timing calculation
Definition: MuonTimeExtra.h:22
float timeAtIpOutInErr
Definition: MuonTime.h:18
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
float towerS9
total energy in 3x3 tower shape
Definition: MuonEnergy.h:12
static const unsigned int BestInStationByDR
MuonTime time() const
get DT/CSC combined timing information
Definition: Muon.h:131
std::vector< Muon > MuonCollection
collection of Muon objects
Definition: MuonFwd.h:9
math::XYZPoint trkGlobPosAtHcal
void clearMesh()
Definition: MuonMesh.h:41
float ecal_time
Calorimeter timing.
Definition: MuonEnergy.h:37
float ho
energy deposited in crossed HO towers
Definition: MuonEnergy.h:32
MuonMesh * meshAlgo_
bool isTrackerMuon() const override
Definition: Muon.h:277
double depositWithin(double coneSize, const Vetos &vetos=Vetos(), bool skipDepositVeto=false) const
Get deposit.
Definition: IsoDeposit.cc:34
bool approxEqual(const double a, const double b, const double tol=1E-3) const
int numberOfMatches(unsigned int type=SegmentAndTrackArbitration) const
get number of chambers with matched segments
void setCSCGeometry(const CSCGeometry *pg)
Definition: MuonMesh.h:43
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
void init(edm::Event &, const edm::EventSetup &)
bool isRPCMuon() const
Definition: Muon.h:281
DetId hcal_id
DetId of the central HCAL tower with smallest depth.
Definition: MuonEnergy.h:50
edm::EDGetTokenT< reco::TrackToTrackMap > tpfmsCollectionToken_
static const int ME0
Definition: MuonSubdetId.h:16
const Point & vertex() const
reference point on the track. This method is DEPRECATED, please use referencePoint() instead ...
Definition: TrackBase.h:687
std::vector< reco::MuonSegmentMatch > me0Matches
int iEvent
Definition: GenABIO.cc:230
static const int CSC
Definition: MuonSubdetId.h:13
virtual reco::IsoDeposit deposit(const edm::Event &ev, const edm::EventSetup &evSetup, const reco::Track &track) const =0
double ptThresholdToFillCandidateP4WithGlobalFit_
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:651
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:44
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:26
float emS25
energy deposited in 5x5 ECAL crystal shape around central crystal
Definition: MuonEnergy.h:20
double p() const
momentum vector magnitude
Definition: CaloMuon.h:51
bool isGlobalMuon() const override
Definition: Muon.h:276
static const unsigned int ME0Muon
Definition: Muon.h:270
ArbitrationType
define arbitration schemes
Definition: Muon.h:186
T sqrt(T t)
Definition: SSEVec.h:18
double p4[4]
Definition: TauolaWrapper.h:92
bool isGoodTrackerMuon(const reco::Muon &muon)
double pt() const
track transverse momentum
Definition: TrackBase.h:621
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:8
bool checkLinks(const reco::MuonTrackLinks *) const
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
float timeAtIpInOutErr
Definition: MuonTime.h:15
std::vector< TAMuonChamberMatch > chambers
int nJets
number of jets in the cone
Definition: MuonIsolation.h:12
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:41
MuonQuality combinedQuality() const
get energy deposition information
Definition: Muon.h:121
float timeAtIpOutIn
b) particle is moving from outside in
Definition: MuonTime.h:17
int nDof
number of muon stations used
Definition: MuonTime.h:10
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
float timeAtIpInOutErr() const
Definition: MuonTimeExtra.h:44
CSCDetId chamberId() const
Definition: CSCDetId.h:53
edm::EDGetTokenT< reco::MuonCollection > muonCollectionToken_
float hoEt
ho sum-Et
Definition: MuonIsolation.h:10
edm::EDGetTokenT< reco::TrackCollection > outerTrackCollectionToken_
def stationIndex(name)
Definition: plotscripts.py:354
edm::Handle< RPCRecHitCollection > rpcHitHandle_
float hoS9
energy deposited in 3x3 HO tower shape around central tower
Definition: MuonEnergy.h:34
std::vector< reco::MuonRPCHitMatch > rpcMatches
static const unsigned int BestInChamberByDR
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:245
T min(T a, T b)
Definition: MathUtil.h:58
ME0SegmentRef me0SegmentRef
bool isQualityValid() const
Definition: Muon.h:119
ParameterDescriptionBase * add(U const &iLabel, T const &value)
edm::Handle< reco::TrackToTrackMap > dytCollectionHandle_
bool isValid() const
Definition: HandleBase.h:74
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:250
#define LogTrace(id)
static const unsigned int BestInStationByDXSlope
math::XYZPointF hcal_position
Definition: MuonEnergy.h:44
bool fillGlobalTrackRefits_
static double sectorPhi(const DetId &id)
bool isEnergyValid() const
Definition: Muon.h:109
TrackRef standAloneMuon() const override
reference to a stand-alone muon Track
Definition: Muon.h:52
float hoVetoEt
ho sum-et in the veto region in r-phi
Definition: MuonIsolation.h:16
#define M_PI
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:639
MuonEnergy calEnergy() const
get energy deposition information
Definition: Muon.h:111
reco::CaloMuon makeCaloMuon(const reco::Muon &)
unsigned int id
int nTracks
number of tracks in the cone (excluding veto region)
Definition: MuonIsolation.h:11
static const unsigned int BestInChamberByDXSlope
float emMax
maximal energy of ECAL crystal in the 5x5 shape
Definition: MuonEnergy.h:22
reco::isodeposit::IsoDepositExtractor * muIsoExtractorTrack_
int ring() const
Definition: CSCDetId.h:75
bool failedToGet() const
Definition: HandleBase.h:78
void setCaloCompatibility(float input)
Definition: CaloMuon.h:43
Definition: DetId.h:18
static const unsigned int RPCMuon
Definition: Muon.h:268
static ICTypeKey toKey(const std::string &s)
bool isTimeValid() const
Definition: Muon.h:129
static const unsigned int TrackerMuon
Definition: Muon.h:264
float emVetoEt
ecal sum-et in the veto region in r-phi
Definition: MuonIsolation.h:14
void configure(const edm::ParameterSet &)
size_type size() const
map size
reco::isodeposit::IsoDepositExtractor * muIsoExtractorJet_
bool isDuplicateOf(const CSCSegmentRef &lhs, const CSCSegmentRef &rhs) const
Definition: MuonMesh.cc:342
MuonTimingFiller * theTimingFiller_
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:30
virtual std::vector< reco::IsoDeposit > deposits(const edm::Event &ev, const edm::EventSetup &evSetup, const reco::Track &track) const
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
TrackRef combinedMuon() const override
reference to a stand-alone muon Track
Definition: Muon.h:55
void setCombinedQuality(const MuonQuality &combinedQuality)
set energy deposition information
Definition: Muon.h:123
std::vector< edm::InputTag > inputCollectionLabels_
static const unsigned int PFMuon
Definition: Muon.h:267
std::vector< MuonChamberMatch > & matches()
get muon matching information
Definition: Muon.h:144
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 fillGlobalTrackQuality_
DetId ecal_id
DetId of the central ECAL crystal.
Definition: MuonEnergy.h:47
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)
fixed size matrix
functor predicate for standard library sort algorithm
static const unsigned int GEMMuon
Definition: Muon.h:269
int sector() const
Definition: DTChamberId.h:61
std::pair< double, int > depositAndCountWithin(double coneSize, const Vetos &vetos=Vetos(), double threshold=-1e+36, bool skipDepositVeto=false) const
Get deposit.
Definition: IsoDeposit.cc:44
T get() const
Definition: EventSetup.h:62
edm::Handle< reco::TrackToTrackMap > tpfmsCollectionHandle_
static const unsigned int BestInStationByDX
TrackDetMatchInfo associate(const edm::Event &, const edm::EventSetup &, const FreeTrajectoryState &, const AssociatorParameters &)
edm::Handle< reco::TrackCollection > innerTrackCollectionHandle_
unsigned int type() const
Definition: Muon.h:273
math::XYZPoint trkGlobPosAtEcal
Track position at different parts of the calorimeter.
int charge() const
track electric charge
Definition: TrackBase.h:567
static const int DT
Definition: MuonSubdetId.h:12
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
MuonTrackType
map for Global Muon refitters
Definition: Muon.h:38
double sigmaThresholdToFillCandidateP4WithGlobalFit_
static const unsigned int StandAloneMuon
Definition: Muon.h:265
float timeAtIpOutIn() const
b) particle is moving from outside in
Definition: MuonTimeExtra.h:48
std::pair< TrackRef, Muon::MuonTrackType > MuonTrackTypePair
Definition: Muon.h:40
void setMatches(const std::vector< MuonChamberMatch > &matches)
set muon matching information
Definition: Muon.h:147
math::XYZPointF ecal_position
Trajectory position at the calorimeter.
Definition: MuonEnergy.h:43
static const unsigned int BestInChamberByDRSlope
double phi() const final
momentum azimuthal angle
float caloCompatibility() const
Definition: CaloMuon.h:42
bool validateGlobalMuonPair(const reco::MuonTrackLinks &goodMuon, const reco::MuonTrackLinks &badMuon)
T const * product() const
Definition: ESHandle.h:86
bool debugWithTruthMatching_
float timeAtIpInOut
Definition: MuonTime.h:14
bool isGoodCaloMuon(const reco::CaloMuon &muon)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
float trackerVetoPt
(sum-)pt inside the veto region in r-phi
Definition: MuonIsolation.h:13
float hadS9
energy deposited in 3x3 HCAL tower shape around central tower
Definition: MuonEnergy.h:28
def move(src, dest)
Definition: eostools.py:511
T get(const Candidate &c)
Definition: component.h:55
edm::Handle< reco::MuonCollection > muonCollectionHandle_
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:633
Definition: Run.h:44
edm::Handle< edm::ValueMap< reco::MuonQuality > > glbQualHandle_
void beginRun(const edm::Run &, const edm::EventSetup &) override
edm::Handle< reco::TrackToTrackMap > pickyCollectionHandle_
edm::EDGetTokenT< reco::TrackToTrackMap > dytCollectionToken_