CMS 3D CMS Logo

GEMSimHitValidation.cc
Go to the documentation of this file.
4 
6  : GEMBaseValidation(pset, "GEMSimHitValidation") {
7  const auto& simhit_pset = pset.getParameterSet("gemSimHit");
8  const auto& simhit_tag = simhit_pset.getParameter<edm::InputTag>("inputTag");
9  simhit_token_ = consumes<edm::PSimHitContainer>(simhit_tag);
10 
11  tof_range_ = pset.getUntrackedParameter<std::vector<Double_t> >("TOFRange");
12  geomToken_ = esConsumes<GEMGeometry, MuonGeometryRecord>();
13  geomTokenBeginRun_ = esConsumes<GEMGeometry, MuonGeometryRecord, edm::Transition::BeginRun>();
14 }
15 
17 
19  const GEMGeometry* gem = &setup.getData(geomTokenBeginRun_);
20 
21  // NOTE Time of flight
22  booker.setCurrentFolder("GEM/SimHits");
23 
24  TString tof_xtitle = "Time of flight [ns]";
25  TString tof_ytitle = "Entries";
26 
27  for (const auto& region : gem->regions()) {
28  Int_t region_id = region->region();
29 
30  for (const auto& station : region->stations()) {
31  Int_t station_id = station->station();
32 
33  const auto [tof_min, tof_max] = getTOFRange(station_id);
34  ME2IdsKey key2{region_id, station_id};
35 
36  me_tof_mu_[key2] = bookHist1D(
37  booker, key2, "sim_tof_muon", "SimHit TOF (Muon only)", 20, tof_min, tof_max, tof_xtitle, tof_ytitle);
38 
39  me_tof_others_[key2] = bookHist1D(
40  booker, key2, "sim_tof_others", "SimHit TOF (Other Particles)", 20, tof_min, tof_max, tof_xtitle, tof_ytitle);
41  } // station loop
42  } // region loop
43 
44  if (detail_plot_) {
45  for (const auto& region : gem->regions()) {
46  Int_t region_id = region->region();
47 
48  for (const auto& station : region->stations()) {
49  Int_t station_id = station->station();
50 
51  const auto [tof_min, tof_max] = getTOFRange(station_id);
52  const auto& superChamberVec = station->superChambers();
53  if (superChamberVec.empty() || superChamberVec.front() == nullptr) {
54  edm::LogError(kLogCategory_) << "Super chambers missing or null for region = " << region_id
55  << " and station = " << station_id;
56  } else {
57  const GEMSuperChamber* super_chamber = superChamberVec.front();
58 
59  for (const auto& chamber : super_chamber->chambers()) {
60  Int_t layer_id = chamber->id().layer();
61  ME3IdsKey key3{region_id, station_id, layer_id};
62 
63  me_detail_tof_[key3] = bookHist1D(
64  booker, key3, "sim_tof", "Time of Flight of Muon SimHits", 40, tof_min, tof_max, tof_xtitle, tof_ytitle);
65 
67  booker, key3, "sim_tof_muon", "SimHit TOF (Muon only)", 40, tof_min, tof_max, tof_xtitle, tof_ytitle);
68  } // chamber loop
69  } // end else
70  } // station loop
71  } // region loop
72  } // detail plot
73 
74  // NOTE Energy Loss
75  TString eloss_xtitle = "Energy loss [eV]";
76  TString eloss_ytitle = "Entries / 0.5 keV";
77 
78  // Demonstrator chamber means we could have a missing station,
79  // process both regions to make sure we include it
80  for (const auto& region : gem->regions()) {
81  for (const auto& station : region->stations()) {
82  Int_t station_id = station->station();
83  if (me_eloss_mu_.find(station_id) != me_eloss_mu_.end())
84  continue;
85 
86  auto eloss_mu_name = TString::Format("sim_eloss_muon_GE%d1", station_id);
87  auto eloss_mu_title = TString::Format("SimHit Energy Loss (Muon only) : GE%d1", station_id);
88 
89  me_eloss_mu_[station_id] =
90  booker.book1D(eloss_mu_name, eloss_mu_title + ";" + eloss_xtitle + ";" + eloss_ytitle, 20, 0.0, 10.0);
91 
92  auto eloss_others_name = TString::Format("sim_eloss_others_GE%d1", station_id);
93  auto eloss_others_title = TString::Format("SimHit Energy Loss (Other Particles) : GE%d1", station_id);
94 
95  me_eloss_others_[station_id] =
96  booker.book1D(eloss_others_name, eloss_others_title + ";" + eloss_xtitle + ";" + eloss_ytitle, 20, 0.0, 10.0);
97  } // station loop
98  } // region loop
99 
100  if (detail_plot_) {
101  for (const auto& region : gem->regions()) {
102  Int_t region_id = region->region();
103  for (const auto& station : region->stations()) {
104  Int_t station_id = station->station();
105  const auto& superChamberVec = station->superChambers();
106  if (superChamberVec.empty() || superChamberVec.front() == nullptr) {
107  edm::LogError(kLogCategory_) << "Super chambers missing or null for region = " << region_id
108  << " and station = " << station_id;
109  } else {
110  for (const auto& chamber : superChamberVec.front()->chambers()) {
111  Int_t layer_id = chamber->id().layer();
112  ME3IdsKey key3{region_id, station_id, layer_id};
113 
115  booker, key3, "sim_eloss", "SimHit Energy Loss", 60, 0.0, 6000.0, eloss_xtitle, eloss_ytitle);
116 
117  me_detail_eloss_mu_[key3] = bookHist1D(booker,
118  key3,
119  "sim_eloss_muon",
120  "SimHit Energy Loss (Muon Only)",
121  60,
122  0.0,
123  6000.0,
124  eloss_xtitle,
125  eloss_ytitle);
126 
127  } // chamber loop
128  } // end else
129  } // station loop
130  } // region loop
131  } // detail plot
132 
133  // NOTE Occupancy
134  for (const auto& region : gem->regions()) {
135  Int_t region_id = region->region();
136 
137  if (detail_plot_)
138  me_detail_occ_zr_[region_id] = bookZROccupancy(booker, region_id, "sim_simhit", "SimHit");
139 
140  for (const auto& station : region->stations()) {
141  Int_t station_id = station->station();
142  ME2IdsKey key2{region_id, station_id};
143 
144  if (detail_plot_) {
145  me_detail_occ_det_[key2] = bookDetectorOccupancy(booker, key2, station, "sim_simhit", "SimHit");
146  me_detail_occ_det_mu_[key2] = bookDetectorOccupancy(booker, key2, station, "sim_muon_simhit", "Muon SimHit");
147  }
148 
149  const auto& superChamberVec = station->superChambers();
150  if (superChamberVec.empty() || superChamberVec.front() == nullptr) {
151  edm::LogError(kLogCategory_) << "Super chambers missing or null for region = " << region_id
152  << " and station = " << station_id;
153  } else {
154  const GEMSuperChamber* super_chamber = superChamberVec.front();
155  for (const auto& chamber : super_chamber->chambers()) {
156  Int_t layer_id = chamber->id().layer();
157  ME3IdsKey key3{region_id, station_id, layer_id};
158 
159  me_occ_eta_mu_[key3] = bookHist1D(booker,
160  key3,
161  "sim_muon_occ_eta",
162  "Muon SimHit Eta Occupancy",
163  16,
164  eta_range_[station_id * 2 + 0],
165  eta_range_[station_id * 2 + 1],
166  "#eta");
167 
168  me_occ_phi_mu_[key3] =
169  bookHist1D(booker, key3, "sim_muon_occ_phi", "Muon SimHit Phi Occupancy", 36, -5, 355, "#phi [degrees]");
170 
171  me_occ_pid_[key3] = bookPIDHist(booker, key3, "sim_occ_pid", "Particle population");
172 
173  if (detail_plot_)
174  me_detail_occ_xy_[key3] = bookXYOccupancy(booker, key3, "sim_simhit", "SimHit");
175  } // layer loop
176  } // end else
177  } // station loop
178  } // region loop
179 }
180 
181 std::tuple<Double_t, Double_t> GEMSimHitValidation::getTOFRange(Int_t station_id) {
182  UInt_t start_index = station_id * 2;
183  Double_t tof_min = tof_range_[start_index];
184  Double_t tof_max = tof_range_[start_index + 1];
185  return std::make_tuple(tof_min, tof_max);
186 }
187 
189  const GEMGeometry* gem = &setup.getData(geomToken_);
190 
191  edm::Handle<edm::PSimHitContainer> simhit_container;
192  event.getByToken(simhit_token_, simhit_container);
193  if (not simhit_container.isValid()) {
194  edm::LogError(kLogCategory_) << "Cannot get GEMHits by Token simhitLabel" << std::endl;
195  return;
196  }
197 
198  for (const auto& simhit : *simhit_container.product()) {
199  const GEMDetId gemid(simhit.detUnitId());
200 
201  if (gem->idToDet(gemid) == nullptr) {
202  edm::LogError(kLogCategory_) << "SimHit did not matched with GEM Geometry." << std::endl;
203  continue;
204  }
205 
206  Int_t region_id = gemid.region();
207  Int_t station_id = gemid.station();
208  Int_t layer_id = gemid.layer();
209  Int_t chamber_id = gemid.chamber();
210  Int_t ieta = gemid.ieta();
211  Int_t num_layers = gemid.nlayers();
212 
213  ME2IdsKey key2{region_id, station_id};
214  ME3IdsKey key3{region_id, station_id, layer_id};
215 
216  GlobalPoint&& simhit_global_pos = gem->idToDet(gemid)->surface().toGlobal(simhit.localPosition());
217 
218  Float_t simhit_g_r = simhit_global_pos.perp();
219  Float_t simhit_g_x = simhit_global_pos.x();
220  Float_t simhit_g_y = simhit_global_pos.y();
221  Float_t simhit_g_abs_z = std::fabs(simhit_global_pos.z());
222  Float_t simhit_g_eta = std::fabs(simhit_global_pos.eta());
223  Float_t simhit_g_phi = toDegree(simhit_global_pos.phi());
224 
225  Float_t energy_loss = kEnergyCF_ * simhit.energyLoss();
226  energy_loss = energy_loss > 10 ? 9.9 : energy_loss;
227  Float_t tof = simhit.timeOfFlight();
228  Int_t pid = simhit.particleType();
229  Int_t pid_idx = getPidIdx(pid);
230 
231  // NOTE Fill MonitorElement
232  Int_t bin_x = getDetOccBinX(num_layers, chamber_id, layer_id);
233 
234  bool is_muon_simhit = isMuonSimHit(simhit);
235  if (is_muon_simhit) {
236  me_tof_mu_[key2]->Fill(tof);
237  me_eloss_mu_[station_id]->Fill(energy_loss);
238  me_occ_eta_mu_[key3]->Fill(simhit_g_eta);
239  me_occ_phi_mu_[key3]->Fill(simhit_g_phi);
240  } else {
241  me_tof_others_[key2]->Fill(tof);
242  me_eloss_others_[station_id]->Fill(energy_loss);
243  }
244 
245  me_occ_pid_[key3]->Fill(pid_idx);
246 
247  if (detail_plot_) {
248  me_detail_tof_[key3]->Fill(tof);
249  me_detail_eloss_[key3]->Fill(energy_loss);
250 
251  me_detail_occ_zr_[region_id]->Fill(simhit_g_abs_z, simhit_g_r);
252  me_detail_occ_det_[key2]->Fill(bin_x, ieta);
253  me_detail_occ_xy_[key3]->Fill(simhit_g_x, simhit_g_y);
254 
255  if (is_muon_simhit) {
256  me_detail_tof_mu_[key3]->Fill(tof);
257  me_detail_eloss_mu_[key3]->Fill(energy_loss);
258  me_detail_occ_det_mu_[key2]->Fill(bin_x, ieta);
259  }
260 
261  } // detail_plot
262  } // simhit loop
263 }
dqm::impl::MonitorElement * bookHist1D(DQMStore::IBooker &booker, const T &key, const char *name, const char *title, Int_t nbinsx, Double_t xlow, Double_t xup, const char *x_title="", const char *y_title="Entries")
T perp() const
Definition: PV3DBase.h:69
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:36
T z() const
Definition: PV3DBase.h:61
GEMSimHitValidation(const edm::ParameterSet &)
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
Bool_t isMuonSimHit(const PSimHit &)
T eta() const
Definition: PV3DBase.h:73
T const * product() const
Definition: Handle.h:70
edm::ESGetToken< GEMGeometry, MuonGeometryRecord > geomToken_
Log< level::Error, false > LogError
dqm::impl::MonitorElement * bookZROccupancy(DQMStore::IBooker &booker, Int_t region_id, const char *name_prfix, const char *title_prefix)
edm::EDGetTokenT< edm::PSimHitContainer > simhit_token_
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
dqm::impl::MonitorElement * bookXYOccupancy(DQMStore::IBooker &booker, const T &key, const char *name_prefix, const char *title_prefix)
std::vector< Double_t > tof_range_
Int_t getPidIdx(Int_t pid)
std::vector< Double_t > eta_range_
edm::ESGetToken< GEMGeometry, MuonGeometryRecord > geomTokenBeginRun_
std::tuple< Double_t, Double_t > getTOFRange(Int_t station_id)
bool isValid() const
Definition: HandleBase.h:70
std::tuple< Int_t, Int_t > ME2IdsKey
Float_t toDegree(Float_t radian)
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
std::tuple< Int_t, Int_t, Int_t > ME3IdsKey
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
Int_t getDetOccBinX(Int_t num_layers, Int_t chamber_id, Int_t layer_id)
void analyze(const edm::Event &, const edm::EventSetup &) override
dqm::impl::MonitorElement * bookPIDHist(DQMStore::IBooker &booker, const T &key, const char *name, const char *title)
const std::string kLogCategory_
const std::vector< const GEMChamber * > & chambers() const
Return the chambers in the super chamber.
Definition: event.py:1
Definition: Run.h:45
dqm::impl::MonitorElement * bookDetectorOccupancy(DQMStore::IBooker &booker, const T &key, const GEMStation *station, const char *name_prfix, const char *title_prefix)