Skip to content

feat: expose PlotTool configs in .py, add per-layer particleId to tree#5530

Draft
altsybee wants to merge 2 commits into
acts-project:mainfrom
altsybee:main
Draft

feat: expose PlotTool configs in .py, add per-layer particleId to tree#5530
altsybee wants to merge 2 commits into
acts-project:mainfrom
altsybee:main

Conversation

@altsybee

@altsybee altsybee commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

This PR makes two (largely independent) improvements to the ActsExamples I/O and performance QA code:

  1. Expose configurations of the plotting tools (EffPlotToolConfig, ResPlotToolConfig etc.) in the reconstruction.py, so binning, pT/eta ranges and other plotting parameters can be configured from .py steering scripts ("full_chain.py") instead of being hard-coded in C++. A small example is added to full_chain_odd.py.

Also, truthPtRangesForEta and truthAbsEtaRangesForPt from EffPlotToolConfig are now exposed to the python level and can be changed in .py scripts; a log-pT variant of the efficiency-vs-pT plots is added.

  1. Add a per-measurement truth particleId branch to the track summary tree, allowing each measurement on a track to be linked back to the truth particle that produced it (e.g. for per-layer particle-identity studies).

@github-actions github-actions Bot added the Component - Examples Affects the Examples module label Jun 1, 2026
@github-actions github-actions Bot added this to the next milestone Jun 1, 2026
@sonarqubecloud

sonarqubecloud Bot commented Jun 1, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

📊: Physics performance monitoring for ec64f27

Full contents

physmon summary

Comment on lines +148 to +153
/// The particle id of the truth particle that left each measurement.
/// Outer: one entry per track. Inner: one entry per measurement on
/// that track, ordered identically to m_measurementVolume /
/// m_measurementLayer (reverse state order). Sentinel value 0 means
/// no truth link or no truth inputs configured.
std::vector<std::vector<std::uint64_t>> m_measurementParticleId;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fear this gets a bit into the direction of the RootTrackStatesWriter which I would rather not duplicate in this writer

Comment on lines +46 to +80
namespace {
/// Tiebreaker for assigning a single particleId to a measurement.
/// 1) Prefer the track's majority particle if any contributing sim hit
/// matches it.
/// 2) Otherwise fall back to the sim hit with the largest deposited
/// energy. Ties broken by first occurrence.
/// Returns 0 if the range is empty.
template <typename Range>
std::uint64_t pickParticleId(const Range& simHitIndices,
const ActsExamples::SimHitContainer& simHits,
const ActsExamples::SimBarcode& majorityParticleId,
bool haveMajorityParticleId) {
// Rule 1: prefer the majority particle if any contributor matches.
if (haveMajorityParticleId) {
for (const auto& [measIdx, simHitIdx] : simHitIndices) {
const auto& simHit = *simHits.nth(simHitIdx);
if (simHit.particleId() == majorityParticleId) {
return static_cast<std::uint64_t>(majorityParticleId.hash());
}
}
}
// Rule 2: fall back to the highest-deposit hit.
std::uint64_t bestId = 0;
double bestDeposit = -std::numeric_limits<double>::infinity();
for (const auto& [measIdx, simHitIdx] : simHitIndices) {
const auto& simHit = *simHits.nth(simHitIdx);
const double dep = simHit.depositedEnergy();
if (dep > bestDeposit) {
bestDeposit = dep;
bestId = static_cast<std::uint64_t>(simHit.particleId().hash());
}
}
return bestId;
}
} // namespace

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems like an alternative approach to truth matching which was extracted into TrackTruthMatcher some time ago to be consistent across all writers. I would discourage us to split this logic again. So I would rather upstream this there but also check against what #5515 is doing

Comment on lines +27 to +38
# Resolution Plots
ResPlotToolConfig = acts.examples.root.ResPlotToolConfig()
# Duplication Plots
DuplicationPlotToolConfig = acts.examples.root.DuplicationPlotToolConfig()
# Efficiency Plots
EffPlotToolConfig = acts.examples.root.EffPlotToolConfig()
# Fake rate Plots
FakePlotToolConfig = acts.examples.root.FakePlotToolConfig()
# TrackQuality Plots
TrackQualityPlotToolConfig = acts.examples.root.TrackQualityPlotToolConfig()
# Track Summary Plots
TrackSummaryPlotToolConfig = acts.examples.root.TrackSummaryPlotToolConfig()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the python scrips are already messy, I fear adding global variables will hurt this even further. I would either use custom addAlgorithm functions on the caller side with the correct params or pass them through names arguments on the high-level add* functions

@andiwand andiwand marked this pull request as draft June 2, 2026 15:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Component - Examples Affects the Examples module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants