ATLAS Offline Software
FPGATrackSimOverlapRemovalTool.cxx
Go to the documentation of this file.
1 // Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2 
6 
7 #include "GaudiKernel/MsgStream.h"
8 
9 #include <sstream>
10 #include <iostream>
11 #include <fstream>
12 
14 FPGATrackSimOverlapRemovalTool::FPGATrackSimOverlapRemovalTool(const std::string& algname, const std::string& name, const IInterface *ifc) :
15  AthAlgTool(algname, name, ifc)
16 {
17 }
18 
20 {
21  ATH_MSG_INFO( "FPGATrackSimOverlapRemovalTool::initialize()" );
22  // Check if this is 2nd stage
23  if(m_do2ndStage)
24  {
25  m_totLayers = m_FPGATrackSimMapping->PlaneMap_2nd(0)->getNLogiLayers();
26  }
27  else
28  {
29  m_totLayers = m_FPGATrackSimMapping->PlaneMap_1st(0)->getNLogiLayers();
30  }
31  ATH_MSG_DEBUG("Total number of layer: " << m_totLayers);
32 
33  // Check road OR
35  ATH_MSG_WARNING("LocalMaxOR only being run per hough slice (i.e. this tool does nothing) since roadSliceOR is turned off");
36 
37 
38  // Setup OR algorithm
39  if(m_algorithm == "Normal") m_algo=ORAlgo::Normal;
40  else if(m_algorithm == "Invert") m_algo=ORAlgo::InvertGrouping;
41  else
42  {
43  ATH_MSG_ERROR("initialize(): OR algorithm doesn't exist. ");
44  return StatusCode::FAILURE;
45  }
46  ATH_MSG_DEBUG("Overlap removal algorithm is "<<m_algorithm.value());
47 
48  return StatusCode::SUCCESS;
49 }
50 
51 bool isLocalMax(vector2D<FPGATrackSimRoad*> const & acc, unsigned x, unsigned y, int localMaxWindowSize)
52 {
53  if (!localMaxWindowSize) return true;
54  if (!acc(y, x)) return false;
55  for (int j = -localMaxWindowSize; j <= localMaxWindowSize; j++)
56  for (int i = -localMaxWindowSize; i <= localMaxWindowSize; i++)
57  {
58  if (i == 0 && j == 0) continue;
59  if (y + j < acc.size(0) && x + i < acc.size(1))
60  {
61  if (!acc(y+j, x+i)) continue;
62  if (acc(y+j, x+i)->getNHitLayers() > acc(y, x)->getNHitLayers()) return false;
63  if (acc(y+j, x+i)->getNHitLayers() == acc(y, x)->getNHitLayers())
64  {
65  if (acc(y+j, x+i)->getNHits() > acc(y, x)->getNHits()) return false;
66  if (acc(y+j, x+i)->getNHits() == acc(y, x)->getNHits() && j <= 0 && i <= 0) return false;
67  }
68  }
69  }
70 
71  return true;
72 }
73 
74 StatusCode FPGATrackSimOverlapRemovalTool::runOverlapRemoval(std::vector<std::shared_ptr<const FPGATrackSimRoad>>& roads)
75 {
76  if (roads.empty()) return StatusCode::SUCCESS;
77 
78  if (!m_roadSliceOR) return StatusCode::SUCCESS;
79  size_t in = roads.size();
80 
81  // Hough image
83 
84  // Slice-wise duplicate removal: accept only one road (with most hits) per bin
85  for (auto &r: roads)
86  {
87  FPGATrackSimRoad* & old = acc(r->getYBin(), r->getXBin());
88  if (!old) old = new FPGATrackSimRoad (*r.get());
89  else if (r->getNHitLayers() > old->getNHitLayers()) *old = *r.get();
90  else if (r->getNHitLayers() == old->getNHitLayers() && r->getNHits() > old->getNHits()) *old = *r.get();
91  }
92 
93  // Reformat to vector
94  roads.clear();
95  for (unsigned y = 0; y < m_imageSize_y; y++)
96  for (unsigned x = 0; x < m_imageSize_x; x++)
97  if (FPGATrackSimRoad *tempPtr = acc(y, x); tempPtr && isLocalMax(acc, x, y, m_localMaxWindowSize)/*All-slices local max*/) {
98  roads.emplace_back(std::shared_ptr<const FPGATrackSimRoad>(tempPtr));
99  acc(y, x) = nullptr;
100  }
101  else {
102  delete acc(y,x);
103  acc(y,x) = nullptr;
104  }
105 
106  ATH_MSG_DEBUG("Input: " << in << " Output: " << roads.size());
107  return StatusCode::SUCCESS;
108 }
109 
110 StatusCode FPGATrackSimOverlapRemovalTool::runOverlapRemoval(std::vector<FPGATrackSimTrack>& tracks)
111 {
112 
113  // Do fast OR instead of requested
114  if (m_doFastOR) return runOverlapRemoval_fast(tracks);
115 
116  // Otherwise, proceed
117  ATH_MSG_DEBUG("Beginning runOverlapRemoval()");
118 
120 }
121 
122 
124 
125  // Hit comparison
126  struct HitCompare {
127  bool operator()(const FPGATrackSimHit* a, const FPGATrackSimHit* b) const {
128  auto hash_a = a->getIdentifierHash();
129  auto hash_b = b->getIdentifierHash();
130  if ( hash_a == hash_b ) {
131  auto phi_a = a->getPhiCoord();
132  auto phi_b = b->getPhiCoord();
133  if ( phi_a == phi_b ) {
134  auto eta_a = a->getEtaCoord();
135  auto eta_b = b->getEtaCoord();
136  if ( eta_a == eta_b) {
137  auto layer_a = a->getLayer();
138  auto layer_b = b->getLayer();
139  return layer_a < layer_b;
140  }
141  return eta_a < eta_b;
142  }
143  return phi_a < phi_b;
144  }
145  return hash_a < hash_b;
146  }
147  };
148 
149  std::set<const FPGATrackSimHit*, HitCompare > hitsInTrack1;
150  for ( auto& hit : track1.getFPGATrackSimHits()) {
151  if (hit.isReal()) hitsInTrack1.insert(&hit);
152  }
153 
154  std::set<const FPGATrackSimHit*, HitCompare> hitsInTrack2;
155  for ( auto& hit: track2.getFPGATrackSimHits()){
156  if (hit.isReal()) hitsInTrack2.insert(&hit);
157  }
158 
159  std::vector<const FPGATrackSimHit*> sharedHits;
160  std::set_intersection( hitsInTrack1.begin(), hitsInTrack1.end(),
161  hitsInTrack2.begin(), hitsInTrack2.end(),
162  std::back_inserter(sharedHits),
163  HitCompare() );
164 
165  // Number of real hits in track 1, number of real hits in track 2, number of shared hits, number of non-shared hits (?)
166  int nHitsInTrack1 = hitsInTrack1.size();
167  int nHitsInTrack2 = hitsInTrack2.size();
168  int nSharedHits = sharedHits.size();
169  // Original version seems to be only track 1; I want to compare each pair only once so
170  // let's make this the most conservative option (i.e. smallest number) ?
171  int nonOverlappingHits = std::min(nHitsInTrack1 - nSharedHits, nHitsInTrack2 - nSharedHits);
172 
173  // Now check if these pass our criteria for overlapping. If not, just return.
174  if(getAlgorithm() == ORAlgo::Normal) {
175  // Here decision is based on number of overlapping hits.
176  // Consider these overlapping if they share >= m_NumOfHitPerGrouping
177  if(nSharedHits < m_NumOfHitPerGrouping) return StatusCode::SUCCESS;
178 
179  } else if(getAlgorithm() == ORAlgo::InvertGrouping) {
180  // This is the opposite: duplicates of number of unique hits is <= m_NumOfHitPerGrouping.
181  if(nonOverlappingHits > m_NumOfHitPerGrouping) return StatusCode::SUCCESS;
182 
183  } else {
184  // Unknown.
185  return StatusCode::FAILURE;
186  }
187 
188  // Made it here: these tracks are overlapping.
189  // But we already sorted them such that track 2 is the one
190  // we want to keep, so we can just set track 1 to be removed.
191  track1.setPassedOR(0);
192 
193  return StatusCode::SUCCESS;
194 }
195 
197 {
198  std::vector<const FPGATrackSimHit*> hitsInTrack1;
199  for ( auto& hit : track1.getFPGATrackSimHits()) {
200  if (hit.isReal()) hitsInTrack1.push_back(&hit);
201  }
202 
203  std::vector<const FPGATrackSimHit*> hitsInTrack2;
204  for ( auto& hit: track2.getFPGATrackSimHits()){
205  if (hit.isReal()) hitsInTrack2.push_back(&hit);
206  }
207 
208  // If one track has more hits than the other, it's better.
209  // Return true if track 2 is better than track 1.
210  // Otherwise, decide based on chi2.
211  bool goodOrder = true;
212  if (hitsInTrack1.size() == hitsInTrack2.size()) {
213  // Surprising number of cases where the chi2 is actually identical.
214  // In these cases, let's default to the track ID number as the next most important property.
215  // So put it higher since we are considering later tracks to be better.
216  if (track1.getChi2ndof() == track2.getChi2ndof() && track1.getTrackID() < track2.getTrackID()) goodOrder = false;
217  // Now assuming they're different, we want them in decreasing chi2 order
218  else if (track1.getChi2ndof() < track2.getChi2ndof()) goodOrder = false;
219  } else if (hitsInTrack1.size() > hitsInTrack2.size()) {
220  goodOrder = false;
221  }
222 
223  return goodOrder;
224 
225 }
226 
228 {
229  ATH_MSG_DEBUG("Beginning fast overlap removal");
230 
231  // Sort tracks in order of increasing quality.
232  // This way, once a track has been eliminated in a comparison, we don't
233  // need to check it against any other tracks - they will always be
234  // better than it.
235  std::sort(std::begin(tracks),
236  std::end(tracks),
238 
239  // Now compare every pair of tracks.
240  // Set passedOR to 0 for the worst one (first one)
241  // if they are found to overlap.
242  for (unsigned int i=0; i < tracks.size(); i++) {
243 
244  // Skip track i if bad chi2.
245  if (tracks.at(i).getChi2ndof() > m_minChi2) {
246  tracks.at(i).setPassedOR(0);
247  continue;
248  }
249 
250  // Now check against all other tracks.
251  for (unsigned int j=i+1; j< tracks.size(); j++) {
252 
253  // Uniquely comparing tracks i and j here.
254 
255  // If have set track i to 0 in a previous comparison,
256  // no need to look at it any more - we're done with it.
257  if (!tracks.at(i).passedOR()) break;
258 
259  // Ignore j if its chi2 is bad.
260  if (tracks.at(j).getChi2ndof() > m_minChi2) tracks.at(j).setPassedOR(0);
261 
262  // If we just set track j to zero for bad chi2,
263  // no need to do the comparison.
264  if (!tracks.at(j).passedOR()) continue;
265 
266  // If we're still here, two at least semi-decent tracks.
267  // Compare them and remove one if necessary.
268  ATH_CHECK(removeOverlapping(tracks.at(i),tracks.at(j)));
269 
270  }
271  }
272 
273  return StatusCode::SUCCESS;
274 }
275 
276 
beamspotman.r
def r
Definition: beamspotman.py:676
FPGATrackSimOverlapRemovalTool::m_NumOfHitPerGrouping
Gaudi::Property< int > m_NumOfHitPerGrouping
Definition: FPGATrackSimOverlapRemovalTool.h:59
getMenu.algname
algname
Definition: getMenu.py:54
FPGATrackSimTrack::getTrackID
int getTrackID() const
Definition: FPGATrackSimTrack.h:33
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
FPGATrackSimOverlapRemovalTool::m_do2ndStage
Gaudi::Property< bool > m_do2ndStage
Definition: FPGATrackSimOverlapRemovalTool.h:58
FPGATrackSimTrack
Definition: FPGATrackSimTrack.h:18
FPGATrackSimPlaneMap.h
Maps physical layers to logical layers.
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
FPGATrackSimOverlapRemovalTool::FPGATrackSimOverlapRemovalTool
FPGATrackSimOverlapRemovalTool()=delete
FPGATrackSimOverlapRemovalTool::getAlgorithm
ORAlgo getAlgorithm() const
Definition: FPGATrackSimOverlapRemovalTool.h:49
ORAlgo::Normal
@ Normal
FPGATrackSimOverlapRemovalTool::m_doFastOR
Gaudi::Property< bool > m_doFastOR
Definition: FPGATrackSimOverlapRemovalTool.h:66
PlotCalibFromCool.begin
begin
Definition: PlotCalibFromCool.py:94
FPGATrackSimTrack::setPassedOR
void setPassedOR(unsigned int)
Definition: FPGATrackSimTrack.cxx:260
FPGATrackSimOverlapRemovalTool::m_imageSize_x
Gaudi::Property< unsigned > m_imageSize_x
Definition: FPGATrackSimOverlapRemovalTool.h:63
FPGATrackSimOverlapRemovalTool::m_imageSize_y
Gaudi::Property< unsigned > m_imageSize_y
Definition: FPGATrackSimOverlapRemovalTool.h:64
x
#define x
isLocalMax
bool isLocalMax(vector2D< FPGATrackSimRoad * > const &acc, unsigned x, unsigned y, int localMaxWindowSize)
Definition: FPGATrackSimOverlapRemovalTool.cxx:51
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
FPGATrackSimHit
Definition: FPGATrackSimHit.h:41
FPGATrackSimTrack::getFPGATrackSimHits
const std::vector< FPGATrackSimHit > & getFPGATrackSimHits() const
Definition: FPGATrackSimTrack.h:63
FPGATrackSimVectors.h
Defines several vector wrappers for homogenous multi-dimensional vectors, declared as 1D arrays for l...
vector2D
Definition: FPGATrackSimVectors.h:28
FPGATrackSimOverlapRemovalTool::m_roadSliceOR
Gaudi::Property< bool > m_roadSliceOR
Definition: FPGATrackSimOverlapRemovalTool.h:61
FPGATrackSimTrack::getChi2ndof
float getChi2ndof() const
Definition: FPGATrackSimTrack.h:46
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
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
FPGATrackSimOverlapRemovalTool::m_algorithm
Gaudi::Property< std::string > m_algorithm
Definition: FPGATrackSimOverlapRemovalTool.h:65
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
FPGATrackSimOverlapRemovalTool::m_totLayers
int m_totLayers
Definition: FPGATrackSimOverlapRemovalTool.h:68
AthenaPoolTestRead.acc
acc
Definition: AthenaPoolTestRead.py:16
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
FPGATrackSimOverlapRemovalTool::m_minChi2
Gaudi::Property< float > m_minChi2
Definition: FPGATrackSimOverlapRemovalTool.h:60
FPGATrackSimOverlapRemovalTool::m_localMaxWindowSize
Gaudi::Property< int > m_localMaxWindowSize
Definition: FPGATrackSimOverlapRemovalTool.h:62
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
FPGATrackSimOverlapRemovalTool::m_FPGATrackSimMapping
ServiceHandle< IFPGATrackSimMappingSvc > m_FPGATrackSimMapping
Definition: FPGATrackSimOverlapRemovalTool.h:75
FPGATrackSimOverlapRemovalTool::m_algo
ORAlgo m_algo
Definition: FPGATrackSimOverlapRemovalTool.h:69
FPGATrackSimOverlapRemovalTool::compareTrackQuality
static bool compareTrackQuality(const FPGATrackSimTrack &track1, const FPGATrackSimTrack &track2)
Definition: FPGATrackSimOverlapRemovalTool.cxx:196
FPGATrackSimOverlapRemovalTool.h
Overlap removal tool for FPGATrackSimTrack.
FPGATrackSimOverlapRemovalTool::runOverlapRemoval_fast
StatusCode runOverlapRemoval_fast(std::vector< FPGATrackSimTrack > &tracks)
Definition: FPGATrackSimOverlapRemovalTool.cxx:227
FPGATrackSimOverlapRemovalTool::removeOverlapping
StatusCode removeOverlapping(FPGATrackSimTrack &track1, FPGATrackSimTrack &track2)
Definition: FPGATrackSimOverlapRemovalTool.cxx:123
ORAlgo::InvertGrouping
@ InvertGrouping
a
TList * a
Definition: liststreamerinfos.cxx:10
y
#define y
CSV_InDetExporter.old
old
Definition: CSV_InDetExporter.py:145
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
FPGATrackSimOverlapRemovalTool::initialize
StatusCode initialize() override
Definition: FPGATrackSimOverlapRemovalTool.cxx:19
AthAlgTool
Definition: AthAlgTool.h:26
set_intersection
Set * set_intersection(Set *set1, Set *set2)
Perform an intersection of two sets.
runOverlapRemoval
StatusCode runOverlapRemoval(std::vector< FPGATrackSimTrack > &tracks, const float minChi2, const int NumOfHitPerGrouping, ORAlgo orAlgo)
Definition: FPGATrackSimHoughFunctions.cxx:12
FPGATrackSimRoad
Definition: FPGATrackSimRoad.h:30
FPGATrackSimOverlapRemovalTool::runOverlapRemoval
StatusCode runOverlapRemoval(std::vector< std::shared_ptr< const FPGATrackSimRoad >> &roads)
Definition: FPGATrackSimOverlapRemovalTool.cxx:74