ATLAS Offline Software
FPGATrackSimGNNGraphConstructionTool.cxx
Go to the documentation of this file.
1 // Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
4 
5 #include <TFile.h>
6 #include <TTree.h>
8 
10 // AthAlgTool
11 
12 FPGATrackSimGNNGraphConstructionTool::FPGATrackSimGNNGraphConstructionTool(const std::string& algname, const std::string &name, const IInterface *ifc)
13  : AthAlgTool(algname, name, ifc) {}
14 
16 {
17  ATH_CHECK(m_FPGATrackSimMapping.retrieve());
18  if(m_graphTool == "ModuleMap") {
19  if (m_FPGATrackSimMapping->getGNNModuleMapString() != "") {
20  m_moduleMapPath = m_FPGATrackSimMapping->getGNNModuleMapString();
21  }
22  else {
23  ATH_MSG_ERROR("Path to 1st stage NN-based fake track removal ONNX file is empty! If you want to run this pipeline, you need to provide an input file.");
24  return StatusCode::FAILURE;
25  }
26 
27  if(m_moduleMapType == "doublet") {
28  loadDoubletModuleMap(); // Load the doublet module map and store entry branches in vectors
29  }
30  }
31  else if(m_graphTool == "MetricLearning") {
32  ATH_CHECK( m_MLInferenceTool.retrieve() );
33  m_MLInferenceTool->printModelInfo();
34  assert(m_MLFeatureNamesVec.size() == m_MLFeatureScalesVec.size());
35  }
36 
37  return StatusCode::SUCCESS;
38 }
39 
41 // Functions
42 
43 StatusCode FPGATrackSimGNNGraphConstructionTool::getEdges(const std::vector<std::shared_ptr<FPGATrackSimGNNHit>> & hits, std::vector<std::shared_ptr<FPGATrackSimGNNEdge>> & edges)
44 {
45  if(m_graphTool == "ModuleMap") {
46  doModuleMap(hits, edges);
47  }
48  else if(m_graphTool == "MetricLearning") {
49  doMetricLearning(hits, edges);
50  }
51 
52  return StatusCode::SUCCESS;
53 }
54 
56 {
57  std::unique_ptr<TFile> file(TFile::Open(m_moduleMapPath.c_str()));
58  std::unique_ptr<TTree> tree(static_cast<TTree*>(file->Get("TreeModuleDoublet")));
59 
60  unsigned int mid1_value = 0;
61  unsigned int mid2_value = 0;
62  float z0min_12_value = 0.0;
63  float dphimin_12_value = 0.0;
64  float phislopemin_12_value = 0.0;
65  float detamin_12_value = 0.0;
66  float z0max_12_value = 0.0;
67  float dphimax_12_value = 0.0;
68  float phislopemax_12_value = 0.0;
69  float detamax_12_value = 0.0;
70 
71  tree->SetBranchAddress("Module1", &mid1_value);
72  tree->SetBranchAddress("Module2", &mid2_value);
73  tree->SetBranchAddress("z0min_12", &z0min_12_value);
74  tree->SetBranchAddress("dphimin_12", &dphimin_12_value);
75  tree->SetBranchAddress("phiSlopemin_12", &phislopemin_12_value);
76  tree->SetBranchAddress("detamin_12", &detamin_12_value);
77  tree->SetBranchAddress("z0max_12", &z0max_12_value);
78  tree->SetBranchAddress("dphimax_12", &dphimax_12_value);
79  tree->SetBranchAddress("phiSlopemax_12", &phislopemax_12_value);
80  tree->SetBranchAddress("detamax_12", &detamax_12_value);
81 
82  int64_t nEntries = tree->GetEntries();
83  for (int64_t i = 0; i < nEntries; ++i) {
84  tree->GetEntry(i);
85  m_mid1.emplace_back(mid1_value);
86  m_mid2.emplace_back(mid2_value);
87  m_z0min_12.emplace_back(z0min_12_value);
88  m_dphimin_12.emplace_back(dphimin_12_value);
89  m_phislopemin_12.emplace_back(phislopemin_12_value);
90  m_detamin_12.emplace_back(detamin_12_value);
91  m_z0max_12.emplace_back(z0max_12_value);
92  m_dphimax_12.emplace_back(dphimax_12_value);
93  m_phislopemax_12.emplace_back(phislopemax_12_value);
94  m_detamax_12.emplace_back(detamax_12_value);
95  }
96 }
97 
98 void FPGATrackSimGNNGraphConstructionTool::doModuleMap(const std::vector<std::shared_ptr<FPGATrackSimGNNHit>> & hits, std::vector<std::shared_ptr<FPGATrackSimGNNEdge>> & edges)
99 {
100  // Use Module Map method for edge building
101  // Two types of module maps: Doublet and Triplet
102  // For each type of module map there is three functions: minmax, meanrms, and hybrid
103  // Use the proper configuration set by the input script and passed as Gaudi::Property variables
104  // Currently only Doublet Module Map with minmax cuts exist, but others can be implemented later on as desired
105 
106  if(m_moduleMapType == "doublet") {
107  getDoubletEdges(hits, edges);
108  }
109 }
110 
111 void FPGATrackSimGNNGraphConstructionTool::getDoubletEdges(const std::vector<std::shared_ptr<FPGATrackSimGNNHit>> & hits, std::vector<std::shared_ptr<FPGATrackSimGNNEdge>> & edges)
112 {
113  // Take the list of hits and use the doublet module map to generate all the edges between hits that pass the doublet cuts
114 
115  for (size_t i = 0; i < m_mid2.size(); i++) {
116  std::vector<std::shared_ptr<FPGATrackSimGNNHit>> hit1_matches;
117  std::vector<std::shared_ptr<FPGATrackSimGNNHit>> hit2_matches;
118 
119  std::vector<int> hit1_indices;
120  std::vector<int> hit2_indices;
121 
122  for (size_t j = 0; j < hits.size(); j++) {
123  if (hits[j]->getIdentifier() == m_mid1[i]) {
124  hit1_matches.emplace_back(hits[j]);
125  hit1_indices.emplace_back(j);
126  }
127  if (hits[j]->getIdentifier() == m_mid2[i]) {
128  hit2_matches.emplace_back(hits[j]);
129  hit2_indices.emplace_back(j);
130  }
131  }
132 
133  for (size_t h1 = 0; h1 < hit1_matches.size(); h1++) {
134  for (size_t h2 = 0; h2 < hit2_matches.size(); h2++) {
135  applyDoubletCuts(hit1_matches[h1], hit2_matches[h2], edges, hit1_indices[h1], hit2_indices[h2], i);
136  }
137  }
138  }
139 }
140 
141 void FPGATrackSimGNNGraphConstructionTool::applyDoubletCuts(const std::shared_ptr<FPGATrackSimGNNHit> & hit1, const std::shared_ptr<FPGATrackSimGNNHit> & hit2, std::vector<std::shared_ptr<FPGATrackSimGNNEdge>> & edges, int hit1_index, int hit2_index, unsigned int modulemap_id)
142 {
143  // Four types of doublet cuts (dEta, z0, dPhi, phiSlope)
144  // If an edge passes all four, then it is a valid edge and can be stored
145 
146  // delta_eta cuts
147  float deta = hit1->getEta() - hit2->getEta();
148  if(!doMask(deta, m_detamin_12[modulemap_id], m_detamax_12[modulemap_id])) return;
149 
150  // z0 cuts
151  float dz = hit2->getZ() - hit1->getZ();
152  float dr = hit2->getR() - hit1->getR();
153  float z0 = dr==0. ? 0. : hit1->getZ() - (hit1->getR() * dz / dr);
154  if(!doMask(z0, m_z0min_12[modulemap_id], m_z0max_12[modulemap_id])) return;
155 
156  // delta_phi cuts
157  float dphi = P4Helpers::deltaPhi(hit2->getPhi(),hit1->getPhi());
158  if(!doMask(dphi, m_dphimin_12[modulemap_id], m_dphimax_12[modulemap_id])) return;
159 
160  // phislope cuts
161  float phislope = dr==0. ? 0. : dphi / dr;
162  if(!doMask(phislope, m_phislopemin_12[modulemap_id], m_phislopemax_12[modulemap_id])) return;
163 
164  // if pass all doublet cuts, then record the edge information
165  std::shared_ptr<FPGATrackSimGNNEdge> edge = std::make_shared<FPGATrackSimGNNEdge>();
166  edge->setEdgeIndex1(hit1_index);
167  edge->setEdgeIndex2(hit2_index);
168  edges.emplace_back(edge);
169 }
170 
172 {
173  bool mask = false;
174  if(m_moduleMapFunc == "minmax") {
175  mask = doMinMaxMask(val, min, max);
176  }
177 
178  return mask;
179 }
180 
182 {
183  bool mask = false;
184 
185  if((val <= max * (1.0 + featureSign(max) * m_moduleMapTol)) &&
186  (val >= min * (1.0 - featureSign(min) * m_moduleMapTol))) {
187  mask = true;
188  }
189 
190  return mask;
191 }
192 
194 {
195  if(feature < 0.0) { return -1.0; }
196  else if(feature > 0.0) { return 1.0; }
197  else { return 0.0; }
198 }
199 
200 void FPGATrackSimGNNGraphConstructionTool::doMetricLearning(const std::vector<std::shared_ptr<FPGATrackSimGNNHit>> & hits, std::vector<std::shared_ptr<FPGATrackSimGNNEdge>> & edges)
201 {
202  // Use Metric Learning for edge construction
203  // Clustering properties can be set in the input scripta as Gaudi::Property variables
204  std::vector<float> gNodeFeatures = getNodeFeatures(hits);
205  std::vector<float> gEmbedded = embed(hits);
206  doClustering(hits, edges, gEmbedded);
207 }
208 
209 std::vector<float> FPGATrackSimGNNGraphConstructionTool::getNodeFeatures(const std::vector<std::shared_ptr<FPGATrackSimGNNHit>> & hits)
210 {
211  std::vector<float> gNodeFeatures;
212 
213  for(auto hit : hits) {
214  std::map<std::string, float> features;
215  features["r"] = hit->getR();
216  features["phi"] = hit->getPhi();
217  features["z"] = hit->getZ();
218 
219  for(size_t i = 0; i < m_MLFeatureNamesVec.size(); i++){
220  gNodeFeatures.push_back(
222  }
223  }
224  return gNodeFeatures;
225 }
226 
227 std::vector<float> FPGATrackSimGNNGraphConstructionTool::embed(const std::vector<std::shared_ptr<FPGATrackSimGNNHit>> & hits)
228 {
229  // Use the ML network to embed the hits in a 12-dim latent space
230  std::vector<float> gNodeFeatures = getNodeFeatures(hits);
231  std::vector<float> gEmbedded;
232 
233  std::vector<Ort::Value> gInputTensor;
234  StatusCode s = m_MLInferenceTool->addInput(gInputTensor, gNodeFeatures, 0, hits.size());
235  std::vector<Ort::Value> gOutputTensor;
236  s = m_MLInferenceTool->addOutput(gOutputTensor, gEmbedded, 0, hits.size());
237  s = m_MLInferenceTool->inference(gInputTensor, gOutputTensor);
238 
239  return gEmbedded;
240 }
241 
242 void FPGATrackSimGNNGraphConstructionTool::doClustering(const std::vector<std::shared_ptr<FPGATrackSimGNNHit>> & hits, std::vector<std::shared_ptr<FPGATrackSimGNNEdge>> & edges,
243  std::vector<float> & gEmbedded)
244 {
245  // Create graph edges based on the hits distance in the latent space
246  // Creates a directed graph
247  int n_dim = 12;
248  int size = hits.size();
249  float r_squared = m_metricLearningR*m_metricLearningR;
250  int index1 = 0;
251  int index2 = 0;
252  int count = 0;
253  float distance = 0.;
254  std::vector<float> start(n_dim);
255 
256  // Loop over all hits
257  for(int k = 0; k < size; ++k){
258  count = 0;
259  // Setup current hit
260  for(int j = 0; j < n_dim; ++j){
261  start[j] = gEmbedded[k*n_dim + j];
262  }
263  // Loop over the hits not yet checked
264  for (int i = k + 1; i < size; ++i){
265  distance = 0.;
266  for(int d = 0; d < n_dim; ++d){
267  distance += (start[d] - gEmbedded[i*n_dim + d]) * (start[d] - gEmbedded[i*n_dim + d]);
268  }
269  // Store edge if the distance between the hits meets is below the limit
270  if(distance < r_squared){
271  std::shared_ptr<FPGATrackSimGNNEdge> edge = std::make_shared<FPGATrackSimGNNEdge>();
272  // Set order of edge indices to make a directed graph
273  float d_i_sq = (hits[i]->getR() * hits[i]->getR()) + (hits[i]->getZ() * hits[i]->getZ());
274  float d_k_sq = (hits[k]->getR() * hits[k]->getR()) + (hits[k]->getZ() * hits[k]->getZ());
275  if (d_i_sq < d_k_sq){
276  index1 = i;
277  index2 = k;
278  } else {
279  index1 = k;
280  index2 = i;
281  }
282 
283  edge->setEdgeIndex1(index1);
284  edge->setEdgeIndex2(index2);
285  edges.emplace_back(edge);
286  ++count;
287  }
288  // Upper limit for connections of the same hit
290  break;
291  }
292  }
293 
294  }
295 }
getMenu.algname
algname
Definition: getMenu.py:54
FPGATrackSimGNNGraphConstructionTool::getNodeFeatures
std::vector< float > getNodeFeatures(const std::vector< std::shared_ptr< FPGATrackSimGNNHit >> &hits)
Definition: FPGATrackSimGNNGraphConstructionTool.cxx:209
TRTCalib_Extractor.hits
hits
Definition: TRTCalib_Extractor.py:35
FPGATrackSimGNNGraphConstructionTool::m_MLFeatureScalesVec
FloatArrayProperty m_MLFeatureScalesVec
Definition: FPGATrackSimGNNGraphConstructionTool.h:102
FPGATrackSimGNNGraphConstructionTool::m_metricLearningMaxN
Gaudi::Property< int > m_metricLearningMaxN
Definition: FPGATrackSimGNNGraphConstructionTool.h:61
hist_file_dump.d
d
Definition: hist_file_dump.py:142
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
FPGATrackSimGNNGraphConstructionTool::embed
std::vector< float > embed(const std::vector< std::shared_ptr< FPGATrackSimGNNHit >> &hits)
Definition: FPGATrackSimGNNGraphConstructionTool.cxx:227
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
FPGATrackSimGNNGraphConstructionTool::m_dphimin_12
std::vector< float > m_dphimin_12
Definition: FPGATrackSimGNNGraphConstructionTool.h:71
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:13
tree
TChain * tree
Definition: tile_monitor.h:30
FPGATrackSimGNNGraphConstructionTool::m_moduleMapFunc
Gaudi::Property< std::string > m_moduleMapFunc
Definition: FPGATrackSimGNNGraphConstructionTool.h:58
FPGATrackSimGNNGraphConstructionTool::m_moduleMapTol
Gaudi::Property< float > m_moduleMapTol
Definition: FPGATrackSimGNNGraphConstructionTool.h:59
python.TurnDataReader.dr
dr
Definition: TurnDataReader.py:111
FPGATrackSimGNNEdge::setEdgeIndex1
void setEdgeIndex1(int v)
Definition: FPGATrackSimGNNEdge.h:27
FPGATrackSimGNNGraphConstructionTool::FPGATrackSimGNNGraphConstructionTool
FPGATrackSimGNNGraphConstructionTool(const std::string &, const std::string &, const IInterface *)
Definition: FPGATrackSimGNNGraphConstructionTool.cxx:12
read_hist_ntuple.h1
h1
Definition: read_hist_ntuple.py:21
FPGATrackSimGNNGraphConstructionTool::m_MLFeatureNamesVec
StringArrayProperty m_MLFeatureNamesVec
Definition: FPGATrackSimGNNGraphConstructionTool.h:98
FPGATrackSimGNNEdge::setEdgeIndex2
void setEdgeIndex2(int v)
Definition: FPGATrackSimGNNEdge.h:28
FPGATrackSimGNNGraphConstructionTool.h
Implements graph construction tool to build edges (connections) between hits.
XMLtoHeader.count
count
Definition: XMLtoHeader.py:84
python.utils.AtlRunQueryLookup.mask
string mask
Definition: AtlRunQueryLookup.py:459
FPGATrackSimGNNGraphConstructionTool::applyDoubletCuts
void applyDoubletCuts(const std::shared_ptr< FPGATrackSimGNNHit > &hit1, const std::shared_ptr< FPGATrackSimGNNHit > &hit2, std::vector< std::shared_ptr< FPGATrackSimGNNEdge >> &edges, int hit1_index, int hit2_index, unsigned int modulemap_id)
Definition: FPGATrackSimGNNGraphConstructionTool.cxx:141
FPGATrackSimGNNHit::getR
float getR() const
Definition: FPGATrackSimGNNHit.h:44
FPGATrackSimGNNGraphConstructionTool::m_z0min_12
std::vector< float > m_z0min_12
Definition: FPGATrackSimGNNGraphConstructionTool.h:70
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
P4Helpers::deltaPhi
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
Definition: P4Helpers.h:34
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Trk::index1
@ index1
Definition: BoundarySurfaceFace.h:48
lumiFormat.i
int i
Definition: lumiFormat.py:85
FPGATrackSimGNNGraphConstructionTool::doMetricLearning
void doMetricLearning(const std::vector< std::shared_ptr< FPGATrackSimGNNHit >> &hits, std::vector< std::shared_ptr< FPGATrackSimGNNEdge >> &edges)
Definition: FPGATrackSimGNNGraphConstructionTool.cxx:200
FPGATrackSimGNNGraphConstructionTool::doMinMaxMask
bool doMinMaxMask(float val, float min, float max)
Definition: FPGATrackSimGNNGraphConstructionTool.cxx:181
FPGATrackSimGNNHit::getEta
float getEta() const
Definition: FPGATrackSimGNNHit.h:46
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
FPGATrackSimGNNGraphConstructionTool::initialize
virtual StatusCode initialize() override
Definition: FPGATrackSimGNNGraphConstructionTool.cxx:15
FPGATrackSimGNNGraphConstructionTool::m_phislopemin_12
std::vector< float > m_phislopemin_12
Definition: FPGATrackSimGNNGraphConstructionTool.h:72
FPGATrackSimGNNGraphConstructionTool::m_MLInferenceTool
ToolHandle< AthOnnx::IOnnxRuntimeInferenceTool > m_MLInferenceTool
Definition: FPGATrackSimGNNGraphConstructionTool.h:50
FPGATrackSimGNNGraphConstructionTool::m_FPGATrackSimMapping
ServiceHandle< IFPGATrackSimMappingSvc > m_FPGATrackSimMapping
Definition: FPGATrackSimGNNGraphConstructionTool.h:51
FPGATrackSimGNNGraphConstructionTool::m_detamin_12
std::vector< float > m_detamin_12
Definition: FPGATrackSimGNNGraphConstructionTool.h:73
file
TFile * file
Definition: tile_monitor.h:29
FPGATrackSimGNNGraphConstructionTool::getDoubletEdges
void getDoubletEdges(const std::vector< std::shared_ptr< FPGATrackSimGNNHit >> &hits, std::vector< std::shared_ptr< FPGATrackSimGNNEdge >> &edges)
Definition: FPGATrackSimGNNGraphConstructionTool.cxx:111
FPGATrackSimGNNHit::getZ
float getZ() const
Definition: FPGATrackSimGNNHit.h:43
FPGATrackSimGNNGraphConstructionTool::m_phislopemax_12
std::vector< float > m_phislopemax_12
Definition: FPGATrackSimGNNGraphConstructionTool.h:76
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
FPGATrackSimGNNGraphConstructionTool::m_moduleMapType
Gaudi::Property< std::string > m_moduleMapType
Definition: FPGATrackSimGNNGraphConstructionTool.h:57
FPGATrackSimGNNGraphConstructionTool::m_z0max_12
std::vector< float > m_z0max_12
Definition: FPGATrackSimGNNGraphConstructionTool.h:74
TRT::Track::z0
@ z0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:63
FPGATrackSimGNNGraphConstructionTool::m_moduleMapPath
std::string m_moduleMapPath
Definition: FPGATrackSimGNNGraphConstructionTool.h:67
FPGATrackSimGNNGraphConstructionTool::m_mid2
std::vector< unsigned int > m_mid2
Definition: FPGATrackSimGNNGraphConstructionTool.h:69
P4Helpers.h
Trk::index2
@ index2
Definition: BoundarySurfaceFace.h:49
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
FPGATrackSimGNNGraphConstructionTool::doModuleMap
void doModuleMap(const std::vector< std::shared_ptr< FPGATrackSimGNNHit >> &hits, std::vector< std::shared_ptr< FPGATrackSimGNNEdge >> &edges)
Definition: FPGATrackSimGNNGraphConstructionTool.cxx:98
FPGATrackSimGNNGraphConstructionTool::m_detamax_12
std::vector< float > m_detamax_12
Definition: FPGATrackSimGNNGraphConstructionTool.h:77
FPGATrackSimGNNGraphConstructionTool::getEdges
virtual StatusCode getEdges(const std::vector< std::shared_ptr< FPGATrackSimGNNHit >> &hits, std::vector< std::shared_ptr< FPGATrackSimGNNEdge >> &edges)
Definition: FPGATrackSimGNNGraphConstructionTool.cxx:43
FPGATrackSimGNNGraphConstructionTool::m_mid1
std::vector< unsigned int > m_mid1
Definition: FPGATrackSimGNNGraphConstructionTool.h:68
FPGATrackSimGNNGraphConstructionTool::doClustering
void doClustering(const std::vector< std::shared_ptr< FPGATrackSimGNNHit >> &hits, std::vector< std::shared_ptr< FPGATrackSimGNNEdge >> &edges, std::vector< float > &gEmbedded)
Definition: FPGATrackSimGNNGraphConstructionTool.cxx:242
FPGATrackSimGNNGraphConstructionTool::doMask
bool doMask(float val, float min, float max)
Definition: FPGATrackSimGNNGraphConstructionTool.cxx:171
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
FPGATrackSimGNNGraphConstructionTool::m_metricLearningR
Gaudi::Property< float > m_metricLearningR
Definition: FPGATrackSimGNNGraphConstructionTool.h:60
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
FPGATrackSimGNNHit::getPhi
float getPhi() const
Definition: FPGATrackSimGNNHit.h:45
FPGATrackSimGNNGraphConstructionTool::featureSign
float featureSign(float feature)
Definition: FPGATrackSimGNNGraphConstructionTool.cxx:193
AthAlgTool
Definition: AthAlgTool.h:26
dqBeamSpot.nEntries
int nEntries
Definition: dqBeamSpot.py:72
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
FPGATrackSimGNNGraphConstructionTool::m_graphTool
Gaudi::Property< std::string > m_graphTool
Definition: FPGATrackSimGNNGraphConstructionTool.h:56
FPGATrackSimGNNGraphConstructionTool::loadDoubletModuleMap
void loadDoubletModuleMap()
Definition: FPGATrackSimGNNGraphConstructionTool.cxx:55
FPGATrackSimGNNGraphConstructionTool::m_dphimax_12
std::vector< float > m_dphimax_12
Definition: FPGATrackSimGNNGraphConstructionTool.h:75
fitman.k
k
Definition: fitman.py:528