CMS 3D CMS Logo

DisappearingMuonsSkimming.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: MuMu/DisappearingMuonsSkimming
4 // Class: DisappearingMuonsSkimming
5 //
13 //
14 // Original Author: Michael Revering
15 // Created: Mon, 18 Jun 2018 21:22:23 GMT
16 //
17 //
18 // system include files
19 #include <memory>
20 
21 #include "Math/VectorUtil.h"
22 // user include files
45 
47  : recoMuonToken_(consumes<std::vector<reco::Muon>>(iConfig.getParameter<edm::InputTag>("recoMuons"))),
48  standaloneMuonToken_(consumes<std::vector<reco::Track>>(iConfig.getParameter<edm::InputTag>("StandaloneTracks"))),
49  trackCollectionToken_(consumes<std::vector<reco::Track>>(iConfig.getParameter<edm::InputTag>("tracks"))),
50  primaryVerticesToken_(
51  consumes<std::vector<reco::Vertex>>(iConfig.getParameter<edm::InputTag>("primaryVertices"))),
52  reducedEndcapRecHitCollectionToken_(
53  consumes<EcalRecHitCollection>(iConfig.getParameter<edm::InputTag>("EERecHits"))),
54  reducedBarrelRecHitCollectionToken_(
55  consumes<EcalRecHitCollection>(iConfig.getParameter<edm::InputTag>("EBRecHits"))),
56  trigResultsToken_(consumes<edm::TriggerResults>(iConfig.getParameter<edm::InputTag>("TriggerResultsTag"))),
57  transientTrackToken_(
58  esConsumes<TransientTrackBuilder, TransientTrackRecord>(edm::ESInputTag("", "TransientTrackBuilder"))),
60  muonPathsToPass_(iConfig.getParameter<std::vector<std::string>>("muonPathsToPass")),
61  minMuPt_(iConfig.getParameter<double>("minMuPt")),
62  maxMuEta_(iConfig.getParameter<double>("maxMuEta")),
63  minTrackEta_(iConfig.getParameter<double>("minTrackEta")),
64  maxTrackEta_(iConfig.getParameter<double>("maxTrackEta")),
65  minTrackPt_(iConfig.getParameter<double>("minTrackPt")),
66  maxTransDCA_(iConfig.getParameter<double>("maxTransDCA")),
67  maxLongDCA_(iConfig.getParameter<double>("maxLongDCA")),
68  maxVtxChi_(iConfig.getParameter<double>("maxVtxChi")),
69  minInvMass_(iConfig.getParameter<double>("minInvMass")),
70  maxInvMass_(iConfig.getParameter<double>("maxInvMass")),
71  trackIsoConesize_(iConfig.getParameter<double>("trackIsoConesize")),
72  trackIsoInnerCone_(iConfig.getParameter<double>("trackIsoInnerCone")),
73  ecalIsoConesize_(iConfig.getParameter<double>("ecalIsoConesize")),
74  minEcalHitE_(iConfig.getParameter<double>("minEcalHitE")),
75  maxTrackIso_(iConfig.getParameter<double>("maxTrackIso")),
76  maxEcalIso_(iConfig.getParameter<double>("maxEcalIso")),
77  minSigInvMass_(iConfig.getParameter<double>("minSigInvMass")),
78  maxSigInvMass_(iConfig.getParameter<double>("maxSigInvMass")),
79  minStandaloneDr_(iConfig.getParameter<double>("minStandaloneDr")),
80  maxStandaloneDE_(iConfig.getParameter<double>("maxStandaloneDE")),
81  keepOffPeak_(iConfig.getParameter<bool>("keepOffPeak")),
82  keepSameSign_(iConfig.getParameter<bool>("keepSameSign")),
83  keepTotalRegion_(iConfig.getParameter<bool>("keepTotalRegion")),
84  keepPartialRegion_(iConfig.getParameter<bool>("keepPartialRegion")) {}
85 
86 //
87 // member functions
88 //
89 
90 // ------------ method called for each event ------------
92  using namespace edm;
93  using namespace std;
94  using namespace reco;
95 
96  bool totalRegion = false;
97  bool sameSign = false;
98  bool offPeak = false;
99  bool partialRegion = false;
100 
106  iEvent.getByToken(recoMuonToken_, recoMuons);
107  edm::Handle<std::vector<reco::Track>> thePATTrackHandle;
108  iEvent.getByToken(trackCollectionToken_, thePATTrackHandle);
109  // this wraps tracks with additional methods that are used in vertex-calculation
110  const TransientTrackBuilder* transientTrackBuilder = &iSetup.getData(transientTrackToken_);
111 
113  return false;
114 
115  int nMuonTrackCand = 0;
116  float MuonTrackMass = 0.;
117 
118  //Looping over the reconstructed Muons
119  for (std::vector<reco::Muon>::const_iterator iMuon = recoMuons->begin(); iMuon != recoMuons->end(); iMuon++) {
120  if (!(iMuon->isPFMuon() && iMuon->isGlobalMuon()))
121  continue;
122  if (!(iMuon->passed(reco::Muon::CutBasedIdTight)))
123  continue;
124  if (!(iMuon->passed(reco::Muon::PFIsoTight)))
125  continue;
126  if (iMuon->pt() < minMuPt_ || fabs(iMuon->eta()) > maxMuEta_)
127  continue;
128 
129  //Looping over tracks for any good muon
130  for (std::vector<reco::Track>::const_iterator iTrack = thePATTrackHandle->begin();
131  iTrack != thePATTrackHandle->end();
132  ++iTrack) {
133  if (!iTrack->quality(reco::Track::qualityByName("highPurity")))
134  continue;
135  if (fabs(iTrack->eta()) > maxTrackEta_ || fabs(iTrack->eta()) < minTrackEta_)
136  continue;
137  if (iTrack->pt() < minTrackPt_)
138  continue;
139  //Check if the track belongs to a primary vertex for isolation calculation
140  bool foundtrack = false;
141  GlobalPoint tkVtx;
142  for (unsigned int i = 0; i < vertices->size(); i++) {
144  if (!vtx->isValid()) {
145  continue;
146  }
147  for (unsigned int j = 0; j < vtx->tracksSize(); j++) {
148  double dPt = fabs(vtx->trackRefAt(j)->pt() - iTrack->pt()) / iTrack->pt();
149  //Find the vertex track that is the same as the probe
150  if (dPt < 0.001) {
151  double dR2 = deltaR2(vtx->trackRefAt(j)->eta(), vtx->trackRefAt(j)->phi(), iTrack->eta(), iTrack->phi());
152  if (dR2 < 0.001 * 0.001) {
153  foundtrack = true;
154  GlobalPoint vert(vtx->x(), vtx->y(), vtx->z());
155  tkVtx = vert;
156  break;
157  }
158  }
159  }
160  }
161  if (!foundtrack)
162  continue;
163  reco::TransientTrack tk = transientTrackBuilder->build(*iTrack);
165  double transDCA = traj.perigeeParameters().transverseImpactParameter();
166  double longDCA = traj.perigeeParameters().longitudinalImpactParameter();
167  if (fabs(longDCA) > maxLongDCA_)
168  continue;
169  if (fabs(transDCA) > maxTransDCA_)
170  continue;
171  // make a pair of TransientTracks to feed the vertexer
172  std::vector<reco::TransientTrack> tracksToVertex;
173  tracksToVertex.push_back(transientTrackBuilder->build(*iTrack));
174  tracksToVertex.push_back(transientTrackBuilder->build(iMuon->globalTrack()));
175  // try to fit these two tracks to a common vertex
177  CachingVertex<5> fittedVertex = vertexFitter.vertex(tracksToVertex);
178  double vtxChi = 0;
179  // some poor fits will simply fail to find a common vertex
180  if (fittedVertex.isValid() && fittedVertex.totalChiSquared() >= 0. && fittedVertex.degreesOfFreedom() > 0) {
181  // others we can exclude by their poor fit
182  vtxChi = fittedVertex.totalChiSquared() / fittedVertex.degreesOfFreedom();
183 
184  if (vtxChi < maxVtxChi_) {
185  // important! evaluate momentum vectors AT THE VERTEX
187  tracksToVertex[0].trajectoryStateClosestToPoint(fittedVertex.position());
189  tracksToVertex[1].trajectoryStateClosestToPoint(fittedVertex.position());
190  GlobalVector one_momentum = one_TSCP.momentum();
191  GlobalVector two_momentum = two_TSCP.momentum();
192 
193  double total_energy = sqrt(one_momentum.mag2() + 0.106 * 0.106) + sqrt(two_momentum.mag2() + 0.106 * 0.106);
194  double total_px = one_momentum.x() + two_momentum.x();
195  double total_py = one_momentum.y() + two_momentum.y();
196  double total_pz = one_momentum.z() + two_momentum.z();
197  MuonTrackMass = sqrt(pow(total_energy, 2) - pow(total_px, 2) - pow(total_py, 2) - pow(total_pz, 2));
198  } else {
199  continue;
200  }
201  } else {
202  continue;
203  }
204  if (MuonTrackMass < minInvMass_ || MuonTrackMass > maxInvMass_)
205  continue;
206 
207  double trackIso = getTrackIsolation(iEvent, vertices, iTrack);
208  //Track iso returns -1 when it fails to find the vertex containing the track (already checked in track selection, but might as well make sure)
209  if (trackIso < 0)
210  continue;
211  double ecalIso = getECALIsolation(iEvent, iSetup, transientTrackBuilder->build(*iTrack));
212  if (trackIso > maxTrackIso_ || ecalIso > maxEcalIso_)
213  continue;
214 
215  //A good tag/probe pair has been selected, now check for control or signal regions
216  if (iMuon->charge() == iTrack->charge()) {
217  sameSign = true;
218  }
219 
220  //If not same sign CR, need to check standalone muons for signal regions
221  double staMinDr2 = 1000;
222  double staMinDEoverE = -10;
223  if (!staTracks->empty()) {
224  for (reco::TrackCollection::const_iterator staTrack = staTracks->begin(); staTrack != staTracks->end();
225  ++staTrack) {
226  reco::TransientTrack track = transientTrackBuilder->build(*staTrack);
227  double dR2 = deltaR2(track.impactPointTSCP().momentum().eta(),
228  track.impactPointTSCP().momentum().phi(),
229  (*iTrack).eta(),
230  (*iTrack).phi());
231  double staDE = (std::sqrt(track.impactPointTSCP().momentum().mag2()) - (*iTrack).p()) / (*iTrack).p();
232  if (dR2 < staMinDr2) {
233  staMinDr2 = dR2;
234  }
235  //Pick the largest standalone muon within the cone
236  if (dR2 < minStandaloneDr_ * minStandaloneDr_ && staDE > staMinDEoverE) {
237  staMinDEoverE = staDE;
238  }
239  }
240  }
241  if (staMinDr2 > minStandaloneDr_ * minStandaloneDr_) {
242  if (MuonTrackMass < minSigInvMass_ || MuonTrackMass > maxSigInvMass_) {
243  offPeak = true;
244  } else {
245  totalRegion = true;
246  }
247  } else {
248  if (staMinDEoverE < maxStandaloneDE_) {
249  if (MuonTrackMass < minSigInvMass_ || MuonTrackMass > maxSigInvMass_) {
250  offPeak = true;
251  } else {
252  partialRegion = true;
253  }
254  }
255  }
256  nMuonTrackCand++;
257  }
258  }
259 
260  if (nMuonTrackCand == 0)
261  return false;
262  bool passes = false;
263  //Pass all same sign CR events
264  if (sameSign && keepSameSign_) {
265  passes = true;
266  }
267  //Pass all total disappearance events
268  else if (totalRegion && keepTotalRegion_) {
269  passes = true;
270  }
271  //Pass all partial disappearkance off-peak events
272  else if (offPeak && keepOffPeak_) {
273  passes = true;
274  }
275  //Pass partial region events that pass minimum standalone muon DE/E.
276  else if (partialRegion && keepPartialRegion_) {
277  passes = true;
278  }
279  return passes;
280 }
281 
283  edm::EDGetToken m_trigResultsToken,
284  std::vector<std::string> m_muonPathsToPass) {
285  bool passTriggers = false;
287  iEvent.getByToken(m_trigResultsToken, triggerResults);
288  const edm::TriggerNames& trigNames = iEvent.triggerNames(*triggerResults);
289  for (size_t i = 0; i < trigNames.size(); ++i) {
290  const std::string& name = trigNames.triggerName(i);
291  for (auto& pathName : m_muonPathsToPass) {
292  if ((name.find(pathName) != std::string::npos)) {
293  if (triggerResults->accept(i)) {
294  passTriggers = true;
295  break;
296  }
297  }
298  }
299  }
300  return passTriggers;
301 }
302 
305  std::vector<reco::Track>::const_iterator& iTrack) {
306  bool foundtrack = false;
307  unsigned int vtxindex = -1;
308  unsigned int trackindex = -1;
309  double Isolation = 0;
310  for (unsigned int i = 0; i < vtxHandle->size(); i++) {
311  reco::VertexRef vtx(vtxHandle, i);
312  if (!vtx->isValid()) {
313  continue;
314  }
315  for (unsigned int j = 0; j < vtx->tracksSize(); j++) {
316  double dPt = fabs(vtx->trackRefAt(j)->pt() - iTrack->pt()) / iTrack->pt();
317  //Find the vertex track that is the same as the probe
318  if (dPt < 0.001) {
319  double dR2 = deltaR2(vtx->trackRefAt(j)->eta(), vtx->trackRefAt(j)->phi(), iTrack->eta(), iTrack->phi());
320  if (dR2 < 0.001 * 0.001) {
321  vtxindex = i;
322  trackindex = j;
323  foundtrack = true;
324  break;
325  }
326  }
327  }
328  }
329 
330  if (!foundtrack) {
331  return -1;
332  }
333 
334  reco::VertexRef primaryVtx(vtxHandle, vtxindex);
335 
336  for (unsigned int i = 0; i < primaryVtx->tracksSize(); i++) {
337  if (i == trackindex)
338  continue;
339  reco::TrackBaseRef secondarytrack = primaryVtx->trackRefAt(i);
340  if (deltaR2(iTrack->eta(), iTrack->phi(), secondarytrack->eta(), secondarytrack->phi()) >
342  deltaR2(iTrack->eta(), iTrack->phi(), secondarytrack->eta(), secondarytrack->phi()) <
344  continue;
345  Isolation += secondarytrack->pt();
346  }
347 
348  return Isolation / iTrack->pt();
349 }
350 
352  const edm::EventSetup& iSetup,
353  const reco::TransientTrack track) {
355  iEvent.getByToken(reducedEndcapRecHitCollectionToken_, rechitsEE);
356 
358  iEvent.getByToken(reducedBarrelRecHitCollectionToken_, rechitsEB);
359 
360  const CaloGeometry& caloGeom = iSetup.getData(geometryToken_);
361  TrajectoryStateClosestToPoint t0 = track.impactPointTSCP();
362  double eDR = 0;
363 
364  for (EcalRecHitCollection::const_iterator hit = rechitsEE->begin(); hit != rechitsEE->end(); hit++) {
365  const DetId id = (*hit).detid();
366  const GlobalPoint hitPos = caloGeom.getSubdetectorGeometry(id)->getGeometry(id)->getPosition();
367  //Check if hit and track trajectory ar in the same endcap (transient track projects both ways)
368  if ((hitPos.eta() * t0.momentum().eta()) < 0) {
369  continue;
370  }
371  TrajectoryStateClosestToPoint traj = track.trajectoryStateClosestToPoint(hitPos);
372  math::XYZVector idPositionRoot(hitPos.x(), hitPos.y(), hitPos.z());
373  math::XYZVector trajRoot(traj.position().x(), traj.position().y(), traj.position().z());
374  if (ROOT::Math::VectorUtil::DeltaR(idPositionRoot, trajRoot) < ecalIsoConesize_ && (*hit).energy() > minEcalHitE_) {
375  eDR += (*hit).energy();
376  }
377  }
378  for (EcalRecHitCollection::const_iterator hit = rechitsEB->begin(); hit != rechitsEB->end(); hit++) {
379  const DetId id = (*hit).detid();
380  const GlobalPoint hitPos = caloGeom.getSubdetectorGeometry(id)->getGeometry(id)->getPosition();
381  if ((hitPos.eta() * t0.momentum().eta()) < 0) {
382  continue;
383  }
384  TrajectoryStateClosestToPoint traj = track.trajectoryStateClosestToPoint(hitPos);
385  math::XYZVector idPositionRoot(hitPos.x(), hitPos.y(), hitPos.z());
386  math::XYZVector trajRoot(traj.position().x(), traj.position().y(), traj.position().z());
387  if (ROOT::Math::VectorUtil::DeltaR(idPositionRoot, trajRoot) < ecalIsoConesize_ && (*hit).energy() > minEcalHitE_) {
388  eDR += (*hit).energy();
389  }
390  }
391 
392  return eDR;
393 }
394 
397 
398  desc.add<edm::InputTag>("recoMuons", edm::InputTag("muons"));
399  desc.add<edm::InputTag>("tracks", edm::InputTag("generalTracks"));
400  desc.add<edm::InputTag>("StandaloneTracks", edm::InputTag("standAloneMuons"));
401  desc.add<edm::InputTag>("primaryVertices", edm::InputTag("offlinePrimaryVertices"));
402  desc.add<edm::InputTag>("EERecHits", edm::InputTag("reducedEcalRecHitsEE"));
403  desc.add<edm::InputTag>("EBRecHits", edm::InputTag("reducedEcalRecHitsEB"));
404  desc.add<edm::InputTag>("TriggerResultsTag", edm::InputTag("TriggerResults", "", "HLT"));
405  desc.add<std::vector<std::string>>("muonPathsToPass",
406  {
407  "HLT_IsoMu24_v",
408  "HLT_IsoMu27_v",
409  });
410  desc.add<double>("minMuPt", 26);
411  desc.add<double>("maxMuEta", 2.4);
412  desc.add<double>("minTrackEta", 0);
413  desc.add<double>("maxTrackEta", 2.4);
414  desc.add<double>("minTrackPt", 20);
415  desc.add<double>("maxTransDCA", 0.005);
416  desc.add<double>("maxLongDCA", 0.05);
417  desc.add<double>("maxVtxChi", 3.0);
418  desc.add<double>("minInvMass", 50);
419  desc.add<double>("maxInvMass", 150);
420  desc.add<double>("trackIsoConesize", 0.3);
421  desc.add<double>("trackIsoInnerCone", 0.01);
422  desc.add<double>("ecalIsoConesize", 0.4);
423  desc.add<double>("minEcalHitE", 0.3);
424  desc.add<double>("maxTrackIso", 0.05);
425  desc.add<double>("maxEcalIso", 10);
426  desc.add<double>("minSigInvMass", 76);
427  desc.add<double>("maxSigInvMass", 106);
428  desc.add<double>("minStandaloneDr", 1.0);
429  desc.add<double>("maxStandaloneDE", -0.5);
430  desc.add<bool>("keepOffPeak", true);
431  desc.add<bool>("keepSameSign", true);
432  desc.add<bool>("keepTotalRegion", true);
433  desc.add<bool>("keepPartialRegion", true);
434  descriptions.addWithDefaultLabel(desc);
435 }
436 
437 // ------------ method called once each job just before starting event loop ------------
439 
440 // ------------ method called once each job just after ending the event loop ------------
442 
443 //define this as a plug-in
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
const std::vector< std::string > muonPathsToPass_
double getTrackIsolation(const edm::Event &, edm::Handle< reco::VertexCollection > vtxHandle, std::vector< reco::Track >::const_iterator &iTrack)
T z() const
Definition: PV3DBase.h:61
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const edm::EDGetTokenT< edm::TriggerResults > trigResultsToken_
T eta() const
Definition: PV3DBase.h:73
std::vector< EcalRecHit >::const_iterator const_iterator
bool passTriggers(const edm::Event &iEvent, edm::EDGetToken m_trigResultsToken, std::vector< std::string > m_muonPathsToPass)
T mag2() const
Definition: PV3DBase.h:63
const edm::EDGetTokenT< std::vector< reco::Vertex > > primaryVerticesToken_
float totalChiSquared() const
reco::TransientTrack build(const reco::Track *p) const
double pt() const
track transverse momentum
Definition: TrackBase.h:637
TrajectoryStateClosestToPoint trajectoryStateClosestToPoint(const GlobalPoint &point) const
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
int iEvent
Definition: GenABIO.cc:224
Definition: Muon.py:1
const edm::ESGetToken< TransientTrackBuilder, TransientTrackRecord > transientTrackToken_
T sqrt(T t)
Definition: SSEVec.h:19
const edm::EDGetTokenT< EcalRecHitCollection > reducedEndcapRecHitCollectionToken_
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:649
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
const_iterator begin() const
static std::string const triggerResults
Definition: EdmProvDump.cc:47
double getECALIsolation(const edm::Event &, const edm::EventSetup &, const reco::TransientTrack track)
const PerigeeTrajectoryParameters & perigeeParameters() const
bool filter(edm::Event &, const edm::EventSetup &) override
virtual std::shared_ptr< const CaloCellGeometry > getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
const_iterator end() const
static const char *const trigNames[]
Definition: EcalDumpRaw.cc:57
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:652
Definition: DetId.h:17
const edm::EDGetTokenT< std::vector< reco::Track > > trackCollectionToken_
static TrackQuality qualityByName(const std::string &name)
Definition: TrackBase.cc:126
bool isValid() const
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
const edm::ESGetToken< CaloGeometry, CaloGeometryRecord > geometryToken_
const edm::EDGetToken recoMuonToken_
const edm::EDGetToken standaloneMuonToken_
fixed size matrix
HLT enums.
float degreesOfFreedom() const
const edm::EDGetTokenT< EcalRecHitCollection > reducedBarrelRecHitCollectionToken_
GlobalPoint position() const
DisappearingMuonsSkimming(const edm::ParameterSet &)
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
Definition: CaloGeometry.cc:34
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29