CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
GEMEfficiencyAnalyzer.cc
Go to the documentation of this file.
2 
12 
14  : GEMOfflineDQMBase(pset),
15  gemToken1_(esConsumes<edm::Transition::BeginRun>()),
18  trasientTrackToken_(
19  esConsumes<TransientTrackBuilder, TransientTrackRecord>(edm::ESInputTag("", "TransientTrackBuilder"))) {
20  name_ = pset.getUntrackedParameter<std::string>("name");
21  folder_ = pset.getUntrackedParameter<std::string>("folder");
22 
23  rechit_token_ = consumes<GEMRecHitCollection>(pset.getParameter<edm::InputTag>("recHitTag"));
24  muon_token_ = consumes<edm::View<reco::Muon> >(pset.getParameter<edm::InputTag>("muonTag"));
25 
26  is_cosmics_ = pset.getUntrackedParameter<bool>("isCosmics");
27  use_global_muon_ = pset.getUntrackedParameter<bool>("useGlobalMuon");
28  use_skip_layer_ = pset.getParameter<bool>("useSkipLayer");
29  use_only_me11_ = pset.getParameter<bool>("useOnlyME11");
30  residual_rphi_cut_ = static_cast<float>(pset.getParameter<double>("residualRPhiCut"));
31  use_prop_r_error_cut_ = pset.getParameter<bool>("usePropRErrorCut");
32  prop_r_error_cut_ = pset.getParameter<double>("propRErrorCut");
33  use_prop_phi_error_cut_ = pset.getParameter<bool>("usePropPhiErrorCut");
34  prop_phi_error_cut_ = pset.getParameter<double>("propPhiErrorCut");
35  pt_bins_ = pset.getUntrackedParameter<std::vector<double> >("ptBins");
36  eta_nbins_ = pset.getUntrackedParameter<int>("etaNbins");
37  eta_low_ = pset.getUntrackedParameter<double>("etaLow");
38  eta_up_ = pset.getUntrackedParameter<double>("etaUp");
39 
40  const edm::ParameterSet&& muon_service_parameter = pset.getParameter<edm::ParameterSet>("ServiceParameters");
41  muon_service_ = new MuonServiceProxy(muon_service_parameter, consumesCollector());
42 
44  pt_clamp_max_ = pt_bins_.back() - eps;
45  eta_clamp_max_ = eta_up_ - eps;
46 
47  // TODO pt, eta, quality check for muons
48 }
49 
51 
53  // beam scenario
54  {
56  desc.addUntracked<std::string>("name", "GlobalMuon");
57  desc.addUntracked<std::string>("folder", "GEM/Efficiency/type0");
58  desc.add<edm::InputTag>("recHitTag", edm::InputTag("gemRecHits"));
59  desc.add<edm::InputTag>("muonTag", edm::InputTag("muons"));
60  desc.addUntracked<bool>("isCosmics", false);
61  desc.addUntracked<bool>("useGlobalMuon", true);
62  desc.add<bool>("useSkipLayer", true);
63  desc.add<bool>("useOnlyME11", false);
64  desc.add<double>("residualRPhiCut", 2.0); // TODO need to be tuned
65  desc.add<bool>("usePropRErrorCut", false);
66  desc.add<double>("propRErrorCut", 1.0);
67  desc.add<bool>("usePropPhiErrorCut", false);
68  desc.add<double>("propPhiErrorCut", 0.01);
69  desc.addUntracked<std::vector<double> >("ptBins", {20., 30., 40., 50., 60., 70., 80., 90., 100., 120.});
70  desc.addUntracked<int>("etaNbins", 9);
71  desc.addUntracked<double>("etaLow", 1.4);
72  desc.addUntracked<double>("etaUp", 2.3);
73  {
75  psd0.setAllowAnything();
76  desc.add<edm::ParameterSetDescription>("ServiceParameters", psd0);
77  }
78  descriptions.add("gemEfficiencyAnalyzerDefault", desc);
79  } // beam scenario
80 
81  // cosmic scenario
82  {
84  desc.addUntracked<std::string>("name", "GlobalMuon"); // FIXME
85  desc.addUntracked<std::string>("folder", "GEM/Efficiency/type0");
86  desc.add<edm::InputTag>("recHitTag", edm::InputTag("gemRecHits"));
87  desc.add<edm::InputTag>("muonTag", edm::InputTag("muons"));
88  desc.addUntracked<bool>("isCosmics", true);
89  desc.addUntracked<bool>("useGlobalMuon", false);
90  desc.add<bool>("useSkipLayer", true);
91  desc.add<bool>("useOnlyME11", true);
92  desc.add<double>("residualRPhiCut", 5.0); // TODO need to be tuned
93  desc.add<bool>("usePropRErrorCut", true);
94  desc.add<double>("propRErrorCut", 1.0);
95  desc.add<bool>("usePropPhiErrorCut", true);
96  desc.add<double>("propPhiErrorCut", 0.001);
97  desc.addUntracked<std::vector<double> >("ptBins", {0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100., 120.});
98  desc.addUntracked<int>("etaNbins", 9);
99  desc.addUntracked<double>("etaLow", 1.4);
100  desc.addUntracked<double>("etaUp", 2.3);
101  {
103  psd0.setAllowAnything();
104  desc.add<edm::ParameterSetDescription>("ServiceParameters", psd0);
105  }
106  descriptions.add("gemEfficiencyAnalyzerCosmicsDefault", desc);
107  } // cosmics
108 }
109 
111  edm::Run const& run,
112  edm::EventSetup const& isetup) {
114  gem = isetup.getHandle(gemToken1_);
115 
116  if (not gem.isValid()) {
117  edm::LogError(kLogCategory_) << "GEMGeometry is invalid" << std::endl;
118  return;
119  }
120 
121  bookEfficiencyMomentum(ibooker, gem);
122  bookEfficiencyChamber(ibooker, gem);
123  bookEfficiencyEtaPartition(ibooker, gem);
124  bookEfficiencyDetector(ibooker, gem);
125  bookResolution(ibooker, gem);
126  bookMisc(ibooker, gem);
127 }
128 
130  const std::string name = me->getName() + "_matched";
131  TH1F* hist = dynamic_cast<TH1F*>(me->getTH1F()->Clone(name.c_str()));
132  return ibooker.book1D(name, hist);
133 }
134 
136  const std::string name = me->getName() + "_matched";
137  TH2F* hist = dynamic_cast<TH2F*>(me->getTH2F()->Clone(name.c_str()));
138  return ibooker.book2D(name, hist);
139 }
140 
142  // TODO Efficiency/Source
143  ibooker.setCurrentFolder(folder_ + "/Efficiency");
144 
145  const TString pt_x_title = "Muon p_{T} [GeV]";
146  const int pt_nbinsx = pt_bins_.size() - 1;
147 
148  const std::string eta_x_title = "Muon |#eta|";
149  const std::string phi_x_title = "Muon #phi [rad]";
150 
151  for (const GEMStation* station : gem->stations()) {
152  const int region_id = station->region();
153  const int station_id = station->station();
154 
155  const GEMDetId&& key = getReStKey(region_id, station_id);
156  const TString&& name_suffix = GEMUtils::getSuffixName(region_id, station_id);
157  const TString&& title_suffix = GEMUtils::getSuffixTitle(region_id, station_id);
158 
159  const TString&& title = name_.c_str() + title_suffix;
160 
161  TH1F* h_muon_pt = new TH1F("muon_pt" + name_suffix, title, pt_nbinsx, &pt_bins_[0]);
162  h_muon_pt->SetXTitle(pt_x_title);
163  me_muon_pt_[key] = ibooker.book1D(h_muon_pt->GetName(), h_muon_pt);
165 
166  me_muon_eta_[key] = ibooker.book1D("muon_eta" + name_suffix, title, eta_nbins_, eta_low_, eta_up_);
167  me_muon_eta_[key]->setXTitle(eta_x_title);
169 
170  me_muon_phi_[key] = ibooker.book1D("muon_phi" + name_suffix, title, 36, -M_PI, M_PI);
171  me_muon_phi_[key]->setAxisTitle(phi_x_title);
173  } // station
174 }
175 
177  // TODO Efficiency/Source
178  ibooker.setCurrentFolder(folder_ + "/Efficiency");
179 
180  for (const GEMStation* station : gem->stations()) {
181  const int region_id = station->region();
182  const int station_id = station->station();
183 
184  const std::vector<const GEMSuperChamber*>&& superchambers = station->superChambers();
185  if (not checkRefs(superchambers)) {
186  edm::LogError(kLogCategory_) << "failed to get a valid vector of GEMSuperChamber ptrs" << std::endl;
187  return;
188  }
189 
190  const int num_chambers = superchambers.size();
191  for (const GEMChamber* chamber : superchambers[0]->chambers()) {
192  const int layer_id = chamber->id().layer();
193 
194  const TString&& name_suffix = GEMUtils::getSuffixName(region_id, station_id, layer_id);
195  const TString&& title_suffix = GEMUtils::getSuffixTitle(region_id, station_id, layer_id);
196  const GEMDetId&& key = getReStLaKey(chamber->id());
197 
198  me_chamber_[key] =
199  ibooker.book1D("chamber" + name_suffix, name_.c_str() + title_suffix, num_chambers, 0.5, num_chambers + 0.5);
200  me_chamber_[key]->setAxisTitle("Chamber");
201  me_chamber_[key]->getTH1F()->SetNdivisions(-num_chambers, "Y");
202  for (int binx = 1; binx <= num_chambers; binx++) {
203  me_chamber_[key]->setBinLabel(binx, std::to_string(binx));
204  }
205 
206  me_chamber_matched_[key] = bookNumerator1D(ibooker, me_chamber_[key]);
207  } // layer
208  } // station
209 }
210 
212  const edm::ESHandle<GEMGeometry>& gem) {
213  // TODO Efficiency/Source
214  ibooker.setCurrentFolder(folder_ + "/Efficiency");
215 
216  for (const GEMStation* station : gem->stations()) {
217  const int region_id = station->region();
218  const int station_id = station->station();
219 
220  const std::vector<const GEMSuperChamber*>&& superchambers = station->superChambers();
221  if (not checkRefs(superchambers)) {
222  edm::LogError(kLogCategory_) << "failed to get a valid vector of GEMSuperChamber ptrs" << std::endl;
223  return;
224  }
225 
226  for (const GEMChamber* chamber : superchambers[0]->chambers()) {
227  const int layer_id = chamber->id().layer();
228  const int num_ieta = chamber->nEtaPartitions();
229 
230  const TString&& name_suffix = GEMUtils::getSuffixName(region_id, station_id, layer_id);
231  const TString&& title_suffix = GEMUtils::getSuffixTitle(region_id, station_id, layer_id);
232  const GEMDetId&& key = getReStLaKey(chamber->id());
233 
234  me_ieta_[key] = ibooker.book1D("ieta" + name_suffix, name_.c_str() + title_suffix, num_ieta, 0.5, num_ieta + 0.5);
235  me_ieta_[key]->setAxisTitle("i#eta");
236  me_ieta_[key]->getTH1F()->SetNdivisions(-num_ieta, "Y");
237  for (int binx = 1; binx <= num_ieta; binx++) {
238  me_ieta_[key]->setBinLabel(binx, std::to_string(binx));
239  }
240 
241  me_ieta_matched_[key] = bookNumerator1D(ibooker, me_ieta_[key]);
242  } // layer
243  } // station
244 }
245 
247  // TODO Efficiency/Source
248  ibooker.setCurrentFolder(folder_ + "/Efficiency");
249 
250  for (const GEMStation* station : gem->stations()) {
251  const int region_id = station->region();
252  const int station_id = station->station();
253 
254  const std::vector<const GEMSuperChamber*>&& superchambers = station->superChambers();
255  if (not checkRefs(superchambers)) {
256  edm::LogError(kLogCategory_) << "failed to get a valid vector of GEMSuperChamber ptrs" << std::endl;
257  return;
258  }
259 
260  const int num_ch = superchambers.size();
261 
262  for (const GEMChamber* chamber : superchambers[0]->chambers()) {
263  const int layer_id = chamber->id().layer();
264  const int num_ieta = chamber->nEtaPartitions();
265 
266  const TString&& name_suffix = GEMUtils::getSuffixName(region_id, station_id, layer_id);
267  const TString&& title_suffix = GEMUtils::getSuffixTitle(region_id, station_id, layer_id);
268  const GEMDetId&& key = getReStLaKey(chamber->id());
269 
270  me_detector_[key] = ibooker.book2D("detector" + name_suffix,
271  name_.c_str() + title_suffix,
272  num_ch,
273  0.5,
274  num_ch + 0.5,
275  num_ieta,
276  0.5,
277  num_ieta + 0.5);
278  setDetLabelsEta(me_detector_[key], station);
279 
280  me_detector_matched_[key] = bookNumerator2D(ibooker, me_detector_[key]);
281  } // layer
282  } // station
283 }
284 
286  ibooker.setCurrentFolder(folder_ + "/Resolution");
287  for (const GEMStation* station : gem->stations()) {
288  const int region_id = station->region();
289  const int station_id = station->station();
290 
291  const std::vector<const GEMSuperChamber*>&& superchambers = station->superChambers();
292  if (not checkRefs(superchambers)) {
293  edm::LogError(kLogCategory_) << "failed to get a valid vector of GEMSuperChamber ptrs" << std::endl;
294  return;
295  }
296 
297  const std::vector<const GEMChamber*>& chambers = superchambers[0]->chambers();
298  if (not checkRefs(chambers)) {
299  edm::LogError(kLogCategory_) << "failed to get a valid vector of GEMChamber ptrs" << std::endl;
300  return;
301  }
302 
303  for (const GEMEtaPartition* eta_partition : chambers[0]->etaPartitions()) {
304  const int ieta = eta_partition->id().roll();
305 
306  const GEMDetId&& key = getReStEtKey(eta_partition->id());
307  // TODO
308  const TString&& name_suffix = TString::Format("_GE%+.2d_R%d", region_id * (station_id * 10 + 1), ieta);
309  const TString&& title =
310  name_.c_str() + TString::Format(" : GE%+.2d Roll %d", region_id * (station_id * 10 + 1), ieta);
311 
313  ibooker.book1D("residual_rphi" + name_suffix, title, 50, -residual_rphi_cut_, residual_rphi_cut_);
314  me_residual_rphi_[key]->setAxisTitle("Residual in R#phi [cm]");
315 
316  me_residual_y_[key] = ibooker.book1D("residual_y" + name_suffix, title, 60, -12.0, 12.0);
317  me_residual_y_[key]->setAxisTitle("Residual in Local Y [cm]");
318 
319  me_pull_y_[key] = ibooker.book1D("pull_y" + name_suffix, title, 60, -3.0, 3.0);
320  me_pull_y_[key]->setAxisTitle("Pull in Local Y");
321  } // ieta
322  } // station
323 }
324 
326  ibooker.setCurrentFolder(folder_ + "/Misc");
327  // FIXME the range shoule be dependent on the scenario
328  me_prop_r_err_ = ibooker.book1D("prop_r_err", ";Propagation Global R Error [cm];Entries", 20, 0.0, 20.0);
329  me_prop_phi_err_ = ibooker.book1D("prop_phi_err", "Propagation Global Phi Error [rad];Entries", 20, 0.0, M_PI);
330  me_all_abs_residual_rphi_ = ibooker.book1D("all_abs_residual_rphi", ";Residual in R#phi [cm];Entries", 20, 0.0, 20.0);
331 
332  for (const GEMStation* station : gem->stations()) {
333  const int region_id = station->region();
334  const int station_id = station->station();
335 
336  const std::vector<const GEMSuperChamber*>&& superchambers = station->superChambers();
337  if (not checkRefs(superchambers)) {
338  edm::LogError(kLogCategory_) << "failed to get a valid vector of GEMSuperChamber ptrs" << std::endl;
339  return;
340  }
341  // ignore layer ids
342  const int num_ch = superchambers.size();
343 
344  const GEMDetId&& key = getReStKey(region_id, station_id);
345  const TString&& name_suffix = GEMUtils::getSuffixName(region_id, station_id);
346  const TString&& title_suffix = GEMUtils::getSuffixTitle(region_id, station_id);
347  me_prop_chamber_[key] = ibooker.book1D("prop_chamber" + name_suffix, title_suffix, num_ch, 0.5, num_ch + 0.5);
348  me_prop_chamber_[key]->setAxisTitle("Destination Chamber Id", 1);
349  me_prop_chamber_[key]->setAxisTitle("Entries", 2);
350  } // station
351 }
352 
354  edm::Handle<GEMRecHitCollection> rechit_collection;
355  event.getByToken(rechit_token_, rechit_collection);
356  if (not rechit_collection.isValid()) {
357  edm::LogError(kLogCategory_) << "GEMRecHitCollection is invalid" << std::endl;
358  return;
359  }
360 
362  event.getByToken(muon_token_, muon_view);
363  if (not muon_view.isValid()) {
364  edm::LogError(kLogCategory_) << "View<Muon> is invalid" << std::endl;
365  return;
366  }
367 
369  gem = setup.getHandle(gemToken2_);
370 
371  if (not gem.isValid()) {
372  edm::LogError(kLogCategory_) << "GEMGeometry is invalid" << std::endl;
373  return;
374  }
375 
376  edm::ESHandle<GlobalTrackingGeometry> global_tracking_geometry;
377 
378  global_tracking_geometry = setup.getHandle(globalGeomToken_);
379 
380  if (not global_tracking_geometry.isValid()) {
381  edm::LogError(kLogCategory_) << "GlobalTrackingGeometry is invalid" << std::endl;
382  return;
383  }
384 
385  edm::ESHandle<TransientTrackBuilder> transient_track_builder;
386  transient_track_builder = setup.getHandle(trasientTrackToken_);
387 
388  if (not transient_track_builder.isValid()) {
389  edm::LogError(kLogCategory_) << "TransientTrackRecord is invalid" << std::endl;
390  return;
391  }
392 
393  muon_service_->update(setup);
394  edm::ESHandle<Propagator>&& propagator = muon_service_->propagator("SteppingHelixPropagatorAny");
395  if (not propagator.isValid()) {
396  edm::LogError(kLogCategory_) << "Propagator is invalid" << std::endl;
397  return;
398  }
399 
400  if (rechit_collection->size() < 1) {
401  edm::LogInfo(kLogCategory_) << "empty rechit collection" << std::endl;
402  return;
403  }
404 
405  if (muon_view->empty()) {
406  edm::LogInfo(kLogCategory_) << "empty muon collection" << std::endl;
407  return;
408  }
409 
410  const std::vector<GEMLayerData>&& layer_vector = buildGEMLayers(gem);
411 
412  for (const reco::Muon& muon : *muon_view) {
413  const reco::Track* track = getTrack(muon);
414  if (track == nullptr) {
415  edm::LogError(kLogCategory_) << "failed to get a muon track" << std::endl;
416  continue;
417  }
418 
419  const reco::TransientTrack&& transient_track = transient_track_builder->build(track);
420  if (not transient_track.isValid()) {
421  edm::LogError(kLogCategory_) << "failed to build TransientTrack" << std::endl;
422  continue;
423  }
424 
425  for (const GEMLayerData& layer : layer_vector) {
426  if (use_skip_layer_ and skipLayer(track, layer)) {
427  edm::LogInfo(kLogCategory_) << "skip GEM Layer" << std::endl;
428  continue;
429  }
430 
431  const auto&& [start_state, start_id] = getStartingState(transient_track, layer, global_tracking_geometry);
432 
433  if (not start_state.isValid()) {
434  edm::LogInfo(kLogCategory_) << "failed to get a starting state" << std::endl;
435  continue;
436  }
437 
438  if (use_only_me11_ and (not isME11(start_id))) {
439  edm::LogInfo(kLogCategory_) << "skip a starting state because it is not ME11" << std::endl;
440  continue;
441  }
442 
443  // the trajectory state on the destination surface
444  const TrajectoryStateOnSurface&& dest_state = propagator->propagate(start_state, *(layer.disk));
445  if (not dest_state.isValid()) {
446  edm::LogInfo(kLogCategory_) << "failed to propagate a muon" << std::endl;
447  continue;
448  }
449 
450  const GlobalPoint&& dest_global_pos = dest_state.globalPosition();
451 
452  if (not checkBounds(dest_global_pos, (*layer.disk))) {
453  edm::LogInfo(kLogCategory_) << "failed to pass checkBounds" << std::endl;
454  continue;
455  }
456 
457  const GEMEtaPartition* eta_partition = findEtaPartition(dest_global_pos, layer.chambers);
458  if (eta_partition == nullptr) {
459  edm::LogInfo(kLogCategory_) << "failed to find an eta partition" << std::endl;
460  continue;
461  }
462 
463  const BoundPlane& surface = eta_partition->surface();
464 
465  const LocalPoint&& dest_local_pos = eta_partition->toLocal(dest_global_pos);
466  const LocalError&& dest_local_err = dest_state.localError().positionError();
467  const GlobalError& dest_global_err = ErrorFrameTransformer().transform(dest_local_err, surface);
468 
469  const double dest_global_r_err = std::sqrt(dest_global_err.rerr(dest_global_pos));
470  const double dest_global_phi_err = std::sqrt(dest_global_err.phierr(dest_global_pos));
471 
472  const GEMDetId&& gem_id = eta_partition->id();
473  const GEMDetId&& rs_key = getReStKey(gem_id);
474  const GEMDetId&& rsl_key = getReStLaKey(gem_id);
475  const GEMDetId&& rse_key = getReStEtKey(gem_id);
476 
477  const int chamber_id = gem_id.chamber();
478  const int ieta = gem_id.ieta();
479 
480  // FIXME clever way to clamp values?
481  me_prop_r_err_->Fill(std::min(dest_global_r_err, 19.999));
482  me_prop_phi_err_->Fill(std::min(dest_global_r_err, M_PI - 0.0001));
483  me_prop_chamber_[rs_key]->Fill(gem_id.chamber());
484 
485  if (use_prop_r_error_cut_ and (dest_global_r_err > prop_r_error_cut_)) {
486  edm::LogInfo(kLogCategory_) << "failed to pass a propagation global R error cut" << std::endl;
487  continue;
488  }
489 
490  if (use_prop_phi_error_cut_ and (dest_global_phi_err > prop_phi_error_cut_)) {
491  edm::LogInfo(kLogCategory_) << "failed to pass a propagation global phi error cut" << std::endl;
492  continue;
493  }
494 
495  const double muon_pt = std::min(muon.pt(), pt_clamp_max_);
496  const double muon_eta = std::clamp(std::fabs(muon.eta()), eta_low_, eta_clamp_max_);
497 
498  fillME(me_muon_pt_, rs_key, muon_pt);
499  fillME(me_muon_eta_, rs_key, muon_eta);
500  fillME(me_muon_phi_, rs_key, muon.phi());
501 
502  fillME(me_chamber_, rsl_key, chamber_id);
503  fillME(me_ieta_, rsl_key, ieta);
504  fillME(me_detector_, rsl_key, chamber_id, ieta);
505 
506  const auto&& [hit, residual_rphi] = findClosetHit(dest_global_pos, rechit_collection->get(gem_id), eta_partition);
507 
508  if (hit == nullptr) {
509  edm::LogInfo(kLogCategory_) << "failed to find a hit" << std::endl;
510  continue;
511  }
512 
513  me_all_abs_residual_rphi_->Fill(std::min(std::abs(residual_rphi), 19.999f));
514  if (std::abs(residual_rphi) > residual_rphi_cut_) {
515  edm::LogInfo(kLogCategory_) << "failed to pass the residual rphi cut" << std::endl;
516  continue;
517  }
518 
519  fillME(me_muon_pt_matched_, rs_key, muon_pt);
520  fillME(me_muon_eta_matched_, rs_key, muon_eta);
521  fillME(me_muon_phi_matched_, rs_key, muon.phi());
522 
523  fillME(me_chamber_matched_, rsl_key, gem_id.chamber());
524  fillME(me_ieta_matched_, rsl_key, gem_id.ieta());
525  fillME(me_detector_matched_, rsl_key, gem_id.chamber(), ieta);
526 
527  const LocalPoint&& hit_local_pos = hit->localPosition();
528  const LocalError&& hit_local_err = hit->localPositionError();
529 
530  const float residual_y = dest_local_pos.y() - hit_local_pos.y();
531  const float pull_y = residual_y / std::sqrt(dest_local_err.yy() + hit_local_err.yy());
532 
533  fillME(me_residual_rphi_, rse_key, residual_rphi);
534  fillME(me_residual_y_, rse_key, residual_y);
535  fillME(me_pull_y_, rse_key, pull_y);
536  } // layer
537  } // Muon
538 }
539 
540 std::vector<GEMEfficiencyAnalyzer::GEMLayerData> GEMEfficiencyAnalyzer::buildGEMLayers(
541  const edm::ESHandle<GEMGeometry>& gem) {
542  std::vector<GEMLayerData> layer_vector;
543 
544  for (const GEMStation* station : gem->stations()) {
545  const int region_id = station->region();
546  const int station_id = station->station();
547  const bool is_ge11 = station_id == 1;
548 
549  // (layer_id, is_odd) - chambers
550  std::map<std::pair<int, bool>, std::vector<const GEMChamber*> > chambers_per_layer;
551 
552  for (const GEMSuperChamber* super_chamber : station->superChambers()) {
553  // For GE0 and GE21, 'is_odd' is always set to 'false'
554  const bool is_odd = is_ge11 ? super_chamber->id().chamber() % 2 == 1 : false;
555 
556  for (const GEMChamber* chamber : super_chamber->chambers()) {
557  const int layer_id = chamber->id().layer();
558  const std::pair<int, bool> key{layer_id, is_odd};
559 
560  if (chambers_per_layer.find(key) == chambers_per_layer.end())
561  chambers_per_layer.insert({key, std::vector<const GEMChamber*>()});
562 
563  chambers_per_layer.at(key).push_back(chamber);
564  } // GEMChamber
565  } // GEMSuperChamber
566 
567  for (auto [key, chamber_vector] : chambers_per_layer) {
568  const int layer_id = key.first;
569 
570  // chambers should have same R and Z spans.
571  auto [rmin, rmax] = chamber_vector[0]->surface().rSpan();
572  auto [zmin, zmax] = chamber_vector[0]->surface().zSpan();
573 
574  // layer position and rotation
575  const float layer_z = chamber_vector[0]->position().z();
576  Surface::PositionType position{0.f, 0.f, layer_z};
578 
579  zmin -= layer_z;
580  zmax -= layer_z;
581 
582  // the bounds from min and max R and Z in the local coordinates.
583  SimpleDiskBounds* bounds = new SimpleDiskBounds(rmin, rmax, zmin, zmax);
584  const Disk::DiskPointer&& layer = Disk::build(position, rotation, bounds);
585 
586  layer_vector.emplace_back(layer, chamber_vector, region_id, station_id, layer_id);
587  } // layer
588  } // GEMStation
589 
590  return layer_vector;
591 }
592 
594  const reco::Track* track = nullptr;
595 
596  if (is_cosmics_) {
597  if (muon.outerTrack().isNonnull())
598  track = muon.outerTrack().get();
599 
600  } else {
601  // beams, i.e. pp or heavy ions
602  if (use_global_muon_ and muon.globalTrack().isNonnull())
603  track = muon.globalTrack().get();
604 
605  else if ((not use_global_muon_) and muon.outerTrack().isNonnull())
606  track = muon.outerTrack().get();
607  }
608 
609  return track;
610 }
611 
612 std::pair<TrajectoryStateOnSurface, DetId> GEMEfficiencyAnalyzer::getStartingState(
613  const reco::TransientTrack& transient_track,
614  const GEMLayerData& layer,
616  TrajectoryStateOnSurface starting_state;
617  DetId starting_id;
618 
619  if (use_global_muon_) {
620  std::tie(starting_state, starting_id) = findStartingState(transient_track, layer, geometry);
621 
622  } else {
623  // if outer track
624  const reco::Track& track = transient_track.track();
625  const bool is_insideout = isInsideOut(track);
626 
627  const DetId inner_id{(is_insideout ? track.outerDetId() : track.innerDetId())};
628  if (MuonHitHelper::isGEM(inner_id.rawId())) {
629  std::tie(starting_state, starting_id) = findStartingState(transient_track, layer, geometry);
630 
631  } else {
632  starting_id = inner_id;
633  if (is_insideout)
634  starting_state = transient_track.outermostMeasurementState();
635  else
636  starting_state = transient_track.innermostMeasurementState();
637  }
638  }
639 
640  return std::make_pair(starting_state, starting_id);
641 }
642 
643 std::pair<TrajectoryStateOnSurface, DetId> GEMEfficiencyAnalyzer::findStartingState(
644  const reco::TransientTrack& transient_track,
645  const GEMLayerData& layer,
646  const edm::ESHandle<GlobalTrackingGeometry>& geometry) {
647  GlobalPoint starting_point;
648  DetId starting_id;
649  float min_distance = 1e12;
650  bool found = false;
651 
652  // TODO optimize this loop because hits should be ordered..
653  for (auto rechit = transient_track.recHitsBegin(); rechit != transient_track.recHitsEnd(); rechit++) {
654  const DetId&& det_id = (*rechit)->geographicalId();
655 
656  if (MuonHitHelper::isGEM(det_id.rawId())) {
657  continue;
658  }
659 
660  const GeomDet* det = geometry->idToDet(det_id);
661  const GlobalPoint&& global_position = det->toGlobal((*rechit)->localPosition());
662  const float distance = std::abs(layer.disk->localZclamped(global_position));
663  if (distance < min_distance) {
664  found = true;
665  min_distance = distance;
666  starting_point = global_position;
667  starting_id = det_id;
668  }
669  }
670 
671  TrajectoryStateOnSurface starting_state;
672  if (found) {
673  starting_state = transient_track.stateOnSurface(starting_point);
674  }
675  return std::make_pair(starting_state, starting_id);
676 }
677 
679  if (not MuonHitHelper::isCSC(det_id))
680  return false;
681  const CSCDetId csc_id{det_id};
682  return (csc_id.station() == 1) or ((csc_id.ring() == 1) or (csc_id.ring() == 4));
683 }
684 
686  const bool is_same_region = track->eta() * layer.region > 0;
687 
688  bool skip = false;
689  if (is_cosmics_) {
690  float p2_in = track->innerMomentum().mag2();
691  float p2_out = track->outerMomentum().mag2();
692  if (isInsideOut(*track))
693  std::swap(p2_in, p2_out);
694  const bool is_outgoing = p2_in > p2_out;
695 
696  skip = (is_outgoing xor is_same_region);
697 
698  } else {
699  // beam scenario
700  skip = not is_same_region;
701  }
702 
703  return skip;
704 }
705 
706 bool GEMEfficiencyAnalyzer::checkBounds(const GlobalPoint& global_point, const Plane& plane) {
707  const LocalPoint&& local_point = plane.toLocal(global_point);
708  const LocalPoint local_point_2d(local_point.x(), local_point.y(), 0.0f);
709  return plane.bounds().inside(local_point_2d);
710 }
711 
713  const std::vector<const GEMChamber*>& chamber_vector) {
714  const GEMEtaPartition* bound = nullptr;
715  for (const GEMChamber* chamber : chamber_vector) {
716  if (not checkBounds(global_point, chamber->surface()))
717  continue;
718 
719  for (const GEMEtaPartition* eta_partition : chamber->etaPartitions()) {
720  if (checkBounds(global_point, eta_partition->surface())) {
721  bound = eta_partition;
722  break;
723  }
724  } // GEMEtaPartition
725  } // GEMChamber
726 
727  return bound;
728 }
729 
730 std::pair<const GEMRecHit*, float> GEMEfficiencyAnalyzer::findClosetHit(const GlobalPoint& dest_global_pos,
732  const GEMEtaPartition* eta_partition) {
733  const StripTopology& topology = eta_partition->specificTopology();
734  const LocalPoint&& dest_local_pos = eta_partition->toLocal(dest_global_pos);
735  const float dest_local_x = dest_local_pos.x();
736  const float dest_local_y = dest_local_pos.y();
737 
738  const GEMRecHit* closest_hit = nullptr;
739  float min_residual_rphi = 1e6;
740 
741  for (auto hit = range.first; hit != range.second; ++hit) {
742  const LocalPoint&& hit_local_pos = hit->localPosition();
743  const float hit_local_phi = topology.stripAngle(eta_partition->strip(hit_local_pos));
744 
745  const float residual_x = dest_local_x - hit_local_pos.x();
746  const float residual_y = dest_local_y - hit_local_pos.y();
747  const float residual_rphi = std::cos(hit_local_phi) * residual_x + std::sin(hit_local_phi) * residual_y;
748 
749  if (std::abs(residual_rphi) < std::abs(min_residual_rphi)) {
750  min_residual_rphi = residual_rphi;
751  closest_hit = &(*hit);
752  }
753  }
754 
755  return std::make_pair(closest_hit, min_residual_rphi);
756 }
T getUntrackedParameter(std::string const &, T const &) const
tuple propagator
static GlobalError transform(const LocalError &le, const Surface &surf)
bool isInsideOut(const reco::Track &)
std::pair< const_iterator, const_iterator > range
iterator range
Definition: RangeMap.h:50
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
const edm::ESGetToken< TransientTrackBuilder, TransientTrackRecord > trasientTrackToken_
GEMDetId getReStLaKey(const GEMDetId &)
static bool isCSC(unsigned int detId)
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
bool skipLayer(const reco::Track *, const GEMLayerData &)
TString getSuffixName(Int_t region_id)
virtual float stripAngle(float strip) const =0
WorkSpace int float eps
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:32
virtual bool inside(const Local3DPoint &) const =0
Determine if the point is inside the bounds.
bool isValid() const
Make the ReferenceCountingProxy method to check validity public.
void setAllowAnything()
allow any parameter label/value pairs
GlobalPoint toGlobal(const Local2DPoint &lp) const
Conversion to the global R.F. from the R.F. of the GeomDet.
Definition: GeomDet.h:49
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
T y() const
Definition: PV3DBase.h:60
GlobalPoint globalPosition() const
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:58
const std::string & getName() const
get name of ME
const Bounds & bounds() const
Definition: Surface.h:87
std::vector< GEMLayerData > buildGEMLayers(const edm::ESHandle< GEMGeometry > &)
Log< level::Error, false > LogError
TString getSuffixTitle(Int_t region_id)
const std::string kLogCategory_
void bookEfficiencyChamber(DQMStore::IBooker &, const edm::ESHandle< GEMGeometry > &)
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
void setDetLabelsEta(MonitorElement *, const GEMStation *)
LocalError positionError() const
void bookEfficiencyDetector(DQMStore::IBooker &, const edm::ESHandle< GEMGeometry > &)
Definition: Plane.h:16
constexpr int ieta() const
Definition: GEMDetId.h:199
GEMDetId id() const
TrajectoryStateOnSurface innermostMeasurementState() const
const edm::ESGetToken< GlobalTrackingGeometry, GlobalTrackingGeometryRecord > globalGeomToken_
constexpr std::array< uint8_t, layerIndexSize > layer
const uint16_t range(const Frame &aFrame)
T phierr(const GlobalPoint &aPoint) const
void Fill(long long x)
void bookResolution(DQMStore::IBooker &, const edm::ESHandle< GEMGeometry > &)
bool checkBounds(const GlobalPoint &, const Plane &)
bool checkRefs(const std::vector< T * > &)
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:652
static DiskPointer build(Args &&...args)
Definition: BoundDisk.h:38
MonitorElement * me_prop_r_err_
float yy() const
Definition: LocalError.h:24
std::pair< TrajectoryStateOnSurface, DetId > getStartingState(const reco::TransientTrack &, const GEMLayerData &, const edm::ESHandle< GlobalTrackingGeometry > &)
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
T sqrt(T t)
Definition: SSEVec.h:19
LocalPoint toLocal(const GlobalPoint &gp) const
void bookEfficiencyEtaPartition(DQMStore::IBooker &, const edm::ESHandle< GEMGeometry > &)
edm::ESHandle< Propagator > propagator(std::string propagatorName) const
get the propagator
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
MonitorElement * me_all_abs_residual_rphi_
std::pair< const GEMRecHit *, float > findClosetHit(const GlobalPoint &, const GEMRecHitCollection::range &, const GEMEtaPartition *)
unsigned int outerDetId() const
DetId of the detector on which surface the outermost state is located.
Definition: Track.h:79
tuple key
prepare the HTCondor submission files and eventually submit them
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Transition
Definition: Transition.h:12
const StripTopology & specificTopology() const
void analyze(const edm::Event &event, const edm::EventSetup &eventSetup) override
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:232
std::pair< TrajectoryStateOnSurface, DetId > findStartingState(const reco::TransientTrack &, const GEMLayerData &, const edm::ESHandle< GlobalTrackingGeometry > &)
T min(T a, T b)
Definition: MathUtil.h:58
const LocalTrajectoryError & localError() const
TrajectoryStateOnSurface outermostMeasurementState() const
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool isValid() const
Definition: HandleBase.h:70
GEMEfficiencyAnalyzer(const edm::ParameterSet &)
virtual TrackRef outerTrack() const
reference to Track reconstructed in the muon detector only
Definition: Muon.h:48
trackingRecHit_iterator recHitsEnd() const
last iterator to RecHits
GEMDetId getReStEtKey(const GEMDetId &)
#define M_PI
void fillME(MEMap &me_map, const GEMDetId &key, const float x)
const edm::ESGetToken< GEMGeometry, MuonGeometryRecord > gemToken1_
__shared__ Hist hist
Log< level::Info, false > LogInfo
const GEMEtaPartition * findEtaPartition(const GlobalPoint &, const std::vector< const GEMChamber * > &)
Definition: DetId.h:17
const math::XYZVector & outerMomentum() const
momentum vector at the outermost hit position
Definition: Track.h:65
const Track & track() const
static void fillDescriptions(edm::ConfigurationDescriptions &)
void bookEfficiencyMomentum(DQMStore::IBooker &, const edm::ESHandle< GEMGeometry > &)
float strip(const LocalPoint &lp) const
void bookMisc(DQMStore::IBooker &, const edm::ESHandle< GEMGeometry > &)
constexpr int chamber() const
Definition: GEMDetId.h:183
T rerr(const GlobalPoint &aPoint) const
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:177
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
void add(std::string const &label, ParameterSetDescription const &psetDescription)
edm::EDGetTokenT< GEMRecHitCollection > rechit_token_
static bool isGEM(unsigned int detId)
Definition: MuonHitHelper.cc:7
edm::EDGetTokenT< edm::View< reco::Muon > > muon_token_
bool isME11(const DetId &)
MonitorElement * me_prop_phi_err_
TrajectoryStateOnSurface stateOnSurface(const GlobalPoint &point) const
const math::XYZVector & innerMomentum() const
momentum vector at the innermost hit position
Definition: Track.h:59
static int position[264][3]
Definition: ReadPGInfo.cc:289
GEMDetId getReStKey(const int, const int)
const edm::ESGetToken< GEMGeometry, MuonGeometryRecord > gemToken2_
MonitorElement * bookNumerator2D(DQMStore::IBooker &, MonitorElement *)
void update(const edm::EventSetup &setup, bool duringEvent=true)
update the services each event
const reco::Track * getTrack(const reco::Muon &)
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
Definition: EventSetup.h:157
MonitorElement * bookNumerator1D(DQMStore::IBooker &, MonitorElement *)
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
static char chambers[264][20]
Definition: ReadPGInfo.cc:243
bool isValid() const
Definition: ESHandle.h:44
std::vector< double > pt_bins_
T x() const
Definition: PV3DBase.h:59
unsigned int innerDetId() const
DetId of the detector on which surface the innermost state is located.
Definition: Track.h:82
ESGetTokenH3DDVariant esConsumes(std::string const &Reccord, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
trackingRecHit_iterator recHitsBegin() const
first iterator to RecHits
MuonServiceProxy * muon_service_
Definition: Run.h:45
virtual TrackRef globalTrack() const
reference to Track reconstructed in both tracked and muon detector
Definition: Muon.h:51
virtual void setAxisTitle(const std::string &title, int axis=1)
set x-, y- or z-axis title (axis=1, 2, 3 respectively)