Skip to content

Commit

Permalink
fix: Distinguish between hits and measurements in ParticleSelector
Browse files Browse the repository at this point in the history
…in Examples (#3947)

This clears out an oversight in a previous PR #3742 where I replaced numbers of measurements with number of hits. This number can be different and should not be confused.

I add an optional input for the particle to measurement map which is then queried if present and used for the number of measurement cuts.

blocked by:
- #3944

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

## Release Notes

- **New Features**
  - Enhanced particle selection with new configuration options for minimum and maximum hit counts.
  - Updated particle selection criteria to focus on hit counts instead of measurement counts.

- **Bug Fixes**
  - Improved validation checks for input measurements to ensure proper initialization.

- **Documentation**
  - Updated comments and documentation to reflect changes in parameter naming from "measurements" to "hits."

- **Tests**
  - Adjusted test cases to align with the new parameter naming conventions.

- **Chores**
  - Minor code formatting and organization improvements throughout various scripts.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
andiwand authored Dec 6, 2024
1 parent 12ea68c commit 03315f8
Show file tree
Hide file tree
Showing 20 changed files with 69 additions and 28 deletions.
2 changes: 1 addition & 1 deletion CI/physmon/workflows/physmon_trackfinding_1muon.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def run_ckf_tracking(label, seeding):
rnd=rnd,
postSelectParticles=ParticleSelectorConfig(
pt=(0.9 * u.GeV, None),
measurements=(9, None),
hits=(9, None),
removeNeutral=True,
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
rnd=rnd,
postSelectParticles=ParticleSelectorConfig(
pt=(0.9 * u.GeV, None),
measurements=(9, None),
hits=(9, None),
removeNeutral=True,
),
)
Expand Down
2 changes: 1 addition & 1 deletion CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
),
postSelectParticles=ParticleSelectorConfig(
pt=(0.5 * u.GeV, None),
measurements=(9, None),
hits=(9, None),
removeNeutral=True,
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,19 @@

#include "ActsExamples/TruthTracking/ParticleSelector.hpp"

#include "Acts/Definitions/Common.hpp"
#include "Acts/Utilities/VectorHelpers.hpp"
#include "ActsExamples/EventData/Index.hpp"
#include "ActsExamples/EventData/SimParticle.hpp"
#include "ActsExamples/Framework/AlgorithmContext.hpp"

#include <ostream>
#include <stdexcept>
#include <utility>

ActsExamples::ParticleSelector::ParticleSelector(const Config& config,
Acts::Logging::Level level)
namespace ActsExamples {

ParticleSelector::ParticleSelector(const Config& config,
Acts::Logging::Level level)
: IAlgorithm("ParticleSelector", level), m_cfg(config) {
if (m_cfg.inputParticles.empty()) {
throw std::invalid_argument("Missing input particles collection");
Expand All @@ -28,8 +30,17 @@ ActsExamples::ParticleSelector::ParticleSelector(const Config& config,
}

m_inputParticles.initialize(m_cfg.inputParticles);
m_inputParticleMeasurementsMap.maybeInitialize(
m_cfg.inputParticleMeasurementsMap);
m_outputParticles.initialize(m_cfg.outputParticles);

if (!m_inputParticleMeasurementsMap.isInitialized() &&
(m_cfg.measurementsMin > 0 ||
m_cfg.measurementsMax < std::numeric_limits<std::size_t>::max())) {
throw std::invalid_argument(
"Measurement-based cuts require the inputMeasurementParticlesMap");
}

ACTS_DEBUG("selection particle rho [" << m_cfg.rhoMin << "," << m_cfg.rhoMax
<< ")");
ACTS_DEBUG("selection particle |z| [" << m_cfg.absZMin << "," << m_cfg.absZMax
Expand All @@ -46,6 +57,8 @@ ActsExamples::ParticleSelector::ParticleSelector(const Config& config,
<< ")");
ACTS_DEBUG("selection particle m [" << m_cfg.mMin << "," << m_cfg.mMax
<< ")");
ACTS_DEBUG("selection particle hits [" << m_cfg.hitsMin << ","
<< m_cfg.hitsMax << ")");
ACTS_DEBUG("selection particle measurements ["
<< m_cfg.measurementsMin << "," << m_cfg.measurementsMax << ")");
ACTS_DEBUG("remove charged particles " << m_cfg.removeCharged);
Expand All @@ -59,12 +72,18 @@ ActsExamples::ParticleSelector::ParticleSelector(const Config& config,
<< m_cfg.maxPrimaryVertexId << ")");
}

ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute(
const AlgorithmContext& ctx) const {
ProcessCode ParticleSelector::execute(const AlgorithmContext& ctx) const {
// prepare input/ output types
const SimParticleContainer& inputParticles = m_inputParticles(ctx);

const static InverseMultimap<SimBarcode> emptyMeasurementParticlesMap;
const InverseMultimap<SimBarcode>& inputMeasurementParticlesMap =
m_inputParticleMeasurementsMap.isInitialized()
? m_inputParticleMeasurementsMap(ctx)
: emptyMeasurementParticlesMap;

std::size_t nInvalidCharge = 0;
std::size_t nInvalidHitCount = 0;
std::size_t nInvalidMeasurementCount = 0;

// helper functions to select tracks
Expand All @@ -87,9 +106,14 @@ ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute(

nInvalidCharge += static_cast<std::size_t>(!validCharge);

bool validMeasurementCount =
within(p.numberOfHits(), m_cfg.measurementsMin, m_cfg.measurementsMax);
const bool validHitCount =
within(p.numberOfHits(), m_cfg.hitsMin, m_cfg.hitsMax);
nInvalidHitCount += static_cast<std::size_t>(!validHitCount);

const std::size_t measurementCount =
inputMeasurementParticlesMap.count(p.particleId());
const bool validMeasurementCount =
within(measurementCount, m_cfg.measurementsMin, m_cfg.measurementsMax);
nInvalidMeasurementCount +=
static_cast<std::size_t>(!validMeasurementCount);

Expand All @@ -103,7 +127,7 @@ ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute(
}

return validPdg && validCharge && validSecondary && validPrimaryVertexId &&
validMeasurementCount &&
validHitCount && validMeasurementCount &&
within(p.transverseMomentum(), m_cfg.ptMin, m_cfg.ptMax) &&
within(std::abs(eta), m_cfg.absEtaMin, m_cfg.absEtaMax) &&
within(eta, m_cfg.etaMin, m_cfg.etaMax) &&
Expand Down Expand Up @@ -132,10 +156,13 @@ ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute(
<< outputParticles.size() << " from "
<< inputParticles.size() << " particles");
ACTS_DEBUG("filtered out because of charge: " << nInvalidCharge);
ACTS_DEBUG("filtered out because of hit count: " << nInvalidHitCount);
ACTS_DEBUG("filtered out because of measurement count: "
<< nInvalidMeasurementCount);

m_outputParticles(ctx, std::move(outputParticles));

return ProcessCode::SUCCESS;
}

} // namespace ActsExamples
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#pragma once

#include "Acts/Utilities/Logger.hpp"
#include "ActsExamples/EventData/Index.hpp"
#include "ActsExamples/EventData/SimParticle.hpp"
#include "ActsExamples/Framework/DataHandle.hpp"
#include "ActsExamples/Framework/IAlgorithm.hpp"
Expand All @@ -26,6 +27,9 @@ class ParticleSelector final : public IAlgorithm {
struct Config {
/// The input particles collection.
std::string inputParticles;
/// (Optionally) The input particle measurements map. Only required for
/// measurement-based cuts.
std::string inputParticleMeasurementsMap;
/// The output particles collection.
std::string outputParticles;

Expand All @@ -51,7 +55,10 @@ class ParticleSelector final : public IAlgorithm {
// Rest mass cuts
double mMin = 0;
double mMax = std::numeric_limits<double>::infinity();
/// Measurement number cuts
// Hit count cuts
std::size_t hitsMin = 0;
std::size_t hitsMax = std::numeric_limits<std::size_t>::max();
// Measurement number cuts
std::size_t measurementsMin = 0;
std::size_t measurementsMax = std::numeric_limits<std::size_t>::max();
/// Remove charged particles.
Expand Down Expand Up @@ -81,6 +88,8 @@ class ParticleSelector final : public IAlgorithm {
Config m_cfg;

ReadDataHandle<SimParticleContainer> m_inputParticles{this, "InputParticles"};
ReadDataHandle<InverseMultimap<SimBarcode>> m_inputParticleMeasurementsMap{
this, "InputParticleMeasurementsMap"};

WriteDataHandle<SimParticleContainer> m_outputParticles{this,
"OutputParticles"};
Expand Down
5 changes: 4 additions & 1 deletion Examples/Python/python/acts/examples/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@
"absEta", # (min,max)
"pt", # (min,max)
"m", # (min,max)
"hits", # (min,max)
"measurements", # (min,max)
"removeCharged", # bool
"removeNeutral", # bool
"removeSecondaries", # bool
],
defaults=[(None, None)] * 9 + [None] * 3,
defaults=[(None, None)] * 10 + [None] * 3,
)


Expand Down Expand Up @@ -393,6 +394,8 @@ def addParticleSelection(
ptMax=config.pt[1],
mMin=config.m[0],
mMax=config.m[1],
hitsMin=config.hits[0],
hitsMax=config.hits[1],
measurementsMin=config.measurements[0],
measurementsMax=config.measurements[1],
removeCharged=config.removeCharged,
Expand Down
2 changes: 2 additions & 0 deletions Examples/Python/src/TruthTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ void addTruthTracking(Context& ctx) {
ACTS_PYTHON_MEMBER(mMax);
ACTS_PYTHON_MEMBER(ptMin);
ACTS_PYTHON_MEMBER(ptMax);
ACTS_PYTHON_MEMBER(hitsMin);
ACTS_PYTHON_MEMBER(hitsMax);
ACTS_PYTHON_MEMBER(measurementsMin);
ACTS_PYTHON_MEMBER(measurementsMax);
ACTS_PYTHON_MEMBER(removeCharged);
Expand Down
2 changes: 1 addition & 1 deletion Examples/Python/tests/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ def test_itk_seeding(tmp_path, trk_geo, field, assert_root_hash):
postSelectParticles=ParticleSelectorConfig(
pt=(0.9 * u.GeV, None),
eta=(-4, 4),
measurements=(9, None),
hits=(9, None),
removeNeutral=True,
),
)
Expand Down
2 changes: 1 addition & 1 deletion Examples/Scripts/Optimization/ckf.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def runCKFTracks(
rnd=rnd,
postSelectParticles=ParticleSelectorConfig(
pt=(0.5 * u.GeV, None),
measurements=(9, None),
hits=(9, None),
removeNeutral=True,
),
)
Expand Down
2 changes: 1 addition & 1 deletion Examples/Scripts/Python/ckf_tracks.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def runCKFTracks(
rnd=rnd,
postSelectParticles=ParticleSelectorConfig(
pt=(0.5 * u.GeV, None),
measurements=(9, None),
hits=(9, None),
removeNeutral=True,
),
)
Expand Down
2 changes: 1 addition & 1 deletion Examples/Scripts/Python/full_chain_itk.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
postSelectParticles=ParticleSelectorConfig(
pt=(1.0 * u.GeV, None),
eta=(-4.0, 4.0),
measurements=(9, None),
hits=(9, None),
removeNeutral=True,
),
outputDirRoot=outputDir,
Expand Down
2 changes: 1 addition & 1 deletion Examples/Scripts/Python/full_chain_itk_Gbts.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
postSelectParticles=ParticleSelectorConfig(
pt=(1.0 * u.GeV, None),
eta=(-4.0, 4.0),
measurements=(9, None),
hits=(9, None),
removeNeutral=True,
),
outputDirRoot=outputDir,
Expand Down
4 changes: 2 additions & 2 deletions Examples/Scripts/Python/full_chain_odd.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@
postSelectParticles=ParticleSelectorConfig(
pt=(1.0 * u.GeV, None),
eta=(-3.0, 3.0),
measurements=(9, None),
hits=(9, None),
removeNeutral=True,
),
outputDirRoot=outputDir if args.output_root else None,
Expand Down Expand Up @@ -306,7 +306,7 @@
postSelectParticles=ParticleSelectorConfig(
pt=(1.0 * u.GeV, None),
eta=(-3.0, 3.0),
measurements=(9, None),
hits=(9, None),
removeNeutral=True,
),
enableInteractions=True,
Expand Down
4 changes: 2 additions & 2 deletions Examples/Scripts/Python/full_chain_odd_LRT.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@
postSelectParticles=ParticleSelectorConfig(
pt=(1.0 * u.GeV, None),
eta=(-3.0, 3.0),
measurements=(9, None),
hits=(9, None),
removeNeutral=True,
),
outputDirRoot=outputDir if args.output_root else None,
Expand All @@ -300,7 +300,7 @@
postSelectParticles=ParticleSelectorConfig(
pt=(1.0 * u.GeV, None),
eta=(-3.0, 3.0),
measurements=(9, None),
hits=(9, None),
removeNeutral=True,
),
enableInteractions=True,
Expand Down
2 changes: 1 addition & 1 deletion Examples/Scripts/Python/full_chain_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ def full_chain(args):
postSelectParticles = ParticleSelectorConfig(
pt=(ptMin, None),
eta=etaRange if not args.generic_detector else (None, None),
measurements=(9, None),
hits=(9, None),
removeNeutral=True,
)

Expand Down
2 changes: 1 addition & 1 deletion Examples/Scripts/Python/hashing_seeding.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ def runHashingSeeding(
postSelectParticles=ParticleSelectorConfig(
pt=(1.0 * u.GeV, None),
eta=(-eta, eta),
measurements=(9, None),
hits=(9, None),
removeNeutral=True,
),
enableInteractions=True,
Expand Down
2 changes: 1 addition & 1 deletion Examples/Scripts/Python/seeding.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def runSeeding(
postSelectParticles=ParticleSelectorConfig(
pt=(1.0 * u.GeV, None),
eta=(-2.5, 2.5),
measurements=(9, None),
hits=(9, None),
removeNeutral=True,
),
)
Expand Down
2 changes: 1 addition & 1 deletion Examples/Scripts/Python/truth_tracking_gsf.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def runTruthTrackingGsf(
enableInteractions=True,
postSelectParticles=ParticleSelectorConfig(
pt=(0.9 * u.GeV, None),
measurements=(7, None),
hits=(7, None),
removeNeutral=True,
removeSecondaries=True,
),
Expand Down
2 changes: 1 addition & 1 deletion Examples/Scripts/Python/truth_tracking_gx2f.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def runTruthTrackingGx2f(
enableInteractions=True,
postSelectParticles=ParticleSelectorConfig(
pt=(0.9 * u.GeV, None),
measurements=(7, None),
hits=(7, None),
removeNeutral=True,
removeSecondaries=True,
),
Expand Down
2 changes: 1 addition & 1 deletion Examples/Scripts/Python/truth_tracking_kalman.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def runTruthTrackingKalman(
enableInteractions=True,
postSelectParticles=ParticleSelectorConfig(
pt=(0.9 * u.GeV, None),
measurements=(7, None),
hits=(7, None),
removeNeutral=True,
removeSecondaries=True,
),
Expand Down

0 comments on commit 03315f8

Please sign in to comment.