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