File indexing completed on 2023-01-23 02:42:44
0001 #ifndef RecoTracker_MkFitCore_interface_TrackStructures_h
0002 #define RecoTracker_MkFitCore_interface_TrackStructures_h
0003
0004 #include "RecoTracker/MkFitCore/interface/Config.h"
0005 #include "RecoTracker/MkFitCore/interface/Hit.h"
0006 #include "RecoTracker/MkFitCore/interface/Track.h"
0007 #include "RecoTracker/MkFitCore/interface/TrackerInfo.h"
0008
0009 #include <algorithm>
0010 #include <array>
0011
0012 namespace mkfit {
0013
0014 class IterationParams;
0015
0016
0017
0018
0019
0020 struct HoTNode {
0021 HitOnTrack m_hot;
0022 float m_chi2;
0023 int m_prev_idx;
0024 };
0025
0026 struct HitMatch {
0027 int m_hit_idx = -1;
0028 int m_module_id = -1;
0029 float m_chi2 = 1e9;
0030
0031 void reset() {
0032 m_hit_idx = -1;
0033 m_module_id = -1;
0034 m_chi2 = 1e9;
0035 }
0036 };
0037
0038 struct HitMatchPair {
0039 HitMatch M[2];
0040
0041 void reset() {
0042 M[0].reset();
0043 M[1].reset();
0044 }
0045
0046 void consider_hit_for_overlap(int hit_idx, int module_id, float chi2) {
0047 if (module_id == M[0].m_module_id) {
0048 if (chi2 < M[0].m_chi2) {
0049 M[0].m_chi2 = chi2;
0050 M[0].m_hit_idx = hit_idx;
0051 }
0052 } else if (module_id == M[1].m_module_id) {
0053 if (chi2 < M[1].m_chi2) {
0054 M[1].m_chi2 = chi2;
0055 M[1].m_hit_idx = hit_idx;
0056 }
0057 } else {
0058 if (M[0].m_chi2 > M[1].m_chi2) {
0059 if (chi2 < M[0].m_chi2) {
0060 M[0] = {hit_idx, module_id, chi2};
0061 }
0062 } else {
0063 if (chi2 < M[1].m_chi2) {
0064 M[1] = {hit_idx, module_id, chi2};
0065 }
0066 }
0067 }
0068 }
0069
0070 HitMatch* find_overlap(int hit_idx, int module_id) {
0071 if (module_id == M[0].m_module_id) {
0072 if (M[1].m_hit_idx >= 0)
0073 return &M[1];
0074 } else if (module_id == M[1].m_module_id) {
0075 if (M[0].m_hit_idx >= 0)
0076 return &M[0];
0077 } else {
0078 if (M[0].m_chi2 <= M[1].m_chi2) {
0079 if (M[0].m_hit_idx >= 0)
0080 return &M[0];
0081 } else {
0082 if (M[1].m_hit_idx >= 0)
0083 return &M[1];
0084 }
0085 }
0086
0087 return nullptr;
0088 }
0089 };
0090
0091
0092
0093 template <class T>
0094 class CcPool {
0095 public:
0096 void reset(std::size_t size) {
0097 if (size > m_mem.size())
0098 m_mem.resize(size);
0099 m_pos = 0;
0100 m_size = size;
0101 }
0102
0103 void release() {
0104 std::vector<T> tmp;
0105 m_mem.swap(tmp);
0106 m_pos = 0;
0107 m_size = 0;
0108 }
0109
0110 CcPool(std::size_t size = 0) {
0111 if (size)
0112 reset(size);
0113 }
0114
0115 T* allocate(std::size_t n) {
0116 if (m_pos + n > m_size)
0117 throw std::bad_alloc();
0118 T* ret = &m_mem[m_pos];
0119 m_pos += n;
0120 return ret;
0121 }
0122
0123 void deallocate(T* p, std::size_t n) noexcept {
0124
0125 }
0126
0127 private:
0128 std::vector<T> m_mem;
0129 std::size_t m_pos = 0;
0130 std::size_t m_size = 0;
0131 };
0132
0133 template <class T>
0134 class CcAlloc {
0135 public:
0136 typedef T value_type;
0137
0138 CcAlloc(CcPool<T>* p) : m_pool(p) {}
0139
0140 const void* pool_id() const { return m_pool; }
0141
0142 T* allocate(std::size_t n) { return m_pool->allocate(n); }
0143
0144 void deallocate(T* p, std::size_t n) noexcept { m_pool->deallocate(p, n); }
0145
0146 private:
0147 CcPool<T>* m_pool;
0148 };
0149
0150 template <class T, class U>
0151 bool operator==(const CcAlloc<T>& a, const CcAlloc<U>& b) {
0152 return a.pool_id() == b.pool_id();
0153 }
0154
0155
0156
0157 class CombCandidate;
0158
0159 class TrackCand : public TrackBase {
0160 public:
0161 TrackCand() = default;
0162
0163 explicit TrackCand(const TrackBase& base, CombCandidate* ccand) : TrackBase(base), m_comb_candidate(ccand) {
0164
0165 lastHitIdx_ = -1;
0166 nFoundHits_ = 0;
0167 }
0168
0169
0170
0171
0172
0173
0174
0175 CombCandidate* combCandidate() const { return m_comb_candidate; }
0176 void setCombCandidate(CombCandidate* cc) { m_comb_candidate = cc; }
0177
0178 int lastCcIndex() const { return lastHitIdx_; }
0179 int nFoundHits() const { return nFoundHits_; }
0180 int nMissingHits() const { return nMissingHits_; }
0181 int nOverlapHits() const { return nOverlapHits_; }
0182 int nTotalHits() const { return nFoundHits_ + nMissingHits_; }
0183
0184 void setLastCcIndex(int i) { lastHitIdx_ = i; }
0185 void setNFoundHits(int n) { nFoundHits_ = n; }
0186 void setNMissingHits(int n) { nMissingHits_ = n; }
0187 void setNOverlapHits(int n) { nOverlapHits_ = n; }
0188
0189 int nInsideMinusOneHits() const { return nInsideMinusOneHits_; }
0190 int nTailMinusOneHits() const { return nTailMinusOneHits_; }
0191
0192 void setNInsideMinusOneHits(int n) { nInsideMinusOneHits_ = n; }
0193 void setNTailMinusOneHits(int n) { nTailMinusOneHits_ = n; }
0194
0195 int originIndex() const { return m_origin_index; }
0196 void setOriginIndex(int oi) { m_origin_index = oi; }
0197
0198 void resetOverlaps() { m_overlap_hits.reset(); }
0199 void considerHitForOverlap(int hit_idx, int module_id, float chi2) {
0200 m_overlap_hits.consider_hit_for_overlap(hit_idx, module_id, chi2);
0201 }
0202 HitMatch* findOverlap(int hit_idx, int module_id) { return m_overlap_hits.find_overlap(hit_idx, module_id); }
0203
0204
0205
0206 HitOnTrack getLastHitOnTrack() const;
0207 int getLastHitIdx() const;
0208 int getLastHitLyr() const;
0209
0210
0211 int getLastFoundPixelHitLyr() const;
0212 int getLastFoundHitLyr() const;
0213 int nUniqueLayers() const;
0214
0215 int nLayersByTypeEncoded(const TrackerInfo& trk_inf) const;
0216 int nHitsByTypeEncoded(const TrackerInfo& trk_inf) const;
0217
0218 int nPixelDecoded(const int& encoded) const { return encoded % 100; }
0219 int nStereoDecoded(const int& encoded) const { return (encoded / 100) % 100; }
0220 int nMonoDecoded(const int& encoded) const { return (encoded / 10000) % 100; }
0221 int nMatchedDecoded(const int& encoded) const { return encoded / 1000000; }
0222 int nTotMatchDecoded(const int& encoded) const {
0223 return encoded % 100 + (encoded / 100) % 100 + (encoded / 10000) % 100 - encoded / 1000000;
0224 }
0225
0226 void addHitIdx(int hitIdx, int hitLyr, float chi2);
0227
0228 HoTNode& refLastHoTNode();
0229 const HoTNode& refLastHoTNode() const;
0230
0231 void incOverlapCount() { ++nOverlapHits_; }
0232
0233 Track exportTrack(bool remove_missing_hits = false) const;
0234
0235 void resetShortTrack() {
0236 score_ = getScoreWorstPossible();
0237 m_comb_candidate = nullptr;
0238 }
0239
0240 private:
0241 CombCandidate* m_comb_candidate = nullptr;
0242 HitMatchPair m_overlap_hits;
0243
0244
0245 short int nMissingHits_ = 0;
0246 short int nOverlapHits_ = 0;
0247
0248 short int nInsideMinusOneHits_ = 0;
0249 short int nTailMinusOneHits_ = 0;
0250
0251 short int m_origin_index = -1;
0252 };
0253
0254 inline bool sortByScoreTrackCand(const TrackCand& cand1, const TrackCand& cand2) {
0255 return cand1.score() > cand2.score();
0256 }
0257
0258 inline float getScoreCand(const track_score_func& score_func,
0259 const TrackCand& cand1,
0260 bool penalizeTailMissHits = false,
0261 bool inFindCandidates = false) {
0262 int nfoundhits = cand1.nFoundHits();
0263 int noverlaphits = cand1.nOverlapHits();
0264 int nmisshits = cand1.nInsideMinusOneHits();
0265 int ntailmisshits = penalizeTailMissHits ? cand1.nTailMinusOneHits() : 0;
0266 float pt = cand1.pT();
0267 float chi2 = cand1.chi2();
0268
0269 if (chi2 < 0)
0270 chi2 = 0.f;
0271 return score_func(nfoundhits, ntailmisshits, noverlaphits, nmisshits, chi2, pt, inFindCandidates);
0272 }
0273
0274
0275
0276 class CombCandidate {
0277 public:
0278 using trk_cand_vec_type = std::vector<TrackCand, CcAlloc<TrackCand>>;
0279 using allocator_type = CcAlloc<TrackCand>;
0280
0281 enum SeedState_e { Dormant = 0, Finding, Finished };
0282
0283 CombCandidate(const allocator_type& alloc) : m_trk_cands(alloc), m_state(Dormant), m_pickup_layer(-1) {}
0284
0285
0286 CombCandidate(const CombCandidate& o)
0287 : m_trk_cands(o.m_trk_cands),
0288 m_state(o.m_state),
0289 m_pickup_layer(o.m_pickup_layer),
0290 m_lastHitIdx_before_bkwsearch(o.m_lastHitIdx_before_bkwsearch),
0291 m_nInsideMinusOneHits_before_bkwsearch(o.m_nInsideMinusOneHits_before_bkwsearch),
0292 m_nTailMinusOneHits_before_bkwsearch(o.m_nTailMinusOneHits_before_bkwsearch),
0293 #ifdef DUMPHITWINDOW
0294 m_seed_algo(o.m_seed_algo),
0295 m_seed_label(o.m_seed_label),
0296 #endif
0297 m_hots_size(o.m_hots_size),
0298 m_hots(o.m_hots) {
0299 }
0300
0301
0302 CombCandidate(CombCandidate&& o)
0303 : m_trk_cands(std::move(o.m_trk_cands)),
0304 m_best_short_cand(std::move(o.m_best_short_cand)),
0305 m_state(o.m_state),
0306 m_pickup_layer(o.m_pickup_layer),
0307 m_lastHitIdx_before_bkwsearch(o.m_lastHitIdx_before_bkwsearch),
0308 m_nInsideMinusOneHits_before_bkwsearch(o.m_nInsideMinusOneHits_before_bkwsearch),
0309 m_nTailMinusOneHits_before_bkwsearch(o.m_nTailMinusOneHits_before_bkwsearch),
0310 #ifdef DUMPHITWINDOW
0311 m_seed_algo(o.m_seed_algo),
0312 m_seed_label(o.m_seed_label),
0313 #endif
0314 m_hots_size(o.m_hots_size),
0315 m_hots(std::move(o.m_hots)) {
0316
0317
0318
0319
0320
0321 }
0322
0323
0324
0325
0326
0327 CombCandidate& operator=(CombCandidate&& o) {
0328 m_trk_cands = (std::move(o.m_trk_cands));
0329 m_best_short_cand = std::move(o.m_best_short_cand);
0330 m_state = o.m_state;
0331 m_pickup_layer = o.m_pickup_layer;
0332 m_lastHitIdx_before_bkwsearch = o.m_lastHitIdx_before_bkwsearch;
0333 m_nInsideMinusOneHits_before_bkwsearch = o.m_nInsideMinusOneHits_before_bkwsearch;
0334 m_nTailMinusOneHits_before_bkwsearch = o.m_nTailMinusOneHits_before_bkwsearch;
0335 #ifdef DUMPHITWINDOW
0336 m_seed_algo = o.m_seed_algo;
0337 m_seed_label = o.m_seed_label;
0338 #endif
0339 m_hots_size = o.m_hots_size;
0340 m_hots = std::move(o.m_hots);
0341
0342 for (auto& tc : m_trk_cands)
0343 tc.setCombCandidate(this);
0344
0345 return *this;
0346 }
0347
0348
0349 bool empty() const { return m_trk_cands.empty(); }
0350 trk_cand_vec_type::size_type size() const { return m_trk_cands.size(); }
0351 void resize(trk_cand_vec_type::size_type count) { m_trk_cands.resize(count); }
0352 TrackCand& operator[](int i) { return m_trk_cands[i]; }
0353 const TrackCand& operator[](int i) const { return m_trk_cands[i]; }
0354 TrackCand& front() { return m_trk_cands.front(); }
0355 const TrackCand& front() const { return m_trk_cands.front(); }
0356 trk_cand_vec_type::reference emplace_back(TrackCand& tc) { return m_trk_cands.emplace_back(tc); }
0357 void clear() { m_trk_cands.clear(); }
0358
0359 void reset(int max_cands_per_seed, int expected_num_hots) {
0360 std::vector<TrackCand, CcAlloc<TrackCand>> tmp(m_trk_cands.get_allocator());
0361 m_trk_cands.swap(tmp);
0362 m_trk_cands.reserve(max_cands_per_seed);
0363
0364 m_best_short_cand.setScore(getScoreWorstPossible());
0365
0366
0367
0368
0369
0370
0371
0372 m_hots.reserve(expected_num_hots);
0373 m_hots_size = 0;
0374 m_hots.clear();
0375 }
0376
0377 void importSeed(const Track& seed, const track_score_func& score_func, int region);
0378
0379 int addHit(const HitOnTrack& hot, float chi2, int prev_idx) {
0380 m_hots.push_back({hot, chi2, prev_idx});
0381 return m_hots_size++;
0382 }
0383
0384 void mergeCandsAndBestShortOne(const IterationParams& params,
0385 const track_score_func& score_func,
0386 bool update_score,
0387 bool sort_cands);
0388
0389 void compactifyHitStorageForBestCand(bool remove_seed_hits, int backward_fit_min_hits);
0390 void beginBkwSearch();
0391 void endBkwSearch();
0392
0393
0394
0395 int hotsSize() const { return m_hots_size; }
0396 const HoTNode& hot_node(int i) const { return m_hots[i]; }
0397 HoTNode& hot_node_nc(int i) { return m_hots[i]; }
0398 HitOnTrack hot(int i) const { return m_hots[i].m_hot; }
0399
0400 const HoTNode* hotsData() const { return m_hots.data(); }
0401
0402 const TrackCand& refBestShortCand() const { return m_best_short_cand; }
0403 void setBestShortCand(const TrackCand& tc) { m_best_short_cand = tc; }
0404
0405 SeedState_e state() const { return m_state; }
0406 void setState(SeedState_e ss) { m_state = ss; }
0407
0408 int pickupLayer() const { return m_pickup_layer; }
0409
0410 #ifdef DUMPHITWINDOW
0411 int seed_algo() const { return m_seed_algo; }
0412 int seed_label() const { return m_seed_label; }
0413 #endif
0414
0415 private:
0416 trk_cand_vec_type m_trk_cands;
0417 TrackCand m_best_short_cand;
0418 SeedState_e m_state : 8;
0419 int m_pickup_layer : 16;
0420 short int m_lastHitIdx_before_bkwsearch = -1;
0421 short int m_nInsideMinusOneHits_before_bkwsearch = -1;
0422 short int m_nTailMinusOneHits_before_bkwsearch = -1;
0423
0424 #ifdef DUMPHITWINDOW
0425 int m_seed_algo = 0;
0426 int m_seed_label = 0;
0427 #endif
0428 int m_hots_size = 0;
0429 std::vector<HoTNode> m_hots;
0430 };
0431
0432
0433
0434 inline HitOnTrack TrackCand::getLastHitOnTrack() const { return m_comb_candidate->hot(lastHitIdx_); }
0435
0436 inline int TrackCand::getLastHitIdx() const { return m_comb_candidate->hot(lastHitIdx_).index; }
0437
0438 inline int TrackCand::getLastHitLyr() const { return m_comb_candidate->hot(lastHitIdx_).layer; }
0439
0440 inline int TrackCand::getLastFoundHitLyr() const {
0441 int nh = nTotalHits();
0442 int ch = lastHitIdx_;
0443 int ll = -1;
0444 while (--nh >= 0) {
0445 const HoTNode& hot_node = m_comb_candidate->hot_node(ch);
0446 if (hot_node.m_hot.index < 0) {
0447 ch = hot_node.m_prev_idx;
0448 } else {
0449 ll = hot_node.m_hot.layer;
0450 break;
0451 }
0452 }
0453 return ll;
0454 }
0455
0456 inline int TrackCand::getLastFoundPixelHitLyr() const {
0457 int nh = nTotalHits();
0458 int ch = lastHitIdx_;
0459 int ll = -1;
0460 while (--nh >= 0) {
0461 const HoTNode& hot_node = m_comb_candidate->hot_node(ch);
0462 int tl = hot_node.m_hot.layer;
0463 if (hot_node.m_hot.index < 0 || !((0 <= tl && tl <= 3) || (18 <= tl && tl <= 20) || (45 <= tl && tl <= 47))) {
0464 ch = hot_node.m_prev_idx;
0465 } else if ((0 <= tl && tl <= 3) || (18 <= tl && tl <= 20) || (45 <= tl && tl <= 47)) {
0466 ll = hot_node.m_hot.layer;
0467 break;
0468 }
0469 }
0470 return ll;
0471 }
0472
0473 inline int TrackCand::nUniqueLayers() const {
0474 int nUL = 0;
0475 int prevL = -1;
0476 int nh = nTotalHits();
0477 int ch = lastHitIdx_;
0478
0479 while (--nh >= 0) {
0480 const HoTNode& hot_node = m_comb_candidate->hot_node(ch);
0481 int thisL = hot_node.m_hot.layer;
0482 if (thisL >= 0 && (hot_node.m_hot.index >= 0 || hot_node.m_hot.index == Hit::kHitCCCFilterIdx) &&
0483 thisL != prevL) {
0484 ++nUL;
0485 prevL = thisL;
0486 }
0487 ch = hot_node.m_prev_idx;
0488 }
0489 return nUL;
0490 }
0491
0492 inline int TrackCand::nHitsByTypeEncoded(const TrackerInfo& trk_inf) const {
0493 int prevL = -1;
0494 bool prevStereo = false;
0495 int nh = nTotalHits();
0496 int ch = lastHitIdx_;
0497 int pix = 0, stereo = 0, mono = 0, matched = 0;
0498 int doubleStereo = -1;
0499 while (--nh >= 0) {
0500 const HoTNode& hot_node = m_comb_candidate->hot_node(ch);
0501 int thisL = hot_node.m_hot.layer;
0502 if (thisL >= 0 && (hot_node.m_hot.index >= 0 || hot_node.m_hot.index == Hit::kHitCCCFilterIdx)) {
0503 bool cStereo = trk_inf[thisL].is_stereo();
0504 if (trk_inf[thisL].is_pixel())
0505 ++pix;
0506 else if (cStereo) {
0507 ++stereo;
0508 if (thisL == prevL)
0509 doubleStereo = thisL;
0510 } else {
0511
0512 ++mono;
0513 if (prevStereo && thisL == prevL - 1)
0514 ++matched;
0515 else if (thisL == prevL && thisL == doubleStereo - 1)
0516 ++matched;
0517 }
0518 prevL = thisL;
0519 prevStereo = cStereo;
0520 }
0521 ch = hot_node.m_prev_idx;
0522 }
0523 return pix + 100 * stereo + 10000 * mono + 1000000 * matched;
0524 }
0525
0526 inline int TrackCand::nLayersByTypeEncoded(const TrackerInfo& trk_inf) const {
0527 int prevL = -1;
0528 bool prevStereo = false;
0529 int nh = nTotalHits();
0530 int ch = lastHitIdx_;
0531 int pix = 0, stereo = 0, mono = 0, matched = 0;
0532 while (--nh >= 0) {
0533 const HoTNode& hot_node = m_comb_candidate->hot_node(ch);
0534 int thisL = hot_node.m_hot.layer;
0535 if (thisL >= 0 && (hot_node.m_hot.index >= 0 || hot_node.m_hot.index == Hit::kHitCCCFilterIdx) &&
0536 thisL != prevL) {
0537 bool cStereo = trk_inf[thisL].is_stereo();
0538 if (trk_inf[thisL].is_pixel())
0539 ++pix;
0540 else if (cStereo)
0541 ++stereo;
0542 else {
0543
0544 ++mono;
0545 if (prevStereo && thisL == prevL - 1)
0546 ++matched;
0547 }
0548 prevL = thisL;
0549 prevStereo = cStereo;
0550 }
0551 ch = hot_node.m_prev_idx;
0552 }
0553 return pix + 100 * stereo + 10000 * mono + 1000000 * matched;
0554 }
0555
0556 inline HoTNode& TrackCand::refLastHoTNode() { return m_comb_candidate->hot_node_nc(lastHitIdx_); }
0557
0558 inline const HoTNode& TrackCand::refLastHoTNode() const { return m_comb_candidate->hot_node(lastHitIdx_); }
0559
0560
0561
0562 inline void TrackCand::addHitIdx(int hitIdx, int hitLyr, float chi2) {
0563 lastHitIdx_ = m_comb_candidate->addHit({hitIdx, hitLyr}, chi2, lastHitIdx_);
0564
0565 if (hitIdx >= 0 || hitIdx == Hit::kHitCCCFilterIdx) {
0566 ++nFoundHits_;
0567 chi2_ += chi2;
0568 nInsideMinusOneHits_ += nTailMinusOneHits_;
0569 nTailMinusOneHits_ = 0;
0570 }
0571
0572 else {
0573 ++nMissingHits_;
0574 if (hitIdx == Hit::kHitMissIdx)
0575 ++nTailMinusOneHits_;
0576 }
0577 }
0578
0579
0580
0581 class EventOfCombCandidates {
0582 public:
0583 EventOfCombCandidates(int size = 0) : m_cc_pool(), m_candidates() {}
0584
0585 void releaseMemory() {
0586 {
0587 std::vector<CombCandidate> tmp;
0588 m_candidates.swap(tmp);
0589 }
0590 m_capacity = 0;
0591 m_size = 0;
0592 m_n_seeds_inserted = 0;
0593 m_cc_pool.release();
0594 }
0595
0596 void reset(int new_capacity, int max_cands_per_seed, int expected_num_hots = 128) {
0597 m_cc_pool.reset(new_capacity * max_cands_per_seed);
0598 if (new_capacity > m_capacity) {
0599 CcAlloc<TrackCand> alloc(&m_cc_pool);
0600 std::vector<CombCandidate> tmp(new_capacity, alloc);
0601 m_candidates.swap(tmp);
0602 m_capacity = new_capacity;
0603 }
0604 for (int s = 0; s < new_capacity; ++s) {
0605 m_candidates[s].reset(max_cands_per_seed, expected_num_hots);
0606 }
0607 for (int s = new_capacity; s < m_capacity; ++s) {
0608 m_candidates[s].reset(0, 0);
0609 }
0610
0611 m_size = new_capacity;
0612 m_n_seeds_inserted = 0;
0613 }
0614
0615 void resizeAfterFiltering(int n_removed) {
0616 assert(n_removed <= m_size);
0617 m_size -= n_removed;
0618 m_n_seeds_inserted -= n_removed;
0619 }
0620
0621 void insertSeed(const Track& seed, const track_score_func& score_func, int region, int pos) {
0622 assert(pos < m_size);
0623
0624 m_candidates[pos].importSeed(seed, score_func, region);
0625
0626 ++m_n_seeds_inserted;
0627 }
0628
0629 void compactifyHitStorageForBestCand(bool remove_seed_hits, int backward_fit_min_hits) {
0630 for (int i = 0; i < m_size; ++i)
0631 m_candidates[i].compactifyHitStorageForBestCand(remove_seed_hits, backward_fit_min_hits);
0632 }
0633
0634 void beginBkwSearch() {
0635 for (int i = 0; i < m_size; ++i)
0636 m_candidates[i].beginBkwSearch();
0637 }
0638 void endBkwSearch() {
0639 for (int i = 0; i < m_size; ++i)
0640 m_candidates[i].endBkwSearch();
0641 }
0642
0643
0644 int size() const { return m_size; }
0645
0646 const CombCandidate& operator[](int i) const { return m_candidates[i]; }
0647 CombCandidate& operator[](int i) { return m_candidates[i]; }
0648 CombCandidate& cand(int i) { return m_candidates[i]; }
0649
0650
0651 const std::vector<CombCandidate>& refCandidates() const { return m_candidates; }
0652 std::vector<CombCandidate>& refCandidates_nc() { return m_candidates; }
0653
0654 private:
0655 CcPool<TrackCand> m_cc_pool;
0656
0657 std::vector<CombCandidate> m_candidates;
0658
0659 int m_capacity = 0;
0660 int m_size = 0;
0661 int m_n_seeds_inserted = 0;
0662 };
0663
0664 }
0665
0666 #endif