Skip to content

Commit

Permalink
feat: Allow tracksummary plots on detector subparts (acts-project#4058)
Browse files Browse the repository at this point in the history
Adds some infrastructure to produce additonal plots for detector regions (specified with a list of volume ids) in the `TrackFinderPerformanceWriter`. Also adjusts some log levels to be less verbose in `DEBUG` mode.
  • Loading branch information
benjaminhuth authored and paulgessinger committed Jan 30, 2025
1 parent d3b9e6b commit bd3ff49
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ ActsExamples::ProcessCode TrackTruthMatcher::execute(
std::size_t nMajorityHits = particleHitCounts.front().hitCount;

if (!particles.contains(majorityParticleId)) {
ACTS_DEBUG(
ACTS_VERBOSE(
"The majority particle is not in the input particle collection, "
"majorityParticleId = "
<< majorityParticleId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ class TrackSummaryPlotTool {
/// @brief book the track info plots
///
/// @param trackSummaryPlotCache the cache for track info plots
void book(TrackSummaryPlotCache& trackSummaryPlotCache) const;
/// @param prefix a prefix prepended to the name, concatenation with '_'
void book(TrackSummaryPlotCache& trackSummaryPlotCache,
const std::string& prefix = "") const;

/// @brief fill reco track info w.r.t. fitted track parameters
///
Expand Down
56 changes: 35 additions & 21 deletions Examples/Framework/src/Validation/TrackSummaryPlotTool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,41 +20,55 @@ ActsExamples::TrackSummaryPlotTool::TrackSummaryPlotTool(
m_logger(Acts::getDefaultLogger("TrackSummaryPlotTool", lvl)) {}

void ActsExamples::TrackSummaryPlotTool::book(
TrackSummaryPlotTool::TrackSummaryPlotCache& trackSummaryPlotCache) const {
TrackSummaryPlotTool::TrackSummaryPlotCache& trackSummaryPlotCache,
const std::string& prefix) const {
PlotHelpers::Binning bEta = m_cfg.varBinning.at("Eta");
PlotHelpers::Binning bPt = m_cfg.varBinning.at("Pt");
PlotHelpers::Binning bNum = m_cfg.varBinning.at("Num");
ACTS_DEBUG("Initialize the histograms for track info plots");
ACTS_DEBUG("Initialize the histograms for track info plots, use prefix '"
<< prefix << "'");
auto addPrefix = [&](const std::string& name) {
return prefix.empty() ? name : prefix + "_" + name;
};
// number of track states versus eta
trackSummaryPlotCache.nStates_vs_eta = PlotHelpers::bookProf(
"nStates_vs_eta", "Number of total states vs. #eta", bEta, bNum);
trackSummaryPlotCache.nStates_vs_eta =
PlotHelpers::bookProf(addPrefix("nStates_vs_eta").c_str(),
"Number of total states vs. #eta", bEta, bNum);
// number of measurements versus eta
trackSummaryPlotCache.nMeasurements_vs_eta = PlotHelpers::bookProf(
"nMeasurements_vs_eta", "Number of measurements vs. #eta", bEta, bNum);
trackSummaryPlotCache.nMeasurements_vs_eta =
PlotHelpers::bookProf(addPrefix("nMeasurements_vs_eta").c_str(),
"Number of measurements vs. #eta", bEta, bNum);
// number of holes versus eta
trackSummaryPlotCache.nHoles_vs_eta = PlotHelpers::bookProf(
"nHoles_vs_eta", "Number of holes vs. #eta", bEta, bNum);
trackSummaryPlotCache.nHoles_vs_eta =
PlotHelpers::bookProf(addPrefix("nHoles_vs_eta").c_str(),
"Number of holes vs. #eta", bEta, bNum);
// number of outliers versus eta
trackSummaryPlotCache.nOutliers_vs_eta = PlotHelpers::bookProf(
"nOutliers_vs_eta", "Number of outliers vs. #eta", bEta, bNum);
trackSummaryPlotCache.nOutliers_vs_eta =
PlotHelpers::bookProf(addPrefix("nOutliers_vs_eta").c_str(),
"Number of outliers vs. #eta", bEta, bNum);
// number of Shared Hits versus eta
trackSummaryPlotCache.nSharedHits_vs_eta = PlotHelpers::bookProf(
"nSharedHits_vs_eta", "Number of Shared Hits vs. #eta", bEta, bNum);
trackSummaryPlotCache.nSharedHits_vs_eta =
PlotHelpers::bookProf(addPrefix("nSharedHits_vs_eta").c_str(),
"Number of Shared Hits vs. #eta", bEta, bNum);
// number of track states versus pt
trackSummaryPlotCache.nStates_vs_pt = PlotHelpers::bookProf(
"nStates_vs_pT", "Number of total states vs. pT", bPt, bNum);
trackSummaryPlotCache.nStates_vs_pt =
PlotHelpers::bookProf(addPrefix("nStates_vs_pT").c_str(),
"Number of total states vs. pT", bPt, bNum);
// number of measurements versus pt
trackSummaryPlotCache.nMeasurements_vs_pt = PlotHelpers::bookProf(
"nMeasurements_vs_pT", "Number of measurements vs. pT", bPt, bNum);
trackSummaryPlotCache.nMeasurements_vs_pt =
PlotHelpers::bookProf(addPrefix("nMeasurements_vs_pT").c_str(),
"Number of measurements vs. pT", bPt, bNum);
// number of holes versus pt
trackSummaryPlotCache.nHoles_vs_pt = PlotHelpers::bookProf(
"nHoles_vs_pT", "Number of holes vs. pT", bPt, bNum);
addPrefix("nHoles_vs_pT").c_str(), "Number of holes vs. pT", bPt, bNum);
// number of outliers versus pt
trackSummaryPlotCache.nOutliers_vs_pt = PlotHelpers::bookProf(
"nOutliers_vs_pT", "Number of outliers vs. pT", bPt, bNum);
trackSummaryPlotCache.nOutliers_vs_pt =
PlotHelpers::bookProf(addPrefix("nOutliers_vs_pT").c_str(),
"Number of outliers vs. pT", bPt, bNum);
// number of Shared Hits versus pt
trackSummaryPlotCache.nSharedHits_vs_pt = PlotHelpers::bookProf(
"nSharedHits_vs_pT", "Number of Shared Hits vs. pT", bPt, bNum);
trackSummaryPlotCache.nSharedHits_vs_pt =
PlotHelpers::bookProf(addPrefix("nSharedHits_vs_pT").c_str(),
"Number of Shared Hits vs. pT", bPt, bNum);
}

void ActsExamples::TrackSummaryPlotTool::clear(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ class TrackFinderPerformanceWriter final : public WriterT<ConstTrackContainer> {
DuplicationPlotTool::Config duplicationPlotToolConfig;
TrackSummaryPlotTool::Config trackSummaryPlotToolConfig;

/// Additional tracksummary plot tool configs for detector regions
/// Allows e.g. to do pixel/strip only plots based on a list of volumes
std::map<std::string, std::set<int>> subDetectorTrackSummaryVolumes;

/// Write additional matching details to a TTree
bool writeMatchingDetails = false;
};
Expand Down Expand Up @@ -97,6 +101,8 @@ class TrackFinderPerformanceWriter final : public WriterT<ConstTrackContainer> {
/// Plot tool for track hit info
TrackSummaryPlotTool m_trackSummaryPlotTool;
TrackSummaryPlotTool::TrackSummaryPlotCache m_trackSummaryPlotCache{};
std::map<std::string, TrackSummaryPlotTool::TrackSummaryPlotCache>
m_subDetectorSummaryCaches;

/// For optional output of the matching details
TTree* m_matchingTree{nullptr};
Expand Down
50 changes: 49 additions & 1 deletion Examples/Io/Root/src/TrackFinderPerformanceWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,19 @@ TrackFinderPerformanceWriter::TrackFinderPerformanceWriter(
m_fakeRatePlotTool.book(m_fakeRatePlotCache);
m_duplicationPlotTool.book(m_duplicationPlotCache);
m_trackSummaryPlotTool.book(m_trackSummaryPlotCache);
for (const auto& [key, _] : m_cfg.subDetectorTrackSummaryVolumes) {
m_trackSummaryPlotTool.book(m_subDetectorSummaryCaches[key], key);
}
}

TrackFinderPerformanceWriter::~TrackFinderPerformanceWriter() {
m_effPlotTool.clear(m_effPlotCache);
m_fakeRatePlotTool.clear(m_fakeRatePlotCache);
m_duplicationPlotTool.clear(m_duplicationPlotCache);
m_trackSummaryPlotTool.clear(m_trackSummaryPlotCache);
for (const auto& [key, _] : m_cfg.subDetectorTrackSummaryVolumes) {
m_trackSummaryPlotTool.clear(m_subDetectorSummaryCaches.at(key));
}
if (m_outputFile != nullptr) {
m_outputFile->Close();
}
Expand Down Expand Up @@ -131,6 +137,10 @@ ProcessCode TrackFinderPerformanceWriter::finalize() {
m_fakeRatePlotTool.write(m_fakeRatePlotCache);
m_duplicationPlotTool.write(m_duplicationPlotCache);
m_trackSummaryPlotTool.write(m_trackSummaryPlotCache);
for (const auto& [key, _] : m_cfg.subDetectorTrackSummaryVolumes) {
m_trackSummaryPlotTool.write(m_subDetectorSummaryCaches.at(key));
}

writeFloat(eff_tracks, "eff_tracks");
writeFloat(fakeRate_tracks, "fakerate_tracks");
writeFloat(duplicationRate_tracks, "duplicaterate_tracks");
Expand Down Expand Up @@ -163,14 +173,17 @@ ProcessCode TrackFinderPerformanceWriter::writeT(
// Vector of input features for neural network classification
std::vector<float> inputFeatures(3);

ACTS_DEBUG("Collect information from " << tracks.size() << " tracks");
std::size_t unmatched = 0, missingRefSurface = 0;
for (const auto& track : tracks) {
// Counting number of total trajectories
m_nTotalTracks++;

// Check if the reco track has fitted track parameters
if (!track.hasReferenceSurface()) {
ACTS_WARNING("No fitted track parameters for track, index = "
ACTS_VERBOSE("No fitted track parameters for track, index = "
<< track.index() << " tip index = " << track.tipIndex());
missingRefSurface++;
continue;
}

Expand All @@ -183,11 +196,38 @@ ProcessCode TrackFinderPerformanceWriter::writeT(
track.nOutliers(), track.nHoles(),
track.nSharedHits());

// Potentially fill other track summary caches for the given volumes
for (const auto& [key, volumes] : m_cfg.subDetectorTrackSummaryVolumes) {
ACTS_VERBOSE("Fill track summary stats for subset " << key);
std::size_t nTrackStates{}, nMeasurements{}, nOutliers{}, nHoles{},
nSharedHits{};
for (auto state : track.trackStatesReversed()) {
if (!state.hasReferenceSurface() ||
!volumes.contains(state.referenceSurface().geometryId().volume())) {
continue;
}

nTrackStates++;
nMeasurements += static_cast<std::size_t>(
state.typeFlags().test(Acts::MeasurementFlag));
nOutliers +=
static_cast<std::size_t>(state.typeFlags().test(Acts::OutlierFlag));
nHoles +=
static_cast<std::size_t>(state.typeFlags().test(Acts::HoleFlag));
nSharedHits += static_cast<std::size_t>(
state.typeFlags().test(Acts::SharedHitFlag));
}
m_trackSummaryPlotTool.fill(m_subDetectorSummaryCaches.at(key),
fittedParameters, nTrackStates, nMeasurements,
nOutliers, nHoles, nSharedHits);
}

// Get the truth matching information
auto imatched = trackParticleMatching.find(track.index());
if (imatched == trackParticleMatching.end()) {
ACTS_DEBUG("No truth matching information for this track, index = "
<< track.index() << " tip index = " << track.tipIndex());
unmatched++;
continue;
}

Expand All @@ -212,6 +252,14 @@ ProcessCode TrackFinderPerformanceWriter::writeT(
particleMatch.classification == TrackMatchClassification::Duplicate);
}

if (unmatched > 0) {
ACTS_DEBUG("No matching information found for " << unmatched << " tracks");
}
if (missingRefSurface > 0) {
ACTS_DEBUG("Reference surface was missing for " << missingRefSurface
<< " tracks");
}

// Loop over all truth particles for efficiency plots and reco details.
for (const auto& particle : particles) {
auto particleId = particle.particleId();
Expand Down
14 changes: 7 additions & 7 deletions Examples/Python/src/Output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,13 +398,13 @@ void addOutput(Context& ctx) {
trackingGeometry, outputDir, outputPrecision, writeSensitive,
writeBoundary, writeSurfaceGrid, writeLayerVolume, writePerEvent);

ACTS_PYTHON_DECLARE_WRITER(ActsExamples::TrackFinderPerformanceWriter, mex,
"TrackFinderPerformanceWriter", inputTracks,
inputParticles, inputTrackParticleMatching,
inputParticleTrackMatching, filePath, fileMode,
effPlotToolConfig, fakeRatePlotToolConfig,
duplicationPlotToolConfig,
trackSummaryPlotToolConfig, writeMatchingDetails);
ACTS_PYTHON_DECLARE_WRITER(
ActsExamples::TrackFinderPerformanceWriter, mex,
"TrackFinderPerformanceWriter", inputTracks, inputParticles,
inputTrackParticleMatching, inputParticleTrackMatching, filePath,
fileMode, effPlotToolConfig, fakeRatePlotToolConfig,
duplicationPlotToolConfig, trackSummaryPlotToolConfig,
subDetectorTrackSummaryVolumes, writeMatchingDetails);

ACTS_PYTHON_DECLARE_WRITER(
ActsExamples::RootNuclearInteractionParametersWriter, mex,
Expand Down

0 comments on commit bd3ff49

Please sign in to comment.