From fe760a7f063313108795f9874cfae453096fd088 Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Tue, 25 Aug 2026 19:49:26 -0400 Subject: [PATCH 1/8] TrackParamTruthInit: implement relaxed mode to include secondaries in B0TrackerTruthSeeds --- src/algorithms/tracking/CKFTracking.cc | 11 ++++- .../tracking/TrackParamTruthInit.cc | 42 +++++++++++++------ .../tracking/TrackParamTruthInitConfig.h | 8 ++++ .../tracking/TrackParamTruthInit_factory.h | 3 ++ src/global/tracking/tracking.cc | 31 ++++++++------ 5 files changed, 69 insertions(+), 26 deletions(-) diff --git a/src/algorithms/tracking/CKFTracking.cc b/src/algorithms/tracking/CKFTracking.cc index dfcd8eb654..8f0c1f2bfb 100644 --- a/src/algorithms/tracking/CKFTracking.cc +++ b/src/algorithms/tracking/CKFTracking.cc @@ -185,8 +185,15 @@ void CKFTracking::process(const Input& input, const Output& output) const { ++i; } - // Construct a perigee surface as the target surface - auto pSurface = Acts::Surface::makeShared(Acts::Vector3(0, 0, 0)); + // Construct the perigee surface at the seed's reference point. + // For IP-originating tracks this is (0,0,0); for displaced seeds (e.g. from + // Lambda decay daughters) the seed carries the actual decay-vertex position + // so the CKF propagates from there instead of from the IP. + const auto& perigee_pos = track_seed.getPerigee(); + auto pSurface = Acts::Surface::makeShared( + Acts::Vector3(perigee_pos.x * Acts::UnitConstants::mm, + perigee_pos.y * Acts::UnitConstants::mm, + perigee_pos.z * Acts::UnitConstants::mm)); // Create parameters acts_init_trk_params.emplace_back(pSurface, params, cov, Acts::ParticleHypothesis::pion()); diff --git a/src/algorithms/tracking/TrackParamTruthInit.cc b/src/algorithms/tracking/TrackParamTruthInit.cc index 35ab17917b..f61009b15d 100644 --- a/src/algorithms/tracking/TrackParamTruthInit.cc +++ b/src/algorithms/tracking/TrackParamTruthInit.cc @@ -87,19 +87,35 @@ void TrackParamTruthInit::process(const Input& input, const Output& output) cons // modify initial momentum to avoid bleeding truth to results when fit fails const auto pinit = pmag * (1.0 + m_cfg.momentumSmear * gaussian(generator)); - // define line surface for local position values - auto perigee = Acts::Surface::makeShared(Acts::Vector3(0, 0, 0)); - - // track particle back to transverse point-of-closest approach - // with respect to the defined line surface - auto linesurface_parameter = -(v.x * p.x + v.y * p.y) / (p.x * p.x + p.y * p.y); + Acts::Vector3 direction(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)); - auto xpca = v.x + linesurface_parameter * p.x; - auto ypca = v.y + linesurface_parameter * p.y; - auto zpca = v.z + linesurface_parameter * p.z; + // Choose the perigee reference point and compute local (d0, z0) coordinates. + // + // Default: back-extrapolate to the transverse PCA w.r.t. the beam axis at z=0. + // This is correct for IP-originating tracks but produces a reference point far + // behind the IP for displaced vertices (e.g. Lambda decay daughters at large z), + // which forces ACTS to propagate many metres before reaching the detector. + // + // useVertexAsPerigee: anchor the perigee at the MCParticle vertex itself so + // the CKF only needs to propagate forward from the actual production point. + Acts::Vector3 perigee_center; + Acts::Vector3 global; + + if (m_cfg.useVertexAsPerigee) { + // Place perigee at the vertex; the particle starts there so d0=z0=0 exactly. + perigee_center = Acts::Vector3(v.x, v.y, v.z); + global = perigee_center; // PCA = vertex itself + } else { + // Standard: perigee at beam axis origin, back-extrapolate to transverse PCA. + perigee_center = Acts::Vector3(0, 0, 0); + auto linesurface_parameter = -(v.x * p.x + v.y * p.y) / (p.x * p.x + p.y * p.y); + global = Acts::Vector3(v.x + linesurface_parameter * p.x, + v.y + linesurface_parameter * p.y, + v.z + linesurface_parameter * p.z); + } - Acts::Vector3 global(xpca, ypca, zpca); - Acts::Vector3 direction(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta)); + // define line surface for local position values + auto perigee = Acts::Surface::makeShared(perigee_center); // convert from global to local coordinates using the defined line surface auto local = perigee->globalToLocal(m_geoSvc->getActsGeometryContext(), global, direction); @@ -131,7 +147,9 @@ void TrackParamTruthInit::process(const Input& input, const Output& output) cons // Insert into edm4eic::TrackSeeds auto track_seed = track_seeds->create(); - track_seed.setPerigee({0.F, 0.F, 0.F}); + track_seed.setPerigee( + {static_cast(perigee_center.x()), static_cast(perigee_center.y()), + static_cast(perigee_center.z())}); track_seed.setParams(track_parameter); // There are no hits to store to the seed diff --git a/src/algorithms/tracking/TrackParamTruthInitConfig.h b/src/algorithms/tracking/TrackParamTruthInitConfig.h index 09ae8ec69a..7f0f70a16e 100644 --- a/src/algorithms/tracking/TrackParamTruthInitConfig.h +++ b/src/algorithms/tracking/TrackParamTruthInitConfig.h @@ -15,4 +15,12 @@ struct TrackParamTruthInitConfig { double maxEtaForward = 6.0; double maxEtaBackward = 4.1; double momentumSmear = 0.1; + /** When true the seed perigee is placed at the MCParticle vertex instead + * of being extrapolated back to the beam axis. This is essential for + * particles produced at large |z| (e.g. Lambda decay daughters) where + * the standard back-extrapolation puts the reference point far behind + * the IP, forcing ACTS to propagate many metres before reaching the + * detector, which degrades or eliminates CKF efficiency. + */ + bool useVertexAsPerigee = false; }; diff --git a/src/factories/tracking/TrackParamTruthInit_factory.h b/src/factories/tracking/TrackParamTruthInit_factory.h index 450838cfa9..8e88c1b7b2 100644 --- a/src/factories/tracking/TrackParamTruthInit_factory.h +++ b/src/factories/tracking/TrackParamTruthInit_factory.h @@ -48,6 +48,9 @@ class TrackParamTruthInit_factory ParameterRef m_momentumSmear{ this, "MomentumSmear", config().momentumSmear, "Momentum magnitude fraction to use as width of gaussian smearing"}; + ParameterRef m_useVertexAsPerigee{ + this, "UseVertexAsPerigee", config().useVertexAsPerigee, + "Anchor the seed perigee at the MCParticle vertex (for displaced tracks)"}; Service m_ACTSGeoSvc{this}; Service m_algorithmsInit{this}; diff --git a/src/global/tracking/tracking.cc b/src/global/tracking/tracking.cc index 18db46f52b..5327c64e6f 100644 --- a/src/global/tracking/tracking.cc +++ b/src/global/tracking/tracking.cc @@ -24,17 +24,16 @@ #include #include -#include "algorithms/meta/SubDivideFunctors.h" #include "algorithms/tracking/TrackPropagationConfig.h" #include "extensions/jana/JOmniFactoryGeneratorT.h" #include "factories/meta/CollectionCollector_factory.h" -#include "factories/meta/SubDivideCollection_factory.h" #include "factories/tracking/ActsToTracks_factory.h" #include "factories/tracking/ActsTrackMerger_factory.h" #include "factories/tracking/AmbiguitySolver_factory.h" #include "factories/tracking/CKFTracking_factory.h" #include "factories/tracking/IterativeVertexFinder_factory.h" #include "factories/tracking/SecondaryVertexFinder_factory.h" +#include "algorithms/tracking/TrackParamTruthInitConfig.h" #include "factories/tracking/TrackParamTruthInit_factory.h" #include "factories/tracking/TrackProjector_factory.h" #include "factories/tracking/TrackPropagation_factory.h" @@ -49,19 +48,27 @@ void InitPlugin(JApplication* app) { using namespace eicrecon; + // Central tracker truth seeds: all IP-originating charged particles. + // Sub-50-mrad seeds included without filtering — the central CKF will simply + // find no hits for them and discard them, which is acceptable. app->Add(new JOmniFactoryGeneratorT( "TrackerTruthSeeds", {"EventHeader", "MCParticles"}, - {"TrackerTruthSeeds", "TrackerTruthSeedParameters"}, {}, app)); + {"CentralTrackerTruthSeeds", "TrackerTruthSeedParameters"}, {}, app)); - std::vector> thetaRanges{{0, 50 * dd4hep::mrad}, - {50 * dd4hep::mrad, 180 * dd4hep::deg}}; - app->Add(new JOmniFactoryGeneratorT>( - "CentralB0TrackerTruthSeeds", {"TrackerTruthSeeds"}, - {"B0TrackerTruthSeeds", "CentralTrackerTruthSeeds"}, - { - .function = RangeSplit< - Chain<&edm4eic::TrackSeed::getParams, &edm4eic::TrackParameters::getTheta>>( - thetaRanges), + // Dedicated B0 truth seeder: relaxed vertex-z cut so that charged daughters of Lambda + // decays at large z (up to ~O(meters)) are also seeded for the B0 tracker CKF. + app->Add(new JOmniFactoryGeneratorT( + "B0TrackerTruthSeeds", {"EventHeader", "MCParticles"}, + {"B0TrackerTruthSeeds", "B0TrackerTruthSeedParameters"}, + TrackParamTruthInitConfig{ + .maxVertexX = 120 * dd4hep::mm, // maxVertexZ * tan(20mrad) ~ 120mm + .maxVertexY = 120 * dd4hep::mm, + .maxVertexZ = 6000 * dd4hep::mm, // B0 tracker starts at ~6 m from IP + .minMomentum = 100 * dd4hep::MeV, + .maxEtaForward = 6.0, + .maxEtaBackward = 0.0, // forward-going particles only + .momentumSmear = 0.1, + .useVertexAsPerigee = true, // anchor at decay vertex, not beam-axis PCA }, app)); From 727b525397aab0763b9357b747a72e72e1151b6c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 26 Aug 2026 03:52:01 +0000 Subject: [PATCH 2/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/algorithms/tracking/CKFTracking.cc | 7 +++---- src/algorithms/tracking/TrackParamTruthInit.cc | 11 +++++------ src/global/tracking/tracking.cc | 14 +++++++------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/algorithms/tracking/CKFTracking.cc b/src/algorithms/tracking/CKFTracking.cc index 8f0c1f2bfb..4bf9de53cc 100644 --- a/src/algorithms/tracking/CKFTracking.cc +++ b/src/algorithms/tracking/CKFTracking.cc @@ -190,10 +190,9 @@ void CKFTracking::process(const Input& input, const Output& output) const { // Lambda decay daughters) the seed carries the actual decay-vertex position // so the CKF propagates from there instead of from the IP. const auto& perigee_pos = track_seed.getPerigee(); - auto pSurface = Acts::Surface::makeShared( - Acts::Vector3(perigee_pos.x * Acts::UnitConstants::mm, - perigee_pos.y * Acts::UnitConstants::mm, - perigee_pos.z * Acts::UnitConstants::mm)); + auto pSurface = Acts::Surface::makeShared(Acts::Vector3( + perigee_pos.x * Acts::UnitConstants::mm, perigee_pos.y * Acts::UnitConstants::mm, + perigee_pos.z * Acts::UnitConstants::mm)); // Create parameters acts_init_trk_params.emplace_back(pSurface, params, cov, Acts::ParticleHypothesis::pion()); diff --git a/src/algorithms/tracking/TrackParamTruthInit.cc b/src/algorithms/tracking/TrackParamTruthInit.cc index f61009b15d..61699dc8b0 100644 --- a/src/algorithms/tracking/TrackParamTruthInit.cc +++ b/src/algorithms/tracking/TrackParamTruthInit.cc @@ -107,10 +107,9 @@ void TrackParamTruthInit::process(const Input& input, const Output& output) cons global = perigee_center; // PCA = vertex itself } else { // Standard: perigee at beam axis origin, back-extrapolate to transverse PCA. - perigee_center = Acts::Vector3(0, 0, 0); + perigee_center = Acts::Vector3(0, 0, 0); auto linesurface_parameter = -(v.x * p.x + v.y * p.y) / (p.x * p.x + p.y * p.y); - global = Acts::Vector3(v.x + linesurface_parameter * p.x, - v.y + linesurface_parameter * p.y, + global = Acts::Vector3(v.x + linesurface_parameter * p.x, v.y + linesurface_parameter * p.y, v.z + linesurface_parameter * p.z); } @@ -147,9 +146,9 @@ void TrackParamTruthInit::process(const Input& input, const Output& output) cons // Insert into edm4eic::TrackSeeds auto track_seed = track_seeds->create(); - track_seed.setPerigee( - {static_cast(perigee_center.x()), static_cast(perigee_center.y()), - static_cast(perigee_center.z())}); + track_seed.setPerigee({static_cast(perigee_center.x()), + static_cast(perigee_center.y()), + static_cast(perigee_center.z())}); track_seed.setParams(track_parameter); // There are no hits to store to the seed diff --git a/src/global/tracking/tracking.cc b/src/global/tracking/tracking.cc index 5327c64e6f..b28a2a8454 100644 --- a/src/global/tracking/tracking.cc +++ b/src/global/tracking/tracking.cc @@ -61,13 +61,13 @@ void InitPlugin(JApplication* app) { "B0TrackerTruthSeeds", {"EventHeader", "MCParticles"}, {"B0TrackerTruthSeeds", "B0TrackerTruthSeedParameters"}, TrackParamTruthInitConfig{ - .maxVertexX = 120 * dd4hep::mm, // maxVertexZ * tan(20mrad) ~ 120mm - .maxVertexY = 120 * dd4hep::mm, - .maxVertexZ = 6000 * dd4hep::mm, // B0 tracker starts at ~6 m from IP - .minMomentum = 100 * dd4hep::MeV, - .maxEtaForward = 6.0, - .maxEtaBackward = 0.0, // forward-going particles only - .momentumSmear = 0.1, + .maxVertexX = 120 * dd4hep::mm, // maxVertexZ * tan(20mrad) ~ 120mm + .maxVertexY = 120 * dd4hep::mm, + .maxVertexZ = 6000 * dd4hep::mm, // B0 tracker starts at ~6 m from IP + .minMomentum = 100 * dd4hep::MeV, + .maxEtaForward = 6.0, + .maxEtaBackward = 0.0, // forward-going particles only + .momentumSmear = 0.1, .useVertexAsPerigee = true, // anchor at decay vertex, not beam-axis PCA }, app)); From ea47d2fb31fd702e74c0d684bbdc137f5e562be2 Mon Sep 17 00:00:00 2001 From: epic-capybara <139920704+epic-capybara@users.noreply.github.com> Date: Wed, 26 Aug 2026 10:42:12 -0400 Subject: [PATCH 3/8] TrackParamTruthInit: implement relaxed mode to include secondaries in B0TrackerTruthSeeds (fix: iwyu) (#2902) This PR applies the include-what-you-use fixes as suggested by https://github.com/eic/EICrecon/actions/runs/32928057137. Please merge this PR into the branch `pr/relaxed_b0_truth_seeding` to resolve failures in PR #2901. Auto-generated by [create-pull-request][1] [1]: https://github.com/peter-evans/create-pull-request Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- src/algorithms/tracking/CKFTracking.cc | 35 +++++++++++++------------- src/global/tracking/tracking.cc | 8 +----- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src/algorithms/tracking/CKFTracking.cc b/src/algorithms/tracking/CKFTracking.cc index 4bf9de53cc..e7600ec103 100644 --- a/src/algorithms/tracking/CKFTracking.cc +++ b/src/algorithms/tracking/CKFTracking.cc @@ -6,35 +6,23 @@ #include #include #include +#include +#include #if Acts_VERSION_MAJOR >= 46 -#include #else #include #endif #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include #include #include +#include #include #include +#include +#include #include #include #include @@ -45,8 +33,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -60,9 +50,20 @@ #include #include #include +#include #include #include #include // IWYU pragma: keep +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // IWYU pragma: no_include // IWYU pragma: no_include diff --git a/src/global/tracking/tracking.cc b/src/global/tracking/tracking.cc index b28a2a8454..fa0d964ddc 100644 --- a/src/global/tracking/tracking.cc +++ b/src/global/tracking/tracking.cc @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -11,19 +10,15 @@ #include #include #include -#include -#include #include #include -#include #include -#include #include #include -#include #include #include +#include "algorithms/tracking/TrackParamTruthInitConfig.h" #include "algorithms/tracking/TrackPropagationConfig.h" #include "extensions/jana/JOmniFactoryGeneratorT.h" #include "factories/meta/CollectionCollector_factory.h" @@ -33,7 +28,6 @@ #include "factories/tracking/CKFTracking_factory.h" #include "factories/tracking/IterativeVertexFinder_factory.h" #include "factories/tracking/SecondaryVertexFinder_factory.h" -#include "algorithms/tracking/TrackParamTruthInitConfig.h" #include "factories/tracking/TrackParamTruthInit_factory.h" #include "factories/tracking/TrackProjector_factory.h" #include "factories/tracking/TrackPropagation_factory.h" From 6395dd3f41e6f59606fe005a60756be6cf584c2e Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Wed, 26 Aug 2026 10:45:04 -0400 Subject: [PATCH 4/8] rename factory to CentralTrackerTruthSeeds --- src/global/tracking/tracking.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/global/tracking/tracking.cc b/src/global/tracking/tracking.cc index fa0d964ddc..56b6b1ebd9 100644 --- a/src/global/tracking/tracking.cc +++ b/src/global/tracking/tracking.cc @@ -46,7 +46,7 @@ void InitPlugin(JApplication* app) { // Sub-50-mrad seeds included without filtering — the central CKF will simply // find no hits for them and discard them, which is acceptable. app->Add(new JOmniFactoryGeneratorT( - "TrackerTruthSeeds", {"EventHeader", "MCParticles"}, + "CentralTrackerTruthSeeds", {"EventHeader", "MCParticles"}, {"CentralTrackerTruthSeeds", "TrackerTruthSeedParameters"}, {}, app)); // Dedicated B0 truth seeder: relaxed vertex-z cut so that charged daughters of Lambda From aa1f7f48cf034105bbcd9c9f090077e679a9e2be Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Wed, 26 Aug 2026 10:48:37 -0400 Subject: [PATCH 5/8] TrackerTruthSeedParameters -> CentralTrackerTruthSeedParameters --- src/global/tracking/tracking.cc | 2 +- src/services/io/podio/JEventProcessorPODIO.cc | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/global/tracking/tracking.cc b/src/global/tracking/tracking.cc index 56b6b1ebd9..8be6cbf6b6 100644 --- a/src/global/tracking/tracking.cc +++ b/src/global/tracking/tracking.cc @@ -47,7 +47,7 @@ void InitPlugin(JApplication* app) { // find no hits for them and discard them, which is acceptable. app->Add(new JOmniFactoryGeneratorT( "CentralTrackerTruthSeeds", {"EventHeader", "MCParticles"}, - {"CentralTrackerTruthSeeds", "TrackerTruthSeedParameters"}, {}, app)); + {"CentralTrackerTruthSeeds", "CentralTrackerTruthSeedParameters"}, {}, app)); // Dedicated B0 truth seeder: relaxed vertex-z cut so that charged daughters of Lambda // decays at large z (up to ~O(meters)) are also seeded for the B0 tracker CKF. diff --git a/src/services/io/podio/JEventProcessorPODIO.cc b/src/services/io/podio/JEventProcessorPODIO.cc index c7ec93153d..7001d888b2 100644 --- a/src/services/io/podio/JEventProcessorPODIO.cc +++ b/src/services/io/podio/JEventProcessorPODIO.cc @@ -62,8 +62,7 @@ JEventProcessorPODIO::JEventProcessorPODIO() { "MCParticlesHeadOnFrameNoBeamFX", // Central tracking hits combined - "TrackerTruthSeeds", - "TrackerTruthSeedParameters", + "CentralTrackerTruthSeedParameters", "CentralTrackerTruthSeeds", "CentralTrackingRecHits", "CentralTrackingRawHitLinks", From cf740ef5c56bb4e7352ce9a850260838d818d35e Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Wed, 26 Aug 2026 11:00:52 -0400 Subject: [PATCH 6/8] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/services/io/podio/JEventProcessorPODIO.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/services/io/podio/JEventProcessorPODIO.cc b/src/services/io/podio/JEventProcessorPODIO.cc index 7001d888b2..417be09d65 100644 --- a/src/services/io/podio/JEventProcessorPODIO.cc +++ b/src/services/io/podio/JEventProcessorPODIO.cc @@ -64,6 +64,7 @@ JEventProcessorPODIO::JEventProcessorPODIO() { // Central tracking hits combined "CentralTrackerTruthSeedParameters", "CentralTrackerTruthSeeds", + "B0TrackerTruthSeedParameters", "CentralTrackingRecHits", "CentralTrackingRawHitLinks", "CentralTrackingRawHitAssociations", From 4165ddc4de0fa6e6e9747936c499d2f91d99552f Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Fri, 28 Aug 2026 13:08:04 -0400 Subject: [PATCH 7/8] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/services/io/podio/JEventProcessorPODIO.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/services/io/podio/JEventProcessorPODIO.cc b/src/services/io/podio/JEventProcessorPODIO.cc index 417be09d65..7b49a9fada 100644 --- a/src/services/io/podio/JEventProcessorPODIO.cc +++ b/src/services/io/podio/JEventProcessorPODIO.cc @@ -65,6 +65,7 @@ JEventProcessorPODIO::JEventProcessorPODIO() { "CentralTrackerTruthSeedParameters", "CentralTrackerTruthSeeds", "B0TrackerTruthSeedParameters", + "B0TrackerTruthSeeds", "CentralTrackingRecHits", "CentralTrackingRawHitLinks", "CentralTrackingRawHitAssociations", From 9b82ed1c2657372970306e3568f2027c1e571d2d Mon Sep 17 00:00:00 2001 From: Dmitry Kalinkin Date: Fri, 28 Aug 2026 13:32:44 -0400 Subject: [PATCH 8/8] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/global/tracking/tracking.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/global/tracking/tracking.cc b/src/global/tracking/tracking.cc index 8be6cbf6b6..6c9e8b08c0 100644 --- a/src/global/tracking/tracking.cc +++ b/src/global/tracking/tracking.cc @@ -42,9 +42,8 @@ void InitPlugin(JApplication* app) { using namespace eicrecon; - // Central tracker truth seeds: all IP-originating charged particles. - // Sub-50-mrad seeds included without filtering — the central CKF will simply - // find no hits for them and discard them, which is acceptable. + // Central tracker truth seeds: charged particles near the IP within the configured vertex cuts. + // (Includes Geant4 secondaries with simulatorStatus != 0; generator intermediates are rejected.) app->Add(new JOmniFactoryGeneratorT( "CentralTrackerTruthSeeds", {"EventHeader", "MCParticles"}, {"CentralTrackerTruthSeeds", "CentralTrackerTruthSeedParameters"}, {}, app));