Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Rework particle selection in Examples #3742

Merged
merged 9 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions CI/physmon/workflows/physmon_trackfinding_1muon.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
EtaConfig,
PhiConfig,
ParticleConfig,
ParticleSelectorConfig,
addFatras,
addDigitization,
)

from acts.examples.reconstruction import (
addSeeding,
TruthSeedRanges,
ParticleSmearingSigmas,
SeedFinderConfigArg,
SeedFinderOptionsArg,
Expand Down Expand Up @@ -72,6 +72,11 @@ def run_ckf_tracking(label, seeding):
setup.field,
enableInteractions=True,
rnd=rnd,
postSelectParticles=ParticleSelectorConfig(
pt=(0.9 * u.GeV, None),
measurements=(9, None),
removeNeutral=True,
),
)

addDigitization(
Expand All @@ -86,7 +91,6 @@ def run_ckf_tracking(label, seeding):
s,
setup.trackingGeometry,
setup.field,
TruthSeedRanges(pt=(500 * u.MeV, None), nHits=(9, None)),
ParticleSmearingSigmas( # only used by SeedingAlgorithm.TruthSmeared
# zero eveything so the CKF has a chance to find the measurements
d0=0,
Expand Down Expand Up @@ -134,7 +138,7 @@ def run_ckf_tracking(label, seeding):
setup.trackingGeometry,
setup.field,
TrackSelectorConfig(
pt=(500 * u.MeV, None),
pt=(0.9 * u.GeV, None),
loc0=(-4.0 * u.mm, 4.0 * u.mm),
nMeasurementsMin=6,
maxHoles=2,
Expand Down
10 changes: 7 additions & 3 deletions CI/physmon/workflows/physmon_trackfinding_4muon_50vertices.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
EtaConfig,
PhiConfig,
ParticleConfig,
ParticleSelectorConfig,
addFatras,
addDigitization,
)
from acts.examples.reconstruction import (
addSeeding,
TruthSeedRanges,
SeedFinderConfigArg,
SeedFinderOptionsArg,
SeedingAlgorithm,
Expand Down Expand Up @@ -69,6 +69,11 @@
setup.trackingGeometry,
setup.field,
rnd=rnd,
postSelectParticles=ParticleSelectorConfig(
pt=(0.9 * u.GeV, None),
andiwand marked this conversation as resolved.
Show resolved Hide resolved
measurements=(9, None),
removeNeutral=True,
),
)

addDigitization(
Expand All @@ -83,7 +88,6 @@
s,
setup.trackingGeometry,
setup.field,
TruthSeedRanges(pt=(500.0 * u.MeV, None), nHits=(9, None)),
SeedFinderConfigArg(
r=(33 * u.mm, 200 * u.mm),
deltaR=(1 * u.mm, 60 * u.mm),
Expand Down Expand Up @@ -116,7 +120,7 @@
setup.trackingGeometry,
setup.field,
TrackSelectorConfig(
pt=(500 * u.MeV, None),
pt=(0.9 * u.GeV, None),
loc0=(-4.0 * u.mm, 4.0 * u.mm),
nMeasurementsMin=6,
maxHoles=2,
Expand Down
7 changes: 5 additions & 2 deletions CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
)
from acts.examples.reconstruction import (
addSeeding,
TruthSeedRanges,
SeedFinderConfigArg,
SeedFinderOptionsArg,
SeedingAlgorithm,
Expand Down Expand Up @@ -68,6 +67,11 @@
rho=(0.0, 24 * u.mm),
absZ=(0.0, 1.0 * u.m),
),
postSelectParticles=ParticleSelectorConfig(
pt=(0.5 * u.GeV, None),
measurements=(9, None),
removeNeutral=True,
),
)

addDigitization(
Expand All @@ -82,7 +86,6 @@
s,
setup.trackingGeometry,
setup.field,
TruthSeedRanges(pt=(500.0 * u.MeV, None), nHits=(9, None)),
SeedFinderConfigArg(
r=(33 * u.mm, 200 * u.mm),
deltaR=(1 * u.mm, 60 * u.mm),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,16 @@ ActsExamples::ParticleSelector::ParticleSelector(const Config& config,
if (m_cfg.outputParticles.empty()) {
throw std::invalid_argument("Missing output particles collection");
}
if (!m_cfg.outputParticlesFinal.empty() &&
m_cfg.inputParticlesFinal.empty()) {
throw std::invalid_argument(
"Output final particles collection requires input final particles");
}

m_inputParticles.initialize(m_cfg.inputParticles);
m_inputParticlesFinal.maybeInitialize(m_cfg.inputParticlesFinal);
m_outputParticles.initialize(m_cfg.outputParticles);
m_outputParticlesFinal.maybeInitialize(m_cfg.outputParticlesFinal);

ACTS_DEBUG("selection particle rho [" << m_cfg.rhoMin << "," << m_cfg.rhoMax
<< ")");
Expand All @@ -52,29 +59,15 @@ ActsExamples::ParticleSelector::ParticleSelector(const Config& config,
ACTS_DEBUG("remove charged particles " << m_cfg.removeCharged);
ACTS_DEBUG("remove neutral particles " << m_cfg.removeNeutral);
ACTS_DEBUG("remove secondary particles " << m_cfg.removeSecondaries);

// We only initialize this if we actually select on this
if (m_cfg.measurementsMin > 0 ||
m_cfg.measurementsMax < std::numeric_limits<std::size_t>::max()) {
m_inputMap.initialize(m_cfg.inputMeasurementParticlesMap);
ACTS_DEBUG("selection particle number of measurements ["
<< m_cfg.measurementsMin << "," << m_cfg.measurementsMax << ")");
}
}

ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute(
const AlgorithmContext& ctx) const {
using ParticlesMeasurmentMap =
boost::container::flat_multimap<ActsFatras::Barcode, Index>;

// prepare input/ output types
const auto& inputParticles = m_inputParticles(ctx);

// Make global particles measurement map if necessary
std::optional<ParticlesMeasurmentMap> particlesMeasMap;
if (m_inputMap.isInitialized()) {
particlesMeasMap = invertIndexMultimap(m_inputMap(ctx));
}
const SimParticleContainer& inputParticles = m_inputParticles(ctx);
const SimParticleContainer& inputParticlesFinal =
(m_inputParticlesFinal.isInitialized()) ? m_inputParticlesFinal(ctx)
: inputParticles;

std::size_t nInvalidCharge = 0;
std::size_t nInvalidMeasurementCount = 0;
Expand All @@ -96,17 +89,14 @@ ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute(

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

// default valid measurement count to true and only change if we have loaded
// the measurement particles map
bool validMeasurementCount = true;
if (particlesMeasMap) {
auto [b, e] = particlesMeasMap->equal_range(p.particleId());
if (auto finalParticleIt = inputParticlesFinal.find(p.particleId());
finalParticleIt != inputParticlesFinal.end()) {
validMeasurementCount =
within(static_cast<std::size_t>(std::distance(b, e)),
m_cfg.measurementsMin, m_cfg.measurementsMax);

ACTS_VERBOSE("Found " << std::distance(b, e) << " measurements for "
<< p.particleId());
within(finalParticleIt->numberOfHits(), m_cfg.measurementsMin,
m_cfg.measurementsMax);
} else {
ACTS_WARNING("No final particle found for " << p.particleId());
}

nInvalidMeasurementCount +=
Expand Down Expand Up @@ -136,14 +126,30 @@ ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute(
SimParticleContainer outputParticles;
outputParticles.reserve(inputParticles.size());

SimParticleContainer outputParticlesFinal;
if (m_outputParticlesFinal.isInitialized()) {
outputParticlesFinal.reserve(inputParticles.size());
}

// copy selected particles
for (const auto& inputParticle : inputParticles) {
if (isValidParticle(inputParticle)) {
// the input parameters should already be
outputParticles.insert(outputParticles.end(), inputParticle);
if (!isValidParticle(inputParticle)) {
continue;
}

outputParticles.insert(outputParticles.end(), inputParticle);

if (m_outputParticlesFinal.isInitialized()) {
if (auto particleFinalIt =
inputParticlesFinal.find(inputParticle.particleId());
particleFinalIt != inputParticlesFinal.end()) {
outputParticlesFinal.insert(outputParticlesFinal.end(),
*particleFinalIt);
}
}
}
outputParticles.shrink_to_fit();
outputParticlesFinal.shrink_to_fit();

ACTS_DEBUG("event " << ctx.eventNumber << " selected "
<< outputParticles.size() << " from "
Expand All @@ -153,5 +159,9 @@ ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute(
<< nInvalidMeasurementCount);

m_outputParticles(ctx, std::move(outputParticles));
if (m_outputParticlesFinal.isInitialized()) {
m_outputParticlesFinal(ctx, std::move(outputParticlesFinal));
}

return ProcessCode::SUCCESS;
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@ class ParticleSelector final : public IAlgorithm {
struct Config {
/// The input particles collection.
std::string inputParticles;
/// Input measurement particles map (Optional)
std::string inputMeasurementParticlesMap;
/// Optional. The input final state particles collection.
/// If provided, this will be used to access the number of measurements.
std::string inputParticlesFinal;
/// The output particles collection.
std::string outputParticles;
/// Optional. The output final state particles collection.
std::string outputParticlesFinal;

// Minimum/maximum distance from the origin in the transverse plane.
double rhoMin = 0;
double rhoMax = std::numeric_limits<double>::infinity();
Expand Down Expand Up @@ -79,11 +83,13 @@ class ParticleSelector final : public IAlgorithm {
Config m_cfg;

ReadDataHandle<SimParticleContainer> m_inputParticles{this, "InputParticles"};
ReadDataHandle<IndexMultimap<ActsFatras::Barcode>> m_inputMap{
this, "InputMeasurementParticlesMap"};
ReadDataHandle<SimParticleContainer> m_inputParticlesFinal{
this, "InputParticlesFinal"};

WriteDataHandle<SimParticleContainer> m_outputParticles{this,
"OutputParticles"};
WriteDataHandle<SimParticleContainer> m_outputParticlesFinal{
this, "OutputParticlesFinal"};
};

} // namespace ActsExamples
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class RootParticleWriter final : public WriterT<SimParticleContainer> {
std::string inputParticles;
/// Optional. If given, the the energy loss and traversed material is
/// computed and written.
std::string inputFinalParticles;
std::string inputParticlesFinal;
/// Path to the output file.
std::string filePath;
/// Output file access mode.
Expand Down Expand Up @@ -74,8 +74,8 @@ class RootParticleWriter final : public WriterT<SimParticleContainer> {
private:
Config m_cfg;

ReadDataHandle<SimParticleContainer> m_inputFinalParticles{
this, "InputFinalParticles"};
ReadDataHandle<SimParticleContainer> m_inputParticlesFinal{
this, "InputParticlesFinal"};

std::mutex m_writeMutex;

Expand Down
8 changes: 4 additions & 4 deletions Examples/Io/Root/src/RootParticleWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ ActsExamples::RootParticleWriter::RootParticleWriter(
throw std::invalid_argument("Missing tree name");
}

m_inputFinalParticles.maybeInitialize(m_cfg.inputFinalParticles);
m_inputParticlesFinal.maybeInitialize(m_cfg.inputParticlesFinal);

// open root file and create the tree
m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str());
Expand Down Expand Up @@ -73,7 +73,7 @@ ActsExamples::RootParticleWriter::RootParticleWriter(
m_outputTree->Branch("generation", &m_generation);
m_outputTree->Branch("sub_particle", &m_subParticle);

if (m_inputFinalParticles.isInitialized()) {
if (m_inputParticlesFinal.isInitialized()) {
m_outputTree->Branch("e_loss", &m_eLoss);
m_outputTree->Branch("total_x0", &m_pathInX0);
m_outputTree->Branch("total_l0", &m_pathInL0);
Expand Down Expand Up @@ -102,8 +102,8 @@ ActsExamples::ProcessCode ActsExamples::RootParticleWriter::finalize() {
ActsExamples::ProcessCode ActsExamples::RootParticleWriter::writeT(
const AlgorithmContext& ctx, const SimParticleContainer& particles) {
const SimParticleContainer* finalParticles = nullptr;
if (m_inputFinalParticles.isInitialized()) {
finalParticles = &m_inputFinalParticles(ctx);
if (m_inputParticlesFinal.isInitialized()) {
finalParticles = &m_inputParticlesFinal(ctx);
}

// ensure exclusive access to tree/file while writing
Expand Down
Loading
Loading