ATLAS Offline Software
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 
8 namespace 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