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 features.assign(nFeatures * nSP, 0.f);
108 ids.resize(nSP);
109
110 for (std::size_t k = 0; k < nSP; ++k) {
111 ids.at(k) = static_cast<int>(k);
112 auto i = idxs.at(k);
113
114 std::span<float> f(features.data() + k * nFeatures, nFeatures);
115 const auto& sp = *allSPPtrs.at(i);
116
117 using namespace Acts::VectorHelpers;
118
119 Acts::Vector3 spp{sp.x(), sp.y(), sp.z()};
120
121 if (sp.measurements().size() == 1) {
122 for (std::size_t j = 0; j < nFeatures; j += 4) {
123 f[j + 0] = perp(spp) / 1000.f;
124 f[j + 1] = phi(spp) / std::numbers::pi_v<float>;
125 f[j + 2] = sp.z() / 1000.f;
126 f[j + 3] = eta(spp);
127 }
128 } else {
129 std::size_t j = 0;
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 for (const auto* m : sp.measurements()) {
136 const auto* cl = static_cast<const xAOD::StripCluster*>(m);
137 auto gp = cl->globalPosition();
138 j += 4;
139 f[j + 0] = perp(gp) / 1000.f;
140 f[j + 1] = phi(gp) / std::numbers::pi_v<float>;
141 f[j + 2] = gp.z() / 1000.f;
142 f[j + 3] = eta(gp);
143 }
144 }
145 }
146
147 return StatusCode::SUCCESS;
148}
149
150} // namespace ActsTrk
151
152#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.