Skip to content
Open
45 changes: 26 additions & 19 deletions src/algorithms/tracking/CKFTracking.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,23 @@
#include <Acts/Definitions/Algebra.hpp>
#include <Acts/Definitions/TrackParametrization.hpp>
#include <Acts/Definitions/Units.hpp>
#include <Acts/Utilities/MathHelpers.hpp>
#include <edm4hep/Vector3f.h>
#if Acts_VERSION_MAJOR >= 46
#include <Acts/EventData/BoundTrackParameters.hpp>
#else
#include <Acts/EventData/GenericBoundTrackParameters.hpp>
#endif
#include <Acts/EventData/MeasurementHelpers.hpp>
#include <Acts/EventData/TrackStatePropMask.hpp>
#include <Acts/Geometry/GeometryContext.hpp>
#include <Acts/Geometry/GeometryHierarchyMap.hpp>
#include <Acts/TrackFinding/CombinatorialKalmanFilterExtensions.hpp>
#include <Acts/Utilities/CalibrationContext.hpp>
#include <spdlog/common.h>
#include <algorithm>
#include <any>
#include <array>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <string>
#include <system_error>
#include <tuple>
#include <utility>
#include <Acts/EventData/ParticleHypothesis.hpp>
#include <Acts/EventData/ProxyAccessor.hpp>
#include <Acts/EventData/SourceLink.hpp>
#include <Acts/EventData/TrackContainer.hpp>
#include <Acts/EventData/TrackProxy.hpp>
#include <Acts/EventData/TrackStatePropMask.hpp>
#include <Acts/EventData/VectorMultiTrajectory.hpp>
#include <Acts/EventData/VectorTrackContainer.hpp>
#include <Acts/Geometry/GeometryContext.hpp>
#include <Acts/Geometry/GeometryHierarchyMap.hpp>
#include <Acts/Geometry/GeometryIdentifier.hpp>
#include <Acts/Propagator/ActorList.hpp>
#include <Acts/Propagator/EigenStepper.hpp>
Expand All @@ -45,8 +33,10 @@
#include <Acts/Propagator/StandardAborters.hpp>
#include <Acts/Surfaces/PerigeeSurface.hpp>
#include <Acts/Surfaces/Surface.hpp>
#include <Acts/TrackFinding/CombinatorialKalmanFilterExtensions.hpp>
#include <Acts/TrackFinding/TrackStateCreator.hpp>
#include <Acts/TrackFitting/GainMatrixUpdater.hpp>
#include <Acts/Utilities/CalibrationContext.hpp>
#include <Acts/Utilities/Logger.hpp>
#include <Acts/Utilities/TrackHelpers.hpp>
#include <ActsExamples/EventData/GeometryContainers.hpp>
Expand All @@ -60,9 +50,20 @@
#include <edm4eic/TrackSeedCollection.h>
#include <edm4eic/unit_system.h>
#include <edm4hep/Vector2f.h>
#include <spdlog/common.h>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <Eigen/LU> // IWYU pragma: keep
#include <algorithm>
#include <any>
#include <array>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <string>
#include <system_error>
#include <tuple>
#include <utility>
// IWYU pragma: no_include <Acts/Utilities/detail/ContextType.hpp>
// IWYU pragma: no_include <Acts/Utilities/detail/ContainerIterator.hpp>

Expand Down Expand Up @@ -185,8 +186,14 @@ void CKFTracking::process(const Input& input, const Output& output) const {
++i;
}

// Construct a perigee surface as the target surface
auto pSurface = Acts::Surface::makeShared<const Acts::PerigeeSurface>(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();
Comment thread
veprbl marked this conversation as resolved.
auto pSurface = Acts::Surface::makeShared<const Acts::PerigeeSurface>(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());
Expand Down
41 changes: 29 additions & 12 deletions src/algorithms/tracking/TrackParamTruthInit.cc
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,34 @@ 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::PerigeeSurface>(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);
Comment thread
veprbl marked this conversation as resolved.
}
Comment thread
veprbl marked this conversation as resolved.

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<Acts::PerigeeSurface>(perigee_center);

// convert from global to local coordinates using the defined line surface
auto local = perigee->globalToLocal(m_geoSvc->getActsGeometryContext(), global, direction);
Expand Down Expand Up @@ -131,7 +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({0.F, 0.F, 0.F});
track_seed.setPerigee({static_cast<float>(perigee_center.x()),
static_cast<float>(perigee_center.y()),
static_cast<float>(perigee_center.z())});
track_seed.setParams(track_parameter);
// There are no hits to store to the seed

