Warning, file /include/Acts/AmbiguityResolution/ScoreBasedAmbiguityResolution.ipp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/AmbiguityResolution/ScoreBasedAmbiguityResolution.hpp"
0012 #include "Acts/Definitions/Units.hpp"
0013 #include "Acts/Utilities/VectorHelpers.hpp"
0014
0015 #include <unordered_map>
0016
0017 namespace Acts {
0018
0019 inline const Logger& ScoreBasedAmbiguityResolution::logger() const {
0020 return *m_logger;
0021 }
0022
0023 template <typename track_container_t, typename traj_t,
0024 template <typename> class holder_t, typename source_link_hash_t,
0025 typename source_link_equality_t>
0026 std::vector<std::vector<ScoreBasedAmbiguityResolution::MeasurementInfo>>
0027 ScoreBasedAmbiguityResolution::computeInitialState(
0028 const TrackContainer<track_container_t, traj_t, holder_t>& tracks,
0029 source_link_hash_t sourceLinkHash,
0030 source_link_equality_t sourceLinkEquality,
0031 std::vector<std::vector<TrackFeatures>>& trackFeaturesVectors) const {
0032 auto MeasurementIndexMap =
0033 std::unordered_map<SourceLink, std::size_t, source_link_hash_t,
0034 source_link_equality_t>(0, sourceLinkHash,
0035 sourceLinkEquality);
0036
0037 std::vector<std::vector<MeasurementInfo>> measurementsPerTrack;
0038 measurementsPerTrack.reserve(tracks.size());
0039 ACTS_VERBOSE("Starting to compute initial state");
0040
0041 for (const auto& track : tracks) {
0042 int numberOfDetectors = m_cfg.detectorConfigs.size();
0043 int numberOfTrackStates = track.nTrackStates();
0044 std::vector<MeasurementInfo> measurements;
0045 measurements.reserve(numberOfTrackStates);
0046 std::vector<TrackFeatures> trackFeaturesVector(numberOfDetectors);
0047
0048 for (const auto& ts : track.trackStatesReversed()) {
0049 if (!ts.hasReferenceSurface()) {
0050 ACTS_ERROR("Track state has no reference surface");
0051 continue;
0052 }
0053 auto iVolume = ts.referenceSurface().geometryId().volume();
0054 auto volume_it = m_cfg.volumeMap.find(iVolume);
0055 if (volume_it == m_cfg.volumeMap.end()) {
0056 ACTS_ERROR("Volume " << iVolume << "not found in the volume map");
0057 continue;
0058 }
0059 auto detectorId = volume_it->second;
0060
0061 if (ts.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag)) {
0062 Acts::SourceLink sourceLink = ts.getUncalibratedSourceLink();
0063 ACTS_DEBUG("Track state type is MeasurementFlag");
0064
0065 if (ts.typeFlags().test(Acts::TrackStateFlag::SharedHitFlag)) {
0066 trackFeaturesVector[detectorId].nSharedHits++;
0067 }
0068 trackFeaturesVector[detectorId].nHits++;
0069
0070
0071 auto emplace = MeasurementIndexMap.try_emplace(
0072 sourceLink, MeasurementIndexMap.size());
0073
0074 bool isoutliner = false;
0075
0076 measurements.push_back({emplace.first->second, detectorId, isoutliner});
0077 } else if (ts.typeFlags().test(Acts::TrackStateFlag::OutlierFlag)) {
0078 Acts::SourceLink sourceLink = ts.getUncalibratedSourceLink();
0079 ACTS_DEBUG("Track state type is OutlierFlag");
0080 trackFeaturesVector[detectorId].nOutliers++;
0081
0082
0083 auto emplace = MeasurementIndexMap.try_emplace(
0084 sourceLink, MeasurementIndexMap.size());
0085
0086 bool isOutliner = true;
0087
0088 measurements.push_back({emplace.first->second, detectorId, isOutliner});
0089 } else if (ts.typeFlags().test(Acts::TrackStateFlag::HoleFlag)) {
0090 ACTS_DEBUG("Track state type is HoleFlag");
0091 trackFeaturesVector[detectorId].nHoles++;
0092 }
0093 }
0094 measurementsPerTrack.push_back(std::move(measurements));
0095 trackFeaturesVectors.push_back(std::move(trackFeaturesVector));
0096 }
0097
0098 return measurementsPerTrack;
0099 }
0100
0101 template <typename track_container_t, typename traj_t,
0102 template <typename> class holder_t, bool ReadOnly>
0103 std::vector<double> Acts::ScoreBasedAmbiguityResolution::simpleScore(
0104 const TrackContainer<track_container_t, traj_t, holder_t>& tracks,
0105 const std::vector<std::vector<TrackFeatures>>& trackFeaturesVectors,
0106 const OptionalCuts<track_container_t, traj_t, holder_t, ReadOnly>&
0107 optionalCuts) const {
0108 std::vector<double> trackScore;
0109 trackScore.reserve(tracks.size());
0110
0111 int iTrack = 0;
0112
0113 ACTS_VERBOSE("Number of detectors: " << m_cfg.detectorConfigs.size());
0114
0115 ACTS_INFO("Starting to score tracks");
0116
0117
0118 for (const auto& track : tracks) {
0119
0120 const auto& trackFeaturesVector = trackFeaturesVectors[iTrack];
0121 double score = 1;
0122 auto pT = Acts::VectorHelpers::perp(track.momentum());
0123 auto eta = Acts::VectorHelpers::eta(track.momentum());
0124 auto phi = Acts::VectorHelpers::phi(track.momentum());
0125
0126 if (pT < m_cfg.pTMin || pT > m_cfg.pTMax) {
0127 score = 0;
0128 iTrack++;
0129 trackScore.push_back(score);
0130 ACTS_DEBUG("Track: " << iTrack
0131 << " has score = 0, due to pT cuts --- pT = " << pT);
0132 continue;
0133 }
0134
0135
0136 if (phi > m_cfg.phiMax || phi < m_cfg.phiMin) {
0137 score = 0;
0138 iTrack++;
0139 trackScore.push_back(score);
0140 ACTS_DEBUG("Track: " << iTrack
0141 << " has score = 0, due to phi cuts --- phi = "
0142 << phi);
0143 continue;
0144 }
0145
0146
0147 if (eta > m_cfg.etaMax || eta < m_cfg.etaMin) {
0148 score = 0;
0149 iTrack++;
0150 trackScore.push_back(score);
0151 ACTS_DEBUG("Track: " << iTrack
0152 << " has score = 0, due to eta cuts --- eta = "
0153 << eta);
0154 continue;
0155 }
0156
0157
0158 for (const auto& cutFunction : optionalCuts.cuts) {
0159 if (cutFunction(track)) {
0160 score = 0;
0161 ACTS_DEBUG("Track: " << iTrack
0162 << " has score = 0, due to optional cuts.");
0163 break;
0164 }
0165 }
0166
0167 if (score == 0) {
0168 iTrack++;
0169 trackScore.push_back(score);
0170 ACTS_DEBUG("Track: " << iTrack << " score : " << score);
0171 continue;
0172 }
0173
0174 for (std::size_t detectorId = 0; detectorId < m_cfg.detectorConfigs.size();
0175 detectorId++) {
0176 const auto& detector = m_cfg.detectorConfigs.at(detectorId);
0177
0178 const auto& trackFeatures = trackFeaturesVector[detectorId];
0179
0180 ACTS_DEBUG("---> Found summary information");
0181 ACTS_DEBUG("---> Detector ID: " << detectorId);
0182 ACTS_DEBUG("---> Number of hits: " << trackFeatures.nHits);
0183 ACTS_DEBUG("---> Number of holes: " << trackFeatures.nHoles);
0184 ACTS_DEBUG("---> Number of outliers: " << trackFeatures.nOutliers);
0185
0186 if ((trackFeatures.nHits < detector.minHits) ||
0187 (trackFeatures.nHits > detector.maxHits) ||
0188 (trackFeatures.nHoles > detector.maxHoles) ||
0189 (trackFeatures.nOutliers > detector.maxOutliers)) {
0190 score = 0;
0191 ACTS_DEBUG("Track: " << iTrack
0192 << " has score = 0, due to detector cuts");
0193 break;
0194 }
0195 }
0196
0197 if (score == 0) {
0198 iTrack++;
0199 trackScore.push_back(score);
0200 ACTS_DEBUG("Track: " << iTrack << " score : " << score);
0201 continue;
0202 }
0203
0204
0205
0206
0207
0208 ACTS_VERBOSE("Using Simple Scoring function");
0209
0210 score = 100;
0211
0212
0213
0214 for (std::size_t detectorId = 0; detectorId < m_cfg.detectorConfigs.size();
0215 detectorId++) {
0216 const auto& detector = m_cfg.detectorConfigs.at(detectorId);
0217 const auto& trackFeatures = trackFeaturesVector[detectorId];
0218
0219 score += trackFeatures.nHits * detector.hitsScoreWeight;
0220 score += trackFeatures.nHoles * detector.holesScoreWeight;
0221 score += trackFeatures.nOutliers * detector.outliersScoreWeight;
0222 score += trackFeatures.nSharedHits * detector.otherScoreWeight;
0223 }
0224
0225
0226 for (const auto& weightFunction : optionalCuts.weights) {
0227 weightFunction(track, score);
0228 }
0229
0230
0231 if (track.chi2() > 0 && track.nDoF() > 0) {
0232 double p = 1. / std::log10(10. + 10. * track.chi2() / track.nDoF());
0233 if (p > 0) {
0234 score += p;
0235 } else {
0236 score -= 50;
0237 }
0238 }
0239
0240 iTrack++;
0241
0242
0243 trackScore.push_back(score);
0244 ACTS_VERBOSE("Track: " << iTrack << " score: " << score);
0245
0246 }
0247
0248 return trackScore;
0249 }
0250
0251 template <typename track_container_t, typename traj_t,
0252 template <typename> class holder_t, bool ReadOnly>
0253 std::vector<double> Acts::ScoreBasedAmbiguityResolution::ambiguityScore(
0254 const TrackContainer<track_container_t, traj_t, holder_t>& tracks,
0255 const std::vector<std::vector<TrackFeatures>>& trackFeaturesVectors,
0256 const OptionalCuts<track_container_t, traj_t, holder_t, ReadOnly>&
0257 optionalCuts) const {
0258 std::vector<double> trackScore;
0259 trackScore.reserve(tracks.size());
0260
0261 ACTS_VERBOSE("Using Ambiguity Scoring function");
0262
0263 int iTrack = 0;
0264
0265 ACTS_VERBOSE("Number of detectors: " << m_cfg.detectorConfigs.size());
0266
0267 ACTS_INFO("Starting to score tracks");
0268
0269
0270 for (const auto& track : tracks) {
0271
0272 const auto& trackFeaturesVector = trackFeaturesVectors[iTrack];
0273 double score = 1;
0274 auto pT = Acts::VectorHelpers::perp(track.momentum());
0275 auto eta = Acts::VectorHelpers::eta(track.momentum());
0276 auto phi = Acts::VectorHelpers::phi(track.momentum());
0277
0278 if (pT < m_cfg.pTMin || pT > m_cfg.pTMax) {
0279 score = 0;
0280 iTrack++;
0281 trackScore.push_back(score);
0282 ACTS_DEBUG("Track: " << iTrack
0283 << " has score = 0, due to pT cuts --- pT = " << pT);
0284 continue;
0285 }
0286
0287
0288 if (phi > m_cfg.phiMax || phi < m_cfg.phiMin) {
0289 score = 0;
0290 iTrack++;
0291 trackScore.push_back(score);
0292 ACTS_DEBUG("Track: " << iTrack
0293 << " has score = 0, due to phi cuts --- phi = "
0294 << phi);
0295 continue;
0296 }
0297
0298
0299 if (eta > m_cfg.etaMax || eta < m_cfg.etaMin) {
0300 score = 0;
0301 iTrack++;
0302 trackScore.push_back(score);
0303 ACTS_DEBUG("Track: " << iTrack
0304 << " has score = 0, due to eta cuts --- eta = "
0305 << eta);
0306 continue;
0307 }
0308
0309
0310 for (const auto& cutFunction : optionalCuts.cuts) {
0311 if (cutFunction(track)) {
0312 score = 0;
0313 ACTS_DEBUG("Track: " << iTrack
0314 << " has score = 0, due to optional cuts.");
0315 break;
0316 }
0317 }
0318
0319 if (score == 0) {
0320 iTrack++;
0321 trackScore.push_back(score);
0322 ACTS_DEBUG("Track: " << iTrack << " score : " << score);
0323 continue;
0324 }
0325
0326 for (std::size_t detectorId = 0; detectorId < m_cfg.detectorConfigs.size();
0327 detectorId++) {
0328 const auto& detector = m_cfg.detectorConfigs.at(detectorId);
0329
0330 const auto& trackFeatures = trackFeaturesVector[detectorId];
0331
0332 ACTS_DEBUG("---> Found summary information");
0333 ACTS_DEBUG("---> Detector ID: " << detectorId);
0334 ACTS_DEBUG("---> Number of hits: " << trackFeatures.nHits);
0335 ACTS_DEBUG("---> Number of holes: " << trackFeatures.nHoles);
0336 ACTS_DEBUG("---> Number of outliers: " << trackFeatures.nOutliers);
0337
0338 if ((trackFeatures.nHits < detector.minHits) ||
0339 (trackFeatures.nHits > detector.maxHits) ||
0340 (trackFeatures.nHoles > detector.maxHoles) ||
0341 (trackFeatures.nOutliers > detector.maxOutliers)) {
0342 score = 0;
0343 ACTS_DEBUG("Track: " << iTrack
0344 << " has score = 0, due to detector cuts");
0345 break;
0346 }
0347 }
0348
0349 if (score == 0) {
0350 iTrack++;
0351 trackScore.push_back(score);
0352 ACTS_DEBUG("Track: " << iTrack << " score : " << score);
0353 continue;
0354 }
0355
0356
0357 score = std::log10(pT / UnitConstants::MeV) - 1.;
0358
0359 ACTS_DEBUG("Modifier for pT = " << pT << " GeV is : " << score
0360 << " New score now: " << score);
0361
0362 for (std::size_t detectorId = 0; detectorId < m_cfg.detectorConfigs.size();
0363 detectorId++) {
0364 const auto& detector = m_cfg.detectorConfigs.at(detectorId);
0365
0366 const auto& trackFeatures = trackFeaturesVector[detectorId];
0367
0368
0369
0370 std::size_t nHits = trackFeatures.nHits;
0371 if (detector.factorHits.size() < nHits) {
0372 ACTS_WARNING("Detector " << detectorId
0373 << " has not enough factorhits in the "
0374 "detector.factorHits vector");
0375 continue;
0376 }
0377 if (nHits > detector.maxHits) {
0378 score = score * (detector.maxHits - nHits + 1);
0379 nHits = detector.maxHits;
0380 }
0381 score = score * detector.factorHits[nHits];
0382 ACTS_DEBUG("Modifier for " << nHits
0383 << " hits: " << detector.factorHits[nHits]
0384 << " New score now: " << score);
0385
0386
0387
0388 std::size_t iHoles = trackFeatures.nHoles;
0389 if (detector.factorHoles.size() < iHoles) {
0390 ACTS_WARNING("Detector " << detectorId
0391 << " has not enough factorholes in the "
0392 "detector.factorHoles vector");
0393 continue;
0394 }
0395 if (iHoles > detector.maxHoles) {
0396 score /= (iHoles - detector.maxHoles + 1);
0397 iHoles = detector.maxHoles;
0398 }
0399 score = score * detector.factorHoles[iHoles];
0400 ACTS_DEBUG("Modifier for " << iHoles
0401 << " holes: " << detector.factorHoles[iHoles]
0402 << " New score now: " << score);
0403 }
0404
0405 for (const auto& scoreFunction : optionalCuts.scores) {
0406 scoreFunction(track, score);
0407 }
0408
0409 if (track.chi2() > 0 && track.nDoF() > 0) {
0410 double chi2 = track.chi2();
0411 int indf = track.nDoF();
0412 double fac = 1. / std::log10(10. + 10. * chi2 / indf);
0413 score = score * fac;
0414 ACTS_DEBUG("Modifier for chi2 = " << chi2 << " and NDF = " << indf
0415 << " is : " << fac
0416 << " New score now: " << score)
0417 }
0418 iTrack++;
0419
0420
0421 trackScore.push_back(score);
0422 ACTS_VERBOSE("Track: " << iTrack << " score: " << score);
0423
0424 }
0425
0426 return trackScore;
0427 }
0428 template <typename track_container_t, typename traj_t,
0429 template <typename> class holder_t, bool ReadOnly>
0430 std::vector<int> Acts::ScoreBasedAmbiguityResolution::solveAmbiguity(
0431 const TrackContainer<track_container_t, traj_t, holder_t>& tracks,
0432 const std::vector<std::vector<MeasurementInfo>>& measurementsPerTrack,
0433 const std::vector<std::vector<TrackFeatures>>& trackFeaturesVectors,
0434 const OptionalCuts<track_container_t, traj_t, holder_t, ReadOnly>&
0435 optionalCuts) const {
0436 ACTS_INFO("Number of tracks before Ambiguty Resolution: " << tracks.size());
0437
0438
0439
0440 std::vector<double> trackScore;
0441 trackScore.reserve(tracks.size());
0442 if (m_cfg.useAmbiguityFunction) {
0443 trackScore = ambiguityScore(tracks, trackFeaturesVectors, optionalCuts);
0444 } else {
0445 trackScore = simpleScore(tracks, trackFeaturesVectors, optionalCuts);
0446 }
0447
0448 std::vector<bool> cleanTracks = getCleanedOutTracks(
0449 trackScore, trackFeaturesVectors, measurementsPerTrack);
0450
0451 std::vector<int> goodTracks;
0452 int cleanTrackIndex = 0;
0453 std::size_t iTrack = 0;
0454 for (const auto& track : tracks) {
0455 if (cleanTracks[iTrack]) {
0456 cleanTrackIndex++;
0457 if (trackScore[iTrack] >= m_cfg.minScore) {
0458 goodTracks.push_back(track.index());
0459 }
0460 }
0461 iTrack++;
0462 }
0463 ACTS_VERBOSE("Number of clean tracks: " << cleanTrackIndex);
0464 ACTS_VERBOSE("Min score: " << m_cfg.minScore);
0465 ACTS_INFO("Number of Good tracks: " << goodTracks.size());
0466 return goodTracks;
0467 }
0468
0469 }