CMS 3D CMS Logo

TrackCleaner.cc
Go to the documentation of this file.
3 
5 
8 
12 
13 using namespace std;
14 using namespace pixeltrackfitting;
15 
16 /*****************************************************************************/
17 class HitComparatorByRadius { // No access to geometry!
18 public:
19  HitComparatorByRadius(const TrackerTopology *tTopo) { tTopo_ = tTopo; }
20 
21 private:
23 
24 public:
25  bool operator()(const TrackingRecHit *a, const TrackingRecHit *b) const {
26  DetId i1 = a->geographicalId();
27  DetId i2 = b->geographicalId();
28 
29  bool isBarrel = (i1.subdetId() == int(PixelSubdetector::PixelBarrel));
30 
31  if (i1.subdetId() != i2.subdetId()) {
32  return isBarrel;
33  } else {
34  if (isBarrel) {
35  int r1 = (tTopo_->pxbLayer(i1) - 1) * 2 + (tTopo_->pxbLadder(i1) - 1) % 2;
36  int r2 = (tTopo_->pxbLayer(i2) - 1) * 2 + (tTopo_->pxbLadder(i2) - 1) % 2;
37 
38  return (r1 < r2);
39  } else {
40  int r1 = (tTopo_->pxfDisk(i1) - 1) * 2 + (tTopo_->pxfPanel(i1) - 1) % 2;
41  int r2 = (tTopo_->pxfDisk(i2) - 1) * 2 + (tTopo_->pxfPanel(i2) - 1) % 2;
42 
43  return (r1 < r2);
44  }
45  }
46  }
47 };
48 
49 /*****************************************************************************/
51 public:
52  bool operator()(const TrackingRecHit *a, const TrackingRecHit *b) const {
53  if (a->geographicalId() < b->geographicalId())
54  return true;
55  if (b->geographicalId() < a->geographicalId())
56  return false;
57 
58  if (a->localPosition().x() < b->localPosition().x() - 1e-5)
59  return true;
60  if (b->localPosition().x() < a->localPosition().x() - 1e-5)
61  return false;
62 
63  if (a->localPosition().y() < b->localPosition().y() - 1e-5)
64  return true;
65  if (b->localPosition().y() < a->localPosition().y() - 1e-5)
66  return false;
67 
68  return false;
69  }
70 };
71 
72 /*****************************************************************************/
73 TrackCleaner::TrackCleaner(const TrackerTopology *tTopo) : tTopo_(tTopo) {}
74 
75 /*****************************************************************************/
77 
78 /*****************************************************************************/
80  if (a->geographicalId() != b->geographicalId())
81  return false;
82 
83  if (fabs(a->localPosition().x() - b->localPosition().x()) < 1e-5 &&
84  fabs(a->localPosition().y() - b->localPosition().y()) < 1e-5)
85  return true;
86  else
87  return false;
88 }
89 
90 /*****************************************************************************/
91 bool TrackCleaner::isCompatible(const DetId &i1, const DetId &i2) const {
92  // different subdet
93  if (i1.subdetId() != i2.subdetId())
94  return true;
95 
96  if (i1.subdetId() == int(PixelSubdetector::PixelBarrel)) { // barrel
97 
98  if (tTopo_->pxbLayer(i1) != tTopo_->pxbLayer(i2))
99  return true;
100 
101  int dphi = abs(int(tTopo_->pxbLadder(i1) - tTopo_->pxbLadder(i2)));
102  //FIXME: non-phase-0 wrap-around is wrong (sh/be 12, 28, 44, 64 in phase-1)
103  // the harm is somewhat minimal with some excess of duplicates.
104  constexpr int max[4] = {20, 32, 44, 64};
105  auto aLayer = tTopo_->pxbLayer(i1) - 1;
106  assert(aLayer < 4);
107  if (dphi > max[aLayer] / 2)
108  dphi = max[aLayer] - dphi;
109 
110  int dz = abs(int(tTopo_->pxbModule(i1) - tTopo_->pxbModule(i2)));
111 
112  if (dphi == 1 && dz <= 1)
113  return true;
114  } else { // endcap
115 
116  if (tTopo_->pxfSide(i1) != tTopo_->pxfSide(i2) || tTopo_->pxfDisk(i1) != tTopo_->pxfDisk(i2))
117  return true;
118 
119  int dphi = abs(int(tTopo_->pxfBlade(i1) - tTopo_->pxfBlade(i2)));
120  constexpr int max = 24; //FIXME: non-phase-0 wrap-around is wrong
121  if (dphi > max / 2)
122  dphi = max - dphi;
123 
124  int dr = abs(int(((tTopo_->pxfModule(i1) - 1) * 2 + (tTopo_->pxfPanel(i1) - 1)) -
125  ((tTopo_->pxfModule(i2) - 1) * 2 + (tTopo_->pxfPanel(i2) - 1))));
126 
127  if (dphi <= 1 && dr <= 1 && !(dphi == 0 && dr == 0))
128  return true;
129  }
130 
131  return false;
132 }
133 
134 /*****************************************************************************/
135 bool TrackCleaner::canBeMerged(const vector<const TrackingRecHit *> &recHitsA,
136  const vector<const TrackingRecHit *> &recHitsB) const {
137  bool ok = true;
138 
139  for (vector<const TrackingRecHit *>::const_iterator recHitA = recHitsA.begin(); recHitA != recHitsA.end(); recHitA++)
140  for (vector<const TrackingRecHit *>::const_iterator recHitB = recHitsB.begin(); recHitB != recHitsB.end();
141  recHitB++)
142  if (!areSame(*recHitA, *recHitB))
143  if (!isCompatible((*recHitA)->geographicalId(), (*recHitB)->geographicalId()))
144  ok = false;
145 
146  return ok;
147 }
148 
149 /*****************************************************************************/
151  // Local copy
152  TracksWithRecHits tracks = tracks_;
153 
154  typedef map<const TrackingRecHit *, vector<unsigned int>, HitComparator> RecHitMap;
155 
156  vector<bool> keep(tracks.size(), true);
157 
158  int changes;
159 
160  LogTrace("MinBiasTracking") << " [TrackCleaner] initial tracks : " << tracks.size();
161 
162  for (unsigned int i = 0; i < tracks.size(); i++)
163  LogTrace("TrackCleaner") << " Track #" << i << " : " << HitInfo::getInfo(tracks[i].second, tTopo_);
164 
165  do {
166  changes = 0;
167 
168  RecHitMap recHitMap;
169 
170  /*
171  LogTrace("MinBiasTracking")
172  << " [TrackCleaner] fill rechit map";
173 */
174 
175  // Fill the rechit map
176  for (unsigned int i = 0; i < tracks.size(); i++)
177  if (keep[i]) {
178  for (vector<const TrackingRecHit *>::const_iterator recHit = tracks[i].second.begin();
179  recHit != tracks[i].second.end();
180  recHit++)
181  recHitMap[*recHit].push_back(i);
182  }
183 
184  // Look at each track
185  typedef map<unsigned int, int, less<unsigned int> > TrackMap;
186 
187  for (unsigned int i = 0; i < tracks.size(); i++) {
188  // Skip if 'i' already removed
189  if (!keep[i])
190  continue;
191 
192  /*
193 
194  bool addedNewHit = false;
195  do
196  {
197 */
198  TrackMap trackMap;
199 
200  // Go trough all rechits of this track
201  for (vector<const TrackingRecHit *>::const_iterator recHit = tracks[i].second.begin();
202  recHit != tracks[i].second.end();
203  recHit++) {
204  // Get tracks sharing this rechit
205  vector<unsigned int> sharing = recHitMap[*recHit];
206 
207  for (vector<unsigned int>::iterator j = sharing.begin(); j != sharing.end(); j++)
208  if (i < *j)
209  trackMap[*j]++;
210  }
211 
212  // Check for tracks with shared rechits
213  for (TrackMap::iterator sharing = trackMap.begin(); sharing != trackMap.end(); sharing++) {
214  unsigned int j = (*sharing).first;
215  if (!keep[i] || !keep[j])
216  continue;
217 
218  if (tracks[i].second.size() >= 3) { // triplet tracks
219  if ((*sharing).second > min(int(tracks[i].second.size()),
220  int(tracks[j].second.size())) /
221  2) { // more than min(hits1,hits2)/2 rechits are shared
222  if (canBeMerged(tracks[i].second, tracks[j].second)) { // no common layer
223  // merge tracks, add separate hits of the second to the first one
224  for (vector<const TrackingRecHit *>::const_iterator recHit = tracks[j].second.begin();
225  recHit != tracks[j].second.end();
226  recHit++) {
227  bool ok = true;
228  for (vector<const TrackingRecHit *>::const_iterator recHitA = tracks[i].second.begin();
229  recHitA != tracks[i].second.end();
230  recHitA++)
231  if (areSame(*recHit, *recHitA))
232  ok = false;
233 
234  if (ok) {
235  tracks[i].second.push_back(*recHit);
236  recHitMap[*recHit].push_back(i);
237 
238  sort(tracks[i].second.begin(), tracks[i].second.end(), HitComparatorByRadius(tTopo_));
239 
240  //addedNewHit = true;
241  }
242  }
243 
244  LogTrace("TrackCleaner") << " Merge #" << i << " #" << j << ", first now has "
245  << tracks[i].second.size();
246 
247  // Remove second track
248  keep[j] = false;
249 
250  changes++;
251  } else { // there is a common layer, keep smaller impact
252  if (fabs(tracks[i].first->d0()) < fabs(tracks[j].first->d0()))
253  keep[j] = false;
254  else
255  keep[i] = false;
256 
257  LogTrace("TrackCleaner") << " Clash #" << i << " #" << j << " keep lower d0 " << tracks[i].first->d0()
258  << " " << tracks[j].first->d0() << ", keep #"
259  << (keep[i] ? i : (keep[j] ? j : 9999));
260 
261  changes++;
262  }
263  } else { // note more than 50%, but at least two are shared
264  if ((*sharing).second > 1) {
265  if (tracks[i].second.size() != tracks[j].second.size()) { // keep longer
266  if (tracks[i].second.size() > tracks[j].second.size())
267  keep[j] = false;
268  else
269  keep[i] = false;
270  changes++;
271 
272  LogTrace("TrackCleaner") << " Sharing " << (*sharing).second << " remove by size";
273  } else { // keep smaller impact
274  if (fabs(tracks[i].first->d0()) < fabs(tracks[j].first->d0()))
275  keep[j] = false;
276  else
277  keep[i] = false;
278  changes++;
279 
280  LogTrace("TrackCleaner") << " Sharing " << (*sharing).second << " remove by d0";
281  }
282  }
283  }
284  } else { // pair tracks
285  if ((*sharing).second > 0) {
286  // Remove second track
287  keep[j] = false;
288 
289  changes++;
290  }
291  }
292  }
293  /*
294  }
295  while(addedNewHit);
296 */
297  }
298  } while (changes > 0);
299 
300  // Final copy
301  TracksWithRecHits cleaned;
302 
303  for (unsigned int i = 0; i < tracks.size(); i++)
304  if (keep[i])
305  cleaned.push_back(tracks[i]);
306  else
307  delete tracks_[i].first;
308 
309  LogTrace("MinBiasTracking") << " [TrackCleaner] cleaned tracks : " << cleaned.size();
310 
311  for (unsigned int i = 0; i < cleaned.size(); i++)
312  LogTrace("TrackCleaner") << " Track #" << i << " : " << HitInfo::getInfo(cleaned[i].second, tTopo_);
313 
314  return cleaned;
315 }
unsigned int pxbLayer(const DetId &id) const
bool isCompatible(const DetId &i1, const DetId &i2) const
Definition: TrackCleaner.cc:91
unsigned int pxfBlade(const DetId &id) const
unsigned int pxfModule(const DetId &id) const
unsigned int pxbLadder(const DetId &id) const
TracksWithRecHits cleanTracks(const TracksWithRecHits &tracksWithRecHits) const override
assert(be >=bs)
#define LogTrace(id)
bool canBeMerged(const std::vector< const TrackingRecHit *> &recHitsA, const std::vector< const TrackingRecHit *> &recHitsB) const
U second(std::pair< T, U > const &p)
HitComparatorByRadius(const TrackerTopology *tTopo)
Definition: TrackCleaner.cc:19
bool operator()(const TrackingRecHit *a, const TrackingRecHit *b) const
Definition: TrackCleaner.cc:52
bool areSame(const TrackingRecHit *a, const TrackingRecHit *b) const
Definition: TrackCleaner.cc:79
bool operator()(const TrackingRecHit *a, const TrackingRecHit *b) const
Definition: TrackCleaner.cc:25
unsigned int pxfDisk(const DetId &id) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
unsigned int pxfPanel(const DetId &id) const
Definition: DetId.h:17
~TrackCleaner() override
Definition: TrackCleaner.cc:76
const TrackerTopology * tTopo_
Definition: TrackCleaner.h:30
unsigned int pxfSide(const DetId &id) const
TrackCleaner(const TrackerTopology *tTopo)
Definition: TrackCleaner.cc:73
double b
Definition: hdecay.h:120
deadvectors [0] push_back({0.0175431, 0.538005, 6.80997, 13.29})
double a
Definition: hdecay.h:121
unsigned int pxbModule(const DetId &id) const
static std::string getInfo(const DetId &id, const TrackerTopology *tTopo)
Definition: HitInfo.cc:19
pixeltrackfitting::TracksWithRecHits TracksWithRecHits
const TrackerTopology * tTopo_
Definition: TrackCleaner.cc:22