Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,9 @@ public:
Acts::MagneticFieldProvider::Cache& magCache) const;

StatusCode tracking(const std::vector<Acts::BoundTrackParameters>& paramseeds, const CKF& trackFinder,
const TrackFinderOptions& ckfOptions, Acts::MagneticFieldProvider::Cache& magCache,
edm4hep::TrackCollection& trackCollection) const;
const TrackFinderOptions& ckfOptions, const Propagator& extrapPropagator,
const Acts::PerigeeSurface& perigeeSurface, Propagator::Options<>& extrapOptions,
Acts::MagneticFieldProvider::Cache& magCache, edm4hep::TrackCollection& trackCollection) const;

protected:
/**
Expand Down
55 changes: 55 additions & 0 deletions k4ActsTracking/include/k4ActsTracking/Helpers.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,32 @@
#include <Acts/EventData/ParticleHypothesis.hpp>
#include <Acts/EventData/VectorMultiTrajectory.hpp>
#include <Acts/EventData/VectorTrackContainer.hpp>
#include <Acts/Geometry/GeometryContext.hpp>
#include <Acts/Geometry/GeometryIdentifier.hpp>
#include <Acts/MagneticField/MagneticFieldContext.hpp>
#include <Acts/MagneticField/MagneticFieldProvider.hpp>
#include <Acts/Propagator/EigenStepper.hpp>
#include <Acts/Propagator/Navigator.hpp>
#include <Acts/Propagator/Propagator.hpp>
#include <Acts/TrackFinding/CombinatorialKalmanFilter.hpp>
#include <Acts/TrackFitting/KalmanFitter.hpp>

// ACTSTracking
#include "k4ActsTracking/IActsGeoSvc.h"
#include "k4ActsTracking/SourceLink.hxx"

// Standard
#include <optional>
#include <vector>

namespace ACTSTracking {

/// Geometry-aware propagator used to extrapolate fitted tracks out to the
/// calorimeter face. It navigates the tracking geometry (which now includes
/// the passive calo volumes), so material along the way is accounted for and
/// the actual curved trajectory selects which calo surface is hit.
using CaloFacePropagator = Acts::Propagator<Acts::EigenStepper<>, Acts::Navigator>;

using TrackResult =
Acts::TrackContainer<Acts::VectorTrackContainer, Acts::VectorMultiTrajectory, std::shared_ptr>::TrackProxy;

Expand Down Expand Up @@ -106,4 +123,42 @@ namespace ACTSTracking {
*/
Acts::ParticleHypothesis convertParticle(const edm4hep::MCParticle mcParticle);

//! Outcome of a calorimeter-face extrapolation.
enum class CaloExtrapolationStatus {
Ok, ///< reached a calo-face surface
NoSurfaces, ///< no calo-face surfaces are configured
NotReached, ///< propagation finished without reaching a calo-face surface
PropagationError, ///< the propagation itself failed
};

//! Result of a calorimeter-face extrapolation.
struct CaloExtrapolationResult {
std::optional<Acts::BoundTrackParameters> params{};
CaloExtrapolationStatus status{CaloExtrapolationStatus::NotReached};
};

//! Extrapolate track parameters to the calorimeter face.
/**
* Propagates the given parameters through the tracking geometry (which contains
* the passive calo volumes) and terminates as soon as the actual trajectory
* reaches one of the calorimeter-face surfaces, identified by their geometry
* ids. Because the propagation follows the real curved trajectory through the
* geometry, no straight-line pre-selection of the target surface is needed and
* material handling integrates naturally once the calo volumes carry material.
*
* \param propagator Geometry-aware propagator
* \param start Track parameters to extrapolate from (e.g. at the last hit)
* \param caloSurfaceGeoIds Geometry ids of the calo-face surfaces (from IActsGeoSvc)
* \param gctx Geometry context
* \param mctx Magnetic-field context
*
* \return Bound track parameters at the calorimeter face together with a status
* describing why the extrapolation succeeded or failed.
*/
CaloExtrapolationResult extrapolateToCaloFace(const CaloFacePropagator& propagator,
const Acts::BoundTrackParameters& start,
const std::vector<Acts::GeometryIdentifier>& caloSurfaceGeoIds,
const Acts::GeometryContext& gctx,
const Acts::MagneticFieldContext& mctx);

} // namespace ACTSTracking
35 changes: 35 additions & 0 deletions k4ActsTracking/include/k4ActsTracking/IActsGeoSvc.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@

