ATLAS Offline Software
FPGATrackSimNNTrackTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
19 
21 FPGATrackSimNNTrackTool::FPGATrackSimNNTrackTool(const std::string &algname, const std::string &name, const IInterface *ifc) : FPGATrackSimTrackingToolBase(algname, name, ifc), OnnxRuntimeBase() {}
22 
23 
24 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
26  ATH_CHECK(m_FPGATrackSimMapping.retrieve());
27  ATH_CHECK(m_tHistSvc.retrieve());
28  if (m_useSpacePoints) ATH_CHECK(m_spRoadFilterTool.retrieve(EnableTool{m_spRoadFilterTool}));
29 
30  if (m_FPGATrackSimMapping->getFakeNNMapString() != "") {
31  m_fakeNN.initialize(m_FPGATrackSimMapping->getFakeNNMapString());
32  }
33  else {
34  ATH_MSG_ERROR("Path to NN-based fake track removal ONNX file is empty! If you want to run this pipeline, you need to provide an input file.");
35  return StatusCode::FAILURE;
36  }
37 
38  if (m_FPGATrackSimMapping->getParamNNMapString() != "") {
39  m_paramNN.initialize(m_FPGATrackSimMapping->getParamNNMapString());
40  }
41  else {
42  ATH_MSG_INFO("Path to NN-based track parameter estimation ONNX file is empty! Estimation is not run...");
43  m_useParamNN = false;
44  }
45 
46  return StatusCode::SUCCESS;
47 }
48 
49 void FPGATrackSimNNTrackTool::setTrackParameters(FPGATrackSimTrack& track, std::vector<float> inputTensorValues) {
50 
51  ATH_MSG_DEBUG("Running NN-based track parameter estimation!");
52  std::vector<float> paramNNoutput = m_paramNN.runONNXInference(inputTensorValues);
53 
54  ATH_MSG_DEBUG("Estimated Track Parameters");
55  for (unsigned int i = 0; i < paramNNoutput.size(); i++) {
56  ATH_MSG_DEBUG(paramNNoutput[i]);
57  }
58 
59  track.setQOverPt(paramNNoutput[0]);
60  track.setEta(paramNNoutput[1]);
61  track.setPhi(paramNNoutput[2]);
62  track.setD0(paramNNoutput[3]);
63  track.setZ0(paramNNoutput[4]);
64 }
65 
66 StatusCode FPGATrackSimNNTrackTool::getTracks(std::vector<std::shared_ptr<const FPGATrackSimRoad>> &roads, std::vector<FPGATrackSimTrack> &tracks) {
67 
68  ATH_CHECK(setRoadSectors(roads));
69  int n_track = 0;
70 
71  // Loop over roads
72  for (auto const &iroad : roads) {
73 
74  double y = iroad->getY();
75 
76  // Error checking
77  int sector = iroad->getSector();
78  if (sector < 0) {
79  ATH_MSG_DEBUG("Bad sector " << sector);
80  return StatusCode::SUCCESS;
81  }
82 
83  // Get info on layers with missing hits
84  int nMissing = 0;
85  layer_bitmask_t missing_mask = 0;
86 
87  // Just used to get number of layers considered
88  const FPGATrackSimPlaneMap *planeMap = nullptr;
89  if (!m_do2ndStage) planeMap = m_FPGATrackSimMapping->PlaneMap_1st(0);
90  else planeMap = m_FPGATrackSimMapping->PlaneMap_2nd(0);
91 
92  // Create a template track with common parameters filled already for
93  // initializing below
94  FPGATrackSimTrack temp;
96  temp.setNLayers(planeMap->getNLogiLayers());
97  temp.setBankID(-1);
98  temp.setPatternID(iroad->getPID());
99  temp.setFirstSectorID(iroad->getSector());
100  temp.setHitMap(missing_mask);
101  temp.setNMissing(nMissing);
102  temp.setQOverPt(y);
103 
104  temp.setSubRegion(iroad->getSubRegion());
105  temp.setHoughX(iroad->getX());
106  temp.setHoughY(iroad->getY());
107  temp.setHoughXBin(iroad->getXBin());
108  temp.setHoughYBin(iroad->getYBin());
109 
111  // Get a list of indices for all possible combinations given a certain
112  // number of layers
113  std::vector<std::vector<int>> combs =
114  getComboIndices(iroad->getNHits_layer());
115 
116  // Loop over possible combinations for this road
117  for (size_t icomb = 0; icomb < combs.size(); icomb++) {
118 
119  // list of indices for this particular combination
120  std::vector<int> const &hit_indices = combs[icomb];
121  std::vector<std::shared_ptr<const FPGATrackSimHit>> hit_list;
122 
123  // Loop over all layers
124  for (unsigned layer = 0; layer < planeMap->getNLogiLayers(); layer++) {
125 
126  // Check to see if this is a valid hit
127  if (hit_indices[layer] >= 0) {
128 
129  std::shared_ptr<const FPGATrackSimHit> hit = iroad->getHits(layer)[hit_indices[layer]];
130  // Add this hit to the road
131  if (hit->isReal()){
132  hit_list.push_back(hit);
133  }
134  }
135  }
136 
137  // TODO: for now ignore roads with non-real hits, because the network needs all hits as input
138  if (hit_list.size() < 9) continue;
139 
140  // Sort the list by radial distance
141  std::sort(hit_list.begin(), hit_list.end(),
142  [](std::shared_ptr<const FPGATrackSimHit> &hit1, std::shared_ptr<const FPGATrackSimHit> &hit2) {
143  double rho1 = std::hypot(hit1->getX(), hit1->getY());
144  double rho2 = std::hypot(hit2->getX(), hit2->getY());
145  return rho1 < rho2;
146  });
147 
148  std::vector<float> inputTensorValues;
149 
150 
151  int index = 1;
152  bool flipZ = false;
153  double rotateAngle = 0;
154  bool gotSecondSP = false;
155  float tmp_xf;
156  float tmp_yf;
157  float tmp_zf;
158 
159  // Loop over all hits
160  for (const auto &hit : hit_list) {
161 
162  // Need to rotate hits
163  float x0 = hit->getX();
164  float y0 = hit->getY();
165  float z0 = hit->getZ();
166  if (index == 1) {
167  if (z0 < 0)
168  flipZ = true;
169  rotateAngle = std::atan(x0 / y0);
170  if (y0 < 0)
171  rotateAngle += M_PI;
172  }
173 
174  float xf = x0 * std::cos(rotateAngle) - y0 * std::sin(rotateAngle);
175  float yf = x0 * std::sin(rotateAngle) + y0 * std::cos(rotateAngle);
176  float zf = z0;
177 
178  if (flipZ) zf = z0 * -1;
179 
180  // Get average of values for strip hit pairs
181  // TODO: this needs to be fixed in the future, for this to work for other cases
182  if (hit->isStrip()) {
183  if (!gotSecondSP) {
184  tmp_xf = xf;
185  tmp_yf = yf;
186  tmp_zf = zf;
187  gotSecondSP = true;
188  }
189  else {
190 
191  float xf_scaled = (xf + tmp_xf) / (2.*getXScale());
192  float yf_scaled = (yf + tmp_yf) / (2.*getYScale());
193  float zf_scaled = (zf + tmp_zf) / (2.*getZScale());
194 
195  // Get average of two hits for strip hits
196  inputTensorValues.push_back(xf_scaled);
197  inputTensorValues.push_back(yf_scaled);
198  inputTensorValues.push_back(zf_scaled);
199  index++;
200  gotSecondSP = false;
201  }
202  }
203  else {
204  float xf_scaled = (xf) / (getXScale());
205  float yf_scaled = (yf) / (getYScale());
206  float zf_scaled = (zf) / (getZScale());
207  inputTensorValues.push_back(xf_scaled);
208  inputTensorValues.push_back(yf_scaled);
209  inputTensorValues.push_back(zf_scaled);
210  index++;
211  }
212  }
213 
214  std::vector<float> NNoutput = m_fakeNN.runONNXInference(inputTensorValues);
215 
216  ATH_MSG_DEBUG("NN InputTensorValues:");
217  ATH_MSG_DEBUG(inputTensorValues);
218  ATH_MSG_DEBUG("NN output:" << NNoutput);
219 
220  float nn_val = NNoutput[0];
221 
222  // Save all hits on this road if it passes our "good" criteria
223  if (nn_val > m_NNCut) {
224 
225  // This is a track. Fill class and add to track list
226  n_track++;
227  FPGATrackSimTrack track_cand;
228  track_cand.setTrackID(n_track);
229  track_cand.setNLayers(planeMap->getNLogiLayers());
230  for (const auto &ihit : hit_list) {
231  unsigned int layer = ihit->getLayer();
232  track_cand.setFPGATrackSimHit(layer, *ihit);
233  }
234  // Nominal chi2ndof cut is 40 and we want to use NN>0.0075 (or
235  // NN<(1-0.0075) Nominal chi2ndof cut is 40 and we want to use NN>0.001
236  // (or NN<(1-0.1)
237  // the 5 comes from the 5 dof we nominally get from a chi2
238  double scale = m_chi2_scalefactor *
239  (track_cand.getNCoords() - track_cand.getNMissing() - 5);
240  double chi2 = scale * (1 - nn_val);
241  track_cand.setOrigChi2(chi2);
242  track_cand.setChi2(chi2);
243  tracks.push_back(track_cand);
244  }
245 
246 
247  if (m_useParamNN) {
248  for (auto& track : tracks) {
249  setTrackParameters(track, inputTensorValues);
250  }
251  }
252  } // loop over combinations
253 
254  } // loop over roads
255 
256  // Add truth info
257  for (FPGATrackSimTrack &t : tracks) {
258  compute_truth(t); // match the track to a geant particle using the
259  // channel-level geant info in the hit data.
260  }
261 
262  return StatusCode::SUCCESS;
263 }
264 
265 // Borrowed same code from TrackFitter - probably a nicer way to inherit instead
267  std::vector<FPGATrackSimMultiTruth> mtv;
268 
269  const FPGATrackSimPlaneMap* planeMap = nullptr;
270  if (!m_do2ndStage) planeMap = m_FPGATrackSimMapping->PlaneMap_1st(0);
271  else planeMap = m_FPGATrackSimMapping->PlaneMap_2nd(0);
272 
273  for (unsigned layer = 0; layer < planeMap->getNLogiLayers(); layer++) {
274  if (t.getHitMap() & (1 << planeMap->getCoordOffset(layer)))
275  continue; // no hit in this plane
276  // Sanity check that we have enough hits.
277  if (layer < t.getFPGATrackSimHits().size())
278  mtv.push_back(t.getFPGATrackSimHits().at(layer).getTruth());
279 
280  // adjust weight for hits without (and also with) a truth match, so that
281  // each is counted with the same weight.
282  mtv.back().assign_equal_normalization();
283  }
284 
287  // frac is then the fraction of the total number of hits on the track
288  // attributed to the barcode.
289 
292  const bool ok = mt.best(tbarcode, tfrac);
293  if (ok) {
294  t.setEventIndex(tbarcode.first);
295  t.setBarcode(tbarcode.second);
296  t.setBarcodeFrac(tfrac);
297  }
298 }
FPGATrackSimTrack::setHitMap
void setHitMap(unsigned int v)
Definition: FPGATrackSimTrack.h:101
OnnxRuntimeBase::runONNXInference
std::vector< float > runONNXInference(std::vector< float > &inputTensorValues) const
Definition: OnnxRuntimeBase.cxx:65
getMenu.algname
algname
Definition: getMenu.py:54
FPGATrackSimPlaneMap::getNLogiLayers
uint32_t getNLogiLayers() const
Definition: FPGATrackSimPlaneMap.h:75
FPGATrackSimTrack::setBankID
void setBankID(int v)
Definition: FPGATrackSimTrack.h:84
FPGATrackSimTrack::getNMissing
int getNMissing() const
Definition: FPGATrackSimTrack.h:52
FPGATrackSimNNTrackTool::getTracks
StatusCode getTracks(std::vector< std::shared_ptr< const FPGATrackSimRoad >> &roads, std::vector< FPGATrackSimTrack > &tracks)
Definition: FPGATrackSimNNTrackTool.cxx:66
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
FPGATrackSimNNMap.h
Map for NN tracking.
FPGATrackSimTrack
Definition: FPGATrackSimTrack.h:18
OnnxRuntimeBase::initialize
void initialize(TString)
Definition: OnnxRuntimeBase.cxx:16
FPGATrackSimTrack::setPatternID
void setPatternID(int v)
Definition: FPGATrackSimTrack.h:85
index
Definition: index.py:1
FPGATrackSimMultiTruth::Weight
float Weight
Definition: FPGATrackSimMultiTruth.h:50
FPGATrackSimNNTrackTool.h
Utilize NN score to build track candidates.
IFPGATrackSimMappingSvc.h
accumulate
bool accumulate(AccumulateMap &map, std::vector< module_t > const &modules, FPGATrackSimMatrixAccumulator const &acc)
Accumulates an accumulator (e.g.
Definition: FPGATrackSimMatrixAccumulator.cxx:22
python.HLT.MinBias.MinBiasMenuSequences.zf
zf
Definition: MinBiasMenuSequences.py:224
FPGATrackSimTrack::setNMissing
void setNMissing(int v)
Definition: FPGATrackSimTrack.h:99
FPGATrackSimHit::isReal
bool isReal() const
Definition: FPGATrackSimHit.cxx:40
FPGATrackSimNNTrackTool::m_fakeNN
OnnxRuntimeBase m_fakeNN
Definition: FPGATrackSimNNTrackTool.h:67
M_PI
#define M_PI
Definition: ActiveFraction.h:11
FPGATrackSimNNTrackTool::m_useParamNN
bool m_useParamNN
Definition: FPGATrackSimNNTrackTool.h:69
FPGATrackSimTrack::setHoughXBin
void setHoughXBin(unsigned v)
Definition: FPGATrackSimTrack.h:108
FPGATrackSimTrack::setFirstSectorID
void setFirstSectorID(int v)
Definition: FPGATrackSimTrack.h:86
FPGATrackSimTrack::getNCoords
int getNCoords() const
Definition: FPGATrackSimTrack.cxx:90
FPGATrackSimNNTrackTool::getXScale
static float getXScale()
Definition: FPGATrackSimNNTrackTool.h:51
FPGATrackSimMultiTruth.h
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
FPGATrackSimTrack::setFPGATrackSimHit
void setFPGATrackSimHit(unsigned i, const FPGATrackSimHit &hit)
Definition: FPGATrackSimTrack.cxx:99
FPGATrackSimTrack::setOrigChi2
void setOrigChi2(float v)
Definition: FPGATrackSimTrack.h:98
FPGATrackSimMultiTruth::best
bool best(FPGATrackSimMultiTruth::Barcode &code, FPGATrackSimMultiTruth::Weight &weight) const
Definition: FPGATrackSimMultiTruth.h:86
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
FPGATrackSimNNTrackTool::setTrackParameters
void setTrackParameters(FPGATrackSimTrack &track, std::vector< float > inputTensorValues)
Definition: FPGATrackSimNNTrackTool.cxx:49
FPGATrackSimNNTrackTool::m_tHistSvc
ServiceHandle< ITHistSvc > m_tHistSvc
Definition: FPGATrackSimNNTrackTool.h:64
FPGATrackSimTrackingToolBase
Definition: FPGATrackSimTrackingToolBase.h:21
FPGATrackSimPlaneMap::getCoordOffset
uint32_t getCoordOffset(size_t logiLayer) const
Definition: FPGATrackSimPlaneMap.h:92
FPGATrackSimTrack::setHoughYBin
void setHoughYBin(unsigned v)
Definition: FPGATrackSimTrack.h:109
FPGATrackSimNNTrackTool::m_chi2_scalefactor
Gaudi::Property< double > m_chi2_scalefactor
Definition: FPGATrackSimNNTrackTool.h:58
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
FPGATrackSimTrackingToolBase::setRoadSectors
StatusCode setRoadSectors(std::vector< std::shared_ptr< const FPGATrackSimRoad >> &roads)
Definition: FPGATrackSimTrackingToolBase.cxx:11
lumiFormat.i
int i
Definition: lumiFormat.py:85
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
TrackStage::FIRST
@ FIRST
FPGATrackSimMultiTruth::Barcode
std::pair< unsigned long, unsigned long > Barcode
Definition: FPGATrackSimMultiTruth.h:49
chi2
double chi2(TH1 *h0, TH1 *h1)
Definition: comparitor.cxx:523
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
TRT::Track::z0
@ z0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:63
FPGATrackSimNNTrackTool::m_NNCut
Gaudi::Property< double > m_NNCut
Definition: FPGATrackSimNNTrackTool.h:57
getComboIndices
std::vector< std::vector< int > > getComboIndices(std::vector< size_t > const &sizes)
Given a vector of sizes (of arrays), generates a vector of all combinations of indices to index one e...
Definition: FPGATrackSimFunctions.cxx:21
FPGATrackSimNNTrackTool::m_FPGATrackSimMapping
ServiceHandle< IFPGATrackSimMappingSvc > m_FPGATrackSimMapping
Definition: FPGATrackSimNNTrackTool.h:63
FPGATrackSimTrackingToolBase::m_useSpacePoints
Gaudi::Property< bool > m_useSpacePoints
Definition: FPGATrackSimTrackingToolBase.h:36
FPGATrackSimPlaneMap
Definition: FPGATrackSimPlaneMap.h:62
FPGATrackSimNNTrackTool::getZScale
static float getZScale()
Definition: FPGATrackSimNNTrackTool.h:53
FPGATrackSimTrack::setTrackStage
void setTrackStage(TrackStage v)
Definition: FPGATrackSimTrack.h:82
FPGATrackSimNNTrackTool::getYScale
static float getYScale()
Definition: FPGATrackSimNNTrackTool.h:52
FPGATrackSimNNTrackTool::FPGATrackSimNNTrackTool
FPGATrackSimNNTrackTool(const std::string &, const std::string &, const IInterface *)
Definition: FPGATrackSimNNTrackTool.cxx:21
FPGATrackSimMultiTruth
Definition: FPGATrackSimMultiTruth.h:46
FPGATrackSimMultiTruth::AddAccumulator
Definition: FPGATrackSimMultiTruth.h:57
OnnxRuntimeBase
Definition: OnnxRuntimeBase.h:13
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
FPGATrackSimFunctions.h
FPGATrackSimTrack::setHoughY
void setHoughY(float v)
Definition: FPGATrackSimTrack.h:91
FPGATrackSimTrack::setTrackID
void setTrackID(int v)
Definition: FPGATrackSimTrack.h:88
FPGATrackSimTrack::setQOverPt
void setQOverPt(float v)
Definition: FPGATrackSimTrack.h:92
FPGATrackSimNNTrackTool::compute_truth
void compute_truth(FPGATrackSimTrack &newtrk) const
Definition: FPGATrackSimNNTrackTool.cxx:266
FPGATrackSimNNTrackTool::m_paramNN
OnnxRuntimeBase m_paramNN
Definition: FPGATrackSimNNTrackTool.h:66
FPGATrackSimNNTrackTool::initialize
virtual StatusCode initialize() override
Definition: FPGATrackSimNNTrackTool.cxx:25
y
#define y
FPGATrackSimTrack::setChi2
void setChi2(float v)
Definition: FPGATrackSimTrack.h:97
layer_bitmask_t
uint32_t layer_bitmask_t
Definition: FPGATrackSimTypes.h:22
FPGATrackSimTrack::setSubRegion
void setSubRegion(unsigned v)
Definition: FPGATrackSimTrack.h:107
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
FPGATrackSimTrack::setNLayers
void setNLayers(int)
set the number of layers in the track.
Definition: FPGATrackSimTrack.cxx:108
FPGATrackSimTrackingToolBase::m_do2ndStage
Gaudi::Property< bool > m_do2ndStage
Definition: FPGATrackSimTrackingToolBase.h:40
FPGATrackSimTrackingToolBase::m_spRoadFilterTool
ToolHandle< IFPGATrackSimRoadFilterTool > m_spRoadFilterTool
Definition: FPGATrackSimTrackingToolBase.h:32
FPGATrackSimTrack::setHoughX
void setHoughX(float v)
Definition: FPGATrackSimTrack.h:90