CMS 3D CMS Logo

GEMPadDigiClusterValidation.cc
Go to the documentation of this file.
2 #include <TMath.h>
3 
5  : GEMBaseValidation(pset, "GEMPadDigiClusterValidation") {
6  const auto& pad_cluster_pset = pset.getParameterSet("gemPadCluster");
7  const auto& pad_cluster_tag = pad_cluster_pset.getParameter<edm::InputTag>("inputTag");
8 
9  const auto& simhit_pset = pset.getParameterSet("gemSimHit");
10  const auto& simhit_tag = simhit_pset.getParameter<edm::InputTag>("inputTag");
11  simhit_token_ = consumes<edm::PSimHitContainer>(simhit_tag);
12 
13  const auto& digisimlink_tag = pset.getParameter<edm::InputTag>("gemDigiSimLink");
14  digisimlink_token_ = consumes<edm::DetSetVector<GEMDigiSimLink>>(digisimlink_tag);
15 
16  pad_cluster_token_ = consumes<GEMPadDigiClusterCollection>(pad_cluster_tag);
17  geomToken_ = esConsumes<GEMGeometry, MuonGeometryRecord>();
18  geomTokenBeginRun_ = esConsumes<GEMGeometry, MuonGeometryRecord, edm::Transition::BeginRun>();
19 }
20 
22  edm::Run const& Run,
23  edm::EventSetup const& setup) {
24  const auto& gemH = setup.getHandle(geomTokenBeginRun_);
25  if (!gemH.isValid()) {
26  edm::LogError(kLogCategory_) << "Failed to initialize GEM geometry.";
27  return;
28  }
29  const GEMGeometry* gem = gemH.product();
30  // NOTE Occupancy
31  booker.setCurrentFolder("GEM/PadCluster");
32 
33  TString cls_title = "Cluster Size Distribution";
34  TString cls_x_title = "Cluster size";
35 
36  me_cls_ = booker.book1D("cls", cls_title + ";" + cls_x_title + ";" + "Entries", 10, 0, 10);
37 
38  // NOTE Occupancy
39  for (const auto& region : gem->regions()) {
40  Int_t region_id = region->region();
41 
42  if (detail_plot_)
43  me_detail_occ_zr_.emplace(region_id, bookZROccupancy(booker, region_id, "pad", "Pad Cluster"));
44 
45  for (const auto& station : region->stations()) {
46  Int_t station_id = station->station();
47  ME2IdsKey key2{region_id, station_id};
48 
49  if (detail_plot_) {
50  me_detail_occ_det_[key2] = bookDetectorOccupancy(booker, key2, station, "pad", "Pad Cluster");
52  bookDetectorOccupancy(booker, key2, station, "sim_matched", "Pad Cluster");
53  }
54 
55  const auto& superChamberVec = station->superChambers();
56  if (superChamberVec.empty()) {
57  edm::LogError(kLogCategory_) << "Super chambers missing for region = " << region_id
58  << " and station = " << station_id;
59  continue;
60  }
61  const GEMSuperChamber* super_chamber = superChamberVec.front();
62  if (super_chamber == nullptr) {
63  edm::LogError(kLogCategory_) << "Failed to find super chamber for region = " << region_id
64  << " and station = " << station_id;
65  continue;
66  }
67  for (const auto& chamber : super_chamber->chambers()) {
68  Int_t layer_id = chamber->id().layer();
69  ME3IdsKey key3{region_id, station_id, layer_id};
70 
71  const auto& etaPartitionVec = chamber->etaPartitions();
72  if (etaPartitionVec.empty() || etaPartitionVec.front() == nullptr) {
74  << "Eta partition missing or null for region, station, super chamber, chamber = (" << region_id << ", "
75  << station_id << ", " << super_chamber->id() << ", " << chamber->id() << ")";
76  continue;
77  }
78  Int_t num_pads = etaPartitionVec.front()->npads();
79 
80  me_total_cluster_[key3] =
81  bookHist1D(booker, key3, "total_pad_cluster", "Number of pad digi cluster per event", 20, 0, 20);
82 
83  me_pad_cluster_occ_eta_[key3] = bookHist1D(booker,
84  key3,
85  "sim_matched_occ_eta",
86  "Matched Pad Cluster Eta Occupancy",
87  16,
88  eta_range_[station_id * 2 + 0],
89  eta_range_[station_id * 2 + 1],
90  "#eta");
91 
93  booker, key3, "sim_matched_occ_phi", "Matched Pad Cluster Phi Occupancy", 36, -5, 355, "#phi [degrees]");
94 
95  if (detail_plot_) {
96  me_detail_occ_xy_[key3] = bookXYOccupancy(booker, key3, "pad", "Pad Cluster");
97 
98  me_detail_occ_phi_pad_[key3] = bookHist2D(booker,
99  key3,
100  "occ_phi_pad",
101  "Pad Cluster Occupancy",
102  280,
103  -M_PI,
104  M_PI,
105  num_pads / 2,
106  0,
107  num_pads,
108  "#phi [rad]",
109  "Pad number");
110 
111  me_detail_occ_pad_[key3] =
112  bookHist1D(booker, key3, "occ_pad", "Pad Cluster Occupancy", num_pads, 0, num_pads, "Pad number");
113  }
114  } // end loop over layer ids
115  } // end loop over station ids
116  } // end loop over region ids
117 
118  // NOTE Bunch Crossing
119  if (detail_plot_) {
120  for (const auto& region : gem->regions()) {
121  Int_t region_id = region->region();
122  for (const auto& station : region->stations()) {
123  Int_t station_id = station->station();
124 
125  const auto& superChamberVec = station->superChambers();
126  if (superChamberVec.empty()) {
127  edm::LogError(kLogCategory_) << "Super chambers missing for region = " << region_id
128  << " and station = " << station_id;
129  continue;
130  }
131  const GEMSuperChamber* super_chamber = superChamberVec.front();
132  if (super_chamber == nullptr) {
133  edm::LogError(kLogCategory_) << "Failed to find super chamber for region = " << region_id
134  << " and station = " << station_id;
135  continue;
136  }
137  for (const auto& chamber : super_chamber->chambers()) {
138  Int_t layer_id = chamber->id().layer();
139  ME3IdsKey key3(region_id, station_id, layer_id);
140  me_detail_bx_[key3] =
141  bookHist1D(booker, key3, "bx", "Pad Cluster Bunch Crossing", 5, -2, 3, "Bunch crossing");
142  } // chamber loop
143  } // station loop
144  } // region loop
145  } // detail plot
146 }
147 
149 
151  Int_t simhit_pad) {
152  for (auto pad : cluster->pads()) {
153  if (pad == simhit_pad) {
154  return true;
155  }
156  }
157  return false;
158 }
159 
161  const auto& gemH = setup.getHandle(geomToken_);
162  if (!gemH.isValid()) {
163  edm::LogError(kLogCategory_) << "Failed to initialize GEM geometry.";
164  return;
165  }
166  const GEMGeometry* gem = gemH.product();
167 
169  event.getByToken(pad_cluster_token_, collection);
170  if (not collection.isValid()) {
171  edm::LogError(kLogCategory_) << "Cannot get pads by label GEMPadToken.";
172  return;
173  }
174 
176  event.getByToken(digisimlink_token_, digiSimLink);
177  if (not digiSimLink.isValid()) {
178  edm::LogError(kLogCategory_) << "Failed to get GEMDigiSimLink." << std::endl;
179  return;
180  }
181 
182  edm::Handle<edm::PSimHitContainer> simhit_container;
183  event.getByToken(simhit_token_, simhit_container);
184  if (not simhit_container.isValid()) {
185  edm::LogError(kLogCategory_) << "Failed to get PSimHitContainer." << std::endl;
186  return;
187  }
188 
189  std::map<ME3IdsKey, Int_t> total_cluster;
190  for (auto range_iter = collection->begin(); range_iter != collection->end(); range_iter++) {
191  GEMDetId gemid = (*range_iter).first;
192  const auto& range = (*range_iter).second;
193 
194  if (gem->idToDet(gemid) == nullptr) {
195  edm::LogError(kLogCategory_) << "Getting DetId failed. Discard this gem pad hit. "
196  << "Maybe it comes from unmatched geometry." << std::endl;
197  continue;
198  }
199 
200  const GEMEtaPartition* roll = gem->etaPartition(gemid);
201  const BoundPlane& surface = roll->surface();
202 
203  Int_t region_id = gemid.region();
204  Int_t station_id = gemid.station();
205  Int_t layer_id = gemid.layer();
206  Int_t chamber_id = gemid.chamber();
207  Int_t ieta = gemid.ieta();
208  Int_t num_layers = gemid.nlayers();
209 
210  ME2IdsKey key2(region_id, station_id);
211  ME3IdsKey key3(region_id, station_id, layer_id);
212 
213  for (auto digi = range.first; digi != range.second; ++digi) {
214  const auto& padsVec = digi->pads();
215  if (padsVec.empty()) {
216  edm::LogError(kLogCategory_) << "Pads missing for digi from GEM ID = " << gemid;
217  continue;
218  }
219  Int_t pad = padsVec[0];
220 
221  total_cluster[key3]++;
222 
223  // bunch crossing
224  Int_t bx = digi->bx();
225  Int_t cls = digi->pads().size();
226 
227  const LocalPoint& local_pos = roll->centreOfPad(pad);
228  const GlobalPoint& global_pos = surface.toGlobal(local_pos);
229 
230  Float_t g_r = global_pos.perp();
231  Float_t g_phi = global_pos.phi();
232  Float_t g_x = global_pos.x();
233  Float_t g_y = global_pos.y();
234  Float_t g_abs_z = std::fabs(global_pos.z());
235 
236  Int_t bin_x = getDetOccBinX(num_layers, chamber_id, layer_id);
237 
238  me_cls_->Fill(cls);
239  if (detail_plot_) {
240  me_detail_occ_zr_[region_id]->Fill(g_abs_z, g_r);
241  me_detail_occ_det_[key2]->Fill(bin_x, ieta);
242  me_detail_occ_xy_[key3]->Fill(g_x, g_y);
243  me_detail_occ_phi_pad_[key3]->Fill(g_phi, pad);
244  me_detail_occ_pad_[key3]->Fill(pad);
245  me_detail_bx_[key3]->Fill(bx);
246  } // detail_plot_
247  }
248  } // end loop over range iters
249 
250  for (const auto& region : gem->regions()) {
251  Int_t region_id = region->region();
252  for (const auto& station : region->stations()) {
253  Int_t station_id = station->station();
254  const auto& superChamberVec = station->superChambers();
255  if (superChamberVec.empty()) {
256  edm::LogError(kLogCategory_) << "Super chambers missing for region = " << region_id
257  << " and station = " << station_id;
258  continue;
259  }
260  const GEMSuperChamber* super_chamber = superChamberVec.front();
261  if (super_chamber == nullptr) {
262  edm::LogError(kLogCategory_) << "Failed to find super chamber for region = " << region_id
263  << " and station = " << station_id;
264  continue;
265  }
266  for (const auto& chamber : super_chamber->chambers()) {
267  Int_t layer_id = chamber->id().layer();
268  ME3IdsKey key3{region_id, station_id, layer_id};
269  me_total_cluster_[key3]->Fill(total_cluster[key3]);
270  }
271  }
272  }
273 
274  // NOTE
275  for (const auto& simhit : *simhit_container.product()) {
276  if (not isMuonSimHit(simhit))
277  continue;
278  if (gem->idToDet(simhit.detUnitId()) == nullptr) {
279  edm::LogError(kLogCategory_) << "SimHit did not match with GEMGeometry." << std::endl;
280  continue;
281  }
282 
283  GEMDetId simhit_gemid(simhit.detUnitId());
284 
285  Int_t region_id = simhit_gemid.region();
286  Int_t station_id = simhit_gemid.station();
287  Int_t layer_id = simhit_gemid.layer();
288  Int_t chamber_id = simhit_gemid.chamber();
289  Int_t ieta = simhit_gemid.ieta();
290  Int_t num_layers = simhit_gemid.nlayers();
291 
292  ME2IdsKey key2{region_id, station_id};
293  ME3IdsKey key3{region_id, station_id, layer_id};
294 
295  const GEMEtaPartition* roll = gem->etaPartition(simhit_gemid);
296 
297  const auto& simhit_local_pos = simhit.localPosition();
298  const auto& simhit_global_pos = roll->surface().toGlobal(simhit_local_pos);
299 
300  Float_t simhit_g_eta = std::abs(simhit_global_pos.eta());
301  Float_t simhit_g_phi = toDegree(simhit_global_pos.phi());
302 
303  auto simhit_trackId = simhit.trackId();
304 
305  Int_t bin_x = getDetOccBinX(num_layers, chamber_id, layer_id);
306 
307  auto links = digiSimLink->find(simhit_gemid);
308  if (links == digiSimLink->end())
309  continue;
310 
311  Int_t simhit_strip = -1;
312  for (const auto& link : *links) {
313  if (simhit_trackId == link.getTrackId()) {
314  simhit_strip = link.getStrip();
315  break;
316  }
317  }
318  Int_t simhit_pad = roll->padOfStrip(simhit_strip);
319  auto range = collection->get(simhit_gemid);
320  for (auto cluster = range.first; cluster != range.second; ++cluster) {
321  if (matchClusterAgainstSimHit(cluster, simhit_pad)) {
322  me_pad_cluster_occ_eta_[key3]->Fill(simhit_g_eta);
323  me_pad_cluster_occ_phi_[key3]->Fill(simhit_g_phi);
324  if (detail_plot_) {
325  me_detail_pad_cluster_occ_det_[key2]->Fill(bin_x, ieta);
326  }
327  break;
328  }
329  }
330  } // simhit_container loop
331 }
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")
constexpr int station() const
Definition: GEMDetId.h:179
T perp() const
Definition: PV3DBase.h:69
edm::EDGetTokenT< edm::DetSetVector< GEMDigiSimLink > > digisimlink_token_
constexpr int region() const
Definition: GEMDetId.h:171
Bool_t matchClusterAgainstSimHit(GEMPadDigiClusterCollection::const_iterator, Int_t)
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:32
T z() const
Definition: PV3DBase.h:61
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
Bool_t isMuonSimHit(const PSimHit &)
T const * product() const
Definition: Handle.h:70
float padOfStrip(int strip) const
returns FRACTIONAL pad number [0.,npads) for an integer strip [0,nstrip-1]
edm::EDGetTokenT< GEMPadDigiClusterCollection > pad_cluster_token_
Log< level::Error, false > LogError
dqm::impl::MonitorElement * bookZROccupancy(DQMStore::IBooker &booker, Int_t region_id, const char *name_prfix, const char *title_prefix)
constexpr int layer() const
Definition: GEMDetId.h:190
constexpr int chamber() const
Definition: GEMDetId.h:183
void Fill(long long x)
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)
edm::EDGetTokenT< edm::PSimHitContainer > simhit_token_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< Double_t > eta_range_
dqm::impl::MonitorElement * bookHist2D(DQMStore::IBooker &booker, const T &key, const char *name, const char *title, Int_t nbinsx, Double_t xlow, Double_t xup, Int_t nbinsy, Double_t ylow, Double_t yup, const char *x_title="", const char *y_title="")
#define M_PI
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:79
constexpr int ieta() const
Definition: GEMDetId.h:199
GEMDetId id() const
Return the GEMDetId of this super chamber.
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
void analyze(const edm::Event &, const edm::EventSetup &) override
std::vector< DigiType >::const_iterator const_iterator
bool isValid() const
Definition: HandleBase.h:70
LocalPoint centreOfPad(int pad) const
edm::ESGetToken< GEMGeometry, MuonGeometryRecord > geomToken_
edm::ESGetToken< GEMGeometry, MuonGeometryRecord > geomTokenBeginRun_
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
std::tuple< Int_t, Int_t > ME2IdsKey
Float_t toDegree(Float_t radian)
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)
const std::string kLogCategory_
constexpr int nlayers() const
Definition: GEMDetId.h:213
const std::vector< const GEMChamber * > & chambers() const
Return the chambers in the super chamber.
GEMPadDigiClusterValidation(const edm::ParameterSet &)
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)