CMS 3D CMS Logo

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