Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:28:18

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