Skip to content
Merged
Show file tree
Hide file tree
Changes from 68 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
5319fc3
Add a simple runtime test
tmadlener Dec 22, 2025
5df80cd
Guard ODD tests via environment variable enable tests for mucoll image
tmadlener Dec 22, 2025
f027dcc
Use more events for test to make sure failures are detected
tmadlener Dec 22, 2025
a9ffd59
Add CKFTrackingAlg using ActsGeoSvc (Gen3 geometry path)
tmadlener Mar 12, 2026
b50d830
Add test for CKFTrackingAlg with MAIA_v0 (Gen3 geometry path)
tmadlener Mar 12, 2026
2bff99a
Properly shoot muons for tests
tmadlener Mar 17, 2026
37617ad
First version of seed selection based off CellIDs
tmadlener Mar 17, 2026
971933c
Add CellID based selection tool
tmadlener Mar 18, 2026
307f45b
Add documentation
tmadlener Mar 18, 2026
ddbd518
Ensure that wildcard only selectors select everything
tmadlener Mar 18, 2026
cc89b14
Add tests to ensure exceptions are thrown
tmadlener Mar 18, 2026
496ac11
Add more tests and checks for potential failure modes
tmadlener Mar 18, 2026
31b372b
Use the new CellIDSelector for the new CKF algorithm
tmadlener Mar 18, 2026
2058273
Remove wildcard selection possibility from CellIDSelector
tmadlener Mar 18, 2026
f6499bd
Reduce internal state of selector
tmadlener Mar 18, 2026
466ab15
Store the selector on the stack and rename property
tmadlener Mar 18, 2026
21a6063
Remove unnecessary debug outputs and comments
tmadlener Mar 20, 2026
40160d5
Try to discover an external Catch2 properly
tmadlener Apr 21, 2026
3abbe73
Fix pre-commit issues
tmadlener Apr 21, 2026
f23b346
Re-organize tests a bit
tmadlener Apr 21, 2026
7a30a16
Remove tests based on old geometry
tmadlener Apr 21, 2026
3b0d050
Add CLD tracking test
tmadlener Apr 28, 2026
9ef961d
Fix config after upstream changes
tmadlener Apr 29, 2026
18657c3
Use single KeyValue inputs and outputs to avoid misconfiguration
tmadlener Apr 29, 2026
dbbe829
Add tests for ILD_FCCee_v01
tmadlener Apr 29, 2026
2141d06
Introduce cmake functions for testing
tmadlener Apr 29, 2026
436f265
Re-use existing helper function
tmadlener Apr 29, 2026
8850e09
Omit post-processing of CLDConfig
tmadlener Apr 29, 2026
9849091
Extract common functionality into helpers
tmadlener Apr 29, 2026
ec65873
Try to set the proper test environment
tmadlener Apr 29, 2026
3c11780
ckf import fix by Claude
madbaron Apr 30, 2026
6c6d943
undo hit merger change
madbaron Apr 30, 2026
7dabc3f
attempt at fixing mucoll ci
madbaron Apr 30, 2026
e285967
fix missing escape char
madbaron May 13, 2026
16795d5
rolling back unneeded copilot changes
madbaron May 13, 2026
3760fdf
typos
madbaron May 26, 2026
a546daf
match type concrete implementation
madbaron May 26, 2026
e116b0f
removed unused function
madbaron May 26, 2026
7359668
made units explicit in property description
madbaron May 26, 2026
1f27141
pre-commit
madbaron May 26, 2026
da72dfd
pre-commit
madbaron May 26, 2026
1fc8342
removing duplicated private flag
madbaron May 26, 2026
b3c6fe4
set pythonpath for ild tests
madbaron May 28, 2026
24686c3
move set block
madbaron May 28, 2026
f6ca185
move to set property
madbaron May 28, 2026
f5e86f1
Merge branch 'main' into dd4hep-gen3-ckf-tests
madbaron Jun 1, 2026
2265de9
exclude ILD/CLD tests from mucoll workflow
madbaron Jun 1, 2026
9256b66
Merge branch 'dd4hep-gen3-ckf-tests' of github.com:tmadlener/k4ActsTr…
madbaron Jun 1, 2026
fbd7588
update mucoll action
madbaron Jun 1, 2026
145c04a
update mucoll action
madbaron Jun 1, 2026
45c28d3
remote workflow doesn't reproduce local behaviour
madbaron Jun 1, 2026
e7c0492
node js 20 action update
madbaron Jun 1, 2026
cf42768
add newline to make precommit happy
madbaron Jun 1, 2026
19e5b0b
move up
madbaron Jun 1, 2026
6bc94a2
random property
madbaron Jun 1, 2026
8c8eed7
at the end
madbaron Jun 1, 2026
2f6d7f1
rollback
madbaron Jun 1, 2026
9eca7f5
rename to alg?
madbaron Jun 1, 2026
fa1fc29
CMakelist change
madbaron Jun 1, 2026
e794ee2
obviously another random attempt
madbaron Jun 1, 2026
8a7ada7
obviously another random attempt
madbaron Jun 1, 2026
998deec
one more
madbaron Jun 1, 2026
264bda2
change test env again
madbaron Jun 1, 2026
b530ae7
is this the fix?
madbaron Jun 1, 2026
9aa1a5d
hardcode genconf
madbaron Jun 1, 2026
b773e02
prepend PROJECT_BINARY_DIR
madbaron Jun 1, 2026
3e03677
build hook
madbaron Jun 1, 2026
a50c097
rollback test env
madbaron Jun 1, 2026
285c954
preload
Jun 2, 2026
74fa975
cleanup of previos fix attempt
madbaron Jun 2, 2026
f7a5e7e
updated ILD tests
Jun 2, 2026
61b57c4
comments from Paul
madbaron Jun 2, 2026
2f38a4f
minor cleanup
madbaron Jun 2, 2026
f9ddd54
update README
madbaron Jun 2, 2026
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
32 changes: 32 additions & 0 deletions .github/workflows/.key4hep-build-env
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Sourced by key4hep/key4hep-actions/key4hep-build from inside the build/
# directory, immediately before `cmake ..`.
#
# Why this exists
# ---------------
# Some of the stacks we build against already ship a copy of k4ActsTracking
# (notably the LCG `devkey-head` view used for the nightly alma9 job). On the
# `*.hsf.org/key4hep` stacks this is handled by `k4_local_repo`, which makes the
# freshly built tree shadow the in-stack copy -- but `k4_local_repo` does not
# exist in the LCG views, so nothing shadows it there.
#
# Gaudi generates the runtime component list by invoking
# listcomponents --output k4ActsTrackingPlugins.components libk4ActsTrackingPlugins.so
# with the *bare soname*. The dynamic loader resolves that name through
# LD_LIBRARY_PATH, which (in the generated build environment) starts with the
# stack's lib directory and does NOT contain the build tree. It therefore
# introspects the stale in-stack libk4ActsTrackingPlugins.so and copies its
# component list verbatim -- silently dropping any component that is new in this
# checkout (e.g. CKFTrackingAlg). At runtime Gaudi then reports the missing
# component as "unknown (No factory available)". (genconf is unaffected because
# it is handed the absolute build-tree path.)
#
# Prepending the build-tree plugin directory (where libk4ActsTrackingPlugins.so
# is linked) makes the bare soname resolve to the freshly built library. This
# value is captured into the generated build environment (k4actstrackingenv.sh)
# at configure time and is what the `run` wrapper uses when it drives
# listcomponents during the build. Harmless on the stacks where k4_local_repo
# already does the right thing.
#
# NOTE: the action `cd`s into build/ before sourcing this file, so ${PWD} is the
# build directory and ${PWD}/k4ActsTracking is the plugin library output dir.
export LD_LIBRARY_PATH="${PWD}/k4ActsTracking:${LD_LIBRARY_PATH}"
2 changes: 1 addition & 1 deletion .github/workflows/downstream-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ jobs:
strategy:
fail-fast: false
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5
- uses: key4hep/key4hep-actions/downstream-build@main
15 changes: 8 additions & 7 deletions .github/workflows/mucoll-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Free Disk Space (Ubuntu)
uses: endersonmenezes/free-disk-space@v2
uses: endersonmenezes/free-disk-space@v3
with:
remove_android: true
remove_dotnet: true
Expand All @@ -25,12 +25,14 @@ jobs:
remove_swap: true
remove_packages: "azure-cli google-cloud-cli microsoft-edge-stable google-chrome-stable firefox postgresql* temurin-* *llvm* mysql* dotnet-sdk-*"
remove_packages_one_command: true
remove_folders: "/usr/share/swift /usr/share/miniconda /usr/share/az* /usr/share/glade* /usr/local/lib/node_modules /usr/local/share/chromium /usr/local/share/powershell"
remove_folders: "/usr/share/swift /usr/share/miniconda /usr/share/az* /usr/local/lib/node_modules /usr/local/share/chromium /usr/local/share/powershell /usr/local/julia /usr/local/aws-cli /usr/local/aws-sam-cli /usr/share/gradle"
rm_cmd: "rmz" # Use 'rmz' for faster deletion (default: 'rm')
rmz_version: "3.1.1" # Required when rm_cmd is 'rmz'
testing: false
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- shell: bash
run: echo "NOW=$(date +'%Y-%m-%d')" >> $GITHUB_ENV
- uses: actions/cache/restore@v4
- uses: actions/cache/restore@v5
with:
path: ~/.cache/ccache
key: ccache-mucoll-image-${{ env.NOW }}
Expand Down Expand Up @@ -59,8 +61,7 @@ jobs:
-DCMAKE_INSTALL_PREFIX=$(pwd)/install \
-DCMAKE_CXX_FLAGS=" -fdiagnostics-color=always -Werror -Wno-error=deprecated-declarations"
cmake --build build
# Tests need OpenDataDetector, which is not present in the mucoll image atm
# ctest --test-dir build -j$(nproc) --output-on-failure
ctest --test-dir build -j$(nproc) --output-on-failure -E "(CLD|ILD)"
cmake --build build --target install

