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
5#include "AthenaMonitoringKernel/Monitored.h"
6#include "xAODInDetMeasurement/ContainerAccessor.h"
7#include "ActsInterop/TableUtils.h"
8#include "AthAllocators/DataPool.h"
9
10namespace {
11 template <typename T>
12 concept has_nRDOs = requires (T &&a) { a.nRDOs(); };
13}
14
15namespace ActsTrk {
16
17template <typename IClusteringTool, bool useCache>
18ClusterizationAlg<IClusteringTool, useCache>::ClusterizationAlg(const std::string& name,
19 ISvcLocator* pSvcLocator)
20 : AthReentrantAlgorithm(name, pSvcLocator)
21{}
22
23template <typename IClusteringTool, bool useCache>
24StatusCode ClusterizationAlg<IClusteringTool, useCache>::initialize()
25{
26 ATH_MSG_DEBUG("Initializing " << name() << " ...");
27
28 ATH_CHECK(m_rdoContainerKey.initialize());
29 ATH_CHECK(m_clusterContainerKey.initialize());
30 ATH_CHECK(m_roiCollectionKey.initialize());
31
32 ATH_CHECK(m_detEleCollKey.initialize());
33 ATH_CHECK(m_detElStatus.initialize());
34
35 ATH_CHECK(m_clusteringTool.retrieve());
36 ATH_CHECK(m_regionSelector.retrieve());
37
38 ATH_CHECK(detStore()->retrieve(m_idHelper, m_idHelperName));
39
40 // Monitoring
41 ATH_CHECK(m_monTool.retrieve(EnableTool{not m_monTool.empty()}));
42
43 //caching
44 ATH_CHECK(m_ClusterCache.initialize(useCache));
45 ATH_CHECK(m_ClusterCacheBackend.initialize(useCache));
46
47 return StatusCode::SUCCESS;
48}
49
50template <typename IClusteringTool, bool useCache>
51StatusCode ClusterizationAlg<IClusteringTool, useCache>::finalize()
52{
53 ATH_MSG_INFO("Clusterization statistics" << std::endl << makeTable(m_stat,
54 std::array<std::string, kNStat>{
55 "RDOs",
56 "Clusters"
57 }).columnWidth(10));
58
59 return StatusCode::SUCCESS;
60}
61
62template <typename IClusteringTool, bool useCache>
63StatusCode ClusterizationAlg<IClusteringTool, useCache>::execute(const EventContext& ctx) const
64{
65 auto timer = Monitored::Timer<std::chrono::milliseconds>( "TIME_execute" );
66 auto timer_rdoReading = Monitored::Timer<std::chrono::milliseconds>( "TIME_readingRDOs" );
67 auto timer_processing = Monitored::Timer<std::chrono::milliseconds>( "TIME_clusterization" );
68 auto mon_nclusters = Monitored::Scalar<int>( "NClustersCreated" );
69 auto mon = Monitored::Group( m_monTool, timer, timer_rdoReading, timer_processing, mon_nclusters );
70
71 timer_rdoReading.start();
72 SG::ReadHandle<RDOContainer> rdoContainerHandle = SG::makeHandle(m_rdoContainerKey, ctx);
73 ATH_CHECK(rdoContainerHandle.isValid());
74 const RDOContainer* rdoContainer = rdoContainerHandle.cptr();
75 timer_rdoReading.stop();
76
77 SG::ReadHandle<TrigRoiDescriptorCollection> roiCollectionHandle = SG::makeHandle( m_roiCollectionKey, ctx );
78 ATH_CHECK(roiCollectionHandle.isValid());
79 const TrigRoiDescriptorCollection *roiCollection = roiCollectionHandle.cptr();
80
81 SG::ReadCondHandle< InDetDD::SiDetectorElementCollection > detEleHandle = SG::makeHandle( m_detEleCollKey, ctx );
82 ATH_CHECK(detEleHandle.isValid());
83 const InDetDD::SiDetectorElementCollection* elements = detEleHandle.cptr();
84
85 SG::ReadHandle< InDet::SiDetectorElementStatus > detEleStatusHandle = SG::makeHandle(m_detElStatus, ctx);
86 ATH_CHECK(detEleStatusHandle.isValid());
87 const InDet::SiDetectorElementStatus* detEleStatus = detEleStatusHandle.cptr();
88
89 timer_processing.start();
90
91 Cache_WriteHandle cacheHandle;
92 if constexpr (useCache) {
93 cacheHandle = Cache_WriteHandle(m_ClusterCache, ctx);
94 auto updateHandle = Cache_BackendUpdateHandle(m_ClusterCacheBackend, ctx);
95 ATH_CHECK(updateHandle.isValid());
96 ATH_CHECK(cacheHandle.record(std::make_unique<Cache_IDC>(updateHandle.ptr())));
97 ATH_CHECK(cacheHandle.isValid());
98 }
99
100 // count number of elements and store some collections
101 std::vector<IdentifierHash> listOfIds;
102 listOfIds.reserve(elements->size());
103
104 std::vector<bool> toBeProcessedIds(elements->size(), false);
105
106 std::vector<const InDetDD::SiDetectorElement*> processedElements {};
107 processedElements.reserve(elements->size());
108 std::vector<typename IClusteringTool::ClusterCollection> clusterCollection {};
109 clusterCollection.reserve(elements->size());
110
111 std::vector<Cache_IDCLock> idclocks;
112
113 Acts::Ccl::ClusteringData data;
114
115 // loop on ROIs
116 unsigned int nClusterRDOs=0u;
117 unsigned int nRDOs = 0u;
118 std::size_t nClusters = 0ul;
119 for (const auto* roi : *roiCollection) {
120 // get list of ids
121 listOfIds.clear();
122 m_regionSelector->lookup(ctx)->HashIDList(*roi, listOfIds);
123
124 // loop on IDs
125 for (const IdentifierHash& id : listOfIds) {
126 if (not id.is_valid()) {
127 ATH_MSG_ERROR("Id hash is not valid: " << id);
128 return StatusCode::FAILURE;
129 }
130
131 // check if already considered
132 if (toBeProcessedIds[id]) continue;
133 toBeProcessedIds[id] = true;
134
135 Cache_IDCLock cache_wh;
136 if constexpr (useCache) {
137 //obtain a write handle
138 auto tmp = cacheHandle->getWriteHandle(id);
139 Cache_IDCLock::Swap(cache_wh, tmp);
140 //check if already available
141 if(cache_wh.OnlineAndPresentInAnotherView()) continue;
142 }
143
144 const InDetDD::SiDetectorElement* element = elements->getDetectorElement(id);
145 if (not element) {
146 ATH_MSG_ERROR("Cannot retrieve Detector Element for id hash: " << id);
147 return StatusCode::FAILURE;
148 }
149
150 // unpack RDOs and store them
151 const RawDataCollection* rdos = rdoContainer->indexFindPtr(id);
152 if (not rdos or rdos->empty()) {
153 continue;
154 }
155
156 if constexpr (useCache) {
157 idclocks.push_back( std::move(cache_wh) );
158 }
159 // make ACTS clusters
160 ATH_CHECK( m_clusteringTool->clusterize(ctx,
161 *rdos,
162 *detEleStatus,
163 *element,
164 data,
165 clusterCollection) );
166 if constexpr(has_nRDOs<typename IClusteringTool::ClusterCollection>) {
167 nClusterRDOs+=clusterCollection.back().nRDOs();
168 }
169 else {
170 nClusterRDOs += rdos->size();
171 }
172 nRDOs+=rdos->size();
173
174 processedElements.push_back( element );
175 nClusters += clusterCollection.back().size();
176 } // loop on IDs
177 } // loop on ROIs
178
179 mon_nclusters = nClusters;
180
181 SG::WriteHandle<ClusterContainer> clusterHandle = SG::makeHandle(m_clusterContainerKey, ctx);
182 ATH_CHECK(clusterHandle.record( std::make_unique<ClusterContainer>(SG::VIEW_ELEMENTS, SG::ALWAYS_TRACK_INDICES),
183 std::make_unique<ClusterAuxContainer>() ));
184 ClusterContainer *clusterContainer = clusterHandle.ptr();
185
186 using xAODCluster_t = typename ClusterContainer::base_value_type;
187 DataPool<xAODCluster_t> pool (nClusters);
188 clusterContainer->push_new(nClusters, [&pool]() {return pool.nextElementPtr();});
189
190 std::any vars = m_clusteringTool->createEventDataCache (*clusterHandle, nClusterRDOs);
191
192 // Fill the collection to xAOD format, computing necessary quantities
193 std::size_t xaodCounter = 0ul;
194 typename ClusterContainer::iterator finalElement = clusterContainer->end();
195 for (std::size_t i(0); i<clusterCollection.size(); ++i) {
196 const InDetDD::SiDetectorElement* element = processedElements[i];
197 typename IClusteringTool::ClusterCollection& actsClusters = clusterCollection[i];
198
199 typename ClusterContainer::iterator itr = clusterContainer->begin() + xaodCounter;
200 if ( std::distance(itr, finalElement) < static_cast<long int>(actsClusters.size()) ) {
201 ATH_MSG_ERROR("Inconsistent size of clusters");
202 return StatusCode::FAILURE;
203 }
204
205 ATH_CHECK( m_clusteringTool->makeClusters(ctx,
206 actsClusters,
207 *element,
208 xaodCounter,
209 vars,
210 itr) );
211
212 if constexpr (useCache) {
213 // add to the cache
214 ATH_CHECK(Cache::Helper<BaseClusterType>::insert(idclocks[i],
215 clusterContainer,
216 xaodCounter,
217 xaodCounter + actsClusters.size()));
218 }
219
220 xaodCounter += actsClusters.size();
221 }
222
223 m_stat[kNRdo] += nRDOs;
224 m_stat[kNClusters] += clusterContainer->size();
225 ATH_MSG_DEBUG("Clusters produced size: "<<clusterContainer->size());
226 timer_processing.stop();
227 return StatusCode::SUCCESS;
228}
229
230} // namespace ActsTrk