CMS 3D CMS Logo

HLTMuonTrackMassFilter.cc
Go to the documentation of this file.
2 
4 
8 
11 
14 
19 
21 
23 
28 
32 
33 #include <vector>
34 #include <memory>
35 #include <iostream>
36 #include <sstream>
37 
38 
40  beamspotTag_(iConfig.getParameter<edm::InputTag>("BeamSpotTag")),
41  beamspotToken_(consumes<reco::BeamSpot>(beamspotTag_)),
42  muonTag_(iConfig.getParameter<edm::InputTag>("CandTag")),
43  muonToken_(consumes<reco::RecoChargedCandidateCollection>(muonTag_)),
44  trackTag_(iConfig.getParameter<edm::InputTag>("TrackTag")),
45  trackToken_(consumes<reco::RecoChargedCandidateCollection>(trackTag_)),
46  prevCandTag_(iConfig.getParameter<edm::InputTag>("PreviousCandTag")),
47  prevCandToken_(consumes<trigger::TriggerFilterObjectWithRefs>(prevCandTag_)),
48  minMasses_(iConfig.getParameter< std::vector<double> >("MinMasses")),
49  maxMasses_(iConfig.getParameter< std::vector<double> >("MaxMasses")),
50  checkCharge_(iConfig.getParameter<bool>("checkCharge")),
51  minTrackPt_(iConfig.getParameter<double>("MinTrackPt")),
52  minTrackP_(iConfig.getParameter<double>("MinTrackP")),
53  maxTrackEta_(iConfig.getParameter<double>("MaxTrackEta")),
54  maxTrackDxy_(iConfig.getParameter<double>("MaxTrackDxy")),
55  maxTrackDz_(iConfig.getParameter<double>("MaxTrackDz")),
56  minTrackHits_(iConfig.getParameter<int>("MinTrackHits")),
57  maxTrackNormChi2_(iConfig.getParameter<double>("MaxTrackNormChi2")),
58 // maxDzMuonTrack_(iConfig.getParameter<double>("MaxDzMuonTrack")),
59  max_DCAMuonTrack_(iConfig.getParameter<double>("MaxDCAMuonTrack")),
60  cutCowboys_(iConfig.getParameter<bool>("CutCowboys"))
61 {
62  //
63  // verify mass windows
64  //
65  bool massesValid = minMasses_.size()==maxMasses_.size();
66  if ( massesValid ) {
67  for ( unsigned int i=0; i<minMasses_.size(); ++i ) {
68  if ( minMasses_[i]<0 || maxMasses_[i]<0 ||
69  minMasses_[i]>maxMasses_[i] ) massesValid = false;
70  }
71  }
72  if ( !massesValid ) {
73  edm::LogError("HLTMuonTrackMassFilter") << "Inconsistency in definition of mass windows, "
74  << "no event will pass the filter";
75  minMasses_.clear();
76  maxMasses_.clear();
77  }
78 
79  std::ostringstream stream;
80  stream << "instantiated with parameters\n";
81  stream << " beamspot = " << beamspotTag_ << "\n";
82  stream << " muonCandidates = " << muonTag_ << "\n";
83  stream << " trackCandidates = " << trackTag_ << "\n";
84  stream << " previousCandidates = " << prevCandTag_ << "\n";
85  stream << " saveTags= " << saveTags() << "\n";
86  stream << " mass windows =";
87  for ( size_t i=0; i<minMasses_.size(); ++i )
88  stream << " (" << minMasses_[i] << "," << maxMasses_[i] << ")";
89  stream << "\n";
90  stream << " checkCharge = " << checkCharge_ << "\n";
91  stream << " MinTrackPt = " << minTrackPt_ << "\n";
92  stream << " MinTrackP = " << minTrackP_ << "\n";
93  stream << " MaxTrackEta = " << maxTrackEta_ << "\n";
94  stream << " MaxTrackDxy = " << maxTrackDxy_ << "\n";
95  stream << " MaxTrackDz = " << maxTrackDz_ << "\n";
96  stream << " MinTrackHits = " << minTrackHits_ << "\n";
97  stream << " MaxTrackNormChi2 = " << maxTrackNormChi2_ << "\n";
98 // stream << " MaxDzMuonTrack = " << maxDzMuonTrack_ << "\n";
99  LogDebug("HLTMuonTrackMassFilter") << stream.str();
100 
101 }
102 
103 void
107  desc.add<edm::InputTag>("BeamSpotTag",edm::InputTag("hltOfflineBeamSpot"));
108  desc.add<edm::InputTag>("CandTag",edm::InputTag("hltL3MuonCandidates"));
109  // desc.add<edm::InputTag>("TrackTag",edm::InputTag("hltMuTkMuJpsiTrackerMuonCands"));
110  desc.add<edm::InputTag>("TrackTag",edm::InputTag(""));
111  // desc.add<edm::InputTag>("PreviousCandTag",edm::InputTag("hltMu0TkMuJpsiTrackMassFiltered"));
112  desc.add<edm::InputTag>("PreviousCandTag",edm::InputTag(""));
113  {
114  std::vector<double> temp1;
115  temp1.reserve(1);
116  temp1.push_back(2.8);
117  desc.add<std::vector<double> >("MinMasses",temp1);
118  }
119  {
120  std::vector<double> temp1;
121  temp1.reserve(1);
122  temp1.push_back(3.4);
123  desc.add<std::vector<double> >("MaxMasses",temp1);
124  }
125  desc.add<bool>("checkCharge",true);
126  desc.add<double>("MinTrackPt",0.0);
127  desc.add<double>("MinTrackP",3.0);
128  desc.add<double>("MaxTrackEta",999.0);
129  desc.add<double>("MaxTrackDxy",999.0);
130  desc.add<double>("MaxTrackDz",999.0);
131  desc.add<int>("MinTrackHits",5);
132  desc.add<double>("MaxTrackNormChi2",10000000000.0);
133  desc.add<double>("MaxDCAMuonTrack",99999.9);
134  desc.add<bool>("CutCowboys",false);
135  descriptions.add("hltMuonTrackMassFilter",desc);
136 }
137 
138 bool
140 {
141  // The filter object
142  if (saveTags()) {
143  filterproduct.addCollectionTag(muonTag_);
144  filterproduct.addCollectionTag(trackTag_);
145  }
146  //
147  // Beamspot
148  //
149  edm::Handle<reco::BeamSpot> beamspotHandle;
150  iEvent.getByToken(beamspotToken_,beamspotHandle);
151  reco::BeamSpot::Point beamspot(beamspotHandle->position());
152  // Needed for DCA calculation
153  edm::ESHandle<MagneticField> bFieldHandle;
154  iSetup.get<IdealMagneticFieldRecord>().get(bFieldHandle);
155  //
156  // Muons
157  //
159  iEvent.getByToken(muonToken_,muonHandle);
160  //
161  // Tracks
162  //
164  iEvent.getByToken(trackToken_,trackHandle);
165  //
166  // Muons from previous filter
167  //
169  iEvent.getByToken(prevCandToken_,prevCandHandle);
170  std::vector<reco::RecoChargedCandidateRef> prevMuonRefs;
171  prevCandHandle->getObjects(trigger::TriggerMuon,prevMuonRefs);
172  std::vector<reco::RecoChargedCandidateRef> prevTrackRefs;
173  prevCandHandle->getObjects(trigger::TriggerTrack,prevTrackRefs);
174  bool checkPrevTracks = prevTrackRefs.size()==prevMuonRefs.size();
175 // LogDebug("HLTMuonTrackMassFilter") << "#previous track refs = " << prevTrackRefs.size();
176  //
177  // access to muons and selection according to configuration
178  // if the previous candidates are taken from a muon+track
179  // quarkonia filter we rely on the fact that only the muons
180  // are flagged as TriggerMuon
181  //
182  std::vector<reco::RecoChargedCandidateRef> selectedMuonRefs;
183  selectedMuonRefs.reserve(muonHandle->size());
184 // std::vector<size_t> prevMuonIndices;
185 // std::ostringstream stream1;
186  for ( unsigned int i=0; i<muonHandle->size(); ++i ) {
187  // Ref
188  reco::RecoChargedCandidateRef muonRef(muonHandle,i);
189 // stream1 << "Checking muon with q / pt / p / eta = "
190 // << muonRef->charge() << " " << muonRef->pt() << " "
191 // << muonRef->p() << " " << muonRef->eta() << "\n";
192  // passed previous filter?
193  if ( find(prevMuonRefs.begin(),prevMuonRefs.end(),muonRef)==
194  prevMuonRefs.end() ) continue;
195 // prevMuonIndices.push_back(find(prevMuonRefs.begin(),prevMuonRefs.end(),muonRef)-
196 // prevMuonRefs.begin());
197  // keep muon
198 // stream1 << "... accepted as #" << selectedMuonRefs.size() << "\n";
199  selectedMuonRefs.push_back(muonRef);
200  }
201 // LogDebug("HLTMuonTrackMassFilter") << stream1.str();
202  //
203  // access to tracks and selection according to configuration
204  //
205  std::vector<reco::RecoChargedCandidateRef> selectedTrackRefs;
206  selectedTrackRefs.reserve(trackHandle->size());
207 // std::ostringstream stream2;
208  for ( unsigned int i=0; i<trackHandle->size(); ++i ) {
209  // validity of REF
210  reco::RecoChargedCandidateRef trackRef(trackHandle,i);
211  const reco::RecoChargedCandidate& trackCand = *trackRef;
212 // stream2 << "Checking track with q / pt / p / eta = "
213 // << trackCand.charge() << " " << trackCand.pt() << " "
214 // << trackCand.p() << " " << trackCand.eta() << "\n";
215  // cuts on the momentum
216  if ( trackCand.pt()<minTrackPt_ || trackCand.p()<minTrackP_ ||
217  fabs(trackCand.eta())>maxTrackEta_ ) continue;
218  if ( trackCand.track().isNull() ) continue;
219  // cuts on track quality
220  const reco::Track& track = *trackCand.track();
221 // stream2 << "... with dxy / dz / #hits / chi2 = "
222 // << track.dxy(beamspot) << " "
223 // << track.dz(beamspot) << " "
224 // << track.numberOfValidHits() << " "
225 // << track.normalizedChi2();
226  if ( fabs(track.dxy(beamspot))>maxTrackDxy_ ||
227  fabs(track.dz(beamspot))>maxTrackDz_ ||
229  track.normalizedChi2()>maxTrackNormChi2_ ) continue;
230  // keep track
231 // stream2 << "... accepted as #" << selectedTrackRefs.size() << "\n";
232  selectedTrackRefs.push_back(trackRef);
233  }
234 // LogDebug("HLTMuonTrackMassFilter") << stream2.str();
235  //
236  // combinations
237  //
238 // unsigned int nDz(0);
239  unsigned int nQ(0);
240  unsigned int nCowboy(0);
241  unsigned int nComb(0);
244 // std::ostringstream stream3;
245  for (auto & selectedMuonRef : selectedMuonRefs) {
246  const reco::RecoChargedCandidate& muon = *selectedMuonRef;
247  int qMuon = muon.charge();
248  p4Muon = muon.p4();
249  for (auto & selectedTrackRef : selectedTrackRefs) {
250  const reco::RecoChargedCandidate& track = *selectedTrackRef;
251 // stream3 << "Combination " << im << " / " << it << " with dz / q / mass = "
252 // << muon.track()->dz(beamspot)-track.track()->dz(beamspot) << " "
253 // << track.charge()+qMuon << " "
254 // << (p4Muon+track.p4()).mass() << "\n";
255 
256 // if ( fabs(muon.track()->dz(beamspot)-track.track()->dz(beamspot))>
257 // maxDzMuonTrack_ ) continue;
258 // ++nDz;
259  if ( checkCharge_ && track.charge()!=-qMuon ) continue;
260  ++nQ;
261 
263 
264  // DCA between the two muons
265 
266  reco::TrackRef tk1 = muon.track();
267  reco::TrackRef tk2 = track.track();
268 
269  reco::TransientTrack mu1TT(*tk1, &(*bFieldHandle));
270  reco::TransientTrack mu2TT(*tk2, &(*bFieldHandle));
273  if (mu1TS.isValid() && mu2TS.isValid()) {
275  cApp.calculate(mu1TS.theState(), mu2TS.theState());
276  if (!cApp.status() || cApp.distance() > max_DCAMuonTrack_) continue;
277  }
278 
280  // if cutting on cowboys reject muons that bend towards each other
281  if(cutCowboys_ && (qMuon*deltaPhi(p4Muon.phi(), track.phi()) > 0.)) continue;
282  ++nCowboy;
283 
284  if ( checkPrevTracks ) {
285  if ( !pairMatched(prevMuonRefs,prevTrackRefs,
286  selectedMuonRef,
287  selectedTrackRef) ) continue;
288  }
289  double mass = (p4Muon+track.p4()).mass();
290  for ( unsigned int j=0; j<minMasses_.size(); ++j ) {
291  if ( mass>minMasses_[j] && mass<maxMasses_[j] ) {
292  ++nComb;
293  filterproduct.addObject(trigger::TriggerMuon,selectedMuonRef);
294  filterproduct.addObject(trigger::TriggerTrack,selectedTrackRef);
295 // stream3 << "... accepted\n";
296  break;
297  }
298  }
299  }
300  }
301 // LogDebug("HLTMuonTrackMassFilter") << stream3.str();
302 
303 
304  if ( edm::isDebugEnabled() ) {
305  std::ostringstream stream;
306  stream << "Total number of combinations = "
307 // << selectedMuonRefs.size()*selectedTrackRefs.size() << " , after dz " << nDz
308  << " , after charge " << nQ << " , after cutCowboy " << nCowboy << " , after mass " << nComb << std::endl;
309  stream << "Found " << nComb << " jpsi candidates with # / mass / q / pt / eta" << std::endl;
310  std::vector<reco::RecoChargedCandidateRef> muRefs;
311  std::vector<reco::RecoChargedCandidateRef> tkRefs;
312  filterproduct.getObjects(trigger::TriggerMuon,muRefs);
313  filterproduct.getObjects(trigger::TriggerTrack,tkRefs);
317  if ( muRefs.size()==tkRefs.size() ) {
318  for ( unsigned int i=0; i<muRefs.size(); ++i ) {
319  p4Mu = muRefs[i]->p4();
320  p4Tk = tkRefs[i]->p4();
321  p4JPsi = p4Mu + p4Tk;
322  stream << " " << i << " "
323  << p4JPsi.M() << " "
324  << muRefs[i]->charge()+tkRefs[i]->charge() << " "
325  << p4JPsi.P() << " "
326  << p4JPsi.Eta() << "\n";
327  }
328  LogDebug("HLTMuonTrackMassFilter") << stream.str();
329  }
330  else {
331  LogDebug("HLTMuonTrackMassFilter") << "different sizes for muon and track containers!!!";
332  }
333  }
334 
335  return nComb>0;
336 }
337 
338 bool
339 HLTMuonTrackMassFilter::pairMatched (std::vector<reco::RecoChargedCandidateRef>& prevMuonRefs,
340  std::vector<reco::RecoChargedCandidateRef>& prevTrackRefs,
341  const reco::RecoChargedCandidateRef& muonRef,
342  const reco::RecoChargedCandidateRef& trackRef) const
343 {
344  //
345  // check only if references to tracks are available
346  //
347  if ( prevTrackRefs.empty() ) return true;
348  //
349  // validity
350  //
351  if ( prevMuonRefs.size()!=prevTrackRefs.size() ) return false;
352  edm::RefToBase<TrajectorySeed> seedRef = trackRef->track()->seedRef();
353  if ( seedRef.isNull() ) return false;
354  //
355  // comparison by hits of TrajectorySeed of the new track
356  // with the previous candidate
357  //
358  TrajectorySeed::range seedHits = seedRef->recHits();
359  trackingRecHit_iterator prevTrackHitEnd;
362  for ( size_t i=0; i<prevMuonRefs.size(); ++i ) {
363  // identity of muon
364  if ( prevMuonRefs[i]!=muonRef ) continue;
365  // validity of Ref to previous track candidate
366  reco::TrackRef prevTrackRef = prevTrackRefs[i]->track();
367  if ( prevTrackRef.isNull() ) continue;
368  // if the references are the same then found and return true otherwise compare by hits
369  if (prevTrackRef==trackRef->track()) return true;
370  // same #hits
371  if ( seedRef->nHits()!=prevTrackRef->recHitsSize() ) continue;
372  // hit-by-hit comparison based on the sharesInput method
373  iseed = seedHits.first;
374  iprev = prevTrackRef->recHitsBegin();
375  prevTrackHitEnd = prevTrackRef->recHitsEnd();
376  bool identical(true);
377  for ( ; iseed!=seedHits.second&&iprev!=prevTrackHitEnd; ++iseed,++iprev ) {
378  if ( (*iseed).isValid()!=(**iprev).isValid() ||
379  !(*iseed).sharesInput(&**iprev,TrackingRecHit::all) ) {
380  // terminate loop over hits on first mismatch
381  identical = false;
382  break;
383  }
384  }
385  // if seed and previous track candidates are identical : return success
386  if ( identical ) return true;
387  }
388  // no match found
389  return false;
390 }
391 
392 
393 
394 
395 
396 // declare this class as a framework plugin
#define LogDebug(id)
bool isDebugEnabled()
double minTrackP_
track p cut
float distance() const override
void getObjects(Vids &ids, VRphoton &refs) const
various physics-level getters:
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
double eta() const final
momentum pseudorapidity
bool checkCharge_
check opposite charge?
bool hltFilter(edm::Event &, const edm::EventSetup &, trigger::TriggerFilterObjectWithRefs &filterproduct) const override
double normalizedChi2() const
chi-squared divided by n.d.o.f. (or chi-squared * 1e6 if n.d.o.f. is zero)
Definition: TrackBase.h:600
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
TrajectoryStateClosestToPoint impactPointTSCP() const
const FreeTrajectoryState & theState() const
edm::InputTag trackTag_
RecoChargedCandidateCollection (tracks)
double pt() const final
transverse momentum
int charge() const final
electric charge
Definition: LeafCandidate.h:91
math::XYZPoint Point
point in the space
Definition: BeamSpot.h:29
edm::EDGetTokenT< reco::BeamSpot > beamspotToken_
beamspot used for quality cuts
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
double maxTrackDz_
track lip cut w.r.t. beamspot
void addObject(int id, const reco::RecoEcalCandidateRef &ref)
setters for L3 collections: (id=physics type, and Ref<C>)
double maxTrackNormChi2_
normalized chi2 of track
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
bool status() const override
std::vector< double > minMasses_
lower mass limits
bool calculate(const TrajectoryStateOnSurface &sta, const TrajectoryStateOnSurface &stb) override
recHitContainer::const_iterator const_iterator
edm::InputTag muonTag_
RecoChargedCandidateCollection (muons)
std::pair< const_iterator, const_iterator > range
HLTMuonTrackMassFilter(const edm::ParameterSet &)
reco::TrackRef track() const override
reference to a track
const LorentzVector & p4() const final
four-momentum Lorentz vector
Definition: LeafCandidate.h:99
bool cutCowboys_
DCA between the two muons.
unsigned short numberOfValidHits() const
number of valid hits found
Definition: TrackBase.h:901
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool isNull() const
Checks for null.
Definition: Ref.h:248
bool pairMatched(std::vector< reco::RecoChargedCandidateRef > &prevMuonRefs, std::vector< reco::RecoChargedCandidateRef > &prevTrackRefs, const reco::RecoChargedCandidateRef &muonRef, const reco::RecoChargedCandidateRef &trackRef) const
double dz() const
dz parameter (= dsz/cos(lambda)). This is the track z0 w.r.t (0,0,0) only if the refPoint is close to...
Definition: TrackBase.h:648
edm::EDGetTokenT< reco::RecoChargedCandidateCollection > muonToken_
RecoChargedCandidateCollection (muons)
std::vector< RecoChargedCandidate > RecoChargedCandidateCollection
collectin of RecoChargedCandidate objects
double p() const final
magnitude of momentum vector
static void makeHLTFilterDescription(edm::ParameterSetDescription &desc)
Definition: HLTFilter.cc:29
int iseed
Definition: AMPTWrapper.h:124
bool isNull() const
Checks for null.
Definition: RefToBase.h:331
range recHits() const
void addCollectionTag(const edm::InputTag &collectionTag)
collectionTags
int minTrackHits_
valid hits on track
void add(std::string const &label, ParameterSetDescription const &psetDescription)
double minTrackPt_
track pt cut
unsigned int nHits() const
fixed size matrix
bool saveTags() const
Definition: HLTFilter.h:45
edm::EDGetTokenT< trigger::TriggerFilterObjectWithRefs > prevCandToken_
filter objects from previous filter
HLT enums.
T get() const
Definition: EventSetup.h:71
std::vector< double > maxMasses_
higher mass limits
edm::EDGetTokenT< reco::RecoChargedCandidateCollection > trackToken_
RecoChargedCandidateCollection (tracks)
edm::InputTag prevCandTag_
filter objects from previous filter
double maxTrackDxy_
track tip cut w.r.t. beamspot
const Point & position() const
position
Definition: BeamSpot.h:62
edm::InputTag beamspotTag_
beamspot used for quality cuts
double dxy() const
dxy parameter. (This is the transverse impact parameter w.r.t. to (0,0,0) ONLY if refPoint is close t...
Definition: TrackBase.h:630
double phi() const final
momentum azimuthal angle
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Particle.h:21
double maxTrackEta_
track |eta| cut