CMS 3D CMS Logo

MuDTMuonExtTableProducer.cc
Go to the documentation of this file.
1 
15 
20 
22 
23 #include "TString.h"
24 #include "TRegexp.h"
25 
26 #include <numeric>
27 #include <vector>
28 
30 
33 
41 
46 
48 public:
51 
54 
55 protected:
57  void fillTable(edm::Event&) final;
58 
60  void getFromES(const edm::Run&, const edm::EventSetup&) final;
61 
62 private:
66 
69 
72 
76 
79 
82 
84  std::vector<int> m_trigIndices;
85  std::vector<int> m_isoTrigIndices;
86 
87  bool hasTrigger(std::vector<int>&,
90  const reco::Muon&);
91 };
92 
95  m_muToken{config, consumesCollector(), "src"},
96  m_dtSegmentToken{config, consumesCollector(), "dtSegmentSrc"},
97  m_trigResultsToken{config, consumesCollector(), "trigResultsSrc"},
98  m_trigEventToken{config, consumesCollector(), "trigEventSrc"},
99  m_fillMatches{config.getParameter<bool>("fillMatches")},
100  m_trigName{config.getParameter<std::string>("trigName")},
101  m_isoTrigName{config.getParameter<std::string>("isoTrigName")},
102  m_dtGeometry{consumesCollector()} {
103  produces<nanoaod::FlatTable>();
104  if (m_fillMatches) {
105  produces<nanoaod::FlatTable>("matches");
106  produces<nanoaod::FlatTable>("staMatches");
107  }
108 }
109 
112 
113  desc.add<std::string>("name", "muon");
114  desc.add<edm::InputTag>("src", edm::InputTag{"patMuons"});
115  desc.add<edm::InputTag>("dtSegmentSrc", edm::InputTag{"dt4DSegments"});
116  desc.add<edm::InputTag>("trigEventSrc", edm::InputTag{"hltTriggerSummaryAOD::HLT"});
117  desc.add<edm::InputTag>("trigResultsSrc", edm::InputTag{"TriggerResults::HLT"});
118 
119  desc.add<bool>("fillMatches", true);
120 
121  desc.add<std::string>("trigName", "HLT_Mu55*");
122  desc.add<std::string>("isoTrigName", "HLT_IsoMu2*");
123 
124  descriptions.addWithDefaultLabel(desc);
125 }
126 
129 
130  bool changed{true};
131  m_hltConfig.init(run, environment, "HLT", changed);
132 
133  const bool enableWildcard{true};
134 
135  TString tName = TString(m_trigName);
136  TRegexp tNamePattern = TRegexp(tName, enableWildcard);
137 
138  for (unsigned iPath = 0; iPath < m_hltConfig.size(); ++iPath) {
139  TString pathName = TString(m_hltConfig.triggerName(iPath));
140  if (pathName.Contains(tNamePattern))
141  m_trigIndices.push_back(static_cast<int>(iPath));
142  }
143 
144  tName = TString(m_isoTrigName);
145  tNamePattern = TRegexp(tName, enableWildcard);
146 
147  for (unsigned iPath = 0; iPath < m_hltConfig.size(); ++iPath) {
148  TString pathName = TString(m_hltConfig.triggerName(iPath));
149  if (pathName.Contains(tNamePattern))
150  m_isoTrigIndices.push_back(static_cast<int>(iPath));
151  }
152 }
153 
155  unsigned int nMuons{0};
156 
157  std::vector<bool> firesIsoTrig;
158  std::vector<bool> firesTrig;
159 
160  std::vector<int> nMatches;
161  std::vector<int> staMu_nMatchSeg;
162 
163  std::vector<uint32_t> matches_begin;
164  std::vector<uint32_t> matches_end;
165 
166  std::vector<uint32_t> staMatches_begin;
167  std::vector<uint32_t> staMatches_end;
168 
169  std::vector<int8_t> matches_wheel;
170  std::vector<int8_t> matches_sector;
171  std::vector<int8_t> matches_station;
172 
173  std::vector<float> matches_x;
174  std::vector<float> matches_y;
175 
176  std::vector<float> matches_phi;
177  std::vector<float> matches_eta;
178  std::vector<float> matches_edgeX;
179  std::vector<float> matches_edgeY;
180 
181  std::vector<float> matches_dXdZ;
182  std::vector<float> matches_dYdZ;
183 
184  std::vector<uint32_t> staMatches_MuSegIdx;
185 
187  auto segments = m_dtSegmentToken.conditionalGet(ev);
188 
191 
192  if (muons.isValid() && segments.isValid()) {
193  for (const auto& muon : (*muons)) {
194  if (triggerResults.isValid() && triggerEvent.isValid()) {
195  const auto& triggerObjects = triggerEvent->getObjects();
196 
199 
200  firesIsoTrig.push_back(hasIsoTrig);
201  firesTrig.push_back(hasTrig);
202 
203  } else {
204  firesIsoTrig.push_back(false);
205  firesTrig.push_back(false);
206  }
207 
208  size_t iMatches = 0;
209  size_t iSegMatches = 0;
210 
211  if (m_fillMatches) {
212  matches_begin.push_back(matches_wheel.size());
213 
214  if (muon.isMatchesValid()) {
215  for (const auto& match : muon.matches()) {
216  if (match.id.det() == DetId::Muon && match.id.subdetId() == MuonSubdetId::DT) {
217  DTChamberId dtId(match.id.rawId());
218  const auto chamb = m_dtGeometry->chamber(static_cast<DTChamberId>(match.id));
219 
220  matches_wheel.push_back(dtId.wheel());
221  matches_sector.push_back(dtId.sector());
222  matches_station.push_back(dtId.station());
223 
224  matches_x.push_back(match.x);
225  matches_y.push_back(match.y);
226 
227  matches_phi.push_back(chamb->toGlobal(LocalPoint(match.x, match.y, 0.)).phi());
228  matches_eta.push_back(chamb->toGlobal(LocalPoint(match.x, match.y, 0.)).eta());
229 
230  matches_edgeX.push_back(match.edgeX);
231  matches_edgeY.push_back(match.edgeY);
232 
233  matches_dXdZ.push_back(match.dXdZ);
234  matches_dYdZ.push_back(match.dYdZ);
235 
236  ++iMatches;
237  }
238  }
239  }
240 
241  matches_end.push_back(matches_wheel.size());
242 
243  //SEGMENT MATCHING VARIABLES
244 
245  staMatches_begin.push_back(staMatches_MuSegIdx.size());
246 
247  if (!muon.outerTrack().isNull()) {
248  reco::TrackRef outerTrackRef = muon.outerTrack();
249 
250  auto recHitIt = outerTrackRef->recHitsBegin();
251  auto recHitEnd = outerTrackRef->recHitsEnd();
252 
253  for (; recHitIt != recHitEnd; ++recHitIt) {
254  DetId detId = (*recHitIt)->geographicalId();
255 
256  if (detId.det() == DetId::Muon && detId.subdetId() == MuonSubdetId::DT) {
257  const auto dtSegmentSta = dynamic_cast<const DTRecSegment4D*>((*recHitIt));
258  int iSeg = 0;
259 
260  for (const auto& segment : (*segments)) {
261  if (dtSegmentSta && dtSegmentSta->chamberId().station() == segment.chamberId().station() &&
262  dtSegmentSta->chamberId().wheel() == segment.chamberId().wheel() &&
263  dtSegmentSta->chamberId().sector() == segment.chamberId().sector() &&
264  std::abs(dtSegmentSta->localPosition().x() - segment.localPosition().x()) < 0.001 &&
265  std::abs(dtSegmentSta->localPosition().y() - segment.localPosition().y()) < 0.001 &&
266  std::abs(dtSegmentSta->localDirection().x() - segment.localDirection().x()) < 0.001 &&
267  std::abs(dtSegmentSta->localDirection().y() - segment.localDirection().y()) < 0.001) {
268  staMatches_MuSegIdx.push_back(iSeg);
269  ++iSegMatches;
270  }
271 
272  ++iSeg;
273  } //loop over segments
274  }
275 
276  } //loop over recHits
277  }
278 
279  staMatches_end.push_back(staMatches_MuSegIdx.size());
280  }
281 
282  nMatches.push_back(iMatches);
283  staMu_nMatchSeg.push_back(iSegMatches);
284 
285  ++nMuons;
286  }
287  }
288 
289  auto table = std::make_unique<nanoaod::FlatTable>(nMuons, m_name, false, true);
290 
292  "firesIsoTrig",
293  firesIsoTrig,
294  "True if the muon is matched to an isolated trigger"
295  "<br />specified in the ntuple config file");
296 
298  "firesTrig",
299  firesTrig,
300  "True if the muon is matched to a (non isolated)trigger"
301  "<br />specified in the ntuple config file");
302 
303  addColumn(table, "nMatches", nMatches, "Number of muon chamber matches (DT only)");
304  addColumn(table, "staMu_nMatchSeg", staMu_nMatchSeg, "Number of segments used in the standalone track (DT only)");
305 
307  "matches_begin",
308  matches_begin,
309  "begin() of range of quantities for a given muon in the *_matches_* vectors");
310  addColumn(
311  table, "matches_end", matches_end, "end() of range of quantities for a given muon in the *_matches_* vectors");
312 
314  "staMatches_begin",
315  staMatches_begin,
316  "begin() of range of quantities for a given muon in the matches_staMuSegIdx vector");
318  "staMatches_end",
319  staMatches_end,
320  "end() of range of quantities for a given muon in the matches_staMuSegIdx vector");
321 
322  ev.put(std::move(table));
323 
324  if (m_fillMatches) {
325  auto sum = [](std::vector<int> v) { return std::accumulate(v.begin(), v.end(), 0); };
326 
327  auto tabMatches = std::make_unique<nanoaod::FlatTable>(sum(nMatches), m_name + "_matches", false, false);
328 
329  tabMatches->setDoc("RECO muon matches_* vectors");
330 
331  addColumn(tabMatches, "x", matches_x, "x position of the extrapolated track on the matched DT chamber");
332  addColumn(tabMatches, "y", matches_y, "x position of the extrapolated track on the matched DT chamber");
333 
334  addColumn(tabMatches, "wheel", matches_wheel, "matched DT chamber wheel");
335  addColumn(tabMatches, "sector", matches_sector, "matched DT chamber sector");
336  addColumn(tabMatches, "station", matches_station, "matched DT chamber station");
337 
338  addColumn(
339  tabMatches, "phi", matches_phi, "phi of the (x,y) position on the matched DT chamber (global reference frame)");
340  addColumn(tabMatches,
341  "eta",
342  matches_eta,
343  " eta of the (x,y) position on the matched cDT hamber (global reference frame)");
344 
345  addColumn(tabMatches, "dXdZ", matches_dXdZ, "dXdZ of the extrapolated track on the matched DT chamber");
346  addColumn(tabMatches, "dYdZ", matches_dYdZ, "dYdZ of the extrapolated track on the matched DT chamber");
347 
348  ev.put(std::move(tabMatches), "matches");
349 
350  auto tabStaMatches =
351  std::make_unique<nanoaod::FlatTable>(sum(staMu_nMatchSeg), m_name + "_staMatches", false, false);
352 
353  tabStaMatches->setDoc("RECO muon staMatches_* vector");
354 
355  addColumn(tabStaMatches,
356  "MuSegIdx",
357  staMatches_MuSegIdx,
358  "Index of DT segments used in the standalone track it corresponds"
359  "<br />to the index of a given segment in the ntuple seg_* collection");
360 
361  ev.put(std::move(tabStaMatches), "staMatches");
362  }
363 }
364 
365 bool MuDTMuonExtTableProducer::hasTrigger(std::vector<int>& trigIndices,
368  const reco::Muon& muon) {
369  float dRMatch = 999.;
370  for (int trigIdx : trigIndices) {
371  const std::vector<std::string> trigModuleLabels = m_hltConfig.moduleLabels(trigIdx);
372 
373  const unsigned trigModuleIndex =
374  std::find(trigModuleLabels.begin(), trigModuleLabels.end(), "hltBoolEnd") - trigModuleLabels.begin() - 1;
375  const unsigned hltFilterIndex = trigEvent->filterIndex(edm::InputTag(trigModuleLabels[trigModuleIndex], "", "HLT"));
376  if (hltFilterIndex < trigEvent->sizeFilters()) {
377  const trigger::Keys keys = trigEvent->filterKeys(hltFilterIndex);
378  const trigger::Vids vids = trigEvent->filterIds(hltFilterIndex);
379  const unsigned nTriggers = vids.size();
380 
381  for (unsigned iTrig = 0; iTrig < nTriggers; ++iTrig) {
382  trigger::TriggerObject trigObj = trigObjs[keys[iTrig]];
383  float dR = deltaR(muon, trigObj);
384  if (dR < dRMatch)
385  dRMatch = dR;
386  }
387  }
388  }
389 
390  return dRMatch < 0.1; //CB should become programmable
391 }
392 
395 
const std::string & triggerName(unsigned int triggerIndex) const
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
dictionary config
Read in AllInOne config in JSON format.
Definition: DMR_cfg.py:21
Definition: config.py:1
auto conditionalGet(const edm::Event &ev) const
Definition: MuNtupleUtils.h:49
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
void addColumn(std::unique_ptr< nanoaod::FlatTable > &table, const std::string name, const std::vector< T > &vec, const std::string descr)
Single trigger physics object (e.g., an isolated muon)
Definition: TriggerObject.h:21
nano_mu::EDTokenHandle< DTRecSegment4DCollection > m_dtSegmentToken
void getFromES(const edm::Run &, const edm::EventSetup &) final
Get info from the ES by run.
MuDTMuonExtTableProducer(const edm::ParameterSet &)
Constructor.
unsigned int size() const
number of trigger paths in trigger table
nano_mu::EDTokenHandle< edm::View< reco::Muon > > m_muToken
Tokens.
const std::vector< std::string > & moduleLabels(unsigned int trigger) const
label(s) of module(s) on a trigger path
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static std::string const triggerResults
Definition: EdmProvDump.cc:47
HLTConfigProvider m_hltConfig
HLT config provider.
static void fillDescriptions(edm::ConfigurationDescriptions &)
Fill descriptors.
nano_mu::EDTokenHandle< edm::TriggerResults > m_trigResultsToken
std::vector< TriggerObject > TriggerObjectCollection
collection of trigger physics objects (e.g., all isolated muons)
Definition: TriggerObject.h:75
Definition: DetId.h:17
std::vector< size_type > Keys
bool init(const edm::Run &iRun, const edm::EventSetup &iSetup, const std::string &processName, bool &changed)
d&#39;tor
std::string m_name
The label name of the FlatTableProducer.
void getFromES(const edm::EventSetup &environment)
Get Handle from ES.
Definition: MuNtupleUtils.h:73
void fillTable(edm::Event &) final
Fill tree branches for a given events.
nano_mu::ESTokenHandle< DTGeometry, MuonGeometryRecord, edm::Transition::BeginRun > m_dtGeometry
DT Geometry.
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
bool m_fillMatches
Fill matches table.
bool hasTrigger(std::vector< int > &, const trigger::TriggerObjectCollection &, edm::Handle< trigger::TriggerEvent > &, const reco::Muon &)
nano_mu::EDTokenHandle< trigger::TriggerEvent > m_trigEventToken
static constexpr int DT
Definition: MuonSubdetId.h:11
std::vector< int > m_trigIndices
Indices of the triggers used by muon filler for trigger matching.
const DTChamber * chamber(const DTChamberId &id) const
Return a DTChamber given its id.
Definition: DTGeometry.cc:90
std::vector< int > Vids
def move(src, dest)
Definition: eostools.py:511
std::string m_trigName
Name of the triggers used by muon filler for trigger matching.
Definition: Run.h:45