Skip to content

Commit 13f9308

Browse files
authored
feat: Initial version of ATLAS-based FTF seeding (#2227)
First few files needed for FTF seeding. Does not create seeds yet, made to check current progress is compatible.
1 parent f54faba commit 13f9308

File tree

18 files changed

+3249
-1
lines changed

18 files changed

+3249
-1
lines changed
Lines changed: 319 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,319 @@
1+
// This file is part of the Acts project.
2+
//
3+
// Copyright (C) 2021 CERN for the benefit of the Acts project
4+
//
5+
// This Source Code Form is subject to the terms of the Mozilla Public
6+
// License, v. 2.0. If a copy of the MPL was not distributed with this
7+
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
8+
9+
#pragma once
10+
11+
// TODO: update to C++17 style
12+
#include "Acts/Definitions/Algebra.hpp"
13+
#include "Acts/Seeding/GNN_Geometry.hpp"
14+
15+
#include <algorithm>
16+
#include <map>
17+
#include <vector>
18+
19+
namespace Acts {
20+
21+
constexpr size_t MAX_SEG_PER_NODE = 1000; // was 30
22+
constexpr size_t N_SEG_CONNS = 6; // was 6
23+
24+
// new sp struct
25+
template <typename space_point_t>
26+
struct FTF_SP {
27+
const space_point_t *SP; // want inside to have pointer
28+
int FTF_ID;
29+
int combined_ID;
30+
FTF_SP(const space_point_t *sp, int id, int combined_id)
31+
: SP(sp), FTF_ID(id), combined_ID{combined_id} {
32+
if (SP->sourceLinks().size() == 1) { // pixels have 1 SL
33+
m_isPixel = true;
34+
} else {
35+
m_isPixel = false;
36+
}
37+
m_phi = std::atan(SP->x() / SP->y());
38+
};
39+
bool isPixel() const { return m_isPixel; }
40+
bool isSCT() const { return !m_isPixel; }
41+
float phi() const { return m_phi; }
42+
bool m_isPixel;
43+
float m_phi;
44+
};
45+
46+
template <typename space_point_t>
47+
class TrigFTF_GNN_Node {
48+
public:
49+
struct CompareByPhi {
50+
bool operator()(const TrigFTF_GNN_Node<space_point_t> *n1,
51+
const TrigFTF_GNN_Node<space_point_t> *n2) {
52+
return (n1->m_sp_FTF.phi() < n2->m_sp_FTF.phi());
53+
}
54+
};
55+
56+
TrigFTF_GNN_Node(const FTF_SP<space_point_t> &FTF_sp, float minT = -100.0,
57+
float maxT = 100.0)
58+
: m_sp_FTF(FTF_sp), m_minCutOnTau(minT), m_maxCutOnTau(maxT) {}
59+
60+
~TrigFTF_GNN_Node() {}
61+
62+
inline void addIn(int i) {
63+
if (m_in.size() < MAX_SEG_PER_NODE) {
64+
m_in.push_back(i);
65+
}
66+
}
67+
68+
inline void addOut(int i) {
69+
if (m_out.size() < MAX_SEG_PER_NODE) {
70+
m_out.push_back(i);
71+
}
72+
}
73+
74+
inline bool isConnector() const {
75+
if (m_in.empty() || m_out.empty())
76+
return false;
77+
return true;
78+
}
79+
80+
inline bool isFull() const {
81+
if (m_in.size() == MAX_SEG_PER_NODE && m_out.size() == MAX_SEG_PER_NODE)
82+
return true;
83+
else
84+
return false;
85+
}
86+
87+
const FTF_SP<space_point_t> &m_sp_FTF;
88+
89+
std::vector<unsigned int> m_in; // indices of the edges in the edge storage
90+
std::vector<unsigned int> m_out;
91+
float m_minCutOnTau, m_maxCutOnTau;
92+
};
93+
94+
template <typename space_point_t>
95+
class TrigFTF_GNN_EtaBin {
96+
public:
97+
TrigFTF_GNN_EtaBin() { m_vn.clear(); }
98+
99+
~TrigFTF_GNN_EtaBin() {
100+
for (typename std::vector<TrigFTF_GNN_Node<space_point_t> *>::iterator it =
101+
m_vn.begin();
102+
it != m_vn.end(); ++it) {
103+
delete (*it);
104+
}
105+
}
106+
107+
void sortByPhi() {
108+
std::sort(m_vn.begin(), m_vn.end(),
109+
typename Acts::TrigFTF_GNN_Node<space_point_t>::CompareByPhi());
110+
}
111+
112+
bool empty() const { return m_vn.empty(); }
113+
114+
void generatePhiIndexing(float dphi) {
115+
for (unsigned int nIdx = 0; nIdx < m_vn.size(); nIdx++) {
116+
TrigFTF_GNN_Node<space_point_t> *pN = m_vn.at(nIdx);
117+
// float phi = pN->m_sp.phi();
118+
// float phi = (std::atan(pN->m_sp.x() / pN->m_sp.y()));
119+
float phi = pN->m_sp_FTF.phi();
120+
if (phi <= M_PI - dphi) {
121+
continue;
122+
}
123+
124+
m_vPhiNodes.push_back(
125+
std::pair<float, unsigned int>(phi - 2 * M_PI, nIdx));
126+
}
127+
128+
for (unsigned int nIdx = 0; nIdx < m_vn.size(); nIdx++) {
129+
TrigFTF_GNN_Node<space_point_t> *pN = m_vn.at(nIdx);
130+
float phi = pN->m_sp_FTF.phi();
131+
m_vPhiNodes.push_back(std::pair<float, unsigned int>(phi, nIdx));
132+
}
133+
134+
for (unsigned int nIdx = 0; nIdx < m_vn.size(); nIdx++) {
135+
TrigFTF_GNN_Node<space_point_t> *pN = m_vn.at(nIdx);
136+
float phi = pN->m_sp_FTF.phi();
137+
if (phi >= -M_PI + dphi) {
138+
break;
139+
}
140+
m_vPhiNodes.push_back(
141+
std::pair<float, unsigned int>(phi + 2 * M_PI, nIdx));
142+
}
143+
}
144+
145+
std::vector<TrigFTF_GNN_Node<space_point_t> *> m_vn;
146+
// TODO change to
147+
// std::vector<std::unique_ptr<TrigFTF_GNN_Node<space_point_t>>> m_vn;
148+
std::vector<std::pair<float, unsigned int>> m_vPhiNodes;
149+
};
150+
151+
template <typename space_point_t>
152+
class TrigFTF_GNN_DataStorage {
153+
public:
154+
TrigFTF_GNN_DataStorage(const TrigFTF_GNN_Geometry<space_point_t> &g)
155+
: m_geo(g) {
156+
m_etaBins.reserve(g.num_bins());
157+
for (int k = 0; k < g.num_bins(); k++) {
158+
m_etaBins.emplace_back(TrigFTF_GNN_EtaBin<space_point_t>());
159+
}
160+
}
161+
162+
~TrigFTF_GNN_DataStorage() {}
163+
164+
int addSpacePoint(const FTF_SP<space_point_t> &sp, bool useClusterWidth) {
165+
const TrigFTF_GNN_Layer<space_point_t> *pL =
166+
m_geo.getTrigFTF_GNN_LayerByKey(sp.combined_ID);
167+
168+
if (pL == nullptr) {
169+
return -1;
170+
}
171+
172+
int binIndex = pL->getEtaBin(sp.SP->z(), sp.SP->r());
173+
174+
if (binIndex == -1) {
175+
return -2;
176+
}
177+
178+
bool isBarrel = (pL->m_layer.m_type == 0);
179+
180+
if (isBarrel) {
181+
float min_tau = -100.0;
182+
float max_tau = 100.0;
183+
// can't do this bit yet as dont have cluster width
184+
if (useClusterWidth) {
185+
// const Trk::SpacePoint* osp = sp.offlineSpacePoint();
186+
// const InDet::PixelCluster* pCL = dynamic_cast<const
187+
// InDet::PixelCluster*>(osp->clusterList().first);
188+
// float cluster_width = pCL->width().widthPhiRZ().y();
189+
float cluster_width = 1; // temporary while cluster width not available
190+
min_tau = 6.7 * (cluster_width - 0.2);
191+
max_tau =
192+
1.6 + 0.15 / (cluster_width + 0.2) + 6.1 * (cluster_width - 0.2);
193+
}
194+
195+
m_etaBins.at(binIndex).m_vn.push_back(new TrigFTF_GNN_Node<space_point_t>(
196+
sp, min_tau, max_tau)); // adding ftf member to nodes
197+
} else {
198+
if (useClusterWidth) {
199+
// const Trk::SpacePoint* osp = sp.offlineSpacePoint();
200+
// const InDet::PixelCluster* pCL = dynamic_cast<const
201+
// InDet::PixelCluster*>(osp->clusterList().first);
202+
// float cluster_width = pCL->width().widthPhiRZ().y();
203+
float cluster_width = 1; // temporary while cluster width not available
204+
if (cluster_width > 0.2) {
205+
return -3;
206+
}
207+
}
208+
m_etaBins.at(binIndex).m_vn.push_back(
209+
new TrigFTF_GNN_Node<space_point_t>(sp));
210+
}
211+
212+
return 0;
213+
}
214+
215+
// for safety to prevent passing as copy
216+
TrigFTF_GNN_DataStorage(const TrigFTF_GNN_DataStorage &) = delete;
217+
TrigFTF_GNN_DataStorage &operator=(const TrigFTF_GNN_DataStorage &) = delete;
218+
219+
unsigned int numberOfNodes() const {
220+
unsigned int n = 0;
221+
222+
for (auto &b : m_etaBins) {
223+
n += b.m_vn.size();
224+
}
225+
return n;
226+
}
227+
228+
void getConnectingNodes(
229+
std::vector<const TrigFTF_GNN_Node<space_point_t> *> &vn) {
230+
vn.clear();
231+
vn.reserve(numberOfNodes());
232+
for (const auto &b : m_etaBins) {
233+
for (typename std::vector<
234+
TrigFTF_GNN_Node<space_point_t> *>::const_iterator nIt =
235+
b.m_vn.begin();
236+
nIt != b.m_vn.end(); ++nIt) {
237+
if ((*nIt)->m_in.empty()) {
238+
continue;
239+
}
240+
if ((*nIt)->m_out.empty()) {
241+
continue;
242+
}
243+
vn.push_back(*nIt);
244+
}
245+
}
246+
}
247+
248+
void sortByPhi() {
249+
for (auto &b : m_etaBins) {
250+
b.sortByPhi();
251+
}
252+
}
253+
254+
void generatePhiIndexing(float dphi) {
255+
for (auto &b : m_etaBins) {
256+
b.generatePhiIndexing(dphi);
257+
}
258+
}
259+
260+
const TrigFTF_GNN_EtaBin<space_point_t> &getEtaBin(int idx) const {
261+
if (idx >= static_cast<int>(m_etaBins.size())) {
262+
idx = idx - 1;
263+
}
264+
return m_etaBins.at(idx);
265+
}
266+
267+
protected:
268+
const TrigFTF_GNN_Geometry<space_point_t> &m_geo;
269+
270+
std::vector<TrigFTF_GNN_EtaBin<space_point_t>> m_etaBins;
271+
};
272+
273+
template <typename space_point_t>
274+
class TrigFTF_GNN_Edge {
275+
public:
276+
struct CompareLevel {
277+
public:
278+
bool operator()(const TrigFTF_GNN_Edge *pS1, const TrigFTF_GNN_Edge *pS2) {
279+
return pS1->m_level > pS2->m_level;
280+
}
281+
};
282+
283+
TrigFTF_GNN_Edge(TrigFTF_GNN_Node<space_point_t> *n1,
284+
TrigFTF_GNN_Node<space_point_t> *n2, float p1, float p2,
285+
float p3, float p4)
286+
: m_n1(n1), m_n2(n2), m_level(1), m_next(1), m_nNei(0) {
287+
m_p[0] = p1;
288+
m_p[1] = p2;
289+
m_p[2] = p3;
290+
m_p[3] = p4;
291+
}
292+
293+
TrigFTF_GNN_Edge()
294+
: m_n1(nullptr), m_n2(nullptr), m_level(-1), m_next(-1), m_nNei(0){};
295+
296+
// TrigFTF_GNN_Edge(const TrigFTF_GNN_Edge<space_point_t> &e)
297+
// : m_n1(e.m_n1), m_n2(e.m_n2){};
298+
299+
// inline void initialize(TrigFTF_GNN_Node<space_point_t> *n1,
300+
// TrigFTF_GNN_Node<space_point_t> *n2) {
301+
// m_n1 = n1;
302+
// m_n2 = n2;
303+
// m_level = 1;
304+
// m_next = 1;
305+
// m_nNei = 0;
306+
// }
307+
308+
TrigFTF_GNN_Node<space_point_t> *m_n1{nullptr};
309+
TrigFTF_GNN_Node<space_point_t> *m_n2{nullptr};
310+
311+
signed char m_level{-1}, m_next{-1};
312+
313+
unsigned char m_nNei{0};
314+
float m_p[4]{};
315+
316+
unsigned int m_vNei[N_SEG_CONNS]{}; // global indices of the connected edges
317+
};
318+
319+
} // namespace Acts

0 commit comments

Comments
 (0)