ATLAS Offline Software
TrigInDetPattRecoTools/src/SeedingToolBase.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
7 
9 
11 
12 #include "GNN_TrackingFilter.h"
13 
15 
16 #include "SeedingToolBase.h"
17 
18 
21 
22  ATH_CHECK(m_layerNumberTool.retrieve());
23 
24 
25  ATH_CHECK(detStore()->retrieve(m_atlasId, "AtlasID"));
26 
27  ATH_CHECK(detStore()->retrieve(m_pixelId, "PixelID"));
28 
29  ATH_CHECK(detStore()->retrieve(m_sctId, "SCT_ID"));
30 
31  std::string conn_fileName = PathResolver::find_file(m_connectionFile, "DATAPATH");
32  if (conn_fileName.empty()) {
33  ATH_MSG_FATAL("Cannot find layer connections file " << conn_fileName);
34  return StatusCode::FAILURE;
35  }
36  else {
37 
38  std::ifstream ifs(conn_fileName.c_str());
39 
40  m_connector = std::make_unique<GNN_FASTRACK_CONNECTOR>(ifs, m_LRTmode);
41  if (m_etaBinOverride != 0.0f) {
42  m_connector->m_etaBin = m_etaBinOverride;
43  }
44 
45  ATH_MSG_INFO("Layer connections are initialized from file " << conn_fileName);
46  }
47 
48  const std::vector<TrigInDetSiLayer>* pVL = m_layerNumberTool->layerGeometry();
49 
50  std::copy(pVL->begin(),pVL->end(), std::back_inserter(m_layerGeometry));
51 
52  m_geo = std::make_unique<TrigFTF_GNN_Geometry>(m_layerGeometry, m_connector);
53 
55 
56  ATH_MSG_INFO("SeedingToolBase initialized ");
57 
58  ATH_MSG_DEBUG("Property useML "<< m_useML);
59  ATH_MSG_DEBUG("Property DoPhiFiltering "<<m_filter_phi);
60  ATH_MSG_DEBUG("Property pTmin "<<m_minPt);
61  ATH_MSG_DEBUG("Property LRTmode "<<m_LRTmode);
62 
63  return StatusCode::SUCCESS;
64 }
65 
68  return sc;
69 }
70 
71 std::pair<int, int> SeedingToolBase::buildTheGraph(const IRoiDescriptor& roi, const std::unique_ptr<TrigFTF_GNN_DataStorage>& storage, std::vector<TrigFTF_GNN_Edge>& edgeStorage) const {
72 
73  const float M_2PI = 2.0*M_PI;
74 
75  const float cut_dphi_max = m_LRTmode ? 0.07f : 0.012f;
76  const float cut_dcurv_max = m_LRTmode ? 0.015f : 0.001f;
77  const float cut_tau_ratio_max = m_LRTmode ? 0.015f : static_cast<float>(m_tau_ratio_cut);
78  const float min_z0 = m_LRTmode ? -600.0 : roi.zedMinus();
79  const float max_z0 = m_LRTmode ? 600.0 : roi.zedPlus();
80  const float min_deltaPhi = m_LRTmode ? 0.01f : 0.001f;
81 
82  const float maxOuterRadius = m_LRTmode ? 1050.0 : 550.0;
83 
84  const float cut_zMinU = min_z0 + maxOuterRadius*roi.dzdrMinus();
85  const float cut_zMaxU = max_z0 + maxOuterRadius*roi.dzdrPlus();
86 
87  const float ptCoeff = 0.29997*1.9972/2.0;// ~0.3*B/2 - assuming nominal field of 2*T
88 
89  float tripletPtMin = 0.8*m_minPt;//correction due to limited pT resolution
90  const float pt_scale = 900.0/m_minPt;//to re-scale original tunings done for the 900 MeV pT cut
91 
92  float maxCurv = ptCoeff/tripletPtMin;
93 
94  float maxKappa_high_eta = m_LRTmode ? 1.0*maxCurv : std::sqrt(0.8)*maxCurv;
95  float maxKappa_low_eta = m_LRTmode ? 1.0*maxCurv : std::sqrt(0.6)*maxCurv;
96 
97  if(!m_useOldTunings && !m_LRTmode) {//new settings for curvature cuts
98  maxKappa_high_eta = 4.75e-4f*pt_scale;
99  maxKappa_low_eta = 3.75e-4f*pt_scale;
100  }
101 
102  const float dphi_coeff = m_LRTmode ? 1.0*maxCurv : 0.68*maxCurv;
103 
104  const float minDeltaRadius = 2.0;
105 
106  float deltaPhi = 0.5f*m_phiSliceWidth;//the default sliding window along phi
107 
108  unsigned int nConnections = 0;
109 
110  edgeStorage.reserve(m_nMaxEdges);
111 
112  int nEdges = 0;
113 
114  for(const auto& bg : m_geo->bin_groups()) {//loop over bin groups
115 
116  TrigFTF_GNN_EtaBin& B1 = storage->getEtaBin(bg.first);
117 
118  if(B1.empty()) continue;
119 
120  float rb1 = B1.getMinBinRadius();
121 
122  for(const auto& b2_idx : bg.second) {
123 
124  const TrigFTF_GNN_EtaBin& B2 = storage->getEtaBin(b2_idx);
125 
126  if(B2.empty()) continue;
127 
128  float rb2 = B2.getMaxBinRadius();
129 
130  if(m_useEtaBinning) {
131  float abs_dr = std::fabs(rb2-rb1);
132  if (m_useOldTunings) {
133  deltaPhi = min_deltaPhi + dphi_coeff*abs_dr;
134  }
135  else {
136  if(abs_dr < 60.0) {
137  deltaPhi = 0.002f + 4.33e-4f*pt_scale*abs_dr;
138  } else {
139  deltaPhi = 0.015f + 2.2e-4f*pt_scale*abs_dr;
140  }
141  }
142  }
143 
144  unsigned int first_it = 0;
145 
146  for(unsigned int n1Idx = 0;n1Idx<B1.m_vn.size();n1Idx++) {//loop over nodes in Layer 1
147 
148  std::vector<unsigned int>& v1In = B1.m_in[n1Idx];
149 
150  if(v1In.size() >= MAX_SEG_PER_NODE) continue;
151 
152  const std::array<float, 5>& n1pars = B1.m_params[n1Idx];
153 
154  float phi1 = n1pars[2];
155  float r1 = n1pars[3];
156  float z1 = n1pars[4];
157 
158  //sliding window phi1 +/- deltaPhi
159 
160  float minPhi = phi1 - deltaPhi;
161  float maxPhi = phi1 + deltaPhi;
162 
163  for(unsigned int n2PhiIdx = first_it; n2PhiIdx<B2.m_vPhiNodes.size();n2PhiIdx++) {//sliding window over nodes in Layer 2
164 
165  float phi2 = B2.m_vPhiNodes[n2PhiIdx].first;
166 
167  if(phi2 < minPhi) {
168  first_it = n2PhiIdx;
169  continue;
170  }
171  if(phi2 > maxPhi) break;
172 
173  unsigned int n2Idx = B2.m_vPhiNodes[n2PhiIdx].second;
174 
175  const std::vector<unsigned int>& v2In = B2.m_in[n2Idx];
176 
177  if(v2In.size() >= MAX_SEG_PER_NODE) continue;
178 
179  const std::array<float, 5>& n2pars = B2.m_params[n2Idx];
180 
181  float r2 = n2pars[3];
182 
183  float dr = r2 - r1;
184 
185  if(dr < minDeltaRadius) {
186  continue;
187  }
188 
189  float z2 = n2pars[4];
190 
191  float dz = z2 - z1;
192  float tau = dz/dr;
193  float ftau = std::fabs(tau);
194  if (ftau > 36.0) {
195  continue;
196  }
197 
198  if(ftau < n1pars[0]) continue;
199  if(ftau > n1pars[1]) continue;
200 
201  if(ftau < n2pars[0]) continue;
202  if(ftau > n2pars[1]) continue;
203 
204  if (m_doubletFilterRZ) {
205 
206  float z0 = z1 - r1*tau;
207 
208  if(z0 < min_z0 || z0 > max_z0) continue;
209 
210  float zouter = z0 + maxOuterRadius*tau;
211 
212  if(zouter < cut_zMinU || zouter > cut_zMaxU) continue;
213  }
214 
215  float curv = (phi2-phi1)/dr;
216  float abs_curv = std::abs(curv);
217 
218  if(ftau < 4.0) {//eta = 2.1
219  if(abs_curv > maxKappa_low_eta) {
220  continue;
221  }
222  }
223  else {
224  if(abs_curv > maxKappa_high_eta) {
225  continue;
226  }
227  }
228 
229  float exp_eta = std::sqrt(1+tau*tau)-tau;
230 
231  if (m_matchBeforeCreate) {//match edge candidate against edges incoming to n2
232 
233  bool isGood = v2In.size() <= 2;//we must have enough incoming edges to decide
234 
235  if(!isGood) {
236 
237  float uat_1 = 1.0f/exp_eta;
238 
239  for(const auto& n2_in_idx : v2In) {
240 
241  float tau2 = edgeStorage.at(n2_in_idx).m_p[0];
242  float tau_ratio = tau2*uat_1 - 1.0f;
243 
244  if(std::fabs(tau_ratio) > cut_tau_ratio_max){//bad match
245  continue;
246  }
247  isGood = true;//good match found
248  break;
249  }
250  }
251 
252  if(!isGood) {//no match found, skip creating [n1 <- n2] edge
253  continue;
254  }
255  }
256 
257  float dPhi2 = curv*r2;
258  float dPhi1 = curv*r1;
259 
260  if(nEdges < m_nMaxEdges) {
261 
262  edgeStorage.emplace_back(B1.m_vn[n1Idx], B2.m_vn[n2Idx], exp_eta, curv, phi1 + dPhi1);
263 
264  if(v1In.size() < MAX_SEG_PER_NODE) v1In.push_back(nEdges);
265 
266  int outEdgeIdx = nEdges;
267 
268  float uat_2 = 1/exp_eta;
269  float Phi2 = phi2 + dPhi2;
270  float curv2 = curv;
271 
272  for(const auto& inEdgeIdx : v2In) {//looking for neighbours of the new edge
273 
274  TrigFTF_GNN_Edge* pS = &(edgeStorage.at(inEdgeIdx));
275 
276  if(pS->m_nNei >= N_SEG_CONNS) continue;
277 
278  float tau_ratio = pS->m_p[0]*uat_2 - 1.0f;
279 
280  if(std::abs(tau_ratio) > cut_tau_ratio_max){//bad match
281  continue;
282  }
283 
284  float dPhi = Phi2 - pS->m_p[2];
285 
286  if(dPhi<-M_PI) dPhi += M_2PI;
287  else if(dPhi>M_PI) dPhi -= M_2PI;
288 
289  if(dPhi < -cut_dphi_max || dPhi > cut_dphi_max) {
290  continue;
291  }
292 
293  float dcurv = curv2 - pS->m_p[1];
294 
295  if(dcurv < -cut_dcurv_max || dcurv > cut_dcurv_max) {
296  continue;
297  }
298 
299  pS->m_vNei[pS->m_nNei++] = outEdgeIdx;
300 
301  nConnections++;
302 
303  }
304  nEdges++;
305  }
306  } //loop over n2 (outer) nodes
307  } //loop over n1 (inner) nodes
308  } //loop over bins in Layer 2
309  } //loop over bin groups
310 
311  if(nEdges >= m_nMaxEdges) {
312  ATH_MSG_WARNING("Maximum number of graph edges exceeded - possible efficiency loss "<< nEdges);
313  }
314 
315  return std::make_pair(nEdges, nConnections);
316 }
317 
318 int SeedingToolBase::runCCA(int nEdges, std::vector<TrigFTF_GNN_Edge>& edgeStorage) const {
319 
320  const int maxIter = 15;
321 
322  int maxLevel = 0;
323 
324  int iter = 0;
325 
326  std::vector<TrigFTF_GNN_Edge*> v_old;
327 
328  for(int edgeIndex=0;edgeIndex<nEdges;edgeIndex++) {
329 
330  TrigFTF_GNN_Edge* pS = &(edgeStorage[edgeIndex]);
331  if(pS->m_nNei == 0) continue;
332 
333  v_old.push_back(pS);//TO-DO: increment level for segments as they already have at least one neighbour
334  }
335 
336  for(;iter<maxIter;iter++) {
337 
338  //generate proposals
339  std::vector<TrigFTF_GNN_Edge*> v_new;
340  v_new.clear();
341  v_new.reserve(v_old.size());
342 
343  for(auto pS : v_old) {
344 
345  int next_level = pS->m_level;
346 
347  for(int nIdx=0;nIdx<pS->m_nNei;nIdx++) {
348 
349  unsigned int nextEdgeIdx = pS->m_vNei[nIdx];
350 
351  TrigFTF_GNN_Edge* pN = &(edgeStorage[nextEdgeIdx]);
352 
353  if(pS->m_level == pN->m_level) {
354  next_level = pS->m_level + 1;
355  v_new.push_back(pS);
356  break;
357  }
358  }
359 
360  pS->m_next = next_level;//proposal
361  }
362 
363  //update
364 
365  int nChanges = 0;
366 
367  for(auto pS : v_new) {
368  if(pS->m_next != pS->m_level) {
369  nChanges++;
370  pS->m_level = pS->m_next;
371  if(maxLevel < pS->m_level) maxLevel = pS->m_level;
372  }
373  }
374 
375  if(nChanges == 0) break;
376 
377 
378  v_old = std::move(v_new);
379  v_new.clear();
380  }
381 
382  return maxLevel;
383 }
384 
TrigFTF_GNN_EtaBin
Definition: GNN_DataStorage.h:40
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
PixelID.h
This is an Identifier helper class for the Pixel subdetector. This class is a factory for creating co...
SeedingToolBase::m_layerGeometry
std::vector< TrigInDetSiLayer > m_layerGeometry
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:72
SeedingToolBase::m_matchBeforeCreate
BooleanProperty m_matchBeforeCreate
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:57
IRegSelTool.h
createLinkingScheme.iter
iter
Definition: createLinkingScheme.py:62
python.tests.PyTestsLib.finalize
def finalize(self)
_info( "content of StoreGate..." ) self.sg.dump()
Definition: PyTestsLib.py:50
TrigFTF_GNN_EtaBin::m_in
std::vector< std::vector< unsigned int > > m_in
Definition: GNN_DataStorage.h:72
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
SCT_ID.h
This is an Identifier helper class for the SCT subdetector. This class is a factory for creating comp...
SeedingToolBase::initialize
virtual StatusCode initialize()
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.cxx:19
SeedingToolBase::m_pixelId
const PixelID * m_pixelId
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:47
StandaloneBunchgroupHandler.bg
bg
Definition: StandaloneBunchgroupHandler.py:241
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
xAOD::deltaPhi
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap setEtaBin setIsTgcFailure setDeltaPt deltaPhi
Definition: L2StandAloneMuon_v1.cxx:161
SeedingToolBase::buildTheGraph
std::pair< int, int > buildTheGraph(const IRoiDescriptor &, const std::unique_ptr< GNN_DataStorage > &, std::vector< GNN_Edge > &) const
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.cxx:71
initialize
void initialize()
Definition: run_EoverP.cxx:894
TrigFTF_GNN_Edge::m_vNei
unsigned int m_vNei[N_SEG_CONNS]
Definition: GNN_DataStorage.h:133
SeedingToolBase::m_nMaxEdges
IntegerProperty m_nMaxEdges
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:60
SeedingToolBase::m_sctId
const SCT_ID * m_sctId
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:46
SeedingToolBase::m_connector
std::unique_ptr< GNN_FasTrackConnector > m_connector
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:71
M_PI
#define M_PI
Definition: ActiveFraction.h:11
SeedingToolBase::m_filter_phi
BooleanProperty m_filter_phi
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:49
python.TurnDataReader.dr
dr
Definition: TurnDataReader.py:111
IRoiDescriptor::dzdrMinus
virtual double dzdrMinus() const =0
return the gradients
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
IRoiDescriptor::dzdrPlus
virtual double dzdrPlus() const =0
N_SEG_CONNS
#define N_SEG_CONNS
Definition: GNN_DataStorage.h:14
AtlasDetectorID.h
This class provides an interface to generate or decode an identifier for the upper levels of the dete...
TrigFTF_GNN_EtaBin::empty
bool empty() const
Definition: GNN_DataStorage.h:56
SeedingToolBase::m_LRTmode
BooleanProperty m_LRTmode
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:51
TrigFTF_GNN_Edge
Definition: GNN_DataStorage.h:106
SeedingToolBase.h
TrigFTF_GNN_EtaBin::m_vPhiNodes
std::vector< std::pair< float, unsigned int > > m_vPhiNodes
Definition: GNN_DataStorage.h:71
TrigFTF_GNN_Edge::m_level
signed char m_level
Definition: GNN_DataStorage.h:128
SeedingToolBase::m_minPt
FloatProperty m_minPt
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:58
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
IRoiDescriptor
Describes the API of the Region of Ineterest geometry.
Definition: IRoiDescriptor.h:23
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TauGNNUtils::Variables::Track::dPhi
bool dPhi(const xAOD::TauJet &tau, const xAOD::TauTrack &track, double &out)
Definition: TauGNNUtils.cxx:549
SeedingToolBase::m_atlasId
const AtlasDetectorID * m_atlasId
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:45
SeedingToolBase::finalize
virtual StatusCode finalize()
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.cxx:66
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
hist_file_dump.f
f
Definition: hist_file_dump.py:140
GNN_TrackingFilter.h
MAX_SEG_PER_NODE
#define MAX_SEG_PER_NODE
Definition: GNN_DataStorage.h:13
TRT::Track::z0
@ z0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:63
TrigFTF_GNN_DataStorage::getEtaBin
TrigFTF_GNN_EtaBin & getEtaBin(int idx)
Definition: GNN_DataStorage.h:93
SeedingToolBase::m_connectionFile
StringProperty m_connectionFile
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:62
TrigFTF_GNN_EtaBin::getMaxBinRadius
float getMaxBinRadius() const
Definition: GNN_DataStorage.h:66
SeedingToolBase::m_doubletFilterRZ
BooleanProperty m_doubletFilterRZ
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:55
SeedingToolBase::m_layerNumberTool
ToolHandle< ITrigL2LayerNumberTool > m_layerNumberTool
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:43
SeedingToolBase::m_useEtaBinning
BooleanProperty m_useEtaBinning
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:56
SeedingToolBase::m_geo
std::unique_ptr< const TrigFTF_GNN_Geometry > m_geo
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:73
PathResolver.h
SeedingToolBase::m_etaBinOverride
FloatProperty m_etaBinOverride
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:59
SeedingToolBase::m_phiSliceWidth
float m_phiSliceWidth
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:69
TrigFTF_GNN_Edge::m_nNei
unsigned char m_nNei
Definition: GNN_DataStorage.h:130
IRoiDescriptor::zedPlus
virtual double zedPlus() const =0
the zed and eta values at the most forward and most rear ends of the RoI
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
PathResolver::find_file
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
Definition: PathResolver.cxx:183
TrigFTF_GNN_Edge::m_p
float m_p[3]
Definition: GNN_DataStorage.h:131
IRoiDescriptor::zedMinus
virtual double zedMinus() const =0
SeedingToolBase::m_useML
BooleanProperty m_useML
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:52
calibdata.copy
bool copy
Definition: calibdata.py:26
SeedingToolBase::m_useOldTunings
BooleanProperty m_useOldTunings
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:65
M_2PI
#define M_2PI
Definition: CaloGpuGeneral_fnc.cxx:8
TrigFTF_GNN_EtaBin::m_vn
std::vector< const TrigFTF_GNN_Node * > m_vn
Definition: GNN_DataStorage.h:70
SeedingToolBase::m_tau_ratio_cut
FloatProperty m_tau_ratio_cut
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:67
SeedingToolBase::runCCA
int runCCA(int, std::vector< GNN_Edge > &) const
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.cxx:318
SeedingToolBase::m_nMaxPhiSlice
UnsignedIntegerProperty m_nMaxPhiSlice
Definition: TrigInDetPattRecoTools/src/SeedingToolBase.h:54
TrigFTF_GNN_EtaBin::getMinBinRadius
float getMinBinRadius() const
Definition: GNN_DataStorage.h:62
TrigFTF_GNN_EtaBin::m_params
std::vector< std::array< float, 5 > > m_params
Definition: GNN_DataStorage.h:73