ATLAS Offline Software
Loading...
Searching...
No Matches
DataPreparationAlg.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 "xAODInDetMeasurement/ContainerAccessor.h"
6#include "AthenaMonitoringKernel/MonitoredTimer.h"
7
8namespace ActsTrk {
9
10 template <typename external_collection_t,
11 typename external_detector_element_collection_t,
12 bool useCache>
13 DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::DataPreparationAlg(const std::string& name,
14 ISvcLocator* pSvcLocator)
15 : AthReentrantAlgorithm(name, pSvcLocator)
16 {}
17
18 template <typename external_collection_t,
19 typename external_detector_element_collection_t,
20 bool useCache>
21 StatusCode DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::initialize()
22 {
23 ATH_MSG_INFO("Initializing " << name() << " ...");
24
25 // Handles we always need
26 ATH_CHECK(m_outputCollectionKey.initialize());
27 ATH_CHECK(m_roiCollectionKey.initialize());
28 // Collections needed if we do not use the cache
29 ATH_CHECK(m_inputCollectionKey.initialize(not useCache));
30 ATH_CHECK(m_detEleCollKey.initialize(not useCache));
31 // Collections needed if we use the cache
32 ATH_CHECK(m_inputIdentifiableContainer.initialize(useCache));
33 // Prd Map from previous tracking pass
34 ATH_CHECK(m_inputPrdMap.initialize(not m_inputPrdMap.empty()));
35
36 // Tools
37 ATH_CHECK(m_monTool.retrieve(EnableTool{not m_monTool.empty()}));
38 ATH_CHECK(m_regionSelector.retrieve(EnableTool{not m_regionSelector.empty()}));
39
40 return StatusCode::SUCCESS;
41 }
42
43 template <typename external_collection_t,
44 typename external_detector_element_collection_t,
45 bool useCache>
46 StatusCode DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::finalize()
47 {
48 ATH_MSG_INFO("Data Prep statistics" << std::endl << makeTable(m_stat,
49 std::array<std::string, kNStat>{
50 "Inputs",
51 "Outputs"
52 }).columnWidth(10));
53
54 return StatusCode::SUCCESS;
55 }
56
57 template <typename external_collection_t,
58 typename external_detector_element_collection_t,
59 bool useCache>
60 StatusCode
61 DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::execute(const EventContext& ctx) const
62 {
63 ATH_MSG_DEBUG("Executing " << name() << " ...");
64 auto timer = Monitored::Timer<std::chrono::milliseconds>( "TIME_execute" );
65 auto mon = Monitored::Group( m_monTool, timer );
66
67
68 ATH_MSG_DEBUG("Writing output collection with key `" << m_outputCollectionKey.key() << "`");
69 SG::WriteHandle< output_collection_t > outputHandle = SG::makeHandle( m_outputCollectionKey, ctx );
70 ATH_CHECK( outputHandle.record( std::make_unique<output_collection_t>(SG::VIEW_ELEMENTS) ) );
71 output_collection_t *outputCollection = outputHandle.ptr();
72
73 ATH_CHECK( fill( ctx, *outputCollection ) );
74 m_stat[kNOutputs] += outputCollection->size();
75 ATH_MSG_DEBUG("Concluded creation of output collection with " << outputCollection->size() << " entries");
76 return StatusCode::SUCCESS;
77 }
78
79 template <typename external_collection_t,
80 typename external_detector_element_collection_t,
81 bool useCache>
82 StatusCode
83 DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::fill(const EventContext& ctx,
84 output_collection_t& outputCollection) const
85 {
86 ATH_MSG_DEBUG("Filling output collection from container");
87
88 // Inputs
89 ATH_MSG_DEBUG("Retrieving Input Collection with key `" << m_inputCollectionKey.key() << "`");
90 SG::ReadHandle< input_collection_t > inputHandle = SG::makeHandle( m_inputCollectionKey, ctx );
91 ATH_CHECK(inputHandle.isValid());
92 const input_collection_t* inputCollection = inputHandle.cptr();
93 ATH_MSG_DEBUG("Retrieved input collection with " << inputCollection->size() << " elements.");
94
95 if (inputCollection->size() == 0) {
96 return StatusCode::SUCCESS;
97 }
98
99 const ActsTrk::PrepRawDataAssociation *inputPrdMap = nullptr;
100 if (not m_inputPrdMap.empty()) {
101 ATH_MSG_DEBUG("Retrieving Prd map from previous Acts Tracking Pass with key: " << m_inputPrdMap.key());
102 SG::ReadHandle< ActsTrk::PrepRawDataAssociation > inputPrdMapHandle = SG::makeHandle( m_inputPrdMap, ctx );
103 ATH_CHECK( inputPrdMapHandle.isValid() );
104 inputPrdMap = inputPrdMapHandle.cptr();
105 ATH_MSG_DEBUG(" \\__ Number of already used measurement from previous passes: " << inputPrdMap->size());
106 }
107
108 ATH_MSG_DEBUG("Retrieving SiDetectorElementCollection with key `" << m_detEleCollKey.key() << "`");
109 SG::ReadCondHandle< external_detector_element_collection_t > detEleHandle = SG::makeHandle( m_detEleCollKey, ctx );
110 ATH_CHECK(detEleHandle.isValid());
111 const external_detector_element_collection_t* detElements = detEleHandle.cptr();
112
113 // Selection
114 // For the time being we simply insert data given the idHash
115 // Use the Container Accessor strategy
116 ContainerAccessor<object_t, IdentifierHash, 1>
117 accessor ( *inputCollection,
118 [this] (const object_t& coll) -> IdentifierHash
119 { return retrieveDetectorIDHash(coll); },
120 detElements->size());
121 m_stat[kNInputs] += inputCollection->size();
122
123 // Get the list of id hashes from the RoI
124 std::set<IdentifierHash> hashes;
125 ATH_CHECK( fetchIdHashes( ctx, hashes ) );
126
127 int nRejected = 0;
128 // Run on all the id hashes that overlap with the RoI
129 for (const IdentifierHash id : hashes) {
130 // If the requested idHash is not present move to the next one
131 // This should not happen for clusters, but may happen for strip space points
132 if (not accessor.isIdentifierPresent(id)) {
133 continue;
134 }
135
136 // Get the objects and add them to the output collection
137 const auto& ranges = accessor.rangesForIdentifierDirect(id);
138 for (auto [firstElement, lastElement] : ranges) {
139 for (; firstElement != lastElement; ++firstElement) {
140 // Check Prd Map
141 if constexpr (not std::is_same<object_t, xAOD::SpacePoint >::value) {
142 if ( inputPrdMap and inputPrdMap->isUsed((*firstElement)->identifier()) ) {
143 ++nRejected;
144 continue;
145 }
146 } else {
147 if ( inputPrdMap and inputPrdMap->isUsed((*firstElement)->measurements()[0]->identifier()) ) {
148 ++nRejected;
149 continue;
150 }
151 }
152 outputCollection.push_back(*firstElement);
153 }
154 }
155 }
156
157 ATH_MSG_VERBOSE("Rejected: " << nRejected);
158
159 return StatusCode::SUCCESS;
160 }
161
162 template <typename external_collection_t,
163 typename external_detector_element_collection_t,
164 bool useCache>
165 StatusCode
166 DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::fill(const EventContext& ctx,
167 output_collection_t& outputCollection) const
168 requires (useCache == true)
169 {
170 ATH_MSG_DEBUG("Filling output collection from cache");
171
172 // Inputs
173 ATH_MSG_DEBUG("Retrieving Identifiable Container with key `" << m_inputIdentifiableContainer.key() << "`");
174 cache_read_handle_t cacheHandle = SG::makeHandle( m_inputIdentifiableContainer, ctx );
175 ATH_CHECK( cacheHandle.isValid() );
176
177 const ActsTrk::PrepRawDataAssociation *inputPrdMap = nullptr;
178 if (not m_inputPrdMap.empty()) {
179 ATH_MSG_DEBUG("Retrieving Prd map from previous Acts Tracking Pass with key: " << m_inputPrdMap.key());
180 SG::ReadHandle< ActsTrk::PrepRawDataAssociation > inputPrdMapHandle = SG::makeHandle( m_inputPrdMap, ctx );
181 ATH_CHECK( inputPrdMapHandle.isValid() );
182 inputPrdMap = inputPrdMapHandle.cptr();
183 ATH_MSG_DEBUG(" \\__ Number of already used measurement from previous passes: " << inputPrdMap->size());
184 }
185
186 std::set<IdentifierHash> hashes;
187 ATH_CHECK( fetchIdHashes( ctx, hashes ) );
188
189 int nRejected = 0;
190 for(auto idHash: hashes) {
191 //this function will wait if an item is not available
192 auto ce = cacheHandle->indexFindPtr(idHash);
193 if(ce == nullptr) continue;
194 for(auto rng: ce->ranges){
195 if(rng.first == rng.second) continue;
196 m_stat[kNInputs] += rng.second - rng.first;
197 for(unsigned int i = rng.first; i < rng.second; i++){
198
199 // Check the measurement has not been used previously
200 if constexpr (not std::is_same<object_t, xAOD::SpacePoint >::value) {
201 if ( inputPrdMap and inputPrdMap->isUsed(ce->container->at(i)->identifier()) ) {
202 ++nRejected;
203 continue;
204 }
205 } else {
206 if ( inputPrdMap and inputPrdMap->isUsed(ce->container->at(i)->measurements()[0]->identifier()) ) {
207 ++nRejected;
208 continue;
209 }
210 }
211
212 outputCollection.push_back(ce->container->at(i));
213 }
214 }
215 }
216
217 ATH_MSG_VERBOSE("Rejected: " << nRejected);
218
219 return StatusCode::SUCCESS;
220 }
221
222 template <typename external_collection_t,
223 typename external_detector_element_collection_t,
224 bool useCache>
225 StatusCode
226 DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::fetchIdHashes(const EventContext& ctx,
227 std::set<IdentifierHash>& hashes) const
228 {
229 // Check Regional Selection Tool is enabled
230 if ( m_regionSelector.empty() ) {
231 ATH_MSG_ERROR("Regional Selector Tool must be enabled in order to fetch the id hashes!");
232 return StatusCode::FAILURE;
233 }
234
235 ATH_MSG_DEBUG("Retrieving RoIs with key `" << m_roiCollectionKey.key() << "`");
236 SG::ReadHandle< TrigRoiDescriptorCollection > roiHandle = SG::makeHandle( m_roiCollectionKey, ctx );
237 ATH_CHECK(roiHandle.isValid());
238 const TrigRoiDescriptorCollection* roiCollection = roiHandle.cptr();
239
240 std::vector<IdentifierHash> listOfIds;
241 for (const auto* roi : *roiCollection) {
242 listOfIds.clear();
243 m_regionSelector->lookup(ctx)->HashIDList(*roi, listOfIds);
244 hashes.insert(listOfIds.begin(), listOfIds.end());
245 }
246
247 return StatusCode::SUCCESS;
248 }
249
250 template <typename external_collection_t,
251 typename external_detector_element_collection_t,
252 bool useCache>
253 inline xAOD::DetectorIDHashType
254 DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::retrieveDetectorIDHash(const object_t&) const
255 { return 0; }
256
257} // namespace