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  monitor_ge11_ = pset.getUntrackedParameter<bool>("monitorGE11");
40  monitor_ge21_ = pset.getUntrackedParameter<bool>("monitorGE21");
41  monitor_ge0_ = pset.getUntrackedParameter<bool>("monitorGE0");
42 
43  const edm::ParameterSet&& muon_service_parameter = pset.getParameter<edm::ParameterSet>("ServiceParameters");
44  muon_service_ = new MuonServiceProxy(muon_service_parameter, consumesCollector());
45 
47  pt_clamp_max_ = pt_bins_.back() - eps;
48  eta_clamp_max_ = eta_up_ - eps;
49 
50  // TODO pt, eta, quality check for muons
51 }
52 
54 
56  // beam scenario
57  {
59  desc.addUntracked<std::string>("name", "GlobalMuon");
60  desc.addUntracked<std::string>("folder", "GEM/Efficiency/type0");
61  desc.add<edm::InputTag>("recHitTag", edm::InputTag("gemRecHits"));
62  desc.add<edm::InputTag>("muonTag", edm::InputTag("muons"));
63  desc.addUntracked<bool>("isCosmics", false);
64  desc.addUntracked<bool>("useGlobalMuon", true);
65  desc.add<bool>("useSkipLayer", true);
66  desc.add<bool>("useOnlyME11", false);
67  desc.add<double>("residualRPhiCut", 2.0); // TODO need to be tuned
68  desc.add<bool>("usePropRErrorCut", false);
69  desc.add<double>("propRErrorCut", 1.0);
70  desc.add<bool>("usePropPhiErrorCut", false);
71  desc.add<double>("propPhiErrorCut", 0.01);
72  desc.addUntracked<std::vector<double> >("ptBins", {20., 30., 40., 50., 60., 70., 80., 90., 100., 120.});
73  desc.addUntracked<int>("etaNbins", 9);
74  desc.addUntracked<double>("etaLow", 1.4);
75  desc.addUntracked<double>("etaUp", 2.3);
76  desc.addUntracked<bool>("monitorGE11", true);
77  desc.addUntracked<bool>("monitorGE21", false);
78  desc.addUntracked<bool>("monitorGE0", false);
79  {
81  psd0.setAllowAnything();
82  desc.add<edm::ParameterSetDescription>("ServiceParameters", psd0);
83  }
84  descriptions.add("gemEfficiencyAnalyzerDefault", desc);
85  } // beam scenario
86 
87  // cosmic scenario
88  {
90  desc.addUntracked<std::string>("name", "GlobalMuon"); // FIXME
91  desc.addUntracked<std::string>("folder", "GEM/Efficiency/type0");
92  desc.add<edm::InputTag>("recHitTag", edm::InputTag("gemRecHits"));
93  desc.add<edm::InputTag>("muonTag", edm::InputTag("muons"));
94  desc.addUntracked<bool>("isCosmics", true);
95  desc.addUntracked<bool>("useGlobalMuon", false);
96  desc.add<bool>("useSkipLayer", true);
97  desc.add<bool>("useOnlyME11", true);
98  desc.add<double>("residualRPhiCut", 5.0); // TODO need to be tuned
99  desc.add<bool>("usePropRErrorCut", true);
100  desc.add<double>("propRErrorCut", 1.0);
101  desc.add<bool>("usePropPhiErrorCut", true);
102  desc.add<double>("propPhiErrorCut", 0.001);
103  desc.addUntracked<std::vector<double> >("ptBins", {0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100., 120.});
104  desc.addUntracked<int>("etaNbins", 9);
105  desc.addUntracked<double>("etaLow", 1.4);
106  desc.addUntracked<double>("etaUp", 2.3);
107  desc.addUntracked<bool>("monitorGE11", true);
108  desc.addUntracked<bool>("monitorGE21", false);
109  desc.addUntracked<bool>("monitorGE0", false);
110  {
112  psd0.setAllowAnything();
113  desc.add<edm::ParameterSetDescription>("ServiceParameters", psd0);
114  }
115  descriptions.add("gemEfficiencyAnalyzerCosmicsDefault", desc);
116  } // cosmics
117 }
118 
120  edm::Run const& run,
121  edm::EventSetup const& isetup) {
123  gem = isetup.getHandle(gemToken1_);
124 
125  if (not gem.isValid()) {
126  edm::LogError(kLogCategory_) << "GEMGeometry is invalid" << std::endl;
127  return;
128  }
129 
130  bookEfficiencyMomentum(ibooker, gem);
131  bookEfficiencyChamber(ibooker, gem);
132  bookEfficiencyEtaPartition(ibooker, gem);
133  bookEfficiencyDetector(ibooker, gem);
134  bookResolution(ibooker, gem);
135  bookMisc(ibooker, gem);
136 }
137 
139  const std::string name = me->getName() + "_matched";
140  TH1F* hist = dynamic_cast<TH1F*>(me->getTH1F()->Clone(name.c_str()));
141  return ibooker.book1D(name, hist);
142 }
143 
145  const std::string name = me->getName() + "_matched";
146  TH2F* hist = dynamic_cast<TH2F*>(me->getTH2F()->Clone(name.c_str()));
147  return ibooker.book2D(name, hist);
148 }
149 
151  // TODO Efficiency/Source
152  ibooker.setCurrentFolder(folder_ + "/Efficiency");
153 
154  const TString pt_x_title = "Muon p_{T} [GeV]";
155  const int pt_nbinsx = pt_bins_.size() - 1;
156 
157  const std::string eta_x_title = "Muon |#eta|";
158  const std::string phi_x_title = "Muon #phi [rad]";
159 
160  for (const GEMStation* station : gem->stations()) {
161  const int region_id = station->region();
162  const int station_id = station->station();
163 
164  if (skipGEMStation(station_id)) {
165  continue;
166  }
167 
168  const GEMDetId&& key = getReStKey(region_id, station_id);
169  const TString&& name_suffix = GEMUtils::getSuffixName(region_id, station_id);
170  const TString&& title_suffix = GEMUtils::getSuffixTitle(region_id, station_id);
171 
172  const TString&& title = name_.c_str() + title_suffix;
173 
174  TH1F* h_muon_pt = new TH1F("muon_pt" + name_suffix, title, pt_nbinsx, &pt_bins_[0]);
175  h_muon_pt->SetXTitle(pt_x_title);
176  me_muon_pt_[key] = ibooker.book1D(h_muon_pt->GetName(), h_muon_pt);
178 
179  me_muon_eta_[key] = ibooker.book1D("muon_eta" + name_suffix, title, eta_nbins_, eta_low_, eta_up_);
180  me_muon_eta_[key]->setXTitle(eta_x_title);
182 
183  me_muon_phi_[key] = ibooker.book1D("muon_phi" + name_suffix, title, 36, -M_PI, M_PI);
184  me_muon_phi_[key]->setAxisTitle(phi_x_title);
186  } // station
187 }
188 
190  // TODO Efficiency/Source
191  ibooker.setCurrentFolder(folder_ + "/Efficiency");
192 
193  for (const GEMStation* station : gem->stations()) {
194  const int region_id = station->region();
195  const int station_id = station->station();
196 
197  if (skipGEMStation(station_id)) {
198  continue;
199  }
200 
201  const std::vector<const GEMSuperChamber*>&& superchambers = station->superChambers();
202  if (not checkRefs(superchambers)) {
203  edm::LogError(kLogCategory_) << "failed to get a valid vector of GEMSuperChamber ptrs" << std::endl;
204  return;
205  }
206 
207  const int num_chambers = superchambers.size();
208  for (const GEMChamber* chamber : superchambers[0]->chambers()) {
209  const int layer_id = chamber->id().layer();
210 
211  const TString&& name_suffix = GEMUtils::getSuffixName(region_id, station_id, layer_id);
212  const TString&& title_suffix = GEMUtils::getSuffixTitle(region_id, station_id, layer_id);
213  const GEMDetId&& key = getReStLaKey(chamber->id());
214 
215  me_chamber_[key] =
216  ibooker.book1D("chamber" + name_suffix, name_.c_str() + title_suffix, num_chambers, 0.5, num_chambers + 0.5);
217  me_chamber_[key]->setAxisTitle("Chamber");
218  me_chamber_[key]->getTH1F()->SetNdivisions(-num_chambers, "Y");
219  for (int binx = 1; binx <= num_chambers; binx++) {
220  me_chamber_[key]->setBinLabel(binx, std::to_string(binx));
221  }
222 
223  me_chamber_matched_[key] = bookNumerator1D(ibooker, me_chamber_[key]);
224  } // layer
225  } // station
226 }
227 
229  const edm::ESHandle<GEMGeometry>& gem) {
230  // TODO Efficiency/Source
231  ibooker.setCurrentFolder(folder_ + "/Efficiency");
232 
233  for (const GEMStation* station : gem->stations()) {
234  const int region_id = station->region();
235  const int station_id = station->station();
236 
237  if (skipGEMStation(station_id)) {
238  continue;
239  }
240 
241  const std::vector<const GEMSuperChamber*>&& superchambers = station->superChambers();
242  if (not checkRefs(superchambers)) {
243  edm::LogError(kLogCategory_) << "failed to get a valid vector of GEMSuperChamber ptrs" << std::endl;
244  return;
245  }
246 
247  for (const GEMChamber* chamber : superchambers[0]->chambers()) {
248  const int layer_id = chamber->id().layer();
249  const int num_ieta = chamber->nEtaPartitions();
250 
251  const TString&& name_suffix = GEMUtils::getSuffixName(region_id, station_id, layer_id);
252  const TString&& title_suffix = GEMUtils::getSuffixTitle(region_id, station_id, layer_id);
253  const GEMDetId&& key = getReStLaKey(chamber->id());
254 
255  me_ieta_[key] = ibooker.book1D("ieta" + name_suffix, name_.c_str() + title_suffix, num_ieta, 0.5, num_ieta + 0.5);
256  me_ieta_[key]->setAxisTitle("i#eta");
257  me_ieta_[key]->getTH1F()->SetNdivisions(-num_ieta, "Y");
258  for (int binx = 1; binx <= num_ieta; binx++) {
259  me_ieta_[key]->setBinLabel(binx, std::to_string(binx));
260  }
261 
262  me_ieta_matched_[key] = bookNumerator1D(ibooker, me_ieta_[key]);
263  } // layer
264  } // station
265 }
266 
268  // TODO Efficiency/Source
269  ibooker.setCurrentFolder(folder_ + "/Efficiency");
270 
271  for (const GEMStation* station : gem->stations()) {
272  const int region_id = station->region();
273  const int station_id = station->station();
274 
275  if (skipGEMStation(station_id)) {
276  continue;
277  }
278 
279  const std::vector<const GEMSuperChamber*>&& superchambers = station->superChambers();
280  if (not checkRefs(superchambers)) {
281  edm::LogError(kLogCategory_) << "failed to get a valid vector of GEMSuperChamber ptrs" << std::endl;
282  return;
283  }
284 
285  const int num_ch = superchambers.size();
286 
287  for (const GEMChamber* chamber : superchambers[0]->chambers()) {
288  const int layer_id = chamber->id().layer();
289  const int num_ieta = chamber->nEtaPartitions();
290 
291  const TString&& name_suffix = GEMUtils::getSuffixName(region_id, station_id, layer_id);
292  const TString&& title_suffix = GEMUtils::getSuffixTitle(region_id, station_id, layer_id);
293  const GEMDetId&& key = getReStLaKey(chamber->id());
294 
295  me_detector_[key] = ibooker.book2D("detector" + name_suffix,
296  name_.c_str() + title_suffix,
297  num_ch,
298  0.5,
299  num_ch + 0.5,
300  num_ieta,
301  0.5,
302  num_ieta + 0.5);
303  setDetLabelsEta(me_detector_[key], station);
304 
305  me_detector_matched_[key] = bookNumerator2D(ibooker, me_detector_[key]);
306  } // layer
307  } // station
308 }
309 
311  ibooker.setCurrentFolder(folder_ + "/Resolution");
312  for (const GEMStation* station : gem->stations()) {
313  const int region_id = station->region();
314  const int station_id = station->station();
315 
316  if (skipGEMStation(station_id)) {
317  continue;
318  }
319 
320  const std::vector<const GEMSuperChamber*>&& superchambers = station->superChambers();
321  if (not checkRefs(superchambers)) {
322  edm::LogError(kLogCategory_) << "failed to get a valid vector of GEMSuperChamber ptrs" << std::endl;
323  return;
324  }
325 
326  const std::vector<const GEMChamber*>& chambers = superchambers[0]->chambers();
327  if (not checkRefs(chambers)) {
328  edm::LogError(kLogCategory_) << "failed to get a valid vector of GEMChamber ptrs" << std::endl;
329  return;
330  }
331 
332  for (const GEMEtaPartition* eta_partition : chambers[0]->etaPartitions()) {
333  const int ieta = eta_partition->id().roll();
334 
335  const GEMDetId&& key = getReStEtKey(eta_partition->id());
336  // TODO
337  const TString&& name_suffix = TString::Format("_GE%+.2d_R%d", region_id * (station_id * 10 + 1), ieta);
338  const TString&& title =
339  name_.c_str() + TString::Format(" : GE%+.2d Roll %d", region_id * (station_id * 10 + 1), ieta);
340 
342  ibooker.book1D("residual_rphi" + name_suffix, title, 50, -residual_rphi_cut_, residual_rphi_cut_);
343  me_residual_rphi_[key]->setAxisTitle("Residual in R#phi [cm]");
344 
345  me_residual_y_[key] = ibooker.book1D("residual_y" + name_suffix, title, 60, -12.0, 12.0);
346  me_residual_y_[key]->setAxisTitle("Residual in Local Y [cm]");
347 
348  me_pull_y_[key] = ibooker.book1D("pull_y" + name_suffix, title, 60, -3.0, 3.0);
349  me_pull_y_[key]->setAxisTitle("Pull in Local Y");
350  } // ieta
351  } // station
352 }
353 
355  ibooker.setCurrentFolder(folder_ + "/Misc");
356  // FIXME the range shoule be dependent on the scenario
357  me_prop_r_err_ = ibooker.book1D("prop_r_err", ";Propagation Global R Error [cm];Entries", 20, 0.0, 20.0);
358  me_prop_phi_err_ = ibooker.book1D("prop_phi_err", "Propagation Global Phi Error [rad];Entries", 20, 0.0, M_PI);
359  me_all_abs_residual_rphi_ = ibooker.book1D("all_abs_residual_rphi", ";Residual in R#phi [cm];Entries", 20, 0.0, 20.0);
360 
361  for (const GEMStation* station : gem->stations()) {
362  const int region_id = station->region();
363  const int station_id = station->station();
364 
365  if (skipGEMStation(station_id)) {
366  continue;
367  }
368 
369  const std::vector<const GEMSuperChamber*>&& superchambers = station->superChambers();
370  if (not checkRefs(superchambers)) {
371  edm::LogError(kLogCategory_) << "failed to get a valid vector of GEMSuperChamber ptrs" << std::endl;
372  return;
373  }
374  // ignore layer ids
375  const int num_ch = superchambers.size();
376 
377  const GEMDetId&& key = getReStKey(region_id, station_id);
378  const TString&& name_suffix = GEMUtils::getSuffixName(region_id, station_id);
379  const TString&& title_suffix = GEMUtils::getSuffixTitle(region_id, station_id);
380  me_prop_chamber_[key] = ibooker.book1D("prop_chamber" + name_suffix, title_suffix, num_ch, 0.5, num_ch + 0.5);
381  me_prop_chamber_[key]->setAxisTitle("Destination Chamber Id", 1);
382  me_prop_chamber_[key]->setAxisTitle("Entries", 2);
383  } // station
384 }
385 
387  edm::Handle<GEMRecHitCollection> rechit_collection;
388  event.getByToken(rechit_token_, rechit_collection);
389  if (not rechit_collection.isValid()) {
390  edm::LogError(kLogCategory_) << "GEMRecHitCollection is invalid" << std::endl;
391  return;
392  }
393 
395  event.getByToken(muon_token_, muon_view);
396  if (not muon_view.isValid()) {
397  edm::LogError(kLogCategory_) << "View<Muon> is invalid" << std::endl;
398  return;
399  }
400 
402  gem = setup.getHandle(gemToken2_);
403 
404  if (not gem.isValid()) {
405  edm::LogError(kLogCategory_) << "GEMGeometry is invalid" << std::endl;
406  return;
407  }
408 
409  edm::ESHandle<GlobalTrackingGeometry> global_tracking_geometry;
410 
411  global_tracking_geometry = setup.getHandle(globalGeomToken_);
412 
413  if (not global_tracking_geometry.isValid()) {
414  edm::LogError(kLogCategory_) << "GlobalTrackingGeometry is invalid" << std::endl;
415  return;
416  }
417 
418  edm::ESHandle<TransientTrackBuilder> transient_track_builder;
419  transient_track_builder = setup.getHandle(trasientTrackToken_);
420 
421  if (not transient_track_builder.isValid()) {
422  edm::LogError(kLogCategory_) << "TransientTrackRecord is invalid" << std::endl;
423  return;
424  }
425 
426  muon_service_->update(setup);
427  edm::ESHandle<Propagator>&& propagator = muon_service_->propagator("SteppingHelixPropagatorAny");
428  if (not propagator.isValid()) {
429  edm::LogError(kLogCategory_) << "Propagator is invalid" << std::endl;
430  return;
431  }
432 
433  if (muon_view->empty()) {
434  edm::LogInfo(kLogCategory_) << "empty muon collection" << std::endl;
435  return;
436  }
437 
438  const std::vector<GEMLayerData>&& layer_vector = buildGEMLayers(gem);
439 
440  for (const reco::Muon& muon : *muon_view) {
441  const reco::Track* track = getTrack(muon);
442  if (track == nullptr) {
443  edm::LogError(kLogCategory_) << "failed to get a muon track" << std::endl;
444  continue;
445  }
446 
447  const reco::TransientTrack&& transient_track = transient_track_builder->build(track);
448  if (not transient_track.isValid()) {
449  edm::LogError(kLogCategory_) << "failed to build TransientTrack" << std::endl;
450  continue;
451  }
452 
453  for (const GEMLayerData& layer : layer_vector) {
454  if (use_skip_layer_ and skipLayer(track, layer)) {
455  edm::LogInfo(kLogCategory_) << "skip GEM Layer" << std::endl;
456  continue;
457  }
458 
459  const auto&& [start_state, start_id] = getStartingState(transient_track, layer, global_tracking_geometry);
460 
461  if (not start_state.isValid()) {
462  edm::LogInfo(kLogCategory_) << "failed to get a starting state" << std::endl;
463  continue;
464  }
465 
466  if (use_only_me11_ and (not isME11(start_id))) {
467  edm::LogInfo(kLogCategory_) << "skip a starting state because it is not ME11" << std::endl;
468  continue;
469  }
470 
471  // the trajectory state on the destination surface
472  const TrajectoryStateOnSurface&& dest_state = propagator->propagate(start_state, *(layer.disk));
473  if (not dest_state.isValid()) {
474  edm::LogInfo(kLogCategory_) << "failed to propagate a muon" << std::endl;
475  continue;
476  }
477 
478  const GlobalPoint&& dest_global_pos = dest_state.globalPosition();
479 
480  if (not checkBounds(dest_global_pos, (*layer.disk))) {
481  edm::LogInfo(kLogCategory_) << "failed to pass checkBounds" << std::endl;
482  continue;
483  }
484 
485  const GEMEtaPartition* eta_partition = findEtaPartition(dest_global_pos, layer.chambers);
486  if (eta_partition == nullptr) {
487  edm::LogInfo(kLogCategory_) << "failed to find an eta partition" << std::endl;
488  continue;
489  }
490 
491  const BoundPlane& surface = eta_partition->surface();
492 
493  const LocalPoint&& dest_local_pos = eta_partition->toLocal(dest_global_pos);
494  const LocalError&& dest_local_err = dest_state.localError().positionError();
495  const GlobalError& dest_global_err = ErrorFrameTransformer().transform(dest_local_err, surface);
496 
497  const double dest_global_r_err = std::sqrt(dest_global_err.rerr(dest_global_pos));
498  const double dest_global_phi_err = std::sqrt(dest_global_err.phierr(dest_global_pos));
499 
500  const GEMDetId&& gem_id = eta_partition->id();
501  const GEMDetId&& rs_key = getReStKey(gem_id);
502  const GEMDetId&& rsl_key = getReStLaKey(gem_id);
503  const GEMDetId&& rse_key = getReStEtKey(gem_id);
504 
505  const int chamber_id = gem_id.chamber();
506  const int ieta = gem_id.ieta();
507 
508  // FIXME clever way to clamp values?
509  me_prop_r_err_->Fill(std::min(dest_global_r_err, 19.999));
510  me_prop_phi_err_->Fill(std::min(dest_global_r_err, M_PI - 0.0001));
511  me_prop_chamber_[rs_key]->Fill(gem_id.chamber());
512 
513  if (use_prop_r_error_cut_ and (dest_global_r_err > prop_r_error_cut_)) {
514  edm::LogInfo(kLogCategory_) << "failed to pass a propagation global R error cut" << std::endl;
515  continue;
516  }
517 
518  if (use_prop_phi_error_cut_ and (dest_global_phi_err > prop_phi_error_cut_)) {
519  edm::LogInfo(kLogCategory_) << "failed to pass a propagation global phi error cut" << std::endl;
520  continue;
521  }
522 
523  const double muon_pt = std::min(muon.pt(), pt_clamp_max_);
524  const double muon_eta = std::clamp(std::fabs(muon.eta()), eta_low_, eta_clamp_max_);
525 
526  fillME(me_muon_pt_, rs_key, muon_pt);
527  fillME(me_muon_eta_, rs_key, muon_eta);
528  fillME(me_muon_phi_, rs_key, muon.phi());
529 
530  fillME(me_chamber_, rsl_key, chamber_id);
531  fillME(me_ieta_, rsl_key, ieta);
532  fillME(me_detector_, rsl_key, chamber_id, ieta);
533 
534  const auto&& [hit, residual_rphi] = findClosetHit(dest_global_pos, rechit_collection->get(gem_id), eta_partition);
535 
536  if (hit == nullptr) {
537  edm::LogInfo(kLogCategory_) << "failed to find a hit" << std::endl;
538  continue;
539  }
540 
541  me_all_abs_residual_rphi_->Fill(std::min(std::abs(residual_rphi), 19.999f));
542  if (std::abs(residual_rphi) > residual_rphi_cut_) {
543  edm::LogInfo(kLogCategory_) << "failed to pass the residual rphi cut" << std::endl;
544  continue;
545  }
546 
547  fillME(me_muon_pt_matched_, rs_key, muon_pt);
548  fillME(me_muon_eta_matched_, rs_key, muon_eta);
549  fillME(me_muon_phi_matched_, rs_key, muon.phi());
550 
551  fillME(me_chamber_matched_, rsl_key, gem_id.chamber());
552  fillME(me_ieta_matched_, rsl_key, gem_id.ieta());
553  fillME(me_detector_matched_, rsl_key, gem_id.chamber(), ieta);
554 
555  const LocalPoint&& hit_local_pos = hit->localPosition();
556  const LocalError&& hit_local_err = hit->localPositionError();
557 
558  const float residual_y = dest_local_pos.y() - hit_local_pos.y();
559  const float pull_y = residual_y / std::sqrt(dest_local_err.yy() + hit_local_err.yy());
560 
561  fillME(me_residual_rphi_, rse_key, residual_rphi);
562  fillME(me_residual_y_, rse_key, residual_y);
563  fillME(me_pull_y_, rse_key, pull_y);
564  } // layer
565  } // Muon
566 }
567 
569  bool skip = false;
570 
571  if (station == 1) {
572  if (not monitor_ge11_) {
573  LogDebug(kLogCategory_) << "skip GE11 because monitorGE11 is " << std::boolalpha << monitor_ge11_;
574  skip = true;
575  }
576 
577  } else if (station == 2) {
578  if (not monitor_ge21_) {
579  LogDebug(kLogCategory_) << "skip GE21 because monitorGE21 is " << std::boolalpha << monitor_ge21_;
580  skip = true;
581  }
582 
583  } else if (station == 0) {
584  if (not monitor_ge0_) {
585  LogDebug(kLogCategory_) << "skip GE0 because monitorGE0 is " << std::boolalpha << monitor_ge0_;
586  skip = true;
587  }
588 
589  } else {
590  edm::LogError(kLogCategory_) << "got an unexpected GEM station " << station << ". skip this station.";
591  skip = true;
592  }
593 
594  return skip;
595 }
596 
597 std::vector<GEMEfficiencyAnalyzer::GEMLayerData> GEMEfficiencyAnalyzer::buildGEMLayers(
598  const edm::ESHandle<GEMGeometry>& gem) {
599  std::vector<GEMLayerData> layer_vector;
600 
601  for (const GEMStation* station : gem->stations()) {
602  const int region_id = station->region();
603  const int station_id = station->station();
604  const bool is_ge11 = station_id == 1;
605 
606  if (skipGEMStation(station_id)) {
607  continue;
608  }
609 
610  // (layer_id, is_odd) - chambers
611  std::map<std::pair<int, bool>, std::vector<const GEMChamber*> > chambers_per_layer;
612 
613  for (const GEMSuperChamber* super_chamber : station->superChambers()) {
614  // For GE0 and GE21, 'is_odd' is always set to 'false'
615  const bool is_odd = is_ge11 ? super_chamber->id().chamber() % 2 == 1 : false;
616 
617  for (const GEMChamber* chamber : super_chamber->chambers()) {
618  const int layer_id = chamber->id().layer();
619  const std::pair<int, bool> key{layer_id, is_odd};
620 
621  if (chambers_per_layer.find(key) == chambers_per_layer.end())
622  chambers_per_layer.insert({key, std::vector<const GEMChamber*>()});
623 
624  chambers_per_layer.at(key).push_back(chamber);
625  } // GEMChamber
626  } // GEMSuperChamber
627 
628  for (auto [key, chamber_vector] : chambers_per_layer) {
629  const int layer_id = key.first;
630 
631  // chambers should have same R and Z spans.
632  auto [rmin, rmax] = chamber_vector[0]->surface().rSpan();
633  auto [zmin, zmax] = chamber_vector[0]->surface().zSpan();
634 
635  // layer position and rotation
636  const float layer_z = chamber_vector[0]->position().z();
637  Surface::PositionType position{0.f, 0.f, layer_z};
639 
640  zmin -= layer_z;
641  zmax -= layer_z;
642 
643  // the bounds from min and max R and Z in the local coordinates.
644  SimpleDiskBounds* bounds = new SimpleDiskBounds(rmin, rmax, zmin, zmax);
645  const Disk::DiskPointer&& layer = Disk::build(position, rotation, bounds);
646 
647  layer_vector.emplace_back(layer, chamber_vector, region_id, station_id, layer_id);
648  } // layer
649  } // GEMStation
650 
651  return layer_vector;
652 }
653 
655  const reco::Track* track = nullptr;
656 
657  if (is_cosmics_) {
658  if (muon.outerTrack().isNonnull())
659  track = muon.outerTrack().get();
660 
661  } else {
662  // beams, i.e. pp or heavy ions
663  if (use_global_muon_ and muon.globalTrack().isNonnull())
664  track = muon.globalTrack().get();
665 
666  else if ((not use_global_muon_) and muon.outerTrack().isNonnull())
667  track = muon.outerTrack().get();
668  }
669 
670  return track;
671 }
672 
673 std::pair<TrajectoryStateOnSurface, DetId> GEMEfficiencyAnalyzer::getStartingState(
674  const reco::TransientTrack& transient_track,
675  const GEMLayerData& layer,
677  TrajectoryStateOnSurface starting_state;
678  DetId starting_id;
679 
680  if (use_global_muon_) {
681  std::tie(starting_state, starting_id) = findStartingState(transient_track, layer, geometry);
682 
683  } else {
684  // if outer track
685  const reco::Track& track = transient_track.track();
686  const bool is_insideout = isInsideOut(track);
687 
688  const DetId inner_id{(is_insideout ? track.outerDetId() : track.innerDetId())};
689  if (MuonHitHelper::isGEM(inner_id.rawId())) {
690  std::tie(starting_state, starting_id) = findStartingState(transient_track, layer, geometry);
691 
692  } else {
693  starting_id = inner_id;
694  if (is_insideout)
695  starting_state = transient_track.outermostMeasurementState();
696  else
697  starting_state = transient_track.innermostMeasurementState();
698  }
699  }
700 
701  return std::make_pair(starting_state, starting_id);
702 }
703 
704 std::pair<TrajectoryStateOnSurface, DetId> GEMEfficiencyAnalyzer::findStartingState(
705  const reco::TransientTrack& transient_track,
706  const GEMLayerData& layer,
707  const edm::ESHandle<GlobalTrackingGeometry>& geometry) {
708  GlobalPoint starting_point;
709  DetId starting_id;
710  float min_distance = 1e12;
711  bool found = false;
712 
713  // TODO optimize this loop because hits should be ordered..
714  for (auto rechit = transient_track.recHitsBegin(); rechit != transient_track.recHitsEnd(); rechit++) {
715  const DetId&& det_id = (*rechit)->geographicalId();
716 
717  if (MuonHitHelper::isGEM(det_id.rawId())) {
718  continue;
719  }
720 
721  const GeomDet* det = geometry->idToDet(det_id);
722  const GlobalPoint&& global_position = det->toGlobal((*rechit)->localPosition());
723  const float distance = std::abs(layer.disk->localZclamped(global_position));
724  if (distance < min_distance) {
725  found = true;
726  min_distance = distance;
727  starting_point = global_position;
728  starting_id = det_id;
729  }
730  }
731 
732  TrajectoryStateOnSurface starting_state;
733  if (found) {
734  starting_state = transient_track.stateOnSurface(starting_point);
735  }
736  return std::make_pair(starting_state, starting_id);
737 }
738 
740  if (not MuonHitHelper::isCSC(det_id))
741  return false;
742  const CSCDetId csc_id{det_id};
743  return (csc_id.station() == 1) or ((csc_id.ring() == 1) or (csc_id.ring() == 4));
744 }
745 
747  const bool is_same_region = track->eta() * layer.region > 0;
748 
749  bool skip = false;
750  if (is_cosmics_) {
751  float p2_in = track->innerMomentum().mag2();
752  float p2_out = track->outerMomentum().mag2();
753  if (isInsideOut(*track))
754  std::swap(p2_in, p2_out);
755  const bool is_outgoing = p2_in > p2_out;
756 
757  skip = (is_outgoing xor is_same_region);
758 
759  } else {
760  // beam scenario
761  skip = not is_same_region;
762  }
763 
764  return skip;
765 }
766 
767 bool GEMEfficiencyAnalyzer::checkBounds(const GlobalPoint& global_point, const Plane& plane) {
768  const LocalPoint&& local_point = plane.toLocal(global_point);
769  const LocalPoint local_point_2d(local_point.x(), local_point.y(), 0.0f);
770  return plane.bounds().inside(local_point_2d);
771 }
772 
774  const std::vector<const GEMChamber*>& chamber_vector) {
775  const GEMEtaPartition* bound = nullptr;
776  for (const GEMChamber* chamber : chamber_vector) {
777  if (not checkBounds(global_point, chamber->surface()))
778  continue;
779 
780  for (const GEMEtaPartition* eta_partition : chamber->etaPartitions()) {
781  if (checkBounds(global_point, eta_partition->surface())) {
782  bound = eta_partition;
783  break;
784  }
785  } // GEMEtaPartition
786  } // GEMChamber
787 
788  return bound;
789 }
790 
791 std::pair<const GEMRecHit*, float> GEMEfficiencyAnalyzer::findClosetHit(const GlobalPoint& dest_global_pos,
793  const GEMEtaPartition* eta_partition) {
794  const StripTopology& topology = eta_partition->specificTopology();
795  const LocalPoint&& dest_local_pos = eta_partition->toLocal(dest_global_pos);
796  const float dest_local_x = dest_local_pos.x();
797  const float dest_local_y = dest_local_pos.y();
798 
799  const GEMRecHit* closest_hit = nullptr;
800  float min_residual_rphi = 1e6;
801 
802  for (auto hit = range.first; hit != range.second; ++hit) {
803  const LocalPoint&& hit_local_pos = hit->localPosition();
804  const float hit_local_phi = topology.stripAngle(eta_partition->strip(hit_local_pos));
805 
806  const float residual_x = dest_local_x - hit_local_pos.x();
807  const float residual_y = dest_local_y - hit_local_pos.y();
808  const float residual_rphi = std::cos(hit_local_phi) * residual_x + std::sin(hit_local_phi) * residual_y;
809 
810  if (std::abs(residual_rphi) < std::abs(min_residual_rphi)) {
811  min_residual_rphi = residual_rphi;
812  closest_hit = &(*hit);
813  }
814  }
815 
816  return std::make_pair(closest_hit, min_residual_rphi);
817 }
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
#define LogDebug(id)
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)