ccache -s
Expand All @@ -69,7 +70,7 @@ jobs:
chmod +x ${GITHUB_WORKSPACE}/build.sh

docker exec ci_container /bin/bash -c "/packages/build.sh"
- uses: actions/cache/save@v4
- uses: actions/cache/save@v5
if: always()
with:
path: ~/.cache/ccache
Expand Down
13 changes: 4 additions & 9 deletions k4ActsTracking/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ set(ACTS_LIBRARY_TARGETS "Acts::Core")
gaudi_add_library(k4ActsTracking
SOURCES
src/ActsGaudiLogger.cpp
src/CellIDSelector.cxx
LINK
DD4hep::DDCore
k4FWCore::k4FWCore
${ACTS_LIBRARY_TARGETS}
)
Expand All @@ -43,6 +45,7 @@ set(_plugin_sources
src/components/TrackTruthAlg.cxx
src/components/ActsTestPropagator.cpp
src/components/DD4hepBlueprintConstruction.cpp
src/components/CKFTrackingAlg.cpp
)

gaudi_add_module(k4ActsTrackingPlugins
Expand All @@ -69,12 +72,4 @@ install(TARGETS k4ActsTrackingPlugins
COMPONENT dev)

set(GAUDI_GENCONF_DIR "genConfDir")

function(set_test_env _testname)
set_property(TEST ${_testname} APPEND PROPERTY ENVIRONMENT
LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}:$<TARGET_FILE_DIR:k4ActsTrackingPlugins>:$<TARGET_FILE_DIR:ROOT::Core>:$<TARGET_FILE_DIR:k4FWCore::k4FWCore>:$<TARGET_FILE_DIR:EDM4HEP::edm4hep>:$<TARGET_FILE_DIR:podio::podio>:$ENV{LD_LIBRARY_PATH}
PYTHONPATH=${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}/${GAUDI_GENCONF_DIR}:$<TARGET_FILE_DIR:k4FWCore::k4FWCore>/../python:$ENV{PYTHONPATH}
PATH=$<TARGET_FILE_DIR:k4FWCore::k4FWCore>/../bin:$ENV{PATH}
K4ACTSTRACKING=${CMAKE_CURRENT_LIST_DIR}/
)
endfunction()
set_property(TARGET k4ActsTrackingPlugins PROPERTY GAUDI_GENCONF TRUE)
51 changes: 51 additions & 0 deletions k4ActsTracking/include/k4ActsTracking/CKFTrackingAlg.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2014-2024 Key4hep-Project.
*
* This file is part of Key4hep.
* See https://key4hep.github.io/key4hep-doc/ for further info.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once

