Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 10:02:33

0001 #include "CandCloner.h"
0002 
0003 #include "RecoTracker/MkFitCore/interface/IterationConfig.h"
0004 
0005 //#define DEBUG
0006 #include "Debug.h"
0007 
0008 namespace {
0009   inline bool sortCandListByScore(const mkfit::IdxChi2List &cand1, const mkfit::IdxChi2List &cand2) {
0010     return mkfit::sortByScoreStruct(cand1, cand2);
0011   }
0012 }  // namespace
0013 
0014 namespace mkfit {
0015 
0016   void CandCloner::setup(const IterationParams &ip) {
0017     mp_iteration_params = &ip;
0018     for (int iseed = 0; iseed < s_max_seed_range; ++iseed) {
0019       t_cands_for_next_lay[iseed].reserve(mp_iteration_params->maxCandsPerSeed);
0020     }
0021   }
0022 
0023   void CandCloner::release() { mp_iteration_params = nullptr; }
0024 
0025   void CandCloner::begin_eta_bin(EventOfCombCandidates *e_o_ccs,
0026                                  std::vector<UpdateIndices> *update_list,
0027                                  std::vector<std::vector<TrackCand>> *extra_cands,
0028                                  int start_seed,
0029                                  int n_seeds) {
0030     mp_event_of_comb_candidates = e_o_ccs;
0031     mp_kalman_update_list = update_list;
0032     mp_extra_cands = extra_cands;
0033     m_start_seed = start_seed;
0034     m_n_seeds = n_seeds;
0035     m_hits_to_add.resize(n_seeds);
0036 
0037     for (int i = 0; i < n_seeds; ++i)
0038       m_hits_to_add[i].reserve(4);
0039 
0040 #ifdef CC_TIME_ETA
0041     printf("CandCloner::begin_eta_bin\n");
0042     t_eta = dtime();
0043 #endif
0044   }
0045 
0046   void CandCloner::begin_layer(int lay) {
0047     m_layer = lay;
0048 
0049     m_idx_max = 0;
0050     m_idx_max_prev = 0;
0051 
0052     mp_kalman_update_list->clear();
0053 
0054 #ifdef CC_TIME_LAYER
0055     t_lay = dtime();
0056 #endif
0057   }
0058 
0059   void CandCloner::begin_iteration() {
0060     // Do nothing, "secondary" state vars updated when work completed/assigned.
0061   }
0062 
0063   void CandCloner::end_iteration() {
0064     int proc_n = m_idx_max - m_idx_max_prev;
0065 
0066     dprintf("CandCloner::end_iteration process %d, max_prev=%d, max=%d\n", proc_n, m_idx_max_prev, m_idx_max);
0067 
0068     if (proc_n >= s_max_seed_range) {
0069       // Round to multiple of s_max_seed_range.
0070       doWork((m_idx_max / s_max_seed_range) * s_max_seed_range);
0071     }
0072   }
0073 
0074   void CandCloner::end_layer() {
0075     if (m_n_seeds > m_idx_max_prev) {
0076       doWork(m_n_seeds);
0077     }
0078 
0079     for (int i = 0; i < m_n_seeds; ++i) {
0080       m_hits_to_add[i].clear();
0081     }
0082 
0083 #ifdef CC_TIME_LAYER
0084     t_lay = dtime() - t_lay;
0085     printf("CandCloner::end_layer %d -- t_lay=%8.6f\n", m_layer, t_lay);
0086     printf("                      m_idx_max=%d, m_idx_max_prev=%d, issued work=%d\n",
0087            m_idx_max,
0088            m_idx_max_prev,
0089            m_idx_max + 1 > m_idx_max_prev);
0090 #endif
0091   }
0092 
0093   void CandCloner::end_eta_bin() {
0094 #ifdef CC_TIME_ETA
0095     t_eta = dtime() - t_eta;
0096     printf("CandCloner::end_eta_bin t_eta=%8.6f\n", t_eta);
0097 #endif
0098   }
0099   //==============================================================================
0100 
0101   void CandCloner::doWork(int idx) {
0102     dprintf("CandCloner::DoWork assigning work from seed %d to %d\n", m_idx_max_prev, idx);
0103 
0104     int beg = m_idx_max_prev;
0105     int the_end = idx;
0106 
0107     dprintf("CandCloner::DoWork working on beg=%d to the_end=%d\n", beg, the_end);
0108 
0109     while (beg != the_end) {
0110       int end = std::min(beg + s_max_seed_range, the_end);
0111 
0112       dprintf("CandCloner::DoWork processing %4d -> %4d\n", beg, end);
0113 
0114       processSeedRange(beg, end);
0115 
0116       beg = end;
0117     }
0118 
0119     m_idx_max_prev = idx;
0120   }
0121 
0122   //==============================================================================
0123 
0124   void CandCloner::processSeedRange(int is_beg, int is_end) {
0125     // Process new hits for a range of seeds.
0126 
0127     // bool debug = true;
0128 
0129     dprintf("\nCandCloner::ProcessSeedRange is_beg=%d, is_end=%d\n", is_beg, is_end);
0130 
0131     //1) sort the candidates
0132     for (int is = is_beg; is < is_end; ++is) {
0133       std::vector<IdxChi2List> &hitsForSeed = m_hits_to_add[is];
0134 
0135       CombCandidate &ccand = mp_event_of_comb_candidates->cand(m_start_seed + is);
0136       std::vector<TrackCand> &extras = (*mp_extra_cands)[is];
0137       auto extra_i = extras.begin();
0138       auto extra_e = extras.end();
0139 
0140       // Extras are sorted by candScore.
0141 
0142 #ifdef DEBUG
0143       dprint("  seed n " << is << " with input candidates=" << hitsForSeed.size());
0144       for (int ih = 0; ih < (int)hitsForSeed.size(); ih++) {
0145         dprint("trkIdx=" << hitsForSeed[ih].trkIdx << " hitIdx=" << hitsForSeed[ih].hitIdx
0146                          << " chi2=" << hitsForSeed[ih].chi2 << std::endl
0147                          << "    "
0148                          << "original pt=" << ccand[hitsForSeed[ih].trkIdx].pT() << " "
0149                          << "nTotalHits=" << ccand[hitsForSeed[ih].trkIdx].nTotalHits() << " "
0150                          << "nFoundHits=" << ccand[hitsForSeed[ih].trkIdx].nFoundHits() << " "
0151                          << "chi2=" << ccand[hitsForSeed[ih].trkIdx].chi2());
0152       }
0153 #endif
0154 
0155       if (!hitsForSeed.empty()) {
0156         //sort the new hits
0157         std::sort(hitsForSeed.begin(), hitsForSeed.end(), sortCandListByScore);
0158 
0159         int num_hits = (int)hitsForSeed.size();
0160 
0161         // This is from buffer, we know it was cleared after last usage.
0162         std::vector<TrackCand> &cv = t_cands_for_next_lay[is - is_beg];
0163 
0164         int n_pushed = 0;
0165 
0166         // Loop over available hits. There are extra loop exit checks every time
0167         // a new candidate is inserted into the new candidate_vector.
0168         for (int ih = 0; ih < num_hits; ih++) {
0169           const IdxChi2List &h2a = hitsForSeed[ih];
0170 
0171           TrackCand tc(ccand[h2a.trkIdx]);
0172           tc.addHitIdx(h2a.hitIdx, m_layer, h2a.chi2_hit);
0173           tc.setScore(h2a.score);
0174 
0175           if (h2a.hitIdx == -2) {
0176             if (h2a.score > ccand.refBestShortCand().score()) {
0177               ccand.setBestShortCand(tc);
0178             }
0179             continue;
0180           }
0181 
0182           // Could also skip storing of cands with last -3 hit.
0183 
0184           // Squeeze in extra tracks that are better than current one.
0185           while (extra_i != extra_e && sortByScoreTrackCand(*extra_i, tc) &&
0186                  n_pushed < mp_iteration_params->maxCandsPerSeed) {
0187             cv.emplace_back(*extra_i);
0188             ++n_pushed;
0189             ++extra_i;
0190           }
0191 
0192           if (n_pushed >= mp_iteration_params->maxCandsPerSeed)
0193             break;
0194 
0195           if (h2a.hitIdx >= 0) {
0196             mp_kalman_update_list->emplace_back(UpdateIndices(m_start_seed + is, n_pushed, h2a.hitIdx));
0197 
0198             // set the overlap if we have it and and pT > pTCutOverlap
0199             HitMatch *hm;
0200             if (tc.pT() > mp_iteration_params->pTCutOverlap &&
0201                 (hm = ccand[h2a.trkIdx].findOverlap(h2a.hitIdx, h2a.module))) {
0202               tc.addHitIdx(hm->m_hit_idx, m_layer, 0);
0203               tc.incOverlapCount();
0204             }
0205           }
0206 
0207           cv.emplace_back(tc);
0208           ++n_pushed;
0209 
0210           if (n_pushed >= mp_iteration_params->maxCandsPerSeed)
0211             break;
0212         }
0213 
0214         // Add remaining extras as long as there is still room for them.
0215         while (extra_i != extra_e && n_pushed < mp_iteration_params->maxCandsPerSeed) {
0216           cv.emplace_back(*extra_i);
0217           ++n_pushed;
0218           ++extra_i;
0219         }
0220 
0221         // Can not use ccand.swap(cv) -- allocations for TrackCand vectors need to be
0222         // in the same memory segment for gather operation to work in backward-fit.
0223         ccand.resize(cv.size());
0224         for (size_t ii = 0; ii < cv.size(); ++ii) {
0225           ccand[ii] = cv[ii];
0226         }
0227         cv.clear();
0228       } else  // hitsForSeed.empty()
0229       {
0230         if (ccand.state() == CombCandidate::Finding) {
0231           ccand.clear();
0232 
0233           while (extra_i != extra_e) {
0234             ccand.emplace_back(*extra_i);
0235             ++extra_i;
0236           }
0237         }
0238       }
0239 
0240       extras.clear();
0241     }
0242   }
0243 
0244 }  // end namespace mkfit