Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SeedingPerformanceWriter.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SeedingPerformanceWriter.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2020-2021 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
16 
17 #include <cstddef>
18 #include <ostream>
19 #include <stdexcept>
20 #include <unordered_map>
21 #include <utility>
22 #include <vector>
23 
24 #include <TFile.h>
25 
26 namespace ActsExamples {
27 struct AlgorithmContext;
28 } // namespace ActsExamples
29 
33  : WriterT(config.inputSeeds, "SeedingPerformanceWriter", level),
34  m_cfg(std::move(config)),
35  m_effPlotTool(m_cfg.effPlotToolConfig, level),
36  m_duplicationPlotTool(m_cfg.duplicationPlotToolConfig, level) {
37  if (m_cfg.inputMeasurementParticlesMap.empty()) {
38  throw std::invalid_argument("Missing hit-particles map input collection");
39  }
40  if (m_cfg.inputParticles.empty()) {
41  throw std::invalid_argument("Missing input particles collection");
42  }
43  if (m_cfg.filePath.empty()) {
44  throw std::invalid_argument("Missing output filename");
45  }
46 
49 
50  // the output file can not be given externally since TFile accesses to the
51  // same file from multiple threads are unsafe.
52  // must always be opened internally
53  auto path = m_cfg.filePath;
54  m_outputFile = TFile::Open(path.c_str(), m_cfg.fileMode.c_str());
55  if (m_outputFile == nullptr) {
56  throw std::invalid_argument("Could not open '" + path + "'");
57  }
58  // initialize the plot tools
61 }
62 
64  m_effPlotTool.clear(m_effPlotCache);
65  m_duplicationPlotTool.clear(m_duplicationPlotCache);
66  if (m_outputFile != nullptr) {
67  m_outputFile->Close();
68  }
69 }
70 
72  float eff = float(m_nTotalMatchedParticles) / m_nTotalParticles;
73  float fakeRate = float(m_nTotalSeeds - m_nTotalMatchedSeeds) / m_nTotalSeeds;
74  float duplicationRate =
75  float(m_nTotalDuplicatedParticles) / m_nTotalMatchedParticles;
76  float aveNDuplicatedSeeds =
77  float(m_nTotalMatchedSeeds - m_nTotalMatchedParticles) /
78  m_nTotalMatchedParticles;
79  float totalSeedPurity = float(m_nTotalMatchedSeeds) / m_nTotalSeeds;
80  ACTS_DEBUG("nTotalSeeds = " << m_nTotalSeeds);
81  ACTS_DEBUG("nTotalMatchedSeeds = " << m_nTotalMatchedSeeds);
82  ACTS_DEBUG("nTotalParticles = " << m_nTotalParticles);
83  ACTS_DEBUG("nTotalMatchedParticles = " << m_nTotalMatchedParticles);
84  ACTS_DEBUG("nTotalDuplicatedParticles = " << m_nTotalDuplicatedParticles);
85 
86  ACTS_INFO("Efficiency (nMatchedParticles / nAllParticles) = " << eff);
87  ACTS_INFO("Fake rate (nUnMatchedSeeds / nAllSeeds) = " << fakeRate);
88  ACTS_INFO("Total seed purity (nTotalMatchedSeeds / m_nTotalSeeds) = "
89  << totalSeedPurity);
90  ACTS_INFO(
91  "Duplication rate (nDuplicatedMatchedParticles / nMatchedParticles) = "
92  << duplicationRate);
93  ACTS_INFO(
94  "Average number of duplicated seeds ((nMatchedSeeds - nMatchedParticles) "
95  "/ nMatchedParticles) = "
96  << aveNDuplicatedSeeds);
97 
98  if (m_outputFile != nullptr) {
99  m_outputFile->cd();
100  m_effPlotTool.write(m_effPlotCache);
101  m_duplicationPlotTool.write(m_duplicationPlotCache);
102  ACTS_INFO("Wrote performance plots to '" << m_outputFile->GetPath() << "'");
103  }
104  return ProcessCode::SUCCESS;
105 }
106 
108  const AlgorithmContext& ctx, const SimSeedContainer& seeds) {
109  // Read truth information collections
110  const auto& particles = m_inputParticles(ctx);
111  const auto& hitParticlesMap = m_inputMeasurementParticlesMap(ctx);
112 
113  size_t nSeeds = seeds.size();
114  size_t nMatchedSeeds = 0;
115  // Map from particles to how many times they were successfully found by a seed
116  std::unordered_map<ActsFatras::Barcode, std::size_t> truthCount;
117 
118  for (size_t itrack = 0; itrack < seeds.size(); ++itrack) {
119  const auto& seed = seeds[itrack];
120  const auto track = seedToPrototrack(seed);
121  std::vector<ParticleHitCount> particleHitCounts;
122  identifyContributingParticles(hitParticlesMap, track, particleHitCounts);
123  // All hits matched to the same particle
124  if (particleHitCounts.size() == 1) {
125  auto prt = particleHitCounts.at(0);
126  auto it = truthCount.try_emplace(prt.particleId, 0u).first;
127  it->second += 1;
128  nMatchedSeeds++;
129  }
130  }
131 
132  int nMatchedParticles = 0;
133  int nDuplicatedParticles = 0;
134  // Fill the efficiency and fake rate plots
135  for (const auto& particle : particles) {
136  const auto it1 = truthCount.find(particle.particleId());
137  bool isMatched = false;
138  int nMatchedSeedsForParticle = 0;
139  if (it1 != truthCount.end()) {
140  isMatched = true;
141  nMatchedParticles++;
142  nMatchedSeedsForParticle = it1->second;
143  if (nMatchedSeedsForParticle > 1) {
144  nDuplicatedParticles++;
145  }
146  }
147  m_effPlotTool.fill(m_effPlotCache, particle, isMatched);
148  m_duplicationPlotTool.fill(m_duplicationPlotCache, particle,
149  nMatchedSeedsForParticle - 1);
150  }
151  ACTS_DEBUG("Number of seeds: " << nSeeds);
152  m_nTotalSeeds += nSeeds;
153  m_nTotalMatchedSeeds += nMatchedSeeds;
154  m_nTotalParticles += particles.size();
155  m_nTotalMatchedParticles += nMatchedParticles;
156  m_nTotalDuplicatedParticles += nDuplicatedParticles;
157 
158  return ProcessCode::SUCCESS;
159 }