#include <DD4hep/Primitives.h>

#include <Acts/Geometry/GeometryIdentifier.hpp>

#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

namespace dd4hep {
namespace rec {
Expand All @@ -44,13 +47,45 @@ class GAUDI_API IActsGeoSvc : virtual public IService {
public:
using CellIDSurfaceMap = std::unordered_map<dd4hep::CellID, const Acts::Surface*>;

/// Surfaces approximating the inner face of the electromagnetic calorimeter,
/// derived from the DD4hep geometry. They are inserted into the tracking
/// geometry as passive surfaces of dedicated calo volumes, so that the
/// standard geometry-aware propagation can navigate to them (see
/// ACTSTracking::extrapolateToCaloFace).
///
/// The barrel is a regular polygon, so its inner face is modelled as one
/// planar surface per polygon side rather than a cylinder. The endcaps are
/// flat discs at constant z. The struct also carries the bounding cylinder
/// dimensions used to build the enclosing TrackingVolumes (ACTS units).
struct CaloFaceSurfaces {
std::vector<std::shared_ptr<Acts::Surface>> barrelFaces; ///< one plane per polygon side
std::shared_ptr<Acts::Surface> endcapPos; ///< disc at +z, may be null
std::shared_ptr<Acts::Surface> endcapNeg; ///< disc at -z, may be null

// Bounding-cylinder dimensions for the enclosing TrackingVolumes.
double barrelRMin = 0; ///< inner radius of the barrel calo volume (~apothem)
double barrelRMax = 0; ///< outer radius of the barrel calo volume (~circumradius)
double barrelHalfZ = 0; ///< barrel half-length along z
double endcapRMin = 0; ///< inner radius of the endcap disc volumes
double endcapRMax = 0; ///< outer radius of the endcap disc volumes
double endcapZ = 0; ///< |z| of the endcap inner face

bool empty() const { return barrelFaces.empty() && !endcapPos && !endcapNeg; }
};

public:
DeclareInterfaceID(IActsGeoSvc, 1, 0);

virtual std::shared_ptr<const Acts::TrackingGeometry> trackingGeometry() const = 0;
virtual std::shared_ptr<const Acts::MagneticFieldProvider> magneticField() const = 0;
virtual const CellIDSurfaceMap& cellIdToSurfaceMap() const = 0;
virtual std::string cellIDEncodingString() const = 0;
virtual const CaloFaceSurfaces& caloFaceSurfaces() const = 0;

/// Geometry identifiers of the calorimeter-face surfaces, valid after the
/// tracking geometry has been constructed. Used by the extrapolation to
/// recognise when the propagation has reached the calo face.
virtual const std::vector<Acts::GeometryIdentifier>& caloSurfaceGeoIds() const = 0;

virtual ~IActsGeoSvc() = default;
};
Expand Down
32 changes: 28 additions & 4 deletions k4ActsTracking/src/components/ACTSSeededCKFTrackingAlg.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <Acts/TrackFitting/GainMatrixUpdater.hpp>
#include <Acts/Utilities/Logger.hpp>
#include <Acts/Utilities/RangeXD.hpp>
#include <Acts/Utilities/TrackHelpers.hpp>

// TBB
#include <tbb/concurrent_vector.h>
Expand Down Expand Up @@ -384,6 +385,12 @@ std::tuple<edm4hep::TrackCollection, edm4hep::TrackCollection> ACTSSeededCKFTrac
Propagator propagator(std::move(stepper), std::move(navigator));
CKF trackFinder(std::move(propagator));

// For extrapolating the fitted track back to the IP (perigee surface)
Stepper extrapStepper(magneticField());
Navigator extrapNavigator(navigatorCfg);
Propagator extrapPropagator(std::move(extrapStepper), std::move(extrapNavigator));
auto perigeeSurface = Acts::Surface::makeShared<Acts::PerigeeSurface>(Acts::Vector3{0., 0., 0.});

// Set the options
Acts::MeasurementSelector::Config measurementSelectorCfg = {
{Acts::GeometryIdentifier(), {{}, {m_CKF_chi2CutOff}, {(std::size_t)(m_CKF_numMeasurementsCutOff)}}}};
Expand All @@ -394,9 +401,11 @@ std::tuple<edm4hep::TrackCollection, edm4hep::TrackCollection> ACTSSeededCKFTrac
pOptions.direction = Acts::Direction::Backward();
}

// Construct a perigee surface as the target surface
std::shared_ptr<Acts::PerigeeSurface> perigeeSurface =
Acts::Surface::makeShared<Acts::PerigeeSurface>(Acts::Vector3{0., 0., 0.});
Propagator::Options<> extrapOptions{geometryContext(), magneticFieldContext()};
extrapOptions.maxSteps = 10000;
if (m_propagateBackward) {
extrapOptions.direction = Acts::Direction::Backward();
}

Acts::GainMatrixUpdater kfUpdater;

Expand Down Expand Up @@ -471,7 +480,9 @@ std::tuple<edm4hep::TrackCollection, edm4hep::TrackCollection> ACTSSeededCKFTrac
if (!m_runCKF)
return;

if (!tracking(paramseeds, trackFinder, ckfOptions, localMagCache, trackCollection).isSuccess()) {
if (!tracking(paramseeds, trackFinder, ckfOptions, extrapPropagator, *perigeeSurface, extrapOptions, localMagCache,
trackCollection)
.isSuccess()) {
warning() << "Tracking failed for this event" << endmsg;
}
}; // parallelSeedingAndTracking
Expand Down Expand Up @@ -586,6 +597,9 @@ std::vector<Acts::BoundTrackParameters> ACTSSeededCKFTrackingAlg::seedsToParamet
// CKF tracking,
StatusCode ACTSSeededCKFTrackingAlg::tracking(const std::vector<Acts::BoundTrackParameters>& paramseeds,
const CKF& trackFinder, const TrackFinderOptions& ckfOptions,
const Propagator& extrapPropagator,
const Acts::PerigeeSurface& perigeeSurface,
Propagator::Options<>& extrapOptions,
Acts::MagneticFieldProvider::Cache& magCache,
edm4hep::TrackCollection& trackCollection) const {
// Initialize track finder
Expand Down Expand Up @@ -613,6 +627,16 @@ StatusCode ACTSSeededCKFTrackingAlg::tracking(const std::vector<Acts::BoundTrack
continue;
}

// Extrapolate the fitted track back to the perigee surface at the IP so
// that the track parameters (in particular D0 and Z0) are expressed
// there. This reproduces the TrackStateAtIP behaviour from older ACTS.
auto extrapResult = Acts::extrapolateTrackToReferenceSurface(
trackTip, perigeeSurface, extrapPropagator, extrapOptions, Acts::TrackExtrapolationStrategy::firstOrLast);
Comment thread
madbaron marked this conversation as resolved.
if (!extrapResult.ok()) {
warning() << "Track extrapolation to perigee failed: " << extrapResult.error() << endmsg;
continue;
}

// Helpful debug output
debug() << "Trajectory Summary" << endmsg;
debug() << "\tchi2Sum " << trackTip.chi2() << endmsg;
Expand Down
Loading
Loading