ATLAS Offline Software
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 
9 namespace ActsTrk {
10 
11 template <typename IClusteringTool, bool useCache>
12 ClusterizationAlg<IClusteringTool, useCache>::ClusterizationAlg(const std::string& name,
13  ISvcLocator* pSvcLocator)
14  : AthReentrantAlgorithm(name, pSvcLocator)
15 {}
16 
17 template <typename IClusteringTool, bool useCache>
18 StatusCode 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_clusteringTool.retrieve());
27  ATH_CHECK(m_regionSelector.retrieve());
28 
29  ATH_CHECK(detStore()->retrieve(m_idHelper, m_idHelperName));
30 
31  // Monitoring
32  ATH_CHECK(m_monTool.retrieve(EnableTool{not m_monTool.empty()}));
33 
34  //caching
35  ATH_CHECK(m_ClusterCache.initialize(useCache));
36  ATH_CHECK(m_ClusterCacheBackend.initialize(useCache));
37 
38  return StatusCode::SUCCESS;
39 }
40 
41 template <typename IClusteringTool, bool useCache>
42 StatusCode ClusterizationAlg<IClusteringTool, useCache>::finalize()
43 {
44  ATH_MSG_INFO("Clusterization statistics" << std::endl << makeTable(m_stat,
45  std::array<std::string, kNStat>{
46  "RDOs",
47  "Clusters"
48  }).columnWidth(10));
49 
50  return StatusCode::SUCCESS;
51 }
52 
53 template <typename IClusteringTool, bool useCache>
54 StatusCode ClusterizationAlg<IClusteringTool, useCache>::execute(const EventContext& ctx) const
55 {
56  auto timer = Monitored::Timer<std::chrono::milliseconds>( "TIME_execute" );
57  auto mon_nclusters = Monitored::Scalar<int>("NClustersCreated");
58  auto mon = Monitored::Group( m_monTool, timer, mon_nclusters );
59 
60  Cache_WriteHandle cacheHandle;
61  if constexpr (useCache) {
62  cacheHandle = Cache_WriteHandle(m_ClusterCache, ctx);
63  auto updateHandle = Cache_BackendUpdateHandle(m_ClusterCacheBackend, ctx);
64  ATH_CHECK(updateHandle.isValid());
65  ATH_CHECK(cacheHandle.record(std::make_unique<Cache_IDC>(updateHandle.ptr())));
66  ATH_CHECK(cacheHandle.isValid());
67  }
68 
69  SG::ReadHandle<RDOContainer> rdoContainer = SG::makeHandle(m_rdoContainerKey, ctx);
70  ATH_CHECK(rdoContainer.isValid());
71 
72  SG::WriteHandle<ClusterContainer> clusterHandle = SG::makeHandle(m_clusterContainerKey, ctx);
73  ATH_CHECK(clusterHandle.record( std::make_unique<ClusterContainer>(),
74  std::make_unique<ClusterAuxContainer>() ));
75  ClusterContainer *clusterContainer = clusterHandle.ptr();
76  // Reserve space, estimate of mean clusters to reduce re-allocations
77  clusterContainer->reserve( m_expectedClustersPerRDO.value() * rdoContainer->size() );
78 
79 
80 
81  // retrieve the RoI as provided from upstream algos
82  SG::ReadHandle<TrigRoiDescriptorCollection> roiCollectionHandle = SG::makeHandle( m_roiCollectionKey, ctx );
83  ATH_CHECK(roiCollectionHandle.isValid());
84  const TrigRoiDescriptorCollection *roiCollection = roiCollectionHandle.cptr();
85 
86  // Get list of Hash Ids from the RoI
87  std::vector<IdentifierHash> listOfIds;
88  for (const auto* roi : *roiCollection) {
89  listOfIds.clear();
90  m_regionSelector->HashIDList(*roi, listOfIds);
91  // We'd need to first check the id hashes have not already been processed beforehand, and only then
92  // add it to the list of ids to be processed.
93  for (const IdentifierHash id : listOfIds) {
94  //obtain the write handle directly when we decide to process a given idhash
95  //this will ensure that proper waiting
96  Cache_IDCLock cache_wh;
97  if constexpr (useCache) {
98  //obtain a write handle
99  auto tmp = cacheHandle->getWriteHandle(id);
100  Cache_IDCLock::Swap(cache_wh, tmp);
101  //check if already available
102  if(cache_wh.OnlineAndPresentInAnotherView()) continue;
103  }
104 
105  auto prev_len = clusterContainer->size();
106 
107  // If not already processed, do it now
108  const RawDataCollection* rdos = rdoContainer->indexFindPtr(id);
109  if (rdos != nullptr && !rdos->empty()) {
110  m_stat[kNRdo] += rdos->size();
111  ATH_CHECK(m_clusteringTool->clusterize(*rdos, *m_idHelper, ctx,*clusterContainer));
112  }
113 
114  if constexpr (useCache) {
115  //add to the cache
116  ATH_CHECK(Cache::Helper<BaseClusterType>::insert(cache_wh, clusterContainer, prev_len, clusterContainer->size()));
117  }
118  } // loop on ids
119  } // loop on rois
120  mon_nclusters = clusterContainer->size();
121 
122  m_stat[kNClusters] += clusterContainer->size();
123  ATH_MSG_DEBUG("Clusters produced size: "<<clusterContainer->size());
124  return StatusCode::SUCCESS;
125 }
126 
127 
128 } // namespace ActsTrk