ATLAS Offline Software
Loading...
Searching...
No Matches
GnnFeatures.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef ACTSGNN_DETAIL_GNNFEATURES_H
6#define ACTSGNN_DETAIL_GNNFEATURES_H
7
8#include <algorithm>
9#include <cstddef>
10#include <cstdint>
11#include <numbers>
12#include <numeric>
13#include <span>
14#include <vector>
15
16#include "Acts/Definitions/Algebra.hpp"
17#include "Acts/Utilities/VectorHelpers.hpp"
18#include "GaudiKernel/StatusCode.h"
19#include "Identifier/Identifier.h"
25
26#include "src/GnnPipelineTool.h"
27
28namespace ActsTrk::detail {
29
30inline int computeOverlapSpFlag(int etaModuleCl1, int phiModuleCl1,
31 int etaModuleCl2, int phiModuleCl2) {
32 if (etaModuleCl1 == etaModuleCl2 && phiModuleCl1 == phiModuleCl2) {
33 return 0; // not an overlap spacepoint
34 }
35 if (etaModuleCl1 != etaModuleCl2 && phiModuleCl1 == phiModuleCl2) {
36 return 1; // overlap in eta only
37 }
38 if (etaModuleCl1 == etaModuleCl2 && phiModuleCl1 != phiModuleCl2) {
39 return 2; // overlap in phi only
40 }
41 return 3; // overlap in eta and phi
42}
43
44} // namespace ActsTrk::detail
45
46namespace ActsTrk {
47
49 const std::vector<const xAOD::SpacePointContainer*>& spacePointCollections,
50 std::vector<float>& features, std::vector<std::uint64_t>& moduleIds,
51 std::vector<int>& ids,
52 std::vector<const xAOD::SpacePoint*>& allSPPtrs,
53 std::size_t nFeatures) const {
54
55 std::size_t nSP = 0;
56 for (const auto* spc : spacePointCollections) {
57 nSP += spc->size();
58 }
59 moduleIds.reserve(nSP);
60 allSPPtrs.reserve(nSP);
61
62 std::size_t skipped = 0;
63 for (const auto* spc : spacePointCollections) {
64 for (const auto* sp : *spc) {
65 const auto* cl1 = sp->measurements().front();
66 Identifier atlasIdCl1(
67 static_cast<Identifier::value_type>(cl1->identifier()));
68
69 if (!m_usePhiOverlapSps.value() && sp->measurements().size() == 2) {
70 const auto* cl2 = sp->measurements().at(1);
71 Identifier atlasIdCl2(
72 static_cast<Identifier::value_type>(cl2->identifier()));
73
74 int overlapFlag = detail::computeOverlapSpFlag(
75 m_stripIdHelper->eta_module(atlasIdCl1),
76 m_stripIdHelper->phi_module(atlasIdCl1),
77 m_stripIdHelper->eta_module(atlasIdCl2),
78 m_stripIdHelper->phi_module(atlasIdCl2));
79
80 if (overlapFlag == 2 || overlapFlag == 3) {
81 ++skipped;
82 ACTS_VERBOSE("Skip phi overlap spacepoint (flag=" << overlapFlag
83 << ")");
84 continue;
85 }
86 }
87
88 Identifier waferIdCl1 =
90 ? m_pixelIdHelper->wafer_id(atlasIdCl1)
91 : m_stripIdHelper->wafer_id(atlasIdCl1);
92 moduleIds.push_back(waferIdCl1.get_compact());
93 allSPPtrs.push_back(sp);
94 }
95 }
96
97 ACTS_DEBUG("Skipped " << skipped << " SPs because of phi overlap");
98 nSP = allSPPtrs.size();
99 ACTS_DEBUG("Keep " << nSP << " SPs for feature creation");
100
101 std::vector<std::size_t> idxs(nSP);
102 std::iota(idxs.begin(), idxs.end(), 0);
103 std::ranges::sort(
104 idxs, [&](auto a, auto b) { return moduleIds.at(a) < moduleIds.at(b); });
105 std::ranges::sort(moduleIds);
106
107 // Reorder the space point pointers to match the sorted module ids, so that
108 // the node ids returned by the pipeline index allSPPtrs directly
109 std::vector<const xAOD::SpacePoint*> sortedSPPtrs(nSP);
110 for (std::size_t k = 0; k < nSP; ++k) {
111 sortedSPPtrs.at(k) = allSPPtrs.at(idxs.at(k));
112 }
113 allSPPtrs.swap(sortedSPPtrs);
114
115 features.assign(nFeatures * nSP, 0.f);
116 ids.resize(nSP);
117
118 for (std::size_t k = 0; k < nSP; ++k) {
119 ids.at(k) = static_cast<int>(k);
120
121 std::span<float> f(features.data() + k * nFeatures, nFeatures);
122 const auto& sp = *allSPPtrs.at(k);
123
124 using namespace Acts::VectorHelpers;
125
126 Acts::Vector3 spp{sp.x(), sp.y(), sp.z()};
127
128 if (sp.measurements().size() == 1) {
129 for (std::size_t j = 0; j < nFeatures; j += 4) {
130 f[j + 0] = perp(spp) / 1000.f;
131 f[j + 1] = phi(spp) / std::numbers::pi_v<float>;
132 f[j + 2] = sp.z() / 1000.f;
133 f[j + 3] = eta(spp);
134 }
135 } else {
136 std::size_t j = 0;
137 f[j + 0] = perp(spp) / 1000.f;
138 f[j + 1] = phi(spp) / std::numbers::pi_v<float>;
139 f[j + 2] = sp.z() / 1000.f;
140 f[j + 3] = eta(spp);
141
142 for (const auto* m : sp.measurements()) {
143 const auto* cl = static_cast<const xAOD::StripCluster*>(m);
144 auto gp = cl->globalPosition();
145 j += 4;
146 f[j + 0] = perp(gp) / 1000.f;
147 f[j + 1] = phi(gp) / std::numbers::pi_v<float>;
148 f[j + 2] = gp.z() / 1000.f;
149 f[j + 3] = eta(gp);
150 }
151 }
152 }
153
154 return StatusCode::SUCCESS;
155}
156
157} // namespace ActsTrk
158
159#endif
Scalar eta() const
pseudorapidity method
Scalar perp() const
perp method - perpendicular length
Scalar phi() const
phi method
static Double_t sp
static Double_t a
This is an Identifier helper class for the Pixel subdetector.
This is an Identifier helper class for the SCT subdetector.
const SCT_ID * m_stripIdHelper
Gaudi::Property< bool > m_usePhiOverlapSps
const PixelID * m_pixelIdHelper
StatusCode buildFeatures(const std::vector< const xAOD::SpacePointContainer * > &spacePointCollections, std::vector< float > &features, std::vector< std::uint64_t > &moduleIds, std::vector< int > &ids, std::vector< const xAOD::SpacePoint * > &allSPPtrs, std::size_t nFeatures=12) const
Definition GnnFeatures.h:48
value_type get_compact() const
Get the compact id.
Hash functions to pack the source link into unordered_maps / unordered_sets.
int computeOverlapSpFlag(int etaModuleCl1, int phiModuleCl1, int etaModuleCl2, int phiModuleCl2)
Definition GnnFeatures.h:30
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
StripCluster_v1 StripCluster
Define the version of the strip cluster class.