CMS 3D CMS Logo

BaseTnPEfficiencyTask.cc
Go to the documentation of this file.
1 /*
2  * \file BaseTnPEfficiencyTask.cc
3  *
4  * \author L. Lunerti - INFN Bologna
5  *
6  */
7 
9 
10 // Framework
12 
13 // Geometry
15 
16 //Math
18 
19 //Root
20 #include "TRegexp.h"
21 
22 #include <tuple>
23 #include <algorithm>
24 
26  : m_nEvents(0),
27  m_muToken(consumes<reco::MuonCollection>(config.getUntrackedParameter<edm::InputTag>("inputTagMuons"))),
28  m_borderCut(config.getUntrackedParameter<double>("borderCut")),
29  m_dxCut(config.getUntrackedParameter<double>("dx_cut")),
30  m_detailedAnalysis(config.getUntrackedParameter<bool>("detailedAnalysis")),
31  m_primaryVerticesToken(
32  consumes<std::vector<reco::Vertex>>(config.getUntrackedParameter<edm::InputTag>("inputTagPrimaryVertices"))),
33  m_triggerResultsToken(
34  consumes<edm::TriggerResults>(config.getUntrackedParameter<edm::InputTag>("trigResultsTag"))),
35  m_triggerEventToken(consumes<trigger::TriggerEvent>(config.getUntrackedParameter<edm::InputTag>("trigEventTag"))),
36  m_trigName(config.getUntrackedParameter<std::string>("trigName")),
37  m_probeSelector(config.getUntrackedParameter<std::string>("probeCut")),
38  m_dxyCut(config.getUntrackedParameter<double>("probeDxyCut")),
39  m_dzCut(config.getUntrackedParameter<double>("probeDzCut")),
40  m_tagSelector(config.getUntrackedParameter<std::string>("tagCut")),
41  m_lowPairMassCut(config.getUntrackedParameter<double>("lowPairMassCut")),
42  m_highPairMassCut(config.getUntrackedParameter<double>("highPairMassCut")) {
43  LogTrace("DQMOffline|MuonDPG|BaseTnPEfficiencyTask") << "[BaseTnPEfficiencyTask]: Constructor" << std::endl;
44 }
45 
47  LogTrace("DQMOffline|MuonDPG|BaseTnPEfficiencyTask")
48  << "[BaseTnPEfficiencyTask]: analyzed " << m_nEvents << " events" << std::endl;
49 }
50 
52  bool changed = true;
53  m_hltConfig.init(run, context, "HLT", changed);
54 
55  bool enableWildCard = true;
56 
57  TString tName = TString(m_trigName);
58  TRegexp tNamePattern = TRegexp(tName, enableWildCard);
59 
60  for (unsigned iPath = 0; iPath < m_hltConfig.size(); ++iPath) {
61  TString pathName = TString(m_hltConfig.triggerName(iPath));
62  if (pathName.Contains(tNamePattern)) {
63  m_trigIndices.push_back(static_cast<int>(iPath));
64  }
65  }
66 }
67 
69  edm::Run const& run,
70  edm::EventSetup const& context) {
71  LogTrace("DQMOffline|MuonDPG|BaseTnPEfficiencyTask") << "[BaseTnPEfficiencyTask]: bookHistograms" << std::endl;
72 
73  if (m_detailedAnalysis) {
74  std::string baseDir = topFolder() + "/detailed/";
75  iBooker.setCurrentFolder(baseDir);
76 
77  LogTrace("DQMOffline|MuonDPG|BaseTnPEfficiencyTask")
78  << "[BaseTnPEfficiencyTask]: booking histos in " << baseDir << std::endl;
79 
80  m_histos["probePt"] = iBooker.book1D("probePt", "probePt;probe p_{T} [GeV];Events", 125, 0., 250.);
81  m_histos["probeEta"] = iBooker.book1D("probeEta", "probeEta;probe #eta;Events", 24, -2.4, 2.4);
82  m_histos["probePhi"] = iBooker.book1D("probePhi", "probePhi;probe #phi; Events", 36, -TMath::Pi(), TMath::Pi());
83  m_histos["probeNumberOfMatchedStations"] = iBooker.book1D(
84  "probeNumberOfMatchedStations", "probeNumberOfMatchedStations;Number of matched stations;Events", 5, 0., 5);
85  m_histos["pairMass"] = iBooker.book1D("pairMass", "pairMass", 25, 70., 120.);
86  }
87 }
88 
90  ++m_nEvents;
91 
93  if (!event.getByToken(m_muToken, muons))
94  return;
95 
97  if (!event.getByToken(m_primaryVerticesToken, vtxs))
98  return;
99  const reco::Vertex& vertex = vtxs->at(0);
100 
102  if (!event.getByToken(m_triggerResultsToken, triggerResults))
103  return;
104 
106  if (!event.getByToken(m_triggerEventToken, triggerEvent))
107  return;
108 
109  //common tnp variables
110  std::vector<unsigned> preSel_tag_indices;
111  std::vector<unsigned> tag_indices;
112  std::vector<unsigned> preSel_probe_indices;
113  std::vector<unsigned> probe_indices;
114 
115  if (muons.isValid() && vtxs.isValid()) {
116  //Is there a better way to initialize two different type variables?
117  for (auto [muon, muonColl_index] = std::tuple{std::vector<reco::Muon>::const_iterator{(*muons).begin()}, 0};
118  muon != (*muons).end();
119  ++muon, ++muonColl_index) {
120  bool trigMatch = false;
121 
122  //Getting trigger infos for tag selection
123  if (triggerResults.isValid() && triggerEvent.isValid()) {
124  const trigger::TriggerObjectCollection trigObjColl = triggerEvent->getObjects();
125  trigMatch = hasTrigger(m_trigIndices, trigObjColl, triggerEvent, *muon);
126  }
127 
128  //Probe selection
129  if (m_probeSelector(*muon) && (std::abs(muon->muonBestTrack()->dxy(vertex.position())) < m_dxyCut) &&
130  (std::abs(muon->muonBestTrack()->dz(vertex.position())) < m_dzCut)) {
131  preSel_probe_indices.push_back(muonColl_index);
132  }
133  //Tag selection
134  if (m_tagSelector(*muon) && trigMatch) {
135  preSel_tag_indices.push_back(muonColl_index);
136  }
137 
138  } //loop over muons
139  }
140 
141  //Probe selection
142  for (const auto i_tag : preSel_tag_indices) {
143  reco::Muon tag = (*muons).at(i_tag);
144  float pt_max = 0.;
145  int max_pt_idx;
146  bool pair_found = false;
147 
148  for (const auto i_probe : preSel_probe_indices) {
149  //Prevent tag and probe to be the same object
150  if (i_probe == i_tag)
151  continue;
152 
153  reco::Muon preSel_probe = (*muons).at(i_probe);
154 
155  int pair_charge_product = tag.charge() * preSel_probe.charge();
156 
157  //check if tag+probe pair is compatible with Z decay
158  if (pair_charge_product > 0)
159  continue;
160 
161  float pair_mass = (tag.polarP4() + preSel_probe.polarP4()).M();
162  m_histos.find("pairMass")->second->Fill(pair_mass);
163 
164  if (pair_mass < m_lowPairMassCut || pair_mass > m_highPairMassCut)
165  continue;
166 
167  float pair_pt = (tag.polarP4() + preSel_probe.polarP4()).Pt();
168  if (pair_pt > pt_max) {
169  pair_found = true;
170  pt_max = pair_pt;
171  max_pt_idx = i_probe;
172  }
173  }
174  if (pair_found) {
175  probe_indices.push_back(max_pt_idx);
176  tag_indices.push_back(i_tag);
177  }
178  }
179 
180  m_probeIndices.push_back(probe_indices);
181  m_tagIndices.push_back(tag_indices);
182 }
183 
184 bool BaseTnPEfficiencyTask::hasTrigger(std::vector<int>& trigIndices,
187  const reco::Muon& muon) {
188  float dR2match = 999.;
189  for (int trigIdx : trigIndices) {
190  const std::vector<std::string> trigModuleLabels = m_hltConfig.moduleLabels(trigIdx);
191 
192  const unsigned trigModuleIndex =
193  std::find(trigModuleLabels.begin(), trigModuleLabels.end(), "hltBoolEnd") - trigModuleLabels.begin() - 1;
194  const unsigned hltFilterIndex = trigEvent->filterIndex(edm::InputTag(trigModuleLabels[trigModuleIndex], "", "HLT"));
195  if (hltFilterIndex < trigEvent->sizeFilters()) {
196  const trigger::Keys keys = trigEvent->filterKeys(hltFilterIndex);
197  const trigger::Vids vids = trigEvent->filterIds(hltFilterIndex);
198  const unsigned nTriggers = vids.size();
199 
200  for (unsigned iTrig = 0; iTrig < nTriggers; ++iTrig) {
201  trigger::TriggerObject trigObj = trigObjs[keys[iTrig]];
202  float dR2 = deltaR2(muon, trigObj);
203  if (dR2 < dR2match)
204  dR2match = dR2;
205  }
206  }
207  }
208 
209  return dR2match < 0.01;
210 }
const double Pi
const std::string & triggerName(unsigned int triggerIndex) const
const std::string m_trigName
virtual std::string topFolder() const =0
Return the top folder.
~BaseTnPEfficiencyTask() override
Destructor.
bool hasTrigger(std::vector< int > &trigIndices, const trigger::TriggerObjectCollection &trigObjs, edm::Handle< trigger::TriggerEvent > &trigEvent, const reco::Muon &muon)
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
std::vector< std::vector< unsigned > > m_tagIndices
const edm::EDGetTokenT< edm::TriggerResults > m_triggerResultsToken
const edm::EDGetTokenT< reco::MuonCollection > m_muToken
Definition: config.py:1
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
const edm::EDGetTokenT< trigger::TriggerEvent > m_triggerEventToken
std::vector< Muon > MuonCollection
collection of Muon objects
Definition: MuonFwd.h:9
#define LogTrace(id)
const edm::EDGetTokenT< std::vector< reco::Vertex > > m_primaryVerticesToken
Single trigger physics object (e.g., an isolated muon)
Definition: TriggerObject.h:21
std::vector< std::vector< unsigned > > m_probeIndices
const StringCutObjectSelector< reco::Candidate, true > m_probeSelector
std::vector< int > m_trigIndices
unsigned int size() const
number of trigger paths in trigger table
const std::vector< std::string > & moduleLabels(unsigned int trigger) const
label(s) of module(s) on a trigger path
const PolarLorentzVector & polarP4() const final
four-momentum Lorentz vector
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::map< std::string, MonitorElement * > m_histos
static std::string const triggerResults
Definition: EdmProvDump.cc:47
void analyze(const edm::Event &event, const edm::EventSetup &context) override
Analyze.
const StringCutObjectSelector< reco::Muon, true > m_tagSelector
std::vector< TriggerObject > TriggerObjectCollection
collection of trigger physics objects (e.g., all isolated muons)
Definition: TriggerObject.h:75
void bookHistograms(DQMStore::IBooker &iBooker, edm::Run const &run, edm::EventSetup const &context) override
std::vector< size_type > Keys
bool init(const edm::Run &iRun, const edm::EventSetup &iSetup, const std::string &processName, bool &changed)
d&#39;tor
void dqmBeginRun(const edm::Run &run, const edm::EventSetup &context) override
BeginRun.
bool isValid() const
Definition: HandleBase.h:70
fixed size matrix
HLT enums.
HLTConfigProvider m_hltConfig
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
BaseTnPEfficiencyTask(const edm::ParameterSet &config)
Constructor.
std::vector< int > Vids
Definition: event.py:1
Definition: Run.h:45
int charge() const final
electric charge