File indexing completed on 2025-12-17 09:21:54
0001 #include "TruthRecoTrackMatching.h"
0002 #include "ClusKeyIter.h"
0003 #include "TrkrClusterIsMatcher.h"
0004
0005 #include <g4detectors/PHG4TpcGeomContainer.h>
0006
0007 #include <g4main/PHG4TruthInfoContainer.h>
0008
0009 #include <g4tracking/EmbRecoMatch.h>
0010 #include <g4tracking/EmbRecoMatchContainer.h>
0011 #include <g4tracking/EmbRecoMatchContainerv1.h>
0012 #include <g4tracking/EmbRecoMatchv1.h>
0013 #include <g4tracking/TrkrTruthTrack.h>
0014 #include <g4tracking/TrkrTruthTrackContainer.h>
0015
0016 #include <trackbase/ActsGeometry.h>
0017 #include <trackbase/TrkrClusterContainer.h>
0018 #include <trackbase/TrkrDefs.h>
0019
0020 #include <trackbase_historic/SvtxTrack.h>
0021 #include <trackbase_historic/SvtxTrackMap.h>
0022
0023 #include <fun4all/Fun4AllReturnCodes.h>
0024
0025 #include <phool/PHCompositeNode.h>
0026 #include <phool/PHIODataNode.h>
0027 #include <phool/PHNode.h> // for PHNode
0028 #include <phool/PHNodeIterator.h>
0029 #include <phool/PHObject.h> // for PHObject
0030 #include <phool/getClass.h>
0031 #include <phool/phool.h> // for PHWHERE
0032
0033 #include <TFile.h>
0034 #include <TTree.h>
0035
0036 #include <algorithm>
0037 #include <format>
0038
0039
0040
0041
0042 TruthRecoTrackMatching::TruthRecoTrackMatching(
0043 TrkrClusterIsMatcher* _ismatcher, const unsigned short _nmincluster_match, const float _nmincluster_ratio, const float _cutoff_dphi, const float _same_dphi, const float _cutoff_deta, const float _same_deta, const unsigned short _max_nreco_per_truth, const unsigned short _max_ntruth_per_reco)
0044 : m_ismatcher{_ismatcher}
0045 , m_nmincluster_match{_nmincluster_match}
0046 , m_nmincluster_ratio{_nmincluster_ratio}
0047
0048 , m_cutoff_dphi{_cutoff_dphi}
0049 , m_same_dphi{_same_dphi}
0050 , m_cutoff_deta{_cutoff_deta}
0051 , m_same_deta{_same_deta}
0052
0053
0054 , m_max_nreco_per_truth{_max_nreco_per_truth}
0055 , m_max_ntruth_per_reco{_max_ntruth_per_reco}
0056 {
0057 m_TCEval.ismatcher = m_ismatcher;
0058 if (Verbosity() > 50)
0059 {
0060 std::cout << " Starting TruthRecoTrackMatching.cc " << std::endl;
0061 }
0062 }
0063
0064 int TruthRecoTrackMatching::InitRun(PHCompositeNode* topNode)
0065 {
0066 if (Verbosity() > 10)
0067 {
0068 topNode->print();
0069 }
0070 auto init_status = m_ismatcher->init(topNode);
0071 if (init_status == Fun4AllReturnCodes::ABORTRUN)
0072 {
0073 return init_status;
0074 }
0075
0076 if (createNodes(topNode) != Fun4AllReturnCodes::EVENT_OK)
0077 {
0078 return Fun4AllReturnCodes::ABORTRUN;
0079 }
0080 m_nmatched_id_reco = &(m_EmbRecoMatchContainer->map_nTruthPerReco());
0081 m_nmatched_id_true = &(m_EmbRecoMatchContainer->map_nRecoPerTruth());
0082 return Fun4AllReturnCodes::EVENT_OK;
0083 }
0084
0085 int TruthRecoTrackMatching::process_event(PHCompositeNode* topnode)
0086 {
0087 if (topnode == nullptr)
0088 {
0089 return Fun4AllReturnCodes::ABORTRUN;
0090 }
0091 if (Verbosity() > 1000)
0092 {
0093 topnode->print();
0094 }
0095
0096 m_nmatched_index_true.clear();
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112 if (Verbosity() > 60)
0113 {
0114 std::cout << "reco tracks size: " << m_SvtxTrackMap->size() << std::endl;
0115 }
0116
0117 recoData.clear();
0118
0119 for (auto& reco : *m_SvtxTrackMap)
0120 {
0121 auto index_reco = reco.first;
0122 auto* track = reco.second;
0123 recoData.emplace_back(track->get_phi(), track->get_eta(), track->get_pt(), index_reco);
0124 }
0125
0126 std::sort(recoData.begin(), recoData.end(), CompRECOtoPhi());
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141 RECOvec wraps{};
0142 auto wrap_from_start = std::upper_bound(recoData.begin(),
0143 recoData.end(), (-M_PI + m_cutoff_dphi), CompRECOtoPhi());
0144 for (auto iter = recoData.begin(); iter != wrap_from_start; ++iter)
0145 {
0146 auto entry = *iter;
0147 std::get<RECOphi>(entry) = std::get<RECOphi>(entry) + 2 * M_PI;
0148 wraps.push_back(entry);
0149 }
0150 for (auto E : wraps)
0151 {
0152 recoData.push_back(E);
0153 }
0154
0155 if (Verbosity() > 70)
0156 {
0157 std::cout << " ****************************************** " << std::endl;
0158 std::cout << " This is the RECO map of tracks to match to " << std::endl;
0159 std::cout << " ****************************************** " << std::endl;
0160 for (auto& E : recoData)
0161 {
0162 std::cout << std::format(" id:{:2} (phi:eta:pt) ({:5.2}:{:5.2}:{:5.2})", std::get<RECOid>(E),
0163 std::get<RECOphi>(E), std::get<RECOeta>(E), std::get<RECOpt>(E))
0164 << std::endl;
0165 }
0166 std::cout << " ****end*listing*********************** " << std::endl;
0167 }
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 std::vector<std::pair<unsigned short, unsigned short>> outerbox_pairs{};
0183 std::vector<std::pair<unsigned short, unsigned short>> innerbox_pairs{};
0184
0185 if (topnode == nullptr)
0186 {
0187 return Fun4AllReturnCodes::ABORTRUN;
0188 }
0189 if (Verbosity() > 70)
0190 {
0191 std::cout << "Number of truth tracks: " << m_TrkrTruthTrackContainer->getMap().size() << std::endl;
0192 for (auto& _pair : m_TrkrTruthTrackContainer->getMap())
0193 {
0194 auto& track = _pair.second;
0195 std::cout << std::format(" id:{:2} (phi:eta:pt) ({:5.2}:{:5.2}:{:5.2} nclus: {})",
0196 track->getTrackid(), track->getPhi(), track->getPseudoRapidity(),
0197 track->getPt(), track->getClusters().size())
0198 << std::endl;
0199 }
0200 std::cout << " ----end-listing-truth-tracks---------- " << std::endl;
0201 }
0202
0203 for (auto _pair : m_TrkrTruthTrackContainer->getMap())
0204 {
0205 auto id_true = _pair.first;
0206 auto* track = _pair.second;
0207
0208 auto match_indices = find_box_matches(track->getPhi(),
0209 track->getPseudoRapidity(), track->getPt());
0210
0211
0212 for (auto& id_reco : match_indices.first)
0213 {
0214 innerbox_pairs.emplace_back(id_true, id_reco);
0215 }
0216 for (auto& id_reco : match_indices.second)
0217 {
0218 outerbox_pairs.emplace_back(id_true, id_reco);
0219 }
0220
0221 if (Verbosity() > 80)
0222 {
0223 std::cout << std::format(" T({}) find box({:5.2}:{:5.2}:{:5.2})",
0224 track->getTrackid(), track->getPhi(),
0225 track->getPseudoRapidity(), track->getPt());
0226 for (auto& id_reco : match_indices.first)
0227 {
0228 std::cout << "->IB(" << id_reco << ")";
0229 }
0230 for (auto& id_reco : match_indices.second)
0231 {
0232 std::cout << "->OB(" << id_reco << ")";
0233 }
0234 std::cout << std::endl;
0235 }
0236 }
0237
0238 if (Verbosity() > 100)
0239 {
0240 std::cout << "Innerbox pairs" << std::endl;
0241 }
0242 match_tracks_in_box(innerbox_pairs);
0243 if (Verbosity() > 100)
0244 {
0245 std::cout << "Outerbox pairs" << std::endl;
0246 }
0247 match_tracks_in_box(outerbox_pairs);
0248
0249
0250 for (auto _pair : m_TrkrTruthTrackContainer->getMap())
0251 {
0252 auto id_true = _pair.first;
0253 m_EmbRecoMatchContainer->checkfill_idsTruthUnmatched(id_true);
0254 }
0255
0256 if (Verbosity() > 50)
0257 {
0258 std::cout << " --START--print-all-stored-matches--" << std::endl;
0259 std::cout << " --0-- Printing all matches stored (start)" << std::endl;
0260
0261 for (auto* match : m_EmbRecoMatchContainer->getMatches())
0262 {
0263 std::cout << std::format(" Match id({:2}->{:2}) nClusMatch-nClusTrue-nClusReco ({:2}:{:2}:{:2})",
0264 match->idTruthTrack(), match->idRecoTrack(), match->nClustersMatched(),
0265 match->nClustersTruth(), match->nClustersReco())
0266 << std::endl;
0267 }
0268 std::cout << " --END--print-all-stored-matches----" << std::endl;
0269 }
0270
0271 if (m_write_diag)
0272 {
0273 fill_tree();
0274 }
0275
0276 return Fun4AllReturnCodes::EVENT_OK;
0277 }
0278
0279 int TruthRecoTrackMatching::End(PHCompositeNode* )
0280 {
0281 TFile* s_current = gDirectory->GetFile();
0282 if (m_write_diag)
0283 {
0284 m_diag_file->cd();
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297 m_diag_tree->Write();
0298 m_diag_file->Save();
0299 m_diag_file->Close();
0300 if (s_current != nullptr)
0301 {
0302 s_current->cd();
0303 }
0304 }
0305
0306 return Fun4AllReturnCodes::EVENT_OK;
0307 }
0308
0309
0310
0311
0312
0313 int TruthRecoTrackMatching::createNodes(PHCompositeNode* topNode)
0314 {
0315 PHNodeIterator iter(topNode);
0316 PHCompositeNode* dstNode = dynamic_cast<PHCompositeNode*>(iter.findFirst("PHCompositeNode", "DST"));
0317 if (!dstNode)
0318 {
0319 std::cout << PHWHERE << "DST Node missing, doing nothing." << std::endl;
0320 exit(1);
0321 }
0322
0323
0324 m_PHG4TruthInfoContainer = findNode::getClass<PHG4TruthInfoContainer>(topNode, "G4TruthInfo");
0325 if (!m_PHG4TruthInfoContainer)
0326 {
0327 std::cout << "Could not locate G4TruthInfo node when running "
0328 << "\"TruthRecoTrackMatching\" module." << std::endl;
0329 return Fun4AllReturnCodes::ABORTEVENT;
0330 }
0331
0332 m_SvtxTrackMap = findNode::getClass<SvtxTrackMap>(topNode, "SvtxTrackMap");
0333 if (!m_SvtxTrackMap)
0334 {
0335 std::cout << "Could not locate SvtxTrackMap node when running "
0336 << "\"TruthRecoTrackMatching\" module." << std::endl;
0337 return Fun4AllReturnCodes::ABORTEVENT;
0338 }
0339
0340 m_TruthClusterContainer = findNode::getClass<TrkrClusterContainer>(topNode,
0341 "TRKR_TRUTHCLUSTERCONTAINER");
0342 if (!m_TruthClusterContainer)
0343 {
0344 std::cout << "Could not locate TRKR_TRUTHCLUSTERCONTAINER node when "
0345 << "running \"TruthRecoTrackMatching\" module." << std::endl;
0346 return Fun4AllReturnCodes::ABORTEVENT;
0347 }
0348
0349 m_RecoClusterContainer = findNode::getClass<TrkrClusterContainer>(topNode, "TRKR_CLUSTER");
0350 if (!m_RecoClusterContainer)
0351 {
0352 std::cout << "Could not locate TRKR_CLUSTER node when running "
0353 << "\"TruthRecoTrackMatching\" module." << std::endl;
0354 return Fun4AllReturnCodes::ABORTEVENT;
0355 }
0356
0357 m_TrkrTruthTrackContainer = findNode::getClass<TrkrTruthTrackContainer>(topNode,
0358 "TRKR_TRUTHTRACKCONTAINER");
0359 if (!m_TrkrTruthTrackContainer)
0360 {
0361 std::cout << "Could not locate TRKR_TRUTHTRACKCONTAINER node when "
0362 << "running \"TruthRecoTrackMatching\" module." << std::endl;
0363 return Fun4AllReturnCodes::ABORTEVENT;
0364 }
0365
0366 m_PHG4TpcGeomContainer =
0367 findNode::getClass<PHG4TpcGeomContainer>(topNode, "TPCGEOMCONTAINER");
0368 if (!m_PHG4TpcGeomContainer)
0369 {
0370 std::cout << "Could not locate TPCGEOMCONTAINER node when "
0371 << "running \"TruthRecoTrackMatching\" module." << std::endl;
0372 return Fun4AllReturnCodes::ABORTEVENT;
0373 }
0374
0375
0376
0377
0378
0379
0380
0381 m_EmbRecoMatchContainer = findNode::getClass<EmbRecoMatchContainer>(topNode,
0382 "TRKR_EMBRECOMATCHCONTAINER");
0383 if (!m_EmbRecoMatchContainer)
0384 {
0385 PHNodeIterator dstiter(dstNode);
0386
0387 auto* DetNode = dynamic_cast<PHCompositeNode*>(dstiter.findFirst("PHCompositeNode", "TRKR"));
0388 if (!DetNode)
0389 {
0390 DetNode = new PHCompositeNode("TRKR");
0391 dstNode->addNode(DetNode);
0392 }
0393
0394 m_EmbRecoMatchContainer = new EmbRecoMatchContainerv1;
0395 auto* newNode = new PHIODataNode<PHObject>(m_EmbRecoMatchContainer,
0396 "TRKR_EMBRECOMATCHCONTAINER", "PHObject");
0397 DetNode->addNode(newNode);
0398 }
0399
0400 m_ActsGeometry = findNode::getClass<ActsGeometry>(topNode, "ActsGeometry");
0401
0402 return Fun4AllReturnCodes::EVENT_OK;
0403 }
0404
0405 std::pair<std::vector<unsigned short>, std::vector<unsigned short>>
0406 TruthRecoTrackMatching::find_box_matches(float truth_phi, float truth_eta, float truth_pt)
0407 {
0408
0409
0410
0411
0412
0413
0414 RECO_pair_iter mix_pair{recoData.begin(), recoData.end()};
0415
0416 mix_pair.first = std::lower_bound(mix_pair.first, mix_pair.second,
0417 truth_phi - m_cutoff_dphi, CompRECOtoPhi());
0418
0419 mix_pair.second = std::upper_bound(mix_pair.first, mix_pair.second,
0420 truth_phi + m_cutoff_dphi, CompRECOtoPhi());
0421
0422 if (mix_pair.first == mix_pair.second)
0423 {
0424
0425 return {{}, {}};
0426 }
0427
0428
0429
0430
0431 std::sort(mix_pair.first, mix_pair.second, CompRECOtoEta());
0432
0433 RECO_pair_iter outer_box = mix_pair;
0434 outer_box.first = std::lower_bound(mix_pair.first, mix_pair.second,
0435 truth_eta - m_cutoff_deta, CompRECOtoEta());
0436
0437 outer_box.second = std::lower_bound(outer_box.first, outer_box.second,
0438 truth_eta + m_cutoff_deta, CompRECOtoEta());
0439
0440 if (outer_box.first == outer_box.second)
0441 {
0442
0443 std::sort(mix_pair.first, mix_pair.second, CompRECOtoPhi());
0444 return {{}, {}};
0445 }
0446
0447
0448 RECO_pair_iter inner_box = outer_box;
0449 const float _delta_outer_pt = delta_outer_pt(truth_pt);
0450 const float _delta_inner_pt = delta_inner_pt(truth_pt);
0451 if (_delta_outer_pt > 0)
0452 {
0453 std::sort(outer_box.first, outer_box.second, CompRECOtoPt());
0454 outer_box.first = std::lower_bound(outer_box.first, outer_box.second, truth_pt - _delta_outer_pt, CompRECOtoPt());
0455 outer_box.second = std::upper_bound(outer_box.first, outer_box.second, truth_pt + _delta_outer_pt, CompRECOtoPt());
0456
0457
0458 if (outer_box.first == outer_box.second)
0459 {
0460
0461 std::sort(mix_pair.first, mix_pair.second, CompRECOtoPhi());
0462 return {{}, {}};
0463 }
0464
0465
0466 inner_box = outer_box;
0467 if (_delta_inner_pt > 0)
0468 {
0469
0470 inner_box.first = std::lower_bound(inner_box.first,
0471 inner_box.second, truth_pt - _delta_inner_pt, CompRECOtoPt());
0472 inner_box.second = std::upper_bound(inner_box.first,
0473 inner_box.second, truth_pt + _delta_inner_pt, CompRECOtoPt());
0474 }
0475
0476
0477 std::sort(inner_box.first, inner_box.second, CompRECOtoEta());
0478 }
0479
0480
0481
0482
0483
0484 if (inner_box.first != inner_box.second)
0485 {
0486 inner_box.first = std::lower_bound(inner_box.first, inner_box.second,
0487 truth_eta - m_same_deta, CompRECOtoEta());
0488
0489 inner_box.second = std::lower_bound(inner_box.first, inner_box.second,
0490 truth_eta + m_same_deta, CompRECOtoEta());
0491 }
0492
0493
0494 if (inner_box.first != inner_box.second)
0495 {
0496 std::sort(inner_box.first, inner_box.second, CompRECOtoPhi());
0497
0498 inner_box.first = std::lower_bound(inner_box.first, inner_box.second,
0499 truth_phi - m_same_dphi, CompRECOtoPhi());
0500
0501 inner_box.second = std::lower_bound(inner_box.first, inner_box.second,
0502 truth_phi + m_same_dphi, CompRECOtoPhi());
0503 }
0504
0505
0506
0507
0508 std::vector<unsigned short> inner_box_matches;
0509 std::vector<unsigned short> outer_box_matches;
0510
0511
0512 for (auto iter = inner_box.first; iter != inner_box.second; ++iter)
0513 {
0514 inner_box_matches.push_back(std::get<RECOid>(*iter));
0515 }
0516
0517 for (auto iter = outer_box.first; iter != inner_box.first; ++iter)
0518 {
0519 outer_box_matches.push_back(std::get<RECOid>(*iter));
0520 }
0521 for (auto iter = inner_box.second; iter != outer_box.second; ++iter)
0522 {
0523 outer_box_matches.push_back(std::get<RECOid>(*iter));
0524 }
0525
0526
0527 std::sort(mix_pair.first, mix_pair.second, CompRECOtoPhi());
0528
0529
0530 return std::make_pair(inner_box_matches, outer_box_matches);
0531 }
0532
0533 void TruthRecoTrackMatching::match_tracks_in_box(
0534 std::vector<std::pair<unsigned short, unsigned short>>& box_pairs
0535 )
0536 {
0537 if (box_pairs.empty())
0538 {
0539 return;
0540 }
0541
0542 std::sort(box_pairs.begin(), box_pairs.end());
0543 std::vector<PossibleMatch> poss_matches;
0544
0545 auto ipair = box_pairs.begin();
0546 while (ipair != box_pairs.end())
0547 {
0548 auto id_true = ipair->first;
0549
0550
0551 if (at_nmax_index_true(id_true))
0552 {
0553 while (ipair != box_pairs.end())
0554 {
0555 ++ipair;
0556 if (ipair->first != id_true)
0557 {
0558 break;
0559 }
0560 }
0561 continue;
0562 }
0563
0564
0565
0566 m_TCEval.addClusKeys(m_TrkrTruthTrackContainer->getTruthTrack(id_true));
0567
0568
0569
0570
0571
0572
0573
0574 while (ipair != box_pairs.end())
0575 {
0576
0577 if (ipair->first != id_true)
0578 {
0579 break;
0580 }
0581 if (at_nmax_id_reco(ipair->second))
0582 {
0583 ++ipair;
0584 continue;
0585 }
0586
0587 SvtxTrack* reco_track = m_SvtxTrackMap->get(ipair->second);
0588 m_TCEval.addClusKeys(reco_track);
0589 m_TCEval.find_matches();
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607
0608
0609 unsigned short nclus_match = m_TCEval.phg4_n_matched();
0610 unsigned short nclus_true = m_TCEval.phg4_nclus();
0611 unsigned short nclus_reco = m_TCEval.svtx_nclus();
0612 unsigned short nclus_nomatch = (int) (m_TCEval.svtx_keys.size() - nclus_match);
0613
0614 if (Verbosity() > 100)
0615 {
0616 auto* truth_track = m_TrkrTruthTrackContainer->getTruthTrack(id_true);
0617 std::cout << std::format(
0618 "possmatch:(phi,eta,pT:id) true({:5.2},{:5.2},{:4.2}:{:2}) reco({:5.2},{:5.2},{:4.2}:{:2}) nCl(match:true:reco:nomatch)({:2}-{:2}-{:2}-{:2})",
0619 truth_track->getPhi(), truth_track->getPseudoRapidity(), truth_track->getPt(),
0620 truth_track->getTrackid(), reco_track->get_phi(), reco_track->get_eta(), reco_track->get_pt(),
0621 ipair->second, nclus_match, nclus_true, nclus_reco, nclus_nomatch)
0622 << std::endl;
0623 }
0624 if (nclus_match >= m_nmincluster_match && (static_cast<float>(nclus_match) / nclus_true >= m_nmincluster_ratio))
0625 {
0626 poss_matches.push_back(
0627 {nclus_match, nclus_true, nclus_reco,
0628 ipair->first, ipair->second});
0629 }
0630 ++ipair;
0631 }
0632 }
0633
0634
0635
0636
0637
0638 std::sort(poss_matches.begin(), poss_matches.end(), SortPossibleMatch());
0639
0640 if (Verbosity() > 200)
0641 {
0642 std::cout << " All chosen possible matches (" << poss_matches.size() << ") track pairs (nClMatched-nClTrue-nClReco : idTrue-idReco)" << std::endl;
0643 int i{0};
0644 for (auto match : poss_matches)
0645 {
0646
0647
0648 std::cout << std::format(" pair({:2}): {:2}-{:2}-{:2}-<{:2}>-{:2} ", (i++), std::get<PM_nmatch>(match),
0649 std::get<PM_ntrue>(match), std::get<PM_nreco>(match), std::get<PM_idtrue>(match),
0650 std::get<PM_idreco>(match))
0651 << std::endl;
0652 }
0653 }
0654
0655
0656 auto iter = poss_matches.begin();
0657 while (iter != poss_matches.end())
0658 {
0659 if (skip_match(*iter))
0660 {
0661 ++iter;
0662 continue;
0663 }
0664 std::vector<std::pair<float, int>> sigma_metric = {{0., 0}};
0665 int n_sigma = 0;
0666 auto iter_same = iter + 1;
0667 while (
0668 iter_same != poss_matches.end() && (*iter_same)[PM_nmatch] == (*iter)[PM_nmatch] && (*iter_same)[PM_ntrue] == (*iter)[PM_ntrue] && (*iter_same)[PM_nreco] == (*iter)[PM_nreco])
0669 {
0670 ++n_sigma;
0671 if (n_sigma == 1)
0672 {
0673 sigma_metric[0].first = sigma_CompMatchClusters(*iter);
0674 }
0675 sigma_metric.emplace_back(sigma_CompMatchClusters(*iter_same), n_sigma);
0676 ++iter_same;
0677 }
0678 std::sort(sigma_metric.begin(), sigma_metric.end());
0679
0680 bool first = true;
0681 for (auto& sigma : sigma_metric)
0682 {
0683 if (first)
0684 {
0685 first = false;
0686 }
0687 else if (skip_match(*(iter + sigma.second)))
0688 {
0689 continue;
0690 }
0691 auto match = *(iter + sigma.second);
0692 auto id_true = match[PM_idtrue];
0693 auto id_reco = match[PM_idreco];
0694 auto* save_match = new EmbRecoMatchv1(id_true, id_reco,
0695 match[PM_ntrue], match[PM_nreco], match[PM_nmatch]);
0696 m_EmbRecoMatchContainer->addMatch(save_match);
0697
0698 if (!m_nmatched_index_true.contains(id_true))
0699 {
0700 m_nmatched_index_true[id_true] = 1;
0701 }
0702 else
0703 {
0704 m_nmatched_index_true[id_true] += 1;
0705 }
0706 }
0707 iter += sigma_metric.size();
0708 }
0709 }
0710
0711
0712
0713
0714 inline float TruthRecoTrackMatching::abs_dphi(float phi0, float phi1)
0715 {
0716 float dphi = std::abs(phi0 - phi1);
0717 while (dphi > M_PI)
0718 {
0719 dphi = std::abs(dphi - 2 * M_PI);
0720 }
0721 return dphi;
0722 }
0723
0724 float TruthRecoTrackMatching::sigma_CompMatchClusters(PossibleMatch& match)
0725 {
0726 auto id_true = match[PM_idtrue];
0727 auto id_reco = match[PM_idreco];
0728
0729 m_TCEval.addClusKeys(m_TrkrTruthTrackContainer->getTruthTrack(id_true));
0730 m_TCEval.addClusKeys(m_SvtxTrackMap->get(id_reco));
0731
0732 m_TCEval.find_matches();
0733
0734 int n_matched = m_TCEval.phg4_n_matched();
0735
0736 if (n_matched)
0737 {
0738 return std::numeric_limits<float>::max();
0739 }
0740
0741 return m_TCEval.match_stat / n_matched;
0742 }
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771 inline bool TruthRecoTrackMatching::skip_match(PossibleMatch& match)
0772 {
0773 return at_nmax_id_reco(match[PM_idreco]) || at_nmax_index_true(match[PM_idreco]);
0774 }
0775
0776
0777
0778
0779
0780
0781
0782
0783 float TruthRecoTrackMatching::delta_outer_pt(float pt) const
0784 {
0785 return -1. + pt * 0.;
0786 }
0787 float TruthRecoTrackMatching::delta_inner_pt(float pt) const
0788 {
0789 return -1. + pt * 0.;
0790 }
0791
0792 bool TruthRecoTrackMatching::at_nmax_index_true(unsigned short index_true)
0793 {
0794 if (!m_nmatched_index_true.contains(index_true))
0795 {
0796 return false;
0797 }
0798 return m_nmatched_index_true[index_true] >= m_max_nreco_per_truth;
0799 }
0800
0801 bool TruthRecoTrackMatching::at_nmax_id_reco(unsigned short id_reco)
0802 {
0803 if (!m_nmatched_id_reco->contains(id_reco))
0804 {
0805 return false;
0806 }
0807 return (*m_nmatched_id_reco)[id_reco] >= m_max_ntruth_per_reco;
0808 }
0809
0810 void TruthRecoTrackMatching::set_diagnostic_file(const std::string& file_name)
0811 {
0812 m_write_diag = true;
0813 TFile* s_current = gDirectory->GetFile();
0814 m_diag_file = new TFile(file_name.c_str(), "recreate");
0815
0816 m_diag_file->cd();
0817 m_diag_tree = new TTree("T", "Tree of Reco and True Clusters");
0818
0819 m_diag_tree->Branch("event", &m_event);
0820
0821 m_diag_tree->Branch("trkid_reco_matched", &m_trkid_reco_matched);
0822 m_diag_tree->Branch("itrk_reco_matched", &m_cnt_reco_matched);
0823 m_diag_tree->Branch("i0_reco_matched", &m_i0_reco_matched);
0824 m_diag_tree->Branch("i1_reco_matched", &m_i1_reco_matched);
0825 m_diag_tree->Branch("layer_reco_matched", &m_layer_reco_matched);
0826 m_diag_tree->Branch("x_reco_matched", &m_x_reco_matched);
0827 m_diag_tree->Branch("y_reco_matched", &m_y_reco_matched);
0828 m_diag_tree->Branch("z_reco_matched", &m_z_reco_matched);
0829
0830 m_diag_tree->Branch("trkid_reco_notmatched", &m_trkid_reco_notmatched);
0831 m_diag_tree->Branch("itrk_reco_notmatched", &m_cnt_reco_notmatched);
0832 m_diag_tree->Branch("i0_reco_notmatched", &m_i0_reco_notmatched);
0833 m_diag_tree->Branch("i1_reco_notmatched", &m_i1_reco_notmatched);
0834 m_diag_tree->Branch("layer_reco_notmatched", &m_layer_reco_notmatched);
0835 m_diag_tree->Branch("x_reco_notmatched", &m_x_reco_notmatched);
0836 m_diag_tree->Branch("y_reco_notmatched", &m_y_reco_notmatched);
0837 m_diag_tree->Branch("z_reco_notmatched", &m_z_reco_notmatched);
0838
0839 m_diag_tree->Branch("trkid_true_matched", &m_trkid_true_matched);
0840 m_diag_tree->Branch("itrk_true_matched", &m_cnt_true_matched);
0841 m_diag_tree->Branch("i0_true_matched", &m_i0_true_matched);
0842 m_diag_tree->Branch("i1_true_matched", &m_i1_true_matched);
0843 m_diag_tree->Branch("layer_true_matched", &m_layer_true_matched);
0844 m_diag_tree->Branch("x_true_matched", &m_x_true_matched);
0845 m_diag_tree->Branch("y_true_matched", &m_y_true_matched);
0846 m_diag_tree->Branch("z_true_matched", &m_z_true_matched);
0847
0848 m_diag_tree->Branch("trkid_true_notmatched", &m_trkid_true_notmatched);
0849 m_diag_tree->Branch("itrk_true_notmatched", &m_cnt_true_notmatched);
0850 m_diag_tree->Branch("i0_true_notmatched", &m_i0_true_notmatched);
0851 m_diag_tree->Branch("i1_true_notmatched", &m_i1_true_notmatched);
0852 m_diag_tree->Branch("layer_true_notmatched", &m_layer_true_notmatched);
0853 m_diag_tree->Branch("x_true_notmatched", &m_x_true_notmatched);
0854 m_diag_tree->Branch("y_true_notmatched", &m_y_true_notmatched);
0855 m_diag_tree->Branch("z_true_notmatched", &m_z_true_notmatched);
0856
0857 if (s_current != nullptr)
0858 {
0859 s_current->cd();
0860 }
0861 }
0862
0863 void TruthRecoTrackMatching::clear_branch_vectors()
0864 {
0865 m_trkid_reco_matched.clear();
0866 m_i0_reco_matched.clear();
0867 m_i1_reco_matched.clear();
0868 m_layer_reco_matched.clear();
0869 m_x_reco_matched.clear();
0870 m_y_reco_matched.clear();
0871 m_z_reco_matched.clear();
0872
0873 m_trkid_reco_notmatched.clear();
0874 m_i0_reco_notmatched.clear();
0875 m_i1_reco_notmatched.clear();
0876 m_layer_reco_notmatched.clear();
0877 m_x_reco_notmatched.clear();
0878 m_y_reco_notmatched.clear();
0879 m_z_reco_notmatched.clear();
0880
0881 m_trkid_true_matched.clear();
0882 m_i0_true_matched.clear();
0883 m_i1_true_matched.clear();
0884 m_layer_true_matched.clear();
0885 m_x_true_matched.clear();
0886 m_y_true_matched.clear();
0887 m_z_true_matched.clear();
0888
0889 m_trkid_true_notmatched.clear();
0890 m_i0_true_notmatched.clear();
0891 m_i1_true_notmatched.clear();
0892 m_layer_true_notmatched.clear();
0893 m_x_true_notmatched.clear();
0894 m_y_true_notmatched.clear();
0895 m_z_true_notmatched.clear();
0896 }
0897
0898 void TruthRecoTrackMatching::fill_tree()
0899 {
0900
0901 int cnt = 0;
0902 int itrk = 0;
0903 for (auto& trkid : m_EmbRecoMatchContainer->ids_TruthUnmatched())
0904 {
0905 m_trkid_true_notmatched.push_back(trkid);
0906 m_i0_true_notmatched.push_back(cnt);
0907 auto* track = m_TrkrTruthTrackContainer->getTruthTrack(trkid);
0908 for (auto& ckey : track->getClusters())
0909 {
0910 auto* cluster = m_TruthClusterContainer->findCluster(ckey);
0911 m_cnt_true_notmatched.push_back(itrk);
0912 Eigen::Vector3d gloc = m_ActsGeometry->getGlobalPosition(ckey, cluster);
0913 m_layer_true_notmatched.push_back(TrkrDefs::getLayer(ckey));
0914 m_x_true_notmatched.push_back(gloc[0]);
0915 m_y_true_notmatched.push_back(gloc[1]);
0916 m_z_true_notmatched.push_back(gloc[2]);
0917 ++cnt;
0918 }
0919 m_i1_true_notmatched.push_back(cnt);
0920 ++itrk;
0921 }
0922
0923
0924 cnt = 0;
0925 itrk = 0;
0926 for (auto& trkid : m_EmbRecoMatchContainer->ids_TruthMatched())
0927 {
0928 m_trkid_true_matched.push_back(trkid);
0929 m_i0_true_matched.push_back(cnt);
0930 auto* track = m_TrkrTruthTrackContainer->getTruthTrack(trkid);
0931 for (auto& ckey : track->getClusters())
0932 {
0933 auto* cluster = m_TruthClusterContainer->findCluster(ckey);
0934 m_cnt_true_matched.push_back(itrk);
0935 Eigen::Vector3d gloc = m_ActsGeometry->getGlobalPosition(ckey, cluster);
0936 m_layer_true_matched.push_back(TrkrDefs::getLayer(ckey));
0937 m_x_true_matched.push_back(gloc[0]);
0938 m_y_true_matched.push_back(gloc[1]);
0939 m_z_true_matched.push_back(gloc[2]);
0940 ++cnt;
0941 }
0942 m_i1_true_matched.push_back(cnt);
0943 ++itrk;
0944 }
0945
0946
0947 std::set<unsigned int> set_reco_matched;
0948 cnt = 0;
0949 itrk = 0;
0950 for (auto& trkid : m_EmbRecoMatchContainer->ids_RecoMatched())
0951 {
0952 set_reco_matched.insert(trkid);
0953 m_trkid_reco_matched.push_back(trkid);
0954 SvtxTrack* reco_track = m_SvtxTrackMap->get(trkid);
0955 m_i0_reco_matched.push_back(cnt);
0956
0957 for (auto reco_ckey : ClusKeyIter(reco_track))
0958 {
0959 auto* cluster = m_RecoClusterContainer->findCluster(reco_ckey);
0960 Eigen::Vector3d gloc = m_ActsGeometry->getGlobalPosition(reco_ckey, cluster);
0961 m_layer_reco_matched.push_back(TrkrDefs::getLayer(reco_ckey));
0962 m_cnt_reco_matched.push_back(itrk);
0963 m_x_reco_matched.push_back(gloc[0]);
0964 m_y_reco_matched.push_back(gloc[1]);
0965 m_z_reco_matched.push_back(gloc[2]);
0966 ++cnt;
0967 }
0968 m_i1_reco_matched.push_back(cnt);
0969 ++itrk;
0970 }
0971
0972
0973 cnt = 0;
0974 itrk = 0;
0975 for (auto& reco : *m_SvtxTrackMap)
0976 {
0977 auto trkid = reco.first;
0978 if (set_reco_matched.contains(trkid))
0979 {
0980 continue;
0981 }
0982 m_trkid_reco_notmatched.push_back(trkid);
0983 SvtxTrack* reco_track = m_SvtxTrackMap->get(trkid);
0984 m_i0_reco_notmatched.push_back(cnt);
0985 for (auto reco_ckey : ClusKeyIter(reco_track))
0986 {
0987 auto* cluster = m_RecoClusterContainer->findCluster(reco_ckey);
0988 Eigen::Vector3d gloc = m_ActsGeometry->getGlobalPosition(reco_ckey, cluster);
0989 m_layer_reco_notmatched.push_back(TrkrDefs::getLayer(reco_ckey));
0990 m_cnt_reco_notmatched.push_back(itrk);
0991 m_x_reco_notmatched.push_back(gloc[0]);
0992 m_y_reco_notmatched.push_back(gloc[1]);
0993 m_z_reco_notmatched.push_back(gloc[2]);
0994 ++cnt;
0995 }
0996 m_i1_reco_notmatched.push_back(cnt);
0997 ++itrk;
0998 }
0999 ++m_event;
1000 m_diag_tree->Fill();
1001 clear_branch_vectors();
1002 return;
1003 }