ATLAS Offline Software
Loading...
Searching...
No Matches
ClusterizationAlg.icc
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4#include "AthenaMonitoringKernel/Monitored.h"
5#include "xAODInDetMeasurement/ContainerAccessor.h"
6#include "ActsInterop/TableUtils.h"
7#include "AthAllocators/DataPool.h"
8#include "RDOCollectionAdapter.h"
9
10namespace ActsTrk {
11
12template <typename IClusteringTool, bool useCache>
13ClusterizationAlg<IClusteringTool, useCache>::ClusterizationAlg(const std::string& name,
14 ISvcLocator* pSvcLocator)
15 : AthReentrantAlgorithm(name, pSvcLocator)
16{}
17
18template <typename IClusteringTool, bool useCache>
19StatusCode ClusterizationAlg<IClusteringTool, useCache>::initialize()
20{
21 ATH_MSG_DEBUG("Initializing " << name() << " ...");
22
23 ATH_CHECK(m_rdoContainerKey.initialize());
24 ATH_CHECK(m_clusterContainerKey.initialize());
25 ATH_CHECK(m_roiCollectionKey.initialize());
26
27 ATH_CHECK(m_detEleCollKey.initialize());
28 ATH_CHECK(m_detElStatus.initialize());
29
30 ATH_CHECK(m_clusteringTool.retrieve());
31 ATH_CHECK(m_regionSelector.retrieve());
32
33 ATH_CHECK(detStore()->retrieve(m_idHelper, m_idHelperName));
34
35 // Monitoring
36 ATH_CHECK(m_monTool.retrieve(EnableTool{not m_monTool.empty()}));
37
38 //caching
39 ATH_CHECK(m_ClusterCache.initialize(useCache));
40 ATH_CHECK(m_ClusterCacheBackend.initialize(useCache));
41
42 return StatusCode::SUCCESS;
43}
44
45template <typename IClusteringTool, bool useCache>
46StatusCode ClusterizationAlg<IClusteringTool, useCache>::finalize()
47{
48 ATH_MSG_INFO("Clusterization statistics" << std::endl << makeTable(m_stat,
49 std::array<std::string, kNStat>{
50 "RDOs",
51 "Clusters"
52 }).columnWidth(10));
53
54 return StatusCode::SUCCESS;
55}
56
57template <typename IClusteringTool, bool useCache>
58StatusCode ClusterizationAlg<IClusteringTool, useCache>::execute(const EventContext& ctx) const
59{
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 );
65
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();
71
72 SG::ReadHandle<TrigRoiDescriptorCollection> roiCollectionHandle = SG::makeHandle( m_roiCollectionKey, ctx );
73 ATH_CHECK(roiCollectionHandle.isValid());
74 const TrigRoiDescriptorCollection *roiCollection = roiCollectionHandle.cptr();
75
76 SG::ReadCondHandle< InDetDD::SiDetectorElementCollection > detEleHandle = SG::makeHandle( m_detEleCollKey, ctx );
77 ATH_CHECK(detEleHandle.isValid());
78 const InDetDD::SiDetectorElementCollection* elements = detEleHandle.cptr();
79
80 SG::ReadHandle< InDet::SiDetectorElementStatus > detEleStatusHandle = SG::makeHandle(m_detElStatus, ctx);
81 ATH_CHECK(detEleStatusHandle.isValid());
82 const InDet::SiDetectorElementStatus* detEleStatus = detEleStatusHandle.cptr();
83
84 timer_processing.start();
85
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());
93 }
94
95 // count number of elements and store some collections
96 std::vector<IdentifierHash> listOfIds;
97 listOfIds.reserve(elements->size());
98
99 std::vector<bool> toBeProcessedIds(elements->size(), false);
100
101 std::vector<Cache_IDCLock> idclocks;
102
103 unsigned int n_rdos_total=0u;
104 unsigned int n_cluster_total=0u;
105 unsigned int n_modules=0u;
106 // numbers not double counting corrected.
107 // So, in case of large overlap of ROIs, will overallocate
108 // the temporary cluster collection
109 for (const auto* roi : *roiCollection) {
110 // get list of ids
111 listOfIds.clear();
112 m_regionSelector->lookup(ctx)->HashIDList(*roi, listOfIds);
113 auto [roi_n_cluster, roi_n_rdos] = m_clusteringTool->countCells(*rdoContainer, listOfIds,*elements );
114 n_cluster_total += roi_n_cluster;
115 n_rdos_total += roi_n_rdos;
116 n_modules += listOfIds.size();
117 }
118
119 typename IClusteringTool::CellContainer cellContainer(n_modules, n_cluster_total, n_rdos_total);
120
121 // loop on ROIs
122 unsigned int nRDOs = 0u;
123 std::size_t nClusters = 0ul;
124 // if the roiCollection is larger than one than listOfIds does not contain the correct
125 // HashIDList and the lists have to be requested again.
126 bool request_id_list_again = roiCollection->size()!=1;
127 for (const auto* roi : *roiCollection) {
128 // get list of ids
129 // if the roi collection contains a single element listOfIds
130 // already contains the result
131 if (request_id_list_again) {
132 listOfIds.clear();
133 m_regionSelector->lookup(ctx)->HashIDList(*roi, listOfIds);
134 }
135
136 // loop on IDs
137 for (const IdentifierHash& id : listOfIds) {
138 if (not id.is_valid()) {
139 ATH_MSG_ERROR("Id hash is not valid: " << id);
140 return StatusCode::FAILURE;
141 }
142
143 // check if already considered
144 if (toBeProcessedIds[id]) continue;
145 toBeProcessedIds[id] = true;
146
147 Cache_IDCLock cache_wh;
148 if constexpr (useCache) {
149 //obtain a write handle
150 auto tmp = cacheHandle->getWriteHandle(id);
151 Cache_IDCLock::Swap(cache_wh, tmp);
152 //check if already available
153 if(cache_wh.OnlineAndPresentInAnotherView()) continue;
154 }
155
156 const InDetDD::SiDetectorElement* element = elements->getDetectorElement(id);
157 if (not element) {
158 ATH_MSG_ERROR("Cannot retrieve Detector Element for id hash: " << id);
159 return StatusCode::FAILURE;
160 }
161
162 // unpack RDOs and store them
163 std::optional<RDOCollectionAdapter<RDOContainer> > optional_RDOs = RDOCollectionAdapter<RDOContainer>::make(*rdoContainer,id);
164 if (not optional_RDOs or optional_RDOs.value()->empty()) {
165 continue;
166 }
167 RDOCollectionAdapter<RDOContainer> RDOs=optional_RDOs.value();
168
169 if constexpr (useCache) {
170 idclocks.push_back( std::move(cache_wh) );
171 }
172 // make ACTS clusters
173 ATH_CHECK( m_clusteringTool->clusterize(ctx,
174 *RDOs,
175 *detEleStatus,
176 *element,
177 cellContainer) );
178 nRDOs+=RDOs->size();
179 nClusters += cellContainer.m_moduleClusterRange.back().nClusters();
180 } // loop on IDs
181 } // loop on ROIs
182
183 mon_nclusters = nClusters;
184
185 SG::WriteHandle<ClusterContainer> clusterHandle = SG::makeHandle(m_clusterContainerKey, ctx);
186 ATH_CHECK(clusterHandle.record( std::make_unique<ClusterContainer>(SG::VIEW_ELEMENTS, SG::ALWAYS_TRACK_INDICES),
187 std::make_unique<ClusterAuxContainer>() ));
188 ClusterContainer *clusterContainer = clusterHandle.ptr();
189
190 using xAODCluster_t = typename ClusterContainer::base_value_type;
191 DataPool<xAODCluster_t> pool (nClusters);
192 clusterContainer->push_new(nClusters, [&pool]() {return pool.nextElementPtr();});
193
194 std::any cache = m_clusteringTool->createEventDataCache (*clusterHandle,cellContainer.nCellsTotal());
195
196 // Fill the collection to xAOD format, computing necessary quantities
197 std::size_t xaodCounter = 0ul;
198 for (std::size_t i(0); i<cellContainer.size(); ++i) {
199 const InDetDD::SiDetectorElement* element = elements->getDetectorElement(cellContainer.moduleClusterRange(i).idHash);
200
201 ATH_CHECK( m_clusteringTool->makeClusters(ctx,
202 *rdoContainer,
203 cellContainer,
204 i,
205 *element,
206 xaodCounter,
207 *clusterContainer,
208 cache) );
209 assert( i < cellContainer.nModules() ) ;
210 unsigned int n_new_clusters=cellContainer.moduleClusterRange(i).nClusters();
211 if constexpr (useCache) {
212 ATH_CHECK(Cache::Helper<BaseClusterType>::insert(idclocks[i],
213 clusterContainer,
214 xaodCounter,
215 xaodCounter + n_new_clusters));
216 }
217 xaodCounter+=n_new_clusters;
218 }
219
220 m_stat[kNRdo] += nRDOs;
221 m_stat[kNClusters] += clusterContainer->size();
222 ATH_MSG_DEBUG("Clusters produced size: "<<clusterContainer->size());
223 timer_processing.stop();
224 return StatusCode::SUCCESS;
225}
226
227} // namespace ActsTrk