Skip to content

Commit

Permalink
Merge branch 'main' into feat-tgeo-binding
Browse files Browse the repository at this point in the history
  • Loading branch information
kodiakhq[bot] authored Dec 6, 2024
2 parents 9a4cbb8 + feac686 commit 9293170
Show file tree
Hide file tree
Showing 119 changed files with 1,569 additions and 896 deletions.
9 changes: 9 additions & 0 deletions CI/physmon/phys_perf_mon.sh
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,15 @@ function trackfinding() {
$path/performance_finding_ckf_ambi.html \
$path/performance_finding_ckf_ambi
fi

if [ -f $refdir/$path/performance_finding_ckf_ml_solver.root ]; then
run_histcmp \
$outdir/data/$path/performance_finding_ckf_ml_solver.root \
$refdir/$path/performance_finding_ckf_ml_solver.root \
"ML Ambisolver | ${name}" \
$path/performance_finding_ckf_ml_solver.html \
$path/performance_finding_ckf_ml_solver
fi
}

function vertexing() {
Expand Down
Binary file not shown.
Binary file not shown.
27 changes: 27 additions & 0 deletions CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@
CkfConfig,
addCKFTracks,
addAmbiguityResolution,
addAmbiguityResolutionML,
AmbiguityResolutionConfig,
AmbiguityResolutionMLConfig,
addVertexFitting,
VertexFinder,
TrackSelectorConfig,
Expand Down Expand Up @@ -134,13 +136,25 @@
outputDirRoot=tp,
)

addAmbiguityResolutionML(
s,
AmbiguityResolutionMLConfig(
maximumSharedHits=3, maximumIterations=1000000, nMeasurementsMin=6
),
tracks="ckf_tracks",
outputDirRoot=tp,
onnxModelFile=Path(__file__).resolve().parent.parent.parent.parent
/ "thirdparty/OpenDataDetector/data/duplicateClassifier.onnx",
)

addAmbiguityResolution(
s,
AmbiguityResolutionConfig(
maximumSharedHits=3,
maximumIterations=100000,
nMeasurementsMin=6,
),
tracks="ckf_tracks",
outputDirRoot=tp,
)

Expand Down Expand Up @@ -187,6 +201,17 @@
tp / "performance_fitting_ambi.root",
tp / "performance_fitting_ckf_ambi.root",
)

shutil.move(
tp / "performance_finding_ambiML.root",
tp / "performance_finding_ckf_ml_solver.root",
)

shutil.move(
tp / "performance_fitting_ambiML.root",
tp / "performance_fitting_ckf_ml_solver.root",
)

for vertexing in ["amvf_gauss_notime", "amvf_grid_time"]:
shutil.move(
tp / f"{vertexing}/performance_vertexing.root",
Expand All @@ -200,6 +225,8 @@
"performance_fitting_ckf.root",
"performance_finding_ckf_ambi.root",
"performance_fitting_ckf_ambi.root",
"performance_finding_ckf_ml_solver.root",
"performance_fitting_ckf_ml_solver.root",
"performance_vertexing_amvf_gauss_notime.root",
"performance_vertexing_amvf_grid_time.root",
]:
Expand Down
51 changes: 51 additions & 0 deletions Core/include/Acts/AmbiguityResolution/AmbiguityNetworkConcept.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// This file is part of the ACTS project.
//
// Copyright (C) 2016 CERN for the benefit of the ACTS project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/EventData/TrackContainer.hpp"
#include "Acts/EventData/TrackContainerFrontendConcept.hpp"
#include "Acts/EventData/VectorMultiTrajectory.hpp"
#include "Acts/EventData/VectorTrackContainer.hpp"
#include "Acts/Utilities/Concepts.hpp"

