File indexing completed on 2023-11-19 23:58:43
0001 #include <memory>
0002 #include <limits>
0003 #include <algorithm>
0004
0005 #include "RecoTracker/MkFitCore/interface/cms_common_macros.h"
0006
0007 #include "RecoTracker/MkFitCore/interface/MkBuilder.h"
0008 #include "RecoTracker/MkFitCore/interface/TrackerInfo.h"
0009 #include "RecoTracker/MkFitCore/interface/binnor.h"
0010
0011 #include "Pool.h"
0012 #include "CandCloner.h"
0013 #include "FindingFoos.h"
0014 #include "MkFitter.h"
0015 #include "MkFinder.h"
0016
0017 #ifdef MKFIT_STANDALONE
0018 #include "RecoTracker/MkFitCore/standalone/Event.h"
0019 #endif
0020
0021
0022 #include "Debug.h"
0023
0024
0025 #include "oneapi/tbb/parallel_for.h"
0026 #include "oneapi/tbb/parallel_for_each.h"
0027
0028 namespace mkfit {
0029
0030
0031
0032
0033
0034 struct ExecutionContext {
0035 ExecutionContext() = default;
0036 ~ExecutionContext() = default;
0037
0038 Pool<CandCloner> m_cloners;
0039 Pool<MkFitter> m_fitters;
0040 Pool<MkFinder> m_finders;
0041
0042 void populate(int n_thr) {
0043 m_cloners.populate(n_thr - m_cloners.size());
0044 m_fitters.populate(n_thr - m_fitters.size());
0045 m_finders.populate(n_thr - m_finders.size());
0046 }
0047 };
0048
0049 CMS_SA_ALLOW ExecutionContext g_exe_ctx;
0050
0051 }
0052
0053
0054
0055 namespace {
0056 using namespace mkfit;
0057
0058
0059 struct RangeOfSeedIndices {
0060 int m_rng_beg, m_rng_end;
0061 int m_beg, m_end;
0062
0063 RangeOfSeedIndices(int rb, int re) : m_rng_beg(rb), m_rng_end(re) { reset(); }
0064
0065 void reset() {
0066 m_end = m_rng_beg;
0067 next_chunk();
0068 }
0069
0070 bool valid() const { return m_beg < m_rng_end; }
0071
0072 int n_proc() const { return m_end - m_beg; }
0073
0074 void next_chunk() {
0075 m_beg = m_end;
0076 m_end = std::min(m_end + NN, m_rng_end);
0077 }
0078
0079 RangeOfSeedIndices &operator++() {
0080 next_chunk();
0081 return *this;
0082 }
0083 };
0084
0085
0086 struct RegionOfSeedIndices {
0087 int m_reg_beg, m_reg_end, m_vec_cnt;
0088
0089 RegionOfSeedIndices(const std::vector<int> &seedEtaSeparators, int region) {
0090 m_reg_beg = (region == 0) ? 0 : seedEtaSeparators[region - 1];
0091 m_reg_end = seedEtaSeparators[region];
0092 m_vec_cnt = (m_reg_end - m_reg_beg + NN - 1) / NN;
0093 }
0094
0095 int count() const { return m_reg_end - m_reg_beg; }
0096
0097 tbb::blocked_range<int> tbb_blk_rng_std(int thr_hint = -1) const {
0098 if (thr_hint < 0)
0099 thr_hint = Config::numSeedsPerTask;
0100 return tbb::blocked_range<int>(m_reg_beg, m_reg_end, thr_hint);
0101 }
0102
0103 tbb::blocked_range<int> tbb_blk_rng_vec() const {
0104 return tbb::blocked_range<int>(0, m_vec_cnt, std::max(1, Config::numSeedsPerTask / NN));
0105 }
0106
0107 RangeOfSeedIndices seed_rng(const tbb::blocked_range<int> &i) const {
0108 return RangeOfSeedIndices(m_reg_beg + NN * i.begin(), std::min(m_reg_beg + NN * i.end(), m_reg_end));
0109 }
0110 };
0111
0112 #ifdef DEBUG
0113 void pre_prop_print(int ilay, MkBase *fir) {
0114 const float pt = 1.f / fir->getPar(0, 0, 3);
0115 std::cout << "propagate to lay=" << ilay << " start from x=" << fir->getPar(0, 0, 0)
0116 << " y=" << fir->getPar(0, 0, 1) << " z=" << fir->getPar(0, 0, 2)
0117 << " r=" << getHypot(fir->getPar(0, 0, 0), fir->getPar(0, 0, 1))
0118 << " px=" << pt * std::cos(fir->getPar(0, 0, 4)) << " py=" << pt * std::sin(fir->getPar(0, 0, 4))
0119 << " pz=" << pt / std::tan(fir->getPar(0, 0, 5)) << " pT=" << pt << std::endl;
0120 }
0121
0122 void post_prop_print(int ilay, MkBase *fir) {
0123 std::cout << "propagate to lay=" << ilay << " arrive at x=" << fir->getPar(0, 1, 0) << " y=" << fir->getPar(0, 1, 1)
0124 << " z=" << fir->getPar(0, 1, 2) << " r=" << getHypot(fir->getPar(0, 1, 0), fir->getPar(0, 1, 1))
0125 << std::endl;
0126 }
0127
0128 void print_seed(const Track &seed) {
0129 std::cout << "MX - found seed with label=" << seed.label() << " nHits=" << seed.nFoundHits()
0130 << " chi2=" << seed.chi2() << " posEta=" << seed.posEta() << " posPhi=" << seed.posPhi()
0131 << " posR=" << seed.posR() << " posZ=" << seed.z() << " pT=" << seed.pT() << std::endl;
0132 }
0133
0134 void print_seed2(const TrackCand &seed) {
0135 std::cout << "MX - found seed with nFoundHits=" << seed.nFoundHits() << " chi2=" << seed.chi2() << " x=" << seed.x()
0136 << " y=" << seed.y() << " z=" << seed.z() << " px=" << seed.px() << " py=" << seed.py()
0137 << " pz=" << seed.pz() << " pT=" << seed.pT() << std::endl;
0138 }
0139
0140 void print_seeds(const TrackVec &seeds) {
0141 std::cout << "found total seeds=" << seeds.size() << std::endl;
0142 for (auto &&seed : seeds) {
0143 print_seed(seed);
0144 }
0145 }
0146
0147 [[maybe_unused]] void print_seeds(const EventOfCombCandidates &event_of_comb_cands) {
0148 for (int iseed = 0; iseed < event_of_comb_cands.size(); iseed++) {
0149 print_seed2(event_of_comb_cands[iseed].front());
0150 }
0151 }
0152 #endif
0153
0154 bool sortCandByScore(const TrackCand &cand1, const TrackCand &cand2) {
0155 return mkfit::sortByScoreTrackCand(cand1, cand2);
0156 }
0157
0158 }
0159
0160
0161
0162
0163
0164 namespace mkfit {
0165
0166 std::unique_ptr<MkBuilder> MkBuilder::make_builder(bool silent) { return std::make_unique<MkBuilder>(silent); }
0167
0168 void MkBuilder::populate() { g_exe_ctx.populate(Config::numThreadsFinder); }
0169
0170 std::pair<int, int> MkBuilder::max_hits_layer(const EventOfHits &eoh) const {
0171 int maxN = 0;
0172 int maxL = 0;
0173 for (int l = 0; l < eoh.nLayers(); ++l) {
0174 int lsize = eoh[l].nHits();
0175 if (lsize > maxN) {
0176 maxN = lsize;
0177 maxL = eoh[l].layer_id();
0178 }
0179 }
0180 return {maxN, maxL};
0181 }
0182
0183 int MkBuilder::total_cands() const {
0184 int res = 0;
0185 for (int i = 0; i < m_event_of_comb_cands.size(); ++i)
0186 res += m_event_of_comb_cands[i].size();
0187 return res;
0188 }
0189
0190
0191
0192
0193
0194 void MkBuilder::begin_event(MkJob *job, Event *ev, const char *build_type) {
0195 m_nan_n_silly_per_layer_count = 0;
0196
0197 m_job = job;
0198 m_event = ev;
0199
0200 m_seedEtaSeparators.resize(m_job->num_regions());
0201 m_seedMinLastLayer.resize(m_job->num_regions());
0202 m_seedMaxLastLayer.resize(m_job->num_regions());
0203
0204 for (int i = 0; i < m_job->num_regions(); ++i) {
0205 m_seedEtaSeparators[i] = 0;
0206 m_seedMinLastLayer[i] = 9999;
0207 m_seedMaxLastLayer[i] = 0;
0208 }
0209
0210 if (!m_silent) {
0211 std::cout << "MkBuilder building tracks with '" << build_type << "'"
0212 << ", iteration_index=" << job->m_iter_config.m_iteration_index
0213 << ", track_algorithm=" << job->m_iter_config.m_track_algorithm << std::endl;
0214 }
0215 }
0216
0217 void MkBuilder::end_event() {
0218 m_job = nullptr;
0219 m_event = nullptr;
0220 }
0221
0222 void MkBuilder::release_memory() {
0223 TrackVec tmp;
0224 m_tracks.swap(tmp);
0225 m_event_of_comb_cands.releaseMemory();
0226 }
0227
0228 void MkBuilder::import_seeds(const TrackVec &in_seeds,
0229 const bool seeds_sorted,
0230 std::function<insert_seed_foo> insert_seed) {
0231
0232
0233 const int size = in_seeds.size();
0234
0235 IterationSeedPartition part(size);
0236 std::vector<unsigned> ranks;
0237 if (!seeds_sorted) {
0238
0239 axis_pow2_u1<float, unsigned short, 10, 4> ax_phi(-Const::PI, Const::PI);
0240 axis<float, unsigned short, 8, 8> ax_eta(-3.0, 3.0, 64u);
0241 binnor<unsigned int, decltype(ax_phi), decltype(ax_eta), 20, 12> phi_eta_binnor(ax_phi, ax_eta);
0242 part.m_phi_eta_foo = [&](float phi, float eta) { phi_eta_binnor.register_entry_safe(phi, eta); };
0243
0244 phi_eta_binnor.begin_registration(size);
0245 m_job->m_iter_config.m_seed_partitioner(m_job->m_trk_info, in_seeds, m_job->m_event_of_hits, part);
0246 phi_eta_binnor.finalize_registration();
0247 ranks.swap(phi_eta_binnor.m_ranks);
0248 } else {
0249 m_job->m_iter_config.m_seed_partitioner(m_job->m_trk_info, in_seeds, m_job->m_event_of_hits, part);
0250 }
0251
0252 for (int i = 0; i < size; ++i) {
0253 int j = seeds_sorted ? i : ranks[i];
0254 int reg = part.m_region[j];
0255 ++m_seedEtaSeparators[reg];
0256 }
0257
0258
0259
0260 std::vector<int> seed_cursors(m_job->num_regions());
0261 for (int reg = 1; reg < m_job->num_regions(); ++reg) {
0262 seed_cursors[reg] = m_seedEtaSeparators[reg - 1];
0263 m_seedEtaSeparators[reg] += m_seedEtaSeparators[reg - 1];
0264 }
0265
0266
0267 for (int i = 0; i < size; ++i) {
0268 int j = seeds_sorted ? i : ranks[i];
0269 int reg = part.m_region[j];
0270 const Track &seed = in_seeds[j];
0271 insert_seed(seed, j, reg, seed_cursors[reg]++);
0272
0273 HitOnTrack hot = seed.getLastHitOnTrack();
0274 m_seedMinLastLayer[reg] = std::min(m_seedMinLastLayer[reg], hot.layer);
0275 m_seedMaxLastLayer[reg] = std::max(m_seedMaxLastLayer[reg], hot.layer);
0276 }
0277
0278
0279 for (int reg = 0; reg < m_job->num_regions(); ++reg) {
0280 if (m_seedMinLastLayer[reg] == 9999)
0281 m_seedMinLastLayer[reg] = -1;
0282 if (m_seedMaxLastLayer[reg] == 0)
0283 m_seedMaxLastLayer[reg] = -1;
0284 }
0285
0286
0287 dprintf("MkBuilder::import_seeds finished import of %d seeds (last seeding layer min, max):\n"
0288 " ec- = %d(%d,%d), t- = %d(%d,%d), brl = %d(%d,%d), t+ = %d(%d,%d), ec+ = %d(%d,%d).\n",
0289 size,
0290 m_seedEtaSeparators[0], m_seedMinLastLayer[0], m_seedMaxLastLayer[0],
0291 m_seedEtaSeparators[1] - m_seedEtaSeparators[0], m_seedMinLastLayer[1], m_seedMaxLastLayer[1],
0292 m_seedEtaSeparators[2] - m_seedEtaSeparators[1], m_seedMinLastLayer[2], m_seedMaxLastLayer[2],
0293 m_seedEtaSeparators[3] - m_seedEtaSeparators[2], m_seedMinLastLayer[3], m_seedMaxLastLayer[3],
0294 m_seedEtaSeparators[4] - m_seedEtaSeparators[3], m_seedMinLastLayer[4], m_seedMaxLastLayer[4]);
0295
0296
0297 }
0298
0299
0300
0301 int MkBuilder::filter_comb_cands(filter_candidates_func filter, bool attempt_all_cands) {
0302 EventOfCombCandidates &eoccs = m_event_of_comb_cands;
0303 int i = 0, place_pos = 0;
0304
0305 dprintf("MkBuilder::filter_comb_cands Entering filter size eoccs.size=%d\n", eoccs.size());
0306
0307 std::vector<int> removed_cnts(m_job->num_regions());
0308 while (i < eoccs.size()) {
0309 if (eoccs.cands_in_backward_rep())
0310 eoccs[i].repackCandPostBkwSearch(0);
0311 bool passed = filter(eoccs[i].front(), *m_job);
0312
0313 if (!passed && attempt_all_cands) {
0314 for (int j = 1; j < (int)eoccs[i].size(); ++j) {
0315 if (eoccs.cands_in_backward_rep())
0316 eoccs[i].repackCandPostBkwSearch(j);
0317 if (filter(eoccs[i][j], *m_job)) {
0318 eoccs[i][0] = eoccs[i][j];
0319 passed = true;
0320 break;
0321 }
0322 }
0323 }
0324 if (passed) {
0325 if (place_pos != i)
0326 std::swap(eoccs[place_pos], eoccs[i]);
0327 ++place_pos;
0328 } else {
0329 assert(eoccs[i].front().getEtaRegion() < m_job->num_regions());
0330 ++removed_cnts[eoccs[i].front().getEtaRegion()];
0331 }
0332 ++i;
0333 }
0334
0335 int n_removed = 0;
0336 for (int reg = 0; reg < m_job->num_regions(); ++reg) {
0337 dprintf("MkBuilder::filter_comb_cands reg=%d: n_rem_was=%d removed_in_r=%d n_rem=%d, es_was=%d es_new=%d\n",
0338 reg,
0339 n_removed,
0340 removed_cnts[reg],
0341 n_removed + removed_cnts[reg],
0342 m_seedEtaSeparators[reg],
0343 m_seedEtaSeparators[reg] - n_removed - removed_cnts[reg]);
0344
0345 n_removed += removed_cnts[reg];
0346 m_seedEtaSeparators[reg] -= n_removed;
0347 }
0348
0349 eoccs.resizeAfterFiltering(n_removed);
0350
0351 dprintf("MkBuilder::filter_comb_cands n_removed = %d, eoccs.size=%d\n", n_removed, eoccs.size());
0352
0353 return n_removed;
0354 }
0355
0356 void MkBuilder::find_min_max_hots_size() {
0357 const EventOfCombCandidates &eoccs = m_event_of_comb_cands;
0358 int min[5], max[5], gmin = 0, gmax = 0;
0359 int i = 0;
0360 for (int reg = 0; reg < 5; ++reg) {
0361 min[reg] = 9999;
0362 max[reg] = 0;
0363 for (; i < m_seedEtaSeparators[reg]; i++) {
0364 min[reg] = std::min(min[reg], eoccs[i].hotsSize());
0365 max[reg] = std::max(max[reg], eoccs[i].hotsSize());
0366 }
0367 gmin = std::max(gmin, min[reg]);
0368 gmax = std::max(gmax, max[reg]);
0369 }
0370
0371 printf("MkBuilder::find_min_max_hots_size MIN %3d -- [ %3d | %3d | %3d | %3d | %3d ] "
0372 "MAX %3d -- [ %3d | %3d | %3d | %3d | %3d ]\n",
0373 gmin, min[0], min[1], min[2], min[3], min[4],
0374 gmax, max[0], max[1], max[2], max[3], max[4]);
0375
0376 }
0377
0378 void MkBuilder::select_best_comb_cands(bool clear_m_tracks, bool remove_missing_hits) {
0379 if (clear_m_tracks)
0380 m_tracks.clear();
0381 export_best_comb_cands(m_tracks, remove_missing_hits);
0382 }
0383
0384 void MkBuilder::export_best_comb_cands(TrackVec &out_vec, bool remove_missing_hits) {
0385 const EventOfCombCandidates &eoccs = m_event_of_comb_cands;
0386 out_vec.reserve(out_vec.size() + eoccs.size());
0387 for (int i = 0; i < eoccs.size(); i++) {
0388
0389 if (!eoccs[i].empty()) {
0390 const TrackCand &bcand = eoccs[i].front();
0391 out_vec.emplace_back(bcand.exportTrack(remove_missing_hits));
0392 }
0393 }
0394 }
0395
0396 void MkBuilder::export_tracks(TrackVec &out_vec) {
0397 out_vec.reserve(out_vec.size() + m_tracks.size());
0398 for (auto &t : m_tracks) {
0399 out_vec.emplace_back(t);
0400 }
0401 }
0402
0403
0404
0405
0406
0407 void MkBuilder::seed_post_cleaning(TrackVec &tv) {
0408 if (Const::nan_n_silly_check_seeds) {
0409 int count = 0;
0410
0411 for (int i = 0; i < (int)tv.size(); ++i) {
0412 bool silly = tv[i].hasSillyValues(Const::nan_n_silly_print_bad_seeds,
0413 Const::nan_n_silly_fixup_bad_seeds,
0414 "Post-cleaning seed silly value check and fix");
0415 if (silly) {
0416 ++count;
0417 if (Const::nan_n_silly_remove_bad_seeds) {
0418
0419
0420 tv.erase(tv.begin() + i);
0421 --i;
0422 }
0423 }
0424 }
0425
0426 if (count > 0 && !m_silent) {
0427 printf("Nan'n'Silly detected %d silly seeds (fix=%d, remove=%d).\n",
0428 count,
0429 Const::nan_n_silly_fixup_bad_seeds,
0430 Const::nan_n_silly_remove_bad_seeds);
0431 }
0432 }
0433 }
0434
0435
0436
0437
0438
0439 void MkBuilder::find_tracks_load_seeds_BH(const TrackVec &in_seeds, const bool seeds_sorted) {
0440
0441 assert(!in_seeds.empty());
0442 m_tracks.resize(in_seeds.size());
0443
0444 import_seeds(in_seeds, seeds_sorted, [&](const Track &seed, int seed_idx, int region, int pos) {
0445 m_tracks[pos] = seed;
0446 m_tracks[pos].setNSeedHits(seed.nTotalHits());
0447 m_tracks[pos].setEtaRegion(region);
0448 });
0449
0450
0451 dcall(print_seeds(m_tracks));
0452 }
0453
0454 void MkBuilder::findTracksBestHit(SteeringParams::IterationType_e iteration_dir) {
0455
0456
0457 TrackVec &cands = m_tracks;
0458
0459 tbb::parallel_for_each(m_job->regions_begin(), m_job->regions_end(), [&](int region) {
0460 if (iteration_dir == SteeringParams::IT_BkwSearch && !m_job->steering_params(region).has_bksearch_plan()) {
0461 printf("No backward search plan for region %d\n", region);
0462 return;
0463 }
0464
0465
0466
0467
0468
0469
0470 const SteeringParams &st_par = m_job->steering_params(region);
0471 const TrackerInfo &trk_info = m_job->m_trk_info;
0472 const PropagationConfig &prop_config = trk_info.prop_config();
0473
0474 const RegionOfSeedIndices rosi(m_seedEtaSeparators, region);
0475
0476 tbb::parallel_for(rosi.tbb_blk_rng_vec(), [&](const tbb::blocked_range<int> &blk_rng) {
0477 auto mkfndr = g_exe_ctx.m_finders.makeOrGet();
0478
0479 RangeOfSeedIndices rng = rosi.seed_rng(blk_rng);
0480
0481 std::vector<int> trk_idcs(NN);
0482 std::vector<int> trk_llay(NN);
0483
0484 while (rng.valid()) {
0485 dprint(std::endl << "processing track=" << rng.m_beg << ", label=" << cands[rng.m_beg].label());
0486
0487 int prev_layer = 9999;
0488
0489 for (int i = rng.m_beg, ii = 0; i < rng.m_end; ++i, ++ii) {
0490 int llay = cands[i].getLastHitLyr();
0491 trk_llay[ii] = llay;
0492 prev_layer = std::min(prev_layer, llay);
0493
0494 dprintf(" %2d %2d %2d lay=%3d prev_layer=%d\n", ii, i, cands[i].label(), llay, prev_layer);
0495 }
0496 int curr_tridx = 0;
0497
0498 auto layer_plan_it = st_par.make_iterator(iteration_dir);
0499
0500 dprintf("Made iterator for %d, first layer=%d ... end layer=%d\n",
0501 iteration_dir,
0502 layer_plan_it.layer(),
0503 layer_plan_it.last_layer());
0504
0505 assert(layer_plan_it.is_pickup_only());
0506
0507 int curr_layer = layer_plan_it.layer();
0508
0509 mkfndr->m_Stopped.setVal(0);
0510
0511
0512
0513
0514 while (++layer_plan_it) {
0515 prev_layer = curr_layer;
0516 curr_layer = layer_plan_it.layer();
0517 mkfndr->setup(prop_config,
0518 m_job->m_iter_config,
0519 m_job->m_iter_config.m_params,
0520 m_job->m_iter_config.m_layer_configs[curr_layer],
0521 st_par,
0522 m_job->get_mask_for_layer(curr_layer),
0523 m_event,
0524 region,
0525 m_job->m_in_fwd);
0526
0527 const LayerOfHits &layer_of_hits = m_job->m_event_of_hits[curr_layer];
0528 const LayerInfo &layer_info = trk_info.layer(curr_layer);
0529 const FindingFoos &fnd_foos = FindingFoos::get_finding_foos(layer_info.is_barrel());
0530 dprint("at layer " << curr_layer << ", nHits in layer " << layer_of_hits.nHits());
0531
0532
0533 if (curr_tridx < rng.n_proc()) {
0534 int prev_tridx = curr_tridx;
0535
0536 for (int i = rng.m_beg, ii = 0; i < rng.m_end; ++i, ++ii) {
0537 if (trk_llay[ii] == prev_layer)
0538 trk_idcs[curr_tridx++] = i;
0539 }
0540 if (curr_tridx > prev_tridx) {
0541 dprintf("added %d seeds, started with %d\n", curr_tridx - prev_tridx, prev_tridx);
0542
0543 mkfndr->inputTracksAndHitIdx(cands, trk_idcs, prev_tridx, curr_tridx, false, prev_tridx);
0544 }
0545 }
0546
0547 if (layer_plan_it.is_pickup_only())
0548 continue;
0549
0550 dcall(pre_prop_print(curr_layer, mkfndr.get()));
0551
0552 mkfndr->clearFailFlag();
0553 (mkfndr.get()->*fnd_foos.m_propagate_foo)(
0554 layer_info.propagate_to(), curr_tridx, prop_config.finding_inter_layer_pflags);
0555
0556 dcall(post_prop_print(curr_layer, mkfndr.get()));
0557
0558 mkfndr->selectHitIndices(layer_of_hits, curr_tridx);
0559
0560
0561 if (layer_info.is_barrel()) {
0562 const float r_min_sqr = layer_info.rin() * layer_info.rin();
0563 for (int i = 0; i < curr_tridx; ++i) {
0564 if (!mkfndr->m_Stopped[i]) {
0565 if (mkfndr->radiusSqr(i, MkBase::iP) < r_min_sqr) {
0566 if (region == TrackerInfo::Reg_Barrel) {
0567 mkfndr->m_Stopped[i] = 1;
0568 mkfndr->outputTrackAndHitIdx(cands[rng.m_beg + i], i, false);
0569 }
0570 mkfndr->m_XWsrResult[i].m_wsr = WSR_Outside;
0571 mkfndr->m_XHitSize[i] = 0;
0572 }
0573 } else {
0574 mkfndr->m_XWsrResult[i].m_wsr = WSR_Outside;
0575 mkfndr->m_XHitSize[i] = 0;
0576 }
0577 }
0578 }
0579
0580
0581 dprint("make new candidates");
0582
0583 mkfndr->addBestHit(layer_of_hits, curr_tridx, fnd_foos);
0584
0585
0586 for (int i = 0; i < curr_tridx; ++i) {
0587 if (!mkfndr->m_Stopped[i] && mkfndr->bestHitLastHoT(i).index == -2) {
0588 mkfndr->m_Stopped[i] = 1;
0589 mkfndr->outputTrackAndHitIdx(cands[rng.m_beg + i], i, false);
0590 }
0591 }
0592
0593 }
0594
0595 mkfndr->outputNonStoppedTracksAndHitIdx(cands, trk_idcs, 0, curr_tridx, false);
0596
0597 ++rng;
0598 }
0599
0600 mkfndr->release();
0601 });
0602 });
0603 }
0604
0605
0606
0607
0608
0609 void MkBuilder::find_tracks_load_seeds(const TrackVec &in_seeds, const bool seeds_sorted) {
0610
0611 assert(!in_seeds.empty());
0612 m_tracks.clear();
0613
0614 m_event_of_comb_cands.reset((int)in_seeds.size(), m_job->max_max_cands());
0615
0616 import_seeds(in_seeds, seeds_sorted, [&](const Track &seed, int seed_idx, int region, int pos) {
0617 m_event_of_comb_cands.insertSeed(seed, seed_idx, m_job->steering_params(region).m_track_scorer, region, pos);
0618 });
0619 }
0620
0621 int MkBuilder::find_tracks_unroll_candidates(std::vector<std::pair<int, int>> &seed_cand_vec,
0622 int start_seed,
0623 int end_seed,
0624 int layer,
0625 int prev_layer,
0626 bool pickup_only,
0627 SteeringParams::IterationType_e iteration_dir) {
0628 int silly_count = 0;
0629
0630 seed_cand_vec.clear();
0631
0632 auto &iter_params = (iteration_dir == SteeringParams::IT_BkwSearch) ? m_job->m_iter_config.m_backward_params
0633 : m_job->m_iter_config.m_params;
0634
0635 for (int iseed = start_seed; iseed < end_seed; ++iseed) {
0636 CombCandidate &ccand = m_event_of_comb_cands[iseed];
0637
0638 if (ccand.state() == CombCandidate::Dormant && ccand.pickupLayer() == prev_layer) {
0639 ccand.setState(CombCandidate::Finding);
0640 }
0641 if (!pickup_only && ccand.state() == CombCandidate::Finding) {
0642 bool active = false;
0643 for (int ic = 0; ic < (int)ccand.size(); ++ic) {
0644 if (ccand[ic].getLastHitIdx() != -2) {
0645
0646 if (ccand[ic].pT() < iter_params.minPtCut) {
0647 ccand[ic].addHitIdx(-2, layer, 0.0f);
0648 continue;
0649 }
0650
0651 if (iteration_dir == SteeringParams::IT_FwdSearch && ccand[ic].pT() < 1.2) {
0652 const float dphi = std::abs(ccand[ic].posPhi() - ccand[ic].momPhi());
0653 if (ccand[ic].posRsq() > 625.f && dphi > 1.371f && dphi < 4.512f) {
0654
0655
0656 ccand[ic].addHitIdx(-2, layer, 0.0f);
0657 continue;
0658 }
0659 }
0660
0661 active = true;
0662 seed_cand_vec.push_back(std::pair<int, int>(iseed, ic));
0663 ccand[ic].resetOverlaps();
0664
0665 if (Const::nan_n_silly_check_cands_every_layer) {
0666 if (ccand[ic].hasSillyValues(Const::nan_n_silly_print_bad_cands_every_layer,
0667 Const::nan_n_silly_fixup_bad_cands_every_layer,
0668 "Per layer silly check"))
0669 ++silly_count;
0670 }
0671 }
0672 }
0673 if (!active) {
0674 ccand.setState(CombCandidate::Finished);
0675 }
0676 }
0677 }
0678
0679 if (Const::nan_n_silly_check_cands_every_layer && silly_count > 0) {
0680 m_nan_n_silly_per_layer_count += silly_count;
0681 }
0682
0683 return seed_cand_vec.size();
0684 }
0685
0686 void MkBuilder::find_tracks_handle_missed_layers(MkFinder *mkfndr,
0687 const LayerInfo &layer_info,
0688 std::vector<std::vector<TrackCand>> &tmp_cands,
0689 const std::vector<std::pair<int, int>> &seed_cand_idx,
0690 const int region,
0691 const int start_seed,
0692 const int itrack,
0693 const int end) {
0694
0695
0696
0697
0698
0699
0700
0701 for (int ti = itrack; ti < end; ++ti) {
0702 TrackCand &cand = m_event_of_comb_cands[seed_cand_idx[ti].first][seed_cand_idx[ti].second];
0703 WSR_Result &w = mkfndr->m_XWsrResult[ti - itrack];
0704
0705
0706 dprintf("WSR Check label %d, seed %d, cand %d score %f -> wsr %d, in_gap %d\n",
0707 cand.label(),
0708 seed_cand_idx[ti].first,
0709 seed_cand_idx[ti].second,
0710 cand.score(),
0711 w.m_wsr,
0712 w.m_in_gap);
0713
0714 if (w.m_wsr == WSR_Failed) {
0715
0716
0717 w.m_wsr = WSR_Outside;
0718
0719 if (layer_info.is_barrel()) {
0720 dprintf("Barrel cand propagation failed, got to r=%f ... layer is %f - %f\n",
0721 mkfndr->radius(ti - itrack, MkBase::iP),
0722 layer_info.rin(),
0723 layer_info.rout());
0724
0725
0726 tmp_cands[seed_cand_idx[ti].first - start_seed].push_back(cand);
0727 if (region == TrackerInfo::Reg_Barrel) {
0728 dprintf(" creating extra stopped held back candidate\n");
0729 tmp_cands[seed_cand_idx[ti].first - start_seed].back().addHitIdx(-2, layer_info.layer_id(), 0);
0730 }
0731 }
0732
0733 } else if (w.m_wsr == WSR_Outside) {
0734 dprintf(" creating extra held back candidate\n");
0735 tmp_cands[seed_cand_idx[ti].first - start_seed].push_back(cand);
0736 } else if (w.m_wsr == WSR_Edge) {
0737
0738 }
0739 }
0740 }
0741
0742
0743
0744
0745
0746 void MkBuilder::findTracksStandard(SteeringParams::IterationType_e iteration_dir) {
0747
0748
0749 EventOfCombCandidates &eoccs = m_event_of_comb_cands;
0750
0751 tbb::parallel_for_each(m_job->regions_begin(), m_job->regions_end(), [&](int region) {
0752 if (iteration_dir == SteeringParams::IT_BkwSearch && !m_job->steering_params(region).has_bksearch_plan()) {
0753 printf("No backward search plan for region %d\n", region);
0754 return;
0755 }
0756
0757 const TrackerInfo &trk_info = m_job->m_trk_info;
0758 const SteeringParams &st_par = m_job->steering_params(region);
0759 const IterationParams ¶ms = m_job->params();
0760 const PropagationConfig &prop_config = trk_info.prop_config();
0761
0762 const RegionOfSeedIndices rosi(m_seedEtaSeparators, region);
0763
0764
0765 const int adaptiveSPT = std::clamp(
0766 Config::numThreadsEvents * eoccs.size() / Config::numThreadsFinder + 1, 4, Config::numSeedsPerTask);
0767 dprint("adaptiveSPT " << adaptiveSPT << " fill " << rosi.count() << "/" << eoccs.size() << " region " << region);
0768
0769
0770 tbb::parallel_for(rosi.tbb_blk_rng_std(adaptiveSPT), [&](const tbb::blocked_range<int> &seeds) {
0771 auto mkfndr = g_exe_ctx.m_finders.makeOrGet();
0772
0773 const int start_seed = seeds.begin();
0774 const int end_seed = seeds.end();
0775 const int n_seeds = end_seed - start_seed;
0776
0777 std::vector<std::vector<TrackCand>> tmp_cands(n_seeds);
0778 for (size_t iseed = 0; iseed < tmp_cands.size(); ++iseed) {
0779 tmp_cands[iseed].reserve(2 * params.maxCandsPerSeed);
0780 }
0781
0782 std::vector<std::pair<int, int>> seed_cand_idx;
0783 seed_cand_idx.reserve(n_seeds * params.maxCandsPerSeed);
0784
0785 auto layer_plan_it = st_par.make_iterator(iteration_dir);
0786
0787 dprintf("Made iterator for %d, first layer=%d ... end layer=%d\n",
0788 iteration_dir,
0789 layer_plan_it.layer(),
0790 layer_plan_it.last_layer());
0791
0792 assert(layer_plan_it.is_pickup_only());
0793
0794 int curr_layer = layer_plan_it.layer(), prev_layer;
0795
0796 dprintf("\nMkBuilder::FindTracksStandard region=%d, seed_pickup_layer=%d, first_layer=%d\n",
0797 region,
0798 curr_layer,
0799 layer_plan_it.next_layer());
0800
0801 auto &iter_params = (iteration_dir == SteeringParams::IT_BkwSearch) ? m_job->m_iter_config.m_backward_params
0802 : m_job->m_iter_config.m_params;
0803
0804
0805 while (++layer_plan_it) {
0806 prev_layer = curr_layer;
0807 curr_layer = layer_plan_it.layer();
0808 mkfndr->setup(prop_config,
0809 m_job->m_iter_config,
0810 iter_params,
0811 m_job->m_iter_config.m_layer_configs[curr_layer],
0812 st_par,
0813 m_job->get_mask_for_layer(curr_layer),
0814 m_event,
0815 region,
0816 m_job->m_in_fwd);
0817
0818 const LayerOfHits &layer_of_hits = m_job->m_event_of_hits[curr_layer];
0819 const LayerInfo &layer_info = trk_info.layer(curr_layer);
0820 const FindingFoos &fnd_foos = FindingFoos::get_finding_foos(layer_info.is_barrel());
0821
0822 dprintf("\n* Processing layer %d\n", curr_layer);
0823 mkfndr->begin_layer(layer_of_hits);
0824
0825 int theEndCand = find_tracks_unroll_candidates(seed_cand_idx,
0826 start_seed,
0827 end_seed,
0828 curr_layer,
0829 prev_layer,
0830 layer_plan_it.is_pickup_only(),
0831 iteration_dir);
0832
0833 dprintf(" Number of candidates to process: %d, nHits in layer: %d\n", theEndCand, layer_of_hits.nHits());
0834
0835 if (layer_plan_it.is_pickup_only() || theEndCand == 0)
0836 continue;
0837
0838
0839 for (int itrack = 0; itrack < theEndCand; itrack += NN) {
0840 int end = std::min(itrack + NN, theEndCand);
0841
0842 dprint("processing track=" << itrack << ", label="
0843 << eoccs[seed_cand_idx[itrack].first][seed_cand_idx[itrack].second].label());
0844
0845
0846 mkfndr->inputTracksAndHitIdx(eoccs.refCandidates(), seed_cand_idx, itrack, end, false);
0847
0848
0849 dcall(pre_prop_print(curr_layer, mkfndr.get()));
0850
0851 mkfndr->clearFailFlag();
0852 (mkfndr.get()->*fnd_foos.m_propagate_foo)(
0853 layer_info.propagate_to(), end - itrack, prop_config.finding_inter_layer_pflags);
0854
0855 dcall(post_prop_print(curr_layer, mkfndr.get()));
0856
0857 dprint("now get hit range");
0858 mkfndr->selectHitIndices(layer_of_hits, end - itrack);
0859
0860 find_tracks_handle_missed_layers(
0861 mkfndr.get(), layer_info, tmp_cands, seed_cand_idx, region, start_seed, itrack, end);
0862
0863 dprint("make new candidates");
0864 mkfndr->findCandidates(layer_of_hits, tmp_cands, start_seed, end - itrack, fnd_foos);
0865
0866 }
0867
0868
0869 for (int is = 0; is < n_seeds; ++is) {
0870 dprint("dump seed n " << is << " with N_input_candidates=" << tmp_cands[is].size());
0871
0872 std::sort(tmp_cands[is].begin(), tmp_cands[is].end(), sortCandByScore);
0873 }
0874
0875
0876 for (int is = 0; is < n_seeds; ++is) {
0877 if (!tmp_cands[is].empty()) {
0878 eoccs[start_seed + is].clear();
0879
0880
0881 int n_placed = 0;
0882 bool first_short = true;
0883 for (int ii = 0; ii < (int)tmp_cands[is].size() && n_placed < params.maxCandsPerSeed; ++ii) {
0884 TrackCand &tc = tmp_cands[is][ii];
0885
0886
0887
0888 if (tc.pT() > params.pTCutOverlap && tc.getLastHitLyr() == curr_layer && tc.getLastHitIdx() >= 0) {
0889 CombCandidate &ccand = eoccs[start_seed + is];
0890
0891 HitMatch *hm = ccand[tc.originIndex()].findOverlap(
0892 tc.getLastHitIdx(), layer_of_hits.refHit(tc.getLastHitIdx()).detIDinLayer());
0893
0894 if (hm) {
0895 tc.addHitIdx(hm->m_hit_idx, curr_layer, hm->m_chi2);
0896 tc.incOverlapCount();
0897 }
0898 }
0899
0900 if (tc.getLastHitIdx() != -2) {
0901 eoccs[start_seed + is].emplace_back(tc);
0902 ++n_placed;
0903 } else if (first_short) {
0904 first_short = false;
0905 if (tc.score() > eoccs[start_seed + is].refBestShortCand().score()) {
0906 eoccs[start_seed + is].setBestShortCand(tc);
0907 }
0908 }
0909 }
0910
0911 tmp_cands[is].clear();
0912 }
0913 }
0914 mkfndr->end_layer();
0915 }
0916 mkfndr->release();
0917
0918
0919 for (int iseed = start_seed; iseed < end_seed; ++iseed) {
0920 eoccs[iseed].mergeCandsAndBestShortOne(m_job->params(), st_par.m_track_scorer, true, true);
0921 }
0922 });
0923 });
0924
0925
0926 }
0927
0928
0929
0930
0931
0932 void MkBuilder::findTracksCloneEngine(SteeringParams::IterationType_e iteration_dir) {
0933
0934
0935 EventOfCombCandidates &eoccs = m_event_of_comb_cands;
0936
0937 tbb::parallel_for_each(m_job->regions_begin(), m_job->regions_end(), [&](int region) {
0938 if (iteration_dir == SteeringParams::IT_BkwSearch && !m_job->steering_params(region).has_bksearch_plan()) {
0939 printf("No backward search plan for region %d\n", region);
0940 return;
0941 }
0942
0943 const RegionOfSeedIndices rosi(m_seedEtaSeparators, region);
0944
0945
0946 const int adaptiveSPT = std::clamp(
0947 Config::numThreadsEvents * eoccs.size() / Config::numThreadsFinder + 1, 4, Config::numSeedsPerTask);
0948 dprint("adaptiveSPT " << adaptiveSPT << " fill " << rosi.count() << "/" << eoccs.size() << " region " << region);
0949
0950 tbb::parallel_for(rosi.tbb_blk_rng_std(adaptiveSPT), [&](const tbb::blocked_range<int> &seeds) {
0951 auto cloner = g_exe_ctx.m_cloners.makeOrGet();
0952 auto mkfndr = g_exe_ctx.m_finders.makeOrGet();
0953
0954 cloner->setup(m_job->params());
0955
0956
0957 find_tracks_in_layers(*cloner, mkfndr.get(), iteration_dir, seeds.begin(), seeds.end(), region);
0958
0959 mkfndr->release();
0960 cloner->release();
0961 });
0962 });
0963
0964
0965 }
0966
0967 void MkBuilder::find_tracks_in_layers(CandCloner &cloner,
0968 MkFinder *mkfndr,
0969 SteeringParams::IterationType_e iteration_dir,
0970 const int start_seed,
0971 const int end_seed,
0972 const int region) {
0973 EventOfCombCandidates &eoccs = m_event_of_comb_cands;
0974 const TrackerInfo &trk_info = m_job->m_trk_info;
0975 const SteeringParams &st_par = m_job->steering_params(region);
0976 const IterationParams ¶ms = m_job->params();
0977 const PropagationConfig &prop_config = trk_info.prop_config();
0978
0979 const int n_seeds = end_seed - start_seed;
0980
0981 std::vector<std::pair<int, int>> seed_cand_idx;
0982 std::vector<UpdateIndices> seed_cand_update_idx;
0983 seed_cand_idx.reserve(n_seeds * params.maxCandsPerSeed);
0984 seed_cand_update_idx.reserve(n_seeds * params.maxCandsPerSeed);
0985
0986 std::vector<std::vector<TrackCand>> extra_cands(n_seeds);
0987 for (int ii = 0; ii < n_seeds; ++ii)
0988 extra_cands[ii].reserve(params.maxCandsPerSeed);
0989
0990 cloner.begin_eta_bin(&eoccs, &seed_cand_update_idx, &extra_cands, start_seed, n_seeds);
0991
0992
0993
0994 auto layer_plan_it = st_par.make_iterator(iteration_dir);
0995
0996 dprintf("Made iterator for %d, first layer=%d ... end layer=%d\n",
0997 iteration_dir,
0998 layer_plan_it.layer(),
0999 layer_plan_it.last_layer());
1000
1001 assert(layer_plan_it.is_pickup_only());
1002
1003 int curr_layer = layer_plan_it.layer(), prev_layer;
1004
1005 dprintf(
1006 "\nMkBuilder::find_tracks_in_layers region=%d, seed_pickup_layer=%d, first_layer=%d; start_seed=%d, "
1007 "end_seed=%d\n",
1008 region,
1009 curr_layer,
1010 layer_plan_it.next_layer(),
1011 start_seed,
1012 end_seed);
1013
1014 auto &iter_params = (iteration_dir == SteeringParams::IT_BkwSearch) ? m_job->m_iter_config.m_backward_params
1015 : m_job->m_iter_config.m_params;
1016
1017
1018 while (++layer_plan_it) {
1019 prev_layer = curr_layer;
1020 curr_layer = layer_plan_it.layer();
1021 mkfndr->setup(prop_config,
1022 m_job->m_iter_config,
1023 iter_params,
1024 m_job->m_iter_config.m_layer_configs[curr_layer],
1025 st_par,
1026 m_job->get_mask_for_layer(curr_layer),
1027 m_event,
1028 region,
1029 m_job->m_in_fwd);
1030
1031 const bool pickup_only = layer_plan_it.is_pickup_only();
1032
1033 const LayerInfo &layer_info = trk_info.layer(curr_layer);
1034 const LayerOfHits &layer_of_hits = m_job->m_event_of_hits[curr_layer];
1035 const FindingFoos &fnd_foos = FindingFoos::get_finding_foos(layer_info.is_barrel());
1036
1037 dprintf("\n\n* Processing layer %d, %s\n\n", curr_layer, pickup_only ? "pickup only" : "full finding");
1038 mkfndr->begin_layer(layer_of_hits);
1039
1040 const int theEndCand = find_tracks_unroll_candidates(
1041 seed_cand_idx, start_seed, end_seed, curr_layer, prev_layer, pickup_only, iteration_dir);
1042
1043 dprintf(" Number of candidates to process: %d, nHits in layer: %d\n", theEndCand, layer_of_hits.nHits());
1044
1045
1046
1047
1048
1049
1050
1051
1052 if (pickup_only || theEndCand == 0)
1053 continue;
1054
1055 cloner.begin_layer(curr_layer);
1056
1057
1058 for (int itrack = 0; itrack < theEndCand; itrack += NN) {
1059 const int end = std::min(itrack + NN, theEndCand);
1060
1061 #ifdef DEBUG
1062 dprintf("\nProcessing track=%d, start_seed=%d, n_seeds=%d, theEndCand=%d, end=%d, nn=%d, end_eq_tec=%d\n",
1063 itrack,
1064 start_seed,
1065 n_seeds,
1066 theEndCand,
1067 end,
1068 end - itrack,
1069 end == theEndCand);
1070 dprintf(" (seed,cand): ");
1071 for (int i = itrack; i < end; ++i)
1072 dprintf("(%d,%d) ", seed_cand_idx[i].first, seed_cand_idx[i].second);
1073 dprintf("\n");
1074 #endif
1075
1076 mkfndr->inputTracksAndHitIdx(eoccs.refCandidates(), seed_cand_idx, itrack, end, false);
1077
1078 #ifdef DEBUG
1079 for (int i = itrack; i < end; ++i)
1080 dprintf(" track %d, idx %d is from seed %d\n", i, i - itrack, mkfndr->m_Label(i - itrack, 0, 0));
1081 #endif
1082
1083
1084 mkfndr->clearFailFlag();
1085 (mkfndr->*fnd_foos.m_propagate_foo)(
1086 layer_info.propagate_to(), end - itrack, prop_config.finding_inter_layer_pflags);
1087
1088 dprint("now get hit range");
1089
1090 mkfndr->selectHitIndices(layer_of_hits, end - itrack);
1091
1092 find_tracks_handle_missed_layers(
1093 mkfndr, layer_info, extra_cands, seed_cand_idx, region, start_seed, itrack, end);
1094
1095
1096
1097
1098
1099
1100
1101
1102 if (Config::usePropToPlane) {
1103 mkfndr->inputTracksAndHitIdx(eoccs.refCandidates(), seed_cand_idx, itrack, end, false);
1104 }
1105
1106 dprint("make new candidates");
1107 cloner.begin_iteration();
1108
1109 mkfndr->findCandidatesCloneEngine(layer_of_hits, cloner, start_seed, end - itrack, fnd_foos);
1110
1111 cloner.end_iteration();
1112 }
1113
1114 cloner.end_layer();
1115
1116
1117
1118
1119 const int theEndUpdater = seed_cand_update_idx.size();
1120
1121 for (int itrack = 0; itrack < theEndUpdater; itrack += NN) {
1122 const int end = std::min(itrack + NN, theEndUpdater);
1123
1124 mkfndr->inputTracksAndHits(eoccs.refCandidates(), layer_of_hits, seed_cand_update_idx, itrack, end, true);
1125
1126 mkfndr->updateWithLoadedHit(end - itrack, layer_of_hits, fnd_foos);
1127
1128
1129 mkfndr->copyOutParErr(eoccs.refCandidates_nc(), end - itrack, false);
1130 }
1131
1132
1133 #ifdef DEBUG
1134 for (int iseed = start_seed; iseed < end_seed; ++iseed) {
1135 auto &cc = eoccs[iseed];
1136
1137 for (int i = 0; i < ((int)cc.size()) - 1; ++i) {
1138 if (cc[i].score() < cc[i + 1].score()) {
1139 printf("CloneEngine - NOT SORTED: layer=%d, iseed=%d (size=%lu)-- %d : %f smaller than %d : %f\n",
1140 curr_layer,
1141 iseed,
1142 cc.size(),
1143 i,
1144 cc[i].score(),
1145 i + 1,
1146 cc[i + 1].score());
1147 }
1148 }
1149 }
1150 #endif
1151 mkfndr->end_layer();
1152 }
1153
1154 cloner.end_eta_bin();
1155
1156
1157 for (int iseed = start_seed; iseed < end_seed; ++iseed) {
1158 eoccs[iseed].mergeCandsAndBestShortOne(m_job->params(), st_par.m_track_scorer, true, true);
1159 }
1160 }
1161
1162
1163
1164
1165
1166 #ifdef DEBUG_FINAL_FIT
1167 namespace {
1168
1169 void dprint_tcand(const TrackCand &t, int i) {
1170 dprintf(" %4d with q=%+d chi2=%7.3f pT=%7.3f eta=% 7.3f x=%.3f y=%.3f z=%.3f"
1171 " nHits=%2d label=%4d findable=%d\n",
1172 i, t.charge(), t.chi2(), t.pT(), t.momEta(), t.x(), t.y(), t.z(),
1173 t.nFoundHits(), t.label(), t.isFindable());
1174 }
1175
1176 }
1177 #endif
1178
1179 void MkBuilder::backwardFitBH() {
1180 tbb::parallel_for_each(m_job->regions_begin(), m_job->regions_end(), [&](int region) {
1181 const RegionOfSeedIndices rosi(m_seedEtaSeparators, region);
1182
1183 tbb::parallel_for(rosi.tbb_blk_rng_vec(), [&](const tbb::blocked_range<int> &blk_rng) {
1184 auto mkfndr = g_exe_ctx.m_finders.makeOrGet();
1185
1186 RangeOfSeedIndices rng = rosi.seed_rng(blk_rng);
1187
1188 while (rng.valid()) {
1189
1190 fit_cands_BH(mkfndr.get(), rng.m_beg, rng.m_end, region);
1191
1192 ++rng;
1193 }
1194 });
1195 });
1196 }
1197
1198 void MkBuilder::fit_cands_BH(MkFinder *mkfndr, int start_cand, int end_cand, int region) {
1199 const SteeringParams &st_par = m_job->steering_params(region);
1200 const PropagationConfig &prop_config = m_job->m_trk_info.prop_config();
1201 mkfndr->setup_bkfit(prop_config, st_par, m_event);
1202 #ifdef DEBUG_FINAL_FIT
1203 EventOfCombCandidates &eoccs = m_event_of_comb_cands;
1204 bool debug = true;
1205 #endif
1206
1207 for (int icand = start_cand; icand < end_cand; icand += NN) {
1208 const int end = std::min(icand + NN, end_cand);
1209
1210 #ifdef DEBUG_FINAL_FIT
1211 dprintf("Pre Final fit for %d - %d\n", icand, end);
1212 for (int i = icand; i < end; ++i) {
1213 dprint_tcand(eoccs[i][0], i);
1214 }
1215 #endif
1216
1217 bool chi_debug = false;
1218 #ifdef DEBUG_BACKWARD_FIT_BH
1219 redo_fit:
1220 #endif
1221
1222
1223 mkfndr->bkFitInputTracks(m_tracks, icand, end);
1224
1225
1226 mkfndr->bkFitFitTracksBH(m_job->m_event_of_hits, st_par, end - icand, chi_debug);
1227
1228
1229 if (prop_config.backward_fit_to_pca) {
1230 mkfndr->bkFitPropTracksToPCA(end - icand);
1231 }
1232
1233 #ifdef DEBUG_BACKWARD_FIT_BH
1234
1235 if (!chi_debug && 1.0f / mkfndr->m_Par[MkBase::iP].At(0, 3, 0) > 2.0f &&
1236 mkfndr->m_Chi2(0, 0, 0) / (eoccs[icand][0].nFoundHits() * 3 - 6) > 20.0f) {
1237 chi_debug = true;
1238 #ifdef MKFIT_STANDALONE
1239 printf("CHIHDR Event %d, Cand %3d, pT %f, chipdof %f ### NOTE x,y,z in cm, sigmas, deltas in mum ### !!!\n",
1240 m_event->evtID(),
1241 #else
1242 printf("CHIHDR Cand %3d, pT %f, chipdof %f ### NOTE x,y,z in cm, sigmas, deltas in mum ### !!!\n",
1243 #endif
1244 icand,
1245 1.0f / mkfndr->m_Par[MkBase::iP].At(0, 3, 0),
1246 mkfndr->m_Chi2(0, 0, 0) / (eoccs[icand][0].nFoundHits() * 3 - 6));
1247
1248 printf("CHIHDR %3s %10s"
1249 " %10s %10s %10s %10s %11s %11s %11s"
1250 " %10s %10s %10s %10s %11s %11s %11s"
1251 " %10s %10s %10s %10s %10s %11s %11s\n",
1252 "lyr", "chi2",
1253 "x_h", "y_h", "z_h", "r_h", "sx_h", "sy_h", "sz_h",
1254 "x_t", "y_t", "z_t", "r_t", "sx_t", "sy_t", "sz_t",
1255 "pt", "phi", "theta", "phi_h", "phi_t", "d_xy", "d_z");
1256
1257 goto redo_fit;
1258 }
1259 #endif
1260
1261
1262 mkfndr->bkFitOutputTracks(m_tracks, icand, end, prop_config.backward_fit_to_pca);
1263
1264 #ifdef DEBUG_FINAL_FIT
1265 dprintf("Post Final fit for %d - %d\n", icand, end);
1266 for (int i = icand; i < end; ++i) {
1267 dprint_tcand(eoccs[i][0], i);
1268 }
1269 #endif
1270 }
1271 }
1272
1273
1274
1275 void MkBuilder::backwardFit() {
1276 EventOfCombCandidates &eoccs = m_event_of_comb_cands;
1277
1278 tbb::parallel_for_each(m_job->regions_begin(), m_job->regions_end(), [&](int region) {
1279 const RegionOfSeedIndices rosi(m_seedEtaSeparators, region);
1280
1281
1282 const int adaptiveSPT = std::clamp(
1283 Config::numThreadsEvents * eoccs.size() / Config::numThreadsFinder + 1, 4, Config::numSeedsPerTask);
1284 dprint("adaptiveSPT " << adaptiveSPT << " fill " << rosi.count() << "/" << eoccs.size() << " region " << region);
1285
1286 tbb::parallel_for(rosi.tbb_blk_rng_std(adaptiveSPT), [&](const tbb::blocked_range<int> &cands) {
1287 auto mkfndr = g_exe_ctx.m_finders.makeOrGet();
1288
1289 fit_cands(mkfndr.get(), cands.begin(), cands.end(), region);
1290 });
1291 });
1292 }
1293
1294 void MkBuilder::fit_cands(MkFinder *mkfndr, int start_cand, int end_cand, int region) {
1295 EventOfCombCandidates &eoccs = m_event_of_comb_cands;
1296 const SteeringParams &st_par = m_job->steering_params(region);
1297 const PropagationConfig &prop_config = m_job->m_trk_info.prop_config();
1298 mkfndr->setup_bkfit(prop_config, st_par, m_event);
1299
1300 int step = NN;
1301 for (int icand = start_cand; icand < end_cand; icand += step) {
1302 int end = std::min(icand + NN, end_cand);
1303
1304 bool chi_debug = false;
1305
1306 #ifdef DEBUG_FINAL_FIT
1307 bool debug = true;
1308 dprintf("Pre Final fit for %d - %d\n", icand, end);
1309 for (int i = icand; i < end; ++i) {
1310 dprint_tcand(eoccs[i][0], i);
1311 }
1312 chi_debug = true;
1313 static bool first = true;
1314 if (first) {
1315
1316 dprintf(
1317 "BKF_OVERLAP event/I:label/I:prod_type/I:is_findable/I:layer/I:is_stereo/I:is_barrel/I:"
1318 "pt/F:pt_cur/F:eta/F:phi/F:phi_cur/F:r_cur/F:z_cur/F:chi2/F:isnan/I:isfin/I:gtzero/I:hit_label/I:"
1319 "sx_t/F:sy_t/F:sz_t/F:d_xy/F:d_z/F\n");
1320 first = false;
1321 }
1322 #endif
1323
1324
1325 mkfndr->bkFitInputTracks(eoccs, icand, end);
1326
1327
1328 mkfndr->bkFitFitTracks(m_job->m_event_of_hits, st_par, end - icand, chi_debug);
1329
1330
1331 if (prop_config.backward_fit_to_pca) {
1332 mkfndr->bkFitPropTracksToPCA(end - icand);
1333 }
1334
1335 mkfndr->bkFitOutputTracks(eoccs, icand, end, prop_config.backward_fit_to_pca);
1336
1337 #ifdef DEBUG_FINAL_FIT
1338 dprintf("Post Final fit for %d - %d\n", icand, end);
1339 for (int i = icand; i < end; ++i) {
1340 dprint_tcand(eoccs[i][0], i);
1341 }
1342 #endif
1343 }
1344 mkfndr->release();
1345 }
1346
1347 }