2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
5 #include "AthenaMonitoringKernel/Monitored.h"
6 #include "xAODInDetMeasurement/ContainerAccessor.h"
7 #include "ActsInterop/TableUtils.h"
11 template <typename IClusteringTool, bool useCache>
12 ClusterizationAlg<IClusteringTool, useCache>::ClusterizationAlg(const std::string& name,
13 ISvcLocator* pSvcLocator)
14 : AthReentrantAlgorithm(name, pSvcLocator)
17 template <typename IClusteringTool, bool useCache>
18 StatusCode ClusterizationAlg<IClusteringTool, useCache>::initialize()
20 ATH_MSG_DEBUG("Initializing " << name() << " ...");
22 ATH_CHECK(m_rdoContainerKey.initialize());
23 ATH_CHECK(m_clusterContainerKey.initialize());
24 ATH_CHECK(m_roiCollectionKey.initialize());
26 ATH_CHECK(m_detEleCollKey.initialize());
27 ATH_CHECK(m_detElStatus.initialize());
29 ATH_CHECK(m_clusteringTool.retrieve());
30 ATH_CHECK(m_regionSelector.retrieve());
32 ATH_CHECK(detStore()->retrieve(m_idHelper, m_idHelperName));
35 ATH_CHECK(m_monTool.retrieve(EnableTool{not m_monTool.empty()}));
38 ATH_CHECK(m_ClusterCache.initialize(useCache));
39 ATH_CHECK(m_ClusterCacheBackend.initialize(useCache));
41 return StatusCode::SUCCESS;
44 template <typename IClusteringTool, bool useCache>
45 StatusCode ClusterizationAlg<IClusteringTool, useCache>::finalize()
47 ATH_MSG_INFO("Clusterization statistics" << std::endl << makeTable(m_stat,
48 std::array<std::string, kNStat>{
53 return StatusCode::SUCCESS;
56 template <typename IClusteringTool, bool useCache>
57 StatusCode ClusterizationAlg<IClusteringTool, useCache>::execute(const EventContext& ctx) const
59 auto timer = Monitored::Timer<std::chrono::milliseconds>( "TIME_execute" );
60 auto mon_nclusters = Monitored::Scalar<int>("NClustersCreated");
61 auto mon = Monitored::Group( m_monTool, timer, mon_nclusters );
63 SG::ReadHandle<RDOContainer> rdoContainerHandle = SG::makeHandle(m_rdoContainerKey, ctx);
64 ATH_CHECK(rdoContainerHandle.isValid());
65 const RDOContainer* rdoContainer = rdoContainerHandle.cptr();
67 SG::ReadHandle<TrigRoiDescriptorCollection> roiCollectionHandle = SG::makeHandle( m_roiCollectionKey, ctx );
68 ATH_CHECK(roiCollectionHandle.isValid());
69 const TrigRoiDescriptorCollection *roiCollection = roiCollectionHandle.cptr();
71 SG::ReadCondHandle< InDetDD::SiDetectorElementCollection > detEleHandle = SG::makeHandle( m_detEleCollKey, ctx );
72 ATH_CHECK(detEleHandle.isValid());
73 const InDetDD::SiDetectorElementCollection* elements = detEleHandle.cptr();
75 SG::ReadHandle< InDet::SiDetectorElementStatus > detEleStatusHandle = SG::makeHandle(m_detElStatus, ctx);
76 ATH_CHECK(detEleStatusHandle.isValid());
77 const InDet::SiDetectorElementStatus* detEleStatus = detEleStatusHandle.cptr();
79 Cache_WriteHandle cacheHandle;
80 if constexpr (useCache) {
81 cacheHandle = Cache_WriteHandle(m_ClusterCache, ctx);
82 auto updateHandle = Cache_BackendUpdateHandle(m_ClusterCacheBackend, ctx);
83 ATH_CHECK(updateHandle.isValid());
84 ATH_CHECK(cacheHandle.record(std::make_unique<Cache_IDC>(updateHandle.ptr())));
85 ATH_CHECK(cacheHandle.isValid());
88 // count number of elements and store some collections
89 std::vector<IdentifierHash> listOfIds;
90 listOfIds.reserve(elements->size());
92 std::vector<bool> toBeProcessedIds(elements->size(), false);
94 std::vector<const InDetDD::SiDetectorElement*> processedElements {};
95 processedElements.reserve(elements->size());
96 std::vector<typename IClusteringTool::ClusterCollection> clusterCollection {};
97 clusterCollection.reserve(elements->size());
99 std::vector<Cache_IDCLock> idclocks;
101 Acts::Ccl::ClusteringData data;
104 std::size_t nClusters = 0ul;
105 for (const auto* roi : *roiCollection) {
108 m_regionSelector->lookup(ctx)->HashIDList(*roi, listOfIds);
111 for (const IdentifierHash& id : listOfIds) {
112 if (not id.is_valid()) {
113 ATH_MSG_ERROR("Id hash is not valid: " << id);
114 return StatusCode::FAILURE;
117 // check if already considered
118 if (toBeProcessedIds[id]) continue;
119 toBeProcessedIds[id] = true;
121 Cache_IDCLock cache_wh;
122 if constexpr (useCache) {
123 //obtain a write handle
124 auto tmp = cacheHandle->getWriteHandle(id);
125 Cache_IDCLock::Swap(cache_wh, tmp);
126 //check if already available
127 if(cache_wh.OnlineAndPresentInAnotherView()) continue;
130 const InDetDD::SiDetectorElement* element = elements->getDetectorElement(id);
132 ATH_MSG_ERROR("Cannot retrieve Detector Element for id hash: " << id);
133 return StatusCode::FAILURE;
136 // unpack RDOs and store them
137 const RawDataCollection* rdos = rdoContainer->indexFindPtr(id);
138 if (not rdos or rdos->empty()) {
142 if constexpr (useCache) {
143 idclocks.push_back( std::move(cache_wh) );
146 m_stat[kNRdo] += rdos->size();
147 // make ACTS clusters
148 ATH_CHECK( m_clusteringTool->clusterize(ctx,
153 clusterCollection) );
154 processedElements.push_back( element );
155 nClusters += clusterCollection.back().size();
159 mon_nclusters = nClusters;
161 SG::WriteHandle<ClusterContainer> clusterHandle = SG::makeHandle(m_clusterContainerKey, ctx);
162 ATH_CHECK(clusterHandle.record( std::make_unique<ClusterContainer>(),
163 std::make_unique<ClusterAuxContainer>() ));
164 ClusterContainer *clusterContainer = clusterHandle.ptr();
166 // Fast Insertion of N elements
167 using xAODCluster_t = typename ClusterContainer::base_value_type;
168 std::vector<xAODCluster_t*> toAddCollection;
169 toAddCollection.reserve(nClusters);
170 for (std::size_t i(0); i<nClusters; ++i)
171 toAddCollection.push_back(new xAODCluster_t());
172 clusterContainer->insert(clusterContainer->end(),
173 toAddCollection.begin(),
174 toAddCollection.end());
176 // Fill the collection to xAOD format, computing necessary quantities
177 std::size_t xaodCounter = 0ul;
178 typename ClusterContainer::iterator finalElement = clusterContainer->end();
179 for (std::size_t i(0); i<clusterCollection.size(); ++i) {
180 const InDetDD::SiDetectorElement* element = processedElements[i];
181 typename IClusteringTool::ClusterCollection& actsClusters = clusterCollection[i];
183 typename ClusterContainer::iterator itr = clusterContainer->begin() + xaodCounter;
184 if ( std::distance(itr, finalElement) < static_cast<long int>(actsClusters.size()) ) {
185 ATH_MSG_ERROR("Inconsistent size of clusters");
186 return StatusCode::FAILURE;
189 ATH_CHECK( m_clusteringTool->makeClusters(ctx,
194 if constexpr (useCache) {
196 ATH_CHECK(Cache::Helper<BaseClusterType>::insert(idclocks[i],
199 xaodCounter + actsClusters.size()));
202 xaodCounter += actsClusters.size();
205 m_stat[kNClusters] += clusterContainer->size();
206 ATH_MSG_DEBUG("Clusters produced size: "<<clusterContainer->size());
207 return StatusCode::SUCCESS;
210 } // namespace ActsTrk