namespace Acts {

/// @brief Concept for the ambiguity network used in the ambiguity resolution
///
/// The ambiguity network correspond to the AmbiguityTrackClassifier found in
/// the Onnx plugin. It is used to score the tracks and select the best ones.
///
/// The constructor of the Ambiguity Solver network should take string as input
/// corresponding to the path of the ONNX model.
/// The implementation of the Ambiguity Solver network should have two methods:
/// - inferScores: takes clusters (a list of track ID associated with a cluster
/// ID) and the track container and return an outputTensor (list of scores for
/// each track in the clusters).
/// - trackSelection: Takes clusters and the output tensor from the inferScores
/// method and return the list of track ID to keep.
///
/// @tparam N the type of the network
template <typename network_t>
concept AmbiguityNetworkConcept = requires(
TrackContainer<VectorTrackContainer, VectorMultiTrajectory,
detail::ValueHolder> &tracks,
std::unordered_map<std::size_t, std::vector<std::size_t>> &clusters,
std::vector<std::vector<float>> &outputTensor, const char *modelPath,
network_t &n) {
{ network_t(modelPath) } -> std::same_as<network_t>;

{
n.inferScores(clusters, tracks)
} -> std::same_as<std::vector<std::vector<float>>>;
{
n.trackSelection(clusters, outputTensor)
} -> std::same_as<std::vector<std::size_t>>;
};

} // namespace Acts
136 changes: 136 additions & 0 deletions Core/include/Acts/AmbiguityResolution/AmbiguityResolutionML.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// This file is part of the ACTS project.
//
// Copyright (C) 2016 CERN for the benefit of the ACTS project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/AmbiguityResolution/AmbiguityNetworkConcept.hpp"
#include "Acts/Definitions/Units.hpp"
#include "Acts/EventData/TrackContainer.hpp"
#include "Acts/Utilities/Delegate.hpp"
#include "Acts/Utilities/Logger.hpp"

#include <cstddef>
#include <map>
#include <memory>
#include <string>
#include <tuple>
#include <vector>

namespace Acts {

/// Generic implementation of the machine learning ambiguity resolution
/// Contains method for data preparations
template <AmbiguityNetworkConcept AmbiguityNetwork>
class AmbiguityResolutionML {
public:
struct Config {
/// Path to the model file for the duplicate neural network
std::string inputDuplicateNN = "";
/// Minimum number of measurement to form a track.
std::size_t nMeasurementsMin = 7;
};
/// Construct the ambiguity resolution algorithm.
///
/// @param cfg is the algorithm configuration
/// @param logger is the logging instance
AmbiguityResolutionML(const Config& cfg,
std::unique_ptr<const Logger> logger = getDefaultLogger(
"AmbiguityResolutionML", Logging::INFO))
: m_cfg{cfg},
m_duplicateClassifier(m_cfg.inputDuplicateNN.c_str()),
m_logger{std::move(logger)} {}

/// Associate the hits to the tracks
///
/// This algorithm performs the mapping of hits ID to track ID. Our final goal
/// is too loop over all the tracks (and their associated hits) by order of
/// decreasing number hits for this we use a multimap where the key is the
/// number of hits as this will automatically perform the sorting.
///
/// @param tracks is the input track container
/// @param sourceLinkHash is the hash function for the source link, will be used to associate to tracks
/// @param sourceLinkEquality is the equality function for the source link used used to associated hits to tracks
/// @return an ordered list containing pairs of track ID and associated measurement ID
template <TrackContainerFrontend track_container_t,
typename source_link_hash_t, typename source_link_equality_t>
std::multimap<int, std::pair<std::size_t, std::vector<std::size_t>>>
mapTrackHits(const track_container_t& tracks,
const source_link_hash_t& sourceLinkHash,
const source_link_equality_t& sourceLinkEquality) const {
// A map to store (and generate) the measurement index for each source link
auto measurementIndexMap =
std::unordered_map<SourceLink, std::size_t, source_link_hash_t,
source_link_equality_t>(0, sourceLinkHash,
sourceLinkEquality);

// A map to store the track Id and their associated measurements ID, a
// multimap is used to automatically sort the tracks by the number of
// measurements
std::multimap<int, std::pair<std::size_t, std::vector<std::size_t>>>
trackMap;
std::size_t trackIndex = 0;
std::vector<std::size_t> measurements;
// Loop over all the trajectories in the events
for (const auto& track : tracks) {
// Kick out tracks that do not fulfill our initial requirements
if (track.nMeasurements() < m_cfg.nMeasurementsMin) {
continue;
}
measurements.clear();
for (auto ts : track.trackStatesReversed()) {
if (ts.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag)) {
SourceLink sourceLink = ts.getUncalibratedSourceLink();
// assign a new measurement index if the source link was not seen yet
auto emplace = measurementIndexMap.try_emplace(
sourceLink, measurementIndexMap.size());
measurements.push_back(emplace.first->second);
}
}
trackMap.emplace(track.nMeasurements(),
std::make_pair(trackIndex, measurements));
++trackIndex;
}
return trackMap;
}

/// Select the track associated with each cluster
///
/// In this algorithm the call the neural network to score the tracks and then
/// select the track with the highest score in each cluster
///
/// @param clusters is a map of clusters, each cluster correspond to a vector of track ID
/// @param tracks is the input track container
/// @return a vector of trackID corresponding tho the good tracks
template <TrackContainerFrontend track_container_t>
std::vector<std::size_t> solveAmbiguity(
std::unordered_map<std::size_t, std::vector<std::size_t>>& clusters,
const track_container_t& tracks) const {
std::vector<std::vector<float>> outputTensor =
m_duplicateClassifier.inferScores(clusters, tracks);
std::vector<std::size_t> goodTracks =
m_duplicateClassifier.trackSelection(clusters, outputTensor);

return goodTracks;
}

private:
// Configuration
Config m_cfg;

// The neural network for duplicate classification, the network
// implementation is chosen with the AmbiguityNetwork template parameter
AmbiguityNetwork m_duplicateClassifier;

/// Logging instance
std::unique_ptr<const Logger> m_logger = nullptr;

/// Private access to logging instance
const Logger& logger() const { return *m_logger; }
};

} // namespace Acts
4 changes: 2 additions & 2 deletions Core/include/Acts/EventData/MultiComponentTrackParameters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,11 @@ class MultiComponentBoundTrackParameters {

/// Get the weight and a GenericBoundTrackParameters object for one component
std::pair<double, Parameters> operator[](std::size_t i) const {
return std::make_pair(
return {
std::get<double>(m_components[i]),
Parameters(m_surface, std::get<BoundVector>(m_components[i]),
std::get<std::optional<BoundSquareMatrix>>(m_components[i]),
m_particleHypothesis));
m_particleHypothesis)};
}

/// Parameters vector.
Expand Down
67 changes: 67 additions & 0 deletions Core/include/Acts/MagneticField/MultiRangeBField.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// This file is part of the ACTS project.
//
// Copyright (C) 2016 CERN for the benefit of the ACTS project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

#pragma once
#include "Acts/Definitions/Algebra.hpp"
#include "Acts/MagneticField/MagneticFieldContext.hpp"
#include "Acts/MagneticField/MagneticFieldError.hpp"
#include "Acts/MagneticField/MagneticFieldProvider.hpp"
#include "Acts/Utilities/RangeXD.hpp"

