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