CMS 3D CMS Logo

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