namespace Acts {

/// @ingroup MagneticField
///
/// @brief Magnetic field provider modelling a magnetic field consisting of
/// several (potentially overlapping) regions of constant values.
class MultiRangeBField final : public MagneticFieldProvider {
private:
struct Cache {
explicit Cache(const MagneticFieldContext& /*unused*/);

std::optional<std::size_t> index = {};
};

using BFieldRange = std::pair<RangeXD<3, double>, Vector3>;

// The different ranges and their corresponding field vectors. Note that
// regions positioned _later_ in this vector take priority over earlier
// regions.
std::vector<BFieldRange> fieldRanges;

public:
/// @brief Construct a magnetic field from a vector of ranges.
///
/// @warning These ranges are listed in increasing order of precedence,
/// i.e. ranges further along the vector have higher priority.
explicit MultiRangeBField(const std::vector<BFieldRange>& ranges);

explicit MultiRangeBField(std::vector<BFieldRange>&& ranges);

/// @brief Construct a cache object.
MagneticFieldProvider::Cache makeCache(
const MagneticFieldContext& mctx) const override;

/// @brief Request the value of the magnetic field at a given position.
///
/// @param [in] position Global 3D position for the lookup.
/// @param [in, out] cache Cache object.
/// @returns A successful value containing a field vector if the given
/// location is contained inside any of the regions, or a failure value
/// otherwise.
Result<Vector3> getField(const Vector3& position,
MagneticFieldProvider::Cache& cache) const override;

/// @brief Get the field gradient at a given position.
///
/// @warning This is not currently implemented.
Result<Vector3> getFieldGradient(
const Vector3& position, ActsMatrix<3, 3>& /*unused*/,
MagneticFieldProvider::Cache& cache) const override;
};
} // namespace Acts
2 changes: 1 addition & 1 deletion Core/include/Acts/Seeding/BinnedGroupIterator.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Acts::BinnedGroupIterator<grid_t>::operator*() const {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-overread"
#endif
return std::make_tuple(std::move(bottoms), global_index, std::move(tops));
return {std::move(bottoms), global_index, std::move(tops)};
#if defined(__GNUC__) && __GNUC__ >= 12 && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
Expand Down
7 changes: 3 additions & 4 deletions Core/include/Acts/Seeding/SeedFinder.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,7 @@ std::pair<float, float> SeedFinder<external_spacepoint_t, grid_t, platform_t>::
const external_spacepoint_t& spM,
const Acts::Range1D<float>& rMiddleSPRange) const {
if (m_config.useVariableMiddleSPRange) {
return std::make_pair(rMiddleSPRange.min(), rMiddleSPRange.max());
return {rMiddleSPRange.min(), rMiddleSPRange.max()};
}
if (!m_config.rRangeMiddleSP.empty()) {
/// get zBin position of the middle SP
Expand All @@ -848,10 +848,9 @@ std::pair<float, float> SeedFinder<external_spacepoint_t, grid_t, platform_t>::
int zBin = std::distance(m_config.zBinEdges.begin(), pVal);
/// protects against zM at the limit of zBinEdges
zBin == 0 ? zBin : --zBin;
return std::make_pair(m_config.rRangeMiddleSP[zBin][0],
m_config.rRangeMiddleSP[zBin][1]);
return {m_config.rRangeMiddleSP[zBin][0], m_config.rRangeMiddleSP[zBin][1]};
}
return std::make_pair(m_config.rMinMiddle, m_config.rMaxMiddle);
return {m_config.rMinMiddle, m_config.rMaxMiddle};
}

} // namespace Acts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@

namespace Acts::detail {

/// Clusterise tracks based on shared hits
/// Cluster tracks based on shared hits.
///
/// In this algorithm we will loop through all the tracks by decreasing number
/// of measurements. Cluster are created when a new track is encountered that
/// doesn't share hits with the leading track of a previous cluster (with the
/// leading track defined as the track that lead to the cluster creation). If a
/// track shares hits with the leading track of a cluster, it is added to that
/// cluster. If a track shares hits with multiple clusters, it is associated to
/// the cluster with the leading track with the most hits.
///
/// @param trackMap : Multimap storing pair of track ID and vector of measurement ID. The keys are the number of measurement and are just there to facilitate the ordering.
/// @return an unordered map representing the clusters, the keys the ID of the primary track of each cluster and the store a vector of track IDs.
Expand Down
Loading

0 comments on commit 9293170

Please sign in to comment.