diff --git a/DataFormats/Common/interface/MultiSpan.h b/DataFormats/Common/interface/MultiSpan.h index 8448dc06fea3c..895a8e1252d93 100644 --- a/DataFormats/Common/interface/MultiSpan.h +++ b/DataFormats/Common/interface/MultiSpan.h @@ -4,10 +4,14 @@ #include #include +#include #include #include #include +#include "DataFormats/Common/interface/RefProd.h" +#include "DataFormats/Common/interface/RefProdVector.h" + namespace edm { /** @@ -29,6 +33,13 @@ namespace edm { public: MultiSpan() = default; + MultiSpan(const RefProdVector>& refProducts) { + std::ranges::for_each(refProducts, [&](auto const& rp) { + if (rp.isNonnull()) + add(*rp); + }); + } + void add(std::span sp) { // Empty spans are not added to reduce the number of spans and speed up the binary search if (sp.empty()) { diff --git a/DataFormats/Common/interface/RefProdVector.h b/DataFormats/Common/interface/RefProdVector.h new file mode 100644 index 0000000000000..fdb404ceab119 --- /dev/null +++ b/DataFormats/Common/interface/RefProdVector.h @@ -0,0 +1,13 @@ +#ifndef DataFormats_Common_interface_RefProdVector_h +#define DataFormats_Common_interface_RefProdVector_h + +#include + +#include "DataFormats/Common/interface/RefProd.h" + +namespace edm { + template + using RefProdVector = std::vector>; +} // namespace edm + +#endif // DataFormats_Common_interface_RefProdVector_h diff --git a/DataFormats/Common/test/test_catch2_MultiSpan.cpp b/DataFormats/Common/test/test_catch2_MultiSpan.cpp index ffcffa5dfd561..a218dfcfe4364 100644 --- a/DataFormats/Common/test/test_catch2_MultiSpan.cpp +++ b/DataFormats/Common/test/test_catch2_MultiSpan.cpp @@ -6,6 +6,8 @@ #include #include "DataFormats/Common/interface/MultiSpan.h" +#include "DataFormats/Common/interface/RefProd.h" +#include "DataFormats/Common/interface/RefProdVector.h" TEST_CASE("MultiSpan basic indexing", "[MultiSpan]") { edm::MultiSpan emptyMultiSpan; @@ -37,6 +39,18 @@ TEST_CASE("MultiSpan basic indexing", "[MultiSpan]") { ms3.add(a); ms3.add(c); + edm::RefProdVector> refProducts; + refProducts.push_back(edm::RefProd>(&b)); + refProducts.push_back(edm::RefProd>(&c)); + refProducts.push_back(edm::RefProd>(&c)); + refProducts.push_back(edm::RefProd>(&c)); + refProducts.push_back(edm::RefProd>(&b)); + refProducts.push_back(edm::RefProd>(&a)); + refProducts.push_back(edm::RefProd>(&c)); + refProducts.push_back( + edm::RefProd>(nullptr)); // Adding a null RefProd. It should be ignored by MultiSpan + edm::MultiSpan ms4(refProducts); // MultiSpan from std::vector of RefProds + using ElementType = decltype(ms[0]); // Check that the const-correctness of the MultiSpan static_assert(!std::is_assignable::value, @@ -175,4 +189,26 @@ TEST_CASE("MultiSpan basic indexing", "[MultiSpan]") { } REQUIRE(collected == std::vector{a[0], a[1], a[2]}); } + + SECTION("Check MultiSpan constructed from std::vector of RefProds") { + REQUIRE(ms4.size() == 7); + + REQUIRE(ms4[0] == b[0]); + REQUIRE(ms4[1] == b[1]); + REQUIRE(ms4[2] == b[0]); + REQUIRE(ms4[3] == b[1]); + REQUIRE(ms4[4] == a[0]); + REQUIRE(ms4[5] == a[1]); + REQUIRE(ms4[6] == a[2]); + + REQUIRE(ms4.globalIndex(0, 0) == 0); + REQUIRE(ms4.globalIndex(1, 1) == 3); + REQUIRE(ms4.globalIndex(2, 1) == 5); + + std::vector collected; + for (auto val : ms4) { + collected.push_back(val); + } + REQUIRE(collected == std::vector{b[0], b[1], b[0], b[1], a[0], a[1], a[2]}); + } } diff --git a/DataFormats/HGCRecHit/src/classes_def.xml b/DataFormats/HGCRecHit/src/classes_def.xml index 861d9eecfa190..683d9ce272310 100644 --- a/DataFormats/HGCRecHit/src/classes_def.xml +++ b/DataFormats/HGCRecHit/src/classes_def.xml @@ -21,9 +21,12 @@ - + + + + diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/RecHitMapProducer.cc b/RecoLocalCalo/HGCalRecProducers/plugins/RecHitMapProducer.cc index ac122c61ba1e2..006d649fbffb5 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/RecHitMapProducer.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/RecHitMapProducer.cc @@ -13,6 +13,7 @@ #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h" +#include "DataFormats/Common/interface/RefProdVector.h" #include "DataFormats/Common/interface/MultiSpan.h" class RecHitMapProducer : public edm::global::EDProducer<> { @@ -43,9 +44,13 @@ RecHitMapProducer::RecHitMapProducer(const edm::ParameterSet& ps) : hgcalOnly_(p } } + produces>("RefProdVectorHGCRecHitCollection"); produces("hgcalRecHitMap"); - if (!hgcalOnly_) + + if (!hgcalOnly_) { + produces>("RefProdVectorPFRecHitCollection"); produces("barrelRecHitMap"); + } } void RecHitMapProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { @@ -69,22 +74,24 @@ void RecHitMapProducer::produce(edm::StreamID, edm::Event& evt, const edm::Event // Check validity of all handles if (!ee_hits.isValid() || !fh_hits.isValid() || !bh_hits.isValid()) { - edm::LogWarning("HGCalRecHitMapProducer") - << "One or more HGCal hit collections are unavailable. Returning an empty map."; + edm::LogWarning("HGCalRecHitMapProducer") << "One or more HGCal hit collections are unavailable. Returning an " + "empty map and an empty RefProdVectorHGCRecHitCollection"; + evt.put(std::make_unique>(), "RefProdVectorHGCRecHitCollection"); evt.put(std::move(hitMapHGCal), "hgcalRecHitMap"); } else { - // TODO may be worth to avoid dependency on the order - // of the collections, maybe using a map - edm::MultiSpan rechitSpan; - rechitSpan.add(*ee_hits); - rechitSpan.add(*fh_hits); - rechitSpan.add(*bh_hits); + // Fix order by storing a edm::RefProdVector + auto mcHGCRecHit = std::make_unique>(); + mcHGCRecHit->push_back(edm::RefProd(ee_hits)); + mcHGCRecHit->push_back(edm::RefProd(fh_hits)); + mcHGCRecHit->push_back(edm::RefProd(bh_hits)); + edm::MultiSpan rechitSpan(*mcHGCRecHit); for (unsigned int i = 0; i < rechitSpan.size(); ++i) { const auto recHitDetId = rechitSpan[i].detid(); hitMapHGCal->emplace(recHitDetId, i); } + evt.put(std::move(mcHGCRecHit), "RefProdVectorHGCRecHitCollection"); evt.put(std::move(hitMapHGCal), "hgcalRecHitMap"); } @@ -99,18 +106,22 @@ void RecHitMapProducer::produce(edm::StreamID, edm::Event& evt, const edm::Event const auto& hbhe_hits = evt.getHandle(barrel_hits_token_[1]); if (!ecal_hits.isValid() || !hbhe_hits.isValid()) { - edm::LogWarning("HGCalRecHitMapProducer") - << "One or more barrel hit collections are unavailable. Returning an empty map."; + edm::LogWarning("HGCalRecHitMapProducer") << "One or more barrel hit collections are unavailable. Returning an " + "empty map and an empty RefProdVectorPFRecHitCollection"; + evt.put(std::make_unique>(), "RefProdVectorPFRecHitCollection"); evt.put(std::move(hitMapBarrel), "barrelRecHitMap"); } else { - edm::MultiSpan barrelRechitSpan; - barrelRechitSpan.add(evt.get(barrel_hits_token_[0])); - barrelRechitSpan.add(evt.get(barrel_hits_token_[1])); + auto mcPFRecHit = std::make_unique>(); + mcPFRecHit->push_back(edm::RefProd(ecal_hits)); + mcPFRecHit->push_back(edm::RefProd(hbhe_hits)); + + edm::MultiSpan barrelRechitSpan(*mcPFRecHit); for (unsigned int i = 0; i < barrelRechitSpan.size(); ++i) { const auto recHitDetId = barrelRechitSpan[i].detId(); hitMapBarrel->emplace(recHitDetId, i); } + evt.put(std::move(mcPFRecHit), "RefProdVectorPFRecHitCollection"); evt.put(std::move(hitMapBarrel), "barrelRecHitMap"); } } diff --git a/RecoLocalCalo/HGCalRecProducers/python/recHitMapProducer_cff.py b/RecoLocalCalo/HGCalRecProducers/python/recHitMapProducer_cff.py index 8e1a4e4977921..dd594012d706f 100644 --- a/RecoLocalCalo/HGCalRecProducers/python/recHitMapProducer_cff.py +++ b/RecoLocalCalo/HGCalRecProducers/python/recHitMapProducer_cff.py @@ -11,4 +11,4 @@ "particleFlowRecHitHBHE"] from Configuration.ProcessModifiers.ticl_barrel_cff import ticl_barrel -ticl_barrel.toModify(recHitMapProducer, hits = hits, hgcalOnly = False) +ticl_barrel.toModify(recHitMapProducer, hits = hits, hgcalOnly = False) diff --git a/SimCalorimetry/HGCalAssociatorProducers/plugins/AllHitToTracksterAssociatorsProducer.cc b/SimCalorimetry/HGCalAssociatorProducers/plugins/AllHitToTracksterAssociatorsProducer.cc index 909d2579843a6..776d7ad7d30de 100644 --- a/SimCalorimetry/HGCalAssociatorProducers/plugins/AllHitToTracksterAssociatorsProducer.cc +++ b/SimCalorimetry/HGCalAssociatorProducers/plugins/AllHitToTracksterAssociatorsProducer.cc @@ -10,6 +10,7 @@ #include "DataFormats/CaloRecHit/interface/CaloCluster.h" #include "SimDataFormats/Associations/interface/TICLAssociationMap.h" #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" +#include "DataFormats/Common/interface/RefProdVector.h" #include "DataFormats/Common/interface/MultiSpan.h" class AllHitToTracksterAssociatorsProducer : public edm::global::EDProducer<> { @@ -25,22 +26,19 @@ class AllHitToTracksterAssociatorsProducer : public edm::global::EDProducer<> { std::vector>>> tracksterCollectionTokens_; edm::EDGetTokenT> layerClustersToken_; edm::EDGetTokenT> hitMapToken_; - std::vector> hitsTokens_; + edm::EDGetTokenT> hitsToken_; }; AllHitToTracksterAssociatorsProducer::AllHitToTracksterAssociatorsProducer(const edm::ParameterSet& pset) : layerClustersToken_(consumes>(pset.getParameter("layerClusters"))), hitMapToken_( - consumes>(pset.getParameter("hitMapTag"))) { + consumes>(pset.getParameter("hitMapTag"))), + hitsToken_(consumes>(pset.getParameter("hits"))) { const auto& tracksterCollections = pset.getParameter>("tracksterCollections"); for (const auto& tag : tracksterCollections) { tracksterCollectionTokens_.emplace_back(tag.label() + tag.instance(), consumes>(tag)); } - for (const auto& tag : pset.getParameter>("hits")) { - hitsTokens_.emplace_back(consumes(tag)); - } - for (const auto& tracksterToken : tracksterCollectionTokens_) { produces>("hitTo" + tracksterToken.first); produces>(tracksterToken.first + "ToHit"); @@ -65,20 +63,25 @@ void AllHitToTracksterAssociatorsProducer::produce(edm::StreamID, edm::Event& iE Handle> hitMap; iEvent.getByToken(hitMapToken_, hitMap); - edm::MultiSpan rechitSpan; - for (const auto& token : hitsTokens_) { - Handle hitsHandle; - iEvent.getByToken(token, hitsHandle); + if (!iEvent.getHandle(hitsToken_)) { + edm::LogWarning("AllHitToTracksterAssociatorsProducer") << "Missing edm::RefProdVector."; + for (const auto& tracksterToken : tracksterCollectionTokens_) { + iEvent.put(std::make_unique>(), "hitTo" + tracksterToken.first); + iEvent.put(std::make_unique>(), tracksterToken.first + "ToHit"); + } + return; + } - // Protection against missing HGCRecHitCollection - if (!hitsHandle.isValid()) { - edm::LogWarning("AllHitToTracksterAssociatorsProducer") - << "Missing HGCRecHitCollection for one of the hitsTokens."; - continue; + // Protection against missing HGCRecHitCollection + const auto hits = iEvent.get(hitsToken_); + for (std::size_t index = 0; const auto& hgcRecHitCollection : hits) { + if (hgcRecHitCollection->empty()) { + edm::LogWarning("AllHitToTracksterAssociatorsProducer") << "HGCRecHitCollections #" << index << " is not valid."; } - rechitSpan.add(*hitsHandle); + index++; } + edm::MultiSpan rechitSpan(hits); // Check if rechitSpan is empty if (rechitSpan.size() == 0) { edm::LogWarning("HitToSimClusterCaloParticleAssociatorProducer") @@ -135,10 +138,7 @@ void AllHitToTracksterAssociatorsProducer::fillDescriptions(edm::ConfigurationDe edm::InputTag("ticlCandidate")}); desc.add("layerClusters", edm::InputTag("hgcalMergeLayerClusters")); desc.add("hitMapTag", edm::InputTag("recHitMapProducer", "hgcalRecHitMap")); - desc.add>("hits", - {edm::InputTag("HGCalRecHit", "HGCEERecHits"), - edm::InputTag("HGCalRecHit", "HGCHEFRecHits"), - edm::InputTag("HGCalRecHit", "HGCHEBRecHits")}); + desc.add("hits", edm::InputTag("recHitMapProducer", "RefProdVectorHGCRecHitCollection")); descriptions.add("AllHitToTracksterAssociatorsProducer", desc); } diff --git a/SimCalorimetry/HGCalAssociatorProducers/plugins/AllTracksterToSimTracksterAssociatorsByHitsProducer.cc b/SimCalorimetry/HGCalAssociatorProducers/plugins/AllTracksterToSimTracksterAssociatorsByHitsProducer.cc index 5656661fe70c0..2d43cf73f6784 100644 --- a/SimCalorimetry/HGCalAssociatorProducers/plugins/AllTracksterToSimTracksterAssociatorsByHitsProducer.cc +++ b/SimCalorimetry/HGCalAssociatorProducers/plugins/AllTracksterToSimTracksterAssociatorsByHitsProducer.cc @@ -10,6 +10,7 @@ #include "SimDataFormats/Associations/interface/TICLAssociationMap.h" #include "DataFormats/Provenance/interface/ProductID.h" #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" +#include "DataFormats/Common/interface/RefProdVector.h" #include "DataFormats/Common/interface/MultiSpan.h" #include "DataFormats/CaloRecHit/interface/CaloCluster.h" #include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h" @@ -37,7 +38,7 @@ class AllTracksterToSimTracksterAssociatorsByHitsProducer : public edm::global:: std::vector>>> simTracksterToHitMapTokens_; - std::vector> hitsTokens_; + edm::EDGetTokenT> hitsToken_; edm::EDGetTokenT> caloParticleToken_; edm::EDGetTokenT> hitToSimClusterMapToken_; edm::EDGetTokenT> hitToCaloParticleMapToken_; @@ -45,7 +46,8 @@ class AllTracksterToSimTracksterAssociatorsByHitsProducer : public edm::global:: AllTracksterToSimTracksterAssociatorsByHitsProducer::AllTracksterToSimTracksterAssociatorsByHitsProducer( const edm::ParameterSet& pset) - : caloParticleToken_(consumes>(pset.getParameter("caloParticles"))), + : hitsToken_(consumes>(pset.getParameter("hits"))), + caloParticleToken_(consumes>(pset.getParameter("caloParticles"))), hitToSimClusterMapToken_(consumes>( pset.getParameter("hitToSimClusterMap"))), hitToCaloParticleMapToken_(consumes>( @@ -78,12 +80,6 @@ AllTracksterToSimTracksterAssociatorsByHitsProducer::AllTracksterToSimTracksterA label, consumes>(edm::InputTag(allHitToTSAccoc, label + "ToHit"))); } - // Hits - auto hitsTags = pset.getParameter>("hits"); - for (const auto& tag : hitsTags) { - hitsTokens_.push_back(consumes(tag)); - } - // Produce separate association maps for each trackster-simTrackster combination for (const auto& tracksterToken : tracksterCollectionTokens_) { for (const auto& simTracksterToken : simTracksterCollectionTokens_) { @@ -104,19 +100,34 @@ void AllTracksterToSimTracksterAssociatorsByHitsProducer::produce(edm::StreamID, const edm::EventSetup&) const { using namespace edm; - edm::MultiSpan rechitSpan; - for (const auto& token : hitsTokens_) { - Handle hitsHandle; - iEvent.getByToken(token, hitsHandle); + if (!iEvent.getHandle(hitsToken_).isValid()) { + edm::LogWarning("AllTracksterToSimTracksterAssociatorsByHitsProducer") << "Missing MultiHGCRecHitCollection."; + for (const auto& tracksterToken : tracksterCollectionTokens_) { + for (const auto& simTracksterToken : simTracksterCollectionTokens_) { + iEvent.put(std::make_unique, + std::vector>>(), + tracksterToken.first + "To" + simTracksterToken.first); + iEvent.put(std::make_unique, + std::vector>>(), + simTracksterToken.first + "To" + tracksterToken.first); + } + } + return; + } - if (!hitsHandle.isValid()) { + // Protection against missing HGCRecHitCollection + const auto hits = iEvent.get(hitsToken_); + for (std::size_t index = 0; const auto& hgcRecHitCollection : hits) { + if (hgcRecHitCollection->empty()) { edm::LogWarning("AllTracksterToSimTracksterAssociatorsByHitsProducer") - << "Missing HGCRecHitCollection for one of the hitsTokens."; - continue; + << "HGCRecHitCollections #" << index << " is not valid."; } - rechitSpan.add(*hitsHandle); + index++; } + edm::MultiSpan rechitSpan(hits); // Check if rechitSpan is empty if (rechitSpan.size() == 0) { edm::LogWarning("AllTracksterToSimTracksterAssociatorsByHitsProducer") @@ -465,10 +476,7 @@ void AllTracksterToSimTracksterAssociatorsByHitsProducer::fillDescriptions( "tracksterCollections", {edm::InputTag("ticlTrackstersCLUE3DHigh"), edm::InputTag("ticlTrackstersLinks")}); desc.add>( "simTracksterCollections", {edm::InputTag("ticlSimTracksters"), edm::InputTag("ticlSimTracksters", "fromCPs")}); - desc.add>("hits", - {edm::InputTag("HGCalRecHit", "HGCEERecHits"), - edm::InputTag("HGCalRecHit", "HGCHEFRecHits"), - edm::InputTag("HGCalRecHit", "HGCHEBRecHits")}); + desc.add("hits", edm::InputTag("recHitMapProducer", "RefProdVectorHGCRecHitCollection")); desc.add("hitToSimClusterMap", edm::InputTag("hitToSimClusterCaloParticleAssociator", "hitToSimClusterMap")); desc.add("hitToCaloParticleMap", diff --git a/SimCalorimetry/HGCalAssociatorProducers/plugins/HitToSimClusterCaloParticleAssociatorProducer.cc b/SimCalorimetry/HGCalAssociatorProducers/plugins/HitToSimClusterCaloParticleAssociatorProducer.cc index 3b26c6b5c8ad1..1ea89645a1b2d 100644 --- a/SimCalorimetry/HGCalAssociatorProducers/plugins/HitToSimClusterCaloParticleAssociatorProducer.cc +++ b/SimCalorimetry/HGCalAssociatorProducers/plugins/HitToSimClusterCaloParticleAssociatorProducer.cc @@ -11,6 +11,7 @@ #include "SimDataFormats/Associations/interface/TICLAssociationMap.h" #include "DataFormats/Provenance/interface/ProductID.h" #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" +#include "DataFormats/Common/interface/RefProdVector.h" #include "DataFormats/Common/interface/MultiSpan.h" #include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h" #include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" @@ -20,10 +21,7 @@ HitToSimClusterCaloParticleAssociatorProducer::HitToSimClusterCaloParticleAssoci : simClusterToken_(consumes>(pset.getParameter("simClusters"))), caloParticleToken_(consumes>(pset.getParameter("caloParticles"))), hitMapToken_(consumes>(pset.getParameter("hitMap"))), - hitsTags_(pset.getParameter>("hits")) { - for (const auto &tag : hitsTags_) { - hitsTokens_.push_back(consumes(tag)); - } + hitsToken_(consumes>(pset.getParameter("hits"))) { produces>("hitToSimClusterMap"); produces>("hitToCaloParticleMap"); } @@ -42,22 +40,26 @@ void HitToSimClusterCaloParticleAssociatorProducer::produce(edm::StreamID, Handle> hitMap; iEvent.getByToken(hitMapToken_, hitMap); - edm::MultiSpan rechitSpan; - // Loop over tokens with index to access corresponding InputTag - for (size_t i = 0; i < hitsTokens_.size(); ++i) { - const auto &token = hitsTokens_[i]; - Handle hitsHandle; - iEvent.getByToken(token, hitsHandle); + if (!iEvent.getHandle(hitsToken_).isValid()) { + edm::LogWarning("HitToSimClusterCaloParticleAssociatorProducer") + << "No valid HGCRecHitCollections found. Association maps will be empty."; + // Store empty maps in the event + iEvent.put(std::make_unique>(), "hitToSimClusterMap"); + iEvent.put(std::make_unique>(), "hitToCaloParticleMap"); + return; + } - // Error handling with tag name - if (!hitsHandle.isValid()) { + // Protection against missing HGCRecHitCollection + const auto hits = iEvent.get(hitsToken_); + for (std::size_t index = 0; const auto &hgcRecHitCollection : hits) { + if (hgcRecHitCollection->empty()) { edm::LogWarning("HitToSimClusterCaloParticleAssociatorProducer") - << "Missing HGCRecHitCollection for tag: " << hitsTags_[i].encode(); - continue; + << "HGCRecHitCollection #" << index << " is empty or not valid."; } - rechitSpan.add(*hitsHandle); + index++; } + edm::MultiSpan rechitSpan(hits); // Check if rechitSpan is empty after processing hitsTokens_ if (rechitSpan.size() == 0) { edm::LogWarning("HitToSimClusterCaloParticleAssociatorProducer") @@ -99,10 +101,7 @@ void HitToSimClusterCaloParticleAssociatorProducer::fillDescriptions(edm::Config desc.add("simClusters", edm::InputTag("mix", "MergedCaloTruth")); desc.add("hitMap", edm::InputTag("recHitMapProducer", "hgcalRecHitMap")); - desc.add>("hits", - {edm::InputTag("HGCalRecHit", "HGCEERecHits"), - edm::InputTag("HGCalRecHit", "HGCHEFRecHits"), - edm::InputTag("HGCalRecHit", "HGCHEBRecHits")}); + desc.add("hits", edm::InputTag("recHitMapProducer", "RefProdVectorHGCRecHitCollection")); descriptions.add("hitToSimClusterCaloParticleAssociator", desc); } diff --git a/SimCalorimetry/HGCalAssociatorProducers/plugins/HitToSimClusterCaloParticleAssociatorProducer.h b/SimCalorimetry/HGCalAssociatorProducers/plugins/HitToSimClusterCaloParticleAssociatorProducer.h index 213006f44aaf1..20c4ab0c789ba 100644 --- a/SimCalorimetry/HGCalAssociatorProducers/plugins/HitToSimClusterCaloParticleAssociatorProducer.h +++ b/SimCalorimetry/HGCalAssociatorProducers/plugins/HitToSimClusterCaloParticleAssociatorProducer.h @@ -16,6 +16,7 @@ #include "SimDataFormats/Associations/interface/TICLAssociationMap.h" #include "DataFormats/Provenance/interface/ProductID.h" #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" +#include "DataFormats/Common/interface/RefProdVector.h" #include "DataFormats/Common/interface/MultiSpan.h" #include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h" #include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" @@ -34,8 +35,7 @@ class HitToSimClusterCaloParticleAssociatorProducer : public edm::global::EDProd const edm::EDGetTokenT> caloParticleToken_; const edm::EDGetTokenT> hitMapToken_; - const std::vector hitsTags_; - std::vector> hitsTokens_; + edm::EDGetTokenT> hitsToken_; }; #endif diff --git a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreImpl.cc b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreImpl.cc index c40d276ed35ec..0eb1df76d3ec8 100644 --- a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreImpl.cc +++ b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreImpl.cc @@ -4,6 +4,7 @@ #include "LCToCPAssociatorByEnergyScoreImpl.h" #include +#include "DataFormats/Common/interface/MultiSpan.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h" #include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" @@ -18,7 +19,7 @@ LCToCPAssociatorByEnergyScoreImplT::LCToCPAssociatorByEnergyScoreI bool hardScatterOnly, std::shared_ptr recHitTools, const std::unordered_map* hitMap, - const std::vector& hits) + const multiCollectionT& hits) : hardScatterOnly_(hardScatterOnly), recHitTools_(recHitTools), hitMap_(hitMap), @@ -68,6 +69,8 @@ ticl::association LCToCPAssociatorByEnergyScoreImplT::makeConnecti // that all the different contributions of the same CaloParticle to a single hit (coming from their // internal SimClusters) are merged into a single entry with the fractions properly summed. std::unordered_map> detIdToCaloParticleId_Map; + edm::MultiSpan hitsMS(hits_); + for (const auto& cpId : cPIndices) { const SimClusterRefVector& simClusterRefVector = caloParticles[cpId].simClusters(); for (const auto& it_sc : simClusterRefVector) { @@ -102,7 +105,7 @@ ticl::association LCToCPAssociatorByEnergyScoreImplT::makeConnecti detIdToCaloParticleId_Map[hitid].emplace_back(cpId, it_haf.second); } } - const HIT* hit = hits_[itcheck->second]; + const HIT* hit = &hitsMS[itcheck->second]; cPOnLayer[cpId][cpLayerId].energy += it_haf.second * hit->energy(); // We need to compress the hits and fractions in order to have a // reasonable score between CP and LC. Imagine, for example, that a @@ -136,7 +139,7 @@ ticl::association LCToCPAssociatorByEnergyScoreImplT::makeConnecti double tot_energy = 0.; for (auto const& haf : cPOnLayer[cp][cpp].hits_and_fractions) { //const HIT* hit = &(hits_[hitMap_->at(DetId(haf.first))]); - const HIT* hit = hits_[hitMap_->at(haf.first)]; + const HIT* hit = &hitsMS[hitMap_->at(haf.first)]; LogDebug("LCToCPAssociatorByEnergyScoreImplT") << " Hits/fraction/energy: " << (uint32_t)haf.first << "/" << haf.second << "/" << haf.second * hit->energy() << std::endl; tot_energy += haf.second * hit->energy(); @@ -154,7 +157,7 @@ ticl::association LCToCPAssociatorByEnergyScoreImplT::makeConnecti LogDebug("LCToCPAssociatorByEnergyScoreImplT") << "For detId: " << (uint32_t)cp.first << " we have found the following connections with CaloParticles:" << std::endl; - const HIT* hit = hits_[hitMap_->at(cp.first)]; + const HIT* hit = &hitsMS[hitMap_->at(cp.first)]; for (auto const& cpp : cp.second) { LogDebug("LCToCPAssociatorByEnergyScoreImplT") << " CaloParticle Id: " << cpp.clusterId << " with fraction: " << cpp.fraction @@ -193,7 +196,7 @@ ticl::association LCToCPAssociatorByEnergyScoreImplT::makeConnecti if (hit_find_in_CP != detIdToCaloParticleId_Map.end()) { const auto itcheck = hitMap_->find(rh_detid); - const HIT* hit = hits_[itcheck->second]; + const HIT* hit = &hitsMS[itcheck->second]; for (auto& h : hit_find_in_CP->second) { cPOnLayer[h.clusterId][lcLayerId].layerClusterIdToEnergyAndScore[lcId].first += h.fraction * hit->energy(); cpsInLayerCluster[lcId].emplace_back(h.clusterId, 0.f); @@ -252,7 +255,7 @@ ticl::association LCToCPAssociatorByEnergyScoreImplT::makeConnecti if (hit_find_in_CP == detIdToCaloParticleId_Map.end()) { hitsToCaloParticleId[hitId] -= 1; } else { - const HIT* hit = hits_[hitMap_->at(rh_detid)]; + const HIT* hit = &hitsMS[hitMap_->at(rh_detid)]; auto maxCPEnergyInLC = 0.f; auto maxCPId = -1; for (auto& h : hit_find_in_CP->second) { @@ -325,7 +328,7 @@ ticl::association LCToCPAssociatorByEnergyScoreImplT::makeConnecti << " Energy: " << cPOnLayer[cp][cpp].energy << std::endl; double tot_energy = 0.; for (auto const& haf : cPOnLayer[cp][cpp].hits_and_fractions) { - const HIT* hit = hits_[hitMap_->at(haf.first)]; + const HIT* hit = &hitsMS[hitMap_->at(haf.first)]; LogDebug("LCToCPAssociatorByEnergyScoreImplT") << " Hits/fraction/energy: " << (uint32_t)haf.first << "/" << haf.second << "/" << haf.second * hit->energy() << std::endl; tot_energy += haf.second * hit->energy(); @@ -343,7 +346,7 @@ ticl::association LCToCPAssociatorByEnergyScoreImplT::makeConnecti LogDebug("LCToCPAssociatorByEnergyScoreImplT") << "For detId: " << (uint32_t)cp.first << " we have found the following connections with CaloParticles:" << std::endl; - const HIT* hit = hits_[hitMap_->at(cp.first)]; + const HIT* hit = &hitsMS[hitMap_->at(cp.first)]; for (auto const& cpp : cp.second) { LogDebug("LCToCPAssociatorByEnergyScoreImplT") << " CaloParticle Id: " << cpp.clusterId << " with fraction: " << cpp.fraction @@ -383,7 +386,7 @@ ticl::association LCToCPAssociatorByEnergyScoreImplT::makeConnecti // It is the inverse of the denominator of the LCToCP score formula. Observe that this is the sum of the squares. float invLayerClusterEnergyWeight = 0.f; for (auto const& haf : hits_and_fractions) { - const HIT* hit = hits_[hitMap_->at(haf.first)]; + const HIT* hit = &hitsMS[hitMap_->at(haf.first)]; invLayerClusterEnergyWeight += (haf.second * hit->energy()) * (haf.second * hit->energy()); } invLayerClusterEnergyWeight = 1.f / invLayerClusterEnergyWeight; @@ -396,7 +399,7 @@ ticl::association LCToCPAssociatorByEnergyScoreImplT::makeConnecti auto itcheck = hitMap_->find(rh_detid); if (itcheck == hitMap_->end()) continue; - const HIT* hit = hits_[itcheck->second]; + const HIT* hit = &hitsMS[itcheck->second]; float hitEnergyWeight = hit->energy() * hit->energy(); for (auto& cpPair : cpsInLayerCluster[lcId]) { @@ -456,7 +459,7 @@ ticl::association LCToCPAssociatorByEnergyScoreImplT::makeConnecti // Compute the correct normalization. Observe that this is the sum of the squares. float invCPEnergyWeight = 0.f; for (auto const& haf : cPOnLayer[cpId][layerId].hits_and_fractions) { - const HIT* hit = hits_[hitMap_->at(haf.first)]; + const HIT* hit = &hitsMS[hitMap_->at(haf.first)]; invCPEnergyWeight += std::pow(haf.second * hit->energy(), 2); } invCPEnergyWeight = 1.f / invCPEnergyWeight; @@ -471,7 +474,7 @@ ticl::association LCToCPAssociatorByEnergyScoreImplT::makeConnecti if (hit_find_in_LC == detIdToLayerClusterId_Map.end()) hitWithNoLC = true; auto itcheck = hitMap_->find(cp_hitDetId); - const HIT* hit = hits_[itcheck->second]; + const HIT* hit = &hitsMS[itcheck->second]; float hitEnergyWeight = hit->energy() * hit->energy(); for (auto& lcPair : cPOnLayer[cpId][layerId].layerClusterIdToEnergyAndScore) { unsigned int layerClusterId = lcPair.first; diff --git a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreImpl.h b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreImpl.h index 0fabcc4e80643..cf95996c8ce3a 100644 --- a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreImpl.h +++ b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreImpl.h @@ -68,11 +68,13 @@ namespace ticl { template class LCToCPAssociatorByEnergyScoreImplT : public ticl::LayerClusterToCaloParticleAssociatorBaseImplT { public: + using multiCollectionT = std::vector>>; + explicit LCToCPAssociatorByEnergyScoreImplT(edm::EDProductGetter const &, bool, std::shared_ptr, const std::unordered_map *, - const std::vector &hits); + const multiCollectionT &hits); ticl::RecoToSimCollectionT associateRecoToSim( const edm::Handle &cCH, const edm::Handle &cPCH) const override; @@ -88,7 +90,7 @@ class LCToCPAssociatorByEnergyScoreImplT : public ticl::LayerClusterToCaloPartic edm::EDProductGetter const *productGetter_; ticl::association makeConnections(const edm::Handle &cCH, const edm::Handle &cPCH) const; - std::vector hits_; + multiCollectionT hits_; }; extern template class LCToCPAssociatorByEnergyScoreImplT; diff --git a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreProducer.cc b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreProducer.cc index 288969190b7e8..7b14b1470943f 100644 --- a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreProducer.cc +++ b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreProducer.cc @@ -1,5 +1,6 @@ #include "LCToCPAssociatorByEnergyScoreProducer.h" +#include #include template @@ -7,11 +8,7 @@ LCToCPAssociatorByEnergyScoreProducerT::LCToCPAssociatorByEnergySc : hitMap_(consumes>(ps.getParameter("hitMapTag"))), caloGeometry_(esConsumes()), hardScatterOnly_(ps.getParameter("hardScatterOnly")), - hits_label_(ps.getParameter>("hits")) { - for (auto &label : hits_label_) { - hits_token_.push_back(consumes>(label)); - } - + hits_token_(consumes(ps.getParameter("hits"))) { rhtools_ = std::make_shared(); // Register the product @@ -28,31 +25,17 @@ void LCToCPAssociatorByEnergyScoreProducerT::produce(edm::StreamID edm::ESHandle geom = es.getHandle(caloGeometry_); rhtools_->setGeometry(*geom); - std::vector hits; - - for (unsigned i = 0; i < hits_token_.size(); ++i) { - auto hits_handle = iEvent.getHandle(hits_token_[i]); - - // Check handle validity - if (!hits_handle.isValid()) { - edm::LogWarning("LCToCPAssociatorByEnergyScoreProducer") - << "Hit collection not available for token " << hits_label_[i] << ". Skipping this collection."; - continue; // Skip invalid handle + if (!iEvent.getHandle(hitMap_) || !iEvent.getHandle(hits_token_)) { + if (!iEvent.getHandle(hitMap_)) { + edm::LogWarning("LCToCPAssociatorByEnergyScoreProducerT") << "Hit map not valid. Producing empty associator."; } - - for (const auto &hit : *hits_handle) { - hits.push_back(&hit); + if (!iEvent.getHandle(hits_token_)) { + edm::LogWarning("LCToCPAssociatorByEnergyScoreProducerT") + << "Hit RefProdVector not available. Producing empty associator."; } - } - - if (hits.empty()) { - edm::LogWarning("LCToCPAssociatorByEnergyScoreProducerT") << "No hits collected. Producing empty associator."; - } - - if (!iEvent.getHandle(hitMap_)) { - edm::LogWarning("LCToCPAssociatorByEnergyScoreProducerT") << "Hit map not valid. Producing empty associator."; const std::unordered_map hitMap; // empty map + const multiCollectionT hits; auto impl = std::make_unique>( iEvent.productGetter(), hardScatterOnly_, rhtools_, &hitMap, hits); auto emptyAssociator = std::make_unique>(std::move(impl)); @@ -60,6 +43,23 @@ void LCToCPAssociatorByEnergyScoreProducerT::produce(edm::StreamID return; } + // Protection against missing HGCRecHitCollection + const auto hits = iEvent.get(hits_token_); + for (std::size_t index = 0; const auto &hgcRecHitCollection : hits) { + if (hgcRecHitCollection->empty()) { + edm::LogWarning("LCToCPAssociatorByEnergyScoreProducerT") + << "HGCRecHitCollections #" << index << " is not valid."; + } + index++; + } + + const bool no_hits = + std::none_of(hits.begin(), hits.end(), [](const auto &subCollection) { return !subCollection->empty(); }); + + if (no_hits) { + edm::LogWarning("LCToCPAssociatorByEnergyScoreProducerT") << "No hits collected. Producing empty associator."; + } + const auto hitMap = &iEvent.get(hitMap_); auto impl = std::make_unique>( iEvent.productGetter(), hardScatterOnly_, rhtools_, hitMap, hits); @@ -73,14 +73,10 @@ void LCToCPAssociatorByEnergyScoreProducerT::fillDescriptions(edm: desc.add("hardScatterOnly", true); if constexpr (std::is_same_v) { desc.add("hitMapTag", edm::InputTag("recHitMapProducer", "hgcalRecHitMap")); - desc.add>("hits", - {edm::InputTag("HGCalRecHit", "HGCEERecHits"), - edm::InputTag("HGCalRecHit", "HGCHEFRecHits"), - edm::InputTag("HGCalRecHit", "HGCHEBRecHits")}); + desc.add("hits", edm::InputTag("recHitMapProducer", "RefProdVectorHGCRecHitCollection")); } else { desc.add("hitMapTag", edm::InputTag("recHitMapProducer", "barrelRecHitMap")); - desc.add>( - "hits", {edm::InputTag("particleFlowRecHitECAL", ""), edm::InputTag("particleFlowRecHitHBHE", "")}); + desc.add("hits", edm::InputTag("recHitMapProducer", "RefProdVectorPFRecHitCollection")); } cfg.addWithDefaultLabel(desc); } diff --git a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreProducer.h b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreProducer.h index 32c933cd0f058..a116217fcd6c5 100644 --- a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreProducer.h +++ b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToCPAssociatorByEnergyScoreProducer.h @@ -18,11 +18,14 @@ #include "SimDataFormats/Associations/interface/LayerClusterToCaloParticleAssociator.h" #include "LCToCPAssociatorByEnergyScoreImpl.h" +#include "DataFormats/Common/interface/RefProdVector.h" #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" template class LCToCPAssociatorByEnergyScoreProducerT : public edm::global::EDProducer<> { public: + using multiCollectionT = edm::RefProdVector>; + explicit LCToCPAssociatorByEnergyScoreProducerT(const edm::ParameterSet &); ~LCToCPAssociatorByEnergyScoreProducerT() override; @@ -34,8 +37,7 @@ class LCToCPAssociatorByEnergyScoreProducerT : public edm::global::EDProducer<> edm::ESGetToken caloGeometry_; const bool hardScatterOnly_; std::shared_ptr rhtools_; - std::vector hits_label_; - std::vector>> hits_token_; + edm::EDGetTokenT hits_token_; }; template class LCToCPAssociatorByEnergyScoreProducerT; diff --git a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreImpl.cc b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreImpl.cc index 7947ba7ad2acc..5f4f97034059f 100644 --- a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreImpl.cc +++ b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreImpl.cc @@ -1,5 +1,6 @@ #include "LCToSCAssociatorByEnergyScoreImpl.h" +#include "DataFormats/Common/interface/MultiSpan.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" #include "DataFormats/CaloRecHit/interface/CaloCluster.h" @@ -10,7 +11,7 @@ LCToSCAssociatorByEnergyScoreImplT::LCToSCAssociatorByEnergyScoreI bool hardScatterOnly, std::shared_ptr recHitTools, const std::unordered_map* hitMap, - std::vector& hits) + const multiCollectionT& hits) : hardScatterOnly_(hardScatterOnly), recHitTools_(recHitTools), hitMap_(hitMap), @@ -70,6 +71,8 @@ ticl::association LCToSCAssociatorByEnergyScoreImplT::makeConnecti // that in contrast to the CaloParticle case there is no merging and summing of the fractions, which // in the CaloParticle's case was necessary due to the multiple SimClusters of a single CaloParticle. std::unordered_map> detIdToSimClusterId_Map; + edm::MultiSpan hitsMS(hits_); + for (const auto& scId : sCIndices) { std::vector> hits_and_fractions = simClusters[scId].hits_and_fractions(); if constexpr (std::is_same_v) @@ -90,7 +93,7 @@ ticl::association LCToSCAssociatorByEnergyScoreImplT::makeConnecti detIdToSimClusterId_Map[hitid] = std::vector(); } detIdToSimClusterId_Map[hitid].emplace_back(scId, it_haf.second); - const HIT* hit = hits_[itcheck->second]; + const HIT* hit = &hitsMS[itcheck->second]; lcsInSimCluster[scId][scLayerId].energy += it_haf.second * hit->energy(); lcsInSimCluster[scId][scLayerId].hits_and_fractions.emplace_back(hitid, it_haf.second); } @@ -111,7 +114,7 @@ ticl::association LCToSCAssociatorByEnergyScoreImplT::makeConnecti << " Energy: " << lcsInSimCluster[sc][sclay].energy << std::endl; double tot_energy = 0.; for (auto const& haf : lcsInSimCluster[sc][sclay].hits_and_fractions) { - const HIT* hit = hits_[hitMap_->at(haf.first)]; + const HIT* hit = &hitsMS[hitMap_->at(haf.first)]; LogDebug("LCToSCAssociatorByEnergyScoreImplT") << " Hits/fraction/energy: " << (uint32_t)haf.first << "/" << haf.second << "/" << haf.second * hit->energy() << std::endl; tot_energy += haf.second * hit->energy(); @@ -133,7 +136,7 @@ ticl::association LCToSCAssociatorByEnergyScoreImplT::makeConnecti // specific detId there are more that one SimClusters contributing with fractions less than 1. // This is important since it effects the score computation, since the fraction is also in the // denominator of the score formula. - const HIT* hit = hits_[hitMap_->at(sc.first)]; + const HIT* hit = &hitsMS[hitMap_->at(sc.first)]; for (auto const& sclu : sc.second) { LogDebug("LCToSCAssociatorByEnergyScoreImplT") << " SimCluster Id: " << sclu.clusterId << " with fraction: " << sclu.fraction @@ -174,7 +177,7 @@ ticl::association LCToSCAssociatorByEnergyScoreImplT::makeConnecti if (hit_find_in_SC != detIdToSimClusterId_Map.end()) { const auto itcheck = hitMap_->find(rh_detid); - const HIT* hit = hits_[itcheck->second]; + const HIT* hit = &hitsMS[itcheck->second]; //Loops through all the simclusters that have the layer cluster rechit under study //Here is time to update the lcsInSimCluster and connect the SimCluster with all //the layer clusters that have the current rechit detid matched. @@ -243,7 +246,7 @@ ticl::association LCToSCAssociatorByEnergyScoreImplT::makeConnecti hitsToSimClusterId[hitId] -= 1; } else { const auto itcheck = hitMap_->find(rh_detid); - const HIT* hit = hits_[itcheck->second]; + const HIT* hit = &hitsMS[itcheck->second]; auto maxSCEnergyInLC = 0.f; auto maxSCId = -1; //Loop through all the linked SimClusters @@ -327,7 +330,7 @@ ticl::association LCToSCAssociatorByEnergyScoreImplT::makeConnecti << " Energy: " << lcsInSimCluster[sc][sclay].energy << std::endl; double tot_energy = 0.; for (auto const& haf : lcsInSimCluster[sc][sclay].hits_and_fractions) { - const HIT* hit = hits_[hitMap_->at(haf.first)]; + const HIT* hit = &hitsMS[hitMap_->at(haf.first)]; LogDebug("LCToSCAssociatorByEnergyScoreImplT") << " Hits/fraction/energy: " << (uint32_t)haf.first << "/" << haf.second << "/" << haf.second * hit->energy() << std::endl; tot_energy += haf.second * hit->energy(); @@ -342,7 +345,7 @@ ticl::association LCToSCAssociatorByEnergyScoreImplT::makeConnecti LogDebug("LCToSCAssociatorByEnergyScoreImplT") << "Improved detIdToSimClusterId_Map INFO" << std::endl; for (auto const& sc : detIdToSimClusterId_Map) { - const HIT* hit = hits_[hitMap_->at(sc.first)]; + const HIT* hit = &hitsMS[hitMap_->at(sc.first)]; LogDebug("LCToSCAssociatorByEnergyScoreImplT") << "For detId: " << (uint32_t)sc.first << " we have found the following connections with SimClusters:" << std::endl; @@ -386,7 +389,7 @@ ticl::association LCToSCAssociatorByEnergyScoreImplT::makeConnecti // It is the inverse of the denominator of the LCToSC score formula. Observe that this is the sum of the squares. float invLayerClusterEnergyWeight = 0.f; for (auto const& haf : hits_and_fractions) { - const HIT* hit = hits_[hitMap_->at(haf.first)]; + const HIT* hit = &hitsMS[hitMap_->at(haf.first)]; invLayerClusterEnergyWeight += (haf.second * hit->energy()) * (haf.second * hit->energy()); } invLayerClusterEnergyWeight = 1.f / invLayerClusterEnergyWeight; @@ -397,7 +400,7 @@ ticl::association LCToSCAssociatorByEnergyScoreImplT::makeConnecti bool hitWithSC = (detIdToSimClusterId_Map.find(rh_detid) != detIdToSimClusterId_Map.end()); auto itcheck = hitMap_->find(rh_detid); - const HIT* hit = hits_[itcheck->second]; + const HIT* hit = &hitsMS[itcheck->second]; float hitEnergyWeight = hit->energy() * hit->energy(); for (auto& scPair : scsInLayerCluster[lcId]) { @@ -469,7 +472,7 @@ ticl::association LCToSCAssociatorByEnergyScoreImplT::makeConnecti // Compute the correct normalization. Observe that this is the sum of the squares. float invSCEnergyWeight = 0.f; for (auto const& haf : lcsInSimCluster[scId][layerId].hits_and_fractions) { - const HIT* hit = hits_[hitMap_->at(haf.first)]; + const HIT* hit = &hitsMS[hitMap_->at(haf.first)]; invSCEnergyWeight += std::pow(haf.second * hit->energy(), 2); } invSCEnergyWeight = 1.f / invSCEnergyWeight; @@ -484,7 +487,7 @@ ticl::association LCToSCAssociatorByEnergyScoreImplT::makeConnecti if (hit_find_in_LC != detIdToLayerClusterId_Map.end()) hitWithLC = true; auto itcheck = hitMap_->find(sc_hitDetId); - const HIT* hit = hits_[itcheck->second]; + const HIT* hit = &hitsMS[itcheck->second]; float hitEnergyWeight = hit->energy() * hit->energy(); for (auto& lcPair : lcsInSimCluster[scId][layerId].layerClusterIdToEnergyAndScore) { unsigned int layerClusterId = lcPair.first; diff --git a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreImpl.h b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreImpl.h index ac4b2dc7ad086..ed517e68599c8 100644 --- a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreImpl.h +++ b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreImpl.h @@ -65,11 +65,13 @@ namespace ticl { template class LCToSCAssociatorByEnergyScoreImplT : public ticl::LayerClusterToSimClusterAssociatorBaseImplT { public: + using multiCollectionT = std::vector>>; + explicit LCToSCAssociatorByEnergyScoreImplT(edm::EDProductGetter const &, bool, std::shared_ptr, const std::unordered_map *, - std::vector &hits); + const multiCollectionT &hits); ticl::RecoToSimCollectionWithSimClustersT associateRecoToSim( const edm::Handle &cCH, const edm::Handle &sCCH) const override; @@ -85,7 +87,7 @@ class LCToSCAssociatorByEnergyScoreImplT : public ticl::LayerClusterToSimCluster edm::EDProductGetter const *productGetter_; ticl::association makeConnections(const edm::Handle &cCH, const edm::Handle &sCCH) const; - std::vector hits_; + multiCollectionT hits_; }; extern template class LCToSCAssociatorByEnergyScoreImplT; diff --git a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreProducer.cc b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreProducer.cc index c3d90da83be95..a5387e794630d 100644 --- a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreProducer.cc +++ b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreProducer.cc @@ -7,11 +7,7 @@ LCToSCAssociatorByEnergyScoreProducerT::LCToSCAssociatorByEnergySc : hitMap_(consumes>(ps.getParameter("hitMapTag"))), caloGeometry_(esConsumes()), hardScatterOnly_(ps.getParameter("hardScatterOnly")), - hits_label_(ps.getParameter>("hits")) { - for (auto &label : hits_label_) { - hits_token_.push_back(consumes>(label)); - } - + hits_token_(consumes(ps.getParameter("hits"))) { rhtools_ = std::make_shared(); // Register the product @@ -28,31 +24,17 @@ void LCToSCAssociatorByEnergyScoreProducerT::produce(edm::StreamID edm::ESHandle geom = es.getHandle(caloGeometry_); rhtools_->setGeometry(*geom); - std::vector hits; - - for (unsigned i = 0; i < hits_token_.size(); ++i) { - auto hits_handle = iEvent.getHandle(hits_token_[i]); - - // Check handle validity - if (!hits_handle.isValid()) { - edm::LogWarning("LCToSCAssociatorByEnergyScoreProducer") - << "Hit collection not available for token " << hits_label_[i] << ". Skipping this collection."; - continue; // Skip invalid handle + if (!iEvent.getHandle(hitMap_) || !iEvent.getHandle(hits_token_)) { + if (!iEvent.getHandle(hitMap_)) { + edm::LogWarning("LCToSCAssociatorByEnergyScoreProducer") << "Hit map not valid. Producing empty associator."; } - - for (const auto &hit : *hits_handle) { - hits.push_back(&hit); + if (!iEvent.getHandle(hits_token_)) { + edm::LogWarning("LCToSCAssociatorByEnergyScoreProducer") + << "Hit RefProdVector not available. Producing empty associator."; } - } - - if (hits.empty()) { - edm::LogWarning("LCToSCAssociatorByEnergyScoreProducerT") << "No hits collected. Producing empty associator."; - } - - if (!iEvent.getHandle(hitMap_)) { - edm::LogWarning("LCToSCAssociatorByEnergyScoreProducerT") << "Hit map not valid. Producing empty associator."; const std::unordered_map hitMap; // empty map + const multiCollectionT hits; auto impl = std::make_unique>( iEvent.productGetter(), hardScatterOnly_, rhtools_, &hitMap, hits); auto emptyAssociator = std::make_unique>(std::move(impl)); @@ -60,6 +42,23 @@ void LCToSCAssociatorByEnergyScoreProducerT::produce(edm::StreamID return; } + // Protection against missing HGCRecHitCollection + const auto hits = iEvent.get(hits_token_); + for (std::size_t index = 0; const auto &hgcRecHitCollection : hits) { + if (hgcRecHitCollection->empty()) { + edm::LogWarning("LCToSCAssociatorByEnergyScoreProducerT") + << "HGCRecHitCollections #" << index << " is not valid."; + } + index++; + } + + const bool no_hits = + std::none_of(hits.begin(), hits.end(), [](const auto &subCollection) { return !subCollection->empty(); }); + + if (no_hits) { + edm::LogWarning("LCToSCAssociatorByEnergyScoreProducerT") << "No hits collected. Producing empty associator."; + } + const auto hitMap = &iEvent.get(hitMap_); auto impl = std::make_unique>( iEvent.productGetter(), hardScatterOnly_, rhtools_, hitMap, hits); @@ -73,14 +72,10 @@ void LCToSCAssociatorByEnergyScoreProducerT::fillDescriptions(edm: desc.add("hardScatterOnly", true); if constexpr (std::is_same_v) { desc.add("hitMapTag", edm::InputTag("recHitMapProducer", "hgcalRecHitMap")); - desc.add>("hits", - {edm::InputTag("HGCalRecHit", "HGCEERecHits"), - edm::InputTag("HGCalRecHit", "HGCHEFRecHits"), - edm::InputTag("HGCalRecHit", "HGCHEBRecHits")}); + desc.add("hits", edm::InputTag("recHitMapProducer", "RefProdVectorHGCRecHitCollection")); } else { desc.add("hitMapTag", edm::InputTag("recHitMapProducer", "barrelRecHitMap")); - desc.add>( - "hits", {edm::InputTag("particleFlowRecHitECAL", ""), edm::InputTag("particleFlowRecHitHBHE", "")}); + desc.add("hits", edm::InputTag("recHitMapProducer", "RefProdVectorPFRecHitCollection")); } cfg.addWithDefaultLabel(desc); } diff --git a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreProducer.h b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreProducer.h index b25da3653a586..7daca4f907681 100644 --- a/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreProducer.h +++ b/SimCalorimetry/HGCalAssociatorProducers/plugins/LCToSCAssociatorByEnergyScoreProducer.h @@ -18,11 +18,14 @@ #include "SimDataFormats/Associations/interface/LayerClusterToSimClusterAssociator.h" #include "LCToSCAssociatorByEnergyScoreImpl.h" +#include "DataFormats/Common/interface/RefProdVector.h" #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" template class LCToSCAssociatorByEnergyScoreProducerT : public edm::global::EDProducer<> { public: + using multiCollectionT = edm::RefProdVector>; + explicit LCToSCAssociatorByEnergyScoreProducerT(const edm::ParameterSet &); ~LCToSCAssociatorByEnergyScoreProducerT() override; @@ -34,8 +37,7 @@ class LCToSCAssociatorByEnergyScoreProducerT : public edm::global::EDProducer<> edm::ESGetToken caloGeometry_; const bool hardScatterOnly_; std::shared_ptr rhtools_; - std::vector hits_label_; - std::vector>> hits_token_; + edm::EDGetTokenT hits_token_; }; template class LCToSCAssociatorByEnergyScoreProducerT; diff --git a/Validation/Configuration/python/hltHGCalSimValid_cff.py b/Validation/Configuration/python/hltHGCalSimValid_cff.py index dd1d82ef5a810..677020c1dd390 100644 --- a/Validation/Configuration/python/hltHGCalSimValid_cff.py +++ b/Validation/Configuration/python/hltHGCalSimValid_cff.py @@ -20,12 +20,12 @@ ) hltLcAssocByEnergyScoreProducer = _lcAssocByEnergyScoreProducer.clone( - hits = cms.VInputTag("hltHGCalRecHit:HGCEERecHits", "hltHGCalRecHit:HGCHEFRecHits", "hltHGCalRecHit:HGCHEBRecHits"), + hits = cms.InputTag("hltRecHitMapProducer", "RefProdVectorHGCRecHitCollection"), hitMapTag = cms.InputTag("hltRecHitMapProducer","hgcalRecHitMap"), ) hltScAssocByEnergyScoreProducer = _scAssocByEnergyScoreProducer.clone( - hits = cms.VInputTag("hltHGCalRecHit:HGCEERecHits", "hltHGCalRecHit:HGCHEFRecHits", "hltHGCalRecHit:HGCHEBRecHits"), + hits = cms.InputTag("hltRecHitMapProducer", "RefProdVectorHGCRecHitCollection"), hitMapTag = cms.InputTag("hltRecHitMapProducer","hgcalRecHitMap"), ) @@ -66,14 +66,14 @@ hltHitToSimClusterCaloParticleAssociator = _hitToSimClusterCaloParticleAssociator.clone( hitMap = cms.InputTag("hltRecHitMapProducer","hgcalRecHitMap"), - hits = cms.VInputTag("hltHGCalRecHit:HGCEERecHits", "hltHGCalRecHit:HGCHEFRecHits", "hltHGCalRecHit:HGCHEBRecHits") + hits = cms.InputTag("hltRecHitMapProducer", "RefProdVectorHGCRecHitCollection"), ) from SimCalorimetry.HGCalAssociatorProducers.AllHitToTracksterAssociatorsProducer_cfi import AllHitToTracksterAssociatorsProducer as _AllHitToTracksterAssociatorsProducer hltAllHitToTracksterAssociations = _AllHitToTracksterAssociatorsProducer.clone( hitMapTag = cms.InputTag("hltRecHitMapProducer","hgcalRecHitMap"), - hits = cms.VInputTag("hltHGCalRecHit:HGCEERecHits", "hltHGCalRecHit:HGCHEFRecHits", "hltHGCalRecHit:HGCHEBRecHits"), + hits = cms.InputTag("hltRecHitMapProducer", "RefProdVectorHGCRecHitCollection"), layerClusters = cms.InputTag("hltMergeLayerClusters"), tracksterCollections = cms.VInputTag( *[cms.InputTag(label) for label in _hltTiclIterLabels], @@ -86,7 +86,7 @@ allHitToTSAccoc = cms.string("hltAllHitToTracksterAssociations"), hitToCaloParticleMap = cms.InputTag("hltHitToSimClusterCaloParticleAssociator","hitToCaloParticleMap"), hitToSimClusterMap = cms.InputTag("hltHitToSimClusterCaloParticleAssociator","hitToSimClusterMap"), - hits = cms.VInputTag("hltHGCalRecHit:HGCEERecHits", "hltHGCalRecHit:HGCHEFRecHits", "hltHGCalRecHit:HGCHEBRecHits"), + hits = cms.InputTag("hltRecHitMapProducer", "RefProdVectorHGCRecHitCollection"), tracksterCollections = cms.VInputTag( *[cms.InputTag(label) for label in _hltTiclIterLabels] ), diff --git a/Validation/HGCalValidation/interface/BarrelValidator.h b/Validation/HGCalValidation/interface/BarrelValidator.h index c1db75980b72c..139d1659a1bc4 100644 --- a/Validation/HGCalValidation/interface/BarrelValidator.h +++ b/Validation/HGCalValidation/interface/BarrelValidator.h @@ -27,6 +27,7 @@ #include "SimDataFormats/Associations/interface/LayerClusterToSimClusterAssociator.h" #include "SimDataFormats/Associations/interface/TICLAssociationMap.h" +#include "DataFormats/Common/interface/RefProdVector.h" #include "DataFormats/Common/interface/MultiSpan.h" class PileupSummaryInfo; @@ -94,8 +95,7 @@ class BarrelValidator : public DQMGlobalEDAnalyzer { std::vector>> associatorMapRtSim; std::unique_ptr histoProducerAlgo_; - std::vector hits_labels_; - std::vector>> hits_tokens_; + edm::EDGetTokenT> hitsToken_; edm::EDGetTokenT scToCpMapToken_; private: diff --git a/Validation/HGCalValidation/interface/HGCalValidator.h b/Validation/HGCalValidation/interface/HGCalValidator.h index 4728ec9dada4c..894d59ff2ebf6 100644 --- a/Validation/HGCalValidation/interface/HGCalValidator.h +++ b/Validation/HGCalValidation/interface/HGCalValidator.h @@ -17,6 +17,7 @@ #include "DataFormats/ParticleFlowReco/interface/PFCluster.h" #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h" #include "DataFormats/HGCalReco/interface/Trackster.h" +#include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" #include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h" #include "SimDataFormats/CaloAnalysis/interface/SimCluster.h" #include "SimDataFormats/Vertex/interface/SimVertex.h" @@ -33,6 +34,7 @@ #include "SimDataFormats/Associations/interface/TICLAssociationMap.h" #include "CommonTools/Utils/interface/StringCutObjectSelector.h" +#include "DataFormats/Common/interface/RefProdVector.h" #include "DataFormats/Common/interface/MultiSpan.h" class PileupSummaryInfo; @@ -113,8 +115,7 @@ class HGCalValidator : public DQMGlobalEDAnalyzer { edm::EDGetTokenT> associatorMapSimtR; edm::EDGetTokenT> associatorMapRtSim; std::unique_ptr histoProducerAlgo_; - std::vector hits_labels_; - std::vector> hits_tokens_; + edm::EDGetTokenT> hitsToken_; std::unique_ptr candidateVal_; std::vector> tracksterToTracksterAssociatorsTokens_; std::vector> tracksterToTracksterByHitsAssociatorsTokens_; diff --git a/Validation/HGCalValidation/plugins/BarrelValidator.cc b/Validation/HGCalValidation/plugins/BarrelValidator.cc index 3d73d7c435cc0..2bc263e84cc2e 100644 --- a/Validation/HGCalValidation/plugins/BarrelValidator.cc +++ b/Validation/HGCalValidation/plugins/BarrelValidator.cc @@ -76,17 +76,13 @@ BarrelValidator::BarrelValidator(const edm::ParameterSet& pset) doLayerClustersPlots_(pset.getUntrackedParameter("doLayerClustersPlots")), label_layerClustersPlots_(pset.getParameter("label_layerClustersPlots")), label_LCToCPLinking_(pset.getParameter("label_LCToCPLinking")), - hits_labels_(pset.getParameter>("hits")), + hitsToken_(consumes>(pset.getParameter("hits"))), scToCpMapToken_( consumes(pset.getParameter("simClustersToCaloParticlesMap"))) { //In this way we can easily generalize to associations between other objects also. const edm::InputTag& label_cp_effic_tag = pset.getParameter("label_cp_effic"); const edm::InputTag& label_cp_fake_tag = pset.getParameter("label_cp_fake"); - for (auto& label : hits_labels_) { - hits_tokens_.push_back(consumes>(label)); - } - label_cp_effic = consumes>(label_cp_effic_tag); label_cp_fake = consumes>(label_cp_fake_tag); @@ -280,17 +276,23 @@ void BarrelValidator::dqmAnalyze(const edm::Event& event, event.getByToken(barrelHitMap_, barrelHitMapHandle); const std::unordered_map& barrelHitMap = *barrelHitMapHandle; - edm::MultiSpan barrelRechitSpan; - for (unsigned int i = 0; i < hits_tokens_.size(); ++i) { - Handle> hitsHandle; - event.getByToken(hits_tokens_[i], hitsHandle); + if (!event.getHandle(hitsToken_).isValid()) { + edm::LogWarning("BarrelValidator") << "edm::RefProdVector token is not valid."; + return; + } - if (!hitsHandle.isValid()) { - edm::LogWarning("MissingInput") << "Missing " << hits_labels_[i] << " handle."; - continue; + // Protection against missing edm::RefProdVector + const auto& hits = event.get(hitsToken_); + for (std::size_t index = 0; const auto& pfRecHitCollection : hits) { + if (pfRecHitCollection->empty()) { + edm::LogWarning("BarrelValidator") << "PFRecHitCollections #" << index << " is not valid."; } + index++; + } - barrelRechitSpan.add(*hitsHandle); + edm::MultiSpan barrelRechitSpan(hits); + if (barrelRechitSpan.size() == 0) { + edm::LogWarning("BarrelValidator") << "The PFRecHitCollection MultiSpan is empty."; } //Some general info on layers etc. @@ -519,12 +521,7 @@ void BarrelValidator::fillDescriptions(edm::ConfigurationDescriptions& descripti psd1.add("nintZ", 1100); desc.add("histoProducerAlgoBlock", psd1); } - desc.add>("hits", - { - edm::InputTag("particleFlowRecHitECAL"), - edm::InputTag("particleFlowRecHitHBHE"), - }); - + desc.add("hits", edm::InputTag("recHitMapProducer", "RefProdVectorPFRecHitCollection")); desc.add("label_lcl", edm::InputTag("hgcalMergeLayerClusters")); desc.add>("label_tst", { diff --git a/Validation/HGCalValidation/plugins/HGCalValidator.cc b/Validation/HGCalValidation/plugins/HGCalValidator.cc index 2ed59f9f7cf72..4493e34924727 100644 --- a/Validation/HGCalValidation/plugins/HGCalValidator.cc +++ b/Validation/HGCalValidation/plugins/HGCalValidator.cc @@ -97,7 +97,7 @@ HGCalValidator::HGCalValidator(const edm::ParameterSet& pset) label_candidates_(pset.getParameter("ticlCandidates")), cummatbudinxo_(pset.getParameter("cummatbudinxo")), isTICLv5_(pset.getUntrackedParameter("isticlv5")), - hits_labels_(pset.getParameter>("hits")), + hitsToken_(consumes>(pset.getParameter("hits"))), scToCpMapToken_( consumes(pset.getParameter("simClustersToCaloParticlesMap"))), cutTk_(pset.getParameter("cutTk")) { @@ -105,9 +105,6 @@ HGCalValidator::HGCalValidator(const edm::ParameterSet& pset) const edm::InputTag& label_cp_effic_tag = pset.getParameter("label_cp_effic"); const edm::InputTag& label_cp_fake_tag = pset.getParameter("label_cp_fake"); - for (auto& label : hits_labels_) { - hits_tokens_.push_back(consumes(label)); - } label_cp_effic = consumes>(label_cp_effic_tag); label_cp_fake = consumes>(label_cp_fake_tag); @@ -417,16 +414,23 @@ void HGCalValidator::dqmAnalyze(const edm::Event& event, event.getByToken(hitMap_, hitMapHandle); const std::unordered_map& hitMap = *hitMapHandle; - edm::MultiSpan rechitSpan; - for (unsigned int i = 0; i < hits_tokens_.size(); ++i) { - auto hitsHandle = event.getHandle(hits_tokens_[i]); + if (!event.getHandle(hitsToken_).isValid()) { + edm::LogWarning("HGCalValidator") << "edm::RefProdVector token is not valid."; + return; + } - if (!hitsHandle.isValid()) { - edm::LogWarning("MissingInput") << "Missing " << hits_labels_[i] << " handle."; - continue; + // Protection against missing HGCRecHitCollection + const auto& hits = event.get(hitsToken_); + for (std::size_t index = 0; const auto& hgcRecHitCollection : hits) { + if (hgcRecHitCollection->empty()) { + edm::LogWarning("HGCalValidator") << "HGCRecHitCollection #" << index << "is not valid."; } + index++; + } - rechitSpan.add(*hitsHandle); + edm::MultiSpan rechitSpan(hits); + if (rechitSpan.size() == 0) { + edm::LogWarning("HGCalValidator") << "The HGCRecHitCollection MultiSpan is empty."; } //Some general info on layers etc. @@ -783,12 +787,7 @@ void HGCalValidator::fillDescriptions(edm::ConfigurationDescriptions& descriptio psd1.add("nintZ", 1100); desc.add("histoProducerAlgoBlock", psd1); } - desc.add>("hits", - { - edm::InputTag("HGCalRecHit", "HGCEERecHits"), - edm::InputTag("HGCalRecHit", "HGCHEFRecHits"), - edm::InputTag("HGCalRecHit", "HGCHEBRecHits"), - }); + desc.add("hits", edm::InputTag("recHitMapProducer", "RefProdVectorHGCRecHitCollection")); desc.add("label_lcl", edm::InputTag("hgcalMergeLayerClusters")); desc.add>("label_tst", { diff --git a/Validation/HGCalValidation/python/HLTHGCalValidator_cff.py b/Validation/HGCalValidation/python/HLTHGCalValidator_cff.py index 3dc13b11e9729..7194a0e86374a 100644 --- a/Validation/HGCalValidation/python/HLTHGCalValidator_cff.py +++ b/Validation/HGCalValidation/python/HLTHGCalValidator_cff.py @@ -18,7 +18,7 @@ associator = cms.untracked.InputTag("hltLayerClusterCaloParticleAssociationProducer"), associatorSim = cms.untracked.InputTag("hltLayerClusterSimClusterAssociationProducer"), dirName = cms.string('HLT/HGCAL/HGCalValidator/'), - hits = cms.VInputTag("hltHGCalRecHit:HGCEERecHits", "hltHGCalRecHit:HGCHEFRecHits", "hltHGCalRecHit:HGCHEBRecHits"), + hits = cms.InputTag("hltRecHitMapProducer", "RefProdVectorHGCRecHitCollection"), hitMap = cms.InputTag("hltRecHitMapProducer","hgcalRecHitMap"), simTrackstersMap = cms.InputTag("hltTiclSimTracksters"), label_layerClustersPlots = cms.string("hltHgcalMergeLayerClusters"),