Expand Down
8 changes: 8 additions & 0 deletions src/algorithms/tracking/TrackParamTruthInitConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
3 changes: 3 additions & 0 deletions src/factories/tracking/TrackParamTruthInit_factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class TrackParamTruthInit_factory
ParameterRef<double> m_momentumSmear{
this, "MomentumSmear", config().momentumSmear,
"Momentum magnitude fraction to use as width of gaussian smearing"};
ParameterRef<bool> m_useVertexAsPerigee{
this, "UseVertexAsPerigee", config().useVertexAsPerigee,
"Anchor the seed perigee at the MCParticle vertex (for displaced tracks)"};

Service<ACTSGeo_service> m_ACTSGeoSvc{this};
Service<AlgorithmsInit_service> m_algorithmsInit{this};
Expand Down
41 changes: 21 additions & 20 deletions src/global/tracking/tracking.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,25 @@

#include <Acts/Definitions/Units.hpp>
#include <Evaluator/DD4hepUnits.h>
#include <JANA/JApplication.h>
#include <JANA/JApplicationFwd.h>
#include <JANA/Utils/JTypeInfo.h>
#include <edm4eic/MCRecoTrackParticleAssociationCollection.h>
#include <edm4eic/MCRecoTrackerHitAssociationCollection.h>
#include <edm4eic/MCRecoTrackerHitLinkCollection.h>
#include <edm4eic/Measurement2D.h>
#include <edm4eic/TrackCollection.h>
#include <edm4eic/TrackParameters.h>
#include <edm4eic/TrackSeed.h>
#include <edm4eic/TrackerHitCollection.h>
#include <podio/detail/Link.h>
#include <cmath>
#include <deque>
#include <functional>
#include <memory>
#include <string>
#include <utility>
#include <variant>
#include <vector>

#include "algorithms/meta/SubDivideFunctors.h"
#include "algorithms/tracking/TrackParamTruthInitConfig.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"
Expand All @@ -49,19 +42,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.
Comment thread
Copilot marked this conversation as resolved.
Outdated
app->Add(new JOmniFactoryGeneratorT<TrackParamTruthInit_factory>(
"TrackerTruthSeeds", {"EventHeader", "MCParticles"},
{"TrackerTruthSeeds", "TrackerTruthSeedParameters"}, {}, app));

std::vector<std::pair<double, double>> thetaRanges{{0, 50 * dd4hep::mrad},
{50 * dd4hep::mrad, 180 * dd4hep::deg}};
app->Add(new JOmniFactoryGeneratorT<SubDivideCollection_factory<edm4eic::TrackSeed>>(
"CentralB0TrackerTruthSeeds", {"TrackerTruthSeeds"},
{"B0TrackerTruthSeeds", "CentralTrackerTruthSeeds"},
{
.function = RangeSplit<
Chain<&edm4eic::TrackSeed::getParams, &edm4eic::TrackParameters::getTheta>>(
thetaRanges),
"CentralTrackerTruthSeeds", {"EventHeader", "MCParticles"},
{"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.
app->Add(new JOmniFactoryGeneratorT<TrackParamTruthInit_factory>(
"B0TrackerTruthSeeds", {"EventHeader", "MCParticles"},
{"B0TrackerTruthSeeds", "B0TrackerTruthSeedParameters"},
Comment thread
veprbl marked this conversation as resolved.
Outdated
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));

Expand Down
4 changes: 2 additions & 2 deletions src/services/io/podio/JEventProcessorPODIO.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ JEventProcessorPODIO::JEventProcessorPODIO() {
"MCParticlesHeadOnFrameNoBeamFX",

// Central tracking hits combined
"TrackerTruthSeeds",
"TrackerTruthSeedParameters",
"CentralTrackerTruthSeedParameters",
"CentralTrackerTruthSeeds",
"B0TrackerTruthSeedParameters",
Comment thread
Copilot marked this conversation as resolved.
"CentralTrackingRecHits",
Comment thread
Copilot marked this conversation as resolved.
"CentralTrackingRawHitLinks",
"CentralTrackingRawHitAssociations",
Expand Down
Loading