CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MuonTrackCleanerBase.cc
Go to the documentation of this file.
2 
4 
9 
11 
12 #include <algorithm>
13 
15  : moduleLabel_(cfg.getParameter<std::string>("@module_label")),
16  srcSelectedMuons_(cfg.getParameter<edm::InputTag>("selectedMuons")),
17  dRmatch_(cfg.getParameter<double>("dRmatch")),
18  removeDuplicates_(cfg.getParameter<bool>("removeDuplicates")),
19  maxWarnings_tooMany_(100),
20  numWarnings_tooMany_(0),
21  maxWarnings_tooFew_(3),
22  numWarnings_tooFew_(0)
23 {
24  std::string type_string = cfg.getParameter<std::string>("type");
25  // CV: types defined in RecoMuon/MuonIdentification/python/muons1stStep_cfi.py
26  if ( type_string == "inner tracks" ) type_ = kInnerTrack;
27  else if ( type_string == "outer tracks" ) type_ = kOuterTrack;
28  else if ( type_string == "links" ) type_ = kLink;
29  else if ( type_string.find("tev") == 0 ) type_ = kTeV;
30  else throw cms::Exception("Configuration")
31  << "Invalid Configuration Parameter 'type' = " << type_string << " !!\n";
32 
33  typedef std::vector<edm::InputTag> VInputTag;
34  VInputTag srcTracks = cfg.getParameter<VInputTag>("tracks");
35  for ( VInputTag::const_iterator srcTracks_i = srcTracks.begin();
36  srcTracks_i != srcTracks.end(); ++srcTracks_i ) {
37  todoListEntryType todoListEntry;
38  todoListEntry.srcTracks_ = (*srcTracks_i);
39 
40  todoList_.push_back(todoListEntry);
41 
42  produces<reco::TrackCollection>(todoListEntry.srcTracks_.instance());
43  }
44 
45  verbosity_ = ( cfg.exists("verbosity") ) ?
46  cfg.getParameter<int>("verbosity") : 0;
47 }
48 
49 namespace
50 {
51  struct muonToTrackMatchInfoType
52  {
53  muonToTrackMatchInfoType(double muonPt, const reco::Track* track, double dR)
54  : muonPt_(muonPt),
55  trackPt_(track->pt()),
56  trackCharge_(track->charge()),
57  dR_(dR),
58  track_(track)
59  {}
60  ~muonToTrackMatchInfoType() {}
61  double muonPt_;
62  double trackPt_;
63  int trackCharge_;
64  double dR_;
65  const reco::Track* track_;
66  };
67 
68  struct SortMuonToTrackMatchInfosDescendingMatchQuality
69  {
70  bool operator() (const muonToTrackMatchInfoType& m1, const muonToTrackMatchInfoType& m2)
71  {
72  // 1st criterion: prefer matches of high Pt
73  if ( m1.trackPt_ > (0.5*m1.muonPt_) && m2.trackPt_ < (0.5*m2.muonPt_) ) return true; // m1 has higher rank than m2
74  if ( m1.trackPt_ < (0.5*m1.muonPt_) && m2.trackPt_ > (0.5*m2.muonPt_) ) return false; // m2 has higher rank than m1
75  // 2nd criterion: in case multiple matches to high Pt tracks exist,
76  // take track matched most closely in dR
77  return (m1.dR_ < m2.dR_);
78  }
79  };
80 
81  std::string runLumiEventNumbers_to_string(const edm::Event& evt)
82  {
85  edm::EventNumber_t event_number = evt.id().event();
86  std::ostringstream retVal;
87  retVal << "Run = " << run_number << ", LS = " << ls_number << ", Event = " << event_number;
88  return retVal.str();
89  }
90 }
91 
93 {
94  produceTracks(evt, es);
95  produceTrackExtras(evt, es);
96 }
97 
99 {
100  muonMomentumType muonMomentum;
101  muonMomentum.pt_ = muon_candidate.pt();
102  muonMomentum.eta_ = muon_candidate.eta();
103  muonMomentum.phi_ = muon_candidate.phi();
104 
105  const reco::Muon* muon = dynamic_cast<const reco::Muon*>(&muon_candidate);
106  if ( muon ) {
107  if ( type_ == kInnerTrack && muon->innerTrack().isNonnull() ) {
108  muonMomentum.eta_ = muon->innerTrack()->eta();
109  muonMomentum.phi_ = muon->innerTrack()->phi();
110  } else if ( type_ == kOuterTrack && muon->outerTrack().isNonnull() ) {
111  muonMomentum.eta_ = muon->outerTrack()->eta();
112  muonMomentum.phi_ = muon->outerTrack()->phi();
113  } else if ( (type_ == kLink || type_ == kTeV) && muon->globalTrack().isNonnull() ) {
114  muonMomentum.eta_ = muon->globalTrack()->eta();
115  muonMomentum.phi_ = muon->globalTrack()->phi();
116  }
117  }
118 
119  return muonMomentum;
120 }
121 
123 {
124  if ( verbosity_ ) std::cout << "<MuonTrackCleanerBase::produceTracks>:" << std::endl;
125 
126  std::vector<reco::CandidateBaseRef> selMuons = getSelMuons(evt, srcSelectedMuons_);
127  const reco::CandidateBaseRef muPlus = getTheMuPlus(selMuons);
128  const reco::CandidateBaseRef muMinus = getTheMuMinus(selMuons);
129 
130  std::vector<muonMomentumType> selMuonMomenta;
131  if ( muPlus.isNonnull() ) {
132  if ( verbosity_ ) std::cout << " muPlus: Pt = " << muPlus->pt() << ", eta = " << muPlus->eta() << ", phi = " << muPlus->phi() << std::endl;
133  selMuonMomenta.push_back(getMuonMomentum(*muPlus));
134  }
135  if ( muMinus.isNonnull() ) {
136  if ( verbosity_ ) std::cout << " muMinus: Pt = " << muMinus->pt() << ", eta = " << muMinus->eta() << ", phi = " << muMinus->phi() << std::endl;
137  selMuonMomenta.push_back(getMuonMomentum(*muMinus));
138  }
139 
140 //--- produce collection of reco::Tracks excluding muons
141  for ( typename std::vector<todoListEntryType>::const_iterator todoItem = todoList_.begin();
142  todoItem != todoList_.end(); ++todoItem ) {
143  if ( verbosity_ ) std::cout << "processing trackCollection = " << todoItem->srcTracks_ << std::endl;
144 
145  todoItem->trackRefMap_.clear();
146 
148  evt.getByLabel(todoItem->srcTracks_, tracks);
149 
150  std::auto_ptr<reco::TrackCollection> tracks_cleaned(new reco::TrackCollection());
151 
152  reco::TrackRefProd trackCollectionRefProd_cleaned = evt.getRefBeforePut<reco::TrackCollection>(todoItem->srcTracks_.instance());
153  size_t idxTrack_cleaned = 0;
154 
155  std::vector<muonToTrackMatchInfoType> selMuonToTrackMatches;
156  for ( std::vector<muonMomentumType>::const_iterator selMuonMomentum = selMuonMomenta.begin();
157  selMuonMomentum != selMuonMomenta.end(); ++selMuonMomentum ) {
158  std::vector<muonToTrackMatchInfoType> tmpMatches;
159  for ( reco::TrackCollection::const_iterator track = tracks->begin();
160  track != tracks->end(); ++track ) {
161  double dR = reco::deltaR(track->eta(), track->phi(), selMuonMomentum->eta_, selMuonMomentum->phi_);
162  if ( dR < dRmatch_ ) tmpMatches.push_back(muonToTrackMatchInfoType(selMuonMomentum->pt_, &(*track), dR));
163  }
164  // rank muon-to-track matches by quality
165  std::sort(tmpMatches.begin(), tmpMatches.end(), SortMuonToTrackMatchInfosDescendingMatchQuality());
166  if ( tmpMatches.size() > 0 ) selMuonToTrackMatches.push_back(tmpMatches.front());
167  if ( removeDuplicates_ ) {
168  // CV: remove all high Pt tracks very close to muon direction
169  // (duplicate tracks arise in case muon track in SiStrip + Pixel detector is reconstructed as 2 disjoint segments)
170  for ( std::vector<muonToTrackMatchInfoType>::const_iterator tmpMatch = tmpMatches.begin();
171  tmpMatch != tmpMatches.end(); ++tmpMatch ) {
172  if ( (tmpMatch->dR_ < 1.e-3 && tmpMatch->trackPt_ > (0.33*tmpMatch->muonPt_)) ||
173  (tmpMatch->dR_ < 1.e-1 && tmpMatch->trackPt_ > TMath::Max(0.66*tmpMatch->muonPt_, 10.)) ) selMuonToTrackMatches.push_back(*tmpMatch);
174  }
175  }
176  }
177 
178  std::vector<reco::TrackRef> removedTracks;
179  size_t numTracks = tracks->size();
180  for ( size_t trackIdx = 0; trackIdx < numTracks; ++trackIdx ) {
181  reco::TrackRef track(tracks, trackIdx);
182  bool isMuon = false;
183  for ( std::vector<muonToTrackMatchInfoType>::const_iterator muonMatchInfo = selMuonToTrackMatches.begin();
184  muonMatchInfo != selMuonToTrackMatches.end(); ++muonMatchInfo ) {
185  if ( muonMatchInfo->track_ == &(*track) ) isMuon = true;
186  }
187  if ( verbosity_ && track->pt() > 5. ) {
188  std::cout << "track: Pt = " << track->pt() << ", eta = " << track->eta() << ", phi = " << track->phi() << ", isMuon = " << isMuon << std::endl;
189  }
190  if ( isMuon ) {
191  removedTracks.push_back(track); // track belongs to a selected muon, do not copy
192  } else {
193  tracks_cleaned->push_back(*track);
194  todoItem->trackRefMap_[reco::TrackRef(trackCollectionRefProd_cleaned, idxTrack_cleaned)] = track;
195  ++idxTrack_cleaned;
196  }
197  }
198  if ( (type_ >= kInnerTrack && type_ <= kLink && removedTracks.size() > selMuons.size() && numWarnings_tooMany_ < maxWarnings_tooMany_) &&
199  (type_ >= kInnerTrack && type_ <= kInnerTrack && removedTracks.size() < selMuons.size() && numWarnings_tooFew_ < maxWarnings_tooFew_ ) ) {
200  edm::LogWarning("MuonTrackCleanerBase")
201  << " (" << runLumiEventNumbers_to_string(evt) << ")" << std::endl
202  << " Removed " << removedTracks.size() << " tracks from event containing " << selMuons.size() << " muons !!" << std::endl;
203  if ( muPlus.isNonnull() ) std::cout << " muPlus: Pt = " << muPlus->pt() << ", eta = " << muPlus->eta() << ", phi = " << muPlus->phi() << std::endl;
204  if ( muMinus.isNonnull() ) std::cout << " muMinus: Pt = " << muMinus->pt() << ", eta = " << muMinus->eta() << ", phi = " << muMinus->phi() << std::endl;
205  std::cout << "Removed tracks:" << std::endl;
206  int idx = 0;
207  for ( std::vector<reco::TrackRef>::const_iterator removedTrack = removedTracks.begin();
208  removedTrack != removedTracks.end(); ++removedTrack ) {
209  std::cout << "track #" << idx << ":"
210  << " Pt = " << (*removedTrack)->pt() << ", eta = " << (*removedTrack)->eta() << ", phi = " << (*removedTrack)->phi() << std::endl;
211  ++idx;
212  }
213  if ( removedTracks.size() > selMuons.size() ) ++numWarnings_tooMany_;
214  if ( removedTracks.size() < selMuons.size() ) ++numWarnings_tooFew_;
215  }
216 
217  evt.put(tracks_cleaned, todoItem->srcTracks_.instance());
218  }
219 }
RunNumber_t run() const
Definition: EventID.h:39
T getParameter(std::string const &) const
EventNumber_t event() const
Definition: EventID.h:41
reco::CandidateBaseRef getTheMuMinus(const std::vector< reco::CandidateBaseRef > &)
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:250
tuple cfg
Definition: looper.py:237
bool isMuon(const Candidate &part)
Definition: pdgIdUtils.h:11
virtual TrackRef innerTrack() const
Definition: Muon.h:48
virtual float eta() const =0
momentum pseudorapidity
std::vector< Track > TrackCollection
collection of Tracks
Definition: TrackFwd.h:13
bool exists(std::string const &parameterName) const
checks if a parameter exists
unsigned long long EventNumber_t
edm::LuminosityBlockNumber_t luminosityBlock() const
Definition: EventBase.h:59
virtual float phi() const =0
momentum azimuthal angle
bool isNonnull() const
Checks for non-null.
Definition: RefToBase.h:280
double deltaR(const T1 &t1, const T2 &t2)
Definition: deltaR.h:48
unsigned int LuminosityBlockNumber_t
virtual float pt() const =0
transverse momentum
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:113
virtual void produce(edm::Event &, const edm::EventSetup &)
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:402
edm::InputTag srcSelectedMuons_
virtual TrackRef outerTrack() const
reference to Track reconstructed in the muon detector only
Definition: Muon.h:51
RefProd< PROD > getRefBeforePut()
Definition: Event.h:133
muonMomentumType getMuonMomentum(const reco::Candidate &)
T Max(T a, T b)
Definition: MathUtil.h:44
tuple tracks
Definition: testEve_cfg.py:39
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
edm::Ref< TrackCollection > TrackRef
persistent reference to a Track
Definition: TrackFwd.h:19
virtual void produceTrackExtras(edm::Event &, const edm::EventSetup &)=0
edm::EventID id() const
Definition: EventBase.h:56
tuple cout
Definition: gather_cfg.py:121
MuonTrackCleanerBase(const edm::ParameterSet &)
unsigned int RunNumber_t
std::vector< reco::CandidateBaseRef > getSelMuons(const edm::Event &, const edm::InputTag &)
reco::CandidateBaseRef getTheMuPlus(const std::vector< reco::CandidateBaseRef > &)
moduleLabel_(iConfig.getParameter< string >("@module_label"))
std::vector< todoListEntryType > todoList_
std::string const & instance() const
Definition: InputTag.h:43
virtual TrackRef globalTrack() const
reference to Track reconstructed in both tracked and muon detector
Definition: Muon.h:54
virtual void produceTracks(edm::Event &, const edm::EventSetup &)