File indexing completed on 2024-09-11 04:33:27
0001 #include "Validation/MuonGEMRecHits/plugins/GEMRecHitValidation.h"
0002 #include "DataFormats/Common/interface/Handle.h"
0003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0004 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
0005
0006 GEMRecHitValidation::GEMRecHitValidation(const edm::ParameterSet& pset)
0007 : GEMBaseValidation(pset, "GEMRecHitsValidation") {
0008 const auto& rechit_pset = pset.getParameterSet("gemRecHit");
0009 const auto& rechit_tag = rechit_pset.getParameter<edm::InputTag>("inputTag");
0010 rechit_token_ = consumes<GEMRecHitCollection>(rechit_tag);
0011
0012 const auto& simhit_pset = pset.getParameterSet("gemSimHit");
0013 const auto& simhit_tag = simhit_pset.getParameter<edm::InputTag>("inputTag");
0014
0015 const auto& digisimlink_tag = pset.getParameter<edm::InputTag>("gemDigiSimLink");
0016 digisimlink_token_ = consumes<edm::DetSetVector<GEMDigiSimLink>>(digisimlink_tag);
0017
0018 simhit_token_ = consumes<edm::PSimHitContainer>(simhit_tag);
0019 geomToken_ = esConsumes<GEMGeometry, MuonGeometryRecord>();
0020 geomTokenBeginRun_ = esConsumes<GEMGeometry, MuonGeometryRecord, edm::Transition::BeginRun>();
0021 }
0022
0023 GEMRecHitValidation::~GEMRecHitValidation() {}
0024
0025 void GEMRecHitValidation::bookHistograms(DQMStore::IBooker& booker, edm::Run const& run, edm::EventSetup const& setup) {
0026 const GEMGeometry* gem = &setup.getData(geomTokenBeginRun_);
0027
0028
0029 booker.setCurrentFolder("GEM/RecHits");
0030
0031 TString cls_title = "Cluster Size Distribution";
0032 TString cls_x_title = "Cluster size";
0033
0034 if (detail_plot_) {
0035 me_detail_cls_total_ = booker.book1D("cls", cls_title + ";" + cls_x_title + ";" + "Entries", 10, 0.5, 10.5);
0036
0037 for (const auto& station : gem->regions()[0]->stations()) {
0038 Int_t station_id = station->station();
0039 for (const auto& roll : station->superChambers()[0]->chambers()[0]->etaPartitions()) {
0040 Int_t ieta = roll->id().ieta();
0041 ME2IdsKey key{station_id, ieta};
0042 me_detail_cls_roll_[key] = booker.book1D(Form("cls_GE%d1-E%d", station_id, ieta),
0043 Form("Cluster Size Distribution : GE%d1-E%d", station_id, ieta),
0044 10,
0045 0.5,
0046 10.5);
0047 }
0048 }
0049
0050 for (const auto& region : gem->regions()) {
0051 Int_t region_id = region->region();
0052
0053 for (const auto& station : region->stations()) {
0054 Int_t station_id = station->station();
0055
0056 const auto& superChamberVec = station->superChambers();
0057 if (superChamberVec.empty() || superChamberVec[0] == nullptr) {
0058 edm::LogError(kLogCategory_) << "Super chambers missing or null for region = " << region_id
0059 << " and station = " << station_id;
0060 } else {
0061 for (const auto& chamber : superChamberVec[0]->chambers()) {
0062 Int_t layer_id = chamber->id().layer();
0063
0064 for (const auto& roll : chamber->etaPartitions()) {
0065 Int_t ieta = roll->id().ieta();
0066 ME4IdsKey key4{region_id, station_id, layer_id, ieta};
0067
0068 me_detail_cls_[key4] = bookHist1D(booker, key4, "cls", "Cluster Size Distribution", 11, -0.5, 10.5);
0069 }
0070 }
0071 }
0072 }
0073 }
0074 }
0075
0076
0077 for (const auto& station : gem->regions()[0]->stations()) {
0078 Int_t station_id = station->station();
0079 for (const auto& roll : station->superChambers()[0]->chambers()[0]->etaPartitions()) {
0080 Int_t ieta = roll->id().ieta();
0081 ME2IdsKey key{station_id, ieta};
0082
0083 me_residual_y_[key] = booker.book1D(Form("residual_y_GE%d1-E%d", station_id, ieta),
0084 Form("Residual in Y : GE%d1-E%d; Residual in Y [cm]", station_id, ieta),
0085 60,
0086 -15,
0087 15);
0088
0089 me_residual_rphi_[key] =
0090 booker.book1D(Form("residual_rphi_GE%d1-E%d", station_id, ieta),
0091 Form("Residual in R #times #phi : GE%d1-E%d; Residual in r #times #phi [cm]", station_id, ieta),
0092 60,
0093 -15,
0094 15);
0095 }
0096 }
0097
0098 if (detail_plot_) {
0099 for (const auto& region : gem->regions()) {
0100 Int_t region_id = region->region();
0101
0102 for (const auto& station : region->stations()) {
0103 Int_t station_id = station->station();
0104
0105 const auto& superChamberVec = station->superChambers();
0106 if (!superChamberVec.empty() && superChamberVec[0] != nullptr) {
0107 for (const auto& chamber : superChamberVec[0]->chambers()) {
0108 Int_t layer_id = chamber->id().layer();
0109
0110 for (const auto& roll : chamber->etaPartitions()) {
0111 Int_t ieta = roll->id().ieta();
0112 ME4IdsKey key4{region_id, station_id, layer_id, ieta};
0113
0114 me_detail_residual_y_[key4] =
0115 bookHist1D(booker, key4, "residual_y", "Residual in y", 60, -15, 15, "Residual in y [cm]");
0116
0117 me_detail_residual_rphi_[key4] = bookHist1D(booker,
0118 key4,
0119 "residual_rphi",
0120 "Residual in r #times #phi",
0121 60,
0122 -15,
0123 15,
0124 "Residual in r #times #phi [cm]");
0125 }
0126 }
0127 }
0128 }
0129 }
0130 }
0131
0132
0133 if (detail_plot_) {
0134 for (const auto& station : gem->regions()[0]->stations()) {
0135 Int_t station_id = station->station();
0136 for (const auto& roll : station->superChambers()[0]->chambers()[0]->etaPartitions()) {
0137 Int_t ieta = roll->id().ieta();
0138 ME2IdsKey key{station_id, ieta};
0139
0140 me_detail_pull_x_[key] = booker.book1D(
0141 Form("pull_x_GE%d1-E%d", station_id, ieta), Form("Pull in X : GE%d1-E%d", station_id, ieta), 60, -3, 3);
0142
0143 me_detail_pull_y_[key] = booker.book1D(
0144 Form("pull_y_GE%d1-E%d", station_id, ieta), Form("Pull in Y : GE%d1-E%d", station_id, ieta), 60, -3, 3);
0145 }
0146 }
0147
0148 for (const auto& region : gem->regions()) {
0149 Int_t region_id = region->region();
0150
0151 for (const auto& station : region->stations()) {
0152 Int_t station_id = station->station();
0153
0154 const auto& superChamberVec = station->superChambers();
0155 if (!superChamberVec.empty() && superChamberVec[0] != nullptr) {
0156 for (const auto& chamber : superChamberVec[0]->chambers()) {
0157 Int_t layer_id = chamber->id().layer();
0158
0159 for (const auto& roll : chamber->etaPartitions()) {
0160 Int_t ieta = roll->id().ieta();
0161 ME4IdsKey key4{region_id, station_id, layer_id, ieta};
0162
0163 me_detail_pull_x_la_[key4] = bookHist1D(booker, key4, "pull_x", "Pull in x", 60, -3, 3);
0164
0165 me_detail_pull_y_la_[key4] = bookHist1D(booker, key4, "pull_y", "Pull in y", 60, -3, 3);
0166 }
0167 }
0168 }
0169 }
0170 }
0171 }
0172
0173
0174 for (const auto& region : gem->regions()) {
0175 Int_t region_id = region->region();
0176
0177 if (detail_plot_)
0178 me_detail_occ_zr_[region_id] = bookZROccupancy(booker, region_id, "rechit", "RecHit");
0179
0180 for (const auto& station : region->stations()) {
0181 Int_t station_id = station->station();
0182 ME2IdsKey key2{region_id, station_id};
0183
0184 if (detail_plot_)
0185 me_detail_rechit_occ_det_[key2] = bookDetectorOccupancy(booker, key2, station, "sim_matched", "Matched RecHit");
0186
0187 const auto& superChamberVec = station->superChambers();
0188 if (!superChamberVec.empty() && superChamberVec[0] != nullptr) {
0189 for (const auto& chamber : superChamberVec[0]->chambers()) {
0190 Int_t layer_id = chamber->id().layer();
0191 ME3IdsKey key3{region_id, station_id, layer_id};
0192
0193 Int_t num_eta_partitions = chamber->nEtaPartitions();
0194
0195 me_rechit_occ_eta_[key3] = bookHist1D(booker,
0196 key3,
0197 "sim_matched_occ_eta",
0198 "Matched RecHit Eta Occupancy",
0199 16,
0200 eta_range_[station_id * 2 + 0],
0201 eta_range_[station_id * 2 + 1],
0202 "|#eta|");
0203
0204 me_rechit_occ_phi_[key3] =
0205 bookHist1D(booker, key3, "sim_matched_occ_phi", "Matched RecHit Phi Occupancy", 36, -5, 355, "#phi");
0206
0207 if (detail_plot_) {
0208 me_detail_total_rechit_[key3] =
0209 bookHist1D(booker, key3, "total_rechit", "Number of rec hits per event", 25, -0.5, 24.5);
0210
0211 me_detail_occ_pid_[key3] = bookPIDHist(booker, key3, "sim_occ_pid", "Number of entreis for each particle");
0212
0213 me_detail_occ_ieta_[key3] = bookHist1D(booker,
0214 key3,
0215 "occ_ieta",
0216 "Rechit Occupancy per eta partition",
0217 num_eta_partitions,
0218 0.5,
0219 num_eta_partitions + 0.5);
0220
0221 me_detail_occ_phi_[key3] = bookHist1D(booker, key3, "occ_phi", "Rechit Phi Occupancy", 108, -5, 355);
0222
0223 me_detail_occ_xy_[key3] = bookXYOccupancy(booker, key3, "rechit", "RecHit");
0224
0225 me_detail_occ_polar_[key3] = bookPolarOccupancy(booker, key3, "rechit", "RecHit");
0226 }
0227 }
0228 }
0229 }
0230 }
0231 }
0232
0233 Bool_t GEMRecHitValidation::matchRecHitAgainstSimHit(GEMRecHitCollection::const_iterator rechit, Int_t simhit_strip) {
0234 Int_t cls = rechit->clusterSize();
0235 Int_t rechit_first_strip = rechit->firstClusterStrip();
0236
0237 if (cls == 1) {
0238 return simhit_strip == rechit_first_strip;
0239 } else {
0240 Int_t rechit_last_strip = rechit_first_strip + cls - 1;
0241 return (simhit_strip >= rechit_first_strip) and (simhit_strip <= rechit_last_strip);
0242 }
0243 }
0244
0245 void GEMRecHitValidation::analyze(const edm::Event& event, const edm::EventSetup& setup) {
0246 const GEMGeometry* gem = &setup.getData(geomToken_);
0247
0248 edm::Handle<edm::DetSetVector<GEMDigiSimLink>> digiSimLink;
0249 event.getByToken(digisimlink_token_, digiSimLink);
0250 if (not digiSimLink.isValid()) {
0251 edm::LogError(kLogCategory_) << "Failed to get GEMDigiSimLink." << std::endl;
0252 return;
0253 }
0254
0255 edm::Handle<edm::PSimHitContainer> simhit_container;
0256 event.getByToken(simhit_token_, simhit_container);
0257 if (not simhit_container.isValid()) {
0258 edm::LogError(kLogCategory_) << "Failed to get PSimHitContainer." << std::endl;
0259 return;
0260 }
0261
0262 edm::Handle<GEMRecHitCollection> rechit_collection;
0263 event.getByToken(rechit_token_, rechit_collection);
0264 if (not rechit_collection.isValid()) {
0265 edm::LogError(kLogCategory_) << "Failed to get GEMRecHitCollection" << std::endl;
0266 return;
0267 }
0268
0269 std::map<ME3IdsKey, Int_t> total_rechit;
0270 for (const auto& rechit : *rechit_collection) {
0271 GEMDetId gem_id{rechit.gemId()};
0272 Int_t region_id = gem_id.region();
0273 Int_t station_id = gem_id.station();
0274 Int_t layer_id = gem_id.layer();
0275 Int_t ieta = gem_id.ieta();
0276 ME4IdsKey key4{region_id, station_id, layer_id, ieta};
0277
0278 ME2IdsKey key{station_id, ieta};
0279 ME2IdsKey key2{region_id, station_id};
0280 ME3IdsKey key3{region_id, station_id, layer_id};
0281
0282 const BoundPlane& surface = gem->idToDet(gem_id)->surface();
0283 GlobalPoint&& rechit_global_pos = surface.toGlobal(rechit.localPosition());
0284
0285 Float_t rechit_g_x = rechit_global_pos.x();
0286 Float_t rechit_g_y = rechit_global_pos.y();
0287 Float_t rechit_g_abs_z = std::fabs(rechit_global_pos.z());
0288 Float_t rechit_g_r = rechit_global_pos.perp();
0289 Float_t rechit_g_phi = toDegree(rechit_global_pos.phi());
0290
0291 Int_t first_strip = rechit.firstClusterStrip();
0292 Int_t cls = rechit.clusterSize();
0293 cls = cls > 10 ? 10 : cls;
0294
0295 total_rechit[key3]++;
0296
0297 if (detail_plot_) {
0298 me_detail_cls_total_->Fill(cls);
0299 me_detail_cls_[key4]->Fill(cls);
0300 me_detail_cls_roll_[key]->Fill(cls);
0301 me_detail_occ_ieta_[key3]->Fill(ieta);
0302 me_detail_occ_phi_[key3]->Fill(rechit_g_phi);
0303 me_detail_occ_zr_[region_id]->Fill(rechit_g_abs_z, rechit_g_r);
0304 me_detail_occ_xy_[key3]->Fill(rechit_g_x, rechit_g_y);
0305 me_detail_occ_polar_[key3]->Fill(rechit_g_phi, rechit_g_r);
0306 }
0307
0308 auto links = digiSimLink->find(gem_id);
0309
0310 if (links == digiSimLink->end())
0311 continue;
0312 std::map<Int_t, Int_t> pid_count;
0313
0314 for (Int_t strip = first_strip; strip < first_strip + cls; strip++) {
0315 for (const auto& link : *links) {
0316 Int_t link_strip = link.getStrip();
0317 if (link_strip == strip) {
0318 Int_t pid = link.getParticleType();
0319 pid_count[pid]++;
0320 break;
0321 }
0322 }
0323 }
0324 if (detail_plot_) {
0325 Int_t max_pid = 0;
0326 Int_t max_count = 0;
0327 for (auto& [pid, count] : pid_count) {
0328 if (max_count < count) {
0329 max_pid = pid;
0330 max_count = count;
0331 }
0332 }
0333 Int_t pid_idx = getPidIdx(max_pid);
0334 me_detail_occ_pid_[key3]->Fill(pid_idx);
0335 }
0336 }
0337
0338 if (detail_plot_) {
0339 for (auto [key, num_total_rechit] : total_rechit) {
0340 me_detail_total_rechit_[key]->Fill(num_total_rechit);
0341 }
0342 }
0343
0344
0345 for (const auto& simhit : *simhit_container.product()) {
0346 if (gem->idToDet(simhit.detUnitId()) == nullptr) {
0347 edm::LogError(kLogCategory_) << "MuonGEMHit didn't matched with GEMGeometry." << std::endl;
0348 continue;
0349 }
0350
0351 GEMDetId simhit_gemid{simhit.detUnitId()};
0352 const BoundPlane& surface = gem->idToDet(simhit_gemid)->surface();
0353
0354 Int_t region_id = simhit_gemid.region();
0355 Int_t station_id = simhit_gemid.station();
0356 Int_t layer_id = simhit_gemid.layer();
0357 Int_t chamber_id = simhit_gemid.chamber();
0358 Int_t ieta = simhit_gemid.ieta();
0359 Int_t num_layers = simhit_gemid.nlayers();
0360
0361 ME2IdsKey key{station_id, ieta};
0362 ME2IdsKey key2{region_id, station_id};
0363 ME3IdsKey key3{region_id, station_id, layer_id};
0364 ME4IdsKey key4{region_id, station_id, layer_id, ieta};
0365
0366 const LocalPoint& simhit_local_pos = simhit.localPosition();
0367 const GlobalPoint& simhit_global_pos = surface.toGlobal(simhit_local_pos);
0368
0369 Float_t simhit_g_abs_eta = std::fabs(simhit_global_pos.eta());
0370 Float_t simhit_g_phi = toDegree(simhit_global_pos.phi());
0371
0372 Int_t det_occ_bin_x = getDetOccBinX(num_layers, chamber_id, layer_id);
0373
0374 auto simhit_trackId = simhit.trackId();
0375
0376 auto links = digiSimLink->find(simhit_gemid);
0377 if (links == digiSimLink->end())
0378 continue;
0379
0380 Int_t simhit_strip = -1;
0381 for (const auto& link : *links) {
0382 if (simhit_trackId == link.getTrackId()) {
0383 simhit_strip = link.getStrip();
0384 break;
0385 }
0386 }
0387
0388 GEMRecHitCollection::range range = rechit_collection->get(simhit_gemid);
0389 for (auto rechit = range.first; rechit != range.second; ++rechit) {
0390 if (gem->idToDet(rechit->gemId()) == nullptr) {
0391 edm::LogError(kLogCategory_) << "GEMRecHit didn't matched with GEMGeometry." << std::endl;
0392 continue;
0393 }
0394
0395 if (not isMuonSimHit(simhit))
0396 continue;
0397
0398 if (matchRecHitAgainstSimHit(rechit, simhit_strip)) {
0399 const LocalPoint& rechit_local_pos = rechit->localPosition();
0400
0401 Float_t resolution_x = std::sqrt(rechit->localPositionError().xx());
0402 Float_t resolution_y = std::sqrt(rechit->localPositionError().yy());
0403
0404 Float_t residual_x = rechit_local_pos.x() - simhit_local_pos.x();
0405 Float_t residual_y = rechit_local_pos.y() - simhit_local_pos.y();
0406 Float_t residual_r = sqrt(pow(residual_x, 2) + pow(residual_y, 2));
0407 Float_t residual_phi = rechit_local_pos.phi() - simhit_local_pos.phi();
0408 Float_t residual_rphi = residual_r * residual_phi;
0409
0410 Float_t pull_x = residual_x / resolution_x;
0411 Float_t pull_y = residual_y / resolution_y;
0412
0413 me_residual_y_[key]->Fill(residual_y);
0414 me_residual_rphi_[key]->Fill(residual_rphi);
0415
0416 me_rechit_occ_eta_[key3]->Fill(simhit_g_abs_eta);
0417 me_rechit_occ_phi_[key3]->Fill(simhit_g_phi);
0418
0419 if (detail_plot_) {
0420 me_detail_rechit_occ_det_[key2]->Fill(det_occ_bin_x, ieta);
0421
0422 me_detail_residual_y_[key4]->Fill(residual_y);
0423 me_detail_residual_rphi_[key4]->Fill(residual_rphi);
0424
0425 me_detail_pull_x_[key]->Fill(pull_x);
0426 me_detail_pull_y_[key]->Fill(pull_y);
0427 me_detail_pull_x_la_[key4]->Fill(pull_x);
0428 me_detail_pull_y_la_[key4]->Fill(pull_y);
0429 }
0430
0431
0432
0433 break;
0434
0435 }
0436 }
0437 }
0438 }