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 if ( inputPrdMap and inputPrdMap->isUsed((*firstElement)->measurements()[0]->identifier()) ) {
152 outputCollection.push_back(*firstElement);
157 ATH_MSG_VERBOSE("Rejected: " << nRejected);
159 return StatusCode::SUCCESS;
162 template <typename external_collection_t,
163 typename external_detector_element_collection_t,
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)
170 ATH_MSG_DEBUG("Filling output collection from cache");
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() );
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());
186 std::set<IdentifierHash> hashes;
187 ATH_CHECK( fetchIdHashes( ctx, hashes ) );
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++){
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()) ) {
206 if ( inputPrdMap and inputPrdMap->isUsed(ce->container->at(i)->measurements()[0]->identifier()) ) {
212 outputCollection.push_back(ce->container->at(i));
217 ATH_MSG_VERBOSE("Rejected: " << nRejected);
219 return StatusCode::SUCCESS;
222 template <typename external_collection_t,
223 typename external_detector_element_collection_t,
226 DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::fetchIdHashes(const EventContext& ctx,
227 std::set<IdentifierHash>& hashes) const
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;
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();
240 std::vector<IdentifierHash> listOfIds;
241 for (const auto* roi : *roiCollection) {
243 m_regionSelector->lookup(ctx)->HashIDList(*roi, listOfIds);
244 hashes.insert(listOfIds.begin(), listOfIds.end());
247 return StatusCode::SUCCESS;
250 template <typename external_collection_t,
251 typename external_detector_element_collection_t,
253 inline xAOD::DetectorIDHashType
254 DataPreparationAlg<external_collection_t, external_detector_element_collection_t, useCache>::retrieveDetectorIDHash(const object_t&) const