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 // $Id: MuonIdProducer.cc,v 1.60 2010/09/26 15:54:05 slava77 Exp $
9 //
10 //
11 
12 
13 // system include files
14 #include <memory>
15 
16 // user include files
19 
22 
24 
34 
37 
38 #include <boost/regex.hpp>
43 
46 
47 #include <algorithm>
48 
53 
55 
57 
59 muIsoExtractorCalo_(0),muIsoExtractorTrack_(0),muIsoExtractorJet_(0)
60 {
61  produces<reco::MuonCollection>();
62  produces<reco::CaloMuonCollection>();
63  produces<reco::MuonTimeExtraMap>("combined");
64  produces<reco::MuonTimeExtraMap>("dt");
65  produces<reco::MuonTimeExtraMap>("csc");
66 
67  minPt_ = iConfig.getParameter<double>("minPt");
68  minP_ = iConfig.getParameter<double>("minP");
69  minPCaloMuon_ = iConfig.getParameter<double>("minPCaloMuon");
70  minNumberOfMatches_ = iConfig.getParameter<int>("minNumberOfMatches");
71  addExtraSoftMuons_ = iConfig.getParameter<bool>("addExtraSoftMuons");
72  maxAbsEta_ = iConfig.getParameter<double>("maxAbsEta");
73  maxAbsDx_ = iConfig.getParameter<double>("maxAbsDx");
74  maxAbsPullX_ = iConfig.getParameter<double>("maxAbsPullX");
75  maxAbsDy_ = iConfig.getParameter<double>("maxAbsDy");
76  maxAbsPullY_ = iConfig.getParameter<double>("maxAbsPullY");
77  fillCaloCompatibility_ = iConfig.getParameter<bool>("fillCaloCompatibility");
78  fillEnergy_ = iConfig.getParameter<bool>("fillEnergy");
79  fillMatching_ = iConfig.getParameter<bool>("fillMatching");
80  fillIsolation_ = iConfig.getParameter<bool>("fillIsolation");
81  writeIsoDeposits_ = iConfig.getParameter<bool>("writeIsoDeposits");
82  fillGlobalTrackQuality_ = iConfig.getParameter<bool>("fillGlobalTrackQuality");
83  //SK: (maybe temporary) run it only if the global is also run
84  fillTrackerKink_ = false;
85  if (fillGlobalTrackQuality_) fillTrackerKink_ = iConfig.getParameter<bool>("fillTrackerKink");
86 
87  ptThresholdToFillCandidateP4WithGlobalFit_ = iConfig.getParameter<double>("ptThresholdToFillCandidateP4WithGlobalFit");
88  sigmaThresholdToFillCandidateP4WithGlobalFit_ = iConfig.getParameter<double>("sigmaThresholdToFillCandidateP4WithGlobalFit");
89  caloCut_ = iConfig.getParameter<double>("minCaloCompatibility"); //CaloMuons
90  arbClean_ = iConfig.getParameter<bool>("runArbitrationCleaner"); // muon mesh
91 
92  // Load TrackDetectorAssociator parameters
93  edm::ParameterSet parameters = iConfig.getParameter<edm::ParameterSet>("TrackAssociatorParameters");
94  parameters_.loadParameters( parameters );
95 
96  // Load parameters for the TimingFiller
97  edm::ParameterSet timingParameters = iConfig.getParameter<edm::ParameterSet>("TimingFillerParameters");
98  theTimingFiller_ = new MuonTimingFiller(timingParameters);
99 
100  if (fillCaloCompatibility_){
101  // Load MuonCaloCompatibility parameters
102  parameters = iConfig.getParameter<edm::ParameterSet>("MuonCaloCompatibility");
103  muonCaloCompatibility_.configure( parameters );
104  }
105 
106  if (fillIsolation_){
107  // Load MuIsoExtractor parameters
108  edm::ParameterSet caloExtractorPSet = iConfig.getParameter<edm::ParameterSet>("CaloExtractorPSet");
109  std::string caloExtractorName = caloExtractorPSet.getParameter<std::string>("ComponentName");
110  muIsoExtractorCalo_ = IsoDepositExtractorFactory::get()->create( caloExtractorName, caloExtractorPSet);
111 
112  edm::ParameterSet trackExtractorPSet = iConfig.getParameter<edm::ParameterSet>("TrackExtractorPSet");
113  std::string trackExtractorName = trackExtractorPSet.getParameter<std::string>("ComponentName");
114  muIsoExtractorTrack_ = IsoDepositExtractorFactory::get()->create( trackExtractorName, trackExtractorPSet);
115 
116  edm::ParameterSet jetExtractorPSet = iConfig.getParameter<edm::ParameterSet>("JetExtractorPSet");
117  std::string jetExtractorName = jetExtractorPSet.getParameter<std::string>("ComponentName");
118  muIsoExtractorJet_ = IsoDepositExtractorFactory::get()->create( jetExtractorName, jetExtractorPSet);
119  }
120  if (fillIsolation_ && writeIsoDeposits_){
121  trackDepositName_ = iConfig.getParameter<std::string>("trackDepositName");
122  produces<reco::IsoDepositMap>(trackDepositName_);
123  ecalDepositName_ = iConfig.getParameter<std::string>("ecalDepositName");
124  produces<reco::IsoDepositMap>(ecalDepositName_);
125  hcalDepositName_ = iConfig.getParameter<std::string>("hcalDepositName");
126  produces<reco::IsoDepositMap>(hcalDepositName_);
127  hoDepositName_ = iConfig.getParameter<std::string>("hoDepositName");
128  produces<reco::IsoDepositMap>(hoDepositName_);
129  jetDepositName_ = iConfig.getParameter<std::string>("jetDepositName");
130  produces<reco::IsoDepositMap>(jetDepositName_);
131  }
132 
133  inputCollectionLabels_ = iConfig.getParameter<std::vector<edm::InputTag> >("inputCollectionLabels");
134  inputCollectionTypes_ = iConfig.getParameter<std::vector<std::string> >("inputCollectionTypes");
135  if (inputCollectionLabels_.size() != inputCollectionTypes_.size())
136  throw cms::Exception("ConfigurationError") << "Number of input collection labels is different from number of types. " <<
137  "For each collection label there should be exactly one collection type specified.";
138  if (inputCollectionLabels_.size()>4 ||inputCollectionLabels_.empty())
139  throw cms::Exception("ConfigurationError") << "Number of input collections should be from 1 to 4.";
140 
141  debugWithTruthMatching_ = iConfig.getParameter<bool>("debugWithTruthMatching");
142  if (debugWithTruthMatching_) edm::LogWarning("MuonIdentification")
143  << "========================================================================\n"
144  << "Debugging mode with truth matching is turned on!!! Make sure you understand what you are doing!\n"
145  << "========================================================================\n";
146  if (fillGlobalTrackQuality_){
147  globalTrackQualityInputTag_ = iConfig.getParameter<edm::InputTag>("globalTrackQualityInputTag");
148  }
149 
150  if (fillTrackerKink_) {
151  trackerKinkFinder_.reset(new MuonKinkFinder(iConfig.getParameter<edm::ParameterSet>("TrackerKinkFinderParameters")));
152  }
153 
154  //create mesh holder
155  meshAlgo_ = new MuonMesh(iConfig.getParameter<edm::ParameterSet>("arbitrationCleanerOptions"));
156 }
157 
158 
160 {
165  if (meshAlgo_) delete meshAlgo_;
166  // TimingReport::current()->dump(std::cout);
167 }
168 
170 {
171  // TimerStack timers;
172  // timers.push("MuonIdProducer::produce::init");
173 
178 
179  // timers.push("MuonIdProducer::produce::init::getPropagator");
181  iSetup.get<TrackingComponentsRecord>().get("SteppingHelixPropagatorAny", propagator);
182  trackAssociator_.setPropagator(propagator.product());
183 
184  if (fillTrackerKink_) trackerKinkFinder_->init(iSetup);
185 
186  // timers.pop_and_push("MuonIdProducer::produce::init::getInputCollections");
187  for ( unsigned int i = 0; i < inputCollectionLabels_.size(); ++i ) {
188  if ( inputCollectionTypes_[i] == "inner tracks" ) {
191  throw cms::Exception("FatalError") << "Failed to get input track collection with label: " << inputCollectionLabels_[i];
192  LogTrace("MuonIdentification") << "Number of input inner tracks: " << innerTrackCollectionHandle_->size();
193  continue;
194  }
195  if ( inputCollectionTypes_[i] == "outer tracks" ) {
198  throw cms::Exception("FatalError") << "Failed to get input track collection with label: " << inputCollectionLabels_[i];
199  LogTrace("MuonIdentification") << "Number of input outer tracks: " << outerTrackCollectionHandle_->size();
200  continue;
201  }
202  if ( inputCollectionTypes_[i] == "links" ) {
205  throw cms::Exception("FatalError") << "Failed to get input link collection with label: " << inputCollectionLabels_[i];
206  LogTrace("MuonIdentification") << "Number of input links: " << linkCollectionHandle_->size();
207  continue;
208  }
209  if ( inputCollectionTypes_[i] == "muons" ) {
212  throw cms::Exception("FatalError") << "Failed to get input muon collection with label: " << inputCollectionLabels_[i];
213  LogTrace("MuonIdentification") << "Number of input muons: " << muonCollectionHandle_->size();
214  continue;
215  }
216  throw cms::Exception("FatalError") << "Unknown input collection type: " << inputCollectionTypes_[i];
217  }
218 }
219 
222 {
223  LogTrace("MuonIdentification") << "Creating a muon from a track " << track.get()->pt() <<
224  " Pt (GeV), eta: " << track.get()->eta();
225  reco::Muon aMuon( makeMuon( *(track.get()) ) );
226  switch (type) {
227  case InnerTrack:
228  aMuon.setInnerTrack( track );
229  break;
230  case OuterTrack:
231  aMuon.setOuterTrack( track );
232  break;
233  case CombinedTrack:
234  aMuon.setGlobalTrack( track );
235  break;
236  }
237  return aMuon;
238 }
239 
240 
242 {
243  reco::CaloMuon aMuon;
244  aMuon.setInnerTrack( muon.innerTrack() );
245 
246  if (muon.isEnergyValid()) aMuon.setCalEnergy( muon.calEnergy() );
247  // get calo compatibility
249  return aMuon;
250 }
251 
252 
254 {
255  LogTrace("MuonIdentification") << "Creating a muon from a link to tracks object";
256  reco::Muon aMuon;
259  ( fabs(links.trackerTrack()->qoverp()-links.globalTrack()->qoverp()) <
261  aMuon = makeMuon( *(links.globalTrack()) );
262  else
263  aMuon = makeMuon( *(links.trackerTrack()) );
264 
265  aMuon.setInnerTrack( links.trackerTrack() );
266  aMuon.setOuterTrack( links.standAloneTrack() );
267  aMuon.setGlobalTrack( links.globalTrack() );
268  return aMuon;
269 }
270 
272 {
273  // Pt and absolute momentum requirement
274  if (track.pt() < minPt_ || (track.p() < minP_ && track.p() < minPCaloMuon_)){
275  LogTrace("MuonIdentification") << "Skipped low momentum track (Pt,P): " << track.pt() <<
276  ", " << track.p() << " GeV";
277  return false;
278  }
279 
280  // Eta requirement
281  if ( fabs(track.eta()) > maxAbsEta_ ){
282  LogTrace("MuonIdentification") << "Skipped track with large pseudo rapidity (Eta: " << track.eta() << " )";
283  return false;
284  }
285  return true;
286 }
287 
288 unsigned int MuonIdProducer::chamberId( const DetId& id )
289 {
290  switch ( id.det() ) {
291  case DetId::Muon:
292  switch ( id.subdetId() ) {
293  case MuonSubdetId::DT:
294  {
295  DTChamberId detId(id.rawId());
296  return detId.rawId();
297  }
298  break;
299  case MuonSubdetId::CSC:
300  {
301  CSCDetId detId(id.rawId());
302  return detId.chamberId().rawId();
303  }
304  break;
305  default:
306  return 0;
307  }
308  default:
309  return 0;
310  }
311  return 0;
312 }
313 
314 
316 {
317  int numberOfCommonDetIds = 0;
318  if ( ! muon.isMatchesValid() ||
319  track.extra().isNull() ||
320  track.extra()->recHits().isNull() ) return numberOfCommonDetIds;
321  const std::vector<reco::MuonChamberMatch>& matches( muon.matches() );
322  for ( std::vector<reco::MuonChamberMatch>::const_iterator match = matches.begin();
323  match != matches.end(); ++match )
324  {
325  if ( match->segmentMatches.empty() ) continue;
326  bool foundCommonDetId = false;
327 
328  for ( TrackingRecHitRefVector::const_iterator hit = track.extra()->recHitsBegin();
329  hit != track.extra()->recHitsEnd(); ++hit )
330  {
331  // LogTrace("MuonIdentification") << "hit DetId: " << std::hex << hit->get()->geographicalId().rawId() <<
332  // "\t hit chamber DetId: " << getChamberId(hit->get()->geographicalId()) <<
333  // "\t segment DetId: " << match->id.rawId() << std::dec;
334 
335  if ( chamberId(hit->get()->geographicalId()) == match->id.rawId() ) {
336  foundCommonDetId = true;
337  break;
338  }
339  }
340  if ( foundCommonDetId ) {
341  numberOfCommonDetIds++;
342  break;
343  }
344  }
345  return numberOfCommonDetIds;
346 }
347 
349 {
350  edm::ESHandle<CSCGeometry> geomHandle;
351  iSetup.get<MuonGeometryRecord>().get(geomHandle);
352 
353  meshAlgo_->setCSCGeometry(geomHandle.product());
354 
355 }
356 
358  const reco::MuonTrackLinks& badMuon )
359 {
360  if ( std::min(goodMuon.globalTrack()->hitPattern().numberOfValidMuonHits(),
361  badMuon.globalTrack()->hitPattern().numberOfValidMuonHits()) > 10 ){
362  if ( goodMuon.globalTrack()->normalizedChi2() >
363  badMuon.globalTrack()->normalizedChi2() )
364  return false;
365  else
366  return true;
367  }
368  if ( goodMuon.globalTrack()->hitPattern().numberOfValidMuonHits() <
369  badMuon.globalTrack()->hitPattern().numberOfValidMuonHits() ) return false;
370  return true;
371 }
372 
374 {
375  // TimerStack timers;
376  // timers.push("MuonIdProducer::produce");
377 
378  std::auto_ptr<reco::MuonCollection> outputMuons(new reco::MuonCollection);
379  std::auto_ptr<reco::CaloMuonCollection> caloMuons( new reco::CaloMuonCollection );
380 
381  init(iEvent, iSetup);
382 
383  std::auto_ptr<reco::MuonTimeExtraMap> muonTimeMap(new reco::MuonTimeExtraMap());
384  reco::MuonTimeExtraMap::Filler filler(*muonTimeMap);
385  std::auto_ptr<reco::MuonTimeExtraMap> muonTimeMapDT(new reco::MuonTimeExtraMap());
386  reco::MuonTimeExtraMap::Filler fillerDT(*muonTimeMapDT);
387  std::auto_ptr<reco::MuonTimeExtraMap> muonTimeMapCSC(new reco::MuonTimeExtraMap());
388  reco::MuonTimeExtraMap::Filler fillerCSC(*muonTimeMapCSC);
389 
390  std::auto_ptr<reco::IsoDepositMap> trackDepMap(new reco::IsoDepositMap());
391  reco::IsoDepositMap::Filler trackDepFiller(*trackDepMap);
392  std::auto_ptr<reco::IsoDepositMap> ecalDepMap(new reco::IsoDepositMap());
393  reco::IsoDepositMap::Filler ecalDepFiller(*ecalDepMap);
394  std::auto_ptr<reco::IsoDepositMap> hcalDepMap(new reco::IsoDepositMap());
395  reco::IsoDepositMap::Filler hcalDepFiller(*hcalDepMap);
396  std::auto_ptr<reco::IsoDepositMap> hoDepMap(new reco::IsoDepositMap());
397  reco::IsoDepositMap::Filler hoDepFiller(*hoDepMap);
398  std::auto_ptr<reco::IsoDepositMap> jetDepMap(new reco::IsoDepositMap());
399  reco::IsoDepositMap::Filler jetDepFiller(*jetDepMap);
400 
401  // loop over input collections
402 
403  // muons first - no cleaning, take as is.
405  for ( reco::MuonCollection::const_iterator muon = muonCollectionHandle_->begin();
406  muon != muonCollectionHandle_->end(); ++muon )
407  outputMuons->push_back(*muon);
408 
409  // links second ( assume global muon type )
411  std::vector<bool> goodmuons(linkCollectionHandle_->size(),true);
412  if ( goodmuons.size()>1 ){
413  // check for shared tracker tracks
414  for ( unsigned int i=0; i<linkCollectionHandle_->size()-1; ++i ){
415  if (!checkLinks(&linkCollectionHandle_->at(i))) continue;
416  for ( unsigned int j=i+1; j<linkCollectionHandle_->size(); ++j ){
417  if (!checkLinks(&linkCollectionHandle_->at(j))) continue;
418  if ( linkCollectionHandle_->at(i).trackerTrack().isNonnull() &&
419  linkCollectionHandle_->at(i).trackerTrack() ==
420  linkCollectionHandle_->at(j).trackerTrack() )
421  {
422  // Tracker track is the essential part that dominates muon resolution
423  // so taking either muon is fine. All that is important is to preserve
424  // the muon identification information. If number of hits is small,
425  // keep the one with large number of hits, otherwise take the smalest chi2/ndof
427  goodmuons[j] = false;
428  else
429  goodmuons[i] = false;
430  }
431  }
432  }
433  // check for shared stand-alone muons.
434  for ( unsigned int i=0; i<linkCollectionHandle_->size()-1; ++i ){
435  if ( !goodmuons[i] ) continue;
436  if (!checkLinks(&linkCollectionHandle_->at(i))) continue;
437  for ( unsigned int j=i+1; j<linkCollectionHandle_->size(); ++j ){
438  if ( !goodmuons[j] ) continue;
439  if (!checkLinks(&linkCollectionHandle_->at(j))) continue;
440  if ( linkCollectionHandle_->at(i).standAloneTrack().isNonnull() &&
441  linkCollectionHandle_->at(i).standAloneTrack() ==
442  linkCollectionHandle_->at(j).standAloneTrack() )
443  {
445  goodmuons[j] = false;
446  else
447  goodmuons[i] = false;
448  }
449  }
450  }
451  }
452 
453  for ( unsigned int i=0; i<linkCollectionHandle_->size(); ++i ){
454  if ( !goodmuons[i] ) continue;
455  const reco::MuonTrackLinks* links = &linkCollectionHandle_->at(i);
456  if ( ! checkLinks(links)) continue;
457  // check if this muon is already in the list
458  bool newMuon = true;
459  for ( reco::MuonCollection::const_iterator muon = outputMuons->begin();
460  muon != outputMuons->end(); ++muon )
461  if ( muon->track() == links->trackerTrack() &&
462  muon->standAloneMuon() == links->standAloneTrack() &&
463  muon->combinedMuon() == links->globalTrack() )
464  newMuon = false;
465  if ( newMuon ) {
466  outputMuons->push_back( makeMuon( *links ) );
467  outputMuons->back().setType(reco::Muon::GlobalMuon | reco::Muon::StandAloneMuon);
468  }
469  }
470  }
471 
472  // tracker and calo muons are next
474  LogTrace("MuonIdentification") << "Creating tracker muons";
475  for ( unsigned int i = 0; i < innerTrackCollectionHandle_->size(); ++i )
476  {
477  const reco::Track& track = innerTrackCollectionHandle_->at(i);
478  if ( ! isGoodTrack( track ) ) continue;
479  bool splitTrack = false;
480  if ( track.extra().isAvailable() &&
481  TrackDetectorAssociator::crossedIP( track ) ) splitTrack = true;
482  std::vector<TrackDetectorAssociator::Direction> directions;
483  if ( splitTrack ) {
484  directions.push_back(TrackDetectorAssociator::InsideOut);
485  directions.push_back(TrackDetectorAssociator::OutsideIn);
486  } else {
487  directions.push_back(TrackDetectorAssociator::Any);
488  }
489  for ( std::vector<TrackDetectorAssociator::Direction>::const_iterator direction = directions.begin();
490  direction != directions.end(); ++direction )
491  {
492  // make muon
493  // timers.push("MuonIdProducer::produce::fillMuonId");
495  trackerMuon.setType( reco::Muon::TrackerMuon );
496  fillMuonId(iEvent, iSetup, trackerMuon, *direction);
497  // timers.pop();
498 
499  if ( debugWithTruthMatching_ ) {
500  // add MC hits to a list of matched segments.
501  // Since it's debugging mode - code is slow
502  MuonIdTruthInfo::truthMatchMuon(iEvent, iSetup, trackerMuon);
503  }
504 
505  // check if this muon is already in the list
506  // have to check where muon hits are really located
507  // to match properly
508  bool newMuon = true;
509  bool goodTrackerMuon = isGoodTrackerMuon( trackerMuon );
510  for ( reco::MuonCollection::iterator muon = outputMuons->begin();
511  muon != outputMuons->end(); ++muon )
512  {
513  if ( muon->innerTrack().get() == trackerMuon.innerTrack().get() &&
515  phiOfMuonIneteractionRegion(trackerMuon)) > 0 )
516  {
517  newMuon = false;
518  muon->setMatches( trackerMuon.matches() );
519  if (trackerMuon.isTimeValid()) muon->setTime( trackerMuon.time() );
520  if (trackerMuon.isEnergyValid()) muon->setCalEnergy( trackerMuon.calEnergy() );
521  if (goodTrackerMuon) muon->setType( muon->type() | reco::Muon::TrackerMuon );
522  LogTrace("MuonIdentification") << "Found a corresponding global muon. Set energy, matches and move on";
523  break;
524  }
525  }
526  if ( newMuon ) {
527  if ( goodTrackerMuon ){
528  outputMuons->push_back( trackerMuon );
529  } else {
530  LogTrace("MuonIdentification") << "track failed minimal number of muon matches requirement";
531  const reco::CaloMuon& caloMuon = makeCaloMuon(trackerMuon);
532  if ( ! caloMuon.isCaloCompatibilityValid() || caloMuon.caloCompatibility() < caloCut_ || caloMuon.p() < minPCaloMuon_) continue;
533  caloMuons->push_back( caloMuon );
534  }
535  }
536  }
537  }
538  }
539 
540  // and at last the stand alone muons
542  LogTrace("MuonIdentification") << "Looking for new muons among stand alone muon tracks";
543  for ( unsigned int i = 0; i < outerTrackCollectionHandle_->size(); ++i )
544  {
545  // check if this muon is already in the list of global muons
546  bool newMuon = true;
547  for ( reco::MuonCollection::iterator muon = outputMuons->begin();
548  muon != outputMuons->end(); ++muon )
549  {
550  if ( ! muon->standAloneMuon().isNull() ) {
551  // global muon
552  if ( muon->standAloneMuon().get() == &(outerTrackCollectionHandle_->at(i)) ) {
553  newMuon = false;
554  break;
555  }
556  } else {
557  // tracker muon - no direct links to the standalone muon
558  // since we have only a few real muons in an event, matching
559  // the stand alone muon to the tracker muon by DetIds should
560  // be good enough for association. At the end it's up to a
561  // user to redefine the association and what it means. Here
562  // we would like to avoid obvious double counting and we
563  // tolerate a potential miss association
564  if ( overlap(*muon,outerTrackCollectionHandle_->at(i))>0 ) {
565  LogTrace("MuonIdentification") << "Found associated tracker muon. Set a reference and move on";
566  newMuon = false;
567  muon->setOuterTrack( reco::TrackRef( outerTrackCollectionHandle_, i ) );
568  muon->setType( muon->type() | reco::Muon::StandAloneMuon );
569  break;
570  }
571  }
572  }
573  if ( newMuon ) {
574  LogTrace("MuonIdentification") << "No associated stand alone track is found. Making a muon";
575  outputMuons->push_back( makeMuon(iEvent, iSetup,
577  outputMuons->back().setType( reco::Muon::StandAloneMuon );
578  }
579  }
580  }
581 
582  LogTrace("MuonIdentification") << "Dress up muons if it's necessary";
583 
584  int nMuons=outputMuons->size();
585 
586  std::vector<reco::MuonTimeExtra> dtTimeColl(nMuons);
587  std::vector<reco::MuonTimeExtra> cscTimeColl(nMuons);
588  std::vector<reco::MuonTimeExtra> combinedTimeColl(nMuons);
589  std::vector<reco::IsoDeposit> trackDepColl(nMuons);
590  std::vector<reco::IsoDeposit> ecalDepColl(nMuons);
591  std::vector<reco::IsoDeposit> hcalDepColl(nMuons);
592  std::vector<reco::IsoDeposit> hoDepColl(nMuons);
593  std::vector<reco::IsoDeposit> jetDepColl(nMuons);
594 
595  // Fill various information
596  unsigned int i=0;
597  for ( reco::MuonCollection::iterator muon = outputMuons->begin(); muon != outputMuons->end(); ++muon )
598  {
599  // Fill muonID
600  // timers.push("MuonIdProducer::produce::fillMuonId");
601  if ( ( fillMatching_ && ! muon->isMatchesValid() ) ||
602  ( fillEnergy_ && !muon->isEnergyValid() ) )
603  {
604  // predict direction based on the muon interaction region location
605  // if it's available
606  if ( muon->isStandAloneMuon() ) {
607  if ( cos(phiOfMuonIneteractionRegion(*muon) - muon->phi()) > 0 )
609  else
611  } else {
612  LogTrace("MuonIdentification") << "THIS SHOULD NEVER HAPPEN";
613  fillMuonId(iEvent, iSetup, *muon);
614  }
615  }
616 
618  // Fill global quality information
619  fillGlbQuality(iEvent, iSetup, *muon);
620  }
621  LogDebug("MuonIdentification");
622 
623  if (fillTrackerKink_) {
625  }
626 
627  // timers.push("MuonIdProducer::produce::fillCaloCompatibility");
628  if ( fillCaloCompatibility_ ) muon->setCaloCompatibility( muonCaloCompatibility_.evaluate(*muon) );
629  // timers.pop();
630 
631  // timers.push("MuonIdProducer::produce::fillIsolation");
632  if ( fillIsolation_ ) fillMuonIsolation(iEvent, iSetup, *muon,
633  trackDepColl[i], ecalDepColl[i], hcalDepColl[i], hoDepColl[i], jetDepColl[i]);
634  // timers.pop();
635 
636  // fill timing information
637  reco::MuonTime muonTime;
638  reco::MuonTimeExtra dtTime;
639  reco::MuonTimeExtra cscTime;
640  reco::MuonTimeExtra combinedTime;
641 
642  theTimingFiller_->fillTiming(*muon, dtTime, cscTime, combinedTime, iEvent, iSetup);
643 
644  muonTime.nDof=combinedTime.nDof();
645  muonTime.timeAtIpInOut=combinedTime.timeAtIpInOut();
646  muonTime.timeAtIpInOutErr=combinedTime.timeAtIpInOutErr();
647  muonTime.timeAtIpOutIn=combinedTime.timeAtIpOutIn();
648  muonTime.timeAtIpOutInErr=combinedTime.timeAtIpOutInErr();
649 
650  muon->setTime( muonTime);
651  dtTimeColl[i] = dtTime;
652  cscTimeColl[i] = cscTime;
653  combinedTimeColl[i] = combinedTime;
654 
655  i++;
656 
657  }
658 
659  LogTrace("MuonIdentification") << "number of muons produced: " << outputMuons->size();
660  // timers.push("MuonIdProducer::produce::fillArbitration");
661  if ( fillMatching_ ) fillArbitrationInfo( outputMuons.get() );
662  // timers.pop();
663  edm::OrphanHandle<reco::MuonCollection> muonHandle = iEvent.put(outputMuons);
664 
665  filler.insert(muonHandle, combinedTimeColl.begin(), combinedTimeColl.end());
666  filler.fill();
667  fillerDT.insert(muonHandle, dtTimeColl.begin(), dtTimeColl.end());
668  fillerDT.fill();
669  fillerCSC.insert(muonHandle, cscTimeColl.begin(), cscTimeColl.end());
670  fillerCSC.fill();
671 
672  iEvent.put(muonTimeMap,"combined");
673  iEvent.put(muonTimeMapDT,"dt");
674  iEvent.put(muonTimeMapCSC,"csc");
675 
677  trackDepFiller.insert(muonHandle, trackDepColl.begin(), trackDepColl.end());
678  trackDepFiller.fill();
679  iEvent.put(trackDepMap, trackDepositName_);
680  ecalDepFiller.insert(muonHandle, ecalDepColl.begin(), ecalDepColl.end());
681  ecalDepFiller.fill();
682  iEvent.put(ecalDepMap, ecalDepositName_);
683  hcalDepFiller.insert(muonHandle, hcalDepColl.begin(), hcalDepColl.end());
684  hcalDepFiller.fill();
685  iEvent.put(hcalDepMap, hcalDepositName_);
686  hoDepFiller.insert(muonHandle, hoDepColl.begin(), hoDepColl.end());
687  hoDepFiller.fill();
688  iEvent.put(hoDepMap, hoDepositName_);
689  jetDepFiller.insert(muonHandle, jetDepColl.begin(), jetDepColl.end());
690  jetDepFiller.fill();
691  iEvent.put(jetDepMap, jetDepositName_);
692  }
693 
694  iEvent.put(caloMuons);
695 }
696 
697 
699 {
700  if(muon.track()->pt() < minPt_ || muon.track()->p() < minP_) return false;
701  if ( addExtraSoftMuons_ &&
702  muon.pt()<5 && fabs(muon.eta())<1.5 &&
703  muon.numberOfMatches( reco::Muon::NoArbitration ) >= 1 ) return true;
705 }
706 
708  reco::Muon& aMuon,
710 {
711  // perform track - detector association
712  const reco::Track* track = 0;
713  if ( ! aMuon.track().isNull() )
714  track = aMuon.track().get();
715  else
716  {
717  if ( ! aMuon.standAloneMuon().isNull() )
718  track = aMuon.standAloneMuon().get();
719  else
720  throw cms::Exception("FatalError") << "Failed to fill muon id information for a muon with undefined references to tracks";
721  }
722 
723  TrackDetMatchInfo info = trackAssociator_.associate(iEvent, iSetup, *track, parameters_, direction);
724 
725  if ( fillEnergy_ ) {
726  reco::MuonEnergy muonEnergy;
729  muonEnergy.ho = info.crossedEnergy(TrackDetMatchInfo::HORecHits);
731  muonEnergy.emS9 = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits,1); // 3x3 energy
732  muonEnergy.emS25 = info.nXnEnergy(TrackDetMatchInfo::EcalRecHits,2); // 5x5 energy
733  muonEnergy.hadS9 = info.nXnEnergy(TrackDetMatchInfo::HcalRecHits,1); // 3x3 energy
734  muonEnergy.hoS9 = info.nXnEnergy(TrackDetMatchInfo::HORecHits,1); // 3x3 energy
735  muonEnergy.towerS9 = info.nXnEnergy(TrackDetMatchInfo::TowerTotal,1); // 3x3 energy
736  muonEnergy.ecal_position = info.trkGlobPosAtEcal;
737  muonEnergy.hcal_position = info.trkGlobPosAtHcal;
738  if (! info.crossedEcalIds.empty() ) muonEnergy.ecal_id = info.crossedEcalIds.front();
739  if (! info.crossedHcalIds.empty() ) muonEnergy.hcal_id = info.crossedHcalIds.front();
740  // find maximal energy depositions and their time
741  DetId emMaxId = info.findMaxDeposition(TrackDetMatchInfo::EcalRecHits,2); // max energy deposit in 5x5 shape
742  for(std::vector<const EcalRecHit*>::const_iterator hit=info.ecalRecHits.begin();
743  hit!=info.ecalRecHits.end(); ++hit) {
744  if ((*hit)->id() != emMaxId) continue;
745  muonEnergy.emMax = (*hit)->energy();
746  muonEnergy.ecal_time = (*hit)->time();
747  }
748  DetId hadMaxId = info.findMaxDeposition(TrackDetMatchInfo::HcalRecHits,1); // max energy deposit in 3x3 shape
749  for(std::vector<const HBHERecHit*>::const_iterator hit=info.hcalRecHits.begin();
750  hit!=info.hcalRecHits.end(); ++hit) {
751  if ((*hit)->id() != hadMaxId) continue;
752  muonEnergy.hadMax = (*hit)->energy();
753  muonEnergy.hcal_time = (*hit)->time();
754  }
755  aMuon.setCalEnergy( muonEnergy );
756  }
757  if ( ! fillMatching_ && ! aMuon.isTrackerMuon() ) return;
758 
759  // fill muon match info
760  std::vector<reco::MuonChamberMatch> muonChamberMatches;
761  unsigned int nubmerOfMatchesAccordingToTrackAssociator = 0;
762  for( std::vector<TAMuonChamberMatch>::const_iterator chamber=info.chambers.begin();
763  chamber!=info.chambers.end(); chamber++ )
764  {
765  reco::MuonChamberMatch matchedChamber;
766 
767  LocalError localError = chamber->tState.localError().positionError();
768  matchedChamber.x = chamber->tState.localPosition().x();
769  matchedChamber.y = chamber->tState.localPosition().y();
770  matchedChamber.xErr = sqrt( localError.xx() );
771  matchedChamber.yErr = sqrt( localError.yy() );
772 
773  matchedChamber.dXdZ = chamber->tState.localDirection().z()!=0?chamber->tState.localDirection().x()/chamber->tState.localDirection().z():9999;
774  matchedChamber.dYdZ = chamber->tState.localDirection().z()!=0?chamber->tState.localDirection().y()/chamber->tState.localDirection().z():9999;
775  // DANGEROUS - compiler cannot guaranty parameters ordering
776  AlgebraicSymMatrix55 trajectoryCovMatrix = chamber->tState.localError().matrix();
777  matchedChamber.dXdZErr = trajectoryCovMatrix(1,1)>0?sqrt(trajectoryCovMatrix(1,1)):0;
778  matchedChamber.dYdZErr = trajectoryCovMatrix(2,2)>0?sqrt(trajectoryCovMatrix(2,2)):0;
779 
780  matchedChamber.edgeX = chamber->localDistanceX;
781  matchedChamber.edgeY = chamber->localDistanceY;
782 
783  matchedChamber.id = chamber->id;
784  if ( ! chamber->segments.empty() ) ++nubmerOfMatchesAccordingToTrackAssociator;
785 
786  // fill segments
787  for( std::vector<TAMuonSegmentMatch>::const_iterator segment = chamber->segments.begin();
788  segment != chamber->segments.end(); segment++ )
789  {
790  reco::MuonSegmentMatch matchedSegment;
791  matchedSegment.x = segment->segmentLocalPosition.x();
792  matchedSegment.y = segment->segmentLocalPosition.y();
793  matchedSegment.dXdZ = segment->segmentLocalDirection.z()?segment->segmentLocalDirection.x()/segment->segmentLocalDirection.z():0;
794  matchedSegment.dYdZ = segment->segmentLocalDirection.z()?segment->segmentLocalDirection.y()/segment->segmentLocalDirection.z():0;
795  matchedSegment.xErr = segment->segmentLocalErrorXX>0?sqrt(segment->segmentLocalErrorXX):0;
796  matchedSegment.yErr = segment->segmentLocalErrorYY>0?sqrt(segment->segmentLocalErrorYY):0;
797  matchedSegment.dXdZErr = segment->segmentLocalErrorDxDz>0?sqrt(segment->segmentLocalErrorDxDz):0;
798  matchedSegment.dYdZErr = segment->segmentLocalErrorDyDz>0?sqrt(segment->segmentLocalErrorDyDz):0;
799  matchedSegment.t0 = segment->t0;
800  matchedSegment.mask = 0;
801  matchedSegment.dtSegmentRef = segment->dtSegmentRef;
802  matchedSegment.cscSegmentRef = segment->cscSegmentRef;
803  matchedSegment.hasZed_ = segment->hasZed;
804  matchedSegment.hasPhi_ = segment->hasPhi;
805  // test segment
806  bool matchedX = false;
807  bool matchedY = false;
808  LogTrace("MuonIdentification") << " matching local x, segment x: " << matchedSegment.x <<
809  ", chamber x: " << matchedChamber.x << ", max: " << maxAbsDx_;
810  LogTrace("MuonIdentification") << " matching local y, segment y: " << matchedSegment.y <<
811  ", chamber y: " << matchedChamber.y << ", max: " << maxAbsDy_;
812  if (matchedSegment.xErr>0 && matchedChamber.xErr>0 )
813  LogTrace("MuonIdentification") << " xpull: " <<
814  fabs(matchedSegment.x - matchedChamber.x)/sqrt(pow(matchedSegment.xErr,2) + pow(matchedChamber.xErr,2));
815  if (matchedSegment.yErr>0 && matchedChamber.yErr>0 )
816  LogTrace("MuonIdentification") << " ypull: " <<
817  fabs(matchedSegment.y - matchedChamber.y)/sqrt(pow(matchedSegment.yErr,2) + pow(matchedChamber.yErr,2));
818 
819  if (fabs(matchedSegment.x - matchedChamber.x) < maxAbsDx_) matchedX = true;
820  if (fabs(matchedSegment.y - matchedChamber.y) < maxAbsDy_) matchedY = true;
821  if (matchedSegment.xErr>0 && matchedChamber.xErr>0 &&
822  fabs(matchedSegment.x - matchedChamber.x)/sqrt(pow(matchedSegment.xErr,2) + pow(matchedChamber.xErr,2)) < maxAbsPullX_) matchedX = true;
823  if (matchedSegment.yErr>0 && matchedChamber.yErr>0 &&
824  fabs(matchedSegment.y - matchedChamber.y)/sqrt(pow(matchedSegment.yErr,2) + pow(matchedChamber.yErr,2)) < maxAbsPullY_) matchedY = true;
825  if (matchedX && matchedY) matchedChamber.segmentMatches.push_back(matchedSegment);
826  }
827  muonChamberMatches.push_back(matchedChamber);
828  }
829  aMuon.setMatches(muonChamberMatches);
830 
831  LogTrace("MuonIdentification") << "number of muon chambers: " << aMuon.matches().size() << "\n"
832  << "number of chambers with segments according to the associator requirements: " <<
833  nubmerOfMatchesAccordingToTrackAssociator;
834  LogTrace("MuonIdentification") << "number of segment matches with the producer requirements: " <<
836 
837  // fillTime( iEvent, iSetup, aMuon );
838 }
839 
841 {
842  //
843  // apply segment flags
844  //
845  std::vector<std::pair<reco::MuonChamberMatch*,reco::MuonSegmentMatch*> > chamberPairs; // for chamber segment sorting
846  std::vector<std::pair<reco::MuonChamberMatch*,reco::MuonSegmentMatch*> > stationPairs; // for station segment sorting
847  std::vector<std::pair<reco::MuonChamberMatch*,reco::MuonSegmentMatch*> > arbitrationPairs; // for muon segment arbitration
848 
849  // muonIndex1
850  for( unsigned int muonIndex1 = 0; muonIndex1 < pOutputMuons->size(); ++muonIndex1 )
851  {
852  // chamberIter1
853  for( std::vector<reco::MuonChamberMatch>::iterator chamberIter1 = pOutputMuons->at(muonIndex1).matches().begin();
854  chamberIter1 != pOutputMuons->at(muonIndex1).matches().end(); ++chamberIter1 )
855  {
856  if(chamberIter1->segmentMatches.empty()) continue;
857  chamberPairs.clear();
858 
859  // segmentIter1
860  for( std::vector<reco::MuonSegmentMatch>::iterator segmentIter1 = chamberIter1->segmentMatches.begin();
861  segmentIter1 != chamberIter1->segmentMatches.end(); ++segmentIter1 )
862  {
863  chamberPairs.push_back(std::make_pair(&(*chamberIter1), &(*segmentIter1)));
864  if(!segmentIter1->isMask()) // has not yet been arbitrated
865  {
866  arbitrationPairs.clear();
867  arbitrationPairs.push_back(std::make_pair(&(*chamberIter1), &(*segmentIter1)));
868 
869 
870 
871  // find identical segments with which to arbitrate
872  // tracker muons only
873  if (pOutputMuons->at(muonIndex1).isTrackerMuon()) {
874  // muonIndex2
875  for( unsigned int muonIndex2 = muonIndex1+1; muonIndex2 < pOutputMuons->size(); ++muonIndex2 )
876  {
877  // tracker muons only
878  if (! pOutputMuons->at(muonIndex2).isTrackerMuon()) continue;
879  // chamberIter2
880  for( std::vector<reco::MuonChamberMatch>::iterator chamberIter2 = pOutputMuons->at(muonIndex2).matches().begin();
881  chamberIter2 != pOutputMuons->at(muonIndex2).matches().end(); ++chamberIter2 )
882  {
883  // segmentIter2
884  for( std::vector<reco::MuonSegmentMatch>::iterator segmentIter2 = chamberIter2->segmentMatches.begin();
885  segmentIter2 != chamberIter2->segmentMatches.end(); ++segmentIter2 )
886  {
887  if(segmentIter2->isMask()) continue; // has already been arbitrated
888  if(fabs(segmentIter2->x - segmentIter1->x ) < 1E-3 &&
889  fabs(segmentIter2->y - segmentIter1->y ) < 1E-3 &&
890  fabs(segmentIter2->dXdZ - segmentIter1->dXdZ ) < 1E-3 &&
891  fabs(segmentIter2->dYdZ - segmentIter1->dYdZ ) < 1E-3 &&
892  fabs(segmentIter2->xErr - segmentIter1->xErr ) < 1E-3 &&
893  fabs(segmentIter2->yErr - segmentIter1->yErr ) < 1E-3 &&
894  fabs(segmentIter2->dXdZErr - segmentIter1->dXdZErr) < 1E-3 &&
895  fabs(segmentIter2->dYdZErr - segmentIter1->dYdZErr) < 1E-3)
896  arbitrationPairs.push_back(std::make_pair(&(*chamberIter2), &(*segmentIter2)));
897  } // segmentIter2
898  } // chamberIter2
899  } // muonIndex2
900  }
901 
902  // arbitration segment sort
903  if(arbitrationPairs.empty()) continue; // this should never happen
904  if(arbitrationPairs.size()==1) {
905  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDRSlope);
906  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDXSlope);
907  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDR);
908  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDX);
909  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::Arbitrated);
910  } else {
911  sort(arbitrationPairs.begin(), arbitrationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BelongsToTrackByDRSlope));
912  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDRSlope);
913  sort(arbitrationPairs.begin(), arbitrationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BelongsToTrackByDXSlope));
914  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDXSlope);
915  sort(arbitrationPairs.begin(), arbitrationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BelongsToTrackByDR));
916  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDR);
917  sort(arbitrationPairs.begin(), arbitrationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BelongsToTrackByDX));
918  arbitrationPairs.front().second->setMask(reco::MuonSegmentMatch::BelongsToTrackByDX);
919  for( unsigned int it = 0; it < arbitrationPairs.size(); ++it )
920  arbitrationPairs.at(it).second->setMask(reco::MuonSegmentMatch::Arbitrated);
921  }
922  }
923 
924  // setup me1a cleaning for later
925  if( chamberIter1->id.subdetId() == MuonSubdetId::CSC && arbClean_ ) {
926  CSCDetId cscid(chamberIter1->id);
927  if(cscid.ring() == 4)
928  for( std::vector<reco::MuonSegmentMatch>::iterator segmentIter2 = chamberIter1->segmentMatches.begin();
929  segmentIter2 != chamberIter1->segmentMatches.end(); ++segmentIter2 ) {
930  if( segmentIter1->cscSegmentRef.isNonnull() && segmentIter2->cscSegmentRef.isNonnull() )
931  if( meshAlgo_->isDuplicateOf(segmentIter1->cscSegmentRef,segmentIter2->cscSegmentRef) &&
932  (segmentIter2->mask & 0x1e0000) &&
933  (segmentIter1->mask & 0x1e0000) )
935  //if the track has lost the segment already through normal arbitration no need to do it again.
936  }
937  }// mark all ME1/a duplicates that this track owns
938 
939  } // segmentIter1
940 
941  // chamber segment sort
942  if(chamberPairs.empty()) continue; // this should never happen
943  if(chamberPairs.size()==1) {
944  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDRSlope);
945  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDXSlope);
946  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDR);
947  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDX);
948  } else {
949  sort(chamberPairs.begin(), chamberPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInChamberByDRSlope));
950  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDRSlope);
951  sort(chamberPairs.begin(), chamberPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInChamberByDXSlope));
952  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDXSlope);
953  sort(chamberPairs.begin(), chamberPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInChamberByDR));
954  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDR);
955  sort(chamberPairs.begin(), chamberPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInChamberByDX));
956  chamberPairs.front().second->setMask(reco::MuonSegmentMatch::BestInChamberByDX);
957  }
958  } // chamberIter1
959 
960  // station segment sort
961  for( int stationIndex = 1; stationIndex < 5; ++stationIndex )
962  for( int detectorIndex = 1; detectorIndex < 4; ++detectorIndex )
963  {
964  stationPairs.clear();
965 
966  // chamberIter
967  for( std::vector<reco::MuonChamberMatch>::iterator chamberIter = pOutputMuons->at(muonIndex1).matches().begin();
968  chamberIter != pOutputMuons->at(muonIndex1).matches().end(); ++chamberIter )
969  {
970  if(!(chamberIter->station()==stationIndex && chamberIter->detector()==detectorIndex)) continue;
971  if(chamberIter->segmentMatches.empty()) continue;
972 
973  for( std::vector<reco::MuonSegmentMatch>::iterator segmentIter = chamberIter->segmentMatches.begin();
974  segmentIter != chamberIter->segmentMatches.end(); ++segmentIter )
975  stationPairs.push_back(std::make_pair(&(*chamberIter), &(*segmentIter)));
976  } // chamberIter
977 
978  if(stationPairs.empty()) continue; // this may very well happen
979  if(stationPairs.size()==1) {
980  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDRSlope);
981  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDXSlope);
982  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDR);
983  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDX);
984  } else {
985  sort(stationPairs.begin(), stationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInStationByDRSlope));
986  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDRSlope);
987  sort(stationPairs.begin(), stationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInStationByDXSlope));
988  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDXSlope);
989  sort(stationPairs.begin(), stationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInStationByDR));
990  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDR);
991  sort(stationPairs.begin(), stationPairs.end(), SortMuonSegmentMatches(reco::MuonSegmentMatch::BestInStationByDX));
992  stationPairs.front().second->setMask(reco::MuonSegmentMatch::BestInStationByDX);
993  }
994  }
995 
996  } // muonIndex1
997 
998  if(arbClean_) {
999  // clear old mesh, create and prune new mesh!
1000  meshAlgo_->clearMesh();
1001  meshAlgo_->runMesh(pOutputMuons);
1002  }
1003 }
1004 
1006  reco::IsoDeposit& trackDep, reco::IsoDeposit& ecalDep, reco::IsoDeposit& hcalDep, reco::IsoDeposit& hoDep,
1007  reco::IsoDeposit& jetDep)
1008 {
1009  reco::MuonIsolation isoR03, isoR05;
1010  const reco::Track* track = 0;
1011  if ( ! aMuon.track().isNull() )
1012  track = aMuon.track().get();
1013  else
1014  {
1015  if ( ! aMuon.standAloneMuon().isNull() )
1016  track = aMuon.standAloneMuon().get();
1017  else
1018  throw cms::Exception("FatalError") << "Failed to compute muon isolation information for a muon with undefined references to tracks";
1019  }
1020 
1021  // get deposits
1022  reco::IsoDeposit depTrk = muIsoExtractorTrack_->deposit(iEvent, iSetup, *track );
1023  std::vector<reco::IsoDeposit> caloDeps = muIsoExtractorCalo_->deposits(iEvent, iSetup, *track);
1024  reco::IsoDeposit depJet = muIsoExtractorJet_->deposit(iEvent, iSetup, *track );
1025 
1026  if(caloDeps.size()!=3) {
1027  LogTrace("MuonIdentification") << "Failed to fill vector of calorimeter isolation deposits!";
1028  return;
1029  }
1030 
1031  reco::IsoDeposit depEcal = caloDeps.at(0);
1032  reco::IsoDeposit depHcal = caloDeps.at(1);
1033  reco::IsoDeposit depHo = caloDeps.at(2);
1034 
1035  trackDep = depTrk;
1036  ecalDep = depEcal;
1037  hcalDep = depHcal;
1038  hoDep = depHo;
1039  jetDep = depJet;
1040 
1041  isoR03.sumPt = depTrk.depositWithin(0.3);
1042  isoR03.emEt = depEcal.depositWithin(0.3);
1043  isoR03.hadEt = depHcal.depositWithin(0.3);
1044  isoR03.hoEt = depHo.depositWithin(0.3);
1045  isoR03.nTracks = depTrk.depositAndCountWithin(0.3).second;
1046  isoR03.nJets = depJet.depositAndCountWithin(0.3).second;
1047  isoR03.trackerVetoPt = depTrk.candEnergy();
1048  isoR03.emVetoEt = depEcal.candEnergy();
1049  isoR03.hadVetoEt = depHcal.candEnergy();
1050  isoR03.hoVetoEt = depHo.candEnergy();
1051 
1052  isoR05.sumPt = depTrk.depositWithin(0.5);
1053  isoR05.emEt = depEcal.depositWithin(0.5);
1054  isoR05.hadEt = depHcal.depositWithin(0.5);
1055  isoR05.hoEt = depHo.depositWithin(0.5);
1056  isoR05.nTracks = depTrk.depositAndCountWithin(0.5).second;
1057  isoR05.nJets = depJet.depositAndCountWithin(0.5).second;
1058  isoR05.trackerVetoPt = depTrk.candEnergy();
1059  isoR05.emVetoEt = depEcal.candEnergy();
1060  isoR05.hadVetoEt = depHcal.candEnergy();
1061  isoR05.hoVetoEt = depHo.candEnergy();
1062 
1063 
1064  aMuon.setIsolation(isoR03, isoR05);
1065 
1066 }
1067 
1069 {
1070  //FIXME: E = sqrt(p^2 + m^2), where m == 0.105658369(9)GeV
1071  double energy = sqrt(track.p() * track.p() + 0.011163691);
1072  math::XYZTLorentzVector p4(track.px(),
1073  track.py(),
1074  track.pz(),
1075  energy);
1076  return reco::Muon( track.charge(), p4, track.vertex() );
1077 }
1078 
1080 {
1081  double phi = 0;
1082  if( id.subdetId() == MuonSubdetId::DT ) { // DT
1083  DTChamberId muonId(id.rawId());
1084  if ( muonId.sector() <= 12 )
1085  phi = (muonId.sector()-1)/6.*M_PI;
1086  if ( muonId.sector() == 13 ) phi = 3/6.*M_PI;
1087  if ( muonId.sector() == 14 ) phi = 9/6.*M_PI;
1088  }
1089  if( id.subdetId() == MuonSubdetId::CSC ) { // CSC
1090  CSCDetId muonId(id.rawId());
1091  phi = M_PI/4+(muonId.triggerSector()-1)/3.*M_PI;
1092  }
1093  if ( phi > M_PI ) phi -= 2*M_PI;
1094  return phi;
1095 }
1096 
1098 {
1099  if ( muon.isStandAloneMuon() ) return muon.standAloneMuon()->innerPosition().phi();
1100  // the rest is tracker muon only
1101  if ( muon.matches().empty() ){
1102  if ( muon.innerTrack().isAvailable() &&
1103  muon.innerTrack()->extra().isAvailable() )
1104  return muon.innerTrack()->outerPosition().phi();
1105  else
1106  return muon.phi(); // makes little sense, but what else can I use
1107  }
1108  return sectorPhi(muon.matches().at(0).id);
1109 }
1110 
1112 {
1114  iEvent.getByLabel(globalTrackQualityInputTag_, glbQualH);
1115 
1116  if(aMuon.isGlobalMuon() && !glbQualH.failedToGet()) {
1117  aMuon.setCombinedQuality((*glbQualH)[aMuon.combinedMuon()]);
1118  }
1119 
1120  LogDebug("MuonIdentification") << "tkChiVal " << aMuon.combinedQuality().trkRelChi2;
1121 
1122 }
1123 
1125  // skip muons with no tracks
1126  if (aMuon.innerTrack().isNull()) return;
1127  // get quality from muon if already there, otherwise make empty one
1128  reco::MuonQuality quality = (aMuon.isQualityValid() ? aMuon.combinedQuality() : reco::MuonQuality());
1129  // fill it
1130  bool filled = trackerKinkFinder_->fillTrkKink(quality, *aMuon.innerTrack());
1131  // if quality was there, or if we filled it, commit to the muon
1132  if (filled || aMuon.isQualityValid()) aMuon.setCombinedQuality(quality);
1133 }
1134 
1136  bool trackBAD = links->trackerTrack().isNull();
1137  bool staBAD = links->standAloneTrack().isNull();
1138  bool glbBAD = links->globalTrack().isNull();
1139  if (trackBAD || staBAD || glbBAD )
1140  {
1141  edm::LogWarning("muonIDbadLinks") << "Global muon links to constituent tracks are invalid: trkBad "
1142  <<trackBAD <<" standaloneBad "<<staBAD<<" globalBad "<<glbBAD
1143  <<". There should be no such object. Muon is skipped.";
1144  return false;
1145  }
1146  return true;
1147 }
#define LogDebug(id)
std::string hoDepositName_
double p() const
momentum vector magnitude
Definition: TrackBase.h:129
type
Definition: HCALResponse.h:22
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:131
int i
Definition: DBlmapReader.cc:9
float xx() const
Definition: LocalError.h:19
reco::Muon makeMuon(edm::Event &iEvent, const edm::EventSetup &iSetup, const reco::TrackRef &track, TrackType type)
dictionary parameters
Definition: Parameters.py:2
static const unsigned int GlobalMuon
Definition: Muon.h:140
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)
static void truthMatchMuon(const edm::Event &iEvent, const edm::EventSetup &iSetup, reco::Muon &aMuon)
DTRecSegment4DRef dtSegmentRef
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
virtual void setOuterTrack(const TrackRef &t)
set reference to Track
Definition: Muon.cc:719
void setType(unsigned int type)
Definition: Muon.h:144
TrackDetectorAssociator trackAssociator_
CSCSegmentRef cscSegmentRef
const TrackExtraRef & extra() const
reference to &quot;extra&quot; object
Definition: Track.h:97
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:38
edm::Handle< reco::MuonTrackLinksCollection > linkCollectionHandle_
bool isTrackerMuon() const
Definition: Muon.h:149
int overlap(const reco::Muon &muon, const reco::Track &track)
bool fillCaloCompatibility_
std::vector< const EcalRecHit * > ecalRecHits
hits in the cone
virtual void setInnerTrack(const TrackRef &t)
set reference to Track
Definition: Muon.cc:720
std::vector< DetId > crossedEcalIds
std::string trackDepositName_
void insert(const H &h, I begin, I end)
Definition: ValueMap.h:53
double phiOfMuonIneteractionRegion(const reco::Muon &muon) const
std::vector< CaloMuon > CaloMuonCollection
collection of Muon objects
Definition: MuonFwd.h:27
DetId findMaxDeposition(EnergyType)
Find detector elements with highest energy deposition.
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:39
bool isGlobalMuon() const
Definition: Muon.h:148
float emS9
energy deposited in 3x3 ECAL crystal shape around central crystal
Definition: MuonEnergy.h:18
std::vector< std::string > inputCollectionTypes_
double evaluate(const reco::Muon &)
MuonCaloCompatibility muonCaloCompatibility_
static const unsigned int BestInStationByDRSlope
float timeAtIpOutInErr() const
Definition: MuonTimeExtra.h:50
bool isMatchesValid() const
Definition: Muon.h:89
#define min(a, b)
Definition: mlp_lapack.h:161
void setIsolation(const MuonIsolation &isoR03, const MuonIsolation &isoR05)
Definition: Muon.cc:712
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
double px() const
x coordinate of momentum vector
Definition: TrackBase.h:133
bool isAvailable() const
Definition: Ref.h:275
static const unsigned int BelongsToTrackByDXSlope
bool isStandAloneMuon() const
Definition: Muon.h:150
void setCalEnergy(const MuonEnergy &calEnergy)
set energy deposition information
Definition: Muon.h:64
void fillGlbQuality(edm::Event &, const edm::EventSetup &, reco::Muon &aMuon)
int nDof() const
number of measurements used in timing calculation
Definition: MuonTimeExtra.h:23
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
virtual double eta() const
momentum pseudorapidity
MuonTime time() const
get timing information
Definition: Muon.h:82
virtual void beginRun(edm::Run &, const edm::EventSetup &)
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_
double depositWithin(double coneSize, const Vetos &vetos=Vetos(), bool skipDepositVeto=false) const
Get deposit.
Definition: IsoDeposit.cc:34
uint32_t rawId() const
get the raw id
Definition: DetId.h:45
void setCSCGeometry(const CSCGeometry *pg)
Definition: MuonMesh.h:43
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:30
void init(edm::Event &, const edm::EventSetup &)
DetId hcal_id
DetId of the central HCAL tower with smallest depth.
Definition: MuonEnergy.h:50
int iEvent
Definition: GenABIO.cc:243
static const int CSC
Definition: MuonSubdetId.h:15
bool isNull() const
Checks for null.
Definition: Ref.h:246
double ptThresholdToFillCandidateP4WithGlobalFit_
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:141
TrackAssociatorParameters parameters_
bool isCaloCompatibilityValid() const
Definition: CaloMuon.h:45
void fillArbitrationInfo(reco::MuonCollection *)
void fillTrackerKink(reco::Muon &aMuon)
void setPropagator(const Propagator *)
use a user configured propagator
float yy() const
Definition: LocalError.h:21
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:52
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:84
T sqrt(T t)
Definition: SSEVec.h:28
double p4[4]
Definition: TauolaWrapper.h:92
bool isGoodTrackerMuon(const reco::Muon &muon)
double pt() const
track transverse momentum
Definition: TrackBase.h:131
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_
MuonQuality combinedQuality() const
get energy deposition information
Definition: Muon.h:72
float timeAtIpOutIn
b) particle is moving from outside in
Definition: MuonTime.h:17
int nDof
number of muon stations used
Definition: MuonTime.h:10
float timeAtIpInOutErr() const
Definition: MuonTimeExtra.h:45
int j
Definition: DBlmapReader.cc:9
CSCDetId chamberId() const
Definition: CSCDetId.h:55
float hoEt
ho sum-Et
Definition: MuonIsolation.h:10
float hoS9
energy deposited in 3x3 HO tower shape around central tower
Definition: MuonEnergy.h:34
static const unsigned int BestInChamberByDR
bool isQualityValid() const
Definition: Muon.h:70
bool isValid() const
Definition: HandleBase.h:76
edm::Handle< reco::TrackCollection > outerTrackCollectionHandle_
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:355
double crossedEnergy(EnergyType)
energy in detector elements crossed by the track by types
#define LogTrace(id)
static const unsigned int BestInStationByDXSlope
math::XYZPointF hcal_position
Definition: MuonEnergy.h:44
static double sectorPhi(const DetId &id)
bool isEnergyValid() const
Definition: Muon.h:60
float hoVetoEt
ho sum-et in the veto region in r-phi
Definition: MuonIsolation.h:16
int numberOfMatches(ArbitrationType type=SegmentAndTrackArbitration) const
get number of chambers with matched segments
Definition: Muon.cc:40
double pz() const
z coordinate of momentum vector
Definition: TrackBase.h:137
MuonEnergy calEnergy() const
get energy deposition information
Definition: Muon.h:62
reco::CaloMuon makeCaloMuon(const reco::Muon &)
virtual ~MuonIdProducer()
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_
const Point & vertex() const
reference point on the track. This method is DEPRECATED, please use referencePoint() instead ...
Definition: TrackBase.h:156
int ring() const
Definition: CSCDetId.h:77
bool failedToGet() const
Definition: HandleBase.h:80
void setCaloCompatibility(float input)
Definition: CaloMuon.h:44
Definition: DetId.h:20
#define M_PI
Definition: BFit3D.cc:3
bool isTimeValid() const
Definition: Muon.h:80
virtual TrackRef combinedMuon() const
reference to a stand-alone muon Track
Definition: Muon.h:45
static const unsigned int TrackerMuon
Definition: Muon.h:141
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_
float timeAtIpInOut() const
Definition: MuonTimeExtra.h:44
float hadMax
maximal energy of HCAL tower in the 3x3 shape
Definition: MuonEnergy.h:30
virtual double pt() const
transverse momentum
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:31
const T & get() const
Definition: EventSetup.h:55
T const * product() const
Definition: ESHandle.h:62
void setCombinedQuality(const MuonQuality &combinedQuality)
set energy deposition information
Definition: Muon.h:74
std::vector< edm::InputTag > inputCollectionLabels_
std::vector< MuonChamberMatch > & matches()
get muon matching information
Definition: Muon.h:91
void setCalEnergy(const MuonEnergy &calEnergy)
set energy deposition information
Definition: CaloMuon.h:38
int triggerSector() const
Definition: CSCDetId.cc:47
MuonIdProducer(const edm::ParameterSet &)
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_
unsigned int chamberId(const DetId &)
static const unsigned int BelongsToTrackByDX
functor predicate for standard library sort algorithm
int sector() const
Definition: DTChamberId.h:63
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
def stationIndex
Definition: plotscripts.py:386
static const unsigned int BestInStationByDX
TrackDetMatchInfo associate(const edm::Event &, const edm::EventSetup &, const FreeTrajectoryState &, const AssociatorParameters &)
edm::Handle< reco::TrackCollection > innerTrackCollectionHandle_
math::XYZPoint trkGlobPosAtEcal
Track position at different parts of the calorimeter.
int charge() const
track electric charge
Definition: TrackBase.h:113
static const int DT
Definition: MuonSubdetId.h:14
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:6
double sigmaThresholdToFillCandidateP4WithGlobalFit_
static const unsigned int StandAloneMuon
Definition: Muon.h:142
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:49
void setMatches(const std::vector< MuonChamberMatch > &matches)
set muon matching information
Definition: Muon.h:94
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:241
virtual void setGlobalTrack(const TrackRef &t)
set reference to Track
Definition: Muon.cc:723
void fillTiming(const reco::Muon &muon, reco::MuonTimeExtra &dtTime, reco::MuonTimeExtra &cscTime, reco::MuonTimeExtra &combinedTime, edm::Event &iEvent, const edm::EventSetup &iSetup)
math::XYZPointF ecal_position
Trajectory position at the calorimeter.
Definition: MuonEnergy.h:43
virtual void produce(edm::Event &, const edm::EventSetup &)
virtual double phi() const
momentum azimuthal angle
static const unsigned int BestInChamberByDRSlope
float caloCompatibility() const
Definition: CaloMuon.h:43
bool validateGlobalMuonPair(const reco::MuonTrackLinks &goodMuon, const reco::MuonTrackLinks &badMuon)
bool debugWithTruthMatching_
float timeAtIpInOut
Definition: MuonTime.h:14
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
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:56
edm::InputTag globalTrackQualityInputTag_
edm::Handle< reco::MuonCollection > muonCollectionHandle_
void loadParameters(const edm::ParameterSet &)
double py() const
y coordinate of momentum vector
Definition: TrackBase.h:135
Definition: Run.h:32
Definition: DDAxes.h:10
virtual TrackRef standAloneMuon() const
reference to a stand-alone muon Track
Definition: Muon.h:42