File indexing completed on 2024-04-25 02:14:12
0001 #include "RecoTracker/MkFitCMS/standalone/Shell.h"
0002
0003 #include "RecoTracker/MkFitCore/src/Debug.h"
0004
0005
0006
0007 #include "RecoTracker/MkFitCMS/interface/runFunctions.h"
0008
0009 #include "RecoTracker/MkFitCore/interface/HitStructures.h"
0010 #include "RecoTracker/MkFitCore/interface/MkBuilder.h"
0011 #include "RecoTracker/MkFitCore/src/MkFitter.h"
0012 #include "RecoTracker/MkFitCMS/interface/MkStdSeqs.h"
0013 #include "RecoTracker/MkFitCMS/standalone/MkStandaloneSeqs.h"
0014
0015 #include "RecoTracker/MkFitCore/interface/Config.h"
0016 #include "RecoTracker/MkFitCore/standalone/ConfigStandalone.h"
0017
0018 #include "RecoTracker/MkFitCore/standalone/Event.h"
0019
0020 #ifndef NO_ROOT
0021 #include "TROOT.h"
0022 #include "TRint.h"
0023 #endif
0024
0025 #include "oneapi/tbb/task_arena.h"
0026
0027 #include <vector>
0028
0029
0030
0031 namespace {
0032 constexpr int algos[] = {4, 22, 23, 5, 24, 7, 8, 9, 10, 6};
0033 constexpr int n_algos = sizeof(algos) / sizeof(int);
0034
0035 const char* b2a(bool b) { return b ? "true" : "false"; }
0036 }
0037
0038 namespace mkfit {
0039
0040 Shell::Shell(std::vector<DeadVec> &dv, const std::string &in_file, int start_ev)
0041 : m_deadvectors(dv)
0042 {
0043 m_eoh = new EventOfHits(Config::TrkInfo);
0044 m_builder = new MkBuilder(Config::silent);
0045
0046 m_backward_fit = Config::backwardFit;
0047
0048 m_data_file = new DataFile;
0049 m_evs_in_file = m_data_file->openRead(in_file, Config::TrkInfo.n_layers());
0050
0051 m_event = new Event(0, Config::TrkInfo.n_layers());
0052 GoToEvent(start_ev);
0053 }
0054
0055 void Shell::Run() {
0056 #ifndef NO_ROOT
0057 std::vector<const char *> argv = { "mkFit", "-l" };
0058 int argc = argv.size();
0059 TRint rint("mkFit-shell", &argc, const_cast<char**>(argv.data()));
0060
0061 char buf[256];
0062 sprintf(buf, "mkfit::Shell &s = * (mkfit::Shell*) %p;", this);
0063 gROOT->ProcessLine(buf);
0064 printf("Shell &s variable is set\n");
0065
0066 rint.Run(true);
0067 printf("Shell::Run finished\n");
0068 #else
0069 printf("Shell::Run() no root, we rot -- erroring out. Recompile with WITH_ROOT=1\n");
0070 exit(1);
0071 #endif
0072 }
0073
0074 void Shell::Status() {
0075 printf("On event %d, selected iteration index %d, algo %d - %s\n"
0076 " debug = %s, use_dead_modules = %s\n"
0077 " clean_seeds = %s, backward_fit = %s, remove_duplicates = %s\n",
0078 m_event->evtID(), m_it_index, algos[m_it_index], TrackBase::algoint_to_cstr(algos[m_it_index]),
0079 b2a(g_debug), b2a(Config::useDeadModules),
0080 b2a(m_clean_seeds), b2a(m_backward_fit), b2a(m_remove_duplicates));
0081 }
0082
0083
0084
0085
0086
0087 void Shell::GoToEvent(int eid) {
0088 if (eid < 1) {
0089 fprintf(stderr, "Requested event %d is less than 1 -- 1 is the first event, %d is total number of events in file\n",
0090 eid, m_evs_in_file);
0091 throw std::runtime_error("event out of range");
0092 }
0093 if (eid > m_evs_in_file) {
0094 fprintf(stderr, "Requested event %d is grater than total number of events in file %d\n",
0095 eid, m_evs_in_file);
0096 throw std::runtime_error("event out of range");
0097 }
0098
0099 int pos = m_event->evtID();
0100 if (eid > pos) {
0101 m_data_file->skipNEvents(eid - pos - 1);
0102 } else {
0103 m_data_file->rewind();
0104 m_data_file->skipNEvents(eid - 1);
0105 }
0106 m_event->resetCurrentSeedTracks();
0107 m_event->reset(eid);
0108 m_event->read_in(*m_data_file);
0109 StdSeq::loadHitsAndBeamSpot(*m_event, *m_eoh);
0110 if (Config::useDeadModules) {
0111 StdSeq::loadDeads(*m_eoh, m_deadvectors);
0112 }
0113
0114 printf("At event %d\n", eid);
0115 }
0116
0117 void Shell::NextEvent(int skip) {
0118 GoToEvent(m_event->evtID() + skip);
0119 }
0120
0121 void Shell::ProcessEvent(SeedSelect_e seed_select, int selected_seed, int count) {
0122
0123
0124
0125 const IterationConfig &itconf = Config::ItrInfo[m_it_index];
0126 IterationMaskIfc mask_ifc;
0127 m_event->fill_hitmask_bool_vectors(itconf.m_track_algorithm, mask_ifc.m_mask_vector);
0128
0129 m_seeds.clear();
0130 m_tracks.clear();
0131
0132 {
0133 int n_algo = 0;
0134 for (auto &s : m_event->seedTracks_) {
0135 if (s.algoint() == itconf.m_track_algorithm) {
0136 if (seed_select == SS_UseAll || seed_select == SS_IndexPostCleaning) {
0137 m_seeds.push_back(s);
0138 } else if (seed_select == SS_Label && s.label() == selected_seed) {
0139 m_seeds.push_back(s);
0140 break;
0141 } else if (seed_select == SS_IndexPreCleaning && n_algo >= selected_seed) {
0142 m_seeds.push_back(s);
0143 if (--count <= 0)
0144 break;
0145 }
0146 ++n_algo;
0147 } else if (n_algo > 0)
0148 break;
0149 }
0150 }
0151
0152 printf("Shell::ProcessEvent running over %d seeds\n", (int) m_seeds.size());
0153
0154
0155
0156 {
0157 const TrackerInfo &trackerInfo = Config::TrkInfo;
0158 const EventOfHits &eoh = *m_eoh;
0159 const IterationMaskIfcBase &it_mask_ifc = mask_ifc;
0160 MkBuilder &builder = *m_builder;
0161 TrackVec &seeds = m_seeds;
0162 TrackVec &out_tracks = m_tracks;
0163 bool do_seed_clean = m_clean_seeds;
0164 bool do_backward_fit = m_backward_fit;
0165 bool do_remove_duplicates = m_remove_duplicates;
0166
0167 MkJob job({trackerInfo, itconf, eoh, eoh.refBeamSpot(), &it_mask_ifc});
0168
0169 builder.begin_event(&job, m_event, __func__);
0170
0171
0172 do_seed_clean = m_clean_seeds && itconf.m_seed_cleaner;
0173
0174 if (do_seed_clean) {
0175 itconf.m_seed_cleaner(seeds, itconf, eoh.refBeamSpot());
0176 printf("Shell::ProcessEvent post seed-cleaning: %d seeds\n", (int) m_seeds.size());
0177 } else {
0178 printf("Shell::ProcessEvent no seed-cleaning\n");
0179 }
0180
0181
0182
0183 builder.seed_post_cleaning(seeds);
0184
0185 if (seed_select == SS_IndexPostCleaning) {
0186 int seed_size = (int) seeds.size();
0187 if (selected_seed >= 0 && selected_seed < seed_size) {
0188 if (selected_seed + count >= seed_size) {
0189 count = seed_size - selected_seed;
0190 printf(" -- selected seed_index + count > seed vector size after cleaning -- trimming count to %d\n",
0191 count);
0192 }
0193 for (int i = 0; i < count; ++i)
0194 seeds[i] = seeds[selected_seed + i];
0195 seeds.resize(count);
0196 } else {
0197 seeds.clear();
0198 }
0199 }
0200
0201 if (seeds.empty()) {
0202 if (seed_select != SS_UseAll)
0203 printf("Shell::ProcessEvent requested seed not found among seeds of the selected iteration.\n");
0204 else
0205 printf("Shell::ProcessEvent no seeds found.\n");
0206 return;
0207 }
0208
0209 if (itconf.m_requires_seed_hit_sorting) {
0210 for (auto &s : seeds)
0211 s.sortHitsByLayer();
0212 }
0213
0214 m_event->setCurrentSeedTracks(seeds);
0215
0216 builder.find_tracks_load_seeds(seeds, do_seed_clean);
0217
0218 builder.findTracksCloneEngine();
0219
0220 printf("Shell::ProcessEvent post fwd search: %d comb-cands\n", builder.ref_eocc().size());
0221
0222
0223 filter_candidates_func pre_filter;
0224 if (do_backward_fit && itconf.m_pre_bkfit_filter)
0225 pre_filter = [&](const TrackCand &tc, const MkJob &jb) -> bool {
0226 return itconf.m_pre_bkfit_filter(tc, jb) && StdSeq::qfilter_nan_n_silly<TrackCand>(tc, jb);
0227 };
0228 else if (itconf.m_pre_bkfit_filter)
0229 pre_filter = itconf.m_pre_bkfit_filter;
0230 else if (do_backward_fit)
0231 pre_filter = StdSeq::qfilter_nan_n_silly<TrackCand>;
0232
0233 if (pre_filter)
0234 builder.filter_comb_cands(pre_filter, true);
0235
0236 printf("Shell::ProcessEvent post pre-bkf-filter (%s) and nan-filter (%s) filter: %d comb-cands\n",
0237 b2a(bool(itconf.m_pre_bkfit_filter)), b2a(do_backward_fit), builder.ref_eocc().size());
0238
0239 job.switch_to_backward();
0240
0241 if (do_backward_fit) {
0242 if (itconf.m_backward_search) {
0243 builder.compactifyHitStorageForBestCand(itconf.m_backward_drop_seed_hits, itconf.m_backward_fit_min_hits);
0244 }
0245
0246 builder.backwardFit();
0247
0248 if (itconf.m_backward_search) {
0249 builder.beginBkwSearch();
0250 builder.findTracksCloneEngine(SteeringParams::IT_BkwSearch);
0251 }
0252
0253 printf("Shell::ProcessEvent post backward fit / search: %d comb-cands\n", builder.ref_eocc().size());
0254 }
0255
0256
0257 filter_candidates_func post_filter;
0258 if (do_backward_fit && itconf.m_post_bkfit_filter)
0259 post_filter = [&](const TrackCand &tc, const MkJob &jb) -> bool {
0260 return itconf.m_post_bkfit_filter(tc, jb) && StdSeq::qfilter_nan_n_silly<TrackCand>(tc, jb);
0261 };
0262 else
0263 post_filter = StdSeq::qfilter_nan_n_silly<TrackCand>;
0264
0265 builder.filter_comb_cands(post_filter, true);
0266
0267 printf("Shell::ProcessEvent post post-bkf-filter (%s) and nan-filter (true): %d comb-cands\n",
0268 b2a(do_backward_fit && itconf.m_post_bkfit_filter), builder.ref_eocc().size());
0269
0270 if (do_backward_fit && itconf.m_backward_search)
0271 builder.endBkwSearch();
0272
0273 builder.export_best_comb_cands(out_tracks, true);
0274
0275 if (do_remove_duplicates && itconf.m_duplicate_cleaner) {
0276 itconf.m_duplicate_cleaner(out_tracks, itconf);
0277 }
0278
0279 printf("Shell::ProcessEvent post remove-duplicates: %d comb-cands\n", (int) out_tracks.size());
0280
0281
0282
0283
0284 builder.end_event();
0285 }
0286
0287 printf("Shell::ProcessEvent found %d tracks, number of seeds at end %d\n",
0288 (int) m_tracks.size(), (int) m_seeds.size());
0289 }
0290
0291
0292
0293
0294
0295 void Shell::SelectIterationIndex(int itidx) {
0296 if (itidx < 0 || itidx >= n_algos) {
0297 fprintf(stderr, "Requested iteration index out of range [%d, %d)", 0, n_algos);
0298 throw std::runtime_error("iteration index out of range");
0299 }
0300 m_it_index = itidx;
0301 }
0302
0303 void Shell::SelectIterationAlgo(int algo) {
0304 for (int i = 0; i < n_algos; ++i) {
0305 if (algos[i] == algo) {
0306 m_it_index = i;
0307 return;
0308 }
0309 }
0310 fprintf(stderr, "Requested algo %d not found", algo);
0311 throw std::runtime_error("algo not found");
0312 }
0313
0314 void Shell::PrintIterations() {
0315 printf("Shell::PrintIterations selected index = %d, %d iterations hardcoded as\n",
0316 m_it_index, n_algos);
0317 for (int i = 0; i < n_algos; ++i)
0318 printf("%d %2d %s\n", i, algos[i], TrackBase::algoint_to_cstr(algos[i]));
0319 }
0320
0321
0322
0323
0324
0325 void Shell::SetDebug(bool b) { g_debug = b; }
0326 void Shell::SetCleanSeeds(bool b) { m_clean_seeds = b; }
0327 void Shell::SetBackwardFit(bool b) { m_backward_fit = b; }
0328 void Shell::SetRemoveDuplicates(bool b) { m_remove_duplicates = b; }
0329 void Shell::SetUseDeadModules(bool b) { Config::useDeadModules = b; }
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345 int Shell::LabelFromHits(Track &t, bool replace, float good_frac) {
0346 std::map<int, int> lab_cnt;
0347 for (int hi = 0; hi < t.nTotalHits(); ++hi) {
0348 auto hot = t.getHitOnTrack(hi);
0349 if (hot.index < 0)
0350 continue;
0351 const Hit &h = m_event->layerHits_[hot.layer][hot.index];
0352 int hl = m_event->simHitsInfo_[h.mcHitID()].mcTrackID_;
0353 if (hl >= 0)
0354 ++lab_cnt[hl];
0355 }
0356 int max_c = -1, max_l = -1;
0357 for (auto& x : lab_cnt) {
0358 if (x.second > max_c) {
0359 max_l = x.first;
0360 max_c = x.second;
0361 }
0362 }
0363 bool success = max_c >= good_frac * t.nFoundHits();
0364 int relabel = success ? max_l : -1;
0365
0366
0367 if (replace)
0368 t.setLabel(relabel);
0369 return relabel;
0370 }
0371
0372 void Shell::FillByLabelMaps_CkfBase() {
0373 Event &ev = *m_event;
0374 const int track_algo = Config::ItrInfo[m_it_index].m_track_algorithm;
0375
0376 m_ckf_map.clear();
0377 m_sim_map.clear();
0378 m_seed_map.clear();
0379 m_mkf_map.clear();
0380
0381
0382 int rec_algo_match = 0;
0383 for (auto &t : ev.cmsswTracks_) {
0384 if (t.algoint() != track_algo)
0385 continue;
0386 ++rec_algo_match;
0387 int label = LabelFromHits(t, false, 0.5);
0388 if (label >= 0) {
0389 m_ckf_map.insert(std::make_pair(label, &t));
0390 }
0391 }
0392
0393
0394 for (auto &t : ev.simTracks_) {
0395 if (t.label() >= 0 && m_ckf_map.find(t.label()) != m_ckf_map.end()) {
0396 m_sim_map.insert(std::make_pair(t.label(), &t));
0397 }
0398 }
0399
0400
0401 for (auto &t : ev.seedTracks_) {
0402 if (t.algoint() == track_algo && t.label() >= 0 && m_ckf_map.find(t.label()) != m_ckf_map.end()) {
0403 m_seed_map.insert(std::make_pair(t.label(), &t));
0404 }
0405 }
0406
0407 for (auto &t : ev.seedTracks_) {
0408 if (t.algoint() == track_algo && t.label() == -1) {
0409 int lab = LabelFromHits(t, true, 0.5);
0410 if (lab >= 0 && m_seed_map.find(lab) == m_seed_map.end()) {
0411 if (m_ckf_map.find(lab) != m_ckf_map.end()) {
0412 m_seed_map.insert(std::make_pair(t.label(), &t));
0413 printf("Saved seed with label -1 -> %d\n", lab);
0414 }
0415 }
0416 }
0417 }
0418
0419
0420 for (auto &t : m_tracks) {
0421 int label = LabelFromHits(t, false, 0.5);
0422 if (label >= 0) {
0423 m_mkf_map.insert(std::make_pair(label, &t));
0424 }
0425 }
0426
0427 printf("Shell::FillByLabelMaps reporting tracks with label >= 0, algo=%d (%s): "
0428 "ckf: %d of %d (same algo=%d)), sim: %d of %d, seed: %d of %d, mkfit: %d w/label of %d\n",
0429 track_algo, TrackBase::algoint_to_cstr(track_algo),
0430 (int) m_ckf_map.size(), (int) ev.cmsswTracks_.size(), rec_algo_match,
0431 (int) m_sim_map.size(), (int) ev.simTracks_.size(),
0432 (int) m_seed_map.size(), (int) m_seeds.size(),
0433 (int) m_mkf_map.size(), (int) m_tracks.size()
0434 );
0435 }
0436
0437 bool Shell::CheckMkFitLayerPlanVsReferenceHits(const Track &mkft, const Track &reft, const std::string &name) {
0438
0439
0440
0441 const IterationConfig &itconf = Config::ItrInfo[m_it_index];
0442 auto lp = itconf.m_steering_params[ mkft.getEtaRegion() ].m_layer_plan;
0443 bool ret = true;
0444 for (int hi = 0; hi < reft.nTotalHits(); ++hi) {
0445 auto hot = reft.getHitOnTrack(hi);
0446 if (std::find_if(lp.begin(), lp.end(), [=](auto &x){ return x.m_layer == hot.layer; }) == lp.end())
0447 {
0448 printf("CheckMkfLayerPlanVsCkfHits: layer %d not in layer plan for region %d, %s label=%d\n",
0449 hot.layer, mkft.getEtaRegion(), name.c_str(), reft.label());
0450 ret = false;
0451 }
0452 }
0453 return ret;
0454 }
0455
0456
0457
0458
0459
0460 void Shell::Compare() {
0461 Event &ev = *m_event;
0462 const IterationConfig &itconf = Config::ItrInfo[m_it_index];
0463
0464 FillByLabelMaps_CkfBase();
0465
0466 printf("------------------------------------------------------\n");
0467
0468 const bool print_all_def = false;
0469 int mkf_cnt=0, less_hits=0, more_hits=0;
0470
0471
0472 int tot_cnt = 0, no_mkf_cnt = 0;
0473
0474 for (auto& [l, simt_ptr]: m_sim_map)
0475 {
0476 auto &simt = * simt_ptr;
0477 auto &ckft = * m_ckf_map[l];
0478 auto mi = m_mkf_map.find(l);
0479
0480 bool print_all = print_all_def;
0481
0482
0483 bool select = true;
0484 {
0485 auto &ckf_seed = ev.seedTracks_[ckft.label()];
0486 for (int hi = 0; hi < ckf_seed.nTotalHits(); ++hi) {
0487 const HitOnTrack hot = ckf_seed.getHitOnTrack(hi);
0488 if (hot.index >= 0 && (hot.layer < 10 || hot.layer > 13)) {
0489 select = false;
0490 break;
0491 }
0492 }
0493 }
0494 if ( ! select) continue;
0495
0496 ++tot_cnt;
0497
0498
0499 if (mi != m_mkf_map.end())
0500 {
0501 auto &mkft = * mi->second;
0502 mkf_cnt++;
0503 if (mkft.nFoundHits() < ckft.nFoundHits()) ++less_hits;
0504 if (mkft.nFoundHits() > ckft.nFoundHits()) ++more_hits;
0505
0506 CheckMkFitLayerPlanVsReferenceHits(mkft, ckft, "CKF");
0507
0508
0509 (void) print_all;
0510 if ( print_all) {
0511
0512
0513 auto &ckf_seed = ev.seedTracks_[ckft.label()];
0514 auto &mkf_seed = m_seeds[mkft.label()];
0515 print("ckf ", 0, ckft, ev);
0516 print("mkfit", 0, mkft, ev);
0517 print("sim ", 0, simt, ev);
0518 print("ckf seed", 0, ckf_seed, ev);
0519 print("mkf seed", 0, mkf_seed, ev);
0520 printf("------------------------------------------------------\n");
0521
0522 TrackVec ssss;
0523 ssss.push_back(mkf_seed);
0524
0525 IterationSeedPartition pppp(1);
0526 IterationConfig::get_seed_partitioner("phase1:1:debug")(Config::TrkInfo, ssss, *m_eoh, pppp);
0527
0528 printf("------------------------------------------------------\n");
0529 printf("\n");
0530 }
0531 }
0532 else
0533 {
0534 printf("\n!!!!! No mkfit track with this label.\n\n");
0535 ++no_mkf_cnt;
0536
0537 auto &ckf_seed = ev.seedTracks_[ckft.label()];
0538 print("ckf ", 0, ckft, ev);
0539 print("sim ", 0, simt, ev);
0540 print("ckf seed", 0, ckf_seed, ev);
0541 auto smi = m_seed_map.find(l);
0542 if (smi != m_seed_map.end())
0543 print("seed with matching label", 0, *smi->second, ev);
0544 printf("------------------------------------------------------\n");
0545 }
0546 }
0547
0548 printf("mkFit found %d, matching_label=%d, less_hits=%d, more_hits=%d [algo=%d (%s)]\n",
0549 (int) ev.fitTracks_.size(), mkf_cnt, less_hits, more_hits,
0550 itconf.m_track_algorithm, TrackBase::algoint_to_cstr(itconf.m_track_algorithm));
0551
0552 if (tot_cnt > 0) {
0553 printf("\ntobtec tob1/2 tot=%d no_mkf=%d (%f%%)\n",
0554 tot_cnt, no_mkf_cnt, 100.0 * no_mkf_cnt / tot_cnt);
0555 } else {
0556 printf("\nNo CKF tracks with seed hits in TOB1/2 found (need iteration idx 8, TobTec?)\n");
0557 }
0558
0559 printf("-------------------------------------------------------------------------------------------\n");
0560 printf("-------------------------------------------------------------------------------------------\n");
0561 printf("\n");
0562 }
0563
0564 }