// ACTS
#include <Acts/EventData/TrackParameters.hpp>

// Standard
#include <cmath>

namespace ACTSTracking {

//! Build a diagonal initial track covariance matrix from per-parameter error estimates
/**
* \param p Absolute momentum [ACTS units].
* \param errPos Local-position error [ACTS units].
* \param errPhi Azimuthal angle error [rad].
* \param errLambda Polar angle (lambda) error [rad].
* \param errRelP Relative momentum error (dimensionless fraction).
* \param errTime Time error [ACTS units].
* \return 5×5 diagonal bound covariance matrix.
*/
inline Acts::BoundMatrix makeInitialCovariance(double p, double errPos, double errPhi, double errLambda,
double errRelP, double errTime) {
Acts::BoundMatrix cov = Acts::BoundMatrix::Zero();
cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = std::pow(errPos, 2);
cov(Acts::eBoundLoc1, Acts::eBoundLoc1) = std::pow(errPos, 2);
cov(Acts::eBoundTime, Acts::eBoundTime) = std::pow(errTime, 2);
cov(Acts::eBoundPhi, Acts::eBoundPhi) = std::pow(errPhi, 2);
cov(Acts::eBoundTheta, Acts::eBoundTheta) = std::pow(errLambda, 2);
cov(Acts::eBoundQOverP, Acts::eBoundQOverP) = std::pow(errRelP * p / (p * p), 2);
return cov;
}

} // namespace ACTSTracking
125 changes: 125 additions & 0 deletions k4ActsTracking/include/k4ActsTracking/CellIDSelector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright (c) 2014-2024 Key4hep-Project.
*
* This file is part of Key4hep.
* See https://key4hep.github.io/key4hep-doc/ for further info.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef K4ACTSTRACKING_CELLIDSELECTOR_H
#define K4ACTSTRACKING_CELLIDSELECTOR_H

