CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HLTmmkkFilter.cc
Go to the documentation of this file.
1 #include <algorithm>
2 #include <cmath>
3 #include <vector>
4 
7 
10 
13 
22 
24 
26 
27 #include "HLTmmkkFilter.h"
28 
29 using namespace edm;
30 using namespace reco;
31 using namespace std;
32 using namespace trigger;
33 
34 
35 // ----------------------------------------------------------------------
37  thirdTrackMass_(iConfig.getParameter<double>("ThirdTrackMass")),
38  fourthTrackMass_(iConfig.getParameter<double>("FourthTrackMass")),
39  maxEta_(iConfig.getParameter<double>("MaxEta")),
40  minPt_(iConfig.getParameter<double>("MinPt")),
41  minInvMass_(iConfig.getParameter<double>("MinInvMass")),
42  maxInvMass_(iConfig.getParameter<double>("MaxInvMass")),
43  maxNormalisedChi2_(iConfig.getParameter<double>("MaxNormalisedChi2")),
44  minLxySignificance_(iConfig.getParameter<double>("MinLxySignificance")),
45  minCosinePointingAngle_(iConfig.getParameter<double>("MinCosinePointingAngle")),
46  minD0Significance_(iConfig.getParameter<double>("MinD0Significance")),
47  fastAccept_(iConfig.getParameter<bool>("FastAccept")),
48  beamSpotTag_ (iConfig.getParameter<edm::InputTag> ("BeamSpotTag"))
49 {
50  muCandLabel_ = iConfig.getParameter<edm::InputTag>("MuCand");
51  trkCandLabel_ = iConfig.getParameter<edm::InputTag>("TrackCand");
52 
53  produces<VertexCollection>();
54  produces<CandidateCollection>();
55 }
56 
57 
58 // ----------------------------------------------------------------------
60 
61 }
62 
63 
64 // ----------------------------------------------------------------------
66 
67 }
68 
69 
70 // ----------------------------------------------------------------------
72 
73 }
74 
75 
76 // ----------------------------------------------------------------------
78 
79  const double MuMass(0.106);
80  const double MuMass2(MuMass*MuMass);
81 
82  const double thirdTrackMass2(thirdTrackMass_*thirdTrackMass_);
83  const double fourthTrackMass2(fourthTrackMass_*fourthTrackMass_);
84 
85  auto_ptr<CandidateCollection> output(new CandidateCollection());
86  auto_ptr<VertexCollection> vertexCollection(new VertexCollection());
87 
88  //get the transient track builder:
90  iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder",theB);
91 
92  //get the beamspot position
93  edm::Handle<reco::BeamSpot> recoBeamSpotHandle;
94  iEvent.getByLabel(beamSpotTag_,recoBeamSpotHandle);
95  const reco::BeamSpot& vertexBeamSpot = *recoBeamSpotHandle;
96 
97  ESHandle<MagneticField> bFieldHandle;
98  iSetup.get<IdealMagneticFieldRecord>().get(bFieldHandle);
99 
100  const MagneticField* magField = bFieldHandle.product();
101 
102  TSCBLBuilderNoMaterial blsBuilder;
103 
104  // Ref to Candidate object to be recorded in filter object
107  RecoChargedCandidateRef refTrk;
108  RecoChargedCandidateRef refTrk2;
109 
110  // get hold of muon trks
112  iEvent.getByLabel (muCandLabel_,mucands);
113 
114  // get track candidates around displaced muons
116  iEvent.getByLabel (trkCandLabel_,trkcands);
117 
118  if (saveTags()) {
119  filterproduct.addCollectionTag(muCandLabel_);
120  filterproduct.addCollectionTag(trkCandLabel_);
121  }
122 
123  double e1,e2,e3,e4;
125 
126  //TrackRefs to mu cands in trkcand
127  vector<TrackRef> trkMuCands;
128 
129  //Already used mu tracks to avoid double counting candidates
130  vector<bool> isUsedCand(trkcands->size(),false);
131 
132  int counter = 0;
133 
134  //run algorithm
135  for (RecoChargedCandidateCollection::const_iterator mucand1=mucands->begin(), endCand1=mucands->end(); mucand1!=endCand1; ++mucand1) {
136 
137  if ( mucands->size()<2) break;
138  if ( trkcands->size()<2) break;
139 
140  TrackRef trk1 = mucand1->get<TrackRef>();
141  LogDebug("HLTDisplacedMumukkFilter") << " 1st muon: q*pt= " << trk1->charge()*trk1->pt() << ", eta= " << trk1->eta() << ", hits= " << trk1->numberOfValidHits();
142 
143  // eta cut
144  if (fabs(trk1->eta()) > maxEta_) continue;
145 
146  // Pt threshold cut
147  if (trk1->pt() < minPt_) continue;
148 
149  RecoChargedCandidateCollection::const_iterator mucand2 = mucand1; ++mucand2;
150 
151  for (RecoChargedCandidateCollection::const_iterator endCand2=mucands->end(); mucand2!=endCand2; ++mucand2) {
152 
153  TrackRef trk2 = mucand2->get<TrackRef>();
154 
155  LogDebug("HLTDisplacedMumukkFilter") << " 2nd muon: q*pt= " << trk2->charge()*trk2->pt() << ", eta= " << trk2->eta() << ", hits= " << trk2->numberOfValidHits();
156 
157  // eta cut
158  if (fabs(trk2->eta()) > maxEta_) continue;
159 
160  // Pt threshold cut
161  if (trk2->pt() < minPt_) continue;
162 
163  RecoChargedCandidateCollection::const_iterator trkcand, endCandTrk;
164 
165  std::vector<bool>::iterator isUsedIter, endIsUsedCand;
166 
167  //get overlapping muon candidates
168  for ( trkcand = trkcands->begin(), endCandTrk=trkcands->end(), isUsedIter = isUsedCand.begin(), endIsUsedCand = isUsedCand.end(); trkcand != endCandTrk && isUsedIter != endIsUsedCand; ++trkcand, ++isUsedIter) {
169  TrackRef trk3 = trkcand->get<TrackRef>();
170 
171  //check for overlapping muon tracks and save TrackRefs
172  if (overlap(*mucand1,*trkcand)) {
173  trkMuCands.push_back(trk3);
174  *isUsedIter = true;
175  continue;
176  }
177  else if (overlap(*mucand2,*trkcand)){
178  trkMuCands.push_back(trk3);
179  *isUsedIter = true;
180  continue;
181  }
182 
183  if(trkMuCands.size()==2) break;
184  }
185 
186  //Not all overlapping candidates found, skip event
187  //if (trkMuCands.size()!=2) continue;
188 
189  //combine muons with all tracks
190  for ( trkcand = trkcands->begin(), endCandTrk=trkcands->end(), isUsedIter = isUsedCand.begin(), endIsUsedCand = isUsedCand.end(); trkcand != endCandTrk && isUsedIter != endIsUsedCand; ++trkcand, ++isUsedIter) {
191 
192  TrackRef trk3 = trkcand->get<TrackRef>();
193 
194  LogDebug("HLTDisplacedMumukkFilter") << " 3rd track: q*pt= " << trk3->charge()*trk3->pt() << ", eta= " << trk3->eta() << ", hits= " << trk3->numberOfValidHits();
195 
196  //skip overlapping muon candidates
197  bool skip=false;
198  for (unsigned int itmc=0;itmc<trkMuCands.size();itmc++) if(trk3==trkMuCands.at(itmc)) skip=true;
199  if(skip) continue;
200 
201  //skip already used tracks
202  if(*isUsedIter) continue;
203 
204  // eta cut
205  if (fabs(trk3->eta()) > maxEta_) continue;
206 
207  // Pt threshold cut
208  if (trk3->pt() < minPt_) continue;
209 
210  RecoChargedCandidateCollection::const_iterator trkcand2;
211 
212  std::vector<bool>::iterator isUsedIter2;
213 
214  for ( trkcand2 = trkcands->begin(), isUsedIter2 = isUsedCand.begin() ; trkcand2 != endCandTrk && isUsedIter2 != endIsUsedCand; ++trkcand2,++isUsedIter2) {
215 
216  if (trkcand2==trkcand) continue;
217 
218  TrackRef trk4 = trkcand2->get<TrackRef>();
219 
220  LogDebug("HLTDisplacedMumukkFilter") << " 4th track: q*pt= " << trk4->charge()*trk4->pt() << ", eta= " << trk4->eta() << ", hits= " << trk4->numberOfValidHits();
221 
222  //skip overlapping muon candidates
223  bool skip2=false;
224  for (unsigned int itmc=0;itmc<trkMuCands.size();itmc++) if(trk4==trkMuCands.at(itmc)) skip2=true;
225  if(skip2) continue;
226 
227  //skip already used tracks
228  if(*isUsedIter2) continue;
229 
230  // eta cut
231  if (fabs(trk4->eta()) > maxEta_) continue;
232 
233  // Pt threshold cut
234  if (trk4->pt() < minPt_) continue;
235 
236  // Combined system
237  e1 = sqrt(trk1->momentum().Mag2()+MuMass2);
238  e2 = sqrt(trk2->momentum().Mag2()+MuMass2);
239  e3 = sqrt(trk3->momentum().Mag2()+thirdTrackMass2);
240  e4 = sqrt(trk4->momentum().Mag2()+fourthTrackMass2);
241 
242  p1 = Particle::LorentzVector(trk1->px(),trk1->py(),trk1->pz(),e1);
243  p2 = Particle::LorentzVector(trk2->px(),trk2->py(),trk2->pz(),e2);
244  p3 = Particle::LorentzVector(trk3->px(),trk3->py(),trk3->pz(),e3);
245  p4 = Particle::LorentzVector(trk4->px(),trk4->py(),trk4->pz(),e4);
246 
247  p = p1+p2+p3+p4;
248 
249  //invariant mass cut
250  double invmass = abs(p.mass());
251 
252  LogDebug("HLTDisplacedMumukkFilter") << " Invmass= " << invmass;
253 
254  FreeTrajectoryState InitialFTS = initialFreeState(*trk3, magField);
255  TrajectoryStateClosestToBeamLine tscb( blsBuilder(InitialFTS, *recoBeamSpotHandle) );
256  double d0sig = tscb.transverseImpactParameter().significance();
257 
258  if (d0sig < minD0Significance_) continue;
259 
260  FreeTrajectoryState InitialFTS2 = initialFreeState(*trk4, magField);
261  TrajectoryStateClosestToBeamLine tscb2( blsBuilder(InitialFTS2, *recoBeamSpotHandle) );
263 
264  if (d0sig < minD0Significance_) continue;
265 
266  if (invmass>maxInvMass_ || invmass<minInvMass_) continue;
267 
268  // do the vertex fit
269  vector<TransientTrack> t_tks;
270  t_tks.push_back((*theB).build(&trk1));
271  t_tks.push_back((*theB).build(&trk2));
272  t_tks.push_back((*theB).build(&trk3));
273  t_tks.push_back((*theB).build(&trk4));
274 
275  if (t_tks.size()!=4) continue;
276 
277  KalmanVertexFitter kvf;
278  TransientVertex tv = kvf.vertex(t_tks);
279 
280  if (!tv.isValid()) continue;
281 
282  Vertex vertex = tv;
283 
284  // get vertex position and error to calculate the decay length significance
285  GlobalPoint secondaryVertex = tv.position();
286  GlobalError err = tv.positionError();
287 
288  //calculate decay length significance w.r.t. the beamspot
289  GlobalPoint displacementFromBeamspot( -1*((vertexBeamSpot.x0() -secondaryVertex.x()) + (secondaryVertex.z() - vertexBeamSpot.z0()) * vertexBeamSpot.dxdz()), -1*((vertexBeamSpot.y0() - secondaryVertex.y())+ (secondaryVertex.z() -vertexBeamSpot.z0()) * vertexBeamSpot.dydz()), 0);
290 
291  float lxy = displacementFromBeamspot.perp();
292  float lxyerr = sqrt(err.rerr(displacementFromBeamspot));
293 
294  // get normalizes chi2
295  float normChi2 = tv.normalisedChiSquared();
296 
297  //calculate the angle between the decay length and the mumu momentum
298  Vertex::Point vperp(displacementFromBeamspot.x(),displacementFromBeamspot.y(),0.);
299  math::XYZVector pperp(p.x(),p.y(),0.);
300 
301  float cosAlpha = vperp.Dot(pperp)/(vperp.R()*pperp.R());
302 
303  LogDebug("HLTDisplacedMumukkFilter") << " vertex fit normalised chi2: " << normChi2 << ", Lxy significance: " << lxy/lxyerr << ", cosine pointing angle: " << cosAlpha;
304 
305  // put vertex in the event
306  vertexCollection->push_back(vertex);
307 
308  if (normChi2 > maxNormalisedChi2_) continue;
309  if (lxy/lxyerr < minLxySignificance_) continue;
310  if(cosAlpha < minCosinePointingAngle_) continue;
311 
312  LogDebug("HLTDisplacedMumukkFilter") << " Event passed!";
313 
314  //Add event
315  ++counter;
316 
317  //Get refs
318  bool i1done = false;
319  bool i2done = false;
320  bool i3done = false;
321  bool i4done = false;
322  vector<RecoChargedCandidateRef> vref;
323  filterproduct.getObjects(TriggerMuon,vref);
324  for (unsigned int i=0; i<vref.size(); i++) {
326  TrackRef trktmp = candref->get<TrackRef>();
327  if (trktmp==trk1) {
328  i1done = true;
329  } else if (trktmp==trk2) {
330  i2done = true;
331  } else if (trktmp==trk3) {
332  i3done = true;
333  } else if (trktmp==trk4) {
334  i4done = true;
335  }
336  if (i1done && i2done && i3done && i4done) break;
337  }
338 
339  if (!i1done) {
340  refMu1=RecoChargedCandidateRef( Ref<RecoChargedCandidateCollection> (mucands,distance(mucands->begin(), mucand1)));
341  filterproduct.addObject(TriggerMuon,refMu1);
342  }
343  if (!i2done) {
344  refMu2=RecoChargedCandidateRef( Ref<RecoChargedCandidateCollection> (mucands,distance(mucands->begin(),mucand2)));
345  filterproduct.addObject(TriggerMuon,refMu2);
346  }
347  if (!i3done) {
348  refTrk=RecoChargedCandidateRef( Ref<RecoChargedCandidateCollection> (trkcands,distance(trkcands->begin(),trkcand)));
349  filterproduct.addObject(TriggerTrack,refTrk);
350  }
351  if (!i4done) {
352  refTrk2=RecoChargedCandidateRef( Ref<RecoChargedCandidateCollection> (trkcands,distance(trkcands->begin(),trkcand)));
353  filterproduct.addObject(TriggerTrack,refTrk2);
354  }
355 
356  if (fastAccept_) break;
357  }
358  }
359 
360  trkMuCands.clear();
361  }
362  }
363 
364  // filter decision
365  const bool accept (counter >= 1);
366 
367  LogDebug("HLTDisplacedMumukkFilter") << " >>>>> Result of HLTDisplacedMumukkFilter is "<< accept << ", number of muon pairs passing thresholds= " << counter;
368 
369  iEvent.put(vertexCollection);
370 
371  return accept;
372 }
373 
374 // ----------------------------------------------------------------------
376  const MagneticField* field)
377 {
379  GlobalPoint gpos( pos);
380  Basic3DVector<float> mom( tk.momentum());
381  GlobalVector gmom( mom);
382  GlobalTrajectoryParameters par( gpos, gmom, tk.charge(), field);
384  return FreeTrajectoryState( par, err);
385 }
386 
388 
389  double eps(1.44e-4);
390 
391  double dpt = a.pt() - b.pt();
392  dpt *= dpt;
393 
394  double dphi = deltaPhi(a.phi(), b.phi());
395  dphi *= dphi;
396 
397  double deta = a.eta() - b.eta();
398  deta *= deta;
399 
400  if ((dphi + deta) < eps) {
401  return 1;
402  }
403 
404  return 0;
405 
406 }
407 
#define LogDebug(id)
GlobalError positionError() const
T getParameter(std::string const &) const
double z0() const
z coordinate
Definition: BeamSpot.h:69
int i
Definition: DBlmapReader.cc:9
const double maxInvMass_
Definition: HLTmmkkFilter.h:57
void getObjects(Vids &ids, VRphoton &refs) const
various physics-level getters:
T perp() const
Definition: PV3DBase.h:71
const Vector & momentum() const
track momentum vector
Definition: TrackBase.h:150
const double minLxySignificance_
Definition: HLTmmkkFilter.h:59
virtual double pt() const =0
transverse momentum
virtual CachingVertex< 5 > vertex(const std::vector< reco::TransientTrack > &tracks) const
T y() const
Definition: PV3DBase.h:62
#define abs(x)
Definition: mlp_lapack.h:159
edm::Ref< RecoChargedCandidateCollection > RecoChargedCandidateRef
reference to an object in a collection of RecoChargedCandidate objects
const double maxNormalisedChi2_
Definition: HLTmmkkFilter.h:58
virtual void endJob()
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
bool accept(const edm::Event &event, const edm::TriggerResults &triggerTable, const std::string &triggerPath)
Definition: TopDQMHelpers.h:22
tuple vertexCollection
CovarianceMatrix covariance() const
return track covariance matrix
Definition: TrackBase.h:182
const double thirdTrackMass_
Definition: HLTmmkkFilter.h:52
void addObject(int id, const reco::RecoEcalCandidateRef &ref)
setters for L3 collections: (id=physics type, and Ref&lt;C&gt;)
virtual int overlap(const reco::Candidate &, const reco::Candidate &)
double dydz() const
dydz slope
Definition: BeamSpot.h:85
float normalisedChiSquared() const
int iEvent
Definition: GenABIO.cc:243
virtual void beginJob()
const bool fastAccept_
Definition: HLTmmkkFilter.h:62
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:85
virtual bool hltFilter(edm::Event &, const edm::EventSetup &, trigger::TriggerFilterObjectWithRefs &filterproduct)
T sqrt(T t)
Definition: SSEVec.h:46
double p4[4]
Definition: TauolaWrapper.h:92
GlobalPoint position() const
T z() const
Definition: PV3DBase.h:63
const double maxEta_
Definition: HLTmmkkFilter.h:54
math::XYZPoint Point
point in the space
Definition: Vertex.h:40
const double minInvMass_
Definition: HLTmmkkFilter.h:56
double p2[4]
Definition: TauolaWrapper.h:90
const double minPt_
Definition: HLTmmkkFilter.h:55
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:356
double dxdz() const
dxdz slope
Definition: BeamSpot.h:83
const Point & vertex() const
reference point on the track. This method is DEPRECATED, please use referencePoint() instead ...
Definition: TrackBase.h:156
edm::InputTag muCandLabel_
Definition: HLTmmkkFilter.h:49
double significance() const
Definition: Measurement1D.h:32
const double minD0Significance_
Definition: HLTmmkkFilter.h:61
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
T rerr(const GlobalPoint &aPoint) const
const T & get() const
Definition: EventSetup.h:55
T const * product() const
Definition: ESHandle.h:62
double b
Definition: hdecay.h:120
void addCollectionTag(const edm::InputTag &collectionTag)
collectionTags
virtual FreeTrajectoryState initialFreeState(const reco::Track &, const MagneticField *)
const double minCosinePointingAngle_
Definition: HLTmmkkFilter.h:60
double value() const
Definition: Measurement1D.h:28
const double fourthTrackMass_
Definition: HLTmmkkFilter.h:53
bool saveTags() const
Definition: HLTFilter.h:45
double p1[4]
Definition: TauolaWrapper.h:89
HLTmmkkFilter(const edm::ParameterSet &)
double a
Definition: hdecay.h:121
edm::InputTag trkCandLabel_
Definition: HLTmmkkFilter.h:50
double y0() const
y coordinate
Definition: BeamSpot.h:67
int charge() const
track electric charge
Definition: TrackBase.h:113
edm::InputTag beamSpotTag_
Definition: HLTmmkkFilter.h:63
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:242
edm::OwnVector< Candidate > CandidateCollection
collection of Candidate objects
Definition: CandidateFwd.h:21
T x() const
Definition: PV3DBase.h:61
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Particle.h:25
bool isValid() const
math::PtEtaPhiELorentzVectorF LorentzVector
virtual double phi() const =0
momentum azimuthal angle
virtual double eta() const =0
momentum pseudorapidity
double p3[4]
Definition: TauolaWrapper.h:91
double x0() const
x coordinate
Definition: BeamSpot.h:65