ATLAS Offline Software
Loading...
Searching...
No Matches
GNN_Geometry.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5
7
8#include <cmath>
9#include <cstring>
10#include <algorithm>
11#include <iostream>
12
13#include <list>
14#include <map>
15
17
18 if(m_layer.m_type == 0) {//barrel
19 m_r1 = m_layer.m_refCoord;
20 m_r2 = m_layer.m_refCoord;
21 m_z1 = m_layer.m_minBound;
22 m_z2 = m_layer.m_maxBound;
23 }
24 else {//endcap
25 m_r1 = m_layer.m_minBound;
26 m_r2 = m_layer.m_maxBound;
27 m_z1 = m_layer.m_refCoord;
28 m_z2 = m_layer.m_refCoord;
29 }
30
31 float t1 = m_z1/m_r1;
32 float eta1 = -std::log(std::sqrt(1+t1*t1)-t1);
33
34
35 float t2 = m_z2/m_r2;
36 float eta2 = -std::log(std::sqrt(1+t2*t2)-t2);
37
38 m_minEta = eta1;
39 m_maxEta = eta2;
40
41 if(m_maxEta < m_minEta) {
42 m_minEta = eta2;
43 m_maxEta = eta1;
44 }
45
46 m_maxEta += 1e-6;//increasing them slightly to avoid range_check exceptions
47 m_minEta -= 1e-6;
48
49 float deltaEta = m_maxEta - m_minEta;
50
51 int binCounter = bin0;
52
53 if(deltaEta < m_etaBinWidth) {
54 m_nBins = 1;
55 m_bins.push_back(binCounter++);
56 m_etaBin = deltaEta;
57 if(m_layer.m_type == 0) {//barrel
58 m_minRadius.push_back(m_layer.m_refCoord - 2.0);
59 m_maxRadius.push_back(m_layer.m_refCoord + 2.0);
60 m_minBinCoord.push_back(m_layer.m_minBound);
61 m_maxBinCoord.push_back(m_layer.m_maxBound);
62 }
63 else {//endcap
64 m_minRadius.push_back(m_layer.m_minBound - 2.0);
65 m_maxRadius.push_back(m_layer.m_maxBound + 2.0);
66 m_minBinCoord.push_back(m_layer.m_minBound);
67 m_maxBinCoord.push_back(m_layer.m_maxBound);
68 }
69 }
70 else {
71 float nB = static_cast<int>(deltaEta/m_etaBinWidth);
72 m_nBins = nB;
73 if(deltaEta - m_etaBinWidth*nB > 0.5*m_etaBinWidth) m_nBins++;
74
75 m_etaBin = deltaEta/m_nBins;
76
77 if(m_nBins == 1) {
78 m_bins.push_back(binCounter++);
79 if(m_layer.m_type == 0) {//barrel
80 m_minRadius.push_back(m_layer.m_refCoord - 2.0);
81 m_maxRadius.push_back(m_layer.m_refCoord + 2.0);
82 m_minBinCoord.push_back(m_layer.m_minBound);
83 m_maxBinCoord.push_back(m_layer.m_maxBound);
84 }
85 else {//endcap
86 m_minRadius.push_back(m_layer.m_minBound - 2.0);
87 m_maxRadius.push_back(m_layer.m_maxBound + 2.0);
88 m_minBinCoord.push_back(m_layer.m_minBound);
89 m_maxBinCoord.push_back(m_layer.m_maxBound);
90 }
91 }
92 else {
93
94 float eta = m_minEta+0.5*m_etaBin;
95
96 for(int i=1;i<=m_nBins;i++) {
97
98 m_bins.push_back(binCounter++);
99
100 float e1 = eta - 0.5*m_etaBin;
101 float e2 = eta + 0.5*m_etaBin;
102
103 if(m_layer.m_type == 0) {//barrel
104 m_minRadius.push_back(m_layer.m_refCoord - 2.0);
105 m_maxRadius.push_back(m_layer.m_refCoord + 2.0);
106 float z1 = m_layer.m_refCoord*std::sinh(e1);
107 m_minBinCoord.push_back(z1);
108 float z2 = m_layer.m_refCoord*std::sinh(e2);
109 m_maxBinCoord.push_back(z2);
110 }
111 else {//endcap
112 if (m_layer.m_refCoord > 0) {//for the positive endcap larger eta corresponds to smaller radius
113 std::swap(e1, e2);
114 }
115 float r = m_layer.m_refCoord/std::sinh(e1);
116 m_minBinCoord.push_back(r);
117 m_minRadius.push_back(r - 2.0);
118 r = m_layer.m_refCoord/std::sinh(e2);
119 m_maxBinCoord.push_back(r);
120 m_maxRadius.push_back(r + 2.0);
121
122 }
123
124 eta += m_etaBin;
125 }
126 }
127 }
128}
129
130bool TrigFTF_GNN_Layer::verifyBin(const TrigFTF_GNN_Layer* pL, int b1, int b2, float min_z0, float max_z0) const {
131
132 float z1min = m_minBinCoord.at(b1);
133 float z1max = m_maxBinCoord.at(b1);
134 float r1 = m_layer.m_refCoord;
135
136 const float tol = 5.0;
137
138 if(m_layer.m_type == 0 && pL->m_layer.m_type == 0) {//barrel <- barrel
139
140 float min_b2 = pL->m_minBinCoord.at(b2);
141 float max_b2 = pL->m_maxBinCoord.at(b2);
142
143 float r2 = pL->m_layer.m_refCoord;
144
145 float A = r2/(r2-r1);
146 float B = r1/(r2-r1);
147
148 float z0_min = z1min*A - max_b2*B;
149 float z0_max = z1max*A - min_b2*B;
150
151 if(z0_max < min_z0-tol || z0_min > max_z0+tol) return false;
152
153 return true;
154 }
155
156 if(m_layer.m_type == 0 && pL->m_layer.m_type != 0) {//barrel <- endcap
157
158 float z2 = pL->m_layer.m_refCoord;
159 float r2max = pL->m_maxBinCoord.at(b2);
160 float r2min = pL->m_minBinCoord.at(b2);
161
162 if(r2max <= r1) return false;
163
164 if(r2min <= r1) {
165 r2min = r1 + 1e-3;
166 }
167
168 float z0_max = 0.0;
169 float z0_min = 0.0;
170
171 if(z2 > 0) {
172 z0_max = (z1max*r2max - z2*r1)/(r2max-r1);
173 z0_min = (z1min*r2min - z2*r1)/(r2min-r1);
174 }
175 else {
176 z0_max = (z1max*r2min - z2*r1)/(r2min-r1);
177 z0_min = (z1min*r2max - z2*r1)/(r2max-r1);
178 }
179
180 if(z0_max < min_z0-tol || z0_min > max_z0+tol) return false;
181 return true;
182 }
183
184 if(m_layer.m_type != 0 && pL->m_layer.m_type != 0) {//endcap <- endcap
185
186 float z2 = pL->m_layer.m_refCoord;
187 float z1 = m_layer.m_refCoord;
188 float r2max = pL->m_maxBinCoord.at(b2);
189 float r2min = pL->m_minBinCoord.at(b2);
190 float r1max = m_maxBinCoord.at(b1);
191 float r1min = m_minBinCoord.at(b1);
192
193 if (r1min >= r2max) return false;
194
195 if (z2 > 0) { // positive endcap
196
197 float z0_max = z1 - r1min*(z2-z1)/(r2max-r1min);
198
199 if(z0_max < min_z0-tol) return false;
200
201 if (r2min > r1max) {
202
203 float z0_min = z1 - r1max*(z2-z1)/(r2min-r1max);
204
205 if (z0_min > max_z0+tol) return false;
206 }
207 }
208 else { // negative endcap
209 float z0_min = z1 - r1min*(z2-z1)/(r2max-r1min);
210
211 if(z0_min > max_z0+tol) return false;
212
213 if (r2min > r1max) {
214
215 float z0_max = z1 - r1max*(z2-z1)/(r2min-r1max);
216
217 if (z0_max < min_z0-tol) return false;
218 }
219 }
220 return true;
221 }
222
223 if(m_layer.m_type != 0 && pL->m_layer.m_type == 0) {//endcap <- barrel
224
225 float z1 = m_layer.m_refCoord;
226 float r1max = m_maxBinCoord.at(b1);
227 float r1min = m_minBinCoord.at(b1);
228
229 float z2min = pL->m_minBinCoord.at(b2);
230 float z2max = pL->m_maxBinCoord.at(b2);
231 float r2 = pL->m_layer.m_refCoord;
232
233 if (r2 < r1min) return false;
234
235 // interval 1
236
237 float z0_min = z1 - (z2max - z1)/(r2/r1max - 1);
238 float z0_max = z1 - (z2max - z1)/(r2/r1min - 1);
239
240 if (z0_min > z0_max) std::swap(z0_min, z0_max);
241
242 bool beyond_range = (z0_max < min_z0-tol || z0_min > max_z0+tol);
243
244 if (!beyond_range) return true;
245
246 // interval 2
247
248 z0_min = z1 - (z2min - z1)/(r2/r1max - 1);
249 z0_max = z1 - (z2min - z1)/(r2/r1min - 1);
250
251 if (z0_min > z0_max) std::swap(z0_min, z0_max);
252
253 beyond_range = (z0_max < min_z0-tol || z0_min > max_z0+tol);
254
255 if (!beyond_range) return true;
256
257 return false;
258
259 }
260
261 return true;
262}
263
264
265int TrigFTF_GNN_Layer::getEtaBin(float zh, float rh) const {
266
267 if(m_bins.size() == 1) return m_bins.at(0);
268
269 float t1 = zh/rh;
270 float eta = -std::log(std::sqrt(1+t1*t1)-t1);
271
272
273 int idx = static_cast<int>((eta-m_minEta)/m_etaBin);
274
275
276 if(idx < 0) idx = 0;
277 if(idx >= static_cast<int>(m_bins.size())) idx = static_cast<int>(m_bins.size())-1;
278
279 return m_bins.at(idx);//index in the global storage
280}
281
283 if(idx >= static_cast<int>(m_minRadius.size())) idx = idx-1;
284 if(idx < 0) idx = 0;
285
286 return m_minRadius.at(idx);
287}
288
290 if(idx >= static_cast<int>(m_maxRadius.size())) idx = idx-1;
291 if(idx < 0) idx = 0;
292
293 return m_maxRadius.at(idx);
294}
295
299
300TrigFTF_GNN_Geometry::TrigFTF_GNN_Geometry(const std::vector<TrigInDetSiLayer>& layers, const std::unique_ptr<GNN_FasTrackConnector>& conn) : m_nEtaBins(0) {
301
302 const float min_z0 = -168.0;
303 const float max_z0 = 168.0;
304
305 m_etaBinWidth = conn->m_etaBin;
306
307 for(const auto& layer : layers) {
308 const TrigFTF_GNN_Layer* pL = addNewLayer(layer, m_nEtaBins);
309 m_nEtaBins += pL->num_bins();
310 }
311
312 //calculating bin tables in the connector...
313 //calculate bin pairs for graph edge building
314
315 int lastBin1 = -1;
316
317 for(std::map<int, std::vector<GNN_FASTRACK_CONNECTION*> >::const_iterator it = conn->m_connMap.begin();it!=conn->m_connMap.end();++it) {
318
319 const std::vector<GNN_FASTRACK_CONNECTION*>& vConn = (*it).second;
320
321 for(std::vector<GNN_FASTRACK_CONNECTION*>::const_iterator cIt=vConn.begin();cIt!=vConn.end();++cIt) {
322
323 unsigned int src = (*cIt)->m_src;//n2 : the new connectors
324 unsigned int dst = (*cIt)->m_dst;//n1
325
326 const TrigFTF_GNN_Layer* pL1 = getTrigFTF_GNN_LayerByKey(dst);
327 const TrigFTF_GNN_Layer* pL2 = getTrigFTF_GNN_LayerByKey(src);
328
329 if (pL1==nullptr) {
330 std::cout << " skipping invalid dst layer " << dst << std::endl;
331 continue;
332 }
333 if (pL2==nullptr) {
334 std::cout << " skipping invalid src layer " << src << std::endl;
335 continue;
336 }
337 int nSrcBins = pL2->m_bins.size();
338 int nDstBins = pL1->m_bins.size();
339
340 (*cIt)->m_binTable.resize(nSrcBins*nDstBins, 0);
341
342 for(int b1=0;b1<nDstBins;b1++) {//loop over bins in Layer 1
343 for(int b2=0;b2<nSrcBins;b2++) {//loop over bins in Layer 2
344 if(!pL1->verifyBin(pL2, b1, b2, min_z0, max_z0)) continue;
345 int address = b1 + b2*nDstBins;
346 (*cIt)->m_binTable.at(address) = 1;
347
348 int bin1_idx = pL1->m_bins.at(b1);
349 int bin2_idx = pL2->m_bins.at(b2);
350
351 if(bin1_idx != lastBin1) {//adding a new group
352
353 std::vector<int> v2(1, bin2_idx);
354 m_binGroups.push_back(std::make_pair(bin1_idx, v2));
355 lastBin1 = bin1_idx;
356
357 }
358 else {//extend the last group
359 (*m_binGroups.rbegin()).second.push_back(bin2_idx);
360 }
361 }
362 }
363 }
364 }
365
366 // find stages of eta-bin pairs using the graph ablation algorithm
367
368 std::map<int, std::pair<std::list<int>, std::list<int> > > bin_map;
369
370 // 1. create a map of bin-to-bin connections
371
372 //initialize with empty links
373
374 for (const auto& bg : m_binGroups) {
375
376 int bin1 = bg.first;
377
378 if (bin_map.find(bin1) == bin_map.end()) {//add to the map
379 std::pair<std::list<int>, std::list<int> > empty_links;
380 bin_map.insert(std::make_pair(bin1, empty_links));
381 }
382
383 std::pair<std::list<int>, std::list<int> >& bin1_links = (*bin_map.find(bin1)).second;
384
385 for (auto bin2 : bg.second) {
386
387 if (bin_map.find(bin2) == bin_map.end()) {//add to the map
388 std::pair<std::list<int>, std::list<int> > empty_links;
389 bin_map.insert(std::make_pair(bin2, empty_links));
390 }
391
392 std::pair<std::list<int>, std::list<int> >& bin2_links = (*bin_map.find(bin2)).second;
393
394 bin1_links.second.push_back(bin2);//incoming link bin1 <- bin2
395 bin2_links.first.push_back(bin1); //outgoing link bin2 -> bin1
396
397 }
398 }
399
400 std::map<int, std::pair<std::list<int>, std::list<int> > > current_map(bin_map);//copy bin map as the original will be modified
401
402 // 2. find stages starting from the last one (i.e. bin1 with no outgoing connections)
403
404 std::vector<std::vector<int> > stages;
405
406 stages.reserve(50);
407
408 while (!current_map.empty()) {
409
410 // 2a. find all bins with zero outgoing links
411
412 std::vector<int> exit_bins;
413
414 for(const auto& bl : current_map) {
415
416 if(!bl.second.first.empty()) continue;
417
418 exit_bins.push_back(bl.first);
419
420 }
421
422 //2b. add a new stage: vector of bin1
423
424 stages.emplace_back(exit_bins);
425
426 //2c. remove links : graph ablation
427
428 for (auto bin1_key : exit_bins) {
429 auto p1 = current_map.find(bin1_key);
430 if (p1 == current_map.end()) continue;
431 auto& bin1_links = (*p1).second;
432
433 for(auto bin2_key : bin1_links.second) {
434 auto p2 = current_map.find(bin2_key);
435 if (p2 == current_map.end()) continue;
436 std::list<int>& links = (*p2).second.first;
437 links.remove(bin1_key);
438 }
439 }
440
441 //2d. finally, remove all exit bin1s from the map
442
443 for (auto bin1_key : exit_bins) {
444 current_map.erase(bin1_key);
445 }
446
447 }
448
449 //3. Refill binGroups with staged bin pair collections.
450
451 m_binGroups.clear();
452
453 for (auto iter = stages.rbegin(); iter != stages.rend(); ++iter) {//refill order is reverse to creation
454
455 for (auto bin1_idx : (*iter)) {
456 const auto p = bin_map.find(bin1_idx);
457 if (p == bin_map.end()) continue;
458 const std::list<int>& bin2_list = (*p).second.second;//bins which are incoming to bin1
459
460 std::vector<int> v2(bin2_list.begin(), bin2_list.end());
461
462 m_binGroups.push_back(std::make_pair(bin1_idx, v2));//store the group
463
464 }
465 }
466}
467
468
470 for(std::vector<TrigFTF_GNN_Layer*>::iterator it = m_layArray.begin();it!=m_layArray.end();++it) {
471 delete (*it);
472 }
473 m_layMap.clear();m_layArray.clear();
474}
475
477 std::map<unsigned int, TrigFTF_GNN_Layer*>::const_iterator it = m_layMap.find(key);
478 if(it == m_layMap.end()) {
479 return nullptr;
480 }
481 return (*it).second;
482}
483
487
488
489
491
492 unsigned int layerKey = l.m_subdet;
493
494 float ew = m_etaBinWidth;
495
496 TrigFTF_GNN_Layer* pHL = new TrigFTF_GNN_Layer(l, ew, bin0);
497
498 m_layMap.insert(std::pair<unsigned int, TrigFTF_GNN_Layer*>(layerKey, pHL));
499 m_layArray.push_back(pHL);
500 m_layerKeys.push_back(layerKey);
501 return pHL;
502}
Scalar eta() const
pseudorapidity method
std::vector< unsigned int > m_layerKeys
const TrigFTF_GNN_Layer * getTrigFTF_GNN_LayerByIndex(int) const
const TrigFTF_GNN_Layer * addNewLayer(const TrigInDetSiLayer &, int)
std::map< unsigned int, TrigFTF_GNN_Layer * > m_layMap
TrigFTF_GNN_Geometry(const std::vector< TrigInDetSiLayer > &, const std::unique_ptr< GNN_FasTrackConnector > &)
const TrigFTF_GNN_Layer * getTrigFTF_GNN_LayerByKey(unsigned int) const
std::vector< TrigFTF_GNN_Layer * > m_layArray
std::vector< float > m_minBinCoord
const TrigInDetSiLayer & m_layer
std::vector< float > m_maxRadius
int getEtaBin(float, float) const
std::vector< int > m_bins
int num_bins() const
std::vector< float > m_minRadius
TrigFTF_GNN_Layer(const TrigInDetSiLayer &, float, int)
float getMinBinRadius(int) const
std::vector< float > m_maxBinCoord
float getMaxBinRadius(int) const
bool verifyBin(const TrigFTF_GNN_Layer *, int, int, float, float) const
int r
Definition globals.cxx:22
double e2(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 2nd sampling
double e1(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 1st sampling
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
hold the test vectors and ease the comparison