2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
5#include "AthenaMonitoringKernel/Monitored.h"
6#include "xAODInDetMeasurement/ContainerAccessor.h"
7#include "ActsInterop/TableUtils.h"
8#include "AthAllocators/DataPool.h"
12template <typename IClusteringTool, bool useCache>
13ClusterizationAlg<IClusteringTool, useCache>::ClusterizationAlg(const std::string& name,
14 ISvcLocator* pSvcLocator)
15 : AthReentrantAlgorithm(name, pSvcLocator)
18template <typename IClusteringTool, bool useCache>
19StatusCode ClusterizationAlg<IClusteringTool, useCache>::initialize()
21 ATH_MSG_DEBUG("Initializing " << name() << " ...");
23 ATH_CHECK(m_rdoContainerKey.initialize());
24 ATH_CHECK(m_clusterContainerKey.initialize());
25 ATH_CHECK(m_roiCollectionKey.initialize());
27 ATH_CHECK(m_detEleCollKey.initialize());
28 ATH_CHECK(m_detElStatus.initialize());
30 ATH_CHECK(m_clusteringTool.retrieve());
31 ATH_CHECK(m_regionSelector.retrieve());
33 ATH_CHECK(detStore()->retrieve(m_idHelper, m_idHelperName));
36 ATH_CHECK(m_monTool.retrieve(EnableTool{not m_monTool.empty()}));
39 ATH_CHECK(m_ClusterCache.initialize(useCache));
40 ATH_CHECK(m_ClusterCacheBackend.initialize(useCache));
42 return StatusCode::SUCCESS;
45template <typename IClusteringTool, bool useCache>
46StatusCode ClusterizationAlg<IClusteringTool, useCache>::finalize()
48 ATH_MSG_INFO("Clusterization statistics" << std::endl << makeTable(m_stat,
49 std::array<std::string, kNStat>{
54 return StatusCode::SUCCESS;
57template <typename IClusteringTool, bool useCache>
58StatusCode ClusterizationAlg<IClusteringTool, useCache>::execute(const EventContext& ctx) const
60 auto timer = Monitored::Timer<std::chrono::milliseconds>( "TIME_execute" );
61 auto timer_rdoReading = Monitored::Timer<std::chrono::milliseconds>( "TIME_readingRDOs" );
62 auto timer_processing = Monitored::Timer<std::chrono::milliseconds>( "TIME_clusterization" );
63 auto mon_nclusters = Monitored::Scalar<int>( "NClustersCreated" );
64 auto mon = Monitored::Group( m_monTool, timer, timer_rdoReading, timer_processing, mon_nclusters );
66 timer_rdoReading.start();
67 SG::ReadHandle<RDOContainer> rdoContainerHandle = SG::makeHandle(m_rdoContainerKey, ctx);
68 ATH_CHECK(rdoContainerHandle.isValid());
69 const RDOContainer* rdoContainer = rdoContainerHandle.cptr();
70 timer_rdoReading.stop();
72 SG::ReadHandle<TrigRoiDescriptorCollection> roiCollectionHandle = SG::makeHandle( m_roiCollectionKey, ctx );
73 ATH_CHECK(roiCollectionHandle.isValid());
74 const TrigRoiDescriptorCollection *roiCollection = roiCollectionHandle.cptr();
76 SG::ReadCondHandle< InDetDD::SiDetectorElementCollection > detEleHandle = SG::makeHandle( m_detEleCollKey, ctx );
77 ATH_CHECK(detEleHandle.isValid());
78 const InDetDD::SiDetectorElementCollection* elements = detEleHandle.cptr();
80 SG::ReadHandle< InDet::SiDetectorElementStatus > detEleStatusHandle = SG::makeHandle(m_detElStatus, ctx);
81 ATH_CHECK(detEleStatusHandle.isValid());
82 const InDet::SiDetectorElementStatus* detEleStatus = detEleStatusHandle.cptr();
84 timer_processing.start();
86 Cache_WriteHandle cacheHandle;
87 if constexpr (useCache) {
88 cacheHandle = Cache_WriteHandle(m_ClusterCache, ctx);
89 auto updateHandle = Cache_BackendUpdateHandle(m_ClusterCacheBackend, ctx);
90 ATH_CHECK(updateHandle.isValid());
91 ATH_CHECK(cacheHandle.record(std::make_unique<Cache_IDC>(updateHandle.ptr())));
92 ATH_CHECK(cacheHandle.isValid());
95 // count number of elements and store some collections
96 std::vector<IdentifierHash> listOfIds;
97 listOfIds.reserve(elements->size());
99 std::vector<bool> toBeProcessedIds(elements->size(), false);
101 std::vector<const InDetDD::SiDetectorElement*> processedElements {};
102 processedElements.reserve(elements->size());
103 std::vector<typename IClusteringTool::ClusterCollection> clusterCollection {};
104 clusterCollection.reserve(elements->size());
106 std::vector<Cache_IDCLock> idclocks;
108 Acts::Ccl::ClusteringData data;
111 std::size_t nClusters = 0ul;
112 for (const auto* roi : *roiCollection) {
115 m_regionSelector->lookup(ctx)->HashIDList(*roi, listOfIds);
118 for (const IdentifierHash& id : listOfIds) {
119 if (not id.is_valid()) {
120 ATH_MSG_ERROR("Id hash is not valid: " << id);
121 return StatusCode::FAILURE;
124 // check if already considered
125 if (toBeProcessedIds[id]) continue;
126 toBeProcessedIds[id] = true;
128 Cache_IDCLock cache_wh;
129 if constexpr (useCache) {
130 //obtain a write handle
131 auto tmp = cacheHandle->getWriteHandle(id);
132 Cache_IDCLock::Swap(cache_wh, tmp);
133 //check if already available
134 if(cache_wh.OnlineAndPresentInAnotherView()) continue;
137 const InDetDD::SiDetectorElement* element = elements->getDetectorElement(id);
139 ATH_MSG_ERROR("Cannot retrieve Detector Element for id hash: " << id);
140 return StatusCode::FAILURE;
143 // unpack RDOs and store them
144 const RawDataCollection* rdos = rdoContainer->indexFindPtr(id);
145 if (not rdos or rdos->empty()) {
149 if constexpr (useCache) {
150 idclocks.push_back( std::move(cache_wh) );
153 m_stat[kNRdo] += rdos->size();
154 // make ACTS clusters
155 ATH_CHECK( m_clusteringTool->clusterize(ctx,
160 clusterCollection) );
161 processedElements.push_back( element );
162 nClusters += clusterCollection.back().size();
166 mon_nclusters = nClusters;
168 SG::WriteHandle<ClusterContainer> clusterHandle = SG::makeHandle(m_clusterContainerKey, ctx);
169 ATH_CHECK(clusterHandle.record( std::make_unique<ClusterContainer>(SG::VIEW_ELEMENTS, SG::ALWAYS_TRACK_INDICES),
170 std::make_unique<ClusterAuxContainer>() ));
171 ClusterContainer *clusterContainer = clusterHandle.ptr();
173 using xAODCluster_t = typename ClusterContainer::base_value_type;
174 DataPool<xAODCluster_t> pool (nClusters);
175 clusterContainer->push_new(nClusters, [&pool]() {return pool.nextElementPtr();});
177 // Fill the collection to xAOD format, computing necessary quantities
178 std::size_t xaodCounter = 0ul;
179 typename ClusterContainer::iterator finalElement = clusterContainer->end();
180 for (std::size_t i(0); i<clusterCollection.size(); ++i) {
181 const InDetDD::SiDetectorElement* element = processedElements[i];
182 typename IClusteringTool::ClusterCollection& actsClusters = clusterCollection[i];
184 typename ClusterContainer::iterator itr = clusterContainer->begin() + xaodCounter;
185 if ( std::distance(itr, finalElement) < static_cast<long int>(actsClusters.size()) ) {
186 ATH_MSG_ERROR("Inconsistent size of clusters");
187 return StatusCode::FAILURE;
190 ATH_CHECK( m_clusteringTool->makeClusters(ctx,
195 if constexpr (useCache) {
197 ATH_CHECK(Cache::Helper<BaseClusterType>::insert(idclocks[i],
200 xaodCounter + actsClusters.size()));
203 xaodCounter += actsClusters.size();
206 m_stat[kNClusters] += clusterContainer->size();
207 ATH_MSG_DEBUG("Clusters produced size: "<<clusterContainer->size());
208 timer_processing.stop();
209 return StatusCode::SUCCESS;
212} // namespace ActsTrk