From 388f63c4bba81cd2d77345126218118bcfaa1b0e Mon Sep 17 00:00:00 2001 From: Simone Date: Fri, 21 Nov 2025 11:21:19 +0100 Subject: [PATCH 01/24] First draft of heterogeneous trackster producer --- .../alpaka/PatternRecognitionAlgoBase.h | 26 +++ .../alpaka/HeterogeneousTracksterProducer.cc | 65 ++++++++ .../PatternRecognitionByCLUEstering.dev.cc | 157 ++++++++++++++++++ .../alpaka/PatternRecognitionByCLUEstering.h | 48 ++++++ 4 files changed, 296 insertions(+) create mode 100644 RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h create mode 100644 RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc create mode 100644 RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc create mode 100644 RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h diff --git a/RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h b/RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h new file mode 100644 index 0000000000000..b5facd5456865 --- /dev/null +++ b/RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h @@ -0,0 +1,26 @@ + +#pragma once + +#include "DataFormats/HGCalReco/interface/HGCalSoAClusters.h" +#include "DataFormats/HGCalReco/interface/HGCalSoARecHitsHostCollection.h" +#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoAClustersDeviceCollection.h" +#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsExtraDeviceCollection.h" +#include "DataFormats/HGCalReco/interface/Trackster.h" + +#include + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + class PatternRecognitionAlgoBase { + protected: + bool m_verbosity; + + public: + PatternRecognitionAlgoBase(const edm::ParameterSet& conf) : m_verbosity(conf.getParameter("verbose")) {} + virtual ~PatternRecognitionAlgoBase() = default; + + virtual void makeTracksters(Queue& queue, + const HGCalSoAClustersDeviceCollection& layerClusters, + std::vector& result) = 0; + }; +} // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc b/RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc new file mode 100644 index 0000000000000..042ed86e9be5e --- /dev/null +++ b/RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc @@ -0,0 +1,65 @@ +#include +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "DataFormats/HGCalReco/interface/HGCalSoAClusters.h" +#include "DataFormats/HGCalReco/interface/HGCalSoARecHitsHostCollection.h" +#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoAClustersDeviceCollection.h" +#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsExtraDeviceCollection.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "Geometry/HGCalGeometry/interface/HGCalGeometry.h" +#include "FWCore/Utilities/interface/EDPutToken.h" +#include "DataFormats/HGCalReco/interface/Trackster.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESGetToken.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/stream/EDProducer.h" +#include "RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h" +#include "RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h" +#include "CLUEstering/CLUEstering.hpp" + +#include +#include +#include + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + class HeterogeneousTracksterProducer : public stream::EDProducer<> { + public: + HeterogeneousTracksterProducer(edm::ParameterSet const& config) + : EDProducer(config), + deviceTokenSoAClusters_{consumes(config.getParameter("layerClusters"))}, + legacyTrackstersToken_{produces()}, + algo_{std::make_unique(config)} {} + ~HeterogeneousTracksterProducer() override = default; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("layerClusters", edm::InputTag("hgcalRecHitsLayerClustersSoA")); + // Still needed? I guess I still need to save them here and then copy to algo + desc.add("rho_c", 0.6); + desc.add>("dc", {2., 2., 2}); + desc.add>("dm", {1.8, 1.8, 2}); + desc.add("verbose", false); + descriptions.addWithDefaultLabel(desc); + } + + void produce(device::Event& iEvent, device::EventSetup const& iSetup) override { + const auto& lc = iEvent.get(deviceTokenSoAClusters_); + auto tracksters = std::vector(); + auto& queue = iEvent.queue(); + algo_->makeTracksters(queue, lc, tracksters); + + iEvent.emplace(legacyTrackstersToken_, std::move(tracksters)); + } + + private: + device::EDGetToken const deviceTokenSoAClusters_; + edm::EDPutTokenT> const legacyTrackstersToken_; + std::unique_ptr algo_; + }; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl + +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/MakerMacros.h" +DEFINE_FWK_ALPAKA_MODULE(HeterogeneousTracksterProducer); diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc new file mode 100644 index 0000000000000..aaf3b1ef7219c --- /dev/null +++ b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc @@ -0,0 +1,157 @@ +#include "DataFormats/HGCalReco/interface/HGCalSoAClusters.h" +#include "DataFormats/HGCalReco/interface/HGCalSoARecHitsHostCollection.h" +#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoAClustersDeviceCollection.h" +#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsExtraDeviceCollection.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h" +#include "DataFormats/HGCalReco/interface/Trackster.h" +#include "CLUEstering/CLUEstering.hpp" + +#include "RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h" + +#include +#include +#include + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + namespace ticl = ::ticl; + + void PatternRecognitionByCLUEstering::makeTracksters(Queue& queue, + const HGCalSoAClustersDeviceCollection& lc, + std::vector& tracksters) { + auto* x = const_cast(lc.view().x().data()); + auto* y = const_cast(lc.view().y().data()); + auto* z = const_cast(lc.view().z().data()); + auto* E = const_cast(lc.view().energy().data()); + // std::unordered_map> map; + + // for (int i = 0; i < lc->metadata().size(); ++i) { + // map[z[i]].push_back(i); + // } + + const int32_t n = static_cast(lc->metadata().size()); + if (n > 0) { + auto d_clIndex = cms::alpakatools::make_device_buffer(queue, n); // temporary buffer needed by CLUEstering + auto dp_clIndex = const_cast(d_clIndex.data()); + clue::PointsDevice<3> d_points(queue, n, x, y, z, E, dp_clIndex); + if (m_verbosity) { + for (int iLC = 0; iLC < n; ++iLC) { + std::cout << "( " << x[iLC] << ", " << y[iLC] << ", " << z[iLC] << ", " << E[iLC] << " )" << std::endl; + } + } + + clue::Clusterer<3> clusterer(queue, m_dc, m_rhoc, m_dm); + clusterer.make_clusters(queue, d_points); + // create hosts points and do the copy + clue::PointsHost<3> h_points(queue, n); + clue::copyToHost(queue, h_points, d_points); + alpaka::wait(queue); + + // get LCs indices in tracksters and fill the trackster collection + const auto tsMap = clue::get_clusters(h_points); + tracksters.resize(tsMap.size()); + for (auto i = 0ul; i < tsMap.size(); ++i) { + const auto [beginLC, endLC] = tsMap.equal_range(i); + std::copy(beginLC, endLC, std::back_inserter(tracksters[i].vertices())); + tracksters[i].vertex_multiplicity().resize(tracksters[i].vertices().size(), 1); + } + + alpaka::memcpy(queue, + cms::alpakatools::make_host_view(h_points.view().coords[0], n), + cms::alpakatools::make_device_view(alpaka::getDev(queue), x, n), + static_cast(n)); + alpaka::memcpy(queue, + cms::alpakatools::make_host_view(h_points.view().coords[1], n), + cms::alpakatools::make_device_view(alpaka::getDev(queue), y, n), + static_cast(n)); + alpaka::memcpy(queue, + cms::alpakatools::make_host_view(h_points.view().coords[2], n), + cms::alpakatools::make_device_view(alpaka::getDev(queue), z, n), + static_cast(n)); + alpaka::memcpy(queue, + cms::alpakatools::make_host_view(h_points.weights(), n), + cms::alpakatools::make_device_view(alpaka::getDev(queue), E, n), + static_cast(n)); + alpaka::wait(queue); + + // compute trackster properties + // TODO: merge with previous loop + bool energyWeight = true; + auto xHost = h_points.coords(0).data(); + auto yHost = h_points.coords(1).data(); + auto zHost = h_points.coords(2).data(); + auto EHost = h_points.weights(); + // if (m_verbosity) { + // std::cout << "Event Number of LCs " << n << std::endl; + // for (const auto& [Z, indices] : map) { + // std::cout << "z = " << Z << " -> Clusters : "; + // for (auto i : indices) + // std::cout << "\t( " << xHost[i] << ", " << yHost[i] << ", " << zHost[i] << ", " << EHost[i] << ")" + // << std::endl; + // std::cout << std::endl; + // } + // } + for (auto& trackster : tracksters) { + size_t N = trackster.vertices().size(); + if (N == 0) + continue; + + Eigen::Vector3f point; + point << 0., 0., 0.; + Eigen::Vector3f barycenter; + barycenter << 0., 0., 0.; + + auto fillPoint = [&](const float x, const float y, const float z, const float weight = 1.f) { + point[0] = weight * x; + point[1] = weight * y; + point[2] = weight * z; + }; + + // Initialize this trackster with default, dummy values + trackster.setRawEnergy(0.f); + trackster.setRawEmEnergy(0.f); + trackster.setRawPt(0.f); + trackster.setRawEmPt(0.f); + + float weight = 1.f / N; + + std::vector layerClusterEnergies; + + for (size_t i = 0; i < N; ++i) { + auto lcIdx = trackster.vertices(i); + auto fraction = 1.f / trackster.vertex_multiplicity(i); + trackster.addToRawEnergy(EHost[lcIdx] * fraction); + // trackster.addToRawEmEnergy(EHost[lcIdx] * fraction); + + // Compute the weighted barycenter. + if (energyWeight) + weight = EHost[lcIdx] * fraction; + fillPoint(xHost[lcIdx], yHost[lcIdx], zHost[lcIdx], weight); + for (size_t j = 0; j < 3; ++j) + barycenter[j] += point[j]; + + layerClusterEnergies.push_back(EHost[lcIdx]); + } + float raw_energy = trackster.raw_energy(); + float inv_raw_energy = 1.f / raw_energy; + if (energyWeight) + barycenter *= inv_raw_energy; + trackster.setBarycenter(ticl::Trackster::Vector(barycenter)); + + trackster.calculateRawPt(); + trackster.calculateRawEmPt(); + if (m_verbosity) { + std::cout << " LC in TS: "; + for (const auto& lc : trackster.vertices()) + std::cout << lc << " "; + std::cout << std::endl; + std::cout << " energy raw: " << trackster.raw_energy() << std::endl; + std::cout << " barycenter: " << trackster.barycenter().x() << ", " << trackster.barycenter().y() << ", " + << trackster.barycenter().z() << std::endl; + } + } + } + } + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h new file mode 100644 index 0000000000000..557e06454e4a0 --- /dev/null +++ b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h @@ -0,0 +1,48 @@ + +#pragma once + +#include "CondCore/CondDB/interface/Exception.h" +#include "DataFormats/HGCalReco/interface/HGCalSoAClusters.h" +#include "DataFormats/HGCalReco/interface/HGCalSoARecHitsHostCollection.h" +#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoAClustersDeviceCollection.h" +#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsExtraDeviceCollection.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h" +#include "DataFormats/HGCalReco/interface/Trackster.h" + +#include +#include +#include +#include +#include + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + class PatternRecognitionByCLUEstering final : public PatternRecognitionAlgoBase { + private: + float m_rhoc; + std::array m_dc; + std::array m_dm; + + public: + PatternRecognitionByCLUEstering(const edm::ParameterSet& config) + : PatternRecognitionAlgoBase(config), m_rhoc(config.getParameter("rho_c")) { + auto dc = config.getParameter>("dc"); + auto dm = config.getParameter>("dm"); + + if (dc.size() != 3 || dm.size() != 3) { + throw cms::Exception("Configuration") << "Parameters 'dc' and 'dm' must each have exactly 3 elements."; + } + + auto to_float = [](auto x) -> float { return static_cast(x); }; + std::ranges::copy(dc | std::views::transform(to_float), m_dc.begin()); + std::ranges::copy(dm | std::views::transform(to_float), m_dm.begin()); + } + ~PatternRecognitionByCLUEstering() override = default; + + void makeTracksters(Queue& queue, + const HGCalSoAClustersDeviceCollection& lc, + std::vector& tracksters) override; + }; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE From 4032467aff728fa1473a65d598db9ad28c7151a1 Mon Sep 17 00:00:00 2001 From: Simone Date: Mon, 24 Nov 2025 11:39:25 +0100 Subject: [PATCH 02/24] Create plugin factory for alpaka pattern recognition plugins --- .../alpaka/PatternRecognitionAlgoBase.h | 4 +- .../alpaka/HeterogeneousTracksterProducer.cc | 26 +++++-- .../PatternRecognitionByCLUEstering.dev.cc | 73 +++++++++++++++---- .../alpaka/PatternRecognitionByCLUEstering.h | 3 + 4 files changed, 85 insertions(+), 21 deletions(-) diff --git a/RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h b/RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h index b5facd5456865..324d2163ee830 100644 --- a/RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h +++ b/RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h @@ -6,6 +6,7 @@ #include "DataFormats/HGCalReco/interface/alpaka/HGCalSoAClustersDeviceCollection.h" #include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsExtraDeviceCollection.h" #include "DataFormats/HGCalReco/interface/Trackster.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" #include @@ -13,10 +14,9 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { class PatternRecognitionAlgoBase { protected: - bool m_verbosity; public: - PatternRecognitionAlgoBase(const edm::ParameterSet& conf) : m_verbosity(conf.getParameter("verbose")) {} + PatternRecognitionAlgoBase(const edm::ParameterSet& conf) {} virtual ~PatternRecognitionAlgoBase() = default; virtual void makeTracksters(Queue& queue, diff --git a/RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc b/RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc index 042ed86e9be5e..142fd05e5efd0 100644 --- a/RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc +++ b/RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc @@ -8,6 +8,7 @@ #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/ParameterSet/interface/PluginDescription.h" #include "FWCore/Utilities/interface/InputTag.h" #include "Geometry/HGCalGeometry/interface/HGCalGeometry.h" #include "FWCore/Utilities/interface/EDPutToken.h" @@ -16,6 +17,7 @@ #include "HeterogeneousCore/AlpakaCore/interface/alpaka/stream/EDProducer.h" #include "RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h" #include "RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h" +#include "RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h" #include "CLUEstering/CLUEstering.hpp" #include @@ -28,19 +30,30 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { public: HeterogeneousTracksterProducer(edm::ParameterSet const& config) : EDProducer(config), + // detector_(config.getParameter("detector")), + // doNose_(detector_ == "HFNose"), deviceTokenSoAClusters_{consumes(config.getParameter("layerClusters"))}, - legacyTrackstersToken_{produces()}, - algo_{std::make_unique(config)} {} + legacyTrackstersToken_{produces()} { + auto plugin = config.getParameter("patternRecognitionBy"); + auto pluginPSet = config.getParameter("pluginPatternRecognitionBy" + plugin); + algo_ = PatternRecognitionFactoryAlpaka::get()->create(config.getParameter("patternRecognitionBy"), + pluginPSet); + } ~HeterogeneousTracksterProducer() override = default; static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; desc.add("layerClusters", edm::InputTag("hgcalRecHitsLayerClustersSoA")); - // Still needed? I guess I still need to save them here and then copy to algo + // Still needed? I guess I still need to save them here and then copy to algo desc.add("rho_c", 0.6); desc.add>("dc", {2., 2., 2}); desc.add>("dm", {1.8, 1.8, 2}); - desc.add("verbose", false); + desc.add("patternRecognitionBy", "CLUEstering"); + + edm::ParameterSetDescription pluginDesc; + pluginDesc.addNode(edm::PluginDescription("type", "CLUEstering", true)); + desc.add("pluginPatternRecognitionByCLUEstering", pluginDesc); + descriptions.addWithDefaultLabel(desc); } @@ -54,12 +67,15 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { } private: + // std::string detector_; + // bool doNose_; device::EDGetToken const deviceTokenSoAClusters_; edm::EDPutTokenT> const legacyTrackstersToken_; std::unique_ptr algo_; + std::unique_ptr myAlgoHFNose_; }; -} // namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl +} // namespace ALPAKA_ACCELERATOR_NAMESPACE #include "HeterogeneousCore/AlpakaCore/interface/alpaka/MakerMacros.h" DEFINE_FWK_ALPAKA_MODULE(HeterogeneousTracksterProducer); diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc index aaf3b1ef7219c..15c863a3ad0bf 100644 --- a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc +++ b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc @@ -6,6 +6,8 @@ #include "RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h" #include "DataFormats/HGCalReco/interface/Trackster.h" #include "CLUEstering/CLUEstering.hpp" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" #include "RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h" @@ -35,11 +37,11 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { auto d_clIndex = cms::alpakatools::make_device_buffer(queue, n); // temporary buffer needed by CLUEstering auto dp_clIndex = const_cast(d_clIndex.data()); clue::PointsDevice<3> d_points(queue, n, x, y, z, E, dp_clIndex); - if (m_verbosity) { - for (int iLC = 0; iLC < n; ++iLC) { - std::cout << "( " << x[iLC] << ", " << y[iLC] << ", " << z[iLC] << ", " << E[iLC] << " )" << std::endl; - } - } + // if (m_verbosity) { + // for (int iLC = 0; iLC < n; ++iLC) { + // std::cout << "( " << x[iLC] << ", " << y[iLC] << ", " << z[iLC] << ", " << E[iLC] << " )" << std::endl; + // } + // } clue::Clusterer<3> clusterer(queue, m_dc, m_rhoc, m_dm); clusterer.make_clusters(queue, d_points); @@ -141,17 +143,60 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { trackster.calculateRawPt(); trackster.calculateRawEmPt(); - if (m_verbosity) { - std::cout << " LC in TS: "; - for (const auto& lc : trackster.vertices()) - std::cout << lc << " "; - std::cout << std::endl; - std::cout << " energy raw: " << trackster.raw_energy() << std::endl; - std::cout << " barycenter: " << trackster.barycenter().x() << ", " << trackster.barycenter().y() << ", " - << trackster.barycenter().z() << std::endl; - } + // if (m_verbosity) { + // std::cout << " LC in TS: "; + // for (const auto& lc : trackster.vertices()) + // std::cout << lc << " "; + // std::cout << std::endl; + // std::cout << " energy raw: " << trackster.raw_energy() << std::endl; + // std::cout << " barycenter: " << trackster.barycenter().x() << ", " << trackster.barycenter().y() << ", " + // << trackster.barycenter().z() << std::endl; + // } } } } + void PatternRecognitionByCLUEstering::fillPSetDescription(::edm::ParameterSetDescription& iDesc) { + // iDesc.add("algo_verbosity", 0); + // iDesc.add>("criticalDensity", {4, 4, 4})->setComment("in GeV"); + // iDesc.add>("criticalSelfDensity", {0.15, 0.15, 0.15} /* roughly 1/(densitySiblingLayers+1) */) + // ->setComment("Minimum ratio of self_energy/local_density to become a seed."); + // iDesc.add>("densitySiblingLayers", {3, 3, 3}) + // ->setComment( + // "inclusive, layers to consider while computing local density and searching for nearestHigher higher"); + // iDesc.add>("densityEtaPhiDistanceSqr", {0.0008, 0.0008, 0.0008}) + // ->setComment("in eta,phi space, distance to consider for local density"); + // iDesc.add>("densityXYDistanceSqr", {3.24, 3.24, 3.24}) + // ->setComment("in cm, distance on the transverse plane to consider for local density"); + // iDesc.add>("kernelDensityFactor", {0.2, 0.2, 0.2}) + // ->setComment("Kernel factor to be applied to other LC while computing the local density"); + // iDesc.add("densityOnSameLayer", false); + // iDesc.add("nearestHigherOnSameLayer", false) + // ->setComment("Allow the nearestHigher to be located on the same layer"); + // iDesc.add("useAbsoluteProjectiveScale", true) + // ->setComment("Express all cuts in terms of r/z*z_0{,phi} projective variables"); + // iDesc.add("useClusterDimensionXY", false) + // ->setComment( + // "Boolean. If true use the estimated cluster radius to determine the cluster compatibility while computing " + // "the local density"); + // iDesc.add("rescaleDensityByZ", false) + // ->setComment( + // "Rescale local density by the extension of the Z 'volume' explored. The transvere dimension is, at " + // "present, " + // "fixed and factored out."); + // iDesc.add>("criticalEtaPhiDistance", {0.025, 0.025, 0.025}) + // ->setComment("Minimal distance in eta,phi space from nearestHigher to become a seed"); + // iDesc.add>("criticalXYDistance", {1.8, 1.8, 1.8}) + // ->setComment("Minimal distance in cm on the XY plane from nearestHigher to become a seed"); + // iDesc.add>("criticalZDistanceLyr", {5, 5, 5}) + // ->setComment("Minimal distance in layers along the Z axis from nearestHigher to become a seed"); + // iDesc.add>("outlierMultiplier", {2, 2, 2}) + // ->setComment("Minimal distance in transverse space from nearestHigher to become an outlier"); + // iDesc.add>("minNumLayerCluster", {2, 2, 2})->setComment("Not Inclusive"); + // iDesc.add("doPidCut", false); + // iDesc.add("cutHadProb", 0.5); + // iDesc.add("computeLocalTime", false); + // iDesc.add("usePCACleaning", false)->setComment("Enable PCA cleaning alorithm"); + } + } // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h index 557e06454e4a0..615197e5bd006 100644 --- a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h +++ b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h @@ -9,6 +9,7 @@ #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h" #include "DataFormats/HGCalReco/interface/Trackster.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" #include #include @@ -43,6 +44,8 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { void makeTracksters(Queue& queue, const HGCalSoAClustersDeviceCollection& lc, std::vector& tracksters) override; + + static void fillPSetDescription(::edm::ParameterSetDescription& iDesc); }; } // namespace ALPAKA_ACCELERATOR_NAMESPACE From 3b759881bc2ffbc4ce91ac02ca8a98c3bc424550 Mon Sep 17 00:00:00 2001 From: Simone Date: Mon, 8 Dec 2025 16:24:47 +0100 Subject: [PATCH 03/24] Add alpaka pattern recognition plugin factory --- .../alpaka/HeterogeneousTracksterProducer.cc | 8 ++-- .../PatternRecognitionByCLUEstering.dev.cc | 42 ++----------------- .../PatternRecognitionPluginFactory.dev.cc | 10 +++++ .../alpaka/PatternRecognitionPluginFactory.h | 16 +++++++ 4 files changed, 33 insertions(+), 43 deletions(-) create mode 100644 RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.dev.cc create mode 100644 RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h diff --git a/RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc b/RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc index 142fd05e5efd0..0d82d89a20cd0 100644 --- a/RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc +++ b/RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc @@ -43,11 +43,11 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; - desc.add("layerClusters", edm::InputTag("hgcalRecHitsLayerClustersSoA")); + desc.add("layerClusters", edm::InputTag("hgcalSoALayerClusters")); // Still needed? I guess I still need to save them here and then copy to algo - desc.add("rho_c", 0.6); - desc.add>("dc", {2., 2., 2}); - desc.add>("dm", {1.8, 1.8, 2}); + // desc.add("rho_c", 0.6); + // desc.add>("dc", {2., 2., 2}); + // desc.add>("dm", {1.8, 1.8, 2}); desc.add("patternRecognitionBy", "CLUEstering"); edm::ParameterSetDescription pluginDesc; diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc index 15c863a3ad0bf..df5f7ed48c422 100644 --- a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc +++ b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc @@ -158,45 +158,9 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { void PatternRecognitionByCLUEstering::fillPSetDescription(::edm::ParameterSetDescription& iDesc) { // iDesc.add("algo_verbosity", 0); - // iDesc.add>("criticalDensity", {4, 4, 4})->setComment("in GeV"); - // iDesc.add>("criticalSelfDensity", {0.15, 0.15, 0.15} /* roughly 1/(densitySiblingLayers+1) */) - // ->setComment("Minimum ratio of self_energy/local_density to become a seed."); - // iDesc.add>("densitySiblingLayers", {3, 3, 3}) - // ->setComment( - // "inclusive, layers to consider while computing local density and searching for nearestHigher higher"); - // iDesc.add>("densityEtaPhiDistanceSqr", {0.0008, 0.0008, 0.0008}) - // ->setComment("in eta,phi space, distance to consider for local density"); - // iDesc.add>("densityXYDistanceSqr", {3.24, 3.24, 3.24}) - // ->setComment("in cm, distance on the transverse plane to consider for local density"); - // iDesc.add>("kernelDensityFactor", {0.2, 0.2, 0.2}) - // ->setComment("Kernel factor to be applied to other LC while computing the local density"); - // iDesc.add("densityOnSameLayer", false); - // iDesc.add("nearestHigherOnSameLayer", false) - // ->setComment("Allow the nearestHigher to be located on the same layer"); - // iDesc.add("useAbsoluteProjectiveScale", true) - // ->setComment("Express all cuts in terms of r/z*z_0{,phi} projective variables"); - // iDesc.add("useClusterDimensionXY", false) - // ->setComment( - // "Boolean. If true use the estimated cluster radius to determine the cluster compatibility while computing " - // "the local density"); - // iDesc.add("rescaleDensityByZ", false) - // ->setComment( - // "Rescale local density by the extension of the Z 'volume' explored. The transvere dimension is, at " - // "present, " - // "fixed and factored out."); - // iDesc.add>("criticalEtaPhiDistance", {0.025, 0.025, 0.025}) - // ->setComment("Minimal distance in eta,phi space from nearestHigher to become a seed"); - // iDesc.add>("criticalXYDistance", {1.8, 1.8, 1.8}) - // ->setComment("Minimal distance in cm on the XY plane from nearestHigher to become a seed"); - // iDesc.add>("criticalZDistanceLyr", {5, 5, 5}) - // ->setComment("Minimal distance in layers along the Z axis from nearestHigher to become a seed"); - // iDesc.add>("outlierMultiplier", {2, 2, 2}) - // ->setComment("Minimal distance in transverse space from nearestHigher to become an outlier"); - // iDesc.add>("minNumLayerCluster", {2, 2, 2})->setComment("Not Inclusive"); - // iDesc.add("doPidCut", false); - // iDesc.add("cutHadProb", 0.5); - // iDesc.add("computeLocalTime", false); - // iDesc.add("usePCACleaning", false)->setComment("Enable PCA cleaning alorithm"); + iDesc.add("rho_c", 6.); + iDesc.add>("dc", {2., 2., 2.}); + iDesc.add>("dm", {1.8, 1.8, 2.}); } } // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.dev.cc b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.dev.cc new file mode 100644 index 0000000000000..0fb23971554b3 --- /dev/null +++ b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.dev.cc @@ -0,0 +1,10 @@ +#include "RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h" +#include "RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h" +#include "FWCore/ParameterSet/interface/ValidatedPluginFactoryMacros.h" +#include "FWCore/ParameterSet/interface/ValidatedPluginMacros.h" + +EDM_REGISTER_VALIDATED_PLUGINFACTORY(PatternRecognitionFactoryAlpaka, "PatternRecognitionFactoryAlpaka"); +// EDM_REGISTER_VALIDATED_PLUGINFACTORY(PatternRecognitionHFNoseFactoryAlpaka, "PatternRecognitionHFNoseFactoryAlpaka"); +DEFINE_EDM_VALIDATED_PLUGIN(PatternRecognitionFactoryAlpaka, + ALPAKA_ACCELERATOR_NAMESPACE::PatternRecognitionByCLUEstering, + "CLUEstering"); diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h new file mode 100644 index 0000000000000..a153c0e82eaea --- /dev/null +++ b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h @@ -0,0 +1,16 @@ +#ifndef RecoHGCal_TICL_PatternRecognitionPluginFactory_H +#define RecoHGCal_TICL_PatternRecognitionPluginFactory_H + +#include "FWCore/PluginManager/interface/PluginFactory.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h" +#include "RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h" +#include "RecoHGCal/TICL/interface/GlobalCache.h" + + using PatternRecognitionFactoryAlpaka = + ::edmplugin::PluginFactory; + // using PatternRecognitionHFNoseFactoryAlpaka = + // edmplugin::PluginFactory; + +#endif From cfb906ec6ebd1c672774bf1092d8fb8e17bc0876 Mon Sep 17 00:00:00 2001 From: Simone Date: Wed, 17 Dec 2025 11:21:10 +0100 Subject: [PATCH 04/24] Use scalar values for CLUEstering parameters --- .../PatternRecognitionByCLUEstering.dev.cc | 4 ++-- .../alpaka/PatternRecognitionByCLUEstering.h | 19 ++++++------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc index df5f7ed48c422..ce27fbdc4ddbb 100644 --- a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc +++ b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc @@ -159,8 +159,8 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { void PatternRecognitionByCLUEstering::fillPSetDescription(::edm::ParameterSetDescription& iDesc) { // iDesc.add("algo_verbosity", 0); iDesc.add("rho_c", 6.); - iDesc.add>("dc", {2., 2., 2.}); - iDesc.add>("dm", {1.8, 1.8, 2.}); + iDesc.add("dc", 2.); + iDesc.add("dm", 1.8); } } // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h index 615197e5bd006..a6edb1857c3f1 100644 --- a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h +++ b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h @@ -22,22 +22,15 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { class PatternRecognitionByCLUEstering final : public PatternRecognitionAlgoBase { private: float m_rhoc; - std::array m_dc; - std::array m_dm; + float m_dc; + float m_dm; public: PatternRecognitionByCLUEstering(const edm::ParameterSet& config) - : PatternRecognitionAlgoBase(config), m_rhoc(config.getParameter("rho_c")) { - auto dc = config.getParameter>("dc"); - auto dm = config.getParameter>("dm"); - - if (dc.size() != 3 || dm.size() != 3) { - throw cms::Exception("Configuration") << "Parameters 'dc' and 'dm' must each have exactly 3 elements."; - } - - auto to_float = [](auto x) -> float { return static_cast(x); }; - std::ranges::copy(dc | std::views::transform(to_float), m_dc.begin()); - std::ranges::copy(dm | std::views::transform(to_float), m_dm.begin()); + : PatternRecognitionAlgoBase(config), + m_rhoc(config.getParameter("rho_c")), + m_dc(config.getParameter("dc")), + m_dm(config.getParameter("dm")) { } ~PatternRecognitionByCLUEstering() override = default; From 49a632927d9b76963bf48717f361bbc67d68328f Mon Sep 17 00:00:00 2001 From: Simone Date: Wed, 17 Dec 2025 13:53:01 +0100 Subject: [PATCH 05/24] Use weighted chebyshev metric for cluestering --- .../TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc index ce27fbdc4ddbb..cf1f6c783db54 100644 --- a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc +++ b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc @@ -44,7 +44,8 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { // } clue::Clusterer<3> clusterer(queue, m_dc, m_rhoc, m_dm); - clusterer.make_clusters(queue, d_points); + std::array weights{{1.f, 1., 2.f}}; + clusterer.make_clusters(queue, d_points, clue::metrics::WeightedChebyshev<3>(weights)); // create hosts points and do the copy clue::PointsHost<3> h_points(queue, n); clue::copyToHost(queue, h_points, d_points); From ead3c3d9ae957adf7c0cc2ed6a9805da279eed02 Mon Sep 17 00:00:00 2001 From: Simone Date: Fri, 19 Dec 2025 14:35:58 +0100 Subject: [PATCH 06/24] Add TICL heterogeneous producer to BuildFile --- RecoHGCal/TICL/plugins/BuildFile.xml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/RecoHGCal/TICL/plugins/BuildFile.xml b/RecoHGCal/TICL/plugins/BuildFile.xml index 7bd12c3249e67..cc98e4a73ee8f 100644 --- a/RecoHGCal/TICL/plugins/BuildFile.xml +++ b/RecoHGCal/TICL/plugins/BuildFile.xml @@ -38,3 +38,24 @@ + + + + + + + + + + + + + + + + + + + + + From dbf3a72355ab24e276176d5a9adc6398a422ad43 Mon Sep 17 00:00:00 2001 From: Simone Date: Thu, 29 Jan 2026 12:14:17 +0100 Subject: [PATCH 07/24] Implement `CaloClusterSoA` and produce it in `HGCalLayerClusterProducer` Co-authored-by: Felice Pantaleo Co-authored-by: Wahid Redjeb Co-authored-by: Aurora Perego Co-authored-by: Leonardo Beltrame --- DataFormats/CaloRecHit/BuildFile.xml | 4 ++ .../interface/CaloClusterHostCollection.h | 12 ++++ .../CaloRecHit/interface/CaloClusterSoA.h | 40 +++++++++++ .../alpaka/CaloClusterDeviceCollection.h | 12 ++++ .../CaloRecHit/src/alpaka/classes_cuda.h | 4 ++ .../src/alpaka/classes_cuda_def.xml | 5 ++ .../CaloRecHit/src/alpaka/classes_rocm.h | 4 ++ .../src/alpaka/classes_rocm_def.xml | 5 ++ DataFormats/CaloRecHit/src/classes.h | 2 + DataFormats/CaloRecHit/src/classes_def.xml | 3 + DataFormats/CaloRecHit/test/BuildFile.xml | 2 +- .../TICL/plugins/alpaka/ClusterFilterBase.h | 22 ++++++ .../plugins/alpaka/ClusterFilterByAlgo.dev.cc | 19 +++++ .../TICL/plugins/alpaka/ClusterFilterByAlgo.h | 2 + .../alpaka/ClusterFilterByAlgoAndSize.h | 0 .../interface/HGCalClusteringAlgoBase.h | 5 +- .../plugins/HGCalCLUEAlgo.cc | 48 ++++++++----- .../HGCalRecProducers/plugins/HGCalCLUEAlgo.h | 3 +- .../plugins/HGCalLayerClusterProducer.cc | 72 +++++++++++-------- 19 files changed, 212 insertions(+), 52 deletions(-) create mode 100644 DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h create mode 100644 DataFormats/CaloRecHit/interface/CaloClusterSoA.h create mode 100644 DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h create mode 100644 DataFormats/CaloRecHit/src/alpaka/classes_cuda.h create mode 100644 DataFormats/CaloRecHit/src/alpaka/classes_cuda_def.xml create mode 100644 DataFormats/CaloRecHit/src/alpaka/classes_rocm.h create mode 100644 DataFormats/CaloRecHit/src/alpaka/classes_rocm_def.xml create mode 100644 RecoHGCal/TICL/plugins/alpaka/ClusterFilterBase.h create mode 100644 RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.dev.cc create mode 100644 RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.h create mode 100644 RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h diff --git a/DataFormats/CaloRecHit/BuildFile.xml b/DataFormats/CaloRecHit/BuildFile.xml index 135aabf10cd07..ded3498780221 100644 --- a/DataFormats/CaloRecHit/BuildFile.xml +++ b/DataFormats/CaloRecHit/BuildFile.xml @@ -4,6 +4,10 @@ + + + + diff --git a/DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h b/DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h new file mode 100644 index 0000000000000..b6dfb967b848e --- /dev/null +++ b/DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h @@ -0,0 +1,12 @@ + +#pragma once + +#include "DataFormats/CaloRecHit/interface/CaloClusterSoA.h" +#include "DataFormats/Portable/interface/PortableHostCollection.h" +#include + +namespace reco { + + using CaloClusterHostCollection = PortableHostCollection; + +} // namespace reco diff --git a/DataFormats/CaloRecHit/interface/CaloClusterSoA.h b/DataFormats/CaloRecHit/interface/CaloClusterSoA.h new file mode 100644 index 0000000000000..4b177fe1b0dd4 --- /dev/null +++ b/DataFormats/CaloRecHit/interface/CaloClusterSoA.h @@ -0,0 +1,40 @@ + +#pragma once + +// Authors: Simone Balducci, Felice Pantaleo, Wahid Redjeb, Aurora Perego, Leonardo Beltrame + +#include "DataFormats/SoATemplate/interface/SoABlocks.h" +#include "DataFormats/SoATemplate/interface/SoALayout.h" +#include "DataFormats/CaloRecHit/interface/CaloCluster.h" +#include "DataFormats/CaloRecHit/interface/CaloID.h" +#include "DataFormats/DetId/interface/DetId.h" + +namespace reco { + + GENERATE_SOA_LAYOUT( + CaloClusterSoAPosition, SOA_COLUMN(float, x), SOA_COLUMN(float, y), SOA_COLUMN(float, z), SOA_COLUMN(int, cells)) + + GENERATE_SOA_LAYOUT(CaloClusterSoAEnergy, + SOA_COLUMN(float, energy), + SOA_COLUMN(float, correctedEnergy), + SOA_COLUMN(float, correctedEnergyUncertainty)) + + GENERATE_SOA_LAYOUT(CaloClusterSoAIndexes, + SOA_COLUMN(CaloID, caloID), + SOA_COLUMN(CaloCluster::AlgoID, algoID), + SOA_COLUMN(DetId, seedID), + SOA_COLUMN(uint32_t, flags)) + + GENERATE_SOA_LAYOUT(CaloClusterSoATiming, SOA_COLUMN(float, time), SOA_COLUMN(float, timeError)) + + GENERATE_SOA_BLOCKS(CaloClusterSoALayout, + SOA_BLOCK(position, CaloClusterSoAPosition), + SOA_BLOCK(energy, CaloClusterSoAEnergy), + SOA_BLOCK(indexes, CaloClusterSoAIndexes), + SOA_BLOCK(timing, CaloClusterSoATiming)) + + using CaloClusterSoA = CaloClusterSoALayout<>; + using CaloClusterSoAView = CaloClusterSoA::View; + using CaloClusterSoAConstView = CaloClusterSoA::ConstView; + +} // namespace reco diff --git a/DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h b/DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h new file mode 100644 index 0000000000000..a0e5ce9a77ab6 --- /dev/null +++ b/DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h @@ -0,0 +1,12 @@ + +#pragma once + +#include "DataFormats/Portable/interface/alpaka/PortableCollection.h" +#include "DataFormats/CaloRecHit/interface/CaloClusterSoA.h" +#include + +namespace ALPAKA_ACCELERATOR_NAMESPACE::reco { + + using CaloClusterDeviceCollection = PortableCollection<::reco::CaloClusterSoA>; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE::reco diff --git a/DataFormats/CaloRecHit/src/alpaka/classes_cuda.h b/DataFormats/CaloRecHit/src/alpaka/classes_cuda.h new file mode 100644 index 0000000000000..5594d8aabd1af --- /dev/null +++ b/DataFormats/CaloRecHit/src/alpaka/classes_cuda.h @@ -0,0 +1,4 @@ +#include "DataFormats/Common/interface/DeviceProduct.h" +#include "DataFormats/Common/interface/Wrapper.h" +#include "DataFormats/CaloRecHit/interface/CaloClusterSoA.h" +#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" diff --git a/DataFormats/CaloRecHit/src/alpaka/classes_cuda_def.xml b/DataFormats/CaloRecHit/src/alpaka/classes_cuda_def.xml new file mode 100644 index 0000000000000..5d5dba63ce18c --- /dev/null +++ b/DataFormats/CaloRecHit/src/alpaka/classes_cuda_def.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/DataFormats/CaloRecHit/src/alpaka/classes_rocm.h b/DataFormats/CaloRecHit/src/alpaka/classes_rocm.h new file mode 100644 index 0000000000000..5594d8aabd1af --- /dev/null +++ b/DataFormats/CaloRecHit/src/alpaka/classes_rocm.h @@ -0,0 +1,4 @@ +#include "DataFormats/Common/interface/DeviceProduct.h" +#include "DataFormats/Common/interface/Wrapper.h" +#include "DataFormats/CaloRecHit/interface/CaloClusterSoA.h" +#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" diff --git a/DataFormats/CaloRecHit/src/alpaka/classes_rocm_def.xml b/DataFormats/CaloRecHit/src/alpaka/classes_rocm_def.xml new file mode 100644 index 0000000000000..e00ae6dc1a263 --- /dev/null +++ b/DataFormats/CaloRecHit/src/alpaka/classes_rocm_def.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/DataFormats/CaloRecHit/src/classes.h b/DataFormats/CaloRecHit/src/classes.h index 1bd0a0724b72c..7cb08d18f2403 100644 --- a/DataFormats/CaloRecHit/src/classes.h +++ b/DataFormats/CaloRecHit/src/classes.h @@ -6,3 +6,5 @@ #include "DataFormats/CaloRecHit/interface/CaloCluster.h" #include "DataFormats/CaloRecHit/interface/CaloClusterFwd.h" #include "DataFormats/CaloRecHit/interface/CaloClusterCollection.h" +#include "DataFormats/CaloRecHit/interface/CaloClusterSoA.h" +#include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" diff --git a/DataFormats/CaloRecHit/src/classes_def.xml b/DataFormats/CaloRecHit/src/classes_def.xml index fa250a91eb62d..cfbdfd4587fa9 100644 --- a/DataFormats/CaloRecHit/src/classes_def.xml +++ b/DataFormats/CaloRecHit/src/classes_def.xml @@ -31,4 +31,7 @@ + + + diff --git a/DataFormats/CaloRecHit/test/BuildFile.xml b/DataFormats/CaloRecHit/test/BuildFile.xml index 8f507461fbb6b..77266cb45b155 100644 --- a/DataFormats/CaloRecHit/test/BuildFile.xml +++ b/DataFormats/CaloRecHit/test/BuildFile.xml @@ -9,6 +9,6 @@ - + diff --git a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterBase.h b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterBase.h new file mode 100644 index 0000000000000..e586bb67ab2e5 --- /dev/null +++ b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterBase.h @@ -0,0 +1,22 @@ + +#pragma once + +#include "DataFormats/HGCalReco/interface/Common.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" + +#include +#include + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + class ClusterFilterBase { + public: + explicit ClusterFilterBase(const edm::ParameterSet&) = default; + virtual ~ClusterFilterBase() = default; + + virtual void filter(const HGCalSoAClustersDeviceCollection& layerClusters, + std::vector& layerClustersMask, + hgcal::RecHitTools& rhtools) const = 0; + }; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.dev.cc b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.dev.cc new file mode 100644 index 0000000000000..8762ff29e5bc5 --- /dev/null +++ b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.dev.cc @@ -0,0 +1,19 @@ + +#include +#include + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + struct KernelFilterLayerClusterByAlgo { + template + ALPAKA_ACC_FN void operator()(const TAcc& acc, + const int32_t* layerClusterAlgoId, + const int32_t* algo_number, + int32_t* layerClusterMask, + int32_t size) const { + for (auto idx : alpaka::uniformElements(acc, size)) { + } + } + }; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.h b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.h new file mode 100644 index 0000000000000..139597f9cb07c --- /dev/null +++ b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.h @@ -0,0 +1,2 @@ + + diff --git a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h b/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h index 152b8b8158d82..1b14a3d251b4f 100644 --- a/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h +++ b/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h @@ -4,6 +4,7 @@ #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/ConsumesCollector.h" +#include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" #include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h" #include "DataFormats/Math/interface/Point3D.h" @@ -61,7 +62,7 @@ class HGCalClusteringAlgoBase { virtual void populate(const HGCRecHitCollection &hits) = 0; virtual void populate(const reco::PFRecHitCollection &hits) = 0; virtual void makeClusters() = 0; - virtual std::vector getClusters(bool) = 0; + virtual reco::CaloClusterHostCollection getClusters(bool) = 0; virtual void reset() = 0; virtual hgcal_clustering::Density getDensity() { return {}; }; //implementation is in some child class virtual void getEventSetupPerAlgorithm(const edm::EventSetup &es) {} //implementation is in some child class @@ -99,6 +100,8 @@ class HGCalClusteringAlgoBase { // The vector of clusters std::vector clusters_v_; + // reco::CaloClusterHostCollection layer_clusters_; + hgcal::RecHitTools rhtools_; // The algo id diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc index 28b5999619f7d..2f6f45d8f2e1f 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc @@ -1,6 +1,7 @@ #include "RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h" // Geometry +#include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" #include "DataFormats/HcalDetId/interface/HcalSubdetector.h" #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h" #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h" @@ -134,7 +135,7 @@ void HGCalCLUEAlgoT::makeClusters() { } template -std::vector HGCalCLUEAlgoT::getClusters(bool) { +reco::CaloClusterHostCollection HGCalCLUEAlgoT::getClusters(bool) { std::vector offsets(numberOfClustersPerLayer_.size(), 0); int maxClustersOnLayer = numberOfClustersPerLayer_[0]; @@ -146,9 +147,14 @@ std::vector HGCalCLUEAlgoT::getClusters(bool) { } auto totalNumberOfClusters = offsets.back() + numberOfClustersPerLayer_.back(); - clusters_v_.resize(totalNumberOfClusters); + // clusters_v_.resize(totalNumberOfClusters); std::vector> cellsIdInCluster; cellsIdInCluster.reserve(maxClustersOnLayer); + reco::CaloClusterHostCollection layer_clusters(cms::alpakatools::host(), + totalNumberOfClusters, + totalNumberOfClusters, + totalNumberOfClusters, + totalNumberOfClusters); for (unsigned int layerId = 0; layerId < 2 * maxlayer_ + 2; ++layerId) { cellsIdInCluster.resize(numberOfClustersPerLayer_[layerId]); @@ -165,14 +171,14 @@ std::vector HGCalCLUEAlgoT::getClusters(bool) { std::vector> thisCluster; for (auto& cl : cellsIdInCluster) { - float maxEnergyValue = std::numeric_limits::min(); - int maxEnergyCellIndex = -1; + auto maxEnergyValue = std::numeric_limits::min(); + auto maxEnergyCellIndex = -1; DetId maxEnergyDetId; - float energy = 0.f; - int seedDetId = -1; - float x = 0.f; - float y = 0.f; - float z = cellsOnLayer.layerDim3; + auto energy = 0.f; + auto seedDetId = -1; + auto x = 0.f; + auto y = 0.f; + auto z = cellsOnLayer.layerDim3; // TODO Felice: maybe use the seed for the position calculation for (auto cellIdx : cl) { energy += cellsOnLayer.weight[cellIdx]; @@ -187,8 +193,8 @@ std::vector HGCalCLUEAlgoT::getClusters(bool) { } } - float total_weight_log = 0.f; - float total_weight = energy; + auto total_weight_log = 0.f; + auto total_weight = energy; if constexpr (std::is_same_v) { auto thick = rhtools_.getSiThickIndex(maxEnergyDetId); @@ -215,27 +221,33 @@ std::vector HGCalCLUEAlgoT::getClusters(bool) { } if (total_weight != 0.) { - float inv_tot_weight = 1.f / total_weight; + auto inv_tot_weight = 1.f / total_weight; x *= inv_tot_weight; y *= inv_tot_weight; } else { x = cellsOnLayer.dim1[maxEnergyCellIndex]; y = cellsOnLayer.dim2[maxEnergyCellIndex]; } - math::XYZPoint position = math::XYZPoint(x, y, z); auto globalClusterIndex = cellsOnLayer.clusterIndex[cl[0]] + firstClusterIdx; - clusters_v_[globalClusterIndex] = - reco::BasicCluster(energy, position, reco::CaloID::DET_HGCAL_ENDCAP, thisCluster, algoId_); - clusters_v_[globalClusterIndex].setSeed(seedDetId); - thisCluster.clear(); + layer_clusters.view().position().x()[globalClusterIndex] = x; + layer_clusters.view().position().y()[globalClusterIndex] = y; + layer_clusters.view().position().z()[globalClusterIndex] = z; + layer_clusters.view().energy().energy()[globalClusterIndex] = energy; + layer_clusters.view().energy().correctedEnergy()[globalClusterIndex] = -1.f; + layer_clusters.view().energy().correctedEnergyUncertainty()[globalClusterIndex] = -1.f; + layer_clusters.view().indexes().caloID()[globalClusterIndex] = reco::CaloID::DET_HGCAL_ENDCAP; + layer_clusters.view().indexes().algoID()[globalClusterIndex] = algoId_; + layer_clusters.view().indexes().seedID()[globalClusterIndex] = seedDetId; + layer_clusters.view().indexes().flags()[globalClusterIndex] = 0; } cellsIdInCluster.clear(); } - return clusters_v_; + return layer_clusters; } + template void HGCalCLUEAlgoT::calculateLocalDensity(const T& lt, const unsigned int layerId, diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h index c31bf4ccfba95..815484a72d9ed 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h @@ -5,6 +5,7 @@ #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" #include "DataFormats/DetId/interface/DetId.h" #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" #include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h" @@ -73,7 +74,7 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { void makeClusters() override; // this is the method to get the cluster collection out - std::vector getClusters(bool) override; + reco::CaloClusterHostCollection getClusters(bool) override; void reset() override { clusters_v_.clear(); diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc index f03d3bc57669c..08506fe839f32 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc @@ -9,12 +9,15 @@ #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/ParameterSet/interface/ParameterSetDescription.h" #include "FWCore/ParameterSet/interface/PluginDescription.h" +#include "HeterogeneousCore/AlpakaInterface/interface/host.h" + #include "RecoParticleFlow/PFClusterProducer/interface/RecHitTopologicalCleanerBase.h" #include "RecoParticleFlow/PFClusterProducer/interface/SeedFinderBase.h" #include "RecoParticleFlow/PFClusterProducer/interface/InitialClusteringStepBase.h" @@ -31,8 +34,7 @@ #include "DataFormats/ParticleFlowReco/interface/PFCluster.h" #include "DataFormats/Common/interface/ValueMap.h" - -#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" #if DEBUG_CLUSTERS_ALPAKA #include "RecoLocalCalo/HGCalRecProducers/interface/DumpClustersDetails.h" @@ -137,9 +139,10 @@ HGCalLayerClusterProducer::HGCalLayerClusterProducer(const edm::ParameterSet& ps positionDeltaRho2_ = pluginPSet.getParameter("positionDeltaRho2"); produces>("InitialLayerClustersMask"); - produces>(); + produces(); + // produces>(); //time for layer clusters - produces>>(timeClname_); + // produces>>(timeClname_); } void HGCalLayerClusterProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { @@ -240,8 +243,6 @@ std::pair HGCalLayerClusterProducer::calculateTime( void HGCalLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& es) { edm::Handle hits; - std::unique_ptr> clusters(new std::vector); - edm::ESHandle geom = es.getHandle(caloGeomToken_); rhtools_.setGeometry(*geom); algo_->getEventSetup(es, rhtools_); @@ -258,22 +259,24 @@ void HGCalLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& } algo_->makeClusters(); + + auto clusters = std::make_unique(new reco::CaloClusterHostCollection); *clusters = algo_->getClusters(false); std::vector> times; - times.reserve(clusters->size()); - - for (unsigned i = 0; i < clusters->size(); ++i) { - reco::CaloCluster& sCl = (*clusters)[i]; - if (!calculatePositionInAlgo_) { - sCl.setPosition(calculatePosition(hitmap, sCl.hitsAndFractions())); - } - if (detector_ != "BH") { - times.push_back(calculateTime(hitmap, sCl.hitsAndFractions(), sCl.size())); - } else { - times.push_back(std::pair(-99.f, -1.f)); - } - } + times.reserve(clusters->view().metadata().size()); + + // for (unsigned i = 0; i < legacy_clusters->size(); ++i) { + // reco::CaloCluster& sCl = (*legacy_clusters)[i]; + // if (!calculatePositionInAlgo_) { + // sCl.setPosition(calculatePosition(hitmap, sCl.hitsAndFractions())); + // } + // if (detector_ != "BH") { + // times.push_back(calculateTime(hitmap, sCl.hitsAndFractions(), sCl.size())); + // } else { + // times.push_back(std::pair(-99.f, -1.f)); + // } + // } #if DEBUG_CLUSTERS_ALPAKA hgcalUtils::DumpClusters dumper; @@ -281,22 +284,29 @@ void HGCalLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& auto lumiNumber = evt.eventAuxiliary().luminosityBlock(); auto evtNumber = evt.eventAuxiliary().id().event(); - dumper.dumpInfos(*clusters, moduleLabel_, runNumber, lumiNumber, evtNumber, true); + dumper.dumpInfos(*legacy_clusters, moduleLabel_, runNumber, lumiNumber, evtNumber, true); #endif - auto clusterHandle = evt.put(std::move(clusters)); + // auto clusterHandle = evt.put(std::move(clusters)); - if (detector_ == "HFNose") { - std::unique_ptr> layerClustersMask(new std::vector); - layerClustersMask->resize(clusterHandle->size(), 1.0); - evt.put(std::move(layerClustersMask), "InitialLayerClustersMask"); - } + // if (detector_ == "HFNose") { + // std::unique_ptr> layerClustersMask(new std::vector); + // layerClustersMask->resize(legacy_clusters->size(), 1.0); + // evt.put(std::move(layerClustersMask), "InitialLayerClustersMask"); + // } + + // auto timeCl = std::make_unique>>(); + // edm::ValueMap>::Filler filler(*timeCl); + // filler.insert(*legacy_clusters, times.begin(), times.end()); + // filler.fill(); + // evt.put(std::move(timeCl), timeClname_); + + // for (auto i = 0; i < timeCl->size(); ++i) { + // clusters->view().timing().time()[i] = (*timeCl)[i].first; + // clusters->view().timing().timeError()[i] = (*timeCl)[i].second; + // } - auto timeCl = std::make_unique>>(); - edm::ValueMap>::Filler filler(*timeCl); - filler.insert(clusterHandle, times.begin(), times.end()); - filler.fill(); - evt.put(std::move(timeCl), timeClname_); + evt.put(std::move(clusters)); algo_->reset(); } From 7b03afe81eec8eaa1d65dad425e95a55a93ca986 Mon Sep 17 00:00:00 2001 From: Simone Date: Mon, 16 Mar 2026 16:54:34 +0100 Subject: [PATCH 08/24] [WIP] use `CLUEstering` for legacy layer clusters --- .../plugins/HGCalCLUEAlgo.cc | 419 ++++-------------- 1 file changed, 85 insertions(+), 334 deletions(-) diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc index 2f6f45d8f2e1f..5e649bd95ce43 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc @@ -3,6 +3,8 @@ // Geometry #include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" #include "DataFormats/HcalDetId/interface/HcalSubdetector.h" +#include "DataFormats/TICL/interface/AssociationMap.h" +#include "DataFormats/TICL/interface/FillAssociator.h" #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h" #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h" #include "Geometry/Records/interface/IdealGeometryRecord.h" @@ -10,15 +12,17 @@ #include "RecoEcal/EgammaCoreTools/interface/PositionCalc.h" // #include "DataFormats/CaloRecHit/interface/CaloID.h" -#include "oneapi/tbb/task_arena.h" +#include "DataFormats/DetId/interface/DetId.h" + +#include "CLUEstering/CLUEstering.hpp" #include "oneapi/tbb.h" +#include "oneapi/tbb/task_arena.h" #include -#include "DataFormats/DetId/interface/DetId.h" using namespace hgcal_clustering; template -void HGCalCLUEAlgoT::getEventSetupPerAlgorithm(const edm::EventSetup& es) { +void HGCalCLUEAlgoT::getEventSetupPerAlgorithm(const edm::EventSetup &es) { cells_.clear(); numberOfClustersPerLayer_.clear(); cells_.resize(2 * (maxlayer_ + 1)); @@ -26,7 +30,7 @@ void HGCalCLUEAlgoT::getEventSetupPerAlgorithm(const edm::EventSetu } template -void HGCalCLUEAlgoT::populate(const HGCRecHitCollection& hits) { +void HGCalCLUEAlgoT::populate(const HGCRecHitCollection &hits) { // loop over all hits and create the Hexel structure, skip energies below ecut if (dependSensor_) { // for each layer and wafer calculate the thresholds (sigmaNoise and energy) @@ -35,7 +39,7 @@ void HGCalCLUEAlgoT::populate(const HGCRecHitCollection& hits) { } for (unsigned int i = 0; i < hits.size(); ++i) { - const HGCRecHit& hgrh = hits[i]; + const HGCRecHit &hgrh = hits[i]; DetId detid = hgrh.detid(); unsigned int layerOnSide = (rhtools_.getLayerWithOffset(detid) - 1); @@ -80,54 +84,36 @@ void HGCalCLUEAlgoT::populate(const HGCRecHitCollection& hits) { } } -template -void HGCalCLUEAlgoT::prepareDataStructures(unsigned int l) { - auto cellsSize = cells_[l].detid.size(); - cells_[l].rho.resize(cellsSize, 0.f); - cells_[l].delta.resize(cellsSize, 9999999); - cells_[l].nearestHigher.resize(cellsSize, -1); - cells_[l].clusterIndex.resize(cellsSize, -1); - cells_[l].followers.resize(cellsSize); - cells_[l].isSeed.resize(cellsSize, false); -} - // Create a vector of Hexels associated to one cluster from a collection of // HGCalRecHits - this can be used directly to make the final cluster list - // this method can be invoked multiple times for the same event with different // input (reset should be called between events) template void HGCalCLUEAlgoT::makeClusters() { - // assign all hits in each layer to a cluster core - tbb::this_task_arena::isolate([&] { - tbb::parallel_for(size_t(0), size_t(2 * maxlayer_ + 2), [&](size_t i) { - prepareDataStructures(i); - T lt; - lt.clear(); - lt.fill(cells_[i].dim1, cells_[i].dim2); - - float delta; - if constexpr (std::is_same_v) { - // maximum search distance (critical distance) for local density calculation - float delta_c; - if (i % maxlayer_ < lastLayerEE_) - delta_c = vecDeltas_[0]; - else if (i % maxlayer_ < (firstLayerBH_ - 1)) - delta_c = vecDeltas_[1]; - else - delta_c = vecDeltas_[2]; - delta = delta_c; - } else { - float delta_r = vecDeltas_[3]; - delta = delta_r; - } - LogDebug("HGCalCLUEAlgo") << "maxlayer: " << maxlayer_ << " lastLayerEE: " << lastLayerEE_ - << " firstLayerBH: " << firstLayerBH_ << "\n"; - - calculateLocalDensity(lt, i, delta); - calculateDistanceToHigher(lt, i, delta); - numberOfClustersPerLayer_[i] = findAndAssignClusters(i, delta); - }); - }); + float delta; + if constexpr (std::is_same_v) { + // maximum search distance (critical distance) for local density + // calculation + float delta_c; + if (i % maxlayer_ < lastLayerEE_) + delta_c = vecDeltas_[0]; + else if (i % maxlayer_ < (firstLayerBH_ - 1)) + delta_c = vecDeltas_[1]; + else + delta_c = vecDeltas_[2]; + delta = delta_c; + } else { + float delta_r = vecDeltas_[3]; + delta = delta_r; + } + auto clusterer = clue::Clusterer<2>(delta); + auto queue = clue::get_queue(0u); + + for (auto l = 0; l < maxlayer_; ++l) { + auto points = clue::PointsHost<2>(queue, cells_[l].dim1.size(), cells_[l].dim1, cells_[l].dim2, cells_[l].weight); + clusterer.make_clusters(points); + numberOfClustersPerLayer_[l] = points.n_clusters(); + } #if DEBUG_CLUSTERS_ALPAKA hgcalUtils::DumpLegacySoA dumperLegacySoA; dumperLegacySoA.dumpInfos(cells_, moduleType_); @@ -135,7 +121,8 @@ void HGCalCLUEAlgoT::makeClusters() { } template -reco::CaloClusterHostCollection HGCalCLUEAlgoT::getClusters(bool) { +std::pair>> +HGCalCLUEAlgoT::getClusters(bool) { std::vector offsets(numberOfClustersPerLayer_.size(), 0); int maxClustersOnLayer = numberOfClustersPerLayer_[0]; @@ -155,82 +142,62 @@ reco::CaloClusterHostCollection HGCalCLUEAlgoT::getClusters(bool) { totalNumberOfClusters, totalNumberOfClusters, totalNumberOfClusters); + // FIXME: put the real number of hits + PortableHostCollection> hits_associations( + cms::alpakatools::host(), totalNumberOfClusters, 1); + std::vector detid_and_fractions; + std::vector cluster_hit_associations; for (unsigned int layerId = 0; layerId < 2 * maxlayer_ + 2; ++layerId) { - cellsIdInCluster.resize(numberOfClustersPerLayer_[layerId]); - auto& cellsOnLayer = cells_[layerId]; - unsigned int numberOfCells = cellsOnLayer.detid.size(); - auto firstClusterIdx = offsets[layerId]; - - for (unsigned int i = 0; i < numberOfCells; ++i) { - auto clusterIndex = cellsOnLayer.clusterIndex[i]; - if (clusterIndex != -1) - cellsIdInCluster[clusterIndex].push_back(i); - } + auto queue = clue::get_queue(0u); + auto points = clue::PointsHost<2>( + queue, cells_[layerId].dim1.size(), cells_[layerId].dim1, cells_[layerId].dim2, cells_[layerId].weight); - std::vector> thisCluster; + std::ranges::copy(points.clusterIndexes(), std::back_inserter(cluster_hit_associations)); - for (auto& cl : cellsIdInCluster) { - auto maxEnergyValue = std::numeric_limits::min(); - auto maxEnergyCellIndex = -1; - DetId maxEnergyDetId; - auto energy = 0.f; - auto seedDetId = -1; + auto clusters = clue::get_clusters(points); + auto to_hit_and_fraction = [&](auto idx) { return std::make_pair(cells_[layerId].detid[idx], -1.f); }; + std::ranges::copy(clusters | std::views::transform(to_hit_and_fraction), std::back_inserter(detid_and_fractions)); + for (auto cl = 0; cl < clusters.size(); ++cl) { + const auto cluster = clusters[cl]; auto x = 0.f; auto y = 0.f; - auto z = cellsOnLayer.layerDim3; - // TODO Felice: maybe use the seed for the position calculation - for (auto cellIdx : cl) { - energy += cellsOnLayer.weight[cellIdx]; - if (cellsOnLayer.weight[cellIdx] > maxEnergyValue) { - maxEnergyValue = cellsOnLayer.weight[cellIdx]; - maxEnergyCellIndex = cellIdx; - maxEnergyDetId = cellsOnLayer.detid[cellIdx]; - } - thisCluster.emplace_back(cellsOnLayer.detid[cellIdx], 1.f); - if (cellsOnLayer.isSeed[cellIdx]) { - seedDetId = cellsOnLayer.detid[cellIdx]; - } - } - - auto total_weight_log = 0.f; - auto total_weight = energy; + const auto z = cells_[layerId].layerDim3; + auto energy = std::reduce( + cluster.begin(), cluster.end(), 0.f, [](auto acc, auto idx) { return acc + points.weights()[idx]; }); + auto max_energy_it = std::ranges::max_element(points.weights); + const auto max_energy = *max_energy_it; + const auto max_energy_idx = std::distance(points.weights.begin(), max_energy_it); + const auto max_energy_detid = cells_[layerId].detid[max_energy_id]; if constexpr (std::is_same_v) { - auto thick = rhtools_.getSiThickIndex(maxEnergyDetId); - for (auto cellIdx : cl) { - const float d1 = cellsOnLayer.dim1[cellIdx] - cellsOnLayer.dim1[maxEnergyCellIndex]; - const float d2 = cellsOnLayer.dim2[cellIdx] - cellsOnLayer.dim2[maxEnergyCellIndex]; + auto thick = rhtools_.getSiThickIndex(max_energy_detid); + auto total_weight_log = 0.f; + for (auto p : cluster) { + const auto d1 = points.coords(0)[p] - points.coords(0)[max_energy_idx]; + const auto d2 = points.coords(1)[p] - points.coords(1)[max_energy_idx]; if ((d1 * d1 + d2 * d2) < positionDeltaRho2_) { - float Wi = std::max(thresholdW0_[thick] + std::log(cellsOnLayer.weight[cellIdx] / energy), 0.); - x += cellsOnLayer.dim1[cellIdx] * Wi; - y += cellsOnLayer.dim2[cellIdx] * Wi; + auto Wi = std::max(thresholdW0_[thick] + std::log(points.weights()[p] / energy), 0.f); + x += points.coords(0)[p] * Wi; + y += points.coords(1)[p] * Wi; total_weight_log += Wi; } } - } else { - for (auto cellIdx : cl) { - auto position = rhtools_.getPosition(cellsOnLayer.detid[cellIdx]); - x += position.x() * cellsOnLayer.weight[cellIdx]; - y += position.y() * cellsOnLayer.weight[cellIdx]; - } - } - if constexpr (std::is_same_v) { - total_weight = total_weight_log; - } - - if (total_weight != 0.) { - auto inv_tot_weight = 1.f / total_weight; - x *= inv_tot_weight; - y *= inv_tot_weight; + if (total_weight_log != 0.) { + auto inv_tot_weight = 1.f / total_weight_log; + x *= inv_tot_weight; + y *= inv_tot_weight; + } else { + x = cellsOnLayer.dim1[maxEnergyCellIndex]; + y = cellsOnLayer.dim2[maxEnergyCellIndex]; + } } else { - x = cellsOnLayer.dim1[maxEnergyCellIndex]; - y = cellsOnLayer.dim2[maxEnergyCellIndex]; + const auto centroid = clue::weighted_cluster_centroid(points, cl); + x = centroid[0]; + y = centroid[1]; } - auto globalClusterIndex = cellsOnLayer.clusterIndex[cl[0]] + firstClusterIdx; - layer_clusters.view().position().x()[globalClusterIndex] = x; layer_clusters.view().position().y()[globalClusterIndex] = y; layer_clusters.view().position().z()[globalClusterIndex] = z; @@ -242,229 +209,12 @@ reco::CaloClusterHostCollection HGCalCLUEAlgoT::getClusters(bool) { layer_clusters.view().indexes().seedID()[globalClusterIndex] = seedDetId; layer_clusters.view().indexes().flags()[globalClusterIndex] = 0; } - - cellsIdInCluster.clear(); - } - return layer_clusters; -} - -template -void HGCalCLUEAlgoT::calculateLocalDensity(const T& lt, - const unsigned int layerId, - float delta, - HGCalSiliconStrategy strategy) { - auto& cellsOnLayer = cells_[layerId]; - unsigned int numberOfCells = cellsOnLayer.detid.size(); - for (unsigned int i = 0; i < numberOfCells; i++) { - std::array search_box = lt.searchBox(cellsOnLayer.dim1[i] - delta, - cellsOnLayer.dim1[i] + delta, - cellsOnLayer.dim2[i] - delta, - cellsOnLayer.dim2[i] + delta); - - for (int xBin = search_box[0]; xBin < search_box[1] + 1; ++xBin) { - for (int yBin = search_box[2]; yBin < search_box[3] + 1; ++yBin) { - int binId = lt.getGlobalBinByBin(xBin, yBin); - size_t binSize = lt[binId].size(); - - for (unsigned int j = 0; j < binSize; j++) { - unsigned int otherId = lt[binId][j]; - if (distance(lt, i, otherId, layerId) < delta) { - cellsOnLayer.rho[i] += (i == otherId ? 1.f : 0.5f) * cellsOnLayer.weight[otherId]; - } - } - } - } - LogDebug("HGCalCLUEAlgo") << "Debugging calculateLocalDensity: \n" - << " cell: " << i << " eta: " << cellsOnLayer.dim1[i] << " phi: " << cellsOnLayer.dim2[i] - << " energy: " << cellsOnLayer.weight[i] << " density: " << cellsOnLayer.rho[i] << "\n"; - } -} -template -void HGCalCLUEAlgoT::calculateLocalDensity(const T& lt, - const unsigned int layerId, - float delta, - HGCalScintillatorStrategy strategy) { - auto& cellsOnLayer = cells_[layerId]; - unsigned int numberOfCells = cellsOnLayer.detid.size(); - for (unsigned int i = 0; i < numberOfCells; i++) { - std::array search_box = lt.searchBox(cellsOnLayer.dim1[i] - delta, - cellsOnLayer.dim1[i] + delta, - cellsOnLayer.dim2[i] - delta, - cellsOnLayer.dim2[i] + delta); - cellsOnLayer.rho[i] += cellsOnLayer.weight[i]; - float northeast(0), northwest(0), southeast(0), southwest(0), all(0); - for (int etaBin = search_box[0]; etaBin < search_box[1] + 1; ++etaBin) { - for (int phiBin = search_box[2]; phiBin < search_box[3] + 1; ++phiBin) { - int phi = (phiBin % T::type::nRows); - int binId = lt.getGlobalBinByBin(etaBin, phi); - size_t binSize = lt[binId].size(); - for (unsigned int j = 0; j < binSize; j++) { - unsigned int otherId = lt[binId][j]; - if (distance(lt, i, otherId, layerId) < delta) { - int iPhi = HGCScintillatorDetId(cellsOnLayer.detid[i]).iphi(); - int otherIPhi = HGCScintillatorDetId(cellsOnLayer.detid[otherId]).iphi(); - int iEta = HGCScintillatorDetId(cellsOnLayer.detid[i]).ieta(); - int otherIEta = HGCScintillatorDetId(cellsOnLayer.detid[otherId]).ieta(); - int dIPhi = otherIPhi - iPhi; - dIPhi += abs(dIPhi) < 2 ? 0 - : dIPhi < 0 ? scintMaxIphi_ - : -scintMaxIphi_; // cells with iPhi=288 and iPhi=1 should be neiboring cells - int dIEta = otherIEta - iEta; - LogDebug("HGCalCLUEAlgo") << " Debugging calculateLocalDensity for Scintillator: \n" - << " cell: " << otherId << " energy: " << cellsOnLayer.weight[otherId] - << " otherIPhi: " << otherIPhi << " iPhi: " << iPhi << " otherIEta: " << otherIEta - << " iEta: " << iEta << "\n"; - - if (otherId != i) { - auto neighborCellContribution = 0.5f * cellsOnLayer.weight[otherId]; - all += neighborCellContribution; - if (dIPhi >= 0 && dIEta >= 0) - northeast += neighborCellContribution; - if (dIPhi <= 0 && dIEta >= 0) - southeast += neighborCellContribution; - if (dIPhi >= 0 && dIEta <= 0) - northwest += neighborCellContribution; - if (dIPhi <= 0 && dIEta <= 0) - southwest += neighborCellContribution; - } - LogDebug("HGCalCLUEAlgo") << " Debugging calculateLocalDensity for Scintillator: \n" - << " northeast: " << northeast << " southeast: " << southeast - << " northwest: " << northwest << " southwest: " << southwest << "\n"; - } - } - } - } - float neighborsval = (std::max(northeast, northwest) > std::max(southeast, southwest)) - ? std::max(northeast, northwest) - : std::max(southeast, southwest); - if (use2x2_) - cellsOnLayer.rho[i] += neighborsval; - else - cellsOnLayer.rho[i] += all; - LogDebug("HGCalCLUEAlgo") << "Debugging calculateLocalDensity: \n" - << " cell: " << i << " eta: " << cellsOnLayer.dim1[i] << " phi: " << cellsOnLayer.dim2[i] - << " energy: " << cellsOnLayer.weight[i] << " density: " << cellsOnLayer.rho[i] << "\n"; } -} -template -void HGCalCLUEAlgoT::calculateLocalDensity(const T& lt, const unsigned int layerId, float delta) { - if constexpr (std::is_same_v) { - calculateLocalDensity(lt, layerId, delta, HGCalSiliconStrategy()); - } else { - calculateLocalDensity(lt, layerId, delta, HGCalScintillatorStrategy()); - } -} + alpaka_serial_sync::Queue queue(cms::alpakatools::host()); + // ticl::associator::fill( + // queue, hits_associations, cluster_hit_associations, detid_and_fractions); -template -void HGCalCLUEAlgoT::calculateDistanceToHigher(const T& lt, const unsigned int layerId, float delta) { - auto& cellsOnLayer = cells_[layerId]; - unsigned int numberOfCells = cellsOnLayer.detid.size(); - - for (unsigned int i = 0; i < numberOfCells; i++) { - // initialize delta and nearest higher for i - float maxDelta = std::numeric_limits::max(); - float i_delta = maxDelta; - int i_nearestHigher = -1; - float rho_max = 0.f; - auto range = outlierDeltaFactor_ * delta; - std::array search_box = lt.searchBox(cellsOnLayer.dim1[i] - range, - cellsOnLayer.dim1[i] + range, - cellsOnLayer.dim2[i] - range, - cellsOnLayer.dim2[i] + range); - // loop over all bins in the search box - for (int dim1Bin = search_box[0]; dim1Bin < search_box[1] + 1; ++dim1Bin) { - for (int dim2Bin = search_box[2]; dim2Bin < search_box[3] + 1; ++dim2Bin) { - // get the id of this bin - size_t binId = lt.getGlobalBinByBin(dim1Bin, dim2Bin); - if constexpr (std::is_same_v) - binId = lt.getGlobalBinByBin(dim1Bin, (dim2Bin % T::type::nRows)); - // get the size of this bin - size_t binSize = lt[binId].size(); - - // loop over all hits in this bin - for (unsigned int j = 0; j < binSize; j++) { - unsigned int otherId = lt[binId][j]; - float dist = distance2(lt, i, otherId, layerId); - bool foundHigher = - (cellsOnLayer.rho[otherId] > cellsOnLayer.rho[i]) || - (cellsOnLayer.rho[otherId] == cellsOnLayer.rho[i] && cellsOnLayer.detid[otherId] > cellsOnLayer.detid[i]); - if (!foundHigher) { - continue; - } - if ((dist < i_delta) || ((dist == i_delta) && (cellsOnLayer.rho[otherId] > rho_max)) || - ((dist == i_delta) && (cellsOnLayer.rho[otherId] == rho_max) && - (cellsOnLayer.detid[otherId] > cellsOnLayer.detid[i]))) { - rho_max = cellsOnLayer.rho[otherId]; - i_delta = dist; - i_nearestHigher = otherId; - } - } - } - } - bool foundNearestHigherInSearchBox = (i_delta != maxDelta); - if (foundNearestHigherInSearchBox) { - cellsOnLayer.delta[i] = std::sqrt(i_delta); - cellsOnLayer.nearestHigher[i] = i_nearestHigher; - } else { - // otherwise delta is guaranteed to be larger outlierDeltaFactor_*delta_c - // we can safely maximize delta to be maxDelta - cellsOnLayer.delta[i] = maxDelta; - cellsOnLayer.nearestHigher[i] = -1; - } - - LogDebug("HGCalCLUEAlgo") << "Debugging calculateDistanceToHigher: \n" - << " cell: " << i << " eta: " << cellsOnLayer.dim1[i] << " phi: " << cellsOnLayer.dim2[i] - << " energy: " << cellsOnLayer.weight[i] << " density: " << cellsOnLayer.rho[i] - << " nearest higher: " << cellsOnLayer.nearestHigher[i] - << " distance: " << cellsOnLayer.delta[i] << "\n"; - } -} - -template -int HGCalCLUEAlgoT::findAndAssignClusters(const unsigned int layerId, float delta) { - // this is called once per layer and endcap... - // so when filling the cluster temporary vector of Hexels we resize each time - // by the number of clusters found. This is always equal to the number of - // cluster centers... - unsigned int nClustersOnLayer = 0; - auto& cellsOnLayer = cells_[layerId]; - unsigned int numberOfCells = cellsOnLayer.detid.size(); - std::vector localStack; - // find cluster seeds and outlier - for (unsigned int i = 0; i < numberOfCells; i++) { - float rho_c = kappa_ * cellsOnLayer.sigmaNoise[i]; - // initialize clusterIndex - cellsOnLayer.clusterIndex[i] = -1; - bool isSeed = (cellsOnLayer.delta[i] > delta) && (cellsOnLayer.rho[i] >= rho_c); - bool isOutlier = (cellsOnLayer.delta[i] > outlierDeltaFactor_ * delta) && (cellsOnLayer.rho[i] < rho_c); - if (isSeed) { - cellsOnLayer.clusterIndex[i] = nClustersOnLayer; - cellsOnLayer.isSeed[i] = true; - nClustersOnLayer++; - localStack.push_back(i); - - } else if (!isOutlier) { - assert(cellsOnLayer.nearestHigher[i] != -1); - assert(cellsOnLayer.nearestHigher[i] < static_cast(cellsOnLayer.followers.size())); - cellsOnLayer.followers[cellsOnLayer.nearestHigher[i]].push_back(i); - } - } - - // need to pass clusterIndex to their followers - while (!localStack.empty()) { - int endStack = localStack.back(); - auto& thisSeed = cellsOnLayer.followers[endStack]; - localStack.pop_back(); - - // loop over followers - for (int j : thisSeed) { - // pass id to a follower - cellsOnLayer.clusterIndex[j] = cellsOnLayer.clusterIndex[endStack]; - // push this follower to localStack - localStack.push_back(j); - } - } - return nClustersOnLayer; + return std::make_pair(layer_clusters, hits_associations); } template @@ -472,10 +222,10 @@ void HGCalCLUEAlgoT::computeThreshold() { // To support the TDR geometry and also the post-TDR one (v9 onwards), we // need to change the logic of the vectors containing signal to noise and // thresholds. The first 3 indices will keep on addressing the different - // thicknesses of the Silicon detectors in CE_E , the next 3 indices will address - // the thicknesses of the Silicon detectors in CE_H, while the last one, number 6 (the - // seventh) will address the Scintillators. This change will support both - // geometries at the same time. + // thicknesses of the Silicon detectors in CE_E , the next 3 indices will + // address the thicknesses of the Silicon detectors in CE_H, while the last + // one, number 6 (the seventh) will address the Scintillators. This change + // will support both geometries at the same time. if (initialized_) return; // only need to calculate thresholds once @@ -484,7 +234,8 @@ void HGCalCLUEAlgoT::computeThreshold() { std::vector dummy; - dummy.resize(maxNumberOfThickIndices_ + !isNose_, 0); // +1 to accomodate for the Scintillators + dummy.resize(maxNumberOfThickIndices_ + !isNose_, + 0); // +1 to accomodate for the Scintillators thresholds_.resize(maxlayer_, dummy); v_sigmaNoise_.resize(maxlayer_, dummy); From fbe7fbe7a926b1534ade962d277ea8a35760b167 Mon Sep 17 00:00:00 2001 From: Simone Date: Wed, 18 Mar 2026 17:20:49 +0100 Subject: [PATCH 09/24] Remove `HGCalImagingAlgo` --- .../interface/HGCalImagingAlgo.h | 269 ------- .../plugins/HGCalImagingAlgo.cc | 668 ------------------ .../HGCalRecProducers/plugins/SealModules.cc | 3 +- 3 files changed, 1 insertion(+), 939 deletions(-) delete mode 100644 RecoLocalCalo/HGCalRecProducers/interface/HGCalImagingAlgo.h delete mode 100644 RecoLocalCalo/HGCalRecProducers/plugins/HGCalImagingAlgo.cc diff --git a/RecoLocalCalo/HGCalRecProducers/interface/HGCalImagingAlgo.h b/RecoLocalCalo/HGCalRecProducers/interface/HGCalImagingAlgo.h deleted file mode 100644 index d198963afd4d7..0000000000000 --- a/RecoLocalCalo/HGCalRecProducers/interface/HGCalImagingAlgo.h +++ /dev/null @@ -1,269 +0,0 @@ -#ifndef RecoLocalCalo_HGCalRecProducers_HGCalImagingAlgo_h -#define RecoLocalCalo_HGCalRecProducers_HGCalImagingAlgo_h - -#include "RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h" - -#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" - -#include "Geometry/HGCalGeometry/interface/HGCalGeometry.h" -#include "Geometry/CaloTopology/interface/HGCalTopology.h" -#include "DataFormats/DetId/interface/DetId.h" -#include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" -#include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h" -#include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h" -#include "Geometry/CaloGeometry/interface/CaloGeometry.h" -#include "Geometry/CaloGeometry/interface/CaloCellGeometry.h" -#include "Geometry/CaloGeometry/interface/TruncatedPyramid.h" -#include "Geometry/Records/interface/CaloGeometryRecord.h" - -#include "DataFormats/Math/interface/Point3D.h" -#include "DataFormats/EgammaReco/interface/BasicCluster.h" - -#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" -#include "CommonTools/RecoAlgos/interface/KDTreeLinkerAlgo.h" - -// C/C++ headers -#include -#include -#include - -using Density = hgcal_clustering::Density; - -class HGCalImagingAlgo : public HGCalClusteringAlgoBase { -public: - HGCalImagingAlgo(const edm::ParameterSet &ps) - : HGCalClusteringAlgoBase( - (HGCalClusteringAlgoBase::VerbosityLevel)ps.getUntrackedParameter("verbosity", 3), - reco::CaloCluster::undefined), - thresholdW0_(ps.getParameter>("thresholdW0")), - positionDeltaRho_c_(ps.getParameter>("positionDeltaRho_c")), - vecDeltas_(ps.getParameter>("deltac")), - kappa_(ps.getParameter("kappa")), - ecut_(ps.getParameter("ecut")), - sigma2_(1.0), - dependSensor_(ps.getParameter("dependSensor")), - dEdXweights_(ps.getParameter>("dEdXweights")), - thicknessCorrection_(ps.getParameter>("thicknessCorrection")), - fcPerMip_(ps.getParameter>("fcPerMip")), - fcPerEle_(ps.getParameter("fcPerEle")), - nonAgedNoises_(ps.getParameter("noises").getParameter>("values")), - noiseMip_(ps.getParameter("noiseMip").getParameter("noise_MIP")), - initialized_(false) {} - - ~HGCalImagingAlgo() override {} - - void getEventSetupPerAlgorithm(const edm::EventSetup &es) override; - - void populate(const HGCRecHitCollection &hits) override; - void populate(const reco::PFRecHitCollection &hits) override {} - // this is the method that will start the clusterisation (it is possible to invoke this method more than once - but make sure it is with - // different hit collections (or else use reset) - - void makeClusters() override; - - // this is the method to get the cluster collection out - std::vector getClusters(bool) override; - - // use this if you want to reuse the same cluster object but don't want to accumulate clusters (hardly useful?) - void reset() override { - clusters_v_.clear(); - clusters_v_.shrink_to_fit(); - layerClustersPerLayer_.clear(); - layerClustersPerLayer_.shrink_to_fit(); - for (auto &it : points_) { - it.clear(); - it.shrink_to_fit(); - std::vector().swap(it); - } - for (unsigned int i = 0; i < minpos_.size(); i++) { - minpos_[i][0] = 0.; - minpos_[i][1] = 0.; - maxpos_[i][0] = 0.; - maxpos_[i][1] = 0.; - } - } - void computeThreshold(); - - //getDensity - Density getDensity() override; - - static void fillPSetDescription(edm::ParameterSetDescription &iDesc) { - iDesc.add>("thresholdW0", {2.9, 2.9, 2.9}); - iDesc.add>("positionDeltaRho_c", {1.3, 1.3, 1.3}); - iDesc.add>("deltac", - { - 2.0, - 2.0, - 5.0, - }); - iDesc.add("dependSensor", true); - iDesc.add("ecut", 3.0); - iDesc.add("kappa", 9.0); - iDesc.addUntracked("verbosity", 3); - iDesc.add>("dEdXweights", {}); - iDesc.add>("thicknessCorrection", {}); - iDesc.add>("fcPerMip", {}); - iDesc.add("fcPerEle", 0.0); - edm::ParameterSetDescription descNestedNoises; - descNestedNoises.add>("values", {}); - iDesc.add("noises", descNestedNoises); - edm::ParameterSetDescription descNestedNoiseMIP; - descNestedNoiseMIP.add("scaleByDose", false); - descNestedNoiseMIP.add("scaleByDoseFactor", 1.); - iDesc.add("scaleByDose", descNestedNoiseMIP); - descNestedNoiseMIP.add("doseMap", ""); - iDesc.add("doseMap", descNestedNoiseMIP); - descNestedNoiseMIP.add("noise_MIP", 1. / 100.); - iDesc.add("noiseMip", descNestedNoiseMIP); - } - - /// point in the space - typedef math::XYZPoint Point; - -private: - // To compute the cluster position - std::vector thresholdW0_; - std::vector positionDeltaRho_c_; - - // The two parameters used to identify clusters - std::vector vecDeltas_; - double kappa_; - - // The hit energy cutoff - double ecut_; - - // for energy sharing - double sigma2_; // transverse shower size - - // The vector of clusters - std::vector clusters_v_; - - // For keeping the density per hit - Density density_; - - // various parameters used for calculating the noise levels for a given sensor (and whether to use them) - bool dependSensor_; - std::vector dEdXweights_; - std::vector thicknessCorrection_; - std::vector fcPerMip_; - double fcPerEle_; - std::vector nonAgedNoises_; - double noiseMip_; - std::vector> thresholds_; - std::vector> sigmaNoise_; - - // initialization bool - bool initialized_; - - struct Hexel { - double x; - double y; - double z; - bool isHalfCell; - double weight; - double fraction; - DetId detid; - double rho; - double delta; - int nearestHigher; - bool isBorder; - bool isHalo; - int clusterIndex; - float sigmaNoise; - float thickness; - const hgcal::RecHitTools *tools; - - Hexel(const HGCRecHit &hit, - DetId id_in, - bool isHalf, - float sigmaNoise_in, - float thickness_in, - const hgcal::RecHitTools *tools_in) - : isHalfCell(isHalf), - weight(0.), - fraction(1.0), - detid(id_in), - rho(0.), - delta(0.), - nearestHigher(-1), - isBorder(false), - isHalo(false), - clusterIndex(-1), - sigmaNoise(sigmaNoise_in), - thickness(thickness_in), - tools(tools_in) { - const GlobalPoint position(tools->getPosition(detid)); - weight = hit.energy(); - x = position.x(); - y = position.y(); - z = position.z(); - } - Hexel() - : x(0.), - y(0.), - z(0.), - isHalfCell(false), - weight(0.), - fraction(1.0), - detid(), - rho(0.), - delta(0.), - nearestHigher(-1), - isBorder(false), - isHalo(false), - clusterIndex(-1), - sigmaNoise(0.), - thickness(0.), - tools(nullptr) {} - bool operator>(const Hexel &rhs) const { return (rho > rhs.rho); } - }; - - typedef KDTreeLinkerAlgo KDTree; - typedef KDTreeNodeInfo KDNode; - - std::vector>> layerClustersPerLayer_; - - std::vector sort_by_delta(const std::vector &v) const { - std::vector idx(v.size()); - std::iota(std::begin(idx), std::end(idx), 0); - sort(idx.begin(), idx.end(), [&v](size_t i1, size_t i2) { return v[i1].data.delta > v[i2].data.delta; }); - return idx; - } - - std::vector> points_; //a vector of vectors of hexels, one for each layer - //@@EM todo: the number of layers should be obtained programmatically - the range is 1-n instead of 0-n-1... - - std::vector> minpos_; - std::vector> maxpos_; - - //these functions should be in a helper class. - inline double distance2(const Hexel &pt1, const Hexel &pt2) const { //distance squared - const double dx = pt1.x - pt2.x; - const double dy = pt1.y - pt2.y; - return (dx * dx + dy * dy); - } //distance squaredq - inline double distance(const Hexel &pt1, const Hexel &pt2) const { //2-d distance on the layer (x-y) - return std::sqrt(distance2(pt1, pt2)); - } - double calculateLocalDensity(std::vector &, KDTree &, const unsigned int) const; //return max density - double calculateDistanceToHigher(std::vector &) const; - int findAndAssignClusters(std::vector &, - KDTree &, - double, - KDTreeBox<2> &, - const unsigned int, - std::vector> &) const; - math::XYZPoint calculatePosition(std::vector &) const; - - //For keeping the density information - void setDensity(const std::vector &nd); - - // attempt to find subclusters within a given set of hexels - std::vector findLocalMaximaInCluster(const std::vector &); - math::XYZPoint calculatePositionWithFraction(const std::vector &, const std::vector &); - double calculateEnergyWithFraction(const std::vector &, const std::vector &); - // outputs - void shareEnergy(const std::vector &, const std::vector &, std::vector> &); -}; - -#endif diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalImagingAlgo.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalImagingAlgo.cc deleted file mode 100644 index c65eb556a47ef..0000000000000 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalImagingAlgo.cc +++ /dev/null @@ -1,668 +0,0 @@ -#include "RecoLocalCalo/HGCalRecProducers/interface/HGCalImagingAlgo.h" - -// Geometry -#include "DataFormats/HcalDetId/interface/HcalSubdetector.h" -#include "Geometry/CaloGeometry/interface/CaloCellGeometry.h" -#include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h" -#include "Geometry/Records/interface/IdealGeometryRecord.h" - -#include "RecoEcal/EgammaCoreTools/interface/PositionCalc.h" -// -#include "DataFormats/CaloRecHit/interface/CaloID.h" -#include "oneapi/tbb/task_arena.h" -#include "oneapi/tbb.h" - -using namespace hgcal_clustering; - -void HGCalImagingAlgo::getEventSetupPerAlgorithm(const edm::EventSetup &es) { - points_.clear(); - minpos_.clear(); - maxpos_.clear(); - points_.resize(2 * (maxlayer_ + 1)); - minpos_.resize(2 * (maxlayer_ + 1), {{0.0f, 0.0f}}); - maxpos_.resize(2 * (maxlayer_ + 1), {{0.0f, 0.0f}}); -} - -void HGCalImagingAlgo::populate(const HGCRecHitCollection &hits) { - // loop over all hits and create the Hexel structure, skip energies below ecut - - if (dependSensor_) { - // for each layer and wafer calculate the thresholds (sigmaNoise and energy) - // once - computeThreshold(); - } - - std::vector firstHit(2 * (maxlayer_ + 1), true); - for (unsigned int i = 0; i < hits.size(); ++i) { - const HGCRecHit &hgrh = hits[i]; - DetId detid = hgrh.detid(); - unsigned int layer = rhtools_.getLayerWithOffset(detid); - float thickness = 0.f; - // set sigmaNoise default value 1 to use kappa value directly in case of - // sensor-independent thresholds - float sigmaNoise = 1.f; - if (dependSensor_) { - thickness = rhtools_.getSiThickness(detid); - int thickness_index = rhtools_.getSiThickIndex(detid); - if (thickness_index == -1) - thickness_index = 3; - double storedThreshold = thresholds_[layer - 1][thickness_index]; - sigmaNoise = sigmaNoise_[layer - 1][thickness_index]; - - if (hgrh.energy() < storedThreshold) - continue; // this sets the ZS threshold at ecut times the sigma noise - // for the sensor - } - if (!dependSensor_ && hgrh.energy() < ecut_) - continue; - - // map layers from positive endcap (z) to layer + maxlayer+1 to prevent - // mixing up hits from different sides - layer += int(rhtools_.zside(detid) > 0) * (maxlayer_ + 1); - - // determine whether this is a half-hexagon - bool isHalf = rhtools_.isHalfCell(detid); - const GlobalPoint position(rhtools_.getPosition(detid)); - - // here's were the KDNode is passed its dims arguments - note that these are - // *copied* from the Hexel - points_[layer].emplace_back( - Hexel(hgrh, detid, isHalf, sigmaNoise, thickness, &rhtools_), position.x(), position.y()); - - // for each layer, store the minimum and maximum x and y coordinates for the - // KDTreeBox boundaries - if (firstHit[layer]) { - minpos_[layer][0] = position.x(); - minpos_[layer][1] = position.y(); - maxpos_[layer][0] = position.x(); - maxpos_[layer][1] = position.y(); - firstHit[layer] = false; - } else { - minpos_[layer][0] = std::min((float)position.x(), minpos_[layer][0]); - minpos_[layer][1] = std::min((float)position.y(), minpos_[layer][1]); - maxpos_[layer][0] = std::max((float)position.x(), maxpos_[layer][0]); - maxpos_[layer][1] = std::max((float)position.y(), maxpos_[layer][1]); - } - - } // end loop hits -} -// Create a vector of Hexels associated to one cluster from a collection of -// HGCalRecHits - this can be used directly to make the final cluster list - -// this method can be invoked multiple times for the same event with different -// input (reset should be called between events) -void HGCalImagingAlgo::makeClusters() { - layerClustersPerLayer_.resize(2 * maxlayer_ + 2); - // assign all hits in each layer to a cluster core or halo - tbb::this_task_arena::isolate([&] { - tbb::parallel_for(size_t(0), size_t(2 * maxlayer_ + 2), [&](size_t i) { - KDTreeBox bounds(minpos_[i][0], maxpos_[i][0], minpos_[i][1], maxpos_[i][1]); - KDTree hit_kdtree; - hit_kdtree.build(points_[i], bounds); - - unsigned int actualLayer = - i > maxlayer_ ? (i - (maxlayer_ + 1)) : i; // maps back from index used for KD trees to actual layer - - double maxdensity = calculateLocalDensity(points_[i], hit_kdtree, actualLayer); // also stores rho (energy - // density) for each point (node) - // calculate distance to nearest point with higher density storing - // distance (delta) and point's index - calculateDistanceToHigher(points_[i]); - findAndAssignClusters(points_[i], hit_kdtree, maxdensity, bounds, actualLayer, layerClustersPerLayer_[i]); - }); - }); - //Now that we have the density per point we can store it - for (auto const &p : points_) { - setDensity(p); - } -} - -std::vector HGCalImagingAlgo::getClusters(bool doSharing) { - reco::CaloID caloID = reco::CaloID::DET_HGCAL_ENDCAP; - std::vector> thisCluster; - for (auto &clsOnLayer : layerClustersPerLayer_) { - for (unsigned int i = 0; i < clsOnLayer.size(); ++i) { - double energy = 0; - Point position; - - //Will save the maximum density hit of the cluster - size_t rsmax = max_index(clsOnLayer[i]); - - if (doSharing) { - std::vector seeds = findLocalMaximaInCluster(clsOnLayer[i]); - // sharing found seeds.size() sub-cluster seeds in cluster i - - std::vector> fractions; - // first pass can have noise it in - shareEnergy(clsOnLayer[i], seeds, fractions); - - // reset and run second pass after vetoing seeds - // that result in trivial clusters (less than 2 effective cells) - - for (unsigned isub = 0; isub < fractions.size(); ++isub) { - double effective_hits = 0.0; - double energy = calculateEnergyWithFraction(clsOnLayer[i], fractions[isub]); - Point position = calculatePositionWithFraction(clsOnLayer[i], fractions[isub]); - - for (unsigned ihit = 0; ihit < fractions[isub].size(); ++ihit) { - const double fraction = fractions[isub][ihit]; - if (fraction > 1e-7) { - effective_hits += fraction; - thisCluster.emplace_back(clsOnLayer[i][ihit].data.detid, fraction); - } - } - - if (verbosity_ < pINFO) { - std::cout << "\t******** NEW CLUSTER (SHARING) ********" << std::endl; - std::cout << "\tEff. No. of cells = " << effective_hits << std::endl; - std::cout << "\t Energy = " << energy << std::endl; - std::cout << "\t Phi = " << position.phi() << std::endl; - std::cout << "\t Eta = " << position.eta() << std::endl; - std::cout << "\t*****************************" << std::endl; - } - clusters_v_.emplace_back(energy, position, caloID, thisCluster, algoId_); - if (!clusters_v_.empty()) { - clusters_v_.back().setSeed(clsOnLayer[i][rsmax].data.detid); - } - thisCluster.clear(); - } - } else { - position = calculatePosition(clsOnLayer[i]); // energy-weighted position - // std::vector< KDNode >::iterator it; - for (auto &it : clsOnLayer[i]) { - energy += it.data.isHalo ? 0. : it.data.weight; - // use fraction to store whether this is a Halo hit or not - thisCluster.emplace_back(it.data.detid, (it.data.isHalo ? 0.f : 1.f)); - } - if (verbosity_ < pINFO) { - std::cout << "******** NEW CLUSTER (HGCIA) ********" << std::endl; - std::cout << "Index " << i << std::endl; - std::cout << "No. of cells = " << clsOnLayer[i].size() << std::endl; - std::cout << " Energy = " << energy << std::endl; - std::cout << " Phi = " << position.phi() << std::endl; - std::cout << " Eta = " << position.eta() << std::endl; - std::cout << "*****************************" << std::endl; - } - clusters_v_.emplace_back(energy, position, caloID, thisCluster, algoId_); - if (!clusters_v_.empty()) { - clusters_v_.back().setSeed(clsOnLayer[i][rsmax].data.detid); - } - thisCluster.clear(); - } - } - } - return clusters_v_; -} - -math::XYZPoint HGCalImagingAlgo::calculatePosition(std::vector &v) const { - float total_weight = 0.f; - float x = 0.f; - float y = 0.f; - - unsigned int v_size = v.size(); - unsigned int maxEnergyIndex = 0; - float maxEnergyValue = 0; - - // loop over hits in cluster candidate - // determining the maximum energy hit - for (unsigned int i = 0; i < v_size; i++) { - if (v[i].data.weight > maxEnergyValue) { - maxEnergyValue = v[i].data.weight; - maxEnergyIndex = i; - } - } - - // Si cell or Scintillator. Used to set approach and parameters - int thick = rhtools_.getSiThickIndex(v[maxEnergyIndex].data.detid); - - // for hits within positionDeltaRho_c_ from maximum energy hit - // build up weight for energy-weighted position - // and save corresponding hits indices - std::vector innerIndices; - for (unsigned int i = 0; i < v_size; i++) { - if (thick == -1 || distance2(v[i].data, v[maxEnergyIndex].data) < positionDeltaRho_c_[thick]) { - innerIndices.push_back(i); - - float rhEnergy = v[i].data.weight; - total_weight += rhEnergy; - // just fill x, y for scintillator - // for Si it is overwritten later anyway - if (thick == -1) { - x += v[i].data.x * rhEnergy; - y += v[i].data.y * rhEnergy; - } - } - } - // just loop on reduced vector of interesting indices - // to compute log weighting - if (thick != -1 && total_weight != 0.) { // Silicon case - float total_weight_log = 0.f; - float x_log = 0.f; - float y_log = 0.f; - for (auto idx : innerIndices) { - float rhEnergy = v[idx].data.weight; - if (rhEnergy == 0.) - continue; - float Wi = std::max(thresholdW0_[thick] + log(rhEnergy / total_weight), 0.); - x_log += v[idx].data.x * Wi; - y_log += v[idx].data.y * Wi; - total_weight_log += Wi; - } - total_weight = total_weight_log; - x = x_log; - y = y_log; - } - - if (total_weight != 0.) { - auto inv_tot_weight = 1. / total_weight; - return math::XYZPoint(x * inv_tot_weight, y * inv_tot_weight, v[maxEnergyIndex].data.z); - } - return math::XYZPoint(0, 0, 0); -} - -double HGCalImagingAlgo::calculateLocalDensity(std::vector &nd, KDTree &lp, const unsigned int layer) const { - double maxdensity = 0.; - float delta_c; // maximum search distance (critical distance) for local - // density calculation - if (layer <= lastLayerEE_) - delta_c = vecDeltas_[0]; - else if (layer < firstLayerBH_) - delta_c = vecDeltas_[1]; - else - delta_c = vecDeltas_[2]; - - // for each node calculate local density rho and store it - for (unsigned int i = 0; i < nd.size(); ++i) { - // speec up search by looking within +/- delta_c window only - KDTreeBox search_box( - nd[i].dims[0] - delta_c, nd[i].dims[0] + delta_c, nd[i].dims[1] - delta_c, nd[i].dims[1] + delta_c); - std::vector found; - lp.search(search_box, found); - const unsigned int found_size = found.size(); - for (unsigned int j = 0; j < found_size; j++) { - if (distance(nd[i].data, found[j]) < delta_c) { - nd[i].data.rho += found[j].weight; - maxdensity = std::max(maxdensity, nd[i].data.rho); - } - } // end loop found - } // end loop nodes - return maxdensity; -} - -double HGCalImagingAlgo::calculateDistanceToHigher(std::vector &nd) const { - // sort vector of Hexels by decreasing local density - std::vector rs = sorted_indices(nd); - - double maxdensity = 0.0; - int nearestHigher = -1; - - if (!rs.empty()) - maxdensity = nd[rs[0]].data.rho; - else - return maxdensity; // there are no hits - double dist2 = 0.; - // start by setting delta for the highest density hit to - // the most distant hit - this is a convention - - for (auto &j : nd) { - double tmp = distance2(nd[rs[0]].data, j.data); - if (tmp > dist2) - dist2 = tmp; - } - nd[rs[0]].data.delta = std::sqrt(dist2); - nd[rs[0]].data.nearestHigher = nearestHigher; - - // now we save the largest distance as a starting point - const double max_dist2 = dist2; - const unsigned int nd_size = nd.size(); - - for (unsigned int oi = 1; oi < nd_size; ++oi) { // start from second-highest density - dist2 = max_dist2; - unsigned int i = rs[oi]; - // we only need to check up to oi since hits - // are ordered by decreasing density - // and all points coming BEFORE oi are guaranteed to have higher rho - // and the ones AFTER to have lower rho - for (unsigned int oj = 0; oj < oi; ++oj) { - unsigned int j = rs[oj]; - // Limit the search box - if ((nd[i].data.x - nd[j].data.x) * (nd[i].data.x - nd[j].data.x) > dist2) - continue; - if ((nd[i].data.y - nd[j].data.y) * (nd[i].data.y - nd[j].data.y) > dist2) - continue; - double tmp = distance2(nd[i].data, nd[j].data); - if (tmp <= dist2) { // this "<=" instead of "<" addresses the (rare) case - // when there are only two hits - dist2 = tmp; - nearestHigher = j; - } - } - nd[i].data.delta = std::sqrt(dist2); - nd[i].data.nearestHigher = nearestHigher; // this uses the original unsorted hitlist - } - return maxdensity; -} -int HGCalImagingAlgo::findAndAssignClusters(std::vector &nd, - KDTree &lp, - double maxdensity, - KDTreeBox<2> &bounds, - const unsigned int layer, - std::vector> &clustersOnLayer) const { - // this is called once per layer and endcap... - // so when filling the cluster temporary vector of Hexels we resize each time - // by the number of clusters found. This is always equal to the number of - // cluster centers... - - unsigned int nClustersOnLayer = 0; - float delta_c; // critical distance - if (layer <= lastLayerEE_) - delta_c = vecDeltas_[0]; - else if (layer < firstLayerBH_) - delta_c = vecDeltas_[1]; - else - delta_c = vecDeltas_[2]; - - std::vector rs = sorted_indices(nd); // indices sorted by decreasing rho - std::vector ds = sort_by_delta(nd); // sort in decreasing distance to higher - - const unsigned int nd_size = nd.size(); - for (unsigned int i = 0; i < nd_size; ++i) { - if (nd[ds[i]].data.delta < delta_c) - break; // no more cluster centers to be looked at - if (dependSensor_) { - float rho_c = kappa_ * nd[ds[i]].data.sigmaNoise; - if (nd[ds[i]].data.rho < rho_c) - continue; // set equal to kappa times noise threshold - - } else if (nd[ds[i]].data.rho * kappa_ < maxdensity) - continue; - - nd[ds[i]].data.clusterIndex = nClustersOnLayer; - if (verbosity_ < pINFO) { - std::cout << "Adding new cluster with index " << nClustersOnLayer << std::endl; - std::cout << "Cluster center is hit " << ds[i] << std::endl; - } - nClustersOnLayer++; - } - - // at this point nClustersOnLayer is equal to the number of cluster centers - - // if it is zero we are done - if (nClustersOnLayer == 0) - return nClustersOnLayer; - - // assign remaining points to clusters, using the nearestHigher set from - // previous step (always set except - // for top density hit that is skipped...) - for (unsigned int oi = 1; oi < nd_size; ++oi) { - unsigned int i = rs[oi]; - int ci = nd[i].data.clusterIndex; - if (ci == -1) { // clusterIndex is initialised with -1 if not yet used in cluster - nd[i].data.clusterIndex = nd[nd[i].data.nearestHigher].data.clusterIndex; - } - } - - // make room in the temporary cluster vector for the additional clusterIndex - // clusters - // from this layer - if (verbosity_ < pINFO) { - std::cout << "resizing cluster vector by " << nClustersOnLayer << std::endl; - } - clustersOnLayer.resize(nClustersOnLayer); - - // assign points closer than dc to other clusters to border region - // and find critical border density - std::vector rho_b(nClustersOnLayer, 0.); - lp.clear(); - lp.build(nd, bounds); - // now loop on all hits again :( and check: if there are hits from another - // cluster within d_c -> flag as border hit - for (unsigned int i = 0; i < nd_size; ++i) { - int ci = nd[i].data.clusterIndex; - bool flag_isolated = true; - if (ci != -1) { - KDTreeBox search_box( - nd[i].dims[0] - delta_c, nd[i].dims[0] + delta_c, nd[i].dims[1] - delta_c, nd[i].dims[1] + delta_c); - std::vector found; - lp.search(search_box, found); - - const unsigned int found_size = found.size(); - for (unsigned int j = 0; j < found_size; j++) { // start from 0 here instead of 1 - // check if the hit is not within d_c of another cluster - if (found[j].clusterIndex != -1) { - float dist = distance(found[j], nd[i].data); - if (dist < delta_c && found[j].clusterIndex != ci) { - // in which case we assign it to the border - nd[i].data.isBorder = true; - break; - } - // because we are using two different containers, we have to make sure - // that we don't unflag the - // hit when it finds *itself* closer than delta_c - if (dist < delta_c && dist != 0. && found[j].clusterIndex == ci) { - // in this case it is not an isolated hit - // the dist!=0 is because the hit being looked at is also inside the - // search box and at dist==0 - flag_isolated = false; - } - } - } - if (flag_isolated) - nd[i].data.isBorder = true; // the hit is more than delta_c from any of its brethren - } - // check if this border hit has density larger than the current rho_b and - // update - if (nd[i].data.isBorder && rho_b[ci] < nd[i].data.rho) - rho_b[ci] = nd[i].data.rho; - } // end loop all hits - - // flag points in cluster with density < rho_b as halo points, then fill the - // cluster vector - for (unsigned int i = 0; i < nd_size; ++i) { - int ci = nd[i].data.clusterIndex; - if (ci != -1) { - if (nd[i].data.rho <= rho_b[ci]) - nd[i].data.isHalo = true; - clustersOnLayer[ci].push_back(nd[i]); - if (verbosity_ < pINFO) { - std::cout << "Pushing hit " << i << " into cluster with index " << ci << std::endl; - } - } - } - - // prepare the offset for the next layer if there is one - if (verbosity_ < pINFO) { - std::cout << "moving cluster offset by " << nClustersOnLayer << std::endl; - } - return nClustersOnLayer; -} - -// find local maxima within delta_c, marking the indices in the cluster -std::vector HGCalImagingAlgo::findLocalMaximaInCluster(const std::vector &cluster) { - std::vector result; - std::vector seed(cluster.size(), true); - float delta_c = 2.; - - for (unsigned i = 0; i < cluster.size(); ++i) { - for (unsigned j = 0; j < cluster.size(); ++j) { - if (i != j and distance(cluster[i].data, cluster[j].data) < delta_c) { - if (cluster[i].data.weight < cluster[j].data.weight) { - seed[i] = false; - break; - } - } - } - } - - for (unsigned i = 0; i < cluster.size(); ++i) { - if (seed[i] && cluster[i].data.weight > 5e-4) { - // seed at i with energy cluster[i].weight - result.push_back(i); - } - } - - // Found result.size() sub-clusters in input cluster of length cluster.size() - - return result; -} - -math::XYZPoint HGCalImagingAlgo::calculatePositionWithFraction(const std::vector &hits, - const std::vector &fractions) { - double norm(0.0), x(0.0), y(0.0), z(0.0); - for (unsigned i = 0; i < hits.size(); ++i) { - const double weight = fractions[i] * hits[i].data.weight; - norm += weight; - x += weight * hits[i].data.x; - y += weight * hits[i].data.y; - z += weight * hits[i].data.z; - } - math::XYZPoint result(x, y, z); - result /= norm; - return result; -} - -double HGCalImagingAlgo::calculateEnergyWithFraction(const std::vector &hits, - const std::vector &fractions) { - double result = 0.0; - for (unsigned i = 0; i < hits.size(); ++i) { - result += fractions[i] * hits[i].data.weight; - } - return result; -} - -void HGCalImagingAlgo::shareEnergy(const std::vector &incluster, - const std::vector &seeds, - std::vector> &outclusters) { - std::vector isaseed(incluster.size(), false); - outclusters.clear(); - outclusters.resize(seeds.size()); - std::vector centroids(seeds.size()); - std::vector energies(seeds.size()); - - if (seeds.size() == 1) { // short circuit the case of a lone cluster - outclusters[0].clear(); - outclusters[0].resize(incluster.size(), 1.0); - return; - } - - // saving seeds - - // create quick seed lookup - for (unsigned i = 0; i < seeds.size(); ++i) { - isaseed[seeds[i]] = true; - } - - // initialize clusters to be shared - // centroids start off at seed positions - // seeds always have fraction 1.0, to stabilize fit - // initializing fit - for (unsigned i = 0; i < seeds.size(); ++i) { - outclusters[i].resize(incluster.size(), 0.0); - for (unsigned j = 0; j < incluster.size(); ++j) { - if (j == seeds[i]) { - outclusters[i][j] = 1.0; - centroids[i] = math::XYZPoint(incluster[j].data.x, incluster[j].data.y, incluster[j].data.z); - energies[i] = incluster[j].data.weight; - } - } - } - - // run the fit while we are less than max iterations, and clusters are still - // moving - const double minFracTot = 1e-20; - unsigned iter = 0; - const unsigned iterMax = 50; - double diff = std::numeric_limits::max(); - const double stoppingTolerance = 1e-8; - const auto numberOfSeeds = seeds.size(); - auto toleranceScaling = numberOfSeeds > 2 ? (numberOfSeeds - 1) * (numberOfSeeds - 1) : 1; - std::vector prevCentroids; - std::vector frac(numberOfSeeds), dist2(numberOfSeeds); - while (iter++ < iterMax && diff > stoppingTolerance * toleranceScaling) { - for (unsigned i = 0; i < incluster.size(); ++i) { - const Hexel &ihit = incluster[i].data; - double fracTot(0.0); - for (unsigned j = 0; j < numberOfSeeds; ++j) { - double fraction = 0.0; - double d2 = (std::pow(ihit.x - centroids[j].x(), 2.0) + std::pow(ihit.y - centroids[j].y(), 2.0) + - std::pow(ihit.z - centroids[j].z(), 2.0)) / - sigma2_; - dist2[j] = d2; - // now we set the fractions up based on hit type - if (i == seeds[j]) { // this cluster's seed - fraction = 1.0; - } else if (isaseed[i]) { - fraction = 0.0; - } else { - fraction = energies[j] * std::exp(-0.5 * d2); - } - fracTot += fraction; - frac[j] = fraction; - } - // now that we have calculated all fractions for all hits - // assign the new fractions - for (unsigned j = 0; j < numberOfSeeds; ++j) { - if (fracTot > minFracTot || (i == seeds[j] && fracTot > 0.0)) { - outclusters[j][i] = frac[j] / fracTot; - } else { - outclusters[j][i] = 0.0; - } - } - } - - // save previous centroids - prevCentroids = std::move(centroids); - // finally update the position of the centroids from the last iteration - centroids.resize(numberOfSeeds); - double diff2 = 0.0; - for (unsigned i = 0; i < numberOfSeeds; ++i) { - centroids[i] = calculatePositionWithFraction(incluster, outclusters[i]); - energies[i] = calculateEnergyWithFraction(incluster, outclusters[i]); - // calculate convergence parameters - const double delta2 = (prevCentroids[i] - centroids[i]).perp2(); - diff2 = std::max(delta2, diff2); - } - // update convergance parameter outside loop - diff = std::sqrt(diff2); - } -} - -void HGCalImagingAlgo::computeThreshold() { - // To support the TDR geometry and also the post-TDR one (v9 onwards), we - // need to change the logic of the vectors containing signal to noise and - // thresholds. The first 3 indices will keep on addressing the different - // thicknesses of the Silicon detectors, while the last one, number 3 (the - // fourth) will address the Scintillators. This change will support both - // geometries at the same time. - - if (initialized_) - return; // only need to calculate thresholds once - - initialized_ = true; - - std::vector dummy; - const unsigned maxNumberOfThickIndices = 3; - dummy.resize(maxNumberOfThickIndices + 1, 0); // +1 to accomodate for the Scintillators - thresholds_.resize(maxlayer_, dummy); - sigmaNoise_.resize(maxlayer_, dummy); - - for (unsigned ilayer = 1; ilayer <= maxlayer_; ++ilayer) { - for (unsigned ithick = 0; ithick < maxNumberOfThickIndices; ++ithick) { - float sigmaNoise = 0.001f * fcPerEle_ * nonAgedNoises_[ithick] * dEdXweights_[ilayer] / - (fcPerMip_[ithick] * thicknessCorrection_[ithick]); - thresholds_[ilayer - 1][ithick] = sigmaNoise * ecut_; - sigmaNoise_[ilayer - 1][ithick] = sigmaNoise; - } - float scintillators_sigmaNoise = 0.001f * noiseMip_ * dEdXweights_[ilayer]; - thresholds_[ilayer - 1][maxNumberOfThickIndices] = ecut_ * scintillators_sigmaNoise; - sigmaNoise_[ilayer - 1][maxNumberOfThickIndices] = scintillators_sigmaNoise; - } -} - -void HGCalImagingAlgo::setDensity(const std::vector &nd) { - // for each node calculate local density rho and store it - for (auto &i : nd) { - density_[i.data.detid] = i.data.rho; - } // end loop nodes -} - -//Density -Density HGCalImagingAlgo::getDensity() { return density_; } diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/SealModules.cc b/RecoLocalCalo/HGCalRecProducers/plugins/SealModules.cc index a472c2f7e0f87..83721cc7f3ec2 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/SealModules.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/SealModules.cc @@ -1,11 +1,10 @@ #include "RecoLocalCalo/HGCalRecProducers/interface/HGCalLayerClusterAlgoFactory.h" #include "RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h" -#include "RecoLocalCalo/HGCalRecProducers/interface/HGCalImagingAlgo.h" #include "RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h" #include "FWCore/ParameterSet/interface/ValidatedPluginMacros.h" -DEFINE_EDM_VALIDATED_PLUGIN(HGCalLayerClusterAlgoFactory, HGCalImagingAlgo, "Imaging"); +// DEFINE_EDM_VALIDATED_PLUGIN(HGCalLayerClusterAlgoFactory, HGCalImagingAlgo, "Imaging"); DEFINE_EDM_VALIDATED_PLUGIN(HGCalLayerClusterAlgoFactory, HGCalSiCLUEAlgo, "SiCLUE"); DEFINE_EDM_VALIDATED_PLUGIN(HGCalLayerClusterAlgoFactory, HGCalSciCLUEAlgo, "SciCLUE"); DEFINE_EDM_VALIDATED_PLUGIN(HGCalLayerClusterAlgoFactory, HFNoseCLUEAlgo, "HFNoseCLUE"); From 8750227e7992bab530d5c9f800409018d5971e5c Mon Sep 17 00:00:00 2001 From: Simone Date: Wed, 18 Mar 2026 17:27:46 +0100 Subject: [PATCH 10/24] Define `ClusterMask` and `HitsAndFractions` for TICL --- DataFormats/TICL/interface/ClusterMask.h | 14 ++++++++++++++ DataFormats/TICL/interface/ClusterMaskHost.h | 11 +++++++++++ DataFormats/TICL/interface/HitAndFraction.h | 13 +++++++++++++ DataFormats/TICL/interface/HitsAndFractionsHost.h | 12 ++++++++++++ .../TICL/interface/alpaka/ClusterMaskDevice.h | 11 +++++++++++ .../TICL/interface/alpaka/HitsAndFractionsDevice.h | 12 ++++++++++++ DataFormats/TICL/src/alpaka/classes_cuda.h | 6 ++++++ DataFormats/TICL/src/alpaka/classes_cuda_def.xml | 9 +++++++++ DataFormats/TICL/src/alpaka/classes_rocm.h | 6 ++++++ DataFormats/TICL/src/alpaka/classes_rocm_def.xml | 9 +++++++++ DataFormats/TICL/src/classes.h | 4 ++++ DataFormats/TICL/src/classes_def.xml | 6 ++++++ 12 files changed, 113 insertions(+) create mode 100644 DataFormats/TICL/interface/ClusterMask.h create mode 100644 DataFormats/TICL/interface/ClusterMaskHost.h create mode 100644 DataFormats/TICL/interface/HitAndFraction.h create mode 100644 DataFormats/TICL/interface/HitsAndFractionsHost.h create mode 100644 DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h create mode 100644 DataFormats/TICL/interface/alpaka/HitsAndFractionsDevice.h create mode 100644 DataFormats/TICL/src/alpaka/classes_cuda.h create mode 100644 DataFormats/TICL/src/alpaka/classes_cuda_def.xml create mode 100644 DataFormats/TICL/src/alpaka/classes_rocm.h create mode 100644 DataFormats/TICL/src/alpaka/classes_rocm_def.xml create mode 100644 DataFormats/TICL/src/classes.h create mode 100644 DataFormats/TICL/src/classes_def.xml diff --git a/DataFormats/TICL/interface/ClusterMask.h b/DataFormats/TICL/interface/ClusterMask.h new file mode 100644 index 0000000000000..990f61e1ebcaa --- /dev/null +++ b/DataFormats/TICL/interface/ClusterMask.h @@ -0,0 +1,14 @@ + +#pragma once + +#include "DataFormats/SoATemplate/interface/SoALayout.h" + +namespace ticl { + + GENERATE_SOA_LAYOUT(ClusterMaskLayout, SOA_COLUMN(float, mask)); + + using ClusterMask = ClusterMaskLayout<>; + using ClusterMaskView = ClusterMask::View; + using ClusterMaskConstView = ClusterMask::ConstView; + +} // namespace ticl diff --git a/DataFormats/TICL/interface/ClusterMaskHost.h b/DataFormats/TICL/interface/ClusterMaskHost.h new file mode 100644 index 0000000000000..b4f508e03fcc2 --- /dev/null +++ b/DataFormats/TICL/interface/ClusterMaskHost.h @@ -0,0 +1,11 @@ + +#pragma once + +#include "DataFormats/Portable/interface/PortableHostCollection.h" +#include "DataFormats/TICL/interface/ClusterMask.h" + +namespace ticl { + + using ClusterMaskHost = PortableHostCollection; + +} diff --git a/DataFormats/TICL/interface/HitAndFraction.h b/DataFormats/TICL/interface/HitAndFraction.h new file mode 100644 index 0000000000000..b2a5566c816f9 --- /dev/null +++ b/DataFormats/TICL/interface/HitAndFraction.h @@ -0,0 +1,13 @@ + +#pragma once + +#include "DataFormats/DetId/interface/DetId.h" + +namespace ticl { + +struct HitAndFraction { + DetId hit; + float fraction; +}; + +} // namespace ticl diff --git a/DataFormats/TICL/interface/HitsAndFractionsHost.h b/DataFormats/TICL/interface/HitsAndFractionsHost.h new file mode 100644 index 0000000000000..f87ea5b72f980 --- /dev/null +++ b/DataFormats/TICL/interface/HitsAndFractionsHost.h @@ -0,0 +1,12 @@ + +#pragma once + +#include "DataFormats/Portable/interface/PortableHostCollection.h" +#include "DataFormats/TICL/interface/AssociationMap.h" +#include "DataFormats/TICL/interface/HitAndFraction.h" + +namespace ticl { + + using HitsAndFractionsHost = PortableHostCollection>; + +} diff --git a/DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h b/DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h new file mode 100644 index 0000000000000..2d6f8082e6471 --- /dev/null +++ b/DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h @@ -0,0 +1,11 @@ + +#pragma once + +#include "DataFormats/Portable/interface/PortableCollection.h" +#include "DataFormats/TICL/interface/ClusterMask.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { + + using ClusterMaskDevice = PortableCollection + +} diff --git a/DataFormats/TICL/interface/alpaka/HitsAndFractionsDevice.h b/DataFormats/TICL/interface/alpaka/HitsAndFractionsDevice.h new file mode 100644 index 0000000000000..e2dc525fc321a --- /dev/null +++ b/DataFormats/TICL/interface/alpaka/HitsAndFractionsDevice.h @@ -0,0 +1,12 @@ + +#pragma once + +#include "DataFormats/Portable/interface/alpaka/PortableCollection.h" +#include "DataFormats/TICL/interface/AssociationMap.h" +#include "DataFormats/TICL/interface/HitAndFraction.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { + + using HitsAndFractionsDevice = PortableCollection>; + +} diff --git a/DataFormats/TICL/src/alpaka/classes_cuda.h b/DataFormats/TICL/src/alpaka/classes_cuda.h new file mode 100644 index 0000000000000..38485b8a91fe3 --- /dev/null +++ b/DataFormats/TICL/src/alpaka/classes_cuda.h @@ -0,0 +1,6 @@ +#include "DataFormats/Common/interface/DeviceProduct.h" +#include "DataFormats/Common/interface/Wrapper.h" +#include "DataFormats/TICL/interface/ClusterMask.h" +#include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h" +#include "DataFormats/TICL/interface/AssociationMap.h" +#include "DataFormats/TICL/interface/alpaka/HitsAndFractionsDevice.h" diff --git a/DataFormats/TICL/src/alpaka/classes_cuda_def.xml b/DataFormats/TICL/src/alpaka/classes_cuda_def.xml new file mode 100644 index 0000000000000..fb2a13f67c75c --- /dev/null +++ b/DataFormats/TICL/src/alpaka/classes_cuda_def.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/DataFormats/TICL/src/alpaka/classes_rocm.h b/DataFormats/TICL/src/alpaka/classes_rocm.h new file mode 100644 index 0000000000000..38485b8a91fe3 --- /dev/null +++ b/DataFormats/TICL/src/alpaka/classes_rocm.h @@ -0,0 +1,6 @@ +#include "DataFormats/Common/interface/DeviceProduct.h" +#include "DataFormats/Common/interface/Wrapper.h" +#include "DataFormats/TICL/interface/ClusterMask.h" +#include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h" +#include "DataFormats/TICL/interface/AssociationMap.h" +#include "DataFormats/TICL/interface/alpaka/HitsAndFractionsDevice.h" diff --git a/DataFormats/TICL/src/alpaka/classes_rocm_def.xml b/DataFormats/TICL/src/alpaka/classes_rocm_def.xml new file mode 100644 index 0000000000000..cbf41600f1921 --- /dev/null +++ b/DataFormats/TICL/src/alpaka/classes_rocm_def.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/DataFormats/TICL/src/classes.h b/DataFormats/TICL/src/classes.h new file mode 100644 index 0000000000000..1ccf4d918d8bd --- /dev/null +++ b/DataFormats/TICL/src/classes.h @@ -0,0 +1,4 @@ +#include "DataFormats/TICL/interface/ClusterMask.h" +#include "DataFormats/TICL/interface/ClusterMaskHost.h" +#include "DataFormats/TICL/interface/AssociationMap.h" +#include "DataFormats/TICL/interface/HitsAndFractionsHost.h" diff --git a/DataFormats/TICL/src/classes_def.xml b/DataFormats/TICL/src/classes_def.xml new file mode 100644 index 0000000000000..3fcc2c578bb54 --- /dev/null +++ b/DataFormats/TICL/src/classes_def.xml @@ -0,0 +1,6 @@ + + + + + + From c32b25d9e3701d768e70654ef20c579f0aa1af8c Mon Sep 17 00:00:00 2001 From: Simone Date: Wed, 18 Mar 2026 17:28:25 +0100 Subject: [PATCH 11/24] Define `LayerClusterAndAssociations` wrapper --- .../interface/LayerClusterAndAssociations.h | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 RecoLocalCalo/HGCalRecProducers/interface/LayerClusterAndAssociations.h diff --git a/RecoLocalCalo/HGCalRecProducers/interface/LayerClusterAndAssociations.h b/RecoLocalCalo/HGCalRecProducers/interface/LayerClusterAndAssociations.h new file mode 100644 index 0000000000000..cdea7b2740cd0 --- /dev/null +++ b/RecoLocalCalo/HGCalRecProducers/interface/LayerClusterAndAssociations.h @@ -0,0 +1,21 @@ + +#pragma once + +#include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" +#include "DataFormats/TICL/interface/HitsAndFractionsHost.h" +#include + +namespace ticl { + + struct LayerClustersAndAssociations { + std::unique_ptr layer_clusters; + std::unique_ptr hits_and_fractions; + + LayerClustersAndAssociations(int number_of_clusters, int total_rechits) + : layer_clusters{std::make_unique( + cms::alpakatools::host(), number_of_clusters, number_of_clusters, number_of_clusters, number_of_clusters)}, + hits_and_fractions{ + std::make_unique(cms::alpakatools::host(), number_of_clusters, total_rechits)} {} + }; + +} // namespace ticl From 70bbaa5b0dfec47629fcc260923da1d021fa21fe Mon Sep 17 00:00:00 2001 From: Simone Date: Wed, 18 Mar 2026 17:28:48 +0100 Subject: [PATCH 12/24] Update legacy LC producer (missing timing) --- DataFormats/CaloRecHit/test/BuildFile.xml | 2 +- .../TICL/plugins/alpaka/ClusterFilterBase.h | 22 --- .../plugins/alpaka/ClusterFilterByAlgo.dev.cc | 19 --- .../TICL/plugins/alpaka/ClusterFilterByAlgo.h | 2 - .../plugins/HGCalCLUEAlgo.cc | 127 +++++++++--------- .../HGCalRecProducers/plugins/HGCalCLUEAlgo.h | 55 +------- .../plugins/HGCalLayerClusterProducer.cc | 26 ++-- 7 files changed, 82 insertions(+), 171 deletions(-) delete mode 100644 RecoHGCal/TICL/plugins/alpaka/ClusterFilterBase.h delete mode 100644 RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.dev.cc delete mode 100644 RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.h diff --git a/DataFormats/CaloRecHit/test/BuildFile.xml b/DataFormats/CaloRecHit/test/BuildFile.xml index 77266cb45b155..8f507461fbb6b 100644 --- a/DataFormats/CaloRecHit/test/BuildFile.xml +++ b/DataFormats/CaloRecHit/test/BuildFile.xml @@ -9,6 +9,6 @@ - + diff --git a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterBase.h b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterBase.h deleted file mode 100644 index e586bb67ab2e5..0000000000000 --- a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterBase.h +++ /dev/null @@ -1,22 +0,0 @@ - -#pragma once - -#include "DataFormats/HGCalReco/interface/Common.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" - -#include -#include - -namespace ALPAKA_ACCELERATOR_NAMESPACE { - class ClusterFilterBase { - public: - explicit ClusterFilterBase(const edm::ParameterSet&) = default; - virtual ~ClusterFilterBase() = default; - - virtual void filter(const HGCalSoAClustersDeviceCollection& layerClusters, - std::vector& layerClustersMask, - hgcal::RecHitTools& rhtools) const = 0; - }; - -} // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.dev.cc b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.dev.cc deleted file mode 100644 index 8762ff29e5bc5..0000000000000 --- a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.dev.cc +++ /dev/null @@ -1,19 +0,0 @@ - -#include -#include - -namespace ALPAKA_ACCELERATOR_NAMESPACE { - - struct KernelFilterLayerClusterByAlgo { - template - ALPAKA_ACC_FN void operator()(const TAcc& acc, - const int32_t* layerClusterAlgoId, - const int32_t* algo_number, - int32_t* layerClusterMask, - int32_t size) const { - for (auto idx : alpaka::uniformElements(acc, size)) { - } - } - }; - -} // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.h b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.h deleted file mode 100644 index 139597f9cb07c..0000000000000 --- a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgo.h +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc index 5e649bd95ce43..23cdc02c563f3 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc @@ -90,27 +90,29 @@ void HGCalCLUEAlgoT::populate(const HGCRecHitCollection &hits) { // input (reset should be called between events) template void HGCalCLUEAlgoT::makeClusters() { - float delta; - if constexpr (std::is_same_v) { - // maximum search distance (critical distance) for local density - // calculation - float delta_c; - if (i % maxlayer_ < lastLayerEE_) - delta_c = vecDeltas_[0]; - else if (i % maxlayer_ < (firstLayerBH_ - 1)) - delta_c = vecDeltas_[1]; - else - delta_c = vecDeltas_[2]; - delta = delta_c; - } else { - float delta_r = vecDeltas_[3]; - delta = delta_r; - } - auto clusterer = clue::Clusterer<2>(delta); - auto queue = clue::get_queue(0u); + for (auto l = 0u; l < maxlayer_; ++l) { + float delta; + if constexpr (std::is_same_v) { + // maximum search distance (critical distance) for local density + // calculation + float delta_c; + if (l % maxlayer_ < lastLayerEE_) + delta_c = vecDeltas_[0]; + else if (l % maxlayer_ < (firstLayerBH_ - 1)) + delta_c = vecDeltas_[1]; + else + delta_c = vecDeltas_[2]; + delta = delta_c; + } else { + float delta_r = vecDeltas_[3]; + delta = delta_r; + } - for (auto l = 0; l < maxlayer_; ++l) { - auto points = clue::PointsHost<2>(queue, cells_[l].dim1.size(), cells_[l].dim1, cells_[l].dim2, cells_[l].weight); + auto clusterer = clue::Clusterer<2>(delta, kappa_); + auto queue = clue::get_queue(0u); + auto points = clue::PointsHost<2>( + queue, cells_[l].dim1.size(), cells_[l].dim1, cells_[l].dim2, cells_[l].weight, cells_[l].clusterIndex); + points.set_density_uncertainty(cells_[l].sigmaNoise); clusterer.make_clusters(points); numberOfClustersPerLayer_[l] = points.n_clusters(); } @@ -121,54 +123,47 @@ void HGCalCLUEAlgoT::makeClusters() { } template -std::pair>> -HGCalCLUEAlgoT::getClusters(bool) { +ticl::LayerClustersAndAssociations HGCalCLUEAlgoT::getClusters(bool) { std::vector offsets(numberOfClustersPerLayer_.size(), 0); - int maxClustersOnLayer = numberOfClustersPerLayer_[0]; - for (unsigned layerId = 1; layerId < offsets.size(); ++layerId) { offsets[layerId] = offsets[layerId - 1] + numberOfClustersPerLayer_[layerId - 1]; - maxClustersOnLayer = std::max(maxClustersOnLayer, numberOfClustersPerLayer_[layerId]); } - auto totalNumberOfClusters = offsets.back() + numberOfClustersPerLayer_.back(); - // clusters_v_.resize(totalNumberOfClusters); - std::vector> cellsIdInCluster; - cellsIdInCluster.reserve(maxClustersOnLayer); - reco::CaloClusterHostCollection layer_clusters(cms::alpakatools::host(), - totalNumberOfClusters, - totalNumberOfClusters, - totalNumberOfClusters, - totalNumberOfClusters); - // FIXME: put the real number of hits - PortableHostCollection> hits_associations( - cms::alpakatools::host(), totalNumberOfClusters, 1); - std::vector detid_and_fractions; + // std::vector> cellsIdInCluster; + // cellsIdInCluster.reserve(maxClustersOnLayer); + const auto total_rechits = std::accumulate( + cells_.begin(), cells_.end(), 0, [](auto acc, const auto &cell) { return acc + cell.dim1.size(); }); + ticl::LayerClustersAndAssociations clusters_and_associations(totalNumberOfClusters, total_rechits); + + std::vector detid_and_fractions; std::vector cluster_hit_associations; for (unsigned int layerId = 0; layerId < 2 * maxlayer_ + 2; ++layerId) { auto queue = clue::get_queue(0u); - auto points = clue::PointsHost<2>( - queue, cells_[layerId].dim1.size(), cells_[layerId].dim1, cells_[layerId].dim2, cells_[layerId].weight); + auto points = clue::PointsHost<2>(queue, + cells_[layerId].dim1.size(), + cells_[layerId].dim1, + cells_[layerId].dim2, + cells_[layerId].weight, + cells_[layerId].clusterIndex); std::ranges::copy(points.clusterIndexes(), std::back_inserter(cluster_hit_associations)); auto clusters = clue::get_clusters(points); - auto to_hit_and_fraction = [&](auto idx) { return std::make_pair(cells_[layerId].detid[idx], -1.f); }; + auto to_hit_and_fraction = [&](auto idx) { return ticl::HitAndFraction{cells_[layerId].detid[idx], -1.f}; }; std::ranges::copy(clusters | std::views::transform(to_hit_and_fraction), std::back_inserter(detid_and_fractions)); - for (auto cl = 0; cl < clusters.size(); ++cl) { + for (auto cl = 0u; cl < clusters.size(); ++cl) { const auto cluster = clusters[cl]; auto x = 0.f; auto y = 0.f; const auto z = cells_[layerId].layerDim3; auto energy = std::reduce( - cluster.begin(), cluster.end(), 0.f, [](auto acc, auto idx) { return acc + points.weights()[idx]; }); - auto max_energy_it = std::ranges::max_element(points.weights); - const auto max_energy = *max_energy_it; - const auto max_energy_idx = std::distance(points.weights.begin(), max_energy_it); - const auto max_energy_detid = cells_[layerId].detid[max_energy_id]; + cluster.begin(), cluster.end(), 0.f, [&](auto acc, auto idx) { return acc + points.weights()[idx]; }); + auto max_energy_it = std::ranges::max_element(points.weights()); + const auto max_energy_idx = std::distance(points.weights().begin(), max_energy_it); + const auto max_energy_detid = cells_[layerId].detid[max_energy_idx]; if constexpr (std::is_same_v) { auto thick = rhtools_.getSiThickIndex(max_energy_detid); @@ -177,7 +172,7 @@ HGCalCLUEAlgoT::getClusters(bool) { const auto d1 = points.coords(0)[p] - points.coords(0)[max_energy_idx]; const auto d2 = points.coords(1)[p] - points.coords(1)[max_energy_idx]; if ((d1 * d1 + d2 * d2) < positionDeltaRho2_) { - auto Wi = std::max(thresholdW0_[thick] + std::log(points.weights()[p] / energy), 0.f); + auto Wi = std::max(thresholdW0_[thick] + std::log(points.weights()[p] / energy), 0.); x += points.coords(0)[p] * Wi; y += points.coords(1)[p] * Wi; total_weight_log += Wi; @@ -189,8 +184,8 @@ HGCalCLUEAlgoT::getClusters(bool) { x *= inv_tot_weight; y *= inv_tot_weight; } else { - x = cellsOnLayer.dim1[maxEnergyCellIndex]; - y = cellsOnLayer.dim2[maxEnergyCellIndex]; + x = points.coords(0)[max_energy_idx]; + y = points.coords(1)[max_energy_idx]; } } else { const auto centroid = clue::weighted_cluster_centroid(points, cl); @@ -198,23 +193,29 @@ HGCalCLUEAlgoT::getClusters(bool) { y = centroid[1]; } - layer_clusters.view().position().x()[globalClusterIndex] = x; - layer_clusters.view().position().y()[globalClusterIndex] = y; - layer_clusters.view().position().z()[globalClusterIndex] = z; - layer_clusters.view().energy().energy()[globalClusterIndex] = energy; - layer_clusters.view().energy().correctedEnergy()[globalClusterIndex] = -1.f; - layer_clusters.view().energy().correctedEnergyUncertainty()[globalClusterIndex] = -1.f; - layer_clusters.view().indexes().caloID()[globalClusterIndex] = reco::CaloID::DET_HGCAL_ENDCAP; - layer_clusters.view().indexes().algoID()[globalClusterIndex] = algoId_; - layer_clusters.view().indexes().seedID()[globalClusterIndex] = seedDetId; - layer_clusters.view().indexes().flags()[globalClusterIndex] = 0; + auto globalClusterIndex = cl + offsets[layerId]; + auto &layer_clusters_view = clusters_and_associations.layer_clusters->view(); + layer_clusters_view.position().x()[globalClusterIndex] = x; + layer_clusters_view.position().y()[globalClusterIndex] = y; + layer_clusters_view.position().z()[globalClusterIndex] = z; + layer_clusters_view.energy().energy()[globalClusterIndex] = energy; + layer_clusters_view.energy().correctedEnergy()[globalClusterIndex] = -1.f; + layer_clusters_view.energy().correctedEnergyUncertainty()[globalClusterIndex] = -1.f; + layer_clusters_view.indexes().caloID()[globalClusterIndex] = reco::CaloID::DET_HGCAL_ENDCAP; + layer_clusters_view.indexes().algoID()[globalClusterIndex] = algoId_; + // TODO: do we really care about the seed? + // layer_clusters.view().indexes().seedID()[globalClusterIndex] = seedDetId; + layer_clusters_view.indexes().flags()[globalClusterIndex] = 0; } } alpaka_serial_sync::Queue queue(cms::alpakatools::host()); - // ticl::associator::fill( - // queue, hits_associations, cluster_hit_associations, detid_and_fractions); + ticl::associator::fill( + queue, + clusters_and_associations.hits_and_fractions->view(), + static_cast>(cluster_hit_associations), + static_cast>(detid_and_fractions)); - return std::make_pair(layer_clusters, hits_associations); + return clusters_and_associations; } template diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h index 815484a72d9ed..66a4756032d75 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h @@ -9,6 +9,7 @@ #include "DataFormats/DetId/interface/DetId.h" #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" #include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h" +#include "DataFormats/TICL/interface/AssociationMap.h" #include "Geometry/CaloTopology/interface/HGCalTopology.h" #include "Geometry/HGCalGeometry/interface/HGCalGeometry.h" #include "Geometry/Records/interface/CaloGeometryRecord.h" @@ -19,6 +20,7 @@ #include "RecoLocalCalo/HGCalRecProducers/interface/HGCalLayerTiles.h" #include "RecoLocalCalo/HGCalRecProducers/interface/HGCalCLUEStrategy.h" +#include "RecoLocalCalo/HGCalRecProducers/interface/LayerClusterAndAssociations.h" #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" @@ -74,7 +76,7 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { void makeClusters() override; // this is the method to get the cluster collection out - reco::CaloClusterHostCollection getClusters(bool) override; + ticl::LayerClustersAndAssociations getClusters(bool) override; void reset() override { clusters_v_.clear(); @@ -127,7 +129,7 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { } /// point in the space - typedef math::XYZPoint Point; + using Point = math::XYZPoint; private: // The two parameters used to identify clusters @@ -165,16 +167,10 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { std::vector detid; std::vector dim1; std::vector dim2; - std::vector weight; - std::vector rho; - - std::vector delta; - std::vector nearestHigher; - std::vector clusterIndex; std::vector sigmaNoise; - std::vector> followers; - std::vector isSeed; + std::vector clusterIndex; + float layerDim3 = std::numeric_limits::infinity(); void clear() { @@ -182,13 +178,6 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { dim1.clear(); dim2.clear(); weight.clear(); - rho.clear(); - delta.clear(); - nearestHigher.clear(); - clusterIndex.clear(); - sigmaNoise.clear(); - followers.clear(); - isSeed.clear(); } void shrink_to_fit() { @@ -196,13 +185,6 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { dim1.shrink_to_fit(); dim2.shrink_to_fit(); weight.shrink_to_fit(); - rho.shrink_to_fit(); - delta.shrink_to_fit(); - nearestHigher.shrink_to_fit(); - clusterIndex.shrink_to_fit(); - sigmaNoise.shrink_to_fit(); - followers.shrink_to_fit(); - isSeed.shrink_to_fit(); } }; @@ -213,31 +195,6 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { #if DEBUG_CLUSTERS_ALPAKA std::string moduleType_; #endif - - inline float distance2(const TILE& lt, int cell1, int cell2, int layerId) const { // 2-d distance on the layer (x-y) - return (lt.distance2(cells_[layerId].dim1[cell1], - cells_[layerId].dim2[cell1], - cells_[layerId].dim1[cell2], - cells_[layerId].dim2[cell2])); - } - - inline float distance(const TILE& lt, int cell1, int cell2, int layerId) const { // 2-d distance on the layer (x-y) - return std::sqrt(lt.distance2(cells_[layerId].dim1[cell1], - cells_[layerId].dim2[cell1], - cells_[layerId].dim1[cell2], - cells_[layerId].dim2[cell2])); - } - - void prepareDataStructures(const unsigned int layerId); - void calculateLocalDensity(const TILE& lt, const unsigned int layerId, - float delta); // return max density - void calculateLocalDensity(const TILE& lt, const unsigned int layerId, float delta, HGCalSiliconStrategy strategy); - void calculateLocalDensity(const TILE& lt, - const unsigned int layerId, - float delta, - HGCalScintillatorStrategy strategy); - void calculateDistanceToHigher(const TILE& lt, const unsigned int layerId, float delta); - int findAndAssignClusters(const unsigned int layerId, float delta); }; // explicit template instantiation diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc index 08506fe839f32..0559e745825a8 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc @@ -35,6 +35,7 @@ #include "DataFormats/ParticleFlowReco/interface/PFCluster.h" #include "DataFormats/Common/interface/ValueMap.h" #include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" +#include "DataFormats/TICL/interface/AssociationMap.h" #if DEBUG_CLUSTERS_ALPAKA #include "RecoLocalCalo/HGCalRecProducers/interface/DumpClustersDetails.h" @@ -260,11 +261,12 @@ void HGCalLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& algo_->makeClusters(); - auto clusters = std::make_unique(new reco::CaloClusterHostCollection); - *clusters = algo_->getClusters(false); + auto clusters_and_associations = algo_->getClusters(false); + auto clusters = std::move(clusters_and_associations.layer_clusters); + auto hits_and_fractions = std::move(clusters_and_associations.hits_and_fractions); std::vector> times; - times.reserve(clusters->view().metadata().size()); + times.reserve(clusters->view().position().metadata().size()); // for (unsigned i = 0; i < legacy_clusters->size(); ++i) { // reco::CaloCluster& sCl = (*legacy_clusters)[i]; @@ -287,13 +289,11 @@ void HGCalLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& dumper.dumpInfos(*legacy_clusters, moduleLabel_, runNumber, lumiNumber, evtNumber, true); #endif - // auto clusterHandle = evt.put(std::move(clusters)); - - // if (detector_ == "HFNose") { - // std::unique_ptr> layerClustersMask(new std::vector); - // layerClustersMask->resize(legacy_clusters->size(), 1.0); - // evt.put(std::move(layerClustersMask), "InitialLayerClustersMask"); - // } + if (detector_ == "HFNose") { + std::unique_ptr> layerClustersMask(new std::vector); + layerClustersMask->resize(clusters->view().position().metadata().size(), 1.0); + evt.put(std::move(layerClustersMask), "InitialLayerClustersMask"); + } // auto timeCl = std::make_unique>>(); // edm::ValueMap>::Filler filler(*timeCl); @@ -301,12 +301,8 @@ void HGCalLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& // filler.fill(); // evt.put(std::move(timeCl), timeClname_); - // for (auto i = 0; i < timeCl->size(); ++i) { - // clusters->view().timing().time()[i] = (*timeCl)[i].first; - // clusters->view().timing().timeError()[i] = (*timeCl)[i].second; - // } - evt.put(std::move(clusters)); + evt.put(std::move(hits_and_fractions)); algo_->reset(); } From a280ac276fc7ab9abcb48ff0c442313d0a9aa0df Mon Sep 17 00:00:00 2001 From: Simone Date: Fri, 20 Mar 2026 10:07:18 +0100 Subject: [PATCH 13/24] Use `CaloClusterSoA` for alpaka LC producer --- .../HGCalRecProducers/plugins/BuildFile.xml | 3 ++ .../HGCalLayerClustersSoAAlgoWrapper.dev.cc | 54 ++++++++++--------- .../alpaka/HGCalLayerClustersSoAAlgoWrapper.h | 5 +- .../alpaka/HGCalSoALayerClustersProducer.cc | 6 ++- 4 files changed, 38 insertions(+), 30 deletions(-) diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/BuildFile.xml b/RecoLocalCalo/HGCalRecProducers/plugins/BuildFile.xml index d83728b81c18a..c41b624c89797 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/BuildFile.xml +++ b/RecoLocalCalo/HGCalRecProducers/plugins/BuildFile.xml @@ -1,5 +1,6 @@ + @@ -20,6 +21,7 @@ + @@ -32,6 +34,7 @@ + diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.dev.cc b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.dev.cc index 52653063e2e2a..ca0563c23d0c5 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.dev.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.dev.cc @@ -5,6 +5,8 @@ #include "CLUEAlgoAlpaka.h" +#include + namespace ALPAKA_ACCELERATOR_NAMESPACE { using namespace cms::alpakatools; @@ -17,18 +19,18 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { const unsigned int numer_of_clusters, const HGCalSoARecHitsDeviceCollection::ConstView input_rechits_soa, const HGCalSoARecHitsExtraDeviceCollection::ConstView input_clusters_soa, - HGCalSoAClustersDeviceCollection::View outputs) const { + reco::CaloClusterDeviceCollection::View outputs) const { // make a strided loop over the kernel grid, covering up to "size" elements - for (int32_t i : uniform_elements(acc, input_rechits_soa.metadata().size())) { + for (auto i : uniform_elements(acc, input_rechits_soa.metadata().size())) { // Skip unassigned rechits if (input_clusters_soa[i].clusterIndex() == kInvalidCluster) { continue; } auto clIdx = input_clusters_soa[i].clusterIndex(); - alpaka::atomicAdd(acc, &outputs[clIdx].energy(), input_rechits_soa[i].energy()); - alpaka::atomicAdd(acc, &outputs[clIdx].cells(), 1); + alpaka::atomicAdd(acc, &outputs.energy()[clIdx].energy(), input_rechits_soa[i].energy()); + alpaka::atomicAdd(acc, &outputs.position()[clIdx].cells(), 1); if (input_clusters_soa[i].isSeed() == 1) { - outputs[clIdx].seed() = input_rechits_soa[i].detid(); + outputs.indexes()[clIdx].seedID() = input_rechits_soa[i].detid(); } } } @@ -43,7 +45,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { float positionDeltaRho2, const HGCalSoARecHitsDeviceCollection::ConstView input_rechits_soa, const HGCalSoARecHitsExtraDeviceCollection::ConstView input_clusters_soa, - HGCalSoAClustersDeviceCollection::View outputs, + reco::CaloClusterDeviceCollection::View outputs, HGCalSoAClustersExtraDeviceCollection::View outputs_service) const { // make a strided loop over the kernel grid, covering up to "size" elements for (int32_t hit_index : uniform_elements(acc, input_rechits_soa.metadata().size())) { @@ -74,8 +76,8 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { clusterEnergy = (clusterSeed == kInvalidIndex) ? 0.f : input_rechits_soa[clusterSeed].energy(); } } // CAS - } // uniform_elements - } // operator() + } // uniform_elements + } // operator() }; // Real Kernel position @@ -87,10 +89,10 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { float positionDeltaRho2, const HGCalSoARecHitsDeviceCollection::ConstView input_rechits_soa, const HGCalSoARecHitsExtraDeviceCollection::ConstView input_clusters_soa, - HGCalSoAClustersDeviceCollection::View outputs, + reco::CaloClusterDeviceCollection::View outputs, HGCalSoAClustersExtraDeviceCollection::View outputs_service) const { // make a strided loop over the kernel grid, covering up to "size" elements - for (int32_t hit_index : uniform_elements(acc, input_rechits_soa.metadata().size())) { + for (auto hit_index : uniform_elements(acc, input_rechits_soa.metadata().size())) { const int cluster_index = input_clusters_soa[hit_index].clusterIndex(); // Bail out if you are not part of any cluster @@ -108,11 +110,11 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { float Wi = std::max(thresholdW0 + std::log(input_rechits_soa[hit_index].energy() / outputs_service[cluster_index].total_weight()), 0.f); - alpaka::atomicAdd(acc, &outputs[cluster_index].x(), input_rechits_soa[hit_index].dim1() * Wi); - alpaka::atomicAdd(acc, &outputs[cluster_index].y(), input_rechits_soa[hit_index].dim2() * Wi); + alpaka::atomicAdd(acc, &outputs.position()[cluster_index].x(), input_rechits_soa[hit_index].dim1() * Wi); + alpaka::atomicAdd(acc, &outputs.position()[cluster_index].y(), input_rechits_soa[hit_index].dim2() * Wi); alpaka::atomicAdd(acc, &outputs_service[cluster_index].total_weight_log(), Wi); } // uniform_elements - } // operator() + } // operator() }; // Besides the final position, add also the DetId of the seed of each cluster @@ -124,23 +126,23 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { float positionDeltaRho2, const HGCalSoARecHitsDeviceCollection::ConstView input_rechits_soa, const HGCalSoARecHitsExtraDeviceCollection::ConstView input_clusters_soa, - HGCalSoAClustersDeviceCollection::View outputs, + reco::CaloClusterDeviceCollection::View outputs, HGCalSoAClustersExtraDeviceCollection::View outputs_service) const { // make a strided loop over the kernel grid, covering up to "size" elements - for (int32_t cluster_index : uniform_elements(acc, outputs.metadata().size())) { + for (auto cluster_index : uniform_elements(acc, outputs.position().metadata().size())) { const int max_energy_index = outputs_service[cluster_index].maxEnergyIndex(); if (outputs_service[cluster_index].total_weight_log() > 0.f) { float inv_tot_weight = 1.f / outputs_service[cluster_index].total_weight_log(); - outputs[cluster_index].x() *= inv_tot_weight; - outputs[cluster_index].y() *= inv_tot_weight; + outputs.position()[cluster_index].x() *= inv_tot_weight; + outputs.position()[cluster_index].y() *= inv_tot_weight; } else { - outputs[cluster_index].x() = input_rechits_soa[max_energy_index].dim1(); - outputs[cluster_index].y() = input_rechits_soa[max_energy_index].dim2(); + outputs.position()[cluster_index].x() = input_rechits_soa[max_energy_index].dim1(); + outputs.position()[cluster_index].y() = input_rechits_soa[max_energy_index].dim2(); } - outputs[cluster_index].z() = input_rechits_soa[max_energy_index].dim3(); + outputs.position()[cluster_index].z() = input_rechits_soa[max_energy_index].dim3(); } // uniform_elements - } // operator() + } // operator() }; void HGCalLayerClustersSoAAlgoWrapper::run(Queue& queue, @@ -149,15 +151,15 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { float positionDeltaRho2, const HGCalSoARecHitsDeviceCollection::ConstView input_rechits_soa, const HGCalSoARecHitsExtraDeviceCollection::ConstView input_clusters_soa, - HGCalSoAClustersDeviceCollection::View outputs, + reco::CaloClusterDeviceCollection::View outputs, HGCalSoAClustersExtraDeviceCollection::View outputs_service) const { - auto x = cms::alpakatools::make_device_view(queue, outputs.x(), size); + auto x = cms::alpakatools::make_device_view(queue, outputs.position().x()); alpaka::memset(queue, x, 0x0); - auto y = cms::alpakatools::make_device_view(queue, outputs.y(), size); + auto y = cms::alpakatools::make_device_view(queue, outputs.position().y()); alpaka::memset(queue, y, 0x0); - auto energy = cms::alpakatools::make_device_view(queue, outputs.energy(), size); + auto energy = cms::alpakatools::make_device_view(queue, outputs.energy().energy()); alpaka::memset(queue, energy, 0x0); - auto cells = cms::alpakatools::make_device_view(queue, outputs.cells(), size); + auto cells = cms::alpakatools::make_device_view(queue, outputs.position().cells()); alpaka::memset(queue, cells, 0x0); auto total_weight = cms::alpakatools::make_device_view(queue, outputs_service.total_weight(), size); alpaka::memset(queue, total_weight, 0x0); diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.h b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.h index 8262966233d52..a70211912f51e 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.h +++ b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.h @@ -6,7 +6,8 @@ #include "DataFormats/HGCalReco/interface/HGCalSoARecHitsHostCollection.h" #include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsDeviceCollection.h" #include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsExtraDeviceCollection.h" -#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoAClustersDeviceCollection.h" +// #include "DataFormats/HGCalReco/interface/alpaka/HGCalSoAClustersDeviceCollection.h" +#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" #include "RecoLocalCalo/HGCalRecProducers/interface/alpaka/HGCalSoAClustersExtraDeviceCollection.h" #include "HeterogeneousCore/AlpakaInterface/interface/config.h" #include "HeterogeneousCore/AlpakaInterface/interface/traits.h" @@ -22,7 +23,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { float positionDeltaRho2, const HGCalSoARecHitsDeviceCollection::ConstView input_rechits_soa, const HGCalSoARecHitsExtraDeviceCollection::ConstView input_clusters_soa, - HGCalSoAClustersDeviceCollection::View outputs, + reco::CaloClusterDeviceCollection::View outputs, HGCalSoAClustersExtraDeviceCollection::View outputs_service) const; }; } // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalSoALayerClustersProducer.cc b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalSoALayerClustersProducer.cc index 7d22480437c6e..c29eb5817d612 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalSoALayerClustersProducer.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalSoALayerClustersProducer.cc @@ -2,6 +2,7 @@ #include "DataFormats/HGCalReco/interface/HGCalSoARecHitsHostCollection.h" #include "DataFormats/HGCalReco/interface/alpaka/HGCalSoAClustersDeviceCollection.h" #include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsExtraDeviceCollection.h" +#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" #include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" @@ -58,7 +59,8 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { auto const& deviceInputClusters = iEvent.get(getTokenDeviceClusters_); auto const inputClusters_v = deviceInputClusters.view(); - HGCalSoAClustersDeviceCollection output(iEvent.queue(), num_clusters_); + reco::CaloClusterDeviceCollection output( + iEvent.queue(), num_clusters_, num_clusters_, num_clusters_, num_clusters_); auto output_v = output.view(); // Allocate workspace SoA cluster HGCalSoAClustersExtraDeviceCollection outputWorkspace(iEvent.queue(), num_clusters_); @@ -87,7 +89,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { private: device::EDGetToken const getTokenDeviceRecHits_; device::EDGetToken const getTokenDeviceClusters_; - device::EDPutToken const deviceTokenSoAClusters_; + device::EDPutToken const deviceTokenSoAClusters_; HGCalLayerClustersSoAAlgoWrapper algo_; unsigned int num_clusters_; float thresholdW0_; From 7a4910acc656251e6e53ab215573f01aa00b564a Mon Sep 17 00:00:00 2001 From: Simone Date: Fri, 20 Mar 2026 10:07:39 +0100 Subject: [PATCH 14/24] Implement heterogeneous LC merging --- .../alpaka/LayerClusterMergingAlgo.dev.cc | 37 ++++++++ .../plugins/alpaka/LayerClusterMergingAlgo.h | 23 +++++ .../alpaka/MergedLayerClusterProducer.cc | 84 +++++++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.dev.cc create mode 100644 RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.h create mode 100644 RecoLocalCalo/HGCalRecProducers/plugins/alpaka/MergedLayerClusterProducer.cc diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.dev.cc b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.dev.cc new file mode 100644 index 0000000000000..825e6c830dd1d --- /dev/null +++ b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.dev.cc @@ -0,0 +1,37 @@ + +#include "RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + ALPAKA_FN_ACC void KernelMergeLayerClusters::operator()(const Acc1D& acc, + reco::CaloClusterDeviceCollection::View merged, + reco::CaloClusterDeviceCollection::ConstView input, + uint32_t start) const { + for (auto idx : alpaka::uniformElements(acc, input.position().metadata().size())) { + auto cumulative_index = idx + start; + merged.position().x()[cumulative_index] = merged.position().x()[idx]; + merged.position().y()[cumulative_index] = merged.position().y()[idx]; + merged.position().z()[cumulative_index] = merged.position().z()[idx]; + merged.energy().energy()[cumulative_index] = merged.energy().energy()[idx]; + merged.energy().correctedEnergy()[cumulative_index] = merged.energy().correctedEnergy()[idx]; + merged.energy().correctedEnergyUncertainty()[cumulative_index] = + merged.energy().correctedEnergyUncertainty()[idx]; + merged.indexes().caloID()[cumulative_index] = merged.indexes().caloID()[idx]; + merged.indexes().algoID()[cumulative_index] = merged.indexes().algoID()[idx]; + merged.indexes().seedID()[cumulative_index] = merged.indexes().seedID()[idx]; + merged.indexes().flags()[cumulative_index] = merged.indexes().flags()[idx]; + } + } + + void LayerClusterMerger::merge(Queue& queue, + reco::CaloClusterDeviceCollection::View merged, + reco::CaloClusterDeviceCollection::ConstView input, + uint32_t& start) { + const auto blocksize = 1024u; + const auto gridsize = cms::alpakatools::divide_up_by(input.position().metadata().size(), blocksize); + const auto workdivision = cms::alpakatools::make_workdiv(gridsize, blocksize); + alpaka::exec(queue, workdivision, KernelMergeLayerClusters{}, merged, input, start); + start += input.position().metadata().size(); + } + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.h b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.h new file mode 100644 index 0000000000000..48e7890922e23 --- /dev/null +++ b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.h @@ -0,0 +1,23 @@ + +#pragma once + +#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" +#include "HeterogeneousCore/AlpakaInterface/interface/workdivision.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + struct KernelMergeLayerClusters { + ALPAKA_FN_ACC void operator()(const Acc1D& acc, + reco::CaloClusterDeviceCollection::View merged, + reco::CaloClusterDeviceCollection::ConstView input, + uint32_t start) const; + }; + + struct LayerClusterMerger { + void merge(Queue& queue, + reco::CaloClusterDeviceCollection::View merged, + reco::CaloClusterDeviceCollection::ConstView input, + uint32_t& start); + }; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/MergedLayerClusterProducer.cc b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/MergedLayerClusterProducer.cc new file mode 100644 index 0000000000000..e12a4b7af125e --- /dev/null +++ b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/MergedLayerClusterProducer.cc @@ -0,0 +1,84 @@ + +#include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" +#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" +#include "DataFormats/TICL/interface/ClusterMaskHost.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/EDPutToken.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/EDGetToken.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/stream/EDProducer.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.h" + +#include + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + class MergedLayerClustersProducer : public stream::EDProducer<> { + public: + MergedLayerClustersProducer(const edm::ParameterSet& config) + : EDProducer(config), layer_cluster_mask_token_{produces()} { + std::vector host_tags = config.getParameter>("hostLayerClusters"); + for (auto& tag : host_tags) { + host_layer_cluster_tokens_.push_back(consumes<::reco::CaloClusterHostCollection>(tag)); + } + std::vector device_tags = config.getParameter>("deviceLayerClusters"); + for (auto& tag : device_tags) { + device_layer_cluster_tokens_.push_back(consumes(tag)); + } + } + ~MergedLayerClustersProducer() = default; + + static void fillDescription(edm::ConfigurationDescriptions& description) { + edm::ParameterSetDescription desc; + + desc.add("deviceLayerClusters"); + + description.addWithDefaultLabel(desc); + } + + void produce(device::Event& iEvent, const device::EventSetup& iSetup) override { + auto& queue = iEvent.queue(); + std::vector> hostLayerClusters; + // std::vector> deviceLayerClusters; + + auto total_layer_clusters = 0; + // auto total_associated_rechits = 0; + for (auto token : host_layer_cluster_tokens_) { + auto handle = iEvent.getHandle(token); + total_layer_clusters += handle->view().position().metadata().size(); + hostLayerClusters.push_back(handle); + } + for (const auto& token : device_layer_cluster_tokens_) { + const auto& prod = iEvent.get(token); + total_layer_clusters += prod.view().position().metadata().size(); + } + + reco::CaloClusterDeviceCollection merged_layer_clusters( + queue, total_layer_clusters, total_layer_clusters, total_layer_clusters, total_layer_clusters); + + auto start = 0u; + for (const auto& token : device_layer_cluster_tokens_) { + const auto& layer_clusters = iEvent.get(token); + merging_algo.merge(iEvent.queue(), merged_layer_clusters.view(), layer_clusters.view(), start); + } + + ticl::ClusterMaskHost layer_cluster_mask(cms::alpakatools::host(), total_layer_clusters); + + iEvent.emplace(layer_cluster_mask_token_, std::move(layer_cluster_mask)); + iEvent.emplace(merged_layer_clusters_token_, std::move(merged_layer_clusters)); + } + + private: + std::vector> device_layer_cluster_tokens_; + std::vector> host_layer_cluster_tokens_; + edm::EDPutTokenT<::ticl::ClusterMaskHost> layer_cluster_mask_token_; + device::EDPutToken merged_layer_clusters_token_; + LayerClusterMerger merging_algo; + }; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE From 0b9b01d207532b839f1678a54d35b79285ae08b6 Mon Sep 17 00:00:00 2001 From: Simone Date: Fri, 19 Dec 2025 14:53:05 +0100 Subject: [PATCH 15/24] [WIP] Add heterogeneous filtered layer cluster producer --- .../alpaka/ClusterFilterByAlgoAndSize.dev.cc | 45 +++++++++++++ .../alpaka/ClusterFilterByAlgoAndSize.h | 29 ++++++++ .../alpaka/FilteredLayerClustersProducer.cc | 66 +++++++++++++++++++ .../PatternRecognitionByCLUEstering.dev.cc | 6 +- .../interface/HGCalClusteringAlgoBase.h | 21 +++--- 5 files changed, 154 insertions(+), 13 deletions(-) create mode 100644 RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc create mode 100644 RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc diff --git a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc new file mode 100644 index 0000000000000..33a7b095c6dff --- /dev/null +++ b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc @@ -0,0 +1,45 @@ + +#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" +#include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h" +#include "HeterogeneousCore/AlpakaInterface/interface/workdivision.h" +#include "RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h" + +#include +#include + +namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { + + template + ALPAKA_FN_ACC void KernelFilterLayerClusterByAlgoAndSize::operator()( + const TAcc& acc, + reco::CaloClusterDeviceCollection::ConstView layerClusters, + std::span algoNumber, + ticl::ClusterMaskDevice::View layerClusterMask, + uint32_t minClusterSize, + uint32_t maxClusterSize) const { + for (auto lcIdx : alpaka::uniformElements(acc, layerClusters.position().metadata().size())) { + bool foundAlgoNumber = false; + for (auto algo : algoNumber) { + if (algo == *layerClusters[lcIdx].algoID()) + foundAlgoNumber = true; + } + const auto layerClusterSize = hitsAssociations[lcIdx].size(); + if (foundAlgoNumber && (layerClusterSize < minClusterSize) || (layerClusterSize > maxClusterSize)) + layerClusterMask[lcIdx] = 0.f; + else + layerClusterMask[lcIdx] = 1.f; + } + } + + void ClusterFilterByAlgoAndSize::filter(Queue& queue, + const reco::CaloClusterDeviceCollection& layerClusters, + uint32_t minClusterSize, + uint32_t maxClusterSize) { + auto blocksize = 1024; + auto gridsize = cms::alpakatools::divide_up_by(layerClusters.metadata().size(), blocksize); + auto workdivision = cms::alpakatools::make_workdiv(gridsize, blocksize); + alpaka::exec( + queue, workdivision, KernelFilterLayerClusterByAlgoAndSize{}, layerClusters.view(), hitsAssociations.view()); + } + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl diff --git a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h index e69de29bb2d1d..21c865044335f 100644 --- a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h +++ b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h @@ -0,0 +1,29 @@ + +#pragma once + +#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" +#include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h" + +#include +#include + +namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { + + struct KernelFilterLayerClusterByAlgoAndSize { + template + ALPAKA_FN_ACC void operator()(const TAcc& acc, + reco::CaloClusterDeviceCollection::ConstView layerClusters, + std::span algoNumber, + ticl::ClusterMaskDevice::View layerClusterMask, + uint32_t minClusterSize, + uint32_t maxClusterSize) const; + }; + + class ClusterFilterByAlgoAndSize { + void filter(Queue& queue, + const reco::CaloClusterDeviceCollection& layerClusters, + uint32_t minClusterSize, + uint32_t maxClusterSize); + }; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl diff --git a/RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc b/RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc new file mode 100644 index 0000000000000..5ba13ee6a6692 --- /dev/null +++ b/RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc @@ -0,0 +1,66 @@ +#include +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" +#include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/ParameterSet/interface/PluginDescription.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "Geometry/HGCalGeometry/interface/HGCalGeometry.h" +#include "FWCore/Utilities/interface/EDPutToken.h" +#include "DataFormats/HGCalReco/interface/Trackster.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESGetToken.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/stream/EDProducer.h" + +#include "RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h" + +#include +#include + +namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { + + class HeterogeneousFilteredLayerClustersProducer : public stream::EDProducer<> { + public: + HeterogeneousFilteredLayerClustersProducer(const edm::ParameterSet& config) + : EDProducer(config), + deviceTokenSoAClusters_{consumes(config.getParameter("layerClusters"))}, + clustersMaskToken_{consumes(config.getParameter("layerClustersInputMask"))}, + minClusterSize_{config.getParameter("minClusterSize")}, + maxClusterSize_{config.getParameter("maxClusterSize")}, + deviceTokenFilteredSoAClusters_{produces()} {} + ~HeterogeneousFilteredLayerClustersProducer() override = default; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("layerClusters", edm::InputTag("hgcalSoALayerClusters")); + desc.add("layerClustersInputMask", + edm::InputTag("hgcalMergeLayerClusters", "InitialLayerClustersMask")); + desc.add("minClusterSize"); + desc.add("maxClusterSize"); + + descriptions.addWithDefaultLabel(desc); + } + + void produce(device::Event& iEvent, const device::EventSetup& iSetup) override { + const auto& layerClusters = iEvent.get(deviceTokenSoAClusters_); + auto& layerClustersMask = iEvent.get(clustersMaskToken_); + + ClusterFilterByAlgoAndSize::filter(iEvent.queue(), layerClusters.view(), minClusterSize_, maxClusterSize_); + + iEvent.emplace(layerClustersMask, clustersMaskToken_); + } + + private: + device::EDGetToken const deviceTokenSoAClusters_; + device::EDGetToken clustersMaskToken_; + device::EDPutToken filteredClustersMaskToken_; + + const uint32_t minClusterSize_; + const uint32_t maxClusterSize_; + + ClusterFilterByAlgoAndSize algo_; + }; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc index cf1f6c783db54..564e3c9ffa27a 100644 --- a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc +++ b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc @@ -61,15 +61,15 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { } alpaka::memcpy(queue, - cms::alpakatools::make_host_view(h_points.view().coords[0], n), + cms::alpakatools::make_host_view(h_points.view().coords()[0], n), cms::alpakatools::make_device_view(alpaka::getDev(queue), x, n), static_cast(n)); alpaka::memcpy(queue, - cms::alpakatools::make_host_view(h_points.view().coords[1], n), + cms::alpakatools::make_host_view(h_points.view().coords()[1], n), cms::alpakatools::make_device_view(alpaka::getDev(queue), y, n), static_cast(n)); alpaka::memcpy(queue, - cms::alpakatools::make_host_view(h_points.view().coords[2], n), + cms::alpakatools::make_host_view(h_points.view().coords()[2], n), cms::alpakatools::make_device_view(alpaka::getDev(queue), z, n), static_cast(n)); alpaka::memcpy(queue, diff --git a/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h b/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h index 1b14a3d251b4f..e1e8aa32c24f4 100644 --- a/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h +++ b/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h @@ -1,25 +1,26 @@ #ifndef RecoLocalCalo_HGCalRecProducers_HGCalClusteringAlgoBase_h #define RecoLocalCalo_HGCalRecProducers_HGCalClusteringAlgoBase_h -#include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/ConsumesCollector.h" +#include "FWCore/Framework/interface/EventSetup.h" #include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" +#include "DataFormats/EgammaReco/interface/BasicCluster.h" #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" -#include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h" #include "DataFormats/Math/interface/Point3D.h" -#include "DataFormats/EgammaReco/interface/BasicCluster.h" +#include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h" #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" +#include "RecoLocalCalo/HGCalRecProducers/interface/LayerClusterAndAssociations.h" #include "CondFormats/DataRecord/interface/EcalPFRecHitThresholdsRcd.h" -#include "CondFormats/EcalObjects/interface/EcalPFRecHitThresholds.h" #include "CondFormats/DataRecord/interface/HcalPFCutsRcd.h" +#include "CondFormats/EcalObjects/interface/EcalPFRecHitThresholds.h" #include "CondFormats/HcalObjects/interface/HcalPFCuts.h" // C/C++ headers -#include #include +#include namespace hgcal_clustering { template @@ -47,7 +48,7 @@ namespace hgcal_clustering { return (*maxidx); } - //Density collection + // Density collection typedef std::map Density; }; // namespace hgcal_clustering @@ -62,10 +63,10 @@ class HGCalClusteringAlgoBase { virtual void populate(const HGCRecHitCollection &hits) = 0; virtual void populate(const reco::PFRecHitCollection &hits) = 0; virtual void makeClusters() = 0; - virtual reco::CaloClusterHostCollection getClusters(bool) = 0; + virtual ticl::LayerClustersAndAssociations getClusters(bool) = 0; virtual void reset() = 0; - virtual hgcal_clustering::Density getDensity() { return {}; }; //implementation is in some child class - virtual void getEventSetupPerAlgorithm(const edm::EventSetup &es) {} //implementation is in some child class + virtual hgcal_clustering::Density getDensity() { return {}; }; // implementation is in some child class + virtual void getEventSetupPerAlgorithm(const edm::EventSetup &es) {} // implementation is in some child class inline void getEventSetup(const edm::EventSetup &es, hgcal::RecHitTools rhtools) { rhtools_ = rhtools; @@ -84,7 +85,7 @@ class HGCalClusteringAlgoBase { virtual void setThresholds(edm::ESGetToken, edm::ESGetToken){}; - //max number of layers + // max number of layers unsigned int maxlayer_ = 0; // last layer per subdetector unsigned int lastLayerEE_ = 0; From 0a731ca38bdeb6861a92fd0bd116b391045d50b8 Mon Sep 17 00:00:00 2001 From: Simone Date: Mon, 23 Mar 2026 11:21:54 +0100 Subject: [PATCH 16/24] Finalize heterogeneous filtered LC producer --- .../TICL/interface/alpaka/ClusterMaskDevice.h | 4 +-- .../alpaka/ClusterFilterByAlgoAndSize.dev.cc | 26 +++++++++++++------ .../alpaka/ClusterFilterByAlgoAndSize.h | 11 +++++++- .../alpaka/FilteredLayerClustersProducer.cc | 14 ++++++---- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h b/DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h index 2d6f8082e6471..9a16c4c32c8f8 100644 --- a/DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h +++ b/DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h @@ -1,11 +1,11 @@ #pragma once -#include "DataFormats/Portable/interface/PortableCollection.h" +#include "DataFormats/Portable/interface/alpaka/PortableCollection.h" #include "DataFormats/TICL/interface/ClusterMask.h" namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { - using ClusterMaskDevice = PortableCollection + using ClusterMaskDevice = PortableCollection<::ticl::ClusterMask>; } diff --git a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc index 33a7b095c6dff..9fd7401c98acf 100644 --- a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc +++ b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc @@ -1,11 +1,14 @@ #include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" +#include "DataFormats/TICL/interface/alpaka/AlgoNumberDevice.h" #include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h" #include "HeterogeneousCore/AlpakaInterface/interface/workdivision.h" +#include "HeterogeneousCore/AlpakaInterface/interface/memory.h" #include "RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h" #include #include +#include namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { @@ -13,33 +16,40 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { ALPAKA_FN_ACC void KernelFilterLayerClusterByAlgoAndSize::operator()( const TAcc& acc, reco::CaloClusterDeviceCollection::ConstView layerClusters, - std::span algoNumber, + std::span algoNumber, ticl::ClusterMaskDevice::View layerClusterMask, uint32_t minClusterSize, uint32_t maxClusterSize) const { for (auto lcIdx : alpaka::uniformElements(acc, layerClusters.position().metadata().size())) { bool foundAlgoNumber = false; for (auto algo : algoNumber) { - if (algo == *layerClusters[lcIdx].algoID()) + if (algo == layerClusters.indexes()[lcIdx].algoID()) foundAlgoNumber = true; } - const auto layerClusterSize = hitsAssociations[lcIdx].size(); + const auto layerClusterSize = static_cast(layerClusters.position()[lcIdx].cells()); if (foundAlgoNumber && (layerClusterSize < minClusterSize) || (layerClusterSize > maxClusterSize)) layerClusterMask[lcIdx] = 0.f; - else - layerClusterMask[lcIdx] = 1.f; } } void ClusterFilterByAlgoAndSize::filter(Queue& queue, const reco::CaloClusterDeviceCollection& layerClusters, + ticl::ClusterMaskDevice& layerClusterMask, uint32_t minClusterSize, uint32_t maxClusterSize) { + auto d_algo_number = cms::alpakatools::make_device_buffer(queue, algo_number_.size()); + alpaka::memcpy(queue, d_algo_number, cms::alpakatools::make_host_view(algo_number_.data(), algo_number_.size())); auto blocksize = 1024; - auto gridsize = cms::alpakatools::divide_up_by(layerClusters.metadata().size(), blocksize); + auto gridsize = cms::alpakatools::divide_up_by(layerClusters.view().position().metadata().size(), blocksize); auto workdivision = cms::alpakatools::make_workdiv(gridsize, blocksize); - alpaka::exec( - queue, workdivision, KernelFilterLayerClusterByAlgoAndSize{}, layerClusters.view(), hitsAssociations.view()); + alpaka::exec(queue, + workdivision, + KernelFilterLayerClusterByAlgoAndSize{}, + layerClusters.view(), + std::span{d_algo_number.data(), algo_number_.size()}, + layerClusterMask.view(), + minClusterSize, + maxClusterSize); } } // namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl diff --git a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h index 21c865044335f..6749268b9936d 100644 --- a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h +++ b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h @@ -2,7 +2,9 @@ #pragma once #include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" +#include "DataFormats/TICL/interface/alpaka/AlgoNumberDevice.h" #include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" #include #include @@ -13,17 +15,24 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { template ALPAKA_FN_ACC void operator()(const TAcc& acc, reco::CaloClusterDeviceCollection::ConstView layerClusters, - std::span algoNumber, + std::span algoNumber, ticl::ClusterMaskDevice::View layerClusterMask, uint32_t minClusterSize, uint32_t maxClusterSize) const; }; class ClusterFilterByAlgoAndSize { + public: + ClusterFilterByAlgoAndSize(const edm::ParameterSet& config) + : algo_number_{config.getParameter("algo_number")} {} void filter(Queue& queue, const reco::CaloClusterDeviceCollection& layerClusters, + ticl::ClusterMaskDevice& layerClusterMask, uint32_t minClusterSize, uint32_t maxClusterSize); + + private: + std::vector algo_number_; }; } // namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl diff --git a/RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc b/RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc index 5ba13ee6a6692..0d1b4cafb700c 100644 --- a/RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc +++ b/RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc @@ -27,9 +27,10 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { : EDProducer(config), deviceTokenSoAClusters_{consumes(config.getParameter("layerClusters"))}, clustersMaskToken_{consumes(config.getParameter("layerClustersInputMask"))}, + filteredClustersMaskToken_{produces()}, minClusterSize_{config.getParameter("minClusterSize")}, maxClusterSize_{config.getParameter("maxClusterSize")}, - deviceTokenFilteredSoAClusters_{produces()} {} + algo_(config) {} ~HeterogeneousFilteredLayerClustersProducer() override = default; static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { @@ -45,11 +46,14 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { void produce(device::Event& iEvent, const device::EventSetup& iSetup) override { const auto& layerClusters = iEvent.get(deviceTokenSoAClusters_); - auto& layerClustersMask = iEvent.get(clustersMaskToken_); + const auto& layerClustersMask = iEvent.get(clustersMaskToken_); - ClusterFilterByAlgoAndSize::filter(iEvent.queue(), layerClusters.view(), minClusterSize_, maxClusterSize_); + auto& queue = iEvent.queue(); + ticl::ClusterMaskDevice filteredMask(queue, layerClustersMask.view().metadata().size()); + alpaka::memcpy(queue, filteredMask.buffer(), layerClustersMask.buffer()); + algo_.filter(queue, layerClusters, filteredMask, minClusterSize_, maxClusterSize_); - iEvent.emplace(layerClustersMask, clustersMaskToken_); + iEvent.emplace(filteredClustersMaskToken_, std::move(filteredMask)); } private: @@ -63,4 +67,4 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { ClusterFilterByAlgoAndSize algo_; }; -} // namespace ALPAKA_ACCELERATOR_NAMESPACE +} // namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl From f7693eae973b35ce91f551dd1d1939292f7d2b9d Mon Sep 17 00:00:00 2001 From: Simone Date: Mon, 23 Mar 2026 11:24:23 +0100 Subject: [PATCH 17/24] Save cluster sizes in legacy producer SoA --- RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc index 23cdc02c563f3..d5ddb49b0c4f0 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc @@ -198,6 +198,7 @@ ticl::LayerClustersAndAssociations HGCalCLUEAlgoT::getClusters(bool layer_clusters_view.position().x()[globalClusterIndex] = x; layer_clusters_view.position().y()[globalClusterIndex] = y; layer_clusters_view.position().z()[globalClusterIndex] = z; + layer_clusters_view.position().cells()[globalClusterIndex] = clusters.count(cl); layer_clusters_view.energy().energy()[globalClusterIndex] = energy; layer_clusters_view.energy().correctedEnergy()[globalClusterIndex] = -1.f; layer_clusters_view.energy().correctedEnergyUncertainty()[globalClusterIndex] = -1.f; From 3652f37eb880706ecbeb77fcb0db07ca4da2095b Mon Sep 17 00:00:00 2001 From: Simone Date: Mon, 23 Mar 2026 11:42:34 +0100 Subject: [PATCH 18/24] [TEMPORARY] add association map headers --- DataFormats/TICL/BuildFile.xml | 3 + DataFormats/TICL/interface/AssociationMap.h | 70 ++++++++++++++++ DataFormats/TICL/interface/FillAssociator.h | 22 +++++ .../TICL/interface/detail/FillAssociator.h | 84 +++++++++++++++++++ 4 files changed, 179 insertions(+) create mode 100644 DataFormats/TICL/BuildFile.xml create mode 100644 DataFormats/TICL/interface/AssociationMap.h create mode 100644 DataFormats/TICL/interface/FillAssociator.h create mode 100644 DataFormats/TICL/interface/detail/FillAssociator.h diff --git a/DataFormats/TICL/BuildFile.xml b/DataFormats/TICL/BuildFile.xml new file mode 100644 index 0000000000000..fdf9d63b89a7f --- /dev/null +++ b/DataFormats/TICL/BuildFile.xml @@ -0,0 +1,3 @@ + + + diff --git a/DataFormats/TICL/interface/AssociationMap.h b/DataFormats/TICL/interface/AssociationMap.h new file mode 100644 index 0000000000000..8ffa5d40b1330 --- /dev/null +++ b/DataFormats/TICL/interface/AssociationMap.h @@ -0,0 +1,70 @@ +#ifndef DataFormats_TICL_interface_AssociationMap_h +#define DataFormats_TICL_interface_AssociationMap_h + +#include "DataFormats/SoATemplate/interface/SoALayout.h" +#include "DataFormats/SoATemplate/interface/SoABlocks.h" +#include +#include +#include + +namespace ticl { + + namespace concepts { + + template + concept trivially_copyable = std::is_trivially_copyable_v; + + } + + // clang-format off + template + struct AssociationMapLayout { + GENERATE_SOA_LAYOUT(ContentBuffersLayout, SOA_COLUMN(TMapped, values)) + GENERATE_SOA_LAYOUT(OffsetBufferLayout, SOA_COLUMN(TKey, keys_offsets)) + + GENERATE_SOA_BLOCKS(Layout, + SOA_BLOCK(content, ContentBuffersLayout), + SOA_BLOCK(offsets, OffsetBufferLayout), + SOA_VIEW_METHODS( + constexpr SOA_HOST_DEVICE auto operator[](TKey key) { + auto offset = (key == 0u) ? 0u : this->offsets()[key].keys_offsets(); + auto size = (key == 0u) ? this->offsets()[0].keys_offsets() + : this->offsets()[key].keys_offsets() - this->offsets()[key - 1].keys_offsets(); + return std::span{this->content().values().data() + offset, size}; + } + ), + SOA_CONST_VIEW_METHODS( + constexpr SOA_HOST_DEVICE auto operator[](TKey key) const { + auto offset = (key == 0) ? 0u : this->offsets().keys_offsets()[key]; + auto size = (key == 0u) ? this->offsets()[0].keys_offsets() + : this->offsets()[key].keys_offsets() - this->offsets()[key - 1].keys_offsets(); + return std::span{this->content().values().data() + offset, size}; + } + constexpr SOA_HOST_DEVICE auto contains(TKey key) const { + return this->count(key) > 0; + } + constexpr SOA_HOST_DEVICE auto count(TKey key) const { + return (key == 0u) ? this->offsets()[0].keys_offsets() + : this->offsets()[key].keys_offsets() - this->offsets()[key - 1].keys_offsets(); + } + constexpr SOA_HOST_DEVICE auto keys() const { + return this->offsets().metadata().size(); + } + constexpr SOA_HOST_DEVICE auto size() const { + return this->offsets().metadata().size(); + } + ) + ) + }; + // clang-format on + + template + using AssociationMap = typename AssociationMapLayout::template Layout<>; + template + using AssociationMapView = typename AssociationMap::View; + template + using AssociationMapConstView = typename AssociationMap::ConstView; + +} // namespace ticl + +#endif diff --git a/DataFormats/TICL/interface/FillAssociator.h b/DataFormats/TICL/interface/FillAssociator.h new file mode 100644 index 0000000000000..ae1901113afc3 --- /dev/null +++ b/DataFormats/TICL/interface/FillAssociator.h @@ -0,0 +1,22 @@ +#ifndef DataFormats_TICL_interface_FillAssociator_h +#define DataFormats_TICL_interface_FillAssociator_h + +#include "DataFormats/TICL/interface/AssociationMap.h" +#include "DataFormats/TICL/interface/detail/FillAssociator.h" +#include +#include + +namespace ticl::associator { + + template + requires alpaka::isQueue + ALPAKA_FN_HOST auto fill(TQueue& queue, + ticl::AssociationMapView& map, + std::span keys, + std::span values) { + detail::fill(queue, map, keys, values); + } + +} // namespace ticl::associator + +#endif diff --git a/DataFormats/TICL/interface/detail/FillAssociator.h b/DataFormats/TICL/interface/detail/FillAssociator.h new file mode 100644 index 0000000000000..3e3218668fa1c --- /dev/null +++ b/DataFormats/TICL/interface/detail/FillAssociator.h @@ -0,0 +1,84 @@ +#ifndef DataFormats_TICL_interface_detail_FillAssociator_h +#define DataFormats_TICL_interface_detail_FillAssociator_h + +#include "DataFormats/TICL/interface/AssociationMap.h" +#include "HeterogeneousCore/AlpakaInterface/interface/prefixScan.h" +#include +#include +#include + +namespace ticl::associator::detail { + + struct KernelComputeAssociationSizes { + template + ALPAKA_FN_ACC void operator()(const TAcc& acc, + std::span keys, + TKey* keys_counts, + std::size_t size) const { + for (auto i : alpaka::uniformElements(acc, size)) { + alpaka::atomicAdd(acc, &keys_counts[keys[i]], TKey{1}); + } + } + }; + + struct KernelFillAssociator { + template + ALPAKA_FN_ACC void operator()(const TAcc& acc, + ticl::AssociationMapView view, + std::span keys, + std::span values, + TKey* temp_offsets) const { + for (auto i : alpaka::uniformElements(acc, values.size())) { + const auto key = keys[i]; + const auto offset = alpaka::atomicAdd(acc, &temp_offsets[key], TKey{1}); + view.content().values()[offset] = values[i]; + } + } + }; + + template + requires alpaka::isQueue + ALPAKA_FN_HOST auto fill(TQueue& queue, + ticl::AssociationMapView& map, + std::span keys, + std::span values) { + using namespace ::cms::alpakatools; + + const auto nkeys = map.metadata().size()[1]; + const auto nvalues = map.metadata().size()[0]; + + const auto blocksize = 1024; + const auto gridsize = divide_up_by(keys.size(), blocksize); + const auto workdiv = make_workdiv(gridsize, blocksize); + auto keys_counts = make_device_buffer(queue, nkeys); + alpaka::memset(queue, keys_counts, 0); + alpaka::exec(queue, workdiv, KernelComputeAssociationSizes{}, keys, keys_counts.data(), nvalues); + + // prepare for prefix scan + auto block_counter = make_device_buffer(queue); + alpaka::memset(queue, block_counter, 0); + auto temp_offsets = make_device_buffer(queue, nkeys + 1); + alpaka::memset(queue, temp_offsets, 0); + const auto blocksize_multiblockscan = 1024; + auto gridsize_multiblockscan = divide_up_by(nkeys, blocksize_multiblockscan); + const auto workdiv_multiblockscan = make_workdiv(gridsize_multiblockscan, blocksize_multiblockscan); + auto warp_size = alpaka::getPreferredWarpSize(alpaka::getDev(queue)); + alpaka::exec(queue, + workdiv_multiblockscan, + multiBlockPrefixScan{}, + keys_counts.data(), + temp_offsets.data() + 1, + nkeys, + gridsize_multiblockscan, + block_counter.data(), + warp_size); + + alpaka::memcpy(queue, + make_device_view(queue, map.offsets().keys_offsets().data(), nkeys), + make_device_view(queue, temp_offsets.data() + 1, nkeys)); + alpaka::exec(queue, workdiv, KernelFillAssociator{}, map, keys, values, temp_offsets.data()); + } + +} // namespace ticl::associator::detail + +#endif From b5e6937f66a7f7b03e1b5f7a03db32349c993818 Mon Sep 17 00:00:00 2001 From: Simone Date: Mon, 23 Mar 2026 12:03:46 +0100 Subject: [PATCH 19/24] Add workaround for legacy LC production in barrel --- .../HGCalRecProducers/interface/HGCalClusteringAlgoBase.h | 1 + RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc | 5 +++++ RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h | 1 + .../PFClusterProducer/plugins/BarrelCLUEAlgo.cc | 7 ++++++- .../PFClusterProducer/plugins/BarrelCLUEAlgo.h | 5 ++++- .../plugins/BarrelLayerClusterProducer.cc | 2 +- 6 files changed, 18 insertions(+), 3 deletions(-) diff --git a/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h b/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h index e1e8aa32c24f4..75b9d1932c894 100644 --- a/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h +++ b/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h @@ -64,6 +64,7 @@ class HGCalClusteringAlgoBase { virtual void populate(const reco::PFRecHitCollection &hits) = 0; virtual void makeClusters() = 0; virtual ticl::LayerClustersAndAssociations getClusters(bool) = 0; + virtual std::vector getClustersLegacy(bool) = 0; virtual void reset() = 0; virtual hgcal_clustering::Density getDensity() { return {}; }; // implementation is in some child class virtual void getEventSetupPerAlgorithm(const edm::EventSetup &es) {} // implementation is in some child class diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc index d5ddb49b0c4f0..478699676a968 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc @@ -122,6 +122,11 @@ void HGCalCLUEAlgoT::makeClusters() { #endif } +template +std::vector HGCalCLUEAlgoT::getClustersLegacy(bool) { + return std::vector(1); +} + template ticl::LayerClustersAndAssociations HGCalCLUEAlgoT::getClusters(bool) { std::vector offsets(numberOfClustersPerLayer_.size(), 0); diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h index 66a4756032d75..ed43ce89bb0fd 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h @@ -76,6 +76,7 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { void makeClusters() override; // this is the method to get the cluster collection out + std::vector getClustersLegacy(bool) override; ticl::LayerClustersAndAssociations getClusters(bool) override; void reset() override { diff --git a/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.cc b/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.cc index 4d56d9d30f80f..581415db2f679 100644 --- a/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.cc +++ b/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.cc @@ -98,7 +98,12 @@ void BarrelCLUEAlgoT::makeClusters() { } template -std::vector BarrelCLUEAlgoT::getClusters(bool) { +ticl::LayerClustersAndAssociations BarrelCLUEAlgoT::getClusters(bool) { + return ticl::LayerClustersAndAssociations(1, 1); +} + +template +std::vector BarrelCLUEAlgoT::getClustersLegacy(bool) { std::vector offsets(numberOfClustersPerLayer_.size(), 0); int maxClustersOnLayer = numberOfClustersPerLayer_[0]; diff --git a/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.h b/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.h index 58d91130a012a..7a27fb9d7402f 100644 --- a/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.h +++ b/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.h @@ -17,6 +17,7 @@ #include "DataFormats/Math/interface/deltaPhi.h" #include "RecoLocalCalo/HGCalRecProducers/interface/HGCalLayerTiles.h" +#include "RecoLocalCalo/HGCalRecProducers/interface/LayerClusterAndAssociations.h" #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" @@ -25,6 +26,7 @@ #include "CondFormats/DataRecord/interface/HcalPFCutsRcd.h" #include "CondFormats/HcalObjects/interface/HcalPFCuts.h" + // C/C++ headers #include #include @@ -59,7 +61,8 @@ class BarrelCLUEAlgoT : public HGCalClusteringAlgoBase { void makeClusters() override; // this is the method to get the cluster collection out - std::vector getClusters(bool) override; + ticl::LayerClustersAndAssociations getClusters(bool) override; + std::vector getClustersLegacy(bool) override; void reset() override { clusters_v_.clear(); diff --git a/RecoParticleFlow/PFClusterProducer/plugins/BarrelLayerClusterProducer.cc b/RecoParticleFlow/PFClusterProducer/plugins/BarrelLayerClusterProducer.cc index 4f7267a870a25..c3d205ee5cfa7 100644 --- a/RecoParticleFlow/PFClusterProducer/plugins/BarrelLayerClusterProducer.cc +++ b/RecoParticleFlow/PFClusterProducer/plugins/BarrelLayerClusterProducer.cc @@ -129,7 +129,7 @@ void BarrelLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& algo_->makeClusters(); std::unique_ptr> clusters(new std::vector); - *clusters = algo_->getClusters(false); + *clusters = algo_->getClustersLegacy(false); auto clusterHandle = evt.put(std::move(clusters)); edm::PtrVector clusterPtrs; //, clusterPtrsSharing; From c1e4879179330cae531f7ace1355941ab0bb7781 Mon Sep 17 00:00:00 2001 From: Simone Date: Mon, 23 Mar 2026 13:57:30 +0100 Subject: [PATCH 20/24] Test classes def fix --- DataFormats/TICL/src/classes_def.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/DataFormats/TICL/src/classes_def.xml b/DataFormats/TICL/src/classes_def.xml index 3fcc2c578bb54..4ba85a3f09e6d 100644 --- a/DataFormats/TICL/src/classes_def.xml +++ b/DataFormats/TICL/src/classes_def.xml @@ -2,5 +2,6 @@ + From 9f87ddd2f438cde299c93e3eb9b43ba43e866aa1 Mon Sep 17 00:00:00 2001 From: Simone Date: Mon, 23 Mar 2026 14:25:54 +0100 Subject: [PATCH 21/24] [TEMPORARY] unlock view methods and fix in associator --- DataFormats/SoATemplate/interface/SoABlocks.h | 2 ++ DataFormats/TICL/interface/AssociationMap.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/DataFormats/SoATemplate/interface/SoABlocks.h b/DataFormats/SoATemplate/interface/SoABlocks.h index 2553cc0b6dd90..814e1e10f044d 100644 --- a/DataFormats/SoATemplate/interface/SoABlocks.h +++ b/DataFormats/SoATemplate/interface/SoABlocks.h @@ -398,6 +398,7 @@ \ /* Accessors for the const views for each block */ \ _ITERATE_ON_ALL(_DECLARE_ACCESSORS_CONST_VIEW_BLOCKS, ~, __VA_ARGS__) \ + ENUM_IF_VALID(_ITERATE_ON_ALL(GENERATE_CONST_VIEW_METHODS, ~, __VA_ARGS__)) \ \ private: \ _ITERATE_ON_ALL(_DECLARE_MEMBERS_CONST_VIEW_BLOCKS, ~, __VA_ARGS__) \ @@ -480,6 +481,7 @@ \ /* Accessors for the views for each block */ \ _ITERATE_ON_ALL(_DECLARE_ACCESSORS_VIEW_BLOCKS, ~, __VA_ARGS__) \ + ENUM_IF_VALID(_ITERATE_ON_ALL(GENERATE_VIEW_METHODS, ~, __VA_ARGS__)) \ \ /* Data members inherited from the ConstView */ \ }; \ diff --git a/DataFormats/TICL/interface/AssociationMap.h b/DataFormats/TICL/interface/AssociationMap.h index 8ffa5d40b1330..6ef9c287107c8 100644 --- a/DataFormats/TICL/interface/AssociationMap.h +++ b/DataFormats/TICL/interface/AssociationMap.h @@ -30,7 +30,7 @@ namespace ticl { auto offset = (key == 0u) ? 0u : this->offsets()[key].keys_offsets(); auto size = (key == 0u) ? this->offsets()[0].keys_offsets() : this->offsets()[key].keys_offsets() - this->offsets()[key - 1].keys_offsets(); - return std::span{this->content().values().data() + offset, size}; + return std::span{this->content().values().data() + offset, static_cast(size)}; } ), SOA_CONST_VIEW_METHODS( @@ -38,7 +38,7 @@ namespace ticl { auto offset = (key == 0) ? 0u : this->offsets().keys_offsets()[key]; auto size = (key == 0u) ? this->offsets()[0].keys_offsets() : this->offsets()[key].keys_offsets() - this->offsets()[key - 1].keys_offsets(); - return std::span{this->content().values().data() + offset, size}; + return std::span{this->content().values().data() + offset, static_cast(size)}; } constexpr SOA_HOST_DEVICE auto contains(TKey key) const { return this->count(key) > 0; From 12e9c7e4bd45503321f00169853713213cdcaade Mon Sep 17 00:00:00 2001 From: Simone Date: Mon, 23 Mar 2026 14:26:20 +0100 Subject: [PATCH 22/24] Compute LC timing in legacy producer --- DataFormats/CaloRecHit/BuildFile.xml | 4 - .../CaloRecHit/src/alpaka/classes_cuda.h | 4 - .../src/alpaka/classes_cuda_def.xml | 5 - .../CaloRecHit/src/alpaka/classes_rocm.h | 4 - .../src/alpaka/classes_rocm_def.xml | 5 - DataFormats/CaloRecHit/src/classes.h | 2 - DataFormats/CaloRecHit/src/classes_def.xml | 3 - DataFormats/TICL/BuildFile.xml | 14 +- DataFormats/TICL/interface/AssociationMap.h | 10 +- .../interface/CaloClusterHostCollection.h | 2 +- .../interface/CaloClusterSoA.h | 0 DataFormats/TICL/interface/FillAssociator.h | 2 +- DataFormats/TICL/interface/HitAndFraction.h | 10 +- .../TICL/interface/HitsAndFractionsHost.h | 5 +- .../alpaka/CaloClusterDeviceCollection.h | 2 +- .../interface/alpaka/HitsAndFractionsDevice.h | 2 +- .../TICL/interface/detail/FillAssociator.h | 4 +- DataFormats/TICL/src/alpaka/classes_cuda.h | 2 + .../TICL/src/alpaka/classes_cuda_def.xml | 4 + DataFormats/TICL/src/alpaka/classes_rocm.h | 2 + .../TICL/src/alpaka/classes_rocm_def.xml | 4 + DataFormats/TICL/src/classes.h | 4 + DataFormats/TICL/src/classes_def.xml | 12 +- .../AssociationMapFlatTableProducer.h | 6 +- .../alpaka/PatternRecognitionAlgoBase.h | 1 - RecoHGCal/TICL/plugins/BuildFile.xml | 8 -- .../alpaka/ClusterFilterByAlgoAndSize.dev.cc | 3 +- .../alpaka/ClusterFilterByAlgoAndSize.h | 3 +- .../alpaka/FilteredLayerClustersProducer.cc | 2 +- .../alpaka/PatternRecognitionByCLUEstering.h | 3 +- .../alpaka/PatternRecognitionPluginFactory.h | 8 +- .../interface/HGCalClusteringAlgoBase.h | 2 +- .../interface/LayerClusterAndAssociations.h | 2 +- .../HGCalRecProducers/plugins/BuildFile.xml | 2 +- .../plugins/HGCalCLUEAlgo.cc | 2 +- .../HGCalRecProducers/plugins/HGCalCLUEAlgo.h | 2 +- .../plugins/HGCalLayerClusterProducer.cc | 124 +++++------------- .../HGCalLayerClustersSoAAlgoWrapper.dev.cc | 8 +- .../alpaka/HGCalLayerClustersSoAAlgoWrapper.h | 2 +- .../alpaka/HGCalSoALayerClustersProducer.cc | 2 +- .../alpaka/LayerClusterMergingAlgo.dev.cc | 6 +- .../plugins/alpaka/LayerClusterMergingAlgo.h | 2 +- .../alpaka/MergedLayerClusterProducer.cc | 4 +- .../plugins/BarrelCLUEAlgo.cc | 2 +- .../plugins/BarrelCLUEAlgo.h | 1 - 45 files changed, 117 insertions(+), 184 deletions(-) delete mode 100644 DataFormats/CaloRecHit/src/alpaka/classes_cuda.h delete mode 100644 DataFormats/CaloRecHit/src/alpaka/classes_cuda_def.xml delete mode 100644 DataFormats/CaloRecHit/src/alpaka/classes_rocm.h delete mode 100644 DataFormats/CaloRecHit/src/alpaka/classes_rocm_def.xml rename DataFormats/{CaloRecHit => TICL}/interface/CaloClusterHostCollection.h (78%) rename DataFormats/{CaloRecHit => TICL}/interface/CaloClusterSoA.h (100%) rename DataFormats/{CaloRecHit => TICL}/interface/alpaka/CaloClusterDeviceCollection.h (82%) diff --git a/DataFormats/CaloRecHit/BuildFile.xml b/DataFormats/CaloRecHit/BuildFile.xml index ded3498780221..135aabf10cd07 100644 --- a/DataFormats/CaloRecHit/BuildFile.xml +++ b/DataFormats/CaloRecHit/BuildFile.xml @@ -4,10 +4,6 @@ - - - - diff --git a/DataFormats/CaloRecHit/src/alpaka/classes_cuda.h b/DataFormats/CaloRecHit/src/alpaka/classes_cuda.h deleted file mode 100644 index 5594d8aabd1af..0000000000000 --- a/DataFormats/CaloRecHit/src/alpaka/classes_cuda.h +++ /dev/null @@ -1,4 +0,0 @@ -#include "DataFormats/Common/interface/DeviceProduct.h" -#include "DataFormats/Common/interface/Wrapper.h" -#include "DataFormats/CaloRecHit/interface/CaloClusterSoA.h" -#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" diff --git a/DataFormats/CaloRecHit/src/alpaka/classes_cuda_def.xml b/DataFormats/CaloRecHit/src/alpaka/classes_cuda_def.xml deleted file mode 100644 index 5d5dba63ce18c..0000000000000 --- a/DataFormats/CaloRecHit/src/alpaka/classes_cuda_def.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/DataFormats/CaloRecHit/src/alpaka/classes_rocm.h b/DataFormats/CaloRecHit/src/alpaka/classes_rocm.h deleted file mode 100644 index 5594d8aabd1af..0000000000000 --- a/DataFormats/CaloRecHit/src/alpaka/classes_rocm.h +++ /dev/null @@ -1,4 +0,0 @@ -#include "DataFormats/Common/interface/DeviceProduct.h" -#include "DataFormats/Common/interface/Wrapper.h" -#include "DataFormats/CaloRecHit/interface/CaloClusterSoA.h" -#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" diff --git a/DataFormats/CaloRecHit/src/alpaka/classes_rocm_def.xml b/DataFormats/CaloRecHit/src/alpaka/classes_rocm_def.xml deleted file mode 100644 index e00ae6dc1a263..0000000000000 --- a/DataFormats/CaloRecHit/src/alpaka/classes_rocm_def.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/DataFormats/CaloRecHit/src/classes.h b/DataFormats/CaloRecHit/src/classes.h index 7cb08d18f2403..1bd0a0724b72c 100644 --- a/DataFormats/CaloRecHit/src/classes.h +++ b/DataFormats/CaloRecHit/src/classes.h @@ -6,5 +6,3 @@ #include "DataFormats/CaloRecHit/interface/CaloCluster.h" #include "DataFormats/CaloRecHit/interface/CaloClusterFwd.h" #include "DataFormats/CaloRecHit/interface/CaloClusterCollection.h" -#include "DataFormats/CaloRecHit/interface/CaloClusterSoA.h" -#include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" diff --git a/DataFormats/CaloRecHit/src/classes_def.xml b/DataFormats/CaloRecHit/src/classes_def.xml index cfbdfd4587fa9..fa250a91eb62d 100644 --- a/DataFormats/CaloRecHit/src/classes_def.xml +++ b/DataFormats/CaloRecHit/src/classes_def.xml @@ -31,7 +31,4 @@ - - - diff --git a/DataFormats/TICL/BuildFile.xml b/DataFormats/TICL/BuildFile.xml index fdf9d63b89a7f..c7e936c3acbfb 100644 --- a/DataFormats/TICL/BuildFile.xml +++ b/DataFormats/TICL/BuildFile.xml @@ -1,3 +1,13 @@ - - + + + + + + + + + + + + diff --git a/DataFormats/TICL/interface/AssociationMap.h b/DataFormats/TICL/interface/AssociationMap.h index 6ef9c287107c8..0548e587e6d2c 100644 --- a/DataFormats/TICL/interface/AssociationMap.h +++ b/DataFormats/TICL/interface/AssociationMap.h @@ -17,7 +17,7 @@ namespace ticl { } // clang-format off - template + template struct AssociationMapLayout { GENERATE_SOA_LAYOUT(ContentBuffersLayout, SOA_COLUMN(TMapped, values)) GENERATE_SOA_LAYOUT(OffsetBufferLayout, SOA_COLUMN(TKey, keys_offsets)) @@ -28,7 +28,7 @@ namespace ticl { SOA_VIEW_METHODS( constexpr SOA_HOST_DEVICE auto operator[](TKey key) { auto offset = (key == 0u) ? 0u : this->offsets()[key].keys_offsets(); - auto size = (key == 0u) ? this->offsets()[0].keys_offsets() + auto size = (key == 0u) ? this->offsets()[0].keys_offsets() : this->offsets()[key].keys_offsets() - this->offsets()[key - 1].keys_offsets(); return std::span{this->content().values().data() + offset, static_cast(size)}; } @@ -59,11 +59,11 @@ namespace ticl { // clang-format on template - using AssociationMap = typename AssociationMapLayout::template Layout<>; + using TICLAssociationMap = typename AssociationMapLayout::template Layout<>; template - using AssociationMapView = typename AssociationMap::View; + using TICLAssociationMapView = typename TICLAssociationMap::View; template - using AssociationMapConstView = typename AssociationMap::ConstView; + using TICLAssociationMapConstView = typename TICLAssociationMap::ConstView; } // namespace ticl diff --git a/DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h b/DataFormats/TICL/interface/CaloClusterHostCollection.h similarity index 78% rename from DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h rename to DataFormats/TICL/interface/CaloClusterHostCollection.h index b6dfb967b848e..3c1d6de51eda0 100644 --- a/DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h +++ b/DataFormats/TICL/interface/CaloClusterHostCollection.h @@ -1,7 +1,7 @@ #pragma once -#include "DataFormats/CaloRecHit/interface/CaloClusterSoA.h" +#include "DataFormats/TICL/interface/CaloClusterSoA.h" #include "DataFormats/Portable/interface/PortableHostCollection.h" #include diff --git a/DataFormats/CaloRecHit/interface/CaloClusterSoA.h b/DataFormats/TICL/interface/CaloClusterSoA.h similarity index 100% rename from DataFormats/CaloRecHit/interface/CaloClusterSoA.h rename to DataFormats/TICL/interface/CaloClusterSoA.h diff --git a/DataFormats/TICL/interface/FillAssociator.h b/DataFormats/TICL/interface/FillAssociator.h index ae1901113afc3..fa7399b2d9cb3 100644 --- a/DataFormats/TICL/interface/FillAssociator.h +++ b/DataFormats/TICL/interface/FillAssociator.h @@ -11,7 +11,7 @@ namespace ticl::associator { template requires alpaka::isQueue ALPAKA_FN_HOST auto fill(TQueue& queue, - ticl::AssociationMapView& map, + ticl::TICLAssociationMapView& map, std::span keys, std::span values) { detail::fill(queue, map, keys, values); diff --git a/DataFormats/TICL/interface/HitAndFraction.h b/DataFormats/TICL/interface/HitAndFraction.h index b2a5566c816f9..26fc049c274ed 100644 --- a/DataFormats/TICL/interface/HitAndFraction.h +++ b/DataFormats/TICL/interface/HitAndFraction.h @@ -5,9 +5,9 @@ namespace ticl { -struct HitAndFraction { - DetId hit; - float fraction; -}; + struct HitAndFraction { + DetId hit; + float fraction; + }; -} // namespace ticl +} // namespace ticl diff --git a/DataFormats/TICL/interface/HitsAndFractionsHost.h b/DataFormats/TICL/interface/HitsAndFractionsHost.h index f87ea5b72f980..7966e094b1b5f 100644 --- a/DataFormats/TICL/interface/HitsAndFractionsHost.h +++ b/DataFormats/TICL/interface/HitsAndFractionsHost.h @@ -7,6 +7,7 @@ namespace ticl { - using HitsAndFractionsHost = PortableHostCollection>; + using TICLAssociationMap_t = AssociationMapLayout::Layout<128, false>; + using HitsAndFractionsHost = PortableHostCollection; -} +} // namespace ticl diff --git a/DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h b/DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h similarity index 82% rename from DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h rename to DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h index a0e5ce9a77ab6..41cf36472196b 100644 --- a/DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h +++ b/DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h @@ -2,7 +2,7 @@ #pragma once #include "DataFormats/Portable/interface/alpaka/PortableCollection.h" -#include "DataFormats/CaloRecHit/interface/CaloClusterSoA.h" +#include "DataFormats/TICL/interface/CaloClusterSoA.h" #include namespace ALPAKA_ACCELERATOR_NAMESPACE::reco { diff --git a/DataFormats/TICL/interface/alpaka/HitsAndFractionsDevice.h b/DataFormats/TICL/interface/alpaka/HitsAndFractionsDevice.h index e2dc525fc321a..65ba946b912b0 100644 --- a/DataFormats/TICL/interface/alpaka/HitsAndFractionsDevice.h +++ b/DataFormats/TICL/interface/alpaka/HitsAndFractionsDevice.h @@ -7,6 +7,6 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { - using HitsAndFractionsDevice = PortableCollection>; + using HitsAndFractionsDevice = PortableCollection>; } diff --git a/DataFormats/TICL/interface/detail/FillAssociator.h b/DataFormats/TICL/interface/detail/FillAssociator.h index 3e3218668fa1c..8c1ee1e2f5401 100644 --- a/DataFormats/TICL/interface/detail/FillAssociator.h +++ b/DataFormats/TICL/interface/detail/FillAssociator.h @@ -24,7 +24,7 @@ namespace ticl::associator::detail { struct KernelFillAssociator { template ALPAKA_FN_ACC void operator()(const TAcc& acc, - ticl::AssociationMapView view, + ticl::TICLAssociationMapView view, std::span keys, std::span values, TKey* temp_offsets) const { @@ -39,7 +39,7 @@ namespace ticl::associator::detail { template requires alpaka::isQueue ALPAKA_FN_HOST auto fill(TQueue& queue, - ticl::AssociationMapView& map, + ticl::TICLAssociationMapView& map, std::span keys, std::span values) { using namespace ::cms::alpakatools; diff --git a/DataFormats/TICL/src/alpaka/classes_cuda.h b/DataFormats/TICL/src/alpaka/classes_cuda.h index 38485b8a91fe3..fcaec167d9c23 100644 --- a/DataFormats/TICL/src/alpaka/classes_cuda.h +++ b/DataFormats/TICL/src/alpaka/classes_cuda.h @@ -1,5 +1,7 @@ #include "DataFormats/Common/interface/DeviceProduct.h" #include "DataFormats/Common/interface/Wrapper.h" +#include "DataFormats/TICL/interface/CaloClusterSoA.h" +#include "DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h" #include "DataFormats/TICL/interface/ClusterMask.h" #include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h" #include "DataFormats/TICL/interface/AssociationMap.h" diff --git a/DataFormats/TICL/src/alpaka/classes_cuda_def.xml b/DataFormats/TICL/src/alpaka/classes_cuda_def.xml index fb2a13f67c75c..d01b41ab9ee97 100644 --- a/DataFormats/TICL/src/alpaka/classes_cuda_def.xml +++ b/DataFormats/TICL/src/alpaka/classes_cuda_def.xml @@ -1,4 +1,8 @@ + + + + diff --git a/DataFormats/TICL/src/alpaka/classes_rocm.h b/DataFormats/TICL/src/alpaka/classes_rocm.h index 38485b8a91fe3..fcaec167d9c23 100644 --- a/DataFormats/TICL/src/alpaka/classes_rocm.h +++ b/DataFormats/TICL/src/alpaka/classes_rocm.h @@ -1,5 +1,7 @@ #include "DataFormats/Common/interface/DeviceProduct.h" #include "DataFormats/Common/interface/Wrapper.h" +#include "DataFormats/TICL/interface/CaloClusterSoA.h" +#include "DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h" #include "DataFormats/TICL/interface/ClusterMask.h" #include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h" #include "DataFormats/TICL/interface/AssociationMap.h" diff --git a/DataFormats/TICL/src/alpaka/classes_rocm_def.xml b/DataFormats/TICL/src/alpaka/classes_rocm_def.xml index cbf41600f1921..66fa2538fc249 100644 --- a/DataFormats/TICL/src/alpaka/classes_rocm_def.xml +++ b/DataFormats/TICL/src/alpaka/classes_rocm_def.xml @@ -1,4 +1,8 @@ + + + + diff --git a/DataFormats/TICL/src/classes.h b/DataFormats/TICL/src/classes.h index 1ccf4d918d8bd..fa9c19c9f042b 100644 --- a/DataFormats/TICL/src/classes.h +++ b/DataFormats/TICL/src/classes.h @@ -1,4 +1,8 @@ +#include "DataFormats/Common/interface/Wrapper.h" #include "DataFormats/TICL/interface/ClusterMask.h" #include "DataFormats/TICL/interface/ClusterMaskHost.h" +#include "DataFormats/TICL/interface/HitAndFraction.h" #include "DataFormats/TICL/interface/AssociationMap.h" #include "DataFormats/TICL/interface/HitsAndFractionsHost.h" +#include "DataFormats/TICL/interface/CaloClusterSoA.h" +#include "DataFormats/TICL/interface/CaloClusterHostCollection.h" diff --git a/DataFormats/TICL/src/classes_def.xml b/DataFormats/TICL/src/classes_def.xml index 4ba85a3f09e6d..81af7c6616927 100644 --- a/DataFormats/TICL/src/classes_def.xml +++ b/DataFormats/TICL/src/classes_def.xml @@ -1,7 +1,17 @@ + + + + - + + + + + + + diff --git a/PhysicsTools/NanoAOD/interface/AssociationMapFlatTableProducer.h b/PhysicsTools/NanoAOD/interface/AssociationMapFlatTableProducer.h index 5558c017cfd11..502dab2d73b15 100644 --- a/PhysicsTools/NanoAOD/interface/AssociationMapFlatTableProducer.h +++ b/PhysicsTools/NanoAOD/interface/AssociationMapFlatTableProducer.h @@ -1,12 +1,12 @@ -#ifndef HLTrigger_HLTUpgradeNano_AssociationMapFlatTable_h -#define HLTrigger_HLTUpgradeNano_AssociationMapFlatTable_h +#ifndef HLTrigger_HLTUpgradeNano_TICLAssociationMapFlatTable_h +#define HLTrigger_HLTUpgradeNano_TICLAssociationMapFlatTable_h #include #include "PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h" #include "SimDataFormats/Associations/interface/TICLAssociationMap.h" -// Concept to check if a type is a valid AssociationMap of AssociationElement, both oneToOne and oneToMany. +// Concept to check if a type is a valid TICLAssociationMap of AssociationElement, both oneToOne and oneToMany. // For oneToOne pass as Container the type std::vector // For oneToMany pass as Container the type std::vector> template diff --git a/RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h b/RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h index 324d2163ee830..4c465e5694984 100644 --- a/RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h +++ b/RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h @@ -14,7 +14,6 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { class PatternRecognitionAlgoBase { protected: - public: PatternRecognitionAlgoBase(const edm::ParameterSet& conf) {} virtual ~PatternRecognitionAlgoBase() = default; diff --git a/RecoHGCal/TICL/plugins/BuildFile.xml b/RecoHGCal/TICL/plugins/BuildFile.xml index cc98e4a73ee8f..52421c137f629 100644 --- a/RecoHGCal/TICL/plugins/BuildFile.xml +++ b/RecoHGCal/TICL/plugins/BuildFile.xml @@ -42,20 +42,12 @@ - - - - - - - - diff --git a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc index 9fd7401c98acf..5dc47a20b8b93 100644 --- a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc +++ b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc @@ -1,6 +1,5 @@ -#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" -#include "DataFormats/TICL/interface/alpaka/AlgoNumberDevice.h" +#include "DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h" #include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h" #include "HeterogeneousCore/AlpakaInterface/interface/workdivision.h" #include "HeterogeneousCore/AlpakaInterface/interface/memory.h" diff --git a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h index 6749268b9936d..a2bc7d5321eb6 100644 --- a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h +++ b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h @@ -1,8 +1,7 @@ #pragma once -#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" -#include "DataFormats/TICL/interface/alpaka/AlgoNumberDevice.h" +#include "DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h" #include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" diff --git a/RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc b/RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc index 0d1b4cafb700c..a2e4f33c7ccd5 100644 --- a/RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc +++ b/RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc @@ -1,6 +1,6 @@ #include #include "HeterogeneousCore/AlpakaInterface/interface/config.h" -#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" +#include "DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h" #include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h" #include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h index a6edb1857c3f1..b3e8f2876ac67 100644 --- a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h +++ b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h @@ -30,8 +30,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { : PatternRecognitionAlgoBase(config), m_rhoc(config.getParameter("rho_c")), m_dc(config.getParameter("dc")), - m_dm(config.getParameter("dm")) { - } + m_dm(config.getParameter("dm")) {} ~PatternRecognitionByCLUEstering() override = default; void makeTracksters(Queue& queue, diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h index a153c0e82eaea..5551b9d6aee67 100644 --- a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h +++ b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h @@ -8,9 +8,9 @@ #include "RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h" #include "RecoHGCal/TICL/interface/GlobalCache.h" - using PatternRecognitionFactoryAlpaka = - ::edmplugin::PluginFactory; - // using PatternRecognitionHFNoseFactoryAlpaka = - // edmplugin::PluginFactory; +using PatternRecognitionFactoryAlpaka = + ::edmplugin::PluginFactory; +// using PatternRecognitionHFNoseFactoryAlpaka = +// edmplugin::PluginFactory; #endif diff --git a/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h b/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h index 75b9d1932c894..b276d5adffcd5 100644 --- a/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h +++ b/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h @@ -4,7 +4,7 @@ #include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/Framework/interface/EventSetup.h" -#include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" +#include "DataFormats/TICL/interface/CaloClusterHostCollection.h" #include "DataFormats/EgammaReco/interface/BasicCluster.h" #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" #include "DataFormats/Math/interface/Point3D.h" diff --git a/RecoLocalCalo/HGCalRecProducers/interface/LayerClusterAndAssociations.h b/RecoLocalCalo/HGCalRecProducers/interface/LayerClusterAndAssociations.h index cdea7b2740cd0..a5b6a15fe4a75 100644 --- a/RecoLocalCalo/HGCalRecProducers/interface/LayerClusterAndAssociations.h +++ b/RecoLocalCalo/HGCalRecProducers/interface/LayerClusterAndAssociations.h @@ -1,7 +1,7 @@ #pragma once -#include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" +#include "DataFormats/TICL/interface/CaloClusterHostCollection.h" #include "DataFormats/TICL/interface/HitsAndFractionsHost.h" #include diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/BuildFile.xml b/RecoLocalCalo/HGCalRecProducers/plugins/BuildFile.xml index c41b624c89797..842ee5cdde378 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/BuildFile.xml +++ b/RecoLocalCalo/HGCalRecProducers/plugins/BuildFile.xml @@ -34,7 +34,7 @@ - + diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc index 478699676a968..e61a923e867fc 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc @@ -1,7 +1,7 @@ #include "RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h" // Geometry -#include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" +#include "DataFormats/TICL/interface/CaloClusterHostCollection.h" #include "DataFormats/HcalDetId/interface/HcalSubdetector.h" #include "DataFormats/TICL/interface/AssociationMap.h" #include "DataFormats/TICL/interface/FillAssociator.h" diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h index ed43ce89bb0fd..9a378f70cd813 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h @@ -5,7 +5,7 @@ #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" -#include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" +#include "DataFormats/TICL/interface/CaloClusterHostCollection.h" #include "DataFormats/DetId/interface/DetId.h" #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" #include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h" diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc index 0559e745825a8..c1a77364ddd3c 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc @@ -34,7 +34,7 @@ #include "DataFormats/ParticleFlowReco/interface/PFCluster.h" #include "DataFormats/Common/interface/ValueMap.h" -#include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" +#include "DataFormats/TICL/interface/CaloClusterHostCollection.h" #include "DataFormats/TICL/interface/AssociationMap.h" #if DEBUG_CLUSTERS_ALPAKA @@ -93,16 +93,6 @@ class HGCalLayerClusterProducer : public edm::stream::EDProducer<> { */ void setAlgoId(); - /** - * @brief Counts position for all points in the cluster - * - * @param[in] hitmap hitmap to find correct RecHit - * @param[in] hitsAndFraction all hits in the cluster - * @return counted position - */ - math::XYZPoint calculatePosition(std::unordered_map& hitmap, - const std::vector>& hitsAndFractions); - /** * @brief Counts time for all points in the cluster * @@ -110,9 +100,9 @@ class HGCalLayerClusterProducer : public edm::stream::EDProducer<> { * @param[in] hitsAndFraction all hits in the cluster * @return counted time */ - std::pair calculateTime(std::unordered_map& hitmap, - const std::vector>& hitsAndFractions, - size_t sizeCluster); + void calculateTime(std::unordered_map& hitmap, + reco::CaloClusterHostCollection::View layerClusters, + ticl::HitsAndFractionsHost::ConstView hitsAndFractions); }; HGCalLayerClusterProducer::HGCalLayerClusterProducer(const edm::ParameterSet& ps) @@ -161,86 +151,34 @@ void HGCalLayerClusterProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions.add("hgcalLayerClusters", desc); } -math::XYZPoint HGCalLayerClusterProducer::calculatePosition( - std::unordered_map& hitmap, - const std::vector>& hitsAndFractions) { - float total_weight = 0.f; - float maxEnergyValue = 0.f; - DetId maxEnergyIndex; - float x = 0.f; - float y = 0.f; - - for (auto const& hit : hitsAndFractions) { - //time is computed wrt 0-25ns + offset and set to -1 if no time - const HGCRecHit* rechit = hitmap[hit.first]; - total_weight += rechit->energy(); - if (rechit->energy() > maxEnergyValue) { - maxEnergyValue = rechit->energy(); - maxEnergyIndex = rechit->detid(); - } - } - float total_weight_log = 0.f; - auto thick = rhtools_.getSiThickIndex(maxEnergyIndex); - const GlobalPoint positionMaxEnergy(rhtools_.getPosition(maxEnergyIndex)); - for (auto const& hit : hitsAndFractions) { - //time is computed wrt 0-25ns + offset and set to -1 if no time - const HGCRecHit* rechit = hitmap[hit.first]; - - const GlobalPoint position(rhtools_.getPosition(rechit->detid())); - - if (thick != -1) { //silicon - //for silicon only just use 1+6 cells = 1.3cm for all thicknesses - const float d1 = position.x() - positionMaxEnergy.x(); - const float d2 = position.y() - positionMaxEnergy.y(); - if ((d1 * d1 + d2 * d2) > positionDeltaRho2_) - continue; - - float Wi = std::max(thresholdW0_[thick] + std::log(rechit->energy() / total_weight), 0.); - x += position.x() * Wi; - y += position.y() * Wi; - total_weight_log += Wi; - } else { //scintillator - x += position.x() * rechit->energy(); - y += position.y() * rechit->energy(); +void HGCalLayerClusterProducer::calculateTime(std::unordered_map& hitmap, + reco::CaloClusterHostCollection::View layerClusters, + ticl::HitsAndFractionsHost::ConstView hitsAndFractions) { + for (auto cluster = 0; cluster < hitsAndFractions.keys(); ++cluster) { + std::pair timeCl(-99., -1.); + + if (hitsAndFractions.count(cluster) >= static_cast(hitsTime_)) { + std::vector timeClhits; + std::vector timeErrorClhits; + + for (auto const& hitAndFraction : hitsAndFractions[cluster]) { + //time is computed wrt 0-25ns + offset and set to -1 if no time + const HGCRecHit* rechit = hitmap[hitAndFraction.hit]; + + float rhTimeE = rechit->timeError(); + //check on timeError to exclude scintillator + if (rhTimeE < 0.f) + continue; + timeClhits.push_back(rechit->time()); + timeErrorClhits.push_back(1.f / (rhTimeE * rhTimeE)); + } + hgcalsimclustertime::ComputeClusterTime timeEstimator; + timeCl = timeEstimator.fixSizeHighestDensity(timeClhits, timeErrorClhits, hitsTime_); } - } - if (thick != -1) { - total_weight = total_weight_log; - } - if (total_weight != 0.) { - float inv_tot_weight = 1.f / total_weight; - return math::XYZPoint(x * inv_tot_weight, y * inv_tot_weight, positionMaxEnergy.z()); - } else { - return {positionMaxEnergy.x(), positionMaxEnergy.y(), positionMaxEnergy.z()}; + layerClusters.timing()[cluster].time() = timeCl.first; + layerClusters.timing()[cluster].timeError() = timeCl.second; } } - -std::pair HGCalLayerClusterProducer::calculateTime( - std::unordered_map& hitmap, - const std::vector>& hitsAndFractions, - size_t sizeCluster) { - std::pair timeCl(-99., -1.); - - if (sizeCluster >= hitsTime_) { - std::vector timeClhits; - std::vector timeErrorClhits; - - for (auto const& hit : hitsAndFractions) { - //time is computed wrt 0-25ns + offset and set to -1 if no time - const HGCRecHit* rechit = hitmap[hit.first]; - - float rhTimeE = rechit->timeError(); - //check on timeError to exclude scintillator - if (rhTimeE < 0.f) - continue; - timeClhits.push_back(rechit->time()); - timeErrorClhits.push_back(1.f / (rhTimeE * rhTimeE)); - } - hgcalsimclustertime::ComputeClusterTime timeEstimator; - timeCl = timeEstimator.fixSizeHighestDensity(timeClhits, timeErrorClhits, hitsTime_); - } - return timeCl; -} void HGCalLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& es) { edm::Handle hits; @@ -268,11 +206,9 @@ void HGCalLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& std::vector> times; times.reserve(clusters->view().position().metadata().size()); + calculateTime(hitmap, clusters->view(), hits_and_fractions->view()); // for (unsigned i = 0; i < legacy_clusters->size(); ++i) { // reco::CaloCluster& sCl = (*legacy_clusters)[i]; - // if (!calculatePositionInAlgo_) { - // sCl.setPosition(calculatePosition(hitmap, sCl.hitsAndFractions())); - // } // if (detector_ != "BH") { // times.push_back(calculateTime(hitmap, sCl.hitsAndFractions(), sCl.size())); // } else { diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.dev.cc b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.dev.cc index ca0563c23d0c5..faffe8e3b41c9 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.dev.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.dev.cc @@ -76,8 +76,8 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { clusterEnergy = (clusterSeed == kInvalidIndex) ? 0.f : input_rechits_soa[clusterSeed].energy(); } } // CAS - } // uniform_elements - } // operator() + } // uniform_elements + } // operator() }; // Real Kernel position @@ -114,7 +114,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { alpaka::atomicAdd(acc, &outputs.position()[cluster_index].y(), input_rechits_soa[hit_index].dim2() * Wi); alpaka::atomicAdd(acc, &outputs_service[cluster_index].total_weight_log(), Wi); } // uniform_elements - } // operator() + } // operator() }; // Besides the final position, add also the DetId of the seed of each cluster @@ -142,7 +142,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { } outputs.position()[cluster_index].z() = input_rechits_soa[max_energy_index].dim3(); } // uniform_elements - } // operator() + } // operator() }; void HGCalLayerClustersSoAAlgoWrapper::run(Queue& queue, diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.h b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.h index a70211912f51e..320797a710a55 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.h +++ b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalLayerClustersSoAAlgoWrapper.h @@ -7,7 +7,7 @@ #include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsDeviceCollection.h" #include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsExtraDeviceCollection.h" // #include "DataFormats/HGCalReco/interface/alpaka/HGCalSoAClustersDeviceCollection.h" -#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" +#include "DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h" #include "RecoLocalCalo/HGCalRecProducers/interface/alpaka/HGCalSoAClustersExtraDeviceCollection.h" #include "HeterogeneousCore/AlpakaInterface/interface/config.h" #include "HeterogeneousCore/AlpakaInterface/interface/traits.h" diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalSoALayerClustersProducer.cc b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalSoALayerClustersProducer.cc index c29eb5817d612..487f2cbd8914b 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalSoALayerClustersProducer.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/HGCalSoALayerClustersProducer.cc @@ -2,7 +2,7 @@ #include "DataFormats/HGCalReco/interface/HGCalSoARecHitsHostCollection.h" #include "DataFormats/HGCalReco/interface/alpaka/HGCalSoAClustersDeviceCollection.h" #include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsExtraDeviceCollection.h" -#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" +#include "DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h" #include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.dev.cc b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.dev.cc index 825e6c830dd1d..a1609a261d76b 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.dev.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.dev.cc @@ -24,9 +24,9 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { } void LayerClusterMerger::merge(Queue& queue, - reco::CaloClusterDeviceCollection::View merged, - reco::CaloClusterDeviceCollection::ConstView input, - uint32_t& start) { + reco::CaloClusterDeviceCollection::View merged, + reco::CaloClusterDeviceCollection::ConstView input, + uint32_t& start) { const auto blocksize = 1024u; const auto gridsize = cms::alpakatools::divide_up_by(input.position().metadata().size(), blocksize); const auto workdivision = cms::alpakatools::make_workdiv(gridsize, blocksize); diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.h b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.h index 48e7890922e23..19180b3a05725 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.h +++ b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/LayerClusterMergingAlgo.h @@ -1,7 +1,7 @@ #pragma once -#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" +#include "DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h" #include "HeterogeneousCore/AlpakaInterface/interface/workdivision.h" namespace ALPAKA_ACCELERATOR_NAMESPACE { diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/MergedLayerClusterProducer.cc b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/MergedLayerClusterProducer.cc index e12a4b7af125e..f817b2cf5f39c 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/MergedLayerClusterProducer.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/MergedLayerClusterProducer.cc @@ -1,6 +1,6 @@ -#include "DataFormats/CaloRecHit/interface/CaloClusterHostCollection.h" -#include "DataFormats/CaloRecHit/interface/alpaka/CaloClusterDeviceCollection.h" +#include "DataFormats/TICL/interface/CaloClusterHostCollection.h" +#include "DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h" #include "DataFormats/TICL/interface/ClusterMaskHost.h" #include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" diff --git a/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.cc b/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.cc index 581415db2f679..1642332f15f25 100644 --- a/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.cc +++ b/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.cc @@ -98,7 +98,7 @@ void BarrelCLUEAlgoT::makeClusters() { } template -ticl::LayerClustersAndAssociations BarrelCLUEAlgoT::getClusters(bool) { +ticl::LayerClustersAndAssociations BarrelCLUEAlgoT::getClusters(bool) { return ticl::LayerClustersAndAssociations(1, 1); } diff --git a/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.h b/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.h index 7a27fb9d7402f..362b7a7975441 100644 --- a/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.h +++ b/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.h @@ -26,7 +26,6 @@ #include "CondFormats/DataRecord/interface/HcalPFCutsRcd.h" #include "CondFormats/HcalObjects/interface/HcalPFCuts.h" - // C/C++ headers #include #include From 4fc9e2ff7e42424ad4e3ce7590ee3eafa479c832 Mon Sep 17 00:00:00 2001 From: Wahid Redjeb Date: Fri, 27 Mar 2026 04:41:28 +0100 Subject: [PATCH 23/24] simplify example --- DataFormats/TICL/interface/AssociationMap.h | 2 +- DataFormats/TICL/src/classes_def.xml | 11 - RecoHGCal/TICL/plugins/BuildFile.xml | 12 - .../alpaka/ClusterFilterByAlgoAndSize.dev.cc | 54 -- .../alpaka/ClusterFilterByAlgoAndSize.h | 37 -- .../alpaka/FilteredLayerClustersProducer.cc | 70 --- .../alpaka/HeterogeneousTracksterProducer.cc | 81 --- .../PatternRecognitionByCLUEstering.dev.cc | 167 ------- .../alpaka/PatternRecognitionByCLUEstering.h | 43 -- .../PatternRecognitionPluginFactory.dev.cc | 10 - .../alpaka/PatternRecognitionPluginFactory.h | 16 - .../interface/HGCalClusteringAlgoBase.h | 25 +- .../plugins/HGCalCLUEAlgo.cc | 468 +++++++++++++----- .../HGCalRecProducers/plugins/HGCalCLUEAlgo.h | 57 ++- .../plugins/HGCalLayerClusterProducer.cc | 185 ++++--- .../plugins/BarrelCLUEAlgo.cc | 7 +- .../plugins/BarrelCLUEAlgo.h | 4 +- .../plugins/BarrelLayerClusterProducer.cc | 2 +- 18 files changed, 536 insertions(+), 715 deletions(-) delete mode 100644 RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc delete mode 100644 RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h delete mode 100644 RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc delete mode 100644 RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc delete mode 100644 RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc delete mode 100644 RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h delete mode 100644 RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.dev.cc delete mode 100644 RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h diff --git a/DataFormats/TICL/interface/AssociationMap.h b/DataFormats/TICL/interface/AssociationMap.h index 0548e587e6d2c..1d4cef1225daf 100644 --- a/DataFormats/TICL/interface/AssociationMap.h +++ b/DataFormats/TICL/interface/AssociationMap.h @@ -35,7 +35,7 @@ namespace ticl { ), SOA_CONST_VIEW_METHODS( constexpr SOA_HOST_DEVICE auto operator[](TKey key) const { - auto offset = (key == 0) ? 0u : this->offsets().keys_offsets()[key]; + auto offset = (key == 0u) ? 0u : this->offsets()[key].keys_offsets(); auto size = (key == 0u) ? this->offsets()[0].keys_offsets() : this->offsets()[key].keys_offsets() - this->offsets()[key - 1].keys_offsets(); return std::span{this->content().values().data() + offset, static_cast(size)}; diff --git a/DataFormats/TICL/src/classes_def.xml b/DataFormats/TICL/src/classes_def.xml index 81af7c6616927..3a12e41bf6708 100644 --- a/DataFormats/TICL/src/classes_def.xml +++ b/DataFormats/TICL/src/classes_def.xml @@ -1,17 +1,6 @@ - - - - - - - - - - - diff --git a/RecoHGCal/TICL/plugins/BuildFile.xml b/RecoHGCal/TICL/plugins/BuildFile.xml index 52421c137f629..7087f2cf0e44c 100644 --- a/RecoHGCal/TICL/plugins/BuildFile.xml +++ b/RecoHGCal/TICL/plugins/BuildFile.xml @@ -39,15 +39,3 @@ - - - - - - - - - - - - diff --git a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc deleted file mode 100644 index 5dc47a20b8b93..0000000000000 --- a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.dev.cc +++ /dev/null @@ -1,54 +0,0 @@ - -#include "DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h" -#include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h" -#include "HeterogeneousCore/AlpakaInterface/interface/workdivision.h" -#include "HeterogeneousCore/AlpakaInterface/interface/memory.h" -#include "RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h" - -#include -#include -#include - -namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { - - template - ALPAKA_FN_ACC void KernelFilterLayerClusterByAlgoAndSize::operator()( - const TAcc& acc, - reco::CaloClusterDeviceCollection::ConstView layerClusters, - std::span algoNumber, - ticl::ClusterMaskDevice::View layerClusterMask, - uint32_t minClusterSize, - uint32_t maxClusterSize) const { - for (auto lcIdx : alpaka::uniformElements(acc, layerClusters.position().metadata().size())) { - bool foundAlgoNumber = false; - for (auto algo : algoNumber) { - if (algo == layerClusters.indexes()[lcIdx].algoID()) - foundAlgoNumber = true; - } - const auto layerClusterSize = static_cast(layerClusters.position()[lcIdx].cells()); - if (foundAlgoNumber && (layerClusterSize < minClusterSize) || (layerClusterSize > maxClusterSize)) - layerClusterMask[lcIdx] = 0.f; - } - } - - void ClusterFilterByAlgoAndSize::filter(Queue& queue, - const reco::CaloClusterDeviceCollection& layerClusters, - ticl::ClusterMaskDevice& layerClusterMask, - uint32_t minClusterSize, - uint32_t maxClusterSize) { - auto d_algo_number = cms::alpakatools::make_device_buffer(queue, algo_number_.size()); - alpaka::memcpy(queue, d_algo_number, cms::alpakatools::make_host_view(algo_number_.data(), algo_number_.size())); - auto blocksize = 1024; - auto gridsize = cms::alpakatools::divide_up_by(layerClusters.view().position().metadata().size(), blocksize); - auto workdivision = cms::alpakatools::make_workdiv(gridsize, blocksize); - alpaka::exec(queue, - workdivision, - KernelFilterLayerClusterByAlgoAndSize{}, - layerClusters.view(), - std::span{d_algo_number.data(), algo_number_.size()}, - layerClusterMask.view(), - minClusterSize, - maxClusterSize); - } - -} // namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl diff --git a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h b/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h deleted file mode 100644 index a2bc7d5321eb6..0000000000000 --- a/RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h +++ /dev/null @@ -1,37 +0,0 @@ - -#pragma once - -#include "DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h" -#include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" - -#include -#include - -namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { - - struct KernelFilterLayerClusterByAlgoAndSize { - template - ALPAKA_FN_ACC void operator()(const TAcc& acc, - reco::CaloClusterDeviceCollection::ConstView layerClusters, - std::span algoNumber, - ticl::ClusterMaskDevice::View layerClusterMask, - uint32_t minClusterSize, - uint32_t maxClusterSize) const; - }; - - class ClusterFilterByAlgoAndSize { - public: - ClusterFilterByAlgoAndSize(const edm::ParameterSet& config) - : algo_number_{config.getParameter("algo_number")} {} - void filter(Queue& queue, - const reco::CaloClusterDeviceCollection& layerClusters, - ticl::ClusterMaskDevice& layerClusterMask, - uint32_t minClusterSize, - uint32_t maxClusterSize); - - private: - std::vector algo_number_; - }; - -} // namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl diff --git a/RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc b/RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc deleted file mode 100644 index a2e4f33c7ccd5..0000000000000 --- a/RecoHGCal/TICL/plugins/alpaka/FilteredLayerClustersProducer.cc +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include "HeterogeneousCore/AlpakaInterface/interface/config.h" -#include "DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h" -#include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h" -#include "FWCore/Framework/interface/ConsumesCollector.h" -#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" -#include "FWCore/ParameterSet/interface/PluginDescription.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "Geometry/HGCalGeometry/interface/HGCalGeometry.h" -#include "FWCore/Utilities/interface/EDPutToken.h" -#include "DataFormats/HGCalReco/interface/Trackster.h" -#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESGetToken.h" -#include "HeterogeneousCore/AlpakaCore/interface/alpaka/stream/EDProducer.h" - -#include "RecoHGCal/TICL/plugins/alpaka/ClusterFilterByAlgoAndSize.h" - -#include -#include - -namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl { - - class HeterogeneousFilteredLayerClustersProducer : public stream::EDProducer<> { - public: - HeterogeneousFilteredLayerClustersProducer(const edm::ParameterSet& config) - : EDProducer(config), - deviceTokenSoAClusters_{consumes(config.getParameter("layerClusters"))}, - clustersMaskToken_{consumes(config.getParameter("layerClustersInputMask"))}, - filteredClustersMaskToken_{produces()}, - minClusterSize_{config.getParameter("minClusterSize")}, - maxClusterSize_{config.getParameter("maxClusterSize")}, - algo_(config) {} - ~HeterogeneousFilteredLayerClustersProducer() override = default; - - static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - edm::ParameterSetDescription desc; - desc.add("layerClusters", edm::InputTag("hgcalSoALayerClusters")); - desc.add("layerClustersInputMask", - edm::InputTag("hgcalMergeLayerClusters", "InitialLayerClustersMask")); - desc.add("minClusterSize"); - desc.add("maxClusterSize"); - - descriptions.addWithDefaultLabel(desc); - } - - void produce(device::Event& iEvent, const device::EventSetup& iSetup) override { - const auto& layerClusters = iEvent.get(deviceTokenSoAClusters_); - const auto& layerClustersMask = iEvent.get(clustersMaskToken_); - - auto& queue = iEvent.queue(); - ticl::ClusterMaskDevice filteredMask(queue, layerClustersMask.view().metadata().size()); - alpaka::memcpy(queue, filteredMask.buffer(), layerClustersMask.buffer()); - algo_.filter(queue, layerClusters, filteredMask, minClusterSize_, maxClusterSize_); - - iEvent.emplace(filteredClustersMaskToken_, std::move(filteredMask)); - } - - private: - device::EDGetToken const deviceTokenSoAClusters_; - device::EDGetToken clustersMaskToken_; - device::EDPutToken filteredClustersMaskToken_; - - const uint32_t minClusterSize_; - const uint32_t maxClusterSize_; - - ClusterFilterByAlgoAndSize algo_; - }; - -} // namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl diff --git a/RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc b/RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc deleted file mode 100644 index 0d82d89a20cd0..0000000000000 --- a/RecoHGCal/TICL/plugins/alpaka/HeterogeneousTracksterProducer.cc +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include "HeterogeneousCore/AlpakaInterface/interface/config.h" -#include "DataFormats/HGCalReco/interface/HGCalSoAClusters.h" -#include "DataFormats/HGCalReco/interface/HGCalSoARecHitsHostCollection.h" -#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoAClustersDeviceCollection.h" -#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsExtraDeviceCollection.h" -#include "FWCore/Framework/interface/ConsumesCollector.h" -#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" -#include "FWCore/ParameterSet/interface/PluginDescription.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "Geometry/HGCalGeometry/interface/HGCalGeometry.h" -#include "FWCore/Utilities/interface/EDPutToken.h" -#include "DataFormats/HGCalReco/interface/Trackster.h" -#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESGetToken.h" -#include "HeterogeneousCore/AlpakaCore/interface/alpaka/stream/EDProducer.h" -#include "RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h" -#include "RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h" -#include "RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h" -#include "CLUEstering/CLUEstering.hpp" - -#include -#include -#include - -namespace ALPAKA_ACCELERATOR_NAMESPACE { - - class HeterogeneousTracksterProducer : public stream::EDProducer<> { - public: - HeterogeneousTracksterProducer(edm::ParameterSet const& config) - : EDProducer(config), - // detector_(config.getParameter("detector")), - // doNose_(detector_ == "HFNose"), - deviceTokenSoAClusters_{consumes(config.getParameter("layerClusters"))}, - legacyTrackstersToken_{produces()} { - auto plugin = config.getParameter("patternRecognitionBy"); - auto pluginPSet = config.getParameter("pluginPatternRecognitionBy" + plugin); - algo_ = PatternRecognitionFactoryAlpaka::get()->create(config.getParameter("patternRecognitionBy"), - pluginPSet); - } - ~HeterogeneousTracksterProducer() override = default; - - static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - edm::ParameterSetDescription desc; - desc.add("layerClusters", edm::InputTag("hgcalSoALayerClusters")); - // Still needed? I guess I still need to save them here and then copy to algo - // desc.add("rho_c", 0.6); - // desc.add>("dc", {2., 2., 2}); - // desc.add>("dm", {1.8, 1.8, 2}); - desc.add("patternRecognitionBy", "CLUEstering"); - - edm::ParameterSetDescription pluginDesc; - pluginDesc.addNode(edm::PluginDescription("type", "CLUEstering", true)); - desc.add("pluginPatternRecognitionByCLUEstering", pluginDesc); - - descriptions.addWithDefaultLabel(desc); - } - - void produce(device::Event& iEvent, device::EventSetup const& iSetup) override { - const auto& lc = iEvent.get(deviceTokenSoAClusters_); - auto tracksters = std::vector(); - auto& queue = iEvent.queue(); - algo_->makeTracksters(queue, lc, tracksters); - - iEvent.emplace(legacyTrackstersToken_, std::move(tracksters)); - } - - private: - // std::string detector_; - // bool doNose_; - device::EDGetToken const deviceTokenSoAClusters_; - edm::EDPutTokenT> const legacyTrackstersToken_; - std::unique_ptr algo_; - std::unique_ptr myAlgoHFNose_; - }; - -} // namespace ALPAKA_ACCELERATOR_NAMESPACE - -#include "HeterogeneousCore/AlpakaCore/interface/alpaka/MakerMacros.h" -DEFINE_FWK_ALPAKA_MODULE(HeterogeneousTracksterProducer); diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc deleted file mode 100644 index 564e3c9ffa27a..0000000000000 --- a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.dev.cc +++ /dev/null @@ -1,167 +0,0 @@ -#include "DataFormats/HGCalReco/interface/HGCalSoAClusters.h" -#include "DataFormats/HGCalReco/interface/HGCalSoARecHitsHostCollection.h" -#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoAClustersDeviceCollection.h" -#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsExtraDeviceCollection.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h" -#include "DataFormats/HGCalReco/interface/Trackster.h" -#include "CLUEstering/CLUEstering.hpp" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" - -#include "RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h" - -#include -#include -#include - -namespace ALPAKA_ACCELERATOR_NAMESPACE { - - namespace ticl = ::ticl; - - void PatternRecognitionByCLUEstering::makeTracksters(Queue& queue, - const HGCalSoAClustersDeviceCollection& lc, - std::vector& tracksters) { - auto* x = const_cast(lc.view().x().data()); - auto* y = const_cast(lc.view().y().data()); - auto* z = const_cast(lc.view().z().data()); - auto* E = const_cast(lc.view().energy().data()); - // std::unordered_map> map; - - // for (int i = 0; i < lc->metadata().size(); ++i) { - // map[z[i]].push_back(i); - // } - - const int32_t n = static_cast(lc->metadata().size()); - if (n > 0) { - auto d_clIndex = cms::alpakatools::make_device_buffer(queue, n); // temporary buffer needed by CLUEstering - auto dp_clIndex = const_cast(d_clIndex.data()); - clue::PointsDevice<3> d_points(queue, n, x, y, z, E, dp_clIndex); - // if (m_verbosity) { - // for (int iLC = 0; iLC < n; ++iLC) { - // std::cout << "( " << x[iLC] << ", " << y[iLC] << ", " << z[iLC] << ", " << E[iLC] << " )" << std::endl; - // } - // } - - clue::Clusterer<3> clusterer(queue, m_dc, m_rhoc, m_dm); - std::array weights{{1.f, 1., 2.f}}; - clusterer.make_clusters(queue, d_points, clue::metrics::WeightedChebyshev<3>(weights)); - // create hosts points and do the copy - clue::PointsHost<3> h_points(queue, n); - clue::copyToHost(queue, h_points, d_points); - alpaka::wait(queue); - - // get LCs indices in tracksters and fill the trackster collection - const auto tsMap = clue::get_clusters(h_points); - tracksters.resize(tsMap.size()); - for (auto i = 0ul; i < tsMap.size(); ++i) { - const auto [beginLC, endLC] = tsMap.equal_range(i); - std::copy(beginLC, endLC, std::back_inserter(tracksters[i].vertices())); - tracksters[i].vertex_multiplicity().resize(tracksters[i].vertices().size(), 1); - } - - alpaka::memcpy(queue, - cms::alpakatools::make_host_view(h_points.view().coords()[0], n), - cms::alpakatools::make_device_view(alpaka::getDev(queue), x, n), - static_cast(n)); - alpaka::memcpy(queue, - cms::alpakatools::make_host_view(h_points.view().coords()[1], n), - cms::alpakatools::make_device_view(alpaka::getDev(queue), y, n), - static_cast(n)); - alpaka::memcpy(queue, - cms::alpakatools::make_host_view(h_points.view().coords()[2], n), - cms::alpakatools::make_device_view(alpaka::getDev(queue), z, n), - static_cast(n)); - alpaka::memcpy(queue, - cms::alpakatools::make_host_view(h_points.weights(), n), - cms::alpakatools::make_device_view(alpaka::getDev(queue), E, n), - static_cast(n)); - alpaka::wait(queue); - - // compute trackster properties - // TODO: merge with previous loop - bool energyWeight = true; - auto xHost = h_points.coords(0).data(); - auto yHost = h_points.coords(1).data(); - auto zHost = h_points.coords(2).data(); - auto EHost = h_points.weights(); - // if (m_verbosity) { - // std::cout << "Event Number of LCs " << n << std::endl; - // for (const auto& [Z, indices] : map) { - // std::cout << "z = " << Z << " -> Clusters : "; - // for (auto i : indices) - // std::cout << "\t( " << xHost[i] << ", " << yHost[i] << ", " << zHost[i] << ", " << EHost[i] << ")" - // << std::endl; - // std::cout << std::endl; - // } - // } - for (auto& trackster : tracksters) { - size_t N = trackster.vertices().size(); - if (N == 0) - continue; - - Eigen::Vector3f point; - point << 0., 0., 0.; - Eigen::Vector3f barycenter; - barycenter << 0., 0., 0.; - - auto fillPoint = [&](const float x, const float y, const float z, const float weight = 1.f) { - point[0] = weight * x; - point[1] = weight * y; - point[2] = weight * z; - }; - - // Initialize this trackster with default, dummy values - trackster.setRawEnergy(0.f); - trackster.setRawEmEnergy(0.f); - trackster.setRawPt(0.f); - trackster.setRawEmPt(0.f); - - float weight = 1.f / N; - - std::vector layerClusterEnergies; - - for (size_t i = 0; i < N; ++i) { - auto lcIdx = trackster.vertices(i); - auto fraction = 1.f / trackster.vertex_multiplicity(i); - trackster.addToRawEnergy(EHost[lcIdx] * fraction); - // trackster.addToRawEmEnergy(EHost[lcIdx] * fraction); - - // Compute the weighted barycenter. - if (energyWeight) - weight = EHost[lcIdx] * fraction; - fillPoint(xHost[lcIdx], yHost[lcIdx], zHost[lcIdx], weight); - for (size_t j = 0; j < 3; ++j) - barycenter[j] += point[j]; - - layerClusterEnergies.push_back(EHost[lcIdx]); - } - float raw_energy = trackster.raw_energy(); - float inv_raw_energy = 1.f / raw_energy; - if (energyWeight) - barycenter *= inv_raw_energy; - trackster.setBarycenter(ticl::Trackster::Vector(barycenter)); - - trackster.calculateRawPt(); - trackster.calculateRawEmPt(); - // if (m_verbosity) { - // std::cout << " LC in TS: "; - // for (const auto& lc : trackster.vertices()) - // std::cout << lc << " "; - // std::cout << std::endl; - // std::cout << " energy raw: " << trackster.raw_energy() << std::endl; - // std::cout << " barycenter: " << trackster.barycenter().x() << ", " << trackster.barycenter().y() << ", " - // << trackster.barycenter().z() << std::endl; - // } - } - } - } - - void PatternRecognitionByCLUEstering::fillPSetDescription(::edm::ParameterSetDescription& iDesc) { - // iDesc.add("algo_verbosity", 0); - iDesc.add("rho_c", 6.); - iDesc.add("dc", 2.); - iDesc.add("dm", 1.8); - } - -} // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h deleted file mode 100644 index b3e8f2876ac67..0000000000000 --- a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h +++ /dev/null @@ -1,43 +0,0 @@ - -#pragma once - -#include "CondCore/CondDB/interface/Exception.h" -#include "DataFormats/HGCalReco/interface/HGCalSoAClusters.h" -#include "DataFormats/HGCalReco/interface/HGCalSoARecHitsHostCollection.h" -#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoAClustersDeviceCollection.h" -#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsExtraDeviceCollection.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h" -#include "DataFormats/HGCalReco/interface/Trackster.h" -#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" - -#include -#include -#include -#include -#include - -namespace ALPAKA_ACCELERATOR_NAMESPACE { - - class PatternRecognitionByCLUEstering final : public PatternRecognitionAlgoBase { - private: - float m_rhoc; - float m_dc; - float m_dm; - - public: - PatternRecognitionByCLUEstering(const edm::ParameterSet& config) - : PatternRecognitionAlgoBase(config), - m_rhoc(config.getParameter("rho_c")), - m_dc(config.getParameter("dc")), - m_dm(config.getParameter("dm")) {} - ~PatternRecognitionByCLUEstering() override = default; - - void makeTracksters(Queue& queue, - const HGCalSoAClustersDeviceCollection& lc, - std::vector& tracksters) override; - - static void fillPSetDescription(::edm::ParameterSetDescription& iDesc); - }; - -} // namespace ALPAKA_ACCELERATOR_NAMESPACE diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.dev.cc b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.dev.cc deleted file mode 100644 index 0fb23971554b3..0000000000000 --- a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.dev.cc +++ /dev/null @@ -1,10 +0,0 @@ -#include "RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h" -#include "RecoHGCal/TICL/plugins/alpaka/PatternRecognitionByCLUEstering.h" -#include "FWCore/ParameterSet/interface/ValidatedPluginFactoryMacros.h" -#include "FWCore/ParameterSet/interface/ValidatedPluginMacros.h" - -EDM_REGISTER_VALIDATED_PLUGINFACTORY(PatternRecognitionFactoryAlpaka, "PatternRecognitionFactoryAlpaka"); -// EDM_REGISTER_VALIDATED_PLUGINFACTORY(PatternRecognitionHFNoseFactoryAlpaka, "PatternRecognitionHFNoseFactoryAlpaka"); -DEFINE_EDM_VALIDATED_PLUGIN(PatternRecognitionFactoryAlpaka, - ALPAKA_ACCELERATOR_NAMESPACE::PatternRecognitionByCLUEstering, - "CLUEstering"); diff --git a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h b/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h deleted file mode 100644 index 5551b9d6aee67..0000000000000 --- a/RecoHGCal/TICL/plugins/alpaka/PatternRecognitionPluginFactory.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef RecoHGCal_TICL_PatternRecognitionPluginFactory_H -#define RecoHGCal_TICL_PatternRecognitionPluginFactory_H - -#include "FWCore/PluginManager/interface/PluginFactory.h" -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/Framework/interface/ConsumesCollector.h" -#include "RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h" -#include "RecoHGCal/TICL/interface/alpaka/PatternRecognitionAlgoBase.h" -#include "RecoHGCal/TICL/interface/GlobalCache.h" - -using PatternRecognitionFactoryAlpaka = - ::edmplugin::PluginFactory; -// using PatternRecognitionHFNoseFactoryAlpaka = -// edmplugin::PluginFactory; - -#endif diff --git a/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h b/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h index b276d5adffcd5..152b8b8158d82 100644 --- a/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h +++ b/RecoLocalCalo/HGCalRecProducers/interface/HGCalClusteringAlgoBase.h @@ -1,26 +1,24 @@ #ifndef RecoLocalCalo_HGCalRecProducers_HGCalClusteringAlgoBase_h #define RecoLocalCalo_HGCalRecProducers_HGCalClusteringAlgoBase_h -#include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/ConsumesCollector.h" -#include "DataFormats/TICL/interface/CaloClusterHostCollection.h" -#include "DataFormats/EgammaReco/interface/BasicCluster.h" #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" -#include "DataFormats/Math/interface/Point3D.h" #include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h" +#include "DataFormats/Math/interface/Point3D.h" +#include "DataFormats/EgammaReco/interface/BasicCluster.h" #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" -#include "RecoLocalCalo/HGCalRecProducers/interface/LayerClusterAndAssociations.h" #include "CondFormats/DataRecord/interface/EcalPFRecHitThresholdsRcd.h" -#include "CondFormats/DataRecord/interface/HcalPFCutsRcd.h" #include "CondFormats/EcalObjects/interface/EcalPFRecHitThresholds.h" +#include "CondFormats/DataRecord/interface/HcalPFCutsRcd.h" #include "CondFormats/HcalObjects/interface/HcalPFCuts.h" // C/C++ headers -#include #include +#include namespace hgcal_clustering { template @@ -48,7 +46,7 @@ namespace hgcal_clustering { return (*maxidx); } - // Density collection + //Density collection typedef std::map Density; }; // namespace hgcal_clustering @@ -63,11 +61,10 @@ class HGCalClusteringAlgoBase { virtual void populate(const HGCRecHitCollection &hits) = 0; virtual void populate(const reco::PFRecHitCollection &hits) = 0; virtual void makeClusters() = 0; - virtual ticl::LayerClustersAndAssociations getClusters(bool) = 0; - virtual std::vector getClustersLegacy(bool) = 0; + virtual std::vector getClusters(bool) = 0; virtual void reset() = 0; - virtual hgcal_clustering::Density getDensity() { return {}; }; // implementation is in some child class - virtual void getEventSetupPerAlgorithm(const edm::EventSetup &es) {} // implementation is in some child class + virtual hgcal_clustering::Density getDensity() { return {}; }; //implementation is in some child class + virtual void getEventSetupPerAlgorithm(const edm::EventSetup &es) {} //implementation is in some child class inline void getEventSetup(const edm::EventSetup &es, hgcal::RecHitTools rhtools) { rhtools_ = rhtools; @@ -86,7 +83,7 @@ class HGCalClusteringAlgoBase { virtual void setThresholds(edm::ESGetToken, edm::ESGetToken){}; - // max number of layers + //max number of layers unsigned int maxlayer_ = 0; // last layer per subdetector unsigned int lastLayerEE_ = 0; @@ -102,8 +99,6 @@ class HGCalClusteringAlgoBase { // The vector of clusters std::vector clusters_v_; - // reco::CaloClusterHostCollection layer_clusters_; - hgcal::RecHitTools rhtools_; // The algo id diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc index e61a923e867fc..28b5999619f7d 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.cc @@ -1,10 +1,7 @@ #include "RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h" // Geometry -#include "DataFormats/TICL/interface/CaloClusterHostCollection.h" #include "DataFormats/HcalDetId/interface/HcalSubdetector.h" -#include "DataFormats/TICL/interface/AssociationMap.h" -#include "DataFormats/TICL/interface/FillAssociator.h" #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h" #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h" #include "Geometry/Records/interface/IdealGeometryRecord.h" @@ -12,17 +9,15 @@ #include "RecoEcal/EgammaCoreTools/interface/PositionCalc.h" // #include "DataFormats/CaloRecHit/interface/CaloID.h" -#include "DataFormats/DetId/interface/DetId.h" - -#include "CLUEstering/CLUEstering.hpp" -#include "oneapi/tbb.h" #include "oneapi/tbb/task_arena.h" +#include "oneapi/tbb.h" #include +#include "DataFormats/DetId/interface/DetId.h" using namespace hgcal_clustering; template -void HGCalCLUEAlgoT::getEventSetupPerAlgorithm(const edm::EventSetup &es) { +void HGCalCLUEAlgoT::getEventSetupPerAlgorithm(const edm::EventSetup& es) { cells_.clear(); numberOfClustersPerLayer_.clear(); cells_.resize(2 * (maxlayer_ + 1)); @@ -30,7 +25,7 @@ void HGCalCLUEAlgoT::getEventSetupPerAlgorithm(const edm::EventSetu } template -void HGCalCLUEAlgoT::populate(const HGCRecHitCollection &hits) { +void HGCalCLUEAlgoT::populate(const HGCRecHitCollection& hits) { // loop over all hits and create the Hexel structure, skip energies below ecut if (dependSensor_) { // for each layer and wafer calculate the thresholds (sigmaNoise and energy) @@ -39,7 +34,7 @@ void HGCalCLUEAlgoT::populate(const HGCRecHitCollection &hits) { } for (unsigned int i = 0; i < hits.size(); ++i) { - const HGCRecHit &hgrh = hits[i]; + const HGCRecHit& hgrh = hits[i]; DetId detid = hgrh.detid(); unsigned int layerOnSide = (rhtools_.getLayerWithOffset(detid) - 1); @@ -84,38 +79,54 @@ void HGCalCLUEAlgoT::populate(const HGCRecHitCollection &hits) { } } +template +void HGCalCLUEAlgoT::prepareDataStructures(unsigned int l) { + auto cellsSize = cells_[l].detid.size(); + cells_[l].rho.resize(cellsSize, 0.f); + cells_[l].delta.resize(cellsSize, 9999999); + cells_[l].nearestHigher.resize(cellsSize, -1); + cells_[l].clusterIndex.resize(cellsSize, -1); + cells_[l].followers.resize(cellsSize); + cells_[l].isSeed.resize(cellsSize, false); +} + // Create a vector of Hexels associated to one cluster from a collection of // HGCalRecHits - this can be used directly to make the final cluster list - // this method can be invoked multiple times for the same event with different // input (reset should be called between events) template void HGCalCLUEAlgoT::makeClusters() { - for (auto l = 0u; l < maxlayer_; ++l) { - float delta; - if constexpr (std::is_same_v) { - // maximum search distance (critical distance) for local density - // calculation - float delta_c; - if (l % maxlayer_ < lastLayerEE_) - delta_c = vecDeltas_[0]; - else if (l % maxlayer_ < (firstLayerBH_ - 1)) - delta_c = vecDeltas_[1]; - else - delta_c = vecDeltas_[2]; - delta = delta_c; - } else { - float delta_r = vecDeltas_[3]; - delta = delta_r; - } + // assign all hits in each layer to a cluster core + tbb::this_task_arena::isolate([&] { + tbb::parallel_for(size_t(0), size_t(2 * maxlayer_ + 2), [&](size_t i) { + prepareDataStructures(i); + T lt; + lt.clear(); + lt.fill(cells_[i].dim1, cells_[i].dim2); - auto clusterer = clue::Clusterer<2>(delta, kappa_); - auto queue = clue::get_queue(0u); - auto points = clue::PointsHost<2>( - queue, cells_[l].dim1.size(), cells_[l].dim1, cells_[l].dim2, cells_[l].weight, cells_[l].clusterIndex); - points.set_density_uncertainty(cells_[l].sigmaNoise); - clusterer.make_clusters(points); - numberOfClustersPerLayer_[l] = points.n_clusters(); - } + float delta; + if constexpr (std::is_same_v) { + // maximum search distance (critical distance) for local density calculation + float delta_c; + if (i % maxlayer_ < lastLayerEE_) + delta_c = vecDeltas_[0]; + else if (i % maxlayer_ < (firstLayerBH_ - 1)) + delta_c = vecDeltas_[1]; + else + delta_c = vecDeltas_[2]; + delta = delta_c; + } else { + float delta_r = vecDeltas_[3]; + delta = delta_r; + } + LogDebug("HGCalCLUEAlgo") << "maxlayer: " << maxlayer_ << " lastLayerEE: " << lastLayerEE_ + << " firstLayerBH: " << firstLayerBH_ << "\n"; + + calculateLocalDensity(lt, i, delta); + calculateDistanceToHigher(lt, i, delta); + numberOfClustersPerLayer_[i] = findAndAssignClusters(i, delta); + }); + }); #if DEBUG_CLUSTERS_ALPAKA hgcalUtils::DumpLegacySoA dumperLegacySoA; dumperLegacySoA.dumpInfos(cells_, moduleType_); @@ -123,105 +134,325 @@ void HGCalCLUEAlgoT::makeClusters() { } template -std::vector HGCalCLUEAlgoT::getClustersLegacy(bool) { - return std::vector(1); -} - -template -ticl::LayerClustersAndAssociations HGCalCLUEAlgoT::getClusters(bool) { +std::vector HGCalCLUEAlgoT::getClusters(bool) { std::vector offsets(numberOfClustersPerLayer_.size(), 0); + int maxClustersOnLayer = numberOfClustersPerLayer_[0]; + for (unsigned layerId = 1; layerId < offsets.size(); ++layerId) { offsets[layerId] = offsets[layerId - 1] + numberOfClustersPerLayer_[layerId - 1]; + maxClustersOnLayer = std::max(maxClustersOnLayer, numberOfClustersPerLayer_[layerId]); } - auto totalNumberOfClusters = offsets.back() + numberOfClustersPerLayer_.back(); - // std::vector> cellsIdInCluster; - // cellsIdInCluster.reserve(maxClustersOnLayer); - const auto total_rechits = std::accumulate( - cells_.begin(), cells_.end(), 0, [](auto acc, const auto &cell) { return acc + cell.dim1.size(); }); - ticl::LayerClustersAndAssociations clusters_and_associations(totalNumberOfClusters, total_rechits); + auto totalNumberOfClusters = offsets.back() + numberOfClustersPerLayer_.back(); + clusters_v_.resize(totalNumberOfClusters); + std::vector> cellsIdInCluster; + cellsIdInCluster.reserve(maxClustersOnLayer); - std::vector detid_and_fractions; - std::vector cluster_hit_associations; for (unsigned int layerId = 0; layerId < 2 * maxlayer_ + 2; ++layerId) { - auto queue = clue::get_queue(0u); - auto points = clue::PointsHost<2>(queue, - cells_[layerId].dim1.size(), - cells_[layerId].dim1, - cells_[layerId].dim2, - cells_[layerId].weight, - cells_[layerId].clusterIndex); - - std::ranges::copy(points.clusterIndexes(), std::back_inserter(cluster_hit_associations)); - - auto clusters = clue::get_clusters(points); - auto to_hit_and_fraction = [&](auto idx) { return ticl::HitAndFraction{cells_[layerId].detid[idx], -1.f}; }; - std::ranges::copy(clusters | std::views::transform(to_hit_and_fraction), std::back_inserter(detid_and_fractions)); - for (auto cl = 0u; cl < clusters.size(); ++cl) { - const auto cluster = clusters[cl]; - auto x = 0.f; - auto y = 0.f; - const auto z = cells_[layerId].layerDim3; - auto energy = std::reduce( - cluster.begin(), cluster.end(), 0.f, [&](auto acc, auto idx) { return acc + points.weights()[idx]; }); - auto max_energy_it = std::ranges::max_element(points.weights()); - const auto max_energy_idx = std::distance(points.weights().begin(), max_energy_it); - const auto max_energy_detid = cells_[layerId].detid[max_energy_idx]; + cellsIdInCluster.resize(numberOfClustersPerLayer_[layerId]); + auto& cellsOnLayer = cells_[layerId]; + unsigned int numberOfCells = cellsOnLayer.detid.size(); + auto firstClusterIdx = offsets[layerId]; + + for (unsigned int i = 0; i < numberOfCells; ++i) { + auto clusterIndex = cellsOnLayer.clusterIndex[i]; + if (clusterIndex != -1) + cellsIdInCluster[clusterIndex].push_back(i); + } + + std::vector> thisCluster; + + for (auto& cl : cellsIdInCluster) { + float maxEnergyValue = std::numeric_limits::min(); + int maxEnergyCellIndex = -1; + DetId maxEnergyDetId; + float energy = 0.f; + int seedDetId = -1; + float x = 0.f; + float y = 0.f; + float z = cellsOnLayer.layerDim3; + // TODO Felice: maybe use the seed for the position calculation + for (auto cellIdx : cl) { + energy += cellsOnLayer.weight[cellIdx]; + if (cellsOnLayer.weight[cellIdx] > maxEnergyValue) { + maxEnergyValue = cellsOnLayer.weight[cellIdx]; + maxEnergyCellIndex = cellIdx; + maxEnergyDetId = cellsOnLayer.detid[cellIdx]; + } + thisCluster.emplace_back(cellsOnLayer.detid[cellIdx], 1.f); + if (cellsOnLayer.isSeed[cellIdx]) { + seedDetId = cellsOnLayer.detid[cellIdx]; + } + } + + float total_weight_log = 0.f; + float total_weight = energy; if constexpr (std::is_same_v) { - auto thick = rhtools_.getSiThickIndex(max_energy_detid); - auto total_weight_log = 0.f; - for (auto p : cluster) { - const auto d1 = points.coords(0)[p] - points.coords(0)[max_energy_idx]; - const auto d2 = points.coords(1)[p] - points.coords(1)[max_energy_idx]; + auto thick = rhtools_.getSiThickIndex(maxEnergyDetId); + for (auto cellIdx : cl) { + const float d1 = cellsOnLayer.dim1[cellIdx] - cellsOnLayer.dim1[maxEnergyCellIndex]; + const float d2 = cellsOnLayer.dim2[cellIdx] - cellsOnLayer.dim2[maxEnergyCellIndex]; if ((d1 * d1 + d2 * d2) < positionDeltaRho2_) { - auto Wi = std::max(thresholdW0_[thick] + std::log(points.weights()[p] / energy), 0.); - x += points.coords(0)[p] * Wi; - y += points.coords(1)[p] * Wi; + float Wi = std::max(thresholdW0_[thick] + std::log(cellsOnLayer.weight[cellIdx] / energy), 0.); + x += cellsOnLayer.dim1[cellIdx] * Wi; + y += cellsOnLayer.dim2[cellIdx] * Wi; total_weight_log += Wi; } } - - if (total_weight_log != 0.) { - auto inv_tot_weight = 1.f / total_weight_log; - x *= inv_tot_weight; - y *= inv_tot_weight; - } else { - x = points.coords(0)[max_energy_idx]; - y = points.coords(1)[max_energy_idx]; + } else { + for (auto cellIdx : cl) { + auto position = rhtools_.getPosition(cellsOnLayer.detid[cellIdx]); + x += position.x() * cellsOnLayer.weight[cellIdx]; + y += position.y() * cellsOnLayer.weight[cellIdx]; } + } + + if constexpr (std::is_same_v) { + total_weight = total_weight_log; + } + + if (total_weight != 0.) { + float inv_tot_weight = 1.f / total_weight; + x *= inv_tot_weight; + y *= inv_tot_weight; } else { - const auto centroid = clue::weighted_cluster_centroid(points, cl); - x = centroid[0]; - y = centroid[1]; + x = cellsOnLayer.dim1[maxEnergyCellIndex]; + y = cellsOnLayer.dim2[maxEnergyCellIndex]; + } + math::XYZPoint position = math::XYZPoint(x, y, z); + + auto globalClusterIndex = cellsOnLayer.clusterIndex[cl[0]] + firstClusterIdx; + + clusters_v_[globalClusterIndex] = + reco::BasicCluster(energy, position, reco::CaloID::DET_HGCAL_ENDCAP, thisCluster, algoId_); + clusters_v_[globalClusterIndex].setSeed(seedDetId); + thisCluster.clear(); + } + + cellsIdInCluster.clear(); + } + return clusters_v_; +} +template +void HGCalCLUEAlgoT::calculateLocalDensity(const T& lt, + const unsigned int layerId, + float delta, + HGCalSiliconStrategy strategy) { + auto& cellsOnLayer = cells_[layerId]; + unsigned int numberOfCells = cellsOnLayer.detid.size(); + for (unsigned int i = 0; i < numberOfCells; i++) { + std::array search_box = lt.searchBox(cellsOnLayer.dim1[i] - delta, + cellsOnLayer.dim1[i] + delta, + cellsOnLayer.dim2[i] - delta, + cellsOnLayer.dim2[i] + delta); + + for (int xBin = search_box[0]; xBin < search_box[1] + 1; ++xBin) { + for (int yBin = search_box[2]; yBin < search_box[3] + 1; ++yBin) { + int binId = lt.getGlobalBinByBin(xBin, yBin); + size_t binSize = lt[binId].size(); + + for (unsigned int j = 0; j < binSize; j++) { + unsigned int otherId = lt[binId][j]; + if (distance(lt, i, otherId, layerId) < delta) { + cellsOnLayer.rho[i] += (i == otherId ? 1.f : 0.5f) * cellsOnLayer.weight[otherId]; + } + } + } + } + LogDebug("HGCalCLUEAlgo") << "Debugging calculateLocalDensity: \n" + << " cell: " << i << " eta: " << cellsOnLayer.dim1[i] << " phi: " << cellsOnLayer.dim2[i] + << " energy: " << cellsOnLayer.weight[i] << " density: " << cellsOnLayer.rho[i] << "\n"; + } +} +template +void HGCalCLUEAlgoT::calculateLocalDensity(const T& lt, + const unsigned int layerId, + float delta, + HGCalScintillatorStrategy strategy) { + auto& cellsOnLayer = cells_[layerId]; + unsigned int numberOfCells = cellsOnLayer.detid.size(); + for (unsigned int i = 0; i < numberOfCells; i++) { + std::array search_box = lt.searchBox(cellsOnLayer.dim1[i] - delta, + cellsOnLayer.dim1[i] + delta, + cellsOnLayer.dim2[i] - delta, + cellsOnLayer.dim2[i] + delta); + cellsOnLayer.rho[i] += cellsOnLayer.weight[i]; + float northeast(0), northwest(0), southeast(0), southwest(0), all(0); + for (int etaBin = search_box[0]; etaBin < search_box[1] + 1; ++etaBin) { + for (int phiBin = search_box[2]; phiBin < search_box[3] + 1; ++phiBin) { + int phi = (phiBin % T::type::nRows); + int binId = lt.getGlobalBinByBin(etaBin, phi); + size_t binSize = lt[binId].size(); + for (unsigned int j = 0; j < binSize; j++) { + unsigned int otherId = lt[binId][j]; + if (distance(lt, i, otherId, layerId) < delta) { + int iPhi = HGCScintillatorDetId(cellsOnLayer.detid[i]).iphi(); + int otherIPhi = HGCScintillatorDetId(cellsOnLayer.detid[otherId]).iphi(); + int iEta = HGCScintillatorDetId(cellsOnLayer.detid[i]).ieta(); + int otherIEta = HGCScintillatorDetId(cellsOnLayer.detid[otherId]).ieta(); + int dIPhi = otherIPhi - iPhi; + dIPhi += abs(dIPhi) < 2 ? 0 + : dIPhi < 0 ? scintMaxIphi_ + : -scintMaxIphi_; // cells with iPhi=288 and iPhi=1 should be neiboring cells + int dIEta = otherIEta - iEta; + LogDebug("HGCalCLUEAlgo") << " Debugging calculateLocalDensity for Scintillator: \n" + << " cell: " << otherId << " energy: " << cellsOnLayer.weight[otherId] + << " otherIPhi: " << otherIPhi << " iPhi: " << iPhi << " otherIEta: " << otherIEta + << " iEta: " << iEta << "\n"; + + if (otherId != i) { + auto neighborCellContribution = 0.5f * cellsOnLayer.weight[otherId]; + all += neighborCellContribution; + if (dIPhi >= 0 && dIEta >= 0) + northeast += neighborCellContribution; + if (dIPhi <= 0 && dIEta >= 0) + southeast += neighborCellContribution; + if (dIPhi >= 0 && dIEta <= 0) + northwest += neighborCellContribution; + if (dIPhi <= 0 && dIEta <= 0) + southwest += neighborCellContribution; + } + LogDebug("HGCalCLUEAlgo") << " Debugging calculateLocalDensity for Scintillator: \n" + << " northeast: " << northeast << " southeast: " << southeast + << " northwest: " << northwest << " southwest: " << southwest << "\n"; + } + } + } + } + float neighborsval = (std::max(northeast, northwest) > std::max(southeast, southwest)) + ? std::max(northeast, northwest) + : std::max(southeast, southwest); + if (use2x2_) + cellsOnLayer.rho[i] += neighborsval; + else + cellsOnLayer.rho[i] += all; + LogDebug("HGCalCLUEAlgo") << "Debugging calculateLocalDensity: \n" + << " cell: " << i << " eta: " << cellsOnLayer.dim1[i] << " phi: " << cellsOnLayer.dim2[i] + << " energy: " << cellsOnLayer.weight[i] << " density: " << cellsOnLayer.rho[i] << "\n"; + } +} +template +void HGCalCLUEAlgoT::calculateLocalDensity(const T& lt, const unsigned int layerId, float delta) { + if constexpr (std::is_same_v) { + calculateLocalDensity(lt, layerId, delta, HGCalSiliconStrategy()); + } else { + calculateLocalDensity(lt, layerId, delta, HGCalScintillatorStrategy()); + } +} + +template +void HGCalCLUEAlgoT::calculateDistanceToHigher(const T& lt, const unsigned int layerId, float delta) { + auto& cellsOnLayer = cells_[layerId]; + unsigned int numberOfCells = cellsOnLayer.detid.size(); + + for (unsigned int i = 0; i < numberOfCells; i++) { + // initialize delta and nearest higher for i + float maxDelta = std::numeric_limits::max(); + float i_delta = maxDelta; + int i_nearestHigher = -1; + float rho_max = 0.f; + auto range = outlierDeltaFactor_ * delta; + std::array search_box = lt.searchBox(cellsOnLayer.dim1[i] - range, + cellsOnLayer.dim1[i] + range, + cellsOnLayer.dim2[i] - range, + cellsOnLayer.dim2[i] + range); + // loop over all bins in the search box + for (int dim1Bin = search_box[0]; dim1Bin < search_box[1] + 1; ++dim1Bin) { + for (int dim2Bin = search_box[2]; dim2Bin < search_box[3] + 1; ++dim2Bin) { + // get the id of this bin + size_t binId = lt.getGlobalBinByBin(dim1Bin, dim2Bin); + if constexpr (std::is_same_v) + binId = lt.getGlobalBinByBin(dim1Bin, (dim2Bin % T::type::nRows)); + // get the size of this bin + size_t binSize = lt[binId].size(); + + // loop over all hits in this bin + for (unsigned int j = 0; j < binSize; j++) { + unsigned int otherId = lt[binId][j]; + float dist = distance2(lt, i, otherId, layerId); + bool foundHigher = + (cellsOnLayer.rho[otherId] > cellsOnLayer.rho[i]) || + (cellsOnLayer.rho[otherId] == cellsOnLayer.rho[i] && cellsOnLayer.detid[otherId] > cellsOnLayer.detid[i]); + if (!foundHigher) { + continue; + } + if ((dist < i_delta) || ((dist == i_delta) && (cellsOnLayer.rho[otherId] > rho_max)) || + ((dist == i_delta) && (cellsOnLayer.rho[otherId] == rho_max) && + (cellsOnLayer.detid[otherId] > cellsOnLayer.detid[i]))) { + rho_max = cellsOnLayer.rho[otherId]; + i_delta = dist; + i_nearestHigher = otherId; + } + } } + } + bool foundNearestHigherInSearchBox = (i_delta != maxDelta); + if (foundNearestHigherInSearchBox) { + cellsOnLayer.delta[i] = std::sqrt(i_delta); + cellsOnLayer.nearestHigher[i] = i_nearestHigher; + } else { + // otherwise delta is guaranteed to be larger outlierDeltaFactor_*delta_c + // we can safely maximize delta to be maxDelta + cellsOnLayer.delta[i] = maxDelta; + cellsOnLayer.nearestHigher[i] = -1; + } + + LogDebug("HGCalCLUEAlgo") << "Debugging calculateDistanceToHigher: \n" + << " cell: " << i << " eta: " << cellsOnLayer.dim1[i] << " phi: " << cellsOnLayer.dim2[i] + << " energy: " << cellsOnLayer.weight[i] << " density: " << cellsOnLayer.rho[i] + << " nearest higher: " << cellsOnLayer.nearestHigher[i] + << " distance: " << cellsOnLayer.delta[i] << "\n"; + } +} + +template +int HGCalCLUEAlgoT::findAndAssignClusters(const unsigned int layerId, float delta) { + // this is called once per layer and endcap... + // so when filling the cluster temporary vector of Hexels we resize each time + // by the number of clusters found. This is always equal to the number of + // cluster centers... + unsigned int nClustersOnLayer = 0; + auto& cellsOnLayer = cells_[layerId]; + unsigned int numberOfCells = cellsOnLayer.detid.size(); + std::vector localStack; + // find cluster seeds and outlier + for (unsigned int i = 0; i < numberOfCells; i++) { + float rho_c = kappa_ * cellsOnLayer.sigmaNoise[i]; + // initialize clusterIndex + cellsOnLayer.clusterIndex[i] = -1; + bool isSeed = (cellsOnLayer.delta[i] > delta) && (cellsOnLayer.rho[i] >= rho_c); + bool isOutlier = (cellsOnLayer.delta[i] > outlierDeltaFactor_ * delta) && (cellsOnLayer.rho[i] < rho_c); + if (isSeed) { + cellsOnLayer.clusterIndex[i] = nClustersOnLayer; + cellsOnLayer.isSeed[i] = true; + nClustersOnLayer++; + localStack.push_back(i); + + } else if (!isOutlier) { + assert(cellsOnLayer.nearestHigher[i] != -1); + assert(cellsOnLayer.nearestHigher[i] < static_cast(cellsOnLayer.followers.size())); + cellsOnLayer.followers[cellsOnLayer.nearestHigher[i]].push_back(i); + } + } + + // need to pass clusterIndex to their followers + while (!localStack.empty()) { + int endStack = localStack.back(); + auto& thisSeed = cellsOnLayer.followers[endStack]; + localStack.pop_back(); - auto globalClusterIndex = cl + offsets[layerId]; - auto &layer_clusters_view = clusters_and_associations.layer_clusters->view(); - layer_clusters_view.position().x()[globalClusterIndex] = x; - layer_clusters_view.position().y()[globalClusterIndex] = y; - layer_clusters_view.position().z()[globalClusterIndex] = z; - layer_clusters_view.position().cells()[globalClusterIndex] = clusters.count(cl); - layer_clusters_view.energy().energy()[globalClusterIndex] = energy; - layer_clusters_view.energy().correctedEnergy()[globalClusterIndex] = -1.f; - layer_clusters_view.energy().correctedEnergyUncertainty()[globalClusterIndex] = -1.f; - layer_clusters_view.indexes().caloID()[globalClusterIndex] = reco::CaloID::DET_HGCAL_ENDCAP; - layer_clusters_view.indexes().algoID()[globalClusterIndex] = algoId_; - // TODO: do we really care about the seed? - // layer_clusters.view().indexes().seedID()[globalClusterIndex] = seedDetId; - layer_clusters_view.indexes().flags()[globalClusterIndex] = 0; + // loop over followers + for (int j : thisSeed) { + // pass id to a follower + cellsOnLayer.clusterIndex[j] = cellsOnLayer.clusterIndex[endStack]; + // push this follower to localStack + localStack.push_back(j); } } - alpaka_serial_sync::Queue queue(cms::alpakatools::host()); - ticl::associator::fill( - queue, - clusters_and_associations.hits_and_fractions->view(), - static_cast>(cluster_hit_associations), - static_cast>(detid_and_fractions)); - - return clusters_and_associations; + return nClustersOnLayer; } template @@ -229,10 +460,10 @@ void HGCalCLUEAlgoT::computeThreshold() { // To support the TDR geometry and also the post-TDR one (v9 onwards), we // need to change the logic of the vectors containing signal to noise and // thresholds. The first 3 indices will keep on addressing the different - // thicknesses of the Silicon detectors in CE_E , the next 3 indices will - // address the thicknesses of the Silicon detectors in CE_H, while the last - // one, number 6 (the seventh) will address the Scintillators. This change - // will support both geometries at the same time. + // thicknesses of the Silicon detectors in CE_E , the next 3 indices will address + // the thicknesses of the Silicon detectors in CE_H, while the last one, number 6 (the + // seventh) will address the Scintillators. This change will support both + // geometries at the same time. if (initialized_) return; // only need to calculate thresholds once @@ -241,8 +472,7 @@ void HGCalCLUEAlgoT::computeThreshold() { std::vector dummy; - dummy.resize(maxNumberOfThickIndices_ + !isNose_, - 0); // +1 to accomodate for the Scintillators + dummy.resize(maxNumberOfThickIndices_ + !isNose_, 0); // +1 to accomodate for the Scintillators thresholds_.resize(maxlayer_, dummy); v_sigmaNoise_.resize(maxlayer_, dummy); diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h index 9a378f70cd813..c31bf4ccfba95 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalCLUEAlgo.h @@ -5,11 +5,9 @@ #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" -#include "DataFormats/TICL/interface/CaloClusterHostCollection.h" #include "DataFormats/DetId/interface/DetId.h" #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h" #include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h" -#include "DataFormats/TICL/interface/AssociationMap.h" #include "Geometry/CaloTopology/interface/HGCalTopology.h" #include "Geometry/HGCalGeometry/interface/HGCalGeometry.h" #include "Geometry/Records/interface/CaloGeometryRecord.h" @@ -20,7 +18,6 @@ #include "RecoLocalCalo/HGCalRecProducers/interface/HGCalLayerTiles.h" #include "RecoLocalCalo/HGCalRecProducers/interface/HGCalCLUEStrategy.h" -#include "RecoLocalCalo/HGCalRecProducers/interface/LayerClusterAndAssociations.h" #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" @@ -76,8 +73,7 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { void makeClusters() override; // this is the method to get the cluster collection out - std::vector getClustersLegacy(bool) override; - ticl::LayerClustersAndAssociations getClusters(bool) override; + std::vector getClusters(bool) override; void reset() override { clusters_v_.clear(); @@ -130,7 +126,7 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { } /// point in the space - using Point = math::XYZPoint; + typedef math::XYZPoint Point; private: // The two parameters used to identify clusters @@ -168,10 +164,16 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { std::vector detid; std::vector dim1; std::vector dim2; + std::vector weight; - std::vector sigmaNoise; - std::vector clusterIndex; + std::vector rho; + std::vector delta; + std::vector nearestHigher; + std::vector clusterIndex; + std::vector sigmaNoise; + std::vector> followers; + std::vector isSeed; float layerDim3 = std::numeric_limits::infinity(); void clear() { @@ -179,6 +181,13 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { dim1.clear(); dim2.clear(); weight.clear(); + rho.clear(); + delta.clear(); + nearestHigher.clear(); + clusterIndex.clear(); + sigmaNoise.clear(); + followers.clear(); + isSeed.clear(); } void shrink_to_fit() { @@ -186,6 +195,13 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { dim1.shrink_to_fit(); dim2.shrink_to_fit(); weight.shrink_to_fit(); + rho.shrink_to_fit(); + delta.shrink_to_fit(); + nearestHigher.shrink_to_fit(); + clusterIndex.shrink_to_fit(); + sigmaNoise.shrink_to_fit(); + followers.shrink_to_fit(); + isSeed.shrink_to_fit(); } }; @@ -196,6 +212,31 @@ class HGCalCLUEAlgoT : public HGCalClusteringAlgoBase { #if DEBUG_CLUSTERS_ALPAKA std::string moduleType_; #endif + + inline float distance2(const TILE& lt, int cell1, int cell2, int layerId) const { // 2-d distance on the layer (x-y) + return (lt.distance2(cells_[layerId].dim1[cell1], + cells_[layerId].dim2[cell1], + cells_[layerId].dim1[cell2], + cells_[layerId].dim2[cell2])); + } + + inline float distance(const TILE& lt, int cell1, int cell2, int layerId) const { // 2-d distance on the layer (x-y) + return std::sqrt(lt.distance2(cells_[layerId].dim1[cell1], + cells_[layerId].dim2[cell1], + cells_[layerId].dim1[cell2], + cells_[layerId].dim2[cell2])); + } + + void prepareDataStructures(const unsigned int layerId); + void calculateLocalDensity(const TILE& lt, const unsigned int layerId, + float delta); // return max density + void calculateLocalDensity(const TILE& lt, const unsigned int layerId, float delta, HGCalSiliconStrategy strategy); + void calculateLocalDensity(const TILE& lt, + const unsigned int layerId, + float delta, + HGCalScintillatorStrategy strategy); + void calculateDistanceToHigher(const TILE& lt, const unsigned int layerId, float delta); + int findAndAssignClusters(const unsigned int layerId, float delta); }; // explicit template instantiation diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc index c1a77364ddd3c..ec577067837e0 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/HGCalLayerClusterProducer.cc @@ -9,15 +9,12 @@ #include "FWCore/Framework/interface/stream/EDProducer.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" -#include "FWCore/Framework/interface/ConsumesCollector.h" #include "FWCore/Framework/interface/Event.h" #include "FWCore/Framework/interface/ESHandle.h" #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" #include "FWCore/ParameterSet/interface/ParameterSetDescription.h" #include "FWCore/ParameterSet/interface/PluginDescription.h" -#include "HeterogeneousCore/AlpakaInterface/interface/host.h" - #include "RecoParticleFlow/PFClusterProducer/interface/RecHitTopologicalCleanerBase.h" #include "RecoParticleFlow/PFClusterProducer/interface/SeedFinderBase.h" #include "RecoParticleFlow/PFClusterProducer/interface/InitialClusteringStepBase.h" @@ -33,9 +30,10 @@ #include "Geometry/HGCalGeometry/interface/HGCalGeometry.h" #include "DataFormats/ParticleFlowReco/interface/PFCluster.h" -#include "DataFormats/Common/interface/ValueMap.h" #include "DataFormats/TICL/interface/CaloClusterHostCollection.h" -#include "DataFormats/TICL/interface/AssociationMap.h" +#include "DataFormats/Common/interface/ValueMap.h" + +#include "FWCore/Framework/interface/ConsumesCollector.h" #if DEBUG_CLUSTERS_ALPAKA #include "RecoLocalCalo/HGCalRecProducers/interface/DumpClustersDetails.h" @@ -93,6 +91,16 @@ class HGCalLayerClusterProducer : public edm::stream::EDProducer<> { */ void setAlgoId(); + /** + * @brief Counts position for all points in the cluster + * + * @param[in] hitmap hitmap to find correct RecHit + * @param[in] hitsAndFraction all hits in the cluster + * @return counted position + */ + math::XYZPoint calculatePosition(std::unordered_map& hitmap, + const std::vector>& hitsAndFractions); + /** * @brief Counts time for all points in the cluster * @@ -100,9 +108,9 @@ class HGCalLayerClusterProducer : public edm::stream::EDProducer<> { * @param[in] hitsAndFraction all hits in the cluster * @return counted time */ - void calculateTime(std::unordered_map& hitmap, - reco::CaloClusterHostCollection::View layerClusters, - ticl::HitsAndFractionsHost::ConstView hitsAndFractions); + std::pair calculateTime(std::unordered_map& hitmap, + const std::vector>& hitsAndFractions, + size_t sizeCluster); }; HGCalLayerClusterProducer::HGCalLayerClusterProducer(const edm::ParameterSet& ps) @@ -130,10 +138,10 @@ HGCalLayerClusterProducer::HGCalLayerClusterProducer(const edm::ParameterSet& ps positionDeltaRho2_ = pluginPSet.getParameter("positionDeltaRho2"); produces>("InitialLayerClustersMask"); - produces(); - // produces>(); + produces>(); //time for layer clusters - // produces>>(timeClname_); + produces(); + produces>>(timeClname_); } void HGCalLayerClusterProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { @@ -151,37 +159,91 @@ void HGCalLayerClusterProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions.add("hgcalLayerClusters", desc); } -void HGCalLayerClusterProducer::calculateTime(std::unordered_map& hitmap, - reco::CaloClusterHostCollection::View layerClusters, - ticl::HitsAndFractionsHost::ConstView hitsAndFractions) { - for (auto cluster = 0; cluster < hitsAndFractions.keys(); ++cluster) { - std::pair timeCl(-99., -1.); - - if (hitsAndFractions.count(cluster) >= static_cast(hitsTime_)) { - std::vector timeClhits; - std::vector timeErrorClhits; - - for (auto const& hitAndFraction : hitsAndFractions[cluster]) { - //time is computed wrt 0-25ns + offset and set to -1 if no time - const HGCRecHit* rechit = hitmap[hitAndFraction.hit]; - - float rhTimeE = rechit->timeError(); - //check on timeError to exclude scintillator - if (rhTimeE < 0.f) - continue; - timeClhits.push_back(rechit->time()); - timeErrorClhits.push_back(1.f / (rhTimeE * rhTimeE)); - } - hgcalsimclustertime::ComputeClusterTime timeEstimator; - timeCl = timeEstimator.fixSizeHighestDensity(timeClhits, timeErrorClhits, hitsTime_); +math::XYZPoint HGCalLayerClusterProducer::calculatePosition( + std::unordered_map& hitmap, + const std::vector>& hitsAndFractions) { + float total_weight = 0.f; + float maxEnergyValue = 0.f; + DetId maxEnergyIndex; + float x = 0.f; + float y = 0.f; + + for (auto const& hit : hitsAndFractions) { + //time is computed wrt 0-25ns + offset and set to -1 if no time + const HGCRecHit* rechit = hitmap[hit.first]; + total_weight += rechit->energy(); + if (rechit->energy() > maxEnergyValue) { + maxEnergyValue = rechit->energy(); + maxEnergyIndex = rechit->detid(); + } + } + float total_weight_log = 0.f; + auto thick = rhtools_.getSiThickIndex(maxEnergyIndex); + const GlobalPoint positionMaxEnergy(rhtools_.getPosition(maxEnergyIndex)); + for (auto const& hit : hitsAndFractions) { + //time is computed wrt 0-25ns + offset and set to -1 if no time + const HGCRecHit* rechit = hitmap[hit.first]; + + const GlobalPoint position(rhtools_.getPosition(rechit->detid())); + + if (thick != -1) { //silicon + //for silicon only just use 1+6 cells = 1.3cm for all thicknesses + const float d1 = position.x() - positionMaxEnergy.x(); + const float d2 = position.y() - positionMaxEnergy.y(); + if ((d1 * d1 + d2 * d2) > positionDeltaRho2_) + continue; + + float Wi = std::max(thresholdW0_[thick] + std::log(rechit->energy() / total_weight), 0.); + x += position.x() * Wi; + y += position.y() * Wi; + total_weight_log += Wi; + } else { //scintillator + x += position.x() * rechit->energy(); + y += position.y() * rechit->energy(); } - layerClusters.timing()[cluster].time() = timeCl.first; - layerClusters.timing()[cluster].timeError() = timeCl.second; } + if (thick != -1) { + total_weight = total_weight_log; + } + if (total_weight != 0.) { + float inv_tot_weight = 1.f / total_weight; + return math::XYZPoint(x * inv_tot_weight, y * inv_tot_weight, positionMaxEnergy.z()); + } else { + return {positionMaxEnergy.x(), positionMaxEnergy.y(), positionMaxEnergy.z()}; + } +} + +std::pair HGCalLayerClusterProducer::calculateTime( + std::unordered_map& hitmap, + const std::vector>& hitsAndFractions, + size_t sizeCluster) { + std::pair timeCl(-99., -1.); + + if (sizeCluster >= hitsTime_) { + std::vector timeClhits; + std::vector timeErrorClhits; + + for (auto const& hit : hitsAndFractions) { + //time is computed wrt 0-25ns + offset and set to -1 if no time + const HGCRecHit* rechit = hitmap[hit.first]; + + float rhTimeE = rechit->timeError(); + //check on timeError to exclude scintillator + if (rhTimeE < 0.f) + continue; + timeClhits.push_back(rechit->time()); + timeErrorClhits.push_back(1.f / (rhTimeE * rhTimeE)); + } + hgcalsimclustertime::ComputeClusterTime timeEstimator; + timeCl = timeEstimator.fixSizeHighestDensity(timeClhits, timeErrorClhits, hitsTime_); + } + return timeCl; } void HGCalLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& es) { edm::Handle hits; + std::unique_ptr> clusters(new std::vector); + edm::ESHandle geom = es.getHandle(caloGeomToken_); rhtools_.setGeometry(*geom); algo_->getEventSetup(es, rhtools_); @@ -198,23 +260,22 @@ void HGCalLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& } algo_->makeClusters(); - - auto clusters_and_associations = algo_->getClusters(false); - auto clusters = std::move(clusters_and_associations.layer_clusters); - auto hits_and_fractions = std::move(clusters_and_associations.hits_and_fractions); + *clusters = algo_->getClusters(false); std::vector> times; - times.reserve(clusters->view().position().metadata().size()); - - calculateTime(hitmap, clusters->view(), hits_and_fractions->view()); - // for (unsigned i = 0; i < legacy_clusters->size(); ++i) { - // reco::CaloCluster& sCl = (*legacy_clusters)[i]; - // if (detector_ != "BH") { - // times.push_back(calculateTime(hitmap, sCl.hitsAndFractions(), sCl.size())); - // } else { - // times.push_back(std::pair(-99.f, -1.f)); - // } - // } + times.reserve(clusters->size()); + + for (unsigned i = 0; i < clusters->size(); ++i) { + reco::CaloCluster& sCl = (*clusters)[i]; + if (!calculatePositionInAlgo_) { + sCl.setPosition(calculatePosition(hitmap, sCl.hitsAndFractions())); + } + if (detector_ != "BH") { + times.push_back(calculateTime(hitmap, sCl.hitsAndFractions(), sCl.size())); + } else { + times.push_back(std::pair(-99.f, -1.f)); + } + } #if DEBUG_CLUSTERS_ALPAKA hgcalUtils::DumpClusters dumper; @@ -222,23 +283,25 @@ void HGCalLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& auto lumiNumber = evt.eventAuxiliary().luminosityBlock(); auto evtNumber = evt.eventAuxiliary().id().event(); - dumper.dumpInfos(*legacy_clusters, moduleLabel_, runNumber, lumiNumber, evtNumber, true); + dumper.dumpInfos(*clusters, moduleLabel_, runNumber, lumiNumber, evtNumber, true); #endif + auto clusterHandle = evt.put(std::move(clusters)); + auto empty_clusters = std::make_unique(cms::alpakatools::host(), 0, 0, 0, 0); + + evt.put(std::move(empty_clusters)); + if (detector_ == "HFNose") { std::unique_ptr> layerClustersMask(new std::vector); - layerClustersMask->resize(clusters->view().position().metadata().size(), 1.0); + layerClustersMask->resize(clusterHandle->size(), 1.0); evt.put(std::move(layerClustersMask), "InitialLayerClustersMask"); } - // auto timeCl = std::make_unique>>(); - // edm::ValueMap>::Filler filler(*timeCl); - // filler.insert(*legacy_clusters, times.begin(), times.end()); - // filler.fill(); - // evt.put(std::move(timeCl), timeClname_); - - evt.put(std::move(clusters)); - evt.put(std::move(hits_and_fractions)); + auto timeCl = std::make_unique>>(); + edm::ValueMap>::Filler filler(*timeCl); + filler.insert(clusterHandle, times.begin(), times.end()); + filler.fill(); + evt.put(std::move(timeCl), timeClname_); algo_->reset(); } diff --git a/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.cc b/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.cc index 1642332f15f25..4d56d9d30f80f 100644 --- a/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.cc +++ b/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.cc @@ -98,12 +98,7 @@ void BarrelCLUEAlgoT::makeClusters() { } template -ticl::LayerClustersAndAssociations BarrelCLUEAlgoT::getClusters(bool) { - return ticl::LayerClustersAndAssociations(1, 1); -} - -template -std::vector BarrelCLUEAlgoT::getClustersLegacy(bool) { +std::vector BarrelCLUEAlgoT::getClusters(bool) { std::vector offsets(numberOfClustersPerLayer_.size(), 0); int maxClustersOnLayer = numberOfClustersPerLayer_[0]; diff --git a/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.h b/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.h index 362b7a7975441..58d91130a012a 100644 --- a/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.h +++ b/RecoParticleFlow/PFClusterProducer/plugins/BarrelCLUEAlgo.h @@ -17,7 +17,6 @@ #include "DataFormats/Math/interface/deltaPhi.h" #include "RecoLocalCalo/HGCalRecProducers/interface/HGCalLayerTiles.h" -#include "RecoLocalCalo/HGCalRecProducers/interface/LayerClusterAndAssociations.h" #include "RecoLocalCalo/HGCalRecAlgos/interface/RecHitTools.h" @@ -60,8 +59,7 @@ class BarrelCLUEAlgoT : public HGCalClusteringAlgoBase { void makeClusters() override; // this is the method to get the cluster collection out - ticl::LayerClustersAndAssociations getClusters(bool) override; - std::vector getClustersLegacy(bool) override; + std::vector getClusters(bool) override; void reset() override { clusters_v_.clear(); diff --git a/RecoParticleFlow/PFClusterProducer/plugins/BarrelLayerClusterProducer.cc b/RecoParticleFlow/PFClusterProducer/plugins/BarrelLayerClusterProducer.cc index c3d205ee5cfa7..4f7267a870a25 100644 --- a/RecoParticleFlow/PFClusterProducer/plugins/BarrelLayerClusterProducer.cc +++ b/RecoParticleFlow/PFClusterProducer/plugins/BarrelLayerClusterProducer.cc @@ -129,7 +129,7 @@ void BarrelLayerClusterProducer::produce(edm::Event& evt, const edm::EventSetup& algo_->makeClusters(); std::unique_ptr> clusters(new std::vector); - *clusters = algo_->getClustersLegacy(false); + *clusters = algo_->getClusters(false); auto clusterHandle = evt.put(std::move(clusters)); edm::PtrVector clusterPtrs; //, clusterPtrsSharing; From efebe87dfd484cc22d876d95ebdd79d613ca6700 Mon Sep 17 00:00:00 2001 From: Wahid Redjeb Date: Fri, 27 Mar 2026 04:45:09 +0100 Subject: [PATCH 24/24] code-checks --- .../plugins/alpaka/MergedLayerClusterProducer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/MergedLayerClusterProducer.cc b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/MergedLayerClusterProducer.cc index f817b2cf5f39c..11b417b3b028f 100644 --- a/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/MergedLayerClusterProducer.cc +++ b/RecoLocalCalo/HGCalRecProducers/plugins/alpaka/MergedLayerClusterProducer.cc @@ -31,7 +31,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { device_layer_cluster_tokens_.push_back(consumes(tag)); } } - ~MergedLayerClustersProducer() = default; + ~MergedLayerClustersProducer() override = default; static void fillDescription(edm::ConfigurationDescriptions& description) { edm::ParameterSetDescription desc;