File indexing completed on 2023-03-31 23:02:12
0001 #include "RecoTracker/PixelLowPtUtilities/interface/TrackCleaner.h"
0002 #include "RecoTracker/PixelLowPtUtilities/interface/HitInfo.h"
0003
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005
0006 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
0007 #include "DataFormats/TrackReco/interface/Track.h"
0008
0009 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0010 #include "Geometry/Records/interface/IdealGeometryRecord.h"
0011 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
0012
0013 using namespace std;
0014 using namespace pixeltrackfitting;
0015
0016
0017 class HitComparatorByRadius {
0018 public:
0019 HitComparatorByRadius(const TrackerTopology *tTopo) { tTopo_ = tTopo; }
0020
0021 private:
0022 const TrackerTopology *tTopo_;
0023
0024 public:
0025 bool operator()(const TrackingRecHit *a, const TrackingRecHit *b) const {
0026 DetId i1 = a->geographicalId();
0027 DetId i2 = b->geographicalId();
0028
0029 bool isBarrel = (i1.subdetId() == int(PixelSubdetector::PixelBarrel));
0030
0031 if (i1.subdetId() != i2.subdetId()) {
0032 return isBarrel;
0033 } else {
0034 if (isBarrel) {
0035 int r1 = (tTopo_->pxbLayer(i1) - 1) * 2 + (tTopo_->pxbLadder(i1) - 1) % 2;
0036 int r2 = (tTopo_->pxbLayer(i2) - 1) * 2 + (tTopo_->pxbLadder(i2) - 1) % 2;
0037
0038 return (r1 < r2);
0039 } else {
0040 int r1 = (tTopo_->pxfDisk(i1) - 1) * 2 + (tTopo_->pxfPanel(i1) - 1) % 2;
0041 int r2 = (tTopo_->pxfDisk(i2) - 1) * 2 + (tTopo_->pxfPanel(i2) - 1) % 2;
0042
0043 return (r1 < r2);
0044 }
0045 }
0046 }
0047 };
0048
0049
0050 class HitComparator {
0051 public:
0052 bool operator()(const TrackingRecHit *a, const TrackingRecHit *b) const {
0053 if (a->geographicalId() < b->geographicalId())
0054 return true;
0055 if (b->geographicalId() < a->geographicalId())
0056 return false;
0057
0058 if (a->localPosition().x() < b->localPosition().x() - 1e-5)
0059 return true;
0060 if (b->localPosition().x() < a->localPosition().x() - 1e-5)
0061 return false;
0062
0063 if (a->localPosition().y() < b->localPosition().y() - 1e-5)
0064 return true;
0065 if (b->localPosition().y() < a->localPosition().y() - 1e-5)
0066 return false;
0067
0068 return false;
0069 }
0070 };
0071
0072
0073 TrackCleaner::TrackCleaner(const TrackerTopology *tTopo) : tTopo_(tTopo) {}
0074
0075
0076 TrackCleaner::~TrackCleaner() {}
0077
0078
0079 bool TrackCleaner::areSame(const TrackingRecHit *a, const TrackingRecHit *b) const {
0080 if (a->geographicalId() != b->geographicalId())
0081 return false;
0082
0083 if (fabs(a->localPosition().x() - b->localPosition().x()) < 1e-5 &&
0084 fabs(a->localPosition().y() - b->localPosition().y()) < 1e-5)
0085 return true;
0086 else
0087 return false;
0088 }
0089
0090
0091 bool TrackCleaner::isCompatible(const DetId &i1, const DetId &i2) const {
0092
0093 if (i1.subdetId() != i2.subdetId())
0094 return true;
0095
0096 if (i1.subdetId() == int(PixelSubdetector::PixelBarrel)) {
0097
0098 if (tTopo_->pxbLayer(i1) != tTopo_->pxbLayer(i2))
0099 return true;
0100
0101 int dphi = abs(int(tTopo_->pxbLadder(i1) - tTopo_->pxbLadder(i2)));
0102
0103
0104 constexpr int max[4] = {20, 32, 44, 64};
0105 auto aLayer = tTopo_->pxbLayer(i1) - 1;
0106 assert(aLayer < 4);
0107 if (dphi > max[aLayer] / 2)
0108 dphi = max[aLayer] - dphi;
0109
0110 int dz = abs(int(tTopo_->pxbModule(i1) - tTopo_->pxbModule(i2)));
0111
0112 if (dphi == 1 && dz <= 1)
0113 return true;
0114 } else {
0115
0116 if (tTopo_->pxfSide(i1) != tTopo_->pxfSide(i2) || tTopo_->pxfDisk(i1) != tTopo_->pxfDisk(i2))
0117 return true;
0118
0119 int dphi = abs(int(tTopo_->pxfBlade(i1) - tTopo_->pxfBlade(i2)));
0120 constexpr int max = 24;
0121 if (dphi > max / 2)
0122 dphi = max - dphi;
0123
0124 int dr = abs(int(((tTopo_->pxfModule(i1) - 1) * 2 + (tTopo_->pxfPanel(i1) - 1)) -
0125 ((tTopo_->pxfModule(i2) - 1) * 2 + (tTopo_->pxfPanel(i2) - 1))));
0126
0127 if (dphi <= 1 && dr <= 1 && !(dphi == 0 && dr == 0))
0128 return true;
0129 }
0130
0131 return false;
0132 }
0133
0134
0135 bool TrackCleaner::canBeMerged(const vector<const TrackingRecHit *> &recHitsA,
0136 const vector<const TrackingRecHit *> &recHitsB) const {
0137 bool ok = true;
0138
0139 for (vector<const TrackingRecHit *>::const_iterator recHitA = recHitsA.begin(); recHitA != recHitsA.end(); recHitA++)
0140 for (vector<const TrackingRecHit *>::const_iterator recHitB = recHitsB.begin(); recHitB != recHitsB.end();
0141 recHitB++)
0142 if (!areSame(*recHitA, *recHitB))
0143 if (!isCompatible((*recHitA)->geographicalId(), (*recHitB)->geographicalId()))
0144 ok = false;
0145
0146 return ok;
0147 }
0148
0149
0150 TracksWithRecHits TrackCleaner::cleanTracks(const TracksWithRecHits &tracks_) const {
0151
0152 TracksWithRecHits tracks = tracks_;
0153
0154 typedef map<const TrackingRecHit *, vector<unsigned int>, HitComparator> RecHitMap;
0155
0156 vector<bool> keep(tracks.size(), true);
0157
0158 int changes;
0159
0160 LogTrace("MinBiasTracking") << " [TrackCleaner] initial tracks : " << tracks.size();
0161
0162 for (unsigned int i = 0; i < tracks.size(); i++)
0163 LogTrace("TrackCleaner") << " Track #" << i << " : " << HitInfo::getInfo(tracks[i].second, tTopo_);
0164
0165 do {
0166 changes = 0;
0167
0168 RecHitMap recHitMap;
0169
0170
0171
0172
0173
0174
0175
0176 for (unsigned int i = 0; i < tracks.size(); i++)
0177 if (keep[i]) {
0178 for (vector<const TrackingRecHit *>::const_iterator recHit = tracks[i].second.begin();
0179 recHit != tracks[i].second.end();
0180 recHit++)
0181 recHitMap[*recHit].push_back(i);
0182 }
0183
0184
0185 typedef map<unsigned int, int, less<unsigned int> > TrackMap;
0186
0187 for (unsigned int i = 0; i < tracks.size(); i++) {
0188
0189 if (!keep[i])
0190 continue;
0191
0192
0193
0194
0195
0196
0197
0198 TrackMap trackMap;
0199
0200
0201 for (vector<const TrackingRecHit *>::const_iterator recHit = tracks[i].second.begin();
0202 recHit != tracks[i].second.end();
0203 recHit++) {
0204
0205 vector<unsigned int> sharing = recHitMap[*recHit];
0206
0207 for (vector<unsigned int>::iterator j = sharing.begin(); j != sharing.end(); j++)
0208 if (i < *j)
0209 trackMap[*j]++;
0210 }
0211
0212
0213 for (TrackMap::iterator sharing = trackMap.begin(); sharing != trackMap.end(); sharing++) {
0214 unsigned int j = (*sharing).first;
0215 if (!keep[i] || !keep[j])
0216 continue;
0217
0218 if (tracks[i].second.size() >= 3) {
0219 if ((*sharing).second > min(int(tracks[i].second.size()),
0220 int(tracks[j].second.size())) /
0221 2) {
0222 if (canBeMerged(tracks[i].second, tracks[j].second)) {
0223
0224 for (vector<const TrackingRecHit *>::const_iterator recHit = tracks[j].second.begin();
0225 recHit != tracks[j].second.end();
0226 recHit++) {
0227 bool ok = true;
0228 for (vector<const TrackingRecHit *>::const_iterator recHitA = tracks[i].second.begin();
0229 recHitA != tracks[i].second.end();
0230 recHitA++)
0231 if (areSame(*recHit, *recHitA))
0232 ok = false;
0233
0234 if (ok) {
0235 tracks[i].second.push_back(*recHit);
0236 recHitMap[*recHit].push_back(i);
0237
0238 sort(tracks[i].second.begin(), tracks[i].second.end(), HitComparatorByRadius(tTopo_));
0239
0240
0241 }
0242 }
0243
0244 LogTrace("TrackCleaner") << " Merge #" << i << " #" << j << ", first now has "
0245 << tracks[i].second.size();
0246
0247
0248 keep[j] = false;
0249
0250 changes++;
0251 } else {
0252 if (fabs(tracks[i].first->d0()) < fabs(tracks[j].first->d0()))
0253 keep[j] = false;
0254 else
0255 keep[i] = false;
0256
0257 LogTrace("TrackCleaner") << " Clash #" << i << " #" << j << " keep lower d0 " << tracks[i].first->d0()
0258 << " " << tracks[j].first->d0() << ", keep #"
0259 << (keep[i] ? i : (keep[j] ? j : 9999));
0260
0261 changes++;
0262 }
0263 } else {
0264 if ((*sharing).second > 1) {
0265 if (tracks[i].second.size() != tracks[j].second.size()) {
0266 if (tracks[i].second.size() > tracks[j].second.size())
0267 keep[j] = false;
0268 else
0269 keep[i] = false;
0270 changes++;
0271
0272 LogTrace("TrackCleaner") << " Sharing " << (*sharing).second << " remove by size";
0273 } else {
0274 if (fabs(tracks[i].first->d0()) < fabs(tracks[j].first->d0()))
0275 keep[j] = false;
0276 else
0277 keep[i] = false;
0278 changes++;
0279
0280 LogTrace("TrackCleaner") << " Sharing " << (*sharing).second << " remove by d0";
0281 }
0282 }
0283 }
0284 } else {
0285 if ((*sharing).second > 0) {
0286
0287 keep[j] = false;
0288
0289 changes++;
0290 }
0291 }
0292 }
0293
0294
0295
0296
0297 }
0298 } while (changes > 0);
0299
0300
0301 TracksWithRecHits cleaned;
0302
0303 for (unsigned int i = 0; i < tracks.size(); i++)
0304 if (keep[i])
0305 cleaned.push_back(tracks[i]);
0306 else
0307 delete tracks_[i].first;
0308
0309 LogTrace("MinBiasTracking") << " [TrackCleaner] cleaned tracks : " << cleaned.size();
0310
0311 for (unsigned int i = 0; i < cleaned.size(); i++)
0312 LogTrace("TrackCleaner") << " Track #" << i << " : " << HitInfo::getInfo(cleaned[i].second, tTopo_);
0313
0314 return cleaned;
0315 }