2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
5#include "xAODInDetMeasurement/ContainerAccessor.h"
6#include "AthenaMonitoringKernel/MonitoredTimer.h"
10 template <typename external_collection_t,
11 typename external_detector_element_collection_t,
13 DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::DataPreparationAlg(const std::string& name,
14 ISvcLocator* pSvcLocator)
15 : AthReentrantAlgorithm(name, pSvcLocator)
18 template <typename external_collection_t,
19 typename external_detector_element_collection_t,
21 StatusCode DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::initialize()
23 ATH_MSG_INFO("Initializing " << name() << " ...");
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()));
37 ATH_CHECK(m_monTool.retrieve(EnableTool{not m_monTool.empty()}));
38 ATH_CHECK(m_regionSelector.retrieve(EnableTool{not m_regionSelector.empty()}));
40 return StatusCode::SUCCESS;
43 template <typename external_collection_t,
44 typename external_detector_element_collection_t,
46 StatusCode DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::finalize()
48 ATH_MSG_INFO("Data Prep statistics" << std::endl << makeTable(m_stat,
49 std::array<std::string, kNStat>{
54 return StatusCode::SUCCESS;
57 template <typename external_collection_t,
58 typename external_detector_element_collection_t,
61 DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::execute(const EventContext& ctx) const
63 ATH_MSG_DEBUG("Executing " << name() << " ...");
64 auto timer = Monitored::Timer<std::chrono::milliseconds>( "TIME_execute" );
65 auto mon = Monitored::Group( m_monTool, timer );
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();
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;
79 template <typename external_collection_t,
80 typename external_detector_element_collection_t,
83 DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::fill(const EventContext& ctx,
84 output_collection_t& outputCollection) const
86 ATH_MSG_DEBUG("Filling output collection from container");
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.");
95 if (inputCollection->size() == 0) {
96 return StatusCode::SUCCESS;
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());
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();
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();
123 // Get the list of id hashes from the RoI
124 std::set<IdentifierHash> hashes;
125 ATH_CHECK( fetchIdHashes( ctx, hashes ) );
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)) {
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) {
141 if constexpr (not std::is_same<object_t, xAOD::SpacePoint >::value) {
142 if ( inputPrdMap and inputPrdMap->isUsed((*firstElement)->identifier()) ) {
147 // a space point is unusable if ANY of its measurements (two
148 // clusters for strip space points) was consumed by a previous pass
151 for (const xAOD::UncalibratedMeasurement* meas : (*firstElement)->measurements()) {
152 if ( inputPrdMap->isUsed(meas->identifier()) ) {
163 outputCollection.push_back(*firstElement);
168 ATH_MSG_VERBOSE("Rejected: " << nRejected);
170 return StatusCode::SUCCESS;
173 template <typename external_collection_t,
174 typename external_detector_element_collection_t,
177 DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::fill(const EventContext& ctx,
178 output_collection_t& outputCollection) const
179 requires (useCache == true)
181 ATH_MSG_DEBUG("Filling output collection from cache");
184 ATH_MSG_DEBUG("Retrieving Identifiable Container with key `" << m_inputIdentifiableContainer.key() << "`");
185 cache_read_handle_t cacheHandle = SG::makeHandle( m_inputIdentifiableContainer, ctx );
186 ATH_CHECK( cacheHandle.isValid() );
188 const ActsTrk::PrepRawDataAssociation *inputPrdMap = nullptr;
189 if (not m_inputPrdMap.empty()) {
190 ATH_MSG_DEBUG("Retrieving Prd map from previous Acts Tracking Pass with key: " << m_inputPrdMap.key());
191 SG::ReadHandle< ActsTrk::PrepRawDataAssociation > inputPrdMapHandle = SG::makeHandle( m_inputPrdMap, ctx );
192 ATH_CHECK( inputPrdMapHandle.isValid() );
193 inputPrdMap = inputPrdMapHandle.cptr();
194 ATH_MSG_DEBUG(" \\__ Number of already used measurement from previous passes: " << inputPrdMap->size());
197 std::set<IdentifierHash> hashes;
198 ATH_CHECK( fetchIdHashes( ctx, hashes ) );
201 for(auto idHash: hashes) {
202 //this function will wait if an item is not available
203 auto ce = cacheHandle->indexFindPtr(idHash);
204 if(ce == nullptr) continue;
205 for(auto rng: ce->ranges){
206 if(rng.first == rng.second) continue;
207 m_stat[kNInputs] += rng.second - rng.first;
208 for(unsigned int i = rng.first; i < rng.second; i++){
210 // Check the measurement has not been used previously
211 if constexpr (not std::is_same<object_t, xAOD::SpacePoint >::value) {
212 if ( inputPrdMap and inputPrdMap->isUsed(ce->container->at(i)->identifier()) ) {
217 // a space point is unusable if ANY of its measurements (two
218 // clusters for strip space points) was consumed by a previous pass
221 for (const xAOD::UncalibratedMeasurement* meas : ce->container->at(i)->measurements()) {
222 if ( inputPrdMap->isUsed(meas->identifier()) ) {
234 outputCollection.push_back(ce->container->at(i));
239 ATH_MSG_VERBOSE("Rejected: " << nRejected);
241 return StatusCode::SUCCESS;
244 template <typename external_collection_t,
245 typename external_detector_element_collection_t,
248 DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::fetchIdHashes(const EventContext& ctx,
249 std::set<IdentifierHash>& hashes) const
251 // Check Regional Selection Tool is enabled
252 if ( m_regionSelector.empty() ) {
253 ATH_MSG_ERROR("Regional Selector Tool must be enabled in order to fetch the id hashes!");
254 return StatusCode::FAILURE;
257 ATH_MSG_DEBUG("Retrieving RoIs with key `" << m_roiCollectionKey.key() << "`");
258 SG::ReadHandle< TrigRoiDescriptorCollection > roiHandle = SG::makeHandle( m_roiCollectionKey, ctx );
259 ATH_CHECK(roiHandle.isValid());
260 const TrigRoiDescriptorCollection* roiCollection = roiHandle.cptr();
262 std::vector<IdentifierHash> listOfIds;
263 for (const auto* roi : *roiCollection) {
265 m_regionSelector->lookup(ctx)->HashIDList(*roi, listOfIds);
266 hashes.insert(listOfIds.begin(), listOfIds.end());
269 return StatusCode::SUCCESS;
272 template <typename external_collection_t,
273 typename external_detector_element_collection_t,
275 inline xAOD::DetectorIDHashType
276 DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::retrieveDetectorIDHash(const object_t&) const