ATLAS Offline Software
Loading...
Searching...
No Matches
BucketGraphUtils.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN
3 for the benefit of the ATLAS collaboration
4*/
5#ifndef MUONINFERENCE_BUCKETGRAPHUTILS_H
6#define MUONINFERENCE_BUCKETGRAPHUTILS_H
7
8#include <vector>
9#include <cstdint>
10#include <algorithm>
11#include <cmath>
12#include <unordered_set>
13
18
20
21struct NodeAux {
22 double x{0.f};
23 double y{0.f};
24 double z{0.f};
25 int layers{0};
26 int nSp{0};
27 double bucketSize{0.f};
28 int sector{0};
29 int chamber{0};
30};
31
33 return b.coveredMax() - b.coveredMin();
34}
35
40 return bucket_size_mm(b) != 0.0;
41}
42
48 const ActsTrk::GeometryContext& gctx,
49 std::vector<NodeAux>& nodes,
50 std::vector<float>& featuresLeaves,
51 std::vector<int64_t>& spInBucket) // << int64_t!
52{
54 nodes.clear();
55 featuresLeaves.clear();
56 spInBucket.clear();
57 nodes.reserve(buckets.size());
58 featuresLeaves.reserve(6u * buckets.size()); // preallocate
59 spInBucket.reserve(buckets.size());
60
62
63 for (const MuonR4::SpacePointBucket* bucket : buckets) {
64 const double bsize = bucket_size_mm(*bucket);
65
66 if (!keepBucketAsTrainingNode(*bucket)) {
67 continue;
68 }
69
70 NodeAux n;
71
72 const double midY = 0.5 * (bucket->coveredMin() + bucket->coveredMax());
73 const Amg::Vector3D glob = bucket->msSector()->localToGlobalTransform(gctx) * (midY * Amg::Vector3D::UnitY());
74 n.x = glob.x();
75 n.y = glob.y();
76 n.z = glob.z();
77
78 std::unordered_set<unsigned int> laySet;
79 laySet.reserve(bucket->size());
80 for (const auto& spPtr : *bucket) {
81 laySet.insert(layerSorter.sectorLayerNum(*spPtr));
82 }
83 n.layers = static_cast<int>(laySet.size());
84 n.nSp = static_cast<int>(bucket->size());
85 n.bucketSize = bsize;
86 n.sector = bucket->msSector()->sector();
87 n.chamber = Acts::toUnderlying(bucket->msSector()->chamberIndex());
88
89 nodes.push_back(n);
90
91 featuresLeaves.push_back(static_cast<float>(n.x));
92 featuresLeaves.push_back(static_cast<float>(n.y));
93 featuresLeaves.push_back(static_cast<float>(n.z));
94 featuresLeaves.push_back(static_cast<float>(n.layers));
95 featuresLeaves.push_back(static_cast<float>(n.nSp));
96 featuresLeaves.push_back(static_cast<float>(n.bucketSize));
97
98 spInBucket.emplace_back(static_cast<int64_t>(n.nSp)); // store as int64_t
99 }
100}
101
102inline void buildSparseEdges(const std::vector<NodeAux>& nodes,
103 int minLayers,
104 int maxChamberDelta,
105 int maxSectorDelta,
106 double maxDistXY,
107 double maxAbsDz,
108 std::vector<int64_t>& srcEdges,
109 std::vector<int64_t>& dstEdges)
110{
112 srcEdges.clear();
113 dstEdges.clear();
114
115 std::vector<size_t> validIdx;
116 validIdx.reserve(nodes.size());
117 for (size_t i = 0; i < nodes.size(); ++i) {
118 if (nodes[i].layers >= minLayers) validIdx.push_back(i);
119 }
120
121 if (validIdx.size() < 2) {
122 if (!nodes.empty()) {
123 srcEdges.push_back(0);
124 dstEdges.push_back(0);
125 }
126 return;
127 }
128
129 const unsigned int secMax = Muon::MuonStationIndex::numberOfSectors();
130
131 for (size_t a = 0; a < validIdx.size(); ++a) {
132 const size_t i = validIdx[a];
133 const auto& ni = nodes[i];
134 for (size_t b = a + 1; b < validIdx.size(); ++b) {
135 const size_t j = validIdx[b];
136 const auto& nj = nodes[j];
137
138 const double dx = static_cast<double>(ni.x) - static_cast<double>(nj.x);
139 const double dy = static_cast<double>(ni.y) - static_cast<double>(nj.y);
140 const double dz = static_cast<double>(ni.z) - static_cast<double>(nj.z);
141
142 const double distXY = Acts::fastHypot(dx, dy);
143 const int secDiffLin = std::abs(ni.sector - nj.sector) % static_cast<int>(secMax);
144 const int d_sec = std::min(secDiffLin, static_cast<int>(secMax) - secDiffLin);
145 const int d_ch = std::abs(ni.chamber - nj.chamber);
146
147 const bool mask =
148 (d_ch > 0) &&
149 (d_sec <= maxSectorDelta) &&
150 (distXY < maxDistXY) &&
151 (std::abs(dz) < maxAbsDz) &&
152 (d_ch <= maxChamberDelta);
153
154 if (mask) {
155 srcEdges.push_back(static_cast<int64_t>(i));
156 dstEdges.push_back(static_cast<int64_t>(j));
157 srcEdges.push_back(static_cast<int64_t>(j));
158 dstEdges.push_back(static_cast<int64_t>(i));
159 }
160 }
161 }
162
163 if (srcEdges.empty() && !nodes.empty()) {
164 srcEdges.push_back(0);
165 dstEdges.push_back(0);
166 }
167}
168
169inline size_t packEdgeIndex(const std::vector<int64_t>& srcEdges,
170 const std::vector<int64_t>& dstEdges,
171 std::vector<int64_t>& edgeIndexPacked)
172{
173 const size_t E = srcEdges.size();
174 edgeIndexPacked = srcEdges;
175 edgeIndexPacked.insert(edgeIndexPacked.end(), dstEdges.begin(), dstEdges.end());
176 return E;
177}
178
179} // namespace MuonML::BucketGraphUtils
180
181#endif
182
static Double_t a
size_type size() const noexcept
Returns the number of elements in the collection.
: The muon space point bucket represents a collection of points that will bre processed together in t...
The SpacePointPerLayerSorter sort two given space points by their layer Identifier.
unsigned int sectorLayerNum(const SpacePoint &sp) const
method returning the logic layer number
Eigen::Matrix< double, 3, 1 > Vector3D
void buildNodesAndFeatures(const MuonR4::SpacePointContainer &buckets, const ActsTrk::GeometryContext &gctx, std::vector< NodeAux > &nodes, std::vector< float > &featuresLeaves, std::vector< int64_t > &spInBucket)
Build nodes + flat features (N,6) and number of SPs per kept bucket.
bool keepBucketAsTrainingNode(const MuonR4::SpacePointBucket &b)
bucket_size == 0, where bucket_size is bucket_max - bucket_min.
void buildSparseEdges(const std::vector< NodeAux > &nodes, int minLayers, int maxChamberDelta, int maxSectorDelta, double maxDistXY, double maxAbsDz, std::vector< int64_t > &srcEdges, std::vector< int64_t > &dstEdges)
size_t packEdgeIndex(const std::vector< int64_t > &srcEdges, const std::vector< int64_t > &dstEdges, std::vector< int64_t > &edgeIndexPacked)
double bucket_size_mm(const MuonR4::SpacePointBucket &b)
DataVector< SpacePointBucket > SpacePointContainer
Abrivation of the space point container type.
constexpr unsigned numberOfSectors()
return total number of sectors