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