16 #include <TEfficiency.h>
37 "performance_track_finder.root",
38 const std::vector<std::string>& inputTrackSummaryFileNames =
39 {
"tracksummary_ckf.root"},
40 const std::vector<std::string>& trackSummaryFileLegends =
41 {
"CKF with reco seeds"},
42 const std::string& simParticleTreeName =
"track_finder_particles",
43 const std::string& trackSummaryTreeName =
"tracksummary_ckf",
45 double ptMin = 0.5,
double truthMatchProbMin = 0.5) {
46 gStyle->SetOptFit(0011);
47 gStyle->SetOptStat(0000);
48 gStyle->SetPadLeftMargin(0.18);
49 gStyle->SetPadRightMargin(0.05);
50 gStyle->SetPadTopMargin(0.1);
51 gStyle->SetPadBottomMargin(0.15);
52 gStyle->SetTitleSize(0.05,
"xy");
53 gStyle->SetLabelSize(0.05,
"xy");
54 gStyle->SetTitleOffset(1.,
"x");
55 gStyle->SetTitleOffset(1.5,
"y");
56 gStyle->SetNdivisions(505,
"y");
59 if (inputTrackSummaryFileNames.size() != trackSummaryFileLegends.size()) {
60 throw std::invalid_argument(
61 "Please specify the legends you want to show for all the track files");
65 TFile* particleFile = TFile::Open(inputSimParticleFileName.c_str(),
"read");
67 unsigned int nTrackFiles = inputTrackSummaryFileNames.size();
68 std::vector<TFile*> trackFiles;
69 trackFiles.reserve(nTrackFiles);
70 for (
const auto& fileName : inputTrackSummaryFileNames) {
71 trackFiles.push_back(TFile::Open(fileName.c_str(),
"read"));
76 (TTree*)particleFile->Get(simParticleTreeName.c_str()),
true);
77 std::vector<TrackSummaryReader> tReaders;
78 tReaders.reserve(nTrackFiles);
79 for (
const auto& trackFile : trackFiles) {
80 tReaders.emplace_back((TTree*)trackFile->Get(trackSummaryTreeName.c_str()),
true);
84 nEvents.reserve(nTrackFiles);
85 for (
const auto& tReader : tReaders) {
86 size_t entries = tReader.tree->GetEntries();
87 nEvents.push_back(entries);
91 std::vector<TEfficiency*> trackEff_vs_eta;
92 std::vector<TEfficiency*> fakeRate_vs_eta;
93 std::vector<TEfficiency*> duplicateRate_vs_eta;
94 std::vector<TEfficiency*> trackEff_vs_pt;
95 std::vector<TEfficiency*> fakeRate_vs_pt;
96 std::vector<TEfficiency*> duplicateRate_vs_pt;
98 for (
int i = 0;
i < nTrackFiles; ++
i) {
99 trackEff_vs_eta.push_back(
new TEfficiency(
100 Form(
"trackeff_vs_eta_%i",
i),
";Truth #eta [GeV/c];Efficiency", 40, -4, 4));
101 fakeRate_vs_eta.push_back(
new TEfficiency(
102 Form(
"fakerate_vs_eta_%i",
i),
";#eta [GeV/c];fake rate", 40, -4, 4));
103 duplicateRate_vs_eta.push_back(
new TEfficiency(
104 Form(
"duplicaterate_vs_eta_%i",
i),
";#eta [GeV/c];Duplicate rate", 40, -4, 4));
105 trackEff_vs_pt.push_back(
new TEfficiency(
106 Form(
"trackeff_vs_pt_%i",
i),
";Truth pt [GeV/c];Efficiency", 40, 0, 100));
107 fakeRate_vs_pt.push_back(
new TEfficiency(
108 Form(
"fakerate_vs_pt_%i",
i),
";pt [GeV/c];fake rate", 40, 0, 100));
109 duplicateRate_vs_pt.push_back(
new TEfficiency(
110 Form(
"duplicaterate_vs_pt_%i",
i),
";pt [GeV/c];Duplicate rate", 40, 0, 100));
114 for (
int i = 0;
i < nTrackFiles; ++
i) {
125 std::map<unsigned int, std::vector<ParticleInfo>>
particles;
128 for (
unsigned int ifile = 0; ifile < nTrackFiles; ++ifile) {
129 std::cout <<
"Processing track file: " << inputTrackSummaryFileNames[ifile]
133 std::map<uint64_t, std::vector<RecoTrackInfo>> matchedParticles;
136 for (
size_t i = 0;
i < nEvents[ifile]; ++
i) {
138 std::cout <<
"Processed events: " <<
i << std::endl;
142 tReaders[ifile].getEntry(
i);
146 auto it = particles.find(
i);
147 if (
it == particles.end()) {
148 particles.emplace(
i, pReader.getParticles(
i));
154 for (
size_t j = 0;
j < tReaders[ifile].nStates->size(); ++
j) {
155 bool hasFittedParameters = tReaders[ifile].hasFittedParams->at(
j);
156 auto nMeasurements = tReaders[ifile].nMeasurements->at(
j);
157 auto nOutliers = tReaders[ifile].nOutliers->at(
j);
158 auto nHoles = tReaders[ifile].nHoles->at(
j);
159 auto theta = tReaders[ifile].eTHETA_fit->at(
j);
160 auto qop = tReaders[ifile].eQOP_fit->at(
j);
161 auto pt = std::abs(1 / qop) * std::sin(
theta);
162 auto eta = std::atanh(std::cos(
theta));
163 auto nMajorityHits = tReaders[ifile].nMajorityHits->at(
j);
164 auto majorityParticleId = tReaders[ifile].majorityParticleId->at(
j);
168 if ((!hasFittedParameters) or nMeasurements < nMeasurementsMin or
174 if (nMajorityHits * 1. / nMeasurements >= truthMatchProbMin) {
175 matchedParticles[majorityParticleId].push_back(
176 {
eta,
pt, nMajorityHits, nMeasurements});
177 fakeRate_vs_eta[ifile]->Fill(
false,
eta);
178 fakeRate_vs_pt[ifile]->Fill(
false,
pt);
180 fakeRate_vs_eta[ifile]->Fill(
true,
eta);
181 fakeRate_vs_pt[ifile]->Fill(
true,
pt);
189 for (
auto& [
id, matchedTracks] : matchedParticles) {
192 std::sort(matchedTracks.begin(), matchedTracks.end(),
206 for (
size_t k = 0;
k < matchedTracks.size(); ++
k) {
207 auto eta = matchedTracks[
k].eta;
208 auto pt = matchedTracks[
k].pt;
210 duplicateRate_vs_eta[ifile]->Fill(
false,
eta);
211 duplicateRate_vs_pt[ifile]->Fill(
false,
pt);
213 duplicateRate_vs_eta[ifile]->Fill(
true,
eta);
214 duplicateRate_vs_pt[ifile]->Fill(
true,
pt);
222 for (
const auto&
particle : particles[
i]) {
226 if (nHits < nHitsMin or
pt < ptMin) {
232 auto ip = matchedParticles.find(
id);
233 if (ip != matchedParticles.end()) {
234 trackEff_vs_eta[ifile]->Fill(
true,
eta);
235 trackEff_vs_pt[ifile]->Fill(
true,
pt);
237 trackEff_vs_eta[ifile]->Fill(
false,
eta);
238 trackEff_vs_pt[ifile]->Fill(
false,
pt);
242 matchedParticles.clear();
246 std::cout <<
"All good. Now plotting..." << std::endl;
249 std::vector<TLegend*> legs;
250 for (
int i = 0; i < 6; ++
i) {
251 TLegend* legend =
new TLegend(0.4, 0.8, 0.9, 0.9);
252 legend->SetBorderSize(0);
253 legend->SetFillStyle(0);
254 legend->SetTextFont(42);
255 legs.push_back(legend);
258 for (
int i = 0; i < nTrackFiles; ++
i) {
259 legs[0]->AddEntry(trackEff_vs_eta[i],
260 Form(
"%s", trackSummaryFileLegends[i].c_str()),
"lp");
261 legs[1]->AddEntry(fakeRate_vs_eta[i],
262 Form(
"%s", trackSummaryFileLegends[i].c_str()),
"lp");
263 legs[2]->AddEntry(duplicateRate_vs_eta[i],
264 Form(
"%s", trackSummaryFileLegends[i].c_str()),
"lp");
265 legs[3]->AddEntry(trackEff_vs_pt[i],
266 Form(
"%s", trackSummaryFileLegends[i].c_str()),
"lp");
267 legs[4]->AddEntry(fakeRate_vs_pt[i],
268 Form(
"%s", trackSummaryFileLegends[i].c_str()),
"lp");
269 legs[5]->AddEntry(duplicateRate_vs_pt[i],
270 Form(
"%s", trackSummaryFileLegends[i].c_str()),
"lp");
274 TCanvas* c1 =
new TCanvas(
"recoPerf",
" ", 1500, 800);
277 float scaleRangeMax = 1.15;
278 for (
int i = 0; i < nTrackFiles; ++
i) {
281 trackEff_vs_eta[
i]->Draw(mode.c_str());
282 if (i == nTrackFiles - 1) {
288 fakeRate_vs_eta[
i]->Draw(mode.c_str());
289 if (i == nTrackFiles - 1) {
295 duplicateRate_vs_eta[
i]->Draw(mode.c_str());
296 if (i == nTrackFiles - 1) {
302 trackEff_vs_pt[
i]->Draw(mode.c_str());
303 if (i == nTrackFiles - 1) {
309 fakeRate_vs_pt[
i]->Draw(mode.c_str());
310 if (i == nTrackFiles - 1) {
316 duplicateRate_vs_pt[
i]->Draw(mode.c_str());
317 if (i == nTrackFiles - 1) {