#include <DD4hep/BitFieldCoder.h>
#include <Parsers/Primitives.h>

#include <string>
#include <vector>

namespace k4ActsTracking {

/// Selects detector hits by matching their DD4hep CellID against a set of
/// user-defined selection strings.
///
/// Each selection string describes a conjunction (AND) of field constraints.
/// Multiple selection strings passed to the constructor are evaluated as a
/// disjunction (OR): a CellID is accepted if it satisfies **at least one** of
/// them.
///
/// ## Selection string grammar
///
/// A selection string is a comma-separated list of `<field>:<value>`
/// constraints, where `<field>` must be a field name present in the DD4hep
/// encoding string supplied to the constructor.
///
/// ### Value syntax
///
/// | Syntax | Meaning |
/// |-----------------|----------------------------------------------|
/// | `field:N` | Field must equal the integer `N` |
/// | `field:N\|M\|…` | Field must equal one of `N`, `M`, … (OR) |
///
/// Fields that appear in the encoding string but are absent from the
/// selection are unconstrained. Specifying the same field more than
/// once in a single selection string is not detected as an error: only the
/// last occurrence takes effect.
///
/// ### Examples
///
/// ```
/// // Accept hits in system 8, layer 3 (any module, sensor, side, …)
/// CellIDSelector sel(enc, {"system:8,layer:3"});
///
/// // Accept hits in system 5 on layers 1, 4, or 5 OR
/// // in system 3 on layers 2, 6, or 8 OR
/// // any hit whose sensor field equals 42
/// CellIDSelector sel(enc, {"system:5,layer:1|4|5",
/// "system:3,layer:2|6|8",
/// "sensor:42"});
///
/// // Empty selection list — rejects every CellID
/// CellIDSelector sel(enc, {});
/// ```
///
/// ### Expansion to (mask, value) pairs
///
/// Internally each selection string is expanded into one or more
/// `Selector{mask, value}` pairs via the Cartesian product of the
/// per-field value lists. A CellID passes the selector when
/// `(cellID & mask) == (value & mask)`. Fields absent from the selection
/// contribute neither to `mask` nor to `value`.
class CellIDSelector {
public:
/// A single bitmask/value pair produced from one element of the Cartesian
/// product expansion of a selection string.
struct Selector {
dd4hep::CellID mask; ///< Bits that are relevant for this selector
dd4hep::CellID value; ///< Expected bit pattern after masking
};

CellIDSelector() = default;
CellIDSelector(const CellIDSelector&) = default;
CellIDSelector& operator=(const CellIDSelector&) = default;
CellIDSelector(CellIDSelector&&) = default;
CellIDSelector& operator=(CellIDSelector&&) = default;
~CellIDSelector() = default;

/// Construct a selector from a DD4hep encoding string and a list of
/// selection strings.
///
/// @param encodingString DD4hep BitFieldCoder descriptor, e.g.
/// `"system:8,side:-2,layer:5,module:7,sensor:10"`
/// @param selections List of selection strings (OR-ed together).
/// An empty list rejects every CellID.
/// @throws std::invalid_argument if a selection string is malformed or
/// references an unknown field.
CellIDSelector(const std::string& encodingString, const std::vector<std::string>& selections);

/// Return `true` if @p cellID satisfies at least one configured selector.
bool accept(const dd4hep::CellID cellID) const;

/// Expand a single selection string into its `Selector` pairs.
///
/// Useful for inspection and testing. The returned vector contains one
/// entry per element of the Cartesian product of all constrained field
/// value lists.
///
/// @param selection A single selection string (see class-level grammar).
/// @throws std::invalid_argument if the string is malformed.
static std::vector<Selector> getSelectionMasks(const std::string& selection, const dd4hep::BitFieldCoder& decoder);

private:
std::vector<Selector> m_selectors{};
};
} // namespace k4ActsTracking

#endif // K4ACTSTRACKING_CELLIDSELECTOR_H
13 changes: 8 additions & 5 deletions k4ActsTracking/include/k4ActsTracking/IActsGeoSvc.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@

#include <GaudiKernel/IService.h>

#include <cstdint>
#include <DD4hep/Primitives.h>

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

namespace dd4hep {
Expand All @@ -40,14 +42,15 @@ namespace Acts {

class GAUDI_API IActsGeoSvc : virtual public IService {
public:
using CellIDSurfaceMap = std::unordered_map<uint64_t, const Acts::Surface*>;
using CellIDSurfaceMap = std::unordered_map<dd4hep::CellID, const Acts::Surface*>;

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::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 ~IActsGeoSvc() = default;
};
Expand Down
Loading
Loading