ATLAS Offline Software
Loading...
Searching...
No Matches
PixelSpacePointFormationAlgBase.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 "InDetReadoutGeometry/SiDetectorElement.h"
6#include "PixelReadoutGeometry/PixelModuleDesign.h"
7
8#include "xAODInDetMeasurement/PixelClusterAuxContainer.h"
9
10#include "AthenaMonitoringKernel/Monitored.h"
11#include "ActsInterop/TableUtils.h"
12
13#include <optional>
14
15namespace ActsTrk {
16
17 //------------------------------------------------------------------------
18 template <bool useCache>
19 PixelSpacePointFormationAlgBase<useCache>::PixelSpacePointFormationAlgBase(const std::string& name,
20 ISvcLocator* pSvcLocator)
21 : AthReentrantAlgorithm(name, pSvcLocator)
22 {}
23
24 //-----------------------------------------------------------------------
25 template <bool useCache>
26 StatusCode PixelSpacePointFormationAlgBase<useCache>::initialize()
27 {
28 ATH_MSG_DEBUG( "Initializing " << name() << " ... " );
29
30 ATH_CHECK( m_pixelClusterContainerKey.initialize() );
31 ATH_CHECK( m_pixelSpacePointContainerKey.initialize() );
32 ATH_CHECK( m_pixelDetEleCollKey.initialize() );
33 ATH_CHECK( m_spacePointMakerTool.retrieve() );
34
35 if ( not m_monTool.empty() )
36 ATH_CHECK( m_monTool.retrieve() );
37
38 //caching
39 ATH_CHECK(m_SPCache.initialize(useCache));
40 ATH_CHECK(m_SPCacheBackend.initialize(useCache));
41
42 return StatusCode::SUCCESS;
43 }
44
45 template <bool useCache>
46 StatusCode PixelSpacePointFormationAlgBase<useCache>::finalize()
47 {
48 ATH_MSG_INFO("Space Point Formation statistics" << std::endl << makeTable(m_stat,
49 std::array<std::string, kNStat>{
50 "Clusters",
51 "Space Points"
52 }).columnWidth(10));
53
54 return StatusCode::SUCCESS;
55 }
56
57 //-------------------------------------------------------------------------
58 template <bool useCache>
59 StatusCode PixelSpacePointFormationAlgBase<useCache>::execute (const EventContext& ctx) const
60 {
61 auto timer = Monitored::Timer<std::chrono::milliseconds>( "TIME_execute" );
62 auto nReceivedSPsPixel = Monitored::Scalar<int>( "numPixSpacePoints" , 0 );
63 auto mon = Monitored::Group( m_monTool, timer, nReceivedSPsPixel );
64
65 SG::ReadHandle<xAOD::PixelClusterContainer> inputPixelClusterContainer( m_pixelClusterContainerKey, ctx );
66 if (!inputPixelClusterContainer.isValid()){
67 ATH_MSG_FATAL("xAOD::PixelClusterContainer with key " << m_pixelClusterContainerKey.key() << " is not available...");
68 return StatusCode::FAILURE;
69 }
70 const xAOD::PixelClusterContainer *pixelClusters = inputPixelClusterContainer.cptr();
71 ATH_MSG_DEBUG("Retrieved " << pixelClusters->size() << " clusters from container " << m_pixelClusterContainerKey.key());
72 m_stat[kNClusters] += pixelClusters->size();
73
74 auto pixelSpacePointContainer = SG::WriteHandle<xAOD::SpacePointContainer>( m_pixelSpacePointContainerKey, ctx );
75 ATH_MSG_DEBUG( "--- Pixel Space Point Container `" << m_pixelSpacePointContainerKey.key() << "` created ..." );
76 ATH_CHECK(pixelSpacePointContainer.record( std::make_unique<xAOD::SpacePointContainer>(),
77 std::make_unique<xAOD::SpacePointAuxContainer>() ));
78 xAOD::SpacePointContainer *pixelSpacePoints = pixelSpacePointContainer.ptr();
79
80 Cache_WriteHandle cacheHandle;
81 if constexpr (useCache) {
82 cacheHandle = Cache_WriteHandle(m_SPCache, ctx);
83 auto updateHandle = Cache_BackendUpdateHandle(m_SPCacheBackend, ctx);
84 ATH_CHECK(updateHandle.isValid());
85 ATH_CHECK(cacheHandle.record(std::make_unique<Cache_IDC>(updateHandle.ptr())));
86 ATH_CHECK(cacheHandle.isValid());
87 }
88
89 // Reserve space
90 pixelSpacePoints->reserve(pixelClusters->size());
91
92 // Early exit in case we have no clusters
93 // We still are saving an empty space point container in SG
94 if (pixelClusters->empty()) {
95 ATH_MSG_DEBUG("No input clusters found, we stop space point formation");
96 return StatusCode::SUCCESS;
97 }
98
99 SG::ReadCondHandle<InDetDD::SiDetectorElementCollection> pixelDetEleHandle(m_pixelDetEleCollKey, ctx);
100 const InDetDD::SiDetectorElementCollection* pixelElements(*pixelDetEleHandle);
101 if (not pixelDetEleHandle.isValid() or pixelElements==nullptr) {
102 ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " is not available.");
103 return StatusCode::FAILURE;
104 }
105
106 // insertion of big collections
107 pixelSpacePoints->push_new(pixelClusters->size(), [] () {return new xAOD::SpacePoint();});
108
109 std::map<IdentifierHash, std::vector<std::pair<unsigned int, unsigned int>>> cache_ranges;
110 int groupStartIdx = 0;
111 std::optional<IdentifierHash> groupIdHash = std::nullopt;
112
113 //when using the cache some clusters can be skipped, this results in discontinuous spacepoints (but the unpopulated SP still exists and is getting filled into the cache and the output container)
114 //need to track the index of the spacepoints which are being inserted, so they are continuous and so that the output collection can be trimmed
115 unsigned int spIdx = 0;
116
117 for(unsigned int idx=0; idx<pixelClusters->size(); idx++){
118 const xAOD::PixelCluster* cluster = pixelClusters->at(idx);
119 IdentifierHash idHash = cluster->identifierHash();
120 if constexpr(useCache){
121 //check if the idHash is already in the cache
122 if(cacheHandle->tryAddFromCache(idHash)) continue;
123 }
124
125 const InDetDD::SiDetectorElement* pixelElement = pixelElements->getDetectorElement(idHash);
126 if (pixelElement == nullptr) {
127 ATH_MSG_FATAL("Element pointer is nullptr");
128 return StatusCode::FAILURE;
129 }
130
131 //get the index of the output spacepoint, when not using the cache this should be equal to the cluster index
132 unsigned int thisSpIdx = spIdx++;
133
134 ATH_CHECK( m_spacePointMakerTool->producePixelSpacePoint(*cluster,
135 *pixelSpacePoints->at(thisSpIdx),
136 *pixelElement ) );
137
138 if constexpr(useCache){
139 //check if the groupIdHash is defined if so and if it has changed then insert the range into the map
140 if(groupIdHash && ((*groupIdHash) != idHash)){
141 cache_ranges[(*groupIdHash)].emplace_back(groupStartIdx, thisSpIdx);
142 groupStartIdx = thisSpIdx;
143 }
144
145 groupIdHash = idHash;
146 }
147 }
148
149 //handle final idHash
150 if constexpr(useCache){
151 if(groupIdHash){
152 cache_ranges[(*groupIdHash)].emplace_back(groupStartIdx, spIdx);
153 }
154 }
155
156 //finally resize the output for the actual number of inserted spacepoints
157 pixelSpacePoints->resize(spIdx);
158
159
160 if constexpr(useCache){
161 //add the ranges to the cache
162 for(auto idr: cache_ranges){
163 auto wh = cacheHandle->getWriteHandle(idr.first);
164 //check that item is not in the cache already (again)
165 if(wh.OnlineAndPresentInAnotherView()) continue;
166 auto ce = std::make_unique<Cache::CacheEntry<xAOD::SpacePoint>>(pixelSpacePoints, idr.second);
167 ATH_CHECK(wh.addOrDelete(std::move(ce)));
168 }
169 }
170
171 nReceivedSPsPixel = pixelSpacePointContainer->size();
172 m_stat[kNSpacePoints] += nReceivedSPsPixel;
173 return StatusCode::SUCCESS;
174 }
175
176} //namespace