diff --git a/L1Trigger/L1TGEM/plugins/GEMPadDigiProducer.cc b/L1Trigger/L1TGEM/plugins/GEMPadDigiProducer.cc index 961ea4a30e538..a8194c05e4f01 100644 --- a/L1Trigger/L1TGEM/plugins/GEMPadDigiProducer.cc +++ b/L1Trigger/L1TGEM/plugins/GEMPadDigiProducer.cc @@ -19,8 +19,16 @@ #include -/// \class GEMPadDigiProducer -/// producer for GEM trigger pads +/* + \class GEMPadDigiProducer + producer for GEM trigger pads + + In GE1/1: trigger pads are made from neighboring strip digis + in the same eta partition + + In GE2/1: trigger pads are made from neighboring strip digis + in neighboring eta partitions +*/ class GEMPadDigiProducer : public edm::stream::EDProducer<> { public: @@ -49,7 +57,7 @@ class GEMPadDigiProducer : public edm::stream::EDProducer<> { const GEMGeometry* geometry_; }; -GEMPadDigiProducer::GEMPadDigiProducer(const edm::ParameterSet& ps) : geometry_(nullptr) { +GEMPadDigiProducer::GEMPadDigiProducer(const edm::ParameterSet& ps) : use16GE21_(false), geometry_(nullptr) { digis_ = ps.getParameter("InputCollection"); digi_token_ = consumes(digis_); @@ -154,17 +162,18 @@ void GEMPadDigiProducer::buildPads16GE21(const GEMDigiCollection& det_digis, GEM // and stuff them into a set of unique pads (equivalent of OR operation) auto digis = det_digis.get(p->id()); + // proto pads for the odd partitions + for (auto d = digis.first; d != digis.second; ++d) { + proto_pads.emplace(d->strip(), d->bx()); + } + GEMDetId gemId2( p->id().region(), p->id().ring(), p->id().station(), p->id().layer(), p->id().chamber(), p->id().roll() + 1); auto digis2 = det_digis.get(gemId2); - for (auto d = digis.first; d != digis.second; ++d) { - // check if the strip digi in the eta partition below also has a digi - for (auto d2 = digis2.first; d2 != digis2.second; ++d2) { - if (d->strip() == d2->strip()) { - proto_pads.emplace(d->strip(), d->bx()); - } - } + // proto pads for the even partitions + for (auto d = digis2.first; d != digis2.second; ++d) { + proto_pads.emplace(d->strip(), d->bx()); } // fill the output collections diff --git a/Validation/MuonGEMDigis/interface/GEMDigiMatcher.h b/Validation/MuonGEMDigis/interface/GEMDigiMatcher.h index a043b597fdb9e..67f2be1e92b93 100644 --- a/Validation/MuonGEMDigis/interface/GEMDigiMatcher.h +++ b/Validation/MuonGEMDigis/interface/GEMDigiMatcher.h @@ -110,10 +110,17 @@ class GEMDigiMatcher { std::shared_ptr muonSimHitMatcher() { return muonSimHitMatcher_; } private: + // match digi simlink to a simtrack (based on track Id and particle type) void matchDigisSLToSimTrack(const edm::DetSetVector&); + // match digi to a simtrack (based on BX and strip number) void matchDigisToSimTrack(const GEMDigiCollection&); + // match pad to a simtrack (based on BX and pad number) void matchPadsToSimTrack(const GEMPadDigiCollection&); + // match pad to a simtrack (based on BX and pad number) + void matchPadsInDetId(const GEMDetId& simhitId, const GEMPadDigiCollection&); + // match cluster to a simtrack (based on BX and pad number) void matchClustersToSimTrack(const GEMPadDigiClusterCollection&); + // match copad to a simtrack (based on previously matching pads) void matchCoPadsToSimTrack(const GEMCoPadDigiCollection&); void clear(); @@ -156,6 +163,7 @@ class GEMDigiMatcher { bool matchToSimLink_; + // map of raw GEMDetId to containers std::map detid_to_simLinks_; std::map detid_to_digis_; diff --git a/Validation/MuonGEMDigis/plugins/GEMPadDigiClusterValidation.cc b/Validation/MuonGEMDigis/plugins/GEMPadDigiClusterValidation.cc index d9004a338823d..5dad4977cc8ef 100644 --- a/Validation/MuonGEMDigis/plugins/GEMPadDigiClusterValidation.cc +++ b/Validation/MuonGEMDigis/plugins/GEMPadDigiClusterValidation.cc @@ -28,7 +28,7 @@ void GEMPadDigiClusterValidation::bookHistograms(DQMStore::IBooker& booker, TString cls_title = "Cluster Size Distribution"; TString cls_x_title = "Cluster size"; - me_cls_ = booker.book1D("cls", cls_title + ";" + cls_x_title + ";" + "Entries", 10, 0.5, 10.5); + me_cls_ = booker.book1D("cls", cls_title + ";" + cls_x_title + ";" + "Entries", 10, 0, 10); // NOTE Occupancy for (const auto& region : gem->regions()) { @@ -73,7 +73,7 @@ void GEMPadDigiClusterValidation::bookHistograms(DQMStore::IBooker& booker, Int_t num_pads = etaPartitionVec.front()->npads(); me_total_cluster_[key3] = - bookHist1D(booker, key3, "total_pad_cluster", "Number of pad digi cluster per event", 21, -0.5, 20.5); + bookHist1D(booker, key3, "total_pad_cluster", "Number of pad digi cluster per event", 20, 0, 20); me_pad_cluster_occ_eta_[key3] = bookHist1D(booker, key3, @@ -104,7 +104,7 @@ void GEMPadDigiClusterValidation::bookHistograms(DQMStore::IBooker& booker, "Pad number"); me_detail_occ_pad_[key3] = - bookHist1D(booker, key3, "occ_pad", "Pad Cluster Occupancy", num_pads, 0.5, num_pads + 0.5, "Pad number"); + bookHist1D(booker, key3, "occ_pad", "Pad Cluster Occupancy", num_pads, 0, num_pads, "Pad number"); } } // end loop over layer ids } // end loop over station ids @@ -133,7 +133,7 @@ void GEMPadDigiClusterValidation::bookHistograms(DQMStore::IBooker& booker, Int_t layer_id = chamber->id().layer(); ME3IdsKey key3(region_id, station_id, layer_id); me_detail_bx_[key3] = - bookHist1D(booker, key3, "bx", "Pad Cluster Bunch Crossing", 5, -2.5, 2.5, "Bunch crossing"); + bookHist1D(booker, key3, "bx", "Pad Cluster Bunch Crossing", 5, -2, 3, "Bunch crossing"); } // chamber loop } // station loop } // region loop @@ -201,10 +201,6 @@ void GEMPadDigiClusterValidation::analyze(const edm::Event& event, const edm::Ev ME3IdsKey key3(region_id, station_id, layer_id); for (auto digi = range.first; digi != range.second; ++digi) { - // ignore 16-partition GE2/1 pads - if (gemid.isGE21() and digi->nPartitions() == GEMPadDigiCluster::GE21SplitStrip) - continue; - const auto& padsVec = digi->pads(); if (padsVec.empty()) { edm::LogError(kLogCategory_) << "Pads missing for digi from GEM ID = " << gemid; diff --git a/Validation/MuonGEMDigis/plugins/GEMPadDigiValidation.cc b/Validation/MuonGEMDigis/plugins/GEMPadDigiValidation.cc index 6ec855d99ee71..d0c9121f0665d 100644 --- a/Validation/MuonGEMDigis/plugins/GEMPadDigiValidation.cc +++ b/Validation/MuonGEMDigis/plugins/GEMPadDigiValidation.cc @@ -66,7 +66,7 @@ void GEMPadDigiValidation::bookHistograms(DQMStore::IBooker& booker, Int_t num_pads = etaPartitionVec.front()->npads(); me_occ_total_pad_[key3] = - bookHist1D(booker, key3, "total_pads_per_event", "Number of pad digis per event", 51, -0.5, 50); + bookHist1D(booker, key3, "total_pads_per_event", "Number of pad digis per event", 50, 0, 50); me_pad_occ_eta_[key3] = bookHist1D(booker, key3, @@ -97,7 +97,7 @@ void GEMPadDigiValidation::bookHistograms(DQMStore::IBooker& booker, "Pad number"); me_detail_occ_pad_[key3] = - bookHist1D(booker, key3, "occ_pad", "Pad Occupancy", num_pads, 0.5, num_pads + 0.5, "Pad number"); + bookHist1D(booker, key3, "occ_pad", "Pad Occupancy", num_pads, 0, num_pads, "Pad number"); } } // layer loop } // station loop @@ -126,7 +126,7 @@ void GEMPadDigiValidation::bookHistograms(DQMStore::IBooker& booker, Int_t layer_id = chamber->id().layer(); ME3IdsKey key3(region_id, station_id, layer_id); - me_detail_bx_[key3] = bookHist1D(booker, key3, "bx", "Pad Bunch Crossing", 5, -2.5, 2.5, "Bunch crossing"); + me_detail_bx_[key3] = bookHist1D(booker, key3, "bx", "Pad Bunch Crossing", 5, -2, 3, "Bunch crossing"); } // chamber loop } // station loop } // region loop @@ -184,10 +184,6 @@ void GEMPadDigiValidation::analyze(const edm::Event& event, const edm::EventSetu ME3IdsKey key3(region_id, station_id, layer_id); for (auto digi = range.first; digi != range.second; ++digi) { - // ignore 16-partition GE2/1 pads - if (gemid.isGE21() and digi->nPartitions() == GEMPadDigi::GE21SplitStrip) - continue; - total_pad[key3]++; Int_t pad = digi->pad(); diff --git a/Validation/MuonGEMDigis/src/GEMDigiMatcher.cc b/Validation/MuonGEMDigis/src/GEMDigiMatcher.cc index 573f58cb47b4c..5886d2431feba 100644 --- a/Validation/MuonGEMDigis/src/GEMDigiMatcher.cc +++ b/Validation/MuonGEMDigis/src/GEMDigiMatcher.cc @@ -174,17 +174,11 @@ void GEMDigiMatcher::matchDigisToSimTrack(const GEMDigiCollection& digis) { } } void GEMDigiMatcher::matchPadsToSimTrack(const GEMPadDigiCollection& pads) { - const auto& det_ids = muonSimHitMatcher_->detIds(); - for (const auto& id : det_ids) { - GEMDetId p_id(id); - - const auto& pads_in_det = pads.get(p_id); - - for (auto pad = pads_in_det.first; pad != pads_in_det.second; ++pad) { - // ignore 16-partition GE2/1 pads - if (p_id.isGE21() and pad->nPartitions() == GEMPadDigi::GE21SplitStrip) - continue; + for (auto it = pads.begin(); it != pads.end(); ++it) { + const GEMDetId& p_id = (*it).first; + const auto& padsvec = (*it).second; + for (auto pad = padsvec.first; pad != padsvec.second; ++pad) { // check that the pad BX is within the range if (pad->bx() < minBXPad_ || pad->bx() > maxBXPad_) continue; @@ -192,9 +186,45 @@ void GEMDigiMatcher::matchPadsToSimTrack(const GEMPadDigiCollection& pads) { if (verbosePad_) edm::LogInfo("GEMDigiMatcher") << "GEMPad " << p_id << " " << *pad << endl; - // check that it matches a pad that was hit by SimHits from our track - for (auto digi : detid_to_digis_[p_id.rawId()]) { - if (digi.strip() / 2 == pad->pad()) { + auto digivec = detid_to_digis_[p_id.rawId()]; + /* + For GE1/1 and ME0 (and obsolete 8-partition GE2/1) geometries, the matching + is pretty simple. Each simhit is converted to a digi. Two digis in neighboring + strips are ed together into a pad. So for these geometries you just need + to match pads to simtracks that are in the same eta partition (detid) as the + simhit is in. By convention, all pads in the 16-partition GE2/1 geometry are + assigned to odd partition numbers. For the 16-partition GE2/1 geometry, you may + have a track with simhits in eta partition 1 and 2 on the same strip and only + produce 1 pad associated to eta partition 1. Therefore, for pads with odd + partition number N, you need to consider the digis in the even partition number + N+1. + */ + if (p_id.roll() % 2 == 1 && p_id.isGE21() && pad->nPartitions() == GEMPadDigi::GE21SplitStrip) { + // make the GEMDetId for the neighboring partition + GEMDetId p_id2(p_id.region(), p_id.ring(), p_id.station(), p_id.layer(), p_id.chamber(), p_id.roll() + 1); + + // make a temporary container for its digis + auto digivec2 = detid_to_digis_[p_id2.rawId()]; + + // now add it to the container for the digis in the odd partition number + digivec.insert(digivec.end(), digivec2.begin(), digivec2.end()); + } + for (const auto& digi : digivec) { + // for 8-partition geometries, the pad number equals the strip number divided by two + const bool match8Partition(digi.strip() / 2 == pad->pad()); + + // for 16-partition geometries, the pad number is the strip number itself + const bool match16Partition(digi.strip() == pad->pad()); + + // now consider the different cases separately + const bool matchGE0(p_id.isME0() and match8Partition); + const bool matchGE11(p_id.isGE11() and match8Partition); + const bool matchGE21_8(p_id.isGE21() and pad->nPartitions() == GEMPadDigi::GE21 and match8Partition); + const bool matchGE21_16(p_id.isGE21() and pad->nPartitions() == GEMPadDigi::GE21SplitStrip and + match16Partition); + + // OR them together + if (matchGE0 or matchGE11 or matchGE21_8 or matchGE21_16) { detid_to_pads_[p_id.rawId()].push_back(*pad); chamber_to_pads_[p_id.chamberId().rawId()].push_back(*pad); superchamber_to_pads_[p_id.superChamberId().rawId()].push_back(*pad); @@ -208,19 +238,12 @@ void GEMDigiMatcher::matchPadsToSimTrack(const GEMPadDigiCollection& pads) { } void GEMDigiMatcher::matchClustersToSimTrack(const GEMPadDigiClusterCollection& clusters) { - const auto& det_ids = muonSimHitMatcher_->detIds(); - for (auto id : det_ids) { - GEMDetId p_id(id); - - auto clusters_in_det = clusters.get(p_id); - - for (auto cluster = clusters_in_det.first; cluster != clusters_in_det.second; ++cluster) { + for (auto it = clusters.begin(); it != clusters.end(); ++it) { + const GEMDetId p_id = (*it).first; + const auto clvec = (*it).second; + for (auto cluster = clvec.first; cluster != clvec.second; ++cluster) { bool isMatched = false; - // ignore 16-partition GE2/1 pads - if (p_id.isGE21() and cluster->nPartitions() == GEMPadDigiCluster::GE21SplitStrip) - continue; - // check that the cluster BX is within the range if (cluster->bx() < minBXCluster_ || cluster->bx() > maxBXCluster_) continue; @@ -230,14 +253,14 @@ void GEMDigiMatcher::matchClustersToSimTrack(const GEMPadDigiClusterCollection& // check that at least one pad was hit by the track for (const auto& p : cluster->pads()) { - for (auto pad : detid_to_pads_[id]) { + for (const auto& pad : detid_to_pads_[p_id.rawId()]) { if (pad.pad() == p) { isMatched = true; } } } if (isMatched) { - detid_to_clusters_[id].push_back(*cluster); + detid_to_clusters_[p_id.rawId()].push_back(*cluster); chamber_to_clusters_[p_id.chamberId().rawId()].push_back(*cluster); superchamber_to_clusters_[p_id.superChamberId().rawId()].push_back(*cluster); if (verboseCluster_)