diff --git a/CI/check_fpe_masks.py b/CI/check_fpe_masks.py index d29e8219203..4c403aa5a27 100755 --- a/CI/check_fpe_masks.py +++ b/CI/check_fpe_masks.py @@ -2,7 +2,6 @@ from pathlib import Path import os import re -import sys import asyncio import aiohttp @@ -53,12 +52,10 @@ async def check(token: str, repo: str): loc = f"{rel}:{i}" this_ok = True - issue_info = number try: issue = await gh.getitem( f"repos/{repo}/issues/{number}" ) - issue_info = issue["html_url"] except gidgethub.BadRequest as e: print( f":red_circle: [bold]FPE mask at {loc} has invalid issue number {number}[/bold]" diff --git a/CI/check_include_guards.py b/CI/check_include_guards.py index 7d57e9b14a0..146322b3bda 100755 --- a/CI/check_include_guards.py +++ b/CI/check_include_guards.py @@ -1,10 +1,7 @@ #!/usr/bin/env python3 -from __future__ import print_function - import argparse import os from glob import glob -from concurrent.futures import ProcessPoolExecutor import re from fnmatch import fnmatch import sys diff --git a/CI/clang_tidy/run_clang_tidy.py b/CI/clang_tidy/run_clang_tidy.py index 900a15a388c..e7b8c5c0074 100755 --- a/CI/clang_tidy/run_clang_tidy.py +++ b/CI/clang_tidy/run_clang_tidy.py @@ -5,7 +5,6 @@ import subprocess from subprocess import check_call, check_output, CalledProcessError from pathlib import Path -import json import re import sys import os @@ -58,9 +57,6 @@ def main(): args.source.exists() and args.source.is_dir() ), f"{args.source} is not a directory" - with (args.build / "compile_commands.json").open() as f: - compilation_database = json.load(f) - futures = [] files = [] active_files = {} diff --git a/CI/fix_pragma.py b/CI/fix_pragma.py index 63b9fe9655b..767601f1f0e 100755 --- a/CI/fix_pragma.py +++ b/CI/fix_pragma.py @@ -1,10 +1,7 @@ #!/usr/bin/env python3 -from __future__ import print_function - import argparse import os from glob import glob -from concurrent.futures import ProcessPoolExecutor import re code_format = """ diff --git a/CI/perf_headwind.py b/CI/perf_headwind.py index 10b9c92968b..86fe88cb296 100755 --- a/CI/perf_headwind.py +++ b/CI/perf_headwind.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import sys -from headwind.spec import CollectorResult, Run, Metric +from headwind.spec import CollectorResult, Metric import pandas as pd diff --git a/CI/physmon/reference/particles_fatras_hist.root b/CI/physmon/reference/particles_fatras_hist.root index e98c0393ae5..8b78d8977b0 100644 Binary files a/CI/physmon/reference/particles_fatras_hist.root and b/CI/physmon/reference/particles_fatras_hist.root differ diff --git a/CI/physmon/reference/particles_geant4_hist.root b/CI/physmon/reference/particles_geant4_hist.root index 2479a93b0e4..25fa6399363 100644 Binary files a/CI/physmon/reference/particles_geant4_hist.root and b/CI/physmon/reference/particles_geant4_hist.root differ diff --git a/CI/physmon/reference/performance_ambi_orthogonal.root b/CI/physmon/reference/performance_ambi_orthogonal.root index 9e701ebcd12..4d0dbc9c6a8 100644 Binary files a/CI/physmon/reference/performance_ambi_orthogonal.root and b/CI/physmon/reference/performance_ambi_orthogonal.root differ diff --git a/CI/physmon/reference/performance_ambi_seeded.root b/CI/physmon/reference/performance_ambi_seeded.root index d32e7a83053..82e218a0cd6 100644 Binary files a/CI/physmon/reference/performance_ambi_seeded.root and b/CI/physmon/reference/performance_ambi_seeded.root differ diff --git a/CI/physmon/reference/performance_ambi_ttbar.root b/CI/physmon/reference/performance_ambi_ttbar.root index 42808c0edfd..447854c935b 100644 Binary files a/CI/physmon/reference/performance_ambi_ttbar.root and b/CI/physmon/reference/performance_ambi_ttbar.root differ diff --git a/CI/physmon/reference/performance_amvf_gridseeder_seeded_hist.root b/CI/physmon/reference/performance_amvf_gridseeder_seeded_hist.root index bca069abd1b..7aa873642da 100644 Binary files a/CI/physmon/reference/performance_amvf_gridseeder_seeded_hist.root and b/CI/physmon/reference/performance_amvf_gridseeder_seeded_hist.root differ diff --git a/CI/physmon/reference/performance_amvf_gridseeder_ttbar_hist.root b/CI/physmon/reference/performance_amvf_gridseeder_ttbar_hist.root index 9a7934ccadb..5046f8437a0 100644 Binary files a/CI/physmon/reference/performance_amvf_gridseeder_ttbar_hist.root and b/CI/physmon/reference/performance_amvf_gridseeder_ttbar_hist.root differ diff --git a/CI/physmon/reference/performance_amvf_orthogonal_hist.root b/CI/physmon/reference/performance_amvf_orthogonal_hist.root index 63c5dd42875..9b987799835 100644 Binary files a/CI/physmon/reference/performance_amvf_orthogonal_hist.root and b/CI/physmon/reference/performance_amvf_orthogonal_hist.root differ diff --git a/CI/physmon/reference/performance_amvf_seeded_hist.root b/CI/physmon/reference/performance_amvf_seeded_hist.root index 37deba488c3..a12095a3cb9 100644 Binary files a/CI/physmon/reference/performance_amvf_seeded_hist.root and b/CI/physmon/reference/performance_amvf_seeded_hist.root differ diff --git a/CI/physmon/reference/performance_amvf_truth_estimated_hist.root b/CI/physmon/reference/performance_amvf_truth_estimated_hist.root index 84a637bab78..31cf6145a29 100644 Binary files a/CI/physmon/reference/performance_amvf_truth_estimated_hist.root and b/CI/physmon/reference/performance_amvf_truth_estimated_hist.root differ diff --git a/CI/physmon/reference/performance_amvf_truth_smeared_hist.root b/CI/physmon/reference/performance_amvf_truth_smeared_hist.root index a1057f9640d..642278c3b5c 100644 Binary files a/CI/physmon/reference/performance_amvf_truth_smeared_hist.root and b/CI/physmon/reference/performance_amvf_truth_smeared_hist.root differ diff --git a/CI/physmon/reference/performance_amvf_ttbar_hist.root b/CI/physmon/reference/performance_amvf_ttbar_hist.root index 2e1566940c3..6d8156be602 100644 Binary files a/CI/physmon/reference/performance_amvf_ttbar_hist.root and b/CI/physmon/reference/performance_amvf_ttbar_hist.root differ diff --git a/CI/physmon/reference/performance_ckf_orthogonal.root b/CI/physmon/reference/performance_ckf_orthogonal.root index d7727cf23d6..3b74c04e73b 100644 Binary files a/CI/physmon/reference/performance_ckf_orthogonal.root and b/CI/physmon/reference/performance_ckf_orthogonal.root differ diff --git a/CI/physmon/reference/performance_ckf_seeded.root b/CI/physmon/reference/performance_ckf_seeded.root index 7aefaca375e..fd993815661 100644 Binary files a/CI/physmon/reference/performance_ckf_seeded.root and b/CI/physmon/reference/performance_ckf_seeded.root differ diff --git a/CI/physmon/reference/performance_ckf_truth_estimated.root b/CI/physmon/reference/performance_ckf_truth_estimated.root index ceaef2121c0..b6940e6288d 100644 Binary files a/CI/physmon/reference/performance_ckf_truth_estimated.root and b/CI/physmon/reference/performance_ckf_truth_estimated.root differ diff --git a/CI/physmon/reference/performance_ckf_truth_smeared.root b/CI/physmon/reference/performance_ckf_truth_smeared.root index 908a29e420e..0705062a396 100644 Binary files a/CI/physmon/reference/performance_ckf_truth_smeared.root and b/CI/physmon/reference/performance_ckf_truth_smeared.root differ diff --git a/CI/physmon/reference/performance_ckf_ttbar.root b/CI/physmon/reference/performance_ckf_ttbar.root index 55dcfa37168..7a8bb020d16 100644 Binary files a/CI/physmon/reference/performance_ckf_ttbar.root and b/CI/physmon/reference/performance_ckf_ttbar.root differ diff --git a/CI/physmon/reference/performance_gx2f.root b/CI/physmon/reference/performance_gx2f.root index 3f9c4482d04..0c1c3facef3 100644 Binary files a/CI/physmon/reference/performance_gx2f.root and b/CI/physmon/reference/performance_gx2f.root differ diff --git a/CI/physmon/reference/performance_ivf_orthogonal_hist.root b/CI/physmon/reference/performance_ivf_orthogonal_hist.root index 4e8f0efdf0e..366411bf431 100644 Binary files a/CI/physmon/reference/performance_ivf_orthogonal_hist.root and b/CI/physmon/reference/performance_ivf_orthogonal_hist.root differ diff --git a/CI/physmon/reference/performance_ivf_seeded_hist.root b/CI/physmon/reference/performance_ivf_seeded_hist.root index 48ab43274f6..2137b17adc4 100644 Binary files a/CI/physmon/reference/performance_ivf_seeded_hist.root and b/CI/physmon/reference/performance_ivf_seeded_hist.root differ diff --git a/CI/physmon/reference/performance_ivf_truth_estimated_hist.root b/CI/physmon/reference/performance_ivf_truth_estimated_hist.root index 0b4e6afcf01..8908c1e609d 100644 Binary files a/CI/physmon/reference/performance_ivf_truth_estimated_hist.root and b/CI/physmon/reference/performance_ivf_truth_estimated_hist.root differ diff --git a/CI/physmon/reference/performance_ivf_truth_smeared_hist.root b/CI/physmon/reference/performance_ivf_truth_smeared_hist.root index 072e2d4a47f..9e614ba8b00 100644 Binary files a/CI/physmon/reference/performance_ivf_truth_smeared_hist.root and b/CI/physmon/reference/performance_ivf_truth_smeared_hist.root differ diff --git a/CI/physmon/reference/tracksummary_ckf_orthogonal_hist.root b/CI/physmon/reference/tracksummary_ckf_orthogonal_hist.root index 9e557cc2e54..d3423b1dc32 100644 Binary files a/CI/physmon/reference/tracksummary_ckf_orthogonal_hist.root and b/CI/physmon/reference/tracksummary_ckf_orthogonal_hist.root differ diff --git a/CI/physmon/reference/tracksummary_ckf_seeded_hist.root b/CI/physmon/reference/tracksummary_ckf_seeded_hist.root index 353b25bce7f..6f850818a06 100644 Binary files a/CI/physmon/reference/tracksummary_ckf_seeded_hist.root and b/CI/physmon/reference/tracksummary_ckf_seeded_hist.root differ diff --git a/CI/physmon/reference/tracksummary_ckf_truth_estimated_hist.root b/CI/physmon/reference/tracksummary_ckf_truth_estimated_hist.root index da7bc88cd11..8eab3640285 100644 Binary files a/CI/physmon/reference/tracksummary_ckf_truth_estimated_hist.root and b/CI/physmon/reference/tracksummary_ckf_truth_estimated_hist.root differ diff --git a/CI/physmon/reference/tracksummary_ckf_truth_smeared_hist.root b/CI/physmon/reference/tracksummary_ckf_truth_smeared_hist.root index 0fe24fb6438..a1eeba9fb60 100644 Binary files a/CI/physmon/reference/tracksummary_ckf_truth_smeared_hist.root and b/CI/physmon/reference/tracksummary_ckf_truth_smeared_hist.root differ diff --git a/CI/physmon/reference/tracksummary_ckf_ttbar_hist.root b/CI/physmon/reference/tracksummary_ckf_ttbar_hist.root index 3b3bcf66341..1eaf4c556bf 100644 Binary files a/CI/physmon/reference/tracksummary_ckf_ttbar_hist.root and b/CI/physmon/reference/tracksummary_ckf_ttbar_hist.root differ diff --git a/CI/physmon/summary.py b/CI/physmon/summary.py index 01aead939da..dfd35331a55 100755 --- a/CI/physmon/summary.py +++ b/CI/physmon/summary.py @@ -3,7 +3,6 @@ import argparse import re -import functools import os import csv diff --git a/CI/physmon/workflows/physmon_ckf_tracking.py b/CI/physmon/workflows/physmon_ckf_tracking.py index 92b361bf128..67a02c9a787 100755 --- a/CI/physmon/workflows/physmon_ckf_tracking.py +++ b/CI/physmon/workflows/physmon_ckf_tracking.py @@ -136,9 +136,12 @@ def run_ckf_tracking(truthSmearedSeeded, truthEstimatedSeeded, label): pt=(500 * u.MeV, None), loc0=(-4.0 * u.mm, 4.0 * u.mm), nMeasurementsMin=6, + maxHoles=2, + maxOutliers=2, ), CkfConfig( seedDeduplication=False if truthSmearedSeeded else True, + stayOnSeed=False if truthSmearedSeeded else True, ), outputDirRoot=tp, ) diff --git a/CI/physmon/workflows/physmon_track_finding_ttbar.py b/CI/physmon/workflows/physmon_track_finding_ttbar.py index cc23bbe7dd1..e9a6ddd55b2 100755 --- a/CI/physmon/workflows/physmon_track_finding_ttbar.py +++ b/CI/physmon/workflows/physmon_track_finding_ttbar.py @@ -102,9 +102,12 @@ pt=(500 * u.MeV, None), loc0=(-4.0 * u.mm, 4.0 * u.mm), nMeasurementsMin=6, + maxHoles=2, + maxOutliers=2, ), CkfConfig( seedDeduplication=True, + stayOnSeed=True, ), outputDirRoot=tp, ) diff --git a/CI/physmon/workflows/physmon_vertexing.py b/CI/physmon/workflows/physmon_vertexing.py index 954109a8880..c20dace32c8 100755 --- a/CI/physmon/workflows/physmon_vertexing.py +++ b/CI/physmon/workflows/physmon_vertexing.py @@ -20,6 +20,7 @@ SeedFinderConfigArg, SeedFinderOptionsArg, SeedingAlgorithm, + CkfConfig, addCKFTracks, addAmbiguityResolution, AmbiguityResolutionConfig, @@ -119,6 +120,12 @@ def run_vertexing(fitter, mu, events): loc0=(-4.0 * u.mm, 4.0 * u.mm), pt=(500 * u.MeV, None), nMeasurementsMin=6, + maxHoles=2, + maxOutliers=2, + ), + CkfConfig( + seedDeduplication=True, + stayOnSeed=True, ), ) diff --git a/CI/release.py b/CI/release.py index 9fa8552876c..827fd7bf1dc 100755 --- a/CI/release.py +++ b/CI/release.py @@ -2,7 +2,6 @@ import os import asyncio from typing import List, Optional, Tuple -import re from pathlib import Path import sys import http diff --git a/CI/util.py b/CI/util.py index 9587c79a3e4..bb08dafcb0a 100644 --- a/CI/util.py +++ b/CI/util.py @@ -1,4 +1,3 @@ -import os import contextlib import sys diff --git a/Core/include/Acts/Detector/ProtoBinning.hpp b/Core/include/Acts/Detector/ProtoBinning.hpp index f3adb4e0779..d0daeb2808a 100644 --- a/Core/include/Acts/Detector/ProtoBinning.hpp +++ b/Core/include/Acts/Detector/ProtoBinning.hpp @@ -10,6 +10,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Common.hpp" +#include "Acts/Utilities/BinUtility.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/detail/AxisFwd.hpp" @@ -130,6 +131,54 @@ struct ProtoBinning { /// @brief A binning description, it helps for screen output struct BinningDescription { + /// Convert the binning description into a bin utility + /// + /// @param binUtility the bin utility to be converted into a BinningDescription + static BinningDescription fromBinUtility(const BinUtility& binUtility) { + BinningDescription bDesc; + for (const auto& bData : binUtility.binningData()) { + // One proto binning per binning data + Acts::detail::AxisBoundaryType boundaryType = + bData.option == open ? Acts::detail::AxisBoundaryType::Bound + : Acts::detail::AxisBoundaryType::Closed; + std::vector edges; + if (bData.type == equidistant) { + bDesc.binning.push_back(ProtoBinning(bData.binvalue, boundaryType, + bData.min, bData.max, bData.bins(), + 0u)); + + } else { + std::for_each(bData.boundaries().begin(), bData.boundaries().end(), + [&](ActsScalar edge) { edges.push_back(edge); }); + bDesc.binning.push_back( + ProtoBinning(bData.binvalue, boundaryType, edges, 0u)); + } + } + return bDesc; + } + + /// Convert to a BinUtility - only basic types are supported + /// + BinUtility toBinUtility() const { + BinUtility binUtility; + for (const auto& b : binning) { + Acts::BinningOption bOption = + b.boundaryType == Acts::detail::AxisBoundaryType::Bound + ? Acts::open + : Acts::closed; + if (b.axisType == Acts::detail::AxisType::Equidistant) { + binUtility += BinUtility(b.bins(), b.edges.front(), b.edges.back(), + bOption, b.binValue); + } else { + std::vector edges; + std::for_each(b.edges.begin(), b.edges.end(), + [&](ActsScalar edge) { edges.push_back(edge); }); + binUtility += BinUtility(edges, bOption, b.binValue); + } + } + return binUtility; + } + /// The contained binnings std::vector binning; diff --git a/Core/include/Acts/EventData/VectorTrackContainer.hpp b/Core/include/Acts/EventData/VectorTrackContainer.hpp index 50bdbc2cd88..df70cdabcfa 100644 --- a/Core/include/Acts/EventData/VectorTrackContainer.hpp +++ b/Core/include/Acts/EventData/VectorTrackContainer.hpp @@ -109,7 +109,6 @@ class VectorTrackContainerBase { bool checkConsistency() const { std::size_t size = m_tipIndex.size(); - (void)size; bool result = true; result = result && m_tipIndex.size() == size; diff --git a/Core/include/Acts/Geometry/ProtoLayerHelper.hpp b/Core/include/Acts/Geometry/ProtoLayerHelper.hpp index 4fa7a1321b7..3b912664d8e 100644 --- a/Core/include/Acts/Geometry/ProtoLayerHelper.hpp +++ b/Core/include/Acts/Geometry/ProtoLayerHelper.hpp @@ -36,14 +36,11 @@ class ProtoLayerHelper { /// Constructor with explicit config /// - /// @param config Explicit config struct /// @param logger logging instance - ProtoLayerHelper(const Config& config, + ProtoLayerHelper(const Config& /*config*/, std::unique_ptr logger = getDefaultLogger("ProtoLayerHelper", Logging::INFO)) - : m_logger(std::move(logger)) { - (void)config; - } + : m_logger(std::move(logger)) {} ~ProtoLayerHelper() = default; /// Sort the surfaces into ProtoLayers diff --git a/Core/include/Acts/Geometry/TrackingVolume.hpp b/Core/include/Acts/Geometry/TrackingVolume.hpp index f49c3bd3745..a61e3989c22 100644 --- a/Core/include/Acts/Geometry/TrackingVolume.hpp +++ b/Core/include/Acts/Geometry/TrackingVolume.hpp @@ -28,6 +28,7 @@ #include "Acts/Utilities/Intersection.hpp" #include "Acts/Utilities/Logger.hpp" #include "Acts/Utilities/Ray.hpp" +#include "Acts/Utilities/TransformRange.hpp" #include #include @@ -53,6 +54,10 @@ class Surface; class TrackingVolume; struct GeometryIdentifierHook; +/// Interface types of the Gen1 geometry model +/// @note This interface is being replaced, and is subject to removal +/// @{ + // master typedefs using TrackingVolumePtr = std::shared_ptr; using MutableTrackingVolumePtr = std::shared_ptr; @@ -83,6 +88,8 @@ using BoundaryIntersection = using BoundaryMultiIntersection = std::pair; +/// @} + /// @class TrackingVolume /// /// Full Volume description used in Tracking, @@ -122,7 +129,7 @@ class TrackingVolume : public Volume { /// @param containedVolumeArray are the static volumes that fill this volume /// @param volumeName is a string identifier TrackingVolume(const Transform3& transform, - std::shared_ptr volbounds, + std::shared_ptr volbounds, const std::shared_ptr& containedVolumeArray = nullptr, const std::string& volumeName = "undefined"); @@ -139,56 +146,22 @@ class TrackingVolume : public Volume { /// @param denseVolumeVector The contained dense volumes /// @param volumeName is a string identifier TrackingVolume( - const Transform3& transform, std::shared_ptr volumeBounds, + const Transform3& transform, + std::shared_ptr volumeBounds, std::shared_ptr volumeMaterial, std::unique_ptr staticLayerArray = nullptr, std::shared_ptr containedVolumeArray = nullptr, MutableTrackingVolumeVector denseVolumeVector = {}, const std::string& volumeName = "undefined"); - /// Return the associated Layer to the global position - /// - /// @param gctx The current geometry context object, e.g. alignment - /// @param position is the associated global position - /// - /// @return plain pointer to layer object - const Layer* associatedLayer(const GeometryContext& gctx, - const Vector3& position) const; - - /// @brief Resolves the volume into (compatible) Layers - /// - /// This is the method for the propagator/extrapolator - /// @tparam options_t Type of navigation options object for decomposition - /// - /// @param gctx The current geometry context object, e.g. alignment - /// @param position Position for the search - /// @param direction Direction for the search - /// @param options The templated navigation options - /// - /// @return vector of compatible intersections with layers - boost::container::small_vector compatibleLayers( - const GeometryContext& gctx, const Vector3& position, - const Vector3& direction, const NavigationOptions& options) const; - - /// @brief Returns all boundary surfaces sorted by the user. - /// - /// @tparam options_t Type of navigation options object for decomposition - /// @tparam sorter_t Type of the boundary surface sorter - /// - /// @param gctx The current geometry context object, e.g. alignment - /// @param position The position for searching - /// @param direction The direction for searching - /// @param options The templated navigation options - /// @param logger A @c Logger instance - /// - /// @return is the templated boundary intersection - boost::container::small_vector compatibleBoundaries( - const GeometryContext& gctx, const Vector3& position, - const Vector3& direction, const NavigationOptions& options, - const Logger& logger = getDummyLogger()) const; + /// Constructor from a regular volume + /// @param volume is the volume to be converted + /// @param volumeName is a string identifier + TrackingVolume(const Volume& volume, + const std::string& volumeName = "undefined"); + // @TODO: This needs to be refactored to include Gen3 volumes /// Return the associated sub Volume, returns THIS if no subVolume exists - /// /// @param gctx The current geometry context object, e.g. alignment /// @param position is the global position associated with that search /// @param tol Search position tolerance for dense volumes @@ -198,16 +171,6 @@ class TrackingVolume : public Volume { const Vector3& position, const double tol = 0.) const; - /// Return the confined static layer array - if it exists - /// @return the BinnedArray of static layers if exists - const LayerArray* confinedLayers() const; - - /// Return the confined volumes of this container array - if it exists - std::shared_ptr confinedVolumes() const; - - /// Return the confined dense volumes - const MutableTrackingVolumeVector denseVolumes() const; - /// @brief Visit all reachable surfaces /// /// @tparam visitor_t Type of the callable visitor @@ -292,40 +255,133 @@ class TrackingVolume : public Volume { volume->visitVolumes(visitor); } } + + for (const auto& volume : m_volumes) { + volume->visitVolumes(visitor); + } } /// Returns the VolumeName - for debug reason, might be depreciated later const std::string& volumeName() const; - /// Method to return the BoundarySurfaces - const TrackingVolumeBoundaries& boundarySurfaces() const; - /// Return the material of the volume const IVolumeMaterial* volumeMaterial() const; /// Return the material of the volume as shared pointer const std::shared_ptr& volumeMaterialSharedPtr() const; - /// Set the boundary surface material description + /// Set the volume material description /// /// The material is usually derived in a complicated way and loaded from /// a framework given source. As various volumes could potentially share the /// the same material description, it is provided as a shared object /// - /// @param surfaceMaterial Material description of this volume - /// @param bsFace Specifies which boundary surface to assign the material to - void assignBoundaryMaterial( - std::shared_ptr surfaceMaterial, - BoundarySurfaceFace bsFace); + /// @param material Material description of this volume + void assignVolumeMaterial(std::shared_ptr material); - /// Set the volume material description + /// Return the MotherVolume - if it exists + const TrackingVolume* motherVolume() const; + + /// Return the MotherVolume - if it exists + TrackingVolume* motherVolume(); + + /// Set the MotherVolume + /// + /// @param mvol is the mother volume + void setMotherVolume(TrackingVolume* mvol); + + using MutableVolumeRange = + detail::TransformRange>>; + using VolumeRange = detail::TransformRange< + detail::ConstDereference, + const std::vector>>; + + /// Return all volumes registered under this tracking volume + /// @return the range of volumes + VolumeRange volumes() const; + + /// Return mutable view of the registered volumes under this tracking volume + /// @return the range of volumes + MutableVolumeRange volumes(); + + /// Add a child volume to this tracking volume + /// @param volume The volume to add + /// @note The @p volume will have its mother volume assigned to @p this. + /// It will throw if @p volume already has a mother volume set + /// @return Reference to the added volume + TrackingVolume& addVolume(std::unique_ptr volume); + + /// Interface of @c TrackingVolume in the Gen1 geometry model + /// @note This interface is being replaced, and is subject to removal + /// + /// @{ + + /// Return the associated Layer to the global position + /// + /// @param gctx The current geometry context object, e.g. alignment + /// @param position is the associated global position + /// + /// @return plain pointer to layer object + const Layer* associatedLayer(const GeometryContext& gctx, + const Vector3& position) const; + + /// @brief Resolves the volume into (compatible) Layers + /// + /// This is the method for the propagator/extrapolator + /// @tparam options_t Type of navigation options object for decomposition + /// + /// @param gctx The current geometry context object, e.g. alignment + /// @param position Position for the search + /// @param direction Direction for the search + /// @param options The templated navigation options + /// + /// @return vector of compatible intersections with layers + boost::container::small_vector compatibleLayers( + const GeometryContext& gctx, const Vector3& position, + const Vector3& direction, const NavigationOptions& options) const; + + /// @brief Returns all boundary surfaces sorted by the user. + /// + /// @tparam options_t Type of navigation options object for decomposition + /// @tparam sorter_t Type of the boundary surface sorter + /// + /// @param gctx The current geometry context object, e.g. alignment + /// @param position The position for searching + /// @param direction The direction for searching + /// @param options The templated navigation options + /// @param logger A @c Logger instance + /// + /// @return is the templated boundary intersection + boost::container::small_vector compatibleBoundaries( + const GeometryContext& gctx, const Vector3& position, + const Vector3& direction, const NavigationOptions& options, + const Logger& logger = getDummyLogger()) const; + + /// Return the confined static layer array - if it exists + /// @return the BinnedArray of static layers if exists + const LayerArray* confinedLayers() const; + + /// Return the confined volumes of this container array - if it exists + std::shared_ptr confinedVolumes() const; + + /// Return the confined dense volumes + const MutableTrackingVolumeVector denseVolumes() const; + + /// Method to return the BoundarySurfaces + const TrackingVolumeBoundaries& boundarySurfaces() const; + + /// Set the boundary surface material description /// /// The material is usually derived in a complicated way and loaded from /// a framework given source. As various volumes could potentially share the /// the same material description, it is provided as a shared object /// - /// @param material Material description of this volume - void assignVolumeMaterial(std::shared_ptr material); + /// @param surfaceMaterial Material description of this volume + /// @param bsFace Specifies which boundary surface to assign the material to + void assignBoundaryMaterial( + std::shared_ptr surfaceMaterial, + BoundarySurfaceFace bsFace); /// Glue another tracking volume to this one /// - if common face is set the glued volumes are sharing the boundary, down @@ -382,21 +438,13 @@ class TrackingVolume : public Volume { /// - positiveFaceXY GlueVolumesDescriptor& glueVolumesDescriptor(); - /// Return the MotherVolume - if it exists - const TrackingVolume* motherVolume() const; - - /// Return the MotherVolume - if it exists - TrackingVolume* motherVolume(); - - /// Set the MotherVolume - /// - /// @param mvol is the mother volume - void setMotherVolume(TrackingVolume* mvol); - private: void connectDenseBoundarySurfaces( MutableTrackingVolumeVector& confinedDenseVolumes); + /// interlink the layers in this TrackingVolume + void interlinkLayers(); + /// Create Boundary Surface void createBoundarySurfaces(); @@ -406,6 +454,25 @@ class TrackingVolume : public Volume { /// @param envelope is the clearance between volume boundary and layer void synchronizeLayers(double envelope = 1.) const; + // the boundary surfaces + std::vector m_boundarySurfaces; + + ///(a) static configuration ordered by Binned arrays + /// static layers + std::unique_ptr m_confinedLayers = nullptr; + + /// Array of Volumes inside the Volume when actin as container + std::shared_ptr m_confinedVolumes = nullptr; + + /// confined dense + MutableTrackingVolumeVector m_confinedDenseVolumes; + + /// Volumes to glue Volumes from the outside + GlueVolumesDescriptor* m_glueVolumeDescriptor{nullptr}; + + /// @} + + private: /// close the Geometry, i.e. set the GeometryIdentifier and assign material /// /// @param materialDecorator is a dedicated decorator for the @@ -422,33 +489,16 @@ class TrackingVolume : public Volume { std::size_t& vol, const GeometryIdentifierHook& hook, const Logger& logger = getDummyLogger()); - /// interlink the layers in this TrackingVolume - void interlinkLayers(); - /// The volume based material the TrackingVolume consists of std::shared_ptr m_volumeMaterial{nullptr}; /// Remember the mother volume TrackingVolume* m_motherVolume{nullptr}; - // the boundary surfaces - std::vector m_boundarySurfaces; - - ///(a) static configuration ordered by Binned arrays - /// static layers - std::unique_ptr m_confinedLayers = nullptr; - - /// Array of Volumes inside the Volume when actin as container - std::shared_ptr m_confinedVolumes = nullptr; - - /// confined dense - MutableTrackingVolumeVector m_confinedDenseVolumes; - - /// Volumes to glue Volumes from the outside - GlueVolumesDescriptor* m_glueVolumeDescriptor{nullptr}; - /// Volume name for debug reasons & screen output std::string m_name; + + std::vector> m_volumes; }; } // namespace Acts diff --git a/Core/include/Acts/Geometry/Volume.hpp b/Core/include/Acts/Geometry/Volume.hpp index 93cf47b11d7..3df0b339fd9 100644 --- a/Core/include/Acts/Geometry/Volume.hpp +++ b/Core/include/Acts/Geometry/Volume.hpp @@ -16,6 +16,7 @@ #include #include +#include namespace Acts { @@ -23,13 +24,12 @@ class VolumeBounds; /// @class Volume /// -/// It inhertis of GeometryObject for TDD identification +/// It inherits from GeometryObject for geometry identification /// -/// Base class for all volumes inside the tracking realm, it defines -/// the interface for inherited Volume classes -/// regarding the geometrical information. - -class Volume : public virtual GeometryObject { +/// Base class for all volumes inside the tracking realm, it defines the +/// interface for inherited Volume classes regarding the geometrical +/// information. +class Volume : public GeometryObject { public: using BoundingBox = AxisAlignedBoundingBox; @@ -60,14 +60,26 @@ class Volume : public virtual GeometryObject { /// Returns the inverted transform of this volume. const Transform3& itransform() const; + void setTransform(const Transform3& transform); + /// returns the center of the volume const Vector3& center() const; /// Returns const reference to the volume bounds const VolumeBounds& volumeBounds() const; + /// Returns shared pointer to the volume bounds + std::shared_ptr volumeBoundsPtr() const; + /// Set volume bounds and update volume bounding boxes implicitly - void assignVolumeBounds(std::shared_ptr volbounds); + /// @param volbounds The volume bounds to be assigned + void assignVolumeBounds(std::shared_ptr volbounds); + + /// Set the volume bounds and optionally also update the volume transform + /// @param volbounds The volume bounds to be assigned + /// @param transform The transform to be assigned, can be optional + virtual void update(std::shared_ptr volbounds, + std::optional transform = std::nullopt); /// Construct bounding box for this shape /// @param envelope Optional envelope to add / subtract from min/max @@ -98,6 +110,9 @@ class Volume : public virtual GeometryObject { Vector3 binningPosition(const GeometryContext& gctx, BinningValue bValue) const override; + bool operator==(const Volume& other) const; + bool operator!=(const Volume& other) const; + protected: Transform3 m_transform; Transform3 m_itransform; diff --git a/Core/include/Acts/MagneticField/ConstantBField.hpp b/Core/include/Acts/MagneticField/ConstantBField.hpp index 15327257ff4..a461242bfcc 100644 --- a/Core/include/Acts/MagneticField/ConstantBField.hpp +++ b/Core/include/Acts/MagneticField/ConstantBField.hpp @@ -67,12 +67,8 @@ class ConstantBField final : public MagneticFieldProvider { /// @brief check whether given 3D position is inside look-up domain /// - /// @param [in] position global 3D position /// @return Always true for constant magnetic field - bool isInside(const Vector3& position) const { - (void)position; - return true; - } + bool isInside(const Vector3& /*position*/) const { return true; } /// @brief update magnetic field vector /// diff --git a/Core/include/Acts/MagneticField/InterpolatedBFieldMap.hpp b/Core/include/Acts/MagneticField/InterpolatedBFieldMap.hpp index 81674380941..09b975f44fe 100644 --- a/Core/include/Acts/MagneticField/InterpolatedBFieldMap.hpp +++ b/Core/include/Acts/MagneticField/InterpolatedBFieldMap.hpp @@ -146,9 +146,7 @@ class InterpolatedBFieldMap : public InterpolatedMagneticField { struct Cache { /// @brief Constructor with magnetic field context - /// - /// @param mctx the magnetic field context - Cache(const MagneticFieldContext& mctx) { (void)mctx; } + Cache(const MagneticFieldContext& /*mctx*/) {} std::optional fieldCell; bool initialized = false; diff --git a/Core/include/Acts/MagneticField/NullBField.hpp b/Core/include/Acts/MagneticField/NullBField.hpp index e12ac9a80b8..9d0f72f9f41 100644 --- a/Core/include/Acts/MagneticField/NullBField.hpp +++ b/Core/include/Acts/MagneticField/NullBField.hpp @@ -59,14 +59,10 @@ class NullBField final : public MagneticFieldProvider { /// @brief check whether given 3D position is inside look-up domain /// - /// @param [in] position global 3D position /// @return @c true if position is inside the defined look-up grid, /// otherwise @c false /// @note The method will always return true for the null B-Field - bool isInside(const Vector3& position) const { - (void)position; - return true; - } + bool isInside(const Vector3& /*position*/) const { return true; } private: /// magnetic field vector diff --git a/Core/include/Acts/MagneticField/SolenoidBField.hpp b/Core/include/Acts/MagneticField/SolenoidBField.hpp index ba02eb6173c..c97f3e96ff3 100644 --- a/Core/include/Acts/MagneticField/SolenoidBField.hpp +++ b/Core/include/Acts/MagneticField/SolenoidBField.hpp @@ -71,9 +71,7 @@ class SolenoidBField final : public MagneticFieldProvider { public: struct Cache { /// @brief Constructor with magnetic field context - /// - /// @param mctx the magnetic field context - Cache(const MagneticFieldContext& mctx) { (void)mctx; } + Cache(const MagneticFieldContext& /*mctx*/) {} }; /// Config struct for the SolenoidBfield. diff --git a/Core/include/Acts/Material/GridSurfaceMaterial.hpp b/Core/include/Acts/Material/GridSurfaceMaterial.hpp index 5b4065e0f85..c97dd9e93a1 100644 --- a/Core/include/Acts/Material/GridSurfaceMaterial.hpp +++ b/Core/include/Acts/Material/GridSurfaceMaterial.hpp @@ -74,7 +74,7 @@ struct IndexedMaterialAccessor { /// /// @param scale the amount of the scaling template - void scale(grid_type& /*unused*/, ActsScalar scale) { + void scale(grid_type& /*grid*/, ActsScalar scale) { for (auto& m : material) { m.scaleThickness(scale); } diff --git a/Core/include/Acts/Material/InterpolatedMaterialMap.hpp b/Core/include/Acts/Material/InterpolatedMaterialMap.hpp index dd9bfef8640..f353efd60c5 100644 --- a/Core/include/Acts/Material/InterpolatedMaterialMap.hpp +++ b/Core/include/Acts/Material/InterpolatedMaterialMap.hpp @@ -292,32 +292,26 @@ class InterpolatedMaterialMap : public IVolumeMaterial { /// @brief Retrieve material value & its "gradient" /// /// @param [in] position Global 3D position - /// @param [out] derivative "Gradient" of material as (5x5) matrix /// @return Material /// /// @note Currently the derivative is not calculated /// @todo return derivative Material getMaterialGradient(const Vector3& position, - ActsMatrix<5, 5>& derivative) const { - (void)derivative; + ActsMatrix<5, 5>& /*derivative*/) const { return m_mapper.getMaterial(position); } /// @brief Retrieve material value & its "gradient" /// /// @param [in] position Global 3D position - /// @param [out] derivative "Gradient" of material as (5x5) matrix - /// @param [in,out] cache Cache object. Contains cell used for /// @return Material /// /// @note Currently the derivative is not calculated /// @note Cache is not used currently /// @todo return derivative Material getMaterialGradient(const Vector3& position, - ActsMatrix<5, 5>& derivative, - Cache& cache) const { - (void)derivative; - (void)cache; + ActsMatrix<5, 5>& /*derivative*/, + Cache& /*cache*/) const { return m_mapper.getMaterial(position); } diff --git a/Core/include/Acts/Material/IntersectionMaterialAssigner.hpp b/Core/include/Acts/Material/IntersectionMaterialAssigner.hpp index aafe9f705ca..408b1a54acd 100644 --- a/Core/include/Acts/Material/IntersectionMaterialAssigner.hpp +++ b/Core/include/Acts/Material/IntersectionMaterialAssigner.hpp @@ -44,7 +44,14 @@ class IntersectionMaterialAssigner final : public IAssignmentFinder { }; /// @brief Construct with the configuration - IntersectionMaterialAssigner(const Config& cfg) : m_cfg(cfg) {} + /// + /// @param cfg is the configuration struct + /// @param mlogger is the logger + IntersectionMaterialAssigner( + const Config& cfg, + std::unique_ptr mlogger = + getDefaultLogger("IntersectionMaterialAssigner", Logging::INFO)) + : m_cfg(cfg), m_logger(std::move(mlogger)) {} /// @brief Method for generating assignment candidates for the /// material interaction assignment to surfaces or volumes @@ -63,8 +70,14 @@ class IntersectionMaterialAssigner final : public IAssignmentFinder { const Vector3& direction) const final; private: + /// Access method to the logger + const Logger& logger() const { return *m_logger; } + /// The configuration Config m_cfg; + + /// The logger + std::unique_ptr m_logger; }; } // namespace Acts diff --git a/Core/include/Acts/Material/PropagatorMaterialAssigner.hpp b/Core/include/Acts/Material/PropagatorMaterialAssigner.hpp index 3c2b06d687c..6fd96951163 100644 --- a/Core/include/Acts/Material/PropagatorMaterialAssigner.hpp +++ b/Core/include/Acts/Material/PropagatorMaterialAssigner.hpp @@ -64,7 +64,7 @@ struct InteractionVolumeCollector { typename navigator_t> void operator()(propagator_state_t& state, const stepper_t& stepper, const navigator_t& navigator, result_type& result, - const Logger& /*unused*/) const { + const Logger& /*logger*/) const { // Retrieve the current volume auto currentVolume = navigator.currentVolume(state.navigation); diff --git a/Core/include/Acts/Material/ProtoSurfaceMaterial.hpp b/Core/include/Acts/Material/ProtoSurfaceMaterial.hpp index 71229f743b1..0eab5c89dff 100644 --- a/Core/include/Acts/Material/ProtoSurfaceMaterial.hpp +++ b/Core/include/Acts/Material/ProtoSurfaceMaterial.hpp @@ -9,6 +9,7 @@ #pragma once #include "Acts/Definitions/Algebra.hpp" +#include "Acts/Detector/ProtoBinning.hpp" #include "Acts/Material/ISurfaceMaterial.hpp" #include "Acts/Material/MaterialSlab.hpp" #include "Acts/Utilities/BinUtility.hpp" @@ -68,7 +69,7 @@ class ProtoSurfaceMaterialT : public ISurfaceMaterial { /// Scale operator - dummy implementation /// - ProtoSurfaceMaterialT& operator*=(double /*unused*/) final { + ProtoSurfaceMaterialT& operator*=(double /*scale*/) final { return (*this); } @@ -79,7 +80,7 @@ class ProtoSurfaceMaterialT : public ISurfaceMaterial { /// coordinates /// /// @return will return dummy material - const MaterialSlab& materialSlab(const Vector2& /*unused*/) const final { + const MaterialSlab& materialSlab(const Vector2& /*lp*/) const final { return (m_materialSlab); } @@ -87,7 +88,7 @@ class ProtoSurfaceMaterialT : public ISurfaceMaterial { /// global coordinates /// /// @return will return dummy material - const MaterialSlab& materialSlab(const Vector3& /*unused*/) const final { + const MaterialSlab& materialSlab(const Vector3& /*gp*/) const final { return (m_materialSlab); } @@ -110,4 +111,7 @@ class ProtoSurfaceMaterialT : public ISurfaceMaterial { using ProtoSurfaceMaterial = ProtoSurfaceMaterialT; +using ProtoGridSurfaceMaterial = + ProtoSurfaceMaterialT; + } // namespace Acts diff --git a/Core/include/Acts/Propagator/AtlasStepper.hpp b/Core/include/Acts/Propagator/AtlasStepper.hpp index 4eaa7a0c257..b61ca832559 100644 --- a/Core/include/Acts/Propagator/AtlasStepper.hpp +++ b/Core/include/Acts/Propagator/AtlasStepper.hpp @@ -375,10 +375,7 @@ class AtlasStepper { } /// Overstep limit - /// - /// @param state The stepping state (thread-local cache) - double overstepLimit(const State& state) const { - (void)state; + double overstepLimit(const State& /*state*/) const { return -m_overstepLimit; } @@ -777,7 +774,7 @@ class AtlasStepper { P[45] *= p; P[46] *= p; - double An = std::hypot(P[4], P[5]); + double An = std::sqrt(P[4] * P[4] + P[5] * P[5]); double Ax[3]; if (An != 0.) { Ax[0] = -P[5] / An; @@ -1286,17 +1283,17 @@ class AtlasStepper { sA[2] = C6 * Sl; double mass = particleHypothesis(state.stepping).mass(); + double momentum = absoluteMomentum(state.stepping); // Evaluate the time propagation - double dtds = std::hypot(1, mass / absoluteMomentum(state.stepping)); + double dtds = std::sqrt(1 + mass * mass / (momentum * momentum)); state.stepping.pVector[3] += h * dtds; state.stepping.pVector[59] = dtds; state.stepping.field = f; state.stepping.newfield = false; if (Jac) { - double dtdl = h * mass * mass * charge(state.stepping) / - (absoluteMomentum(state.stepping) * dtds); + double dtdl = h * mass * mass * qOverP(state.stepping) / dtds; state.stepping.pVector[43] += dtdl; // Jacobian calculation diff --git a/Core/include/Acts/Propagator/DefaultExtension.hpp b/Core/include/Acts/Propagator/DefaultExtension.hpp index c78f88b2838..1ae901f42eb 100644 --- a/Core/include/Acts/Propagator/DefaultExtension.hpp +++ b/Core/include/Acts/Propagator/DefaultExtension.hpp @@ -133,7 +133,7 @@ struct DefaultExtension { /// = sqrt(m^2/p^2 + c^{-2}) with the mass m and the momentum p. auto m = stepper.particleHypothesis(state.stepping).mass(); auto p = stepper.absoluteMomentum(state.stepping); - auto dtds = std::hypot(1, m / p); + auto dtds = std::sqrt(1 + m * m / (p * p)); state.stepping.pars[eFreeTime] += h * dtds; if (state.stepping.covTransport) { state.stepping.derivative(3) = dtds; @@ -178,7 +178,7 @@ struct DefaultExtension { auto dir = stepper.direction(state.stepping); auto qop = stepper.qOverP(state.stepping); auto p = stepper.absoluteMomentum(state.stepping); - auto dtds = std::hypot(1, m / p); + auto dtds = std::sqrt(1 + m * m / (p * p)); D = FreeMatrix::Identity(); diff --git a/Core/include/Acts/Propagator/DirectNavigator.hpp b/Core/include/Acts/Propagator/DirectNavigator.hpp index 144eba6fa71..fc8439d023c 100644 --- a/Core/include/Acts/Propagator/DirectNavigator.hpp +++ b/Core/include/Acts/Propagator/DirectNavigator.hpp @@ -186,11 +186,9 @@ class DirectNavigator { /// @tparam stepper_t The type of stepper used for the propagation /// /// @param [in,out] state is the propagation state object - /// @param [in] stepper Stepper in use template - void initialize(propagator_state_t& state, const stepper_t& stepper) const { - (void)stepper; - + void initialize(propagator_state_t& state, + const stepper_t& /*stepper*/) const { ACTS_VERBOSE(volInfo(state) << "initialize"); // We set the current surface to the start surface diff --git a/Core/include/Acts/Propagator/EigenStepper.hpp b/Core/include/Acts/Propagator/EigenStepper.hpp index b12962ca1f3..11f32490c7c 100644 --- a/Core/include/Acts/Propagator/EigenStepper.hpp +++ b/Core/include/Acts/Propagator/EigenStepper.hpp @@ -312,10 +312,7 @@ class EigenStepper { } /// Overstep limit - /// - /// @param state The stepping state (thread-local cache) - double overstepLimit(const State& state) const { - (void)state; + double overstepLimit(const State& /*state*/) const { // A dynamic overstep limit could sit here return -m_overstepLimit; } diff --git a/Core/include/Acts/Propagator/EigenStepper.ipp b/Core/include/Acts/Propagator/EigenStepper.ipp index 96947e8a39d..d0d08e3881f 100644 --- a/Core/include/Acts/Propagator/EigenStepper.ipp +++ b/Core/include/Acts/Propagator/EigenStepper.ipp @@ -151,8 +151,6 @@ template template Acts::Result Acts::EigenStepper::step( propagator_state_t& state, const navigator_t& navigator) const { - using namespace UnitLiterals; - // Runge-Kutta integrator state auto& sd = state.stepping.stepData; double error_estimate = 0.; @@ -242,11 +240,11 @@ Acts::Result Acts::EigenStepper::step( break; } + // double std::sqrt is 3x faster than std::pow const double stepSizeScaling = - std::min(std::max(0.25f, std::sqrt(std::sqrt(static_cast( - state.options.stepTolerance / - std::abs(2. * error_estimate))))), - 4.0f); + std::clamp(std::sqrt(std::sqrt(state.options.stepTolerance / + std::abs(2. * error_estimate))), + 0.25, 4.0); h *= stepSizeScaling; // If step size becomes too small the particle remains at the initial @@ -323,11 +321,11 @@ Acts::Result Acts::EigenStepper::step( state.stepping.derivative.template segment<3>(4) = sd.k4; } state.stepping.pathAccumulated += h; - const double stepSizeScaling = std::min( - std::max(0.25f, - std::sqrt(std::sqrt(static_cast( - state.options.stepTolerance / std::abs(error_estimate))))), - 4.0f); + // double std::sqrt is 3x faster than std::pow + const double stepSizeScaling = + std::clamp(std::sqrt(std::sqrt(state.options.stepTolerance / + std::abs(error_estimate))), + 0.25, 4.0); const double nextAccuracy = std::abs(h * stepSizeScaling); const double previousAccuracy = std::abs(state.stepping.stepSize.accuracy()); const double initialStepLength = std::abs(initialH); diff --git a/Core/include/Acts/Propagator/StraightLineStepper.hpp b/Core/include/Acts/Propagator/StraightLineStepper.hpp index 05fa59d54c6..cd5c2c20f67 100644 --- a/Core/include/Acts/Propagator/StraightLineStepper.hpp +++ b/Core/include/Acts/Propagator/StraightLineStepper.hpp @@ -60,14 +60,13 @@ class StraightLineStepper { /// Constructor from the initial bound track parameters /// /// @param [in] gctx is the context object for the geometry - /// @param [in] mctx is the context object for the magnetic field /// @param [in] par The track parameters at start /// @param [in] ssize is the maximum step size /// @param [in] stolerance is the stepping tolerance /// /// @note the covariance matrix is copied when needed explicit State(const GeometryContext& gctx, - const MagneticFieldContext& mctx, + const MagneticFieldContext& /*mctx*/, const BoundTrackParameters& par, double ssize = std::numeric_limits::max(), double stolerance = s_onSurfaceTolerance) @@ -75,7 +74,6 @@ class StraightLineStepper { stepSize(ssize), tolerance(stolerance), geoContext(gctx) { - (void)mctx; Vector3 position = par.position(gctx); Vector3 direction = par.direction(); pars.template segment<3>(eFreePos0) = position; @@ -157,13 +155,7 @@ class StraightLineStepper { const double stepSize = std::numeric_limits::max()) const; /// Get the field for the stepping, this gives back a zero field - /// - /// @param [in,out] state is the propagation state associated with the track - /// the magnetic field cell is used (and potentially updated) - /// @param [in] pos is the field position - Result getField(State& state, const Vector3& pos) const { - (void)state; - (void)pos; + Result getField(State& /*state*/, const Vector3& /*pos*/) const { // get the field from the cell return Result::success({0., 0., 0.}); } @@ -221,10 +213,7 @@ class StraightLineStepper { double time(const State& state) const { return state.pars[eFreeTime]; } /// Overstep limit - /// - /// @param state The stepping state (thread-local cache) - double overstepLimit(const State& state) const { - (void)state; + double overstepLimit(const State& /*state*/) const { return -m_overstepLimit; } diff --git a/Core/include/Acts/Surfaces/SurfaceArray.hpp b/Core/include/Acts/Surfaces/SurfaceArray.hpp index bc24af364d1..2330122c7d7 100644 --- a/Core/include/Acts/Surfaces/SurfaceArray.hpp +++ b/Core/include/Acts/Surfaces/SurfaceArray.hpp @@ -361,42 +361,30 @@ class SurfaceArray { SingleElementLookup(const SurfaceVector& elements) : m_element(elements) {} /// @brief Lookup, always returns @c element - /// @param position is ignored /// @return reference to vector containing only @c element - SurfaceVector& lookup(const Vector3& position) override { - (void)position; + SurfaceVector& lookup(const Vector3& /*position*/) override { return m_element; } /// @brief Lookup, always returns @c element - /// @param position is ignored /// @return reference to vector containing only @c element - const SurfaceVector& lookup(const Vector3& position) const override { - (void)position; + const SurfaceVector& lookup(const Vector3& /*position*/) const override { return m_element; } /// @brief Lookup, always returns @c element - /// @param bin is ignored /// @return reference to vector containing only @c element - SurfaceVector& lookup(std::size_t bin) override { - (void)bin; - return m_element; - } + SurfaceVector& lookup(std::size_t /*bin*/) override { return m_element; } /// @brief Lookup, always returns @c element - /// @param bin is ignored /// @return reference to vector containing only @c element - const SurfaceVector& lookup(std::size_t bin) const override { - (void)bin; + const SurfaceVector& lookup(std::size_t /*bin*/) const override { return m_element; } /// @brief Lookup, always returns @c element - /// @param position is ignored /// @return reference to vector containing only @c element - const SurfaceVector& neighbors(const Vector3& position) const override { - (void)position; + const SurfaceVector& neighbors(const Vector3& /*position*/) const override { return m_element; } @@ -405,10 +393,8 @@ class SurfaceArray { std::size_t size() const override { return 1; } /// @brief Gets the bin center, but always returns (0, 0, 0) - /// @param bin is ignored /// @return (0, 0, 0) - Vector3 getBinCenter(std::size_t bin) const override { - (void)bin; + Vector3 getBinCenter(std::size_t /*bin*/) const override { return Vector3(0, 0, 0); } @@ -433,12 +419,8 @@ class SurfaceArray { } /// @brief Returns if the bin is valid (it is) - /// @param bin is ignored /// @return always true - bool isValidBin(std::size_t bin) const override { - (void)bin; - return true; - } + bool isValidBin(std::size_t /*bin*/) const override { return true; } private: SurfaceVector m_element; diff --git a/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp b/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp index 7c0404ffa62..0369c49a8b4 100644 --- a/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp +++ b/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp @@ -101,28 +101,20 @@ struct CombinatorialKalmanFilterExtensions { private: /// Default measurement selector which will return all measurements /// @param candidates Measurement track state candidates - /// @param isOutlier Output variable indicating whether the returned state is an outlier (unused) - /// @param logger A logger instance static Result::iterator, typename std::vector::iterator>> voidMeasurementSelector( typename std::vector& candidates, - bool& isOutlier, const Logger& logger) { - (void)isOutlier; - (void)logger; + bool& /*isOutlier*/, const Logger& /*logger*/) { return std::pair{candidates.begin(), candidates.end()}; }; /// Default branch stopper which will never stop - /// @param tipState The tip state to decide whether to stop (unused) - /// @param trackState The track state to decide whether to stop (unused) /// @return false static bool voidBranchStopper( - const CombinatorialKalmanFilterTipState& tipState, - typename traj_t::TrackStateProxy& trackState) { - (void)tipState; - (void)trackState; + const CombinatorialKalmanFilterTipState& /*tipState*/, + typename traj_t::TrackStateProxy& /*trackState*/) { return false; } }; @@ -572,7 +564,9 @@ class CombinatorialKalmanFilter { if (!boundStateRes.ok()) { return boundStateRes.error(); } - auto boundState = *boundStateRes; + auto& boundState = *boundStateRes; + auto& [boundParams, jacobian, pathLength] = boundState; + boundParams.covariance() = state.stepping.cov; // Retrieve the previous tip and its state // The states created on this surface will have the common previous tip @@ -670,8 +664,7 @@ class CombinatorialKalmanFilter { // TrackState. No storage allocation for uncalibrated/calibrated // measurement and filtered parameter auto stateMask = - ~(TrackStatePropMask::Calibrated | TrackStatePropMask::Filtered | - TrackStatePropMask::Smoothed); + TrackStatePropMask::Predicted | TrackStatePropMask::Jacobian; // Increment of number of processed states tipState.nStates++; @@ -681,13 +674,19 @@ class CombinatorialKalmanFilter { tipState.nHoles++; } + // Transport the covariance to a curvilinear surface + stepper.transportCovarianceToCurvilinear(state.stepping); + // Transport & bind the state to the current surface - auto res = stepper.boundState(state.stepping, *surface); - if (!res.ok()) { - ACTS_ERROR("Error in filter: " << res.error()); - return res.error(); + auto boundStateRes = + stepper.boundState(state.stepping, *surface, false); + if (!boundStateRes.ok()) { + return boundStateRes.error(); } - const auto boundState = *res; + auto& boundState = *boundStateRes; + auto& [boundParams, jacobian, pathLength] = boundState; + boundParams.covariance() = state.stepping.cov; + // Add a hole or material track state to the multitrajectory currentTip = addNonSourcelinkState(stateMask, boundState, result, isSensitive, prevTip); @@ -940,16 +939,12 @@ class CombinatorialKalmanFilter { const auto& [boundParams, jacobian, pathLength] = boundState; // Fill the track state trackStateProxy.predicted() = boundParams.parameters(); - if (boundParams.covariance().has_value()) { - trackStateProxy.predictedCovariance() = *boundParams.covariance(); - } + trackStateProxy.predictedCovariance() = boundParams.covariance().value(); trackStateProxy.jacobian() = jacobian; trackStateProxy.pathLength() = pathLength; // Set the surface trackStateProxy.setReferenceSurface( boundParams.referenceSurface().getSharedPtr()); - // Set the filtered parameter index to be the same with predicted - // parameter // Set the track state flags auto typeFlags = trackStateProxy.typeFlags(); @@ -961,6 +956,8 @@ class CombinatorialKalmanFilter { typeFlags.set(TrackStateFlag::HoleFlag); } + // Set the filtered parameter index to be the same with predicted + // parameter trackStateProxy.shareFrom(TrackStatePropMask::Predicted, TrackStatePropMask::Filtered); @@ -1070,9 +1067,9 @@ class CombinatorialKalmanFilter { template - bool operator()(propagator_state_t& /*unused*/, const stepper_t& /*unused*/, - const navigator_t& /*unused*/, - const Logger& /*unused*/) const { + bool operator()(propagator_state_t& /*state*/, const stepper_t& /*stepper*/, + const navigator_t& /*navigator*/, + const Logger& /*logger*/) const { return false; } }; diff --git a/Core/include/Acts/TrackFinding/TrackSelector.hpp b/Core/include/Acts/TrackFinding/TrackSelector.hpp index 94fead22510..1316932d32b 100644 --- a/Core/include/Acts/TrackFinding/TrackSelector.hpp +++ b/Core/include/Acts/TrackFinding/TrackSelector.hpp @@ -188,6 +188,11 @@ class TrackSelector { friend std::ostream& operator<<(std::ostream& os, const EtaBinnedConfig& cfg); + /// Check if the configuration has a bin for a given eta + /// @param eta Eta value + /// @return True if the configuration has a bin for the given eta + bool hasCuts(double eta) const; + /// Get the index of the eta bin for a given eta /// @param eta Eta value /// @return Index of the eta bin @@ -337,8 +342,12 @@ inline TrackSelector::EtaBinnedConfig& TrackSelector::EtaBinnedConfig::addCuts( return addCuts(inf, callback); } +inline bool TrackSelector::EtaBinnedConfig::hasCuts(double eta) const { + return std::abs(eta) < absEtaEdges.back(); +} + inline std::size_t TrackSelector::EtaBinnedConfig::binIndex(double eta) const { - if (std::abs(eta) >= absEtaEdges.back()) { + if (!hasCuts(eta)) { throw std::invalid_argument{"Eta is outside the abs eta bin edges"}; } diff --git a/Core/include/Acts/TrackFitting/GainMatrixSmoother.hpp b/Core/include/Acts/TrackFitting/GainMatrixSmoother.hpp index 8d8a731039f..6c6c48d430e 100644 --- a/Core/include/Acts/TrackFitting/GainMatrixSmoother.hpp +++ b/Core/include/Acts/TrackFitting/GainMatrixSmoother.hpp @@ -31,16 +31,13 @@ class GainMatrixSmoother { public: /// Run the Kalman smoothing for one trajectory. /// - /// @param[in] gctx The geometry context for the smoothing /// @param[in,out] trajectory The trajectory to be smoothed /// @param[in] entryIndex The index of state to start the smoothing /// @param[in] logger Where to write logging information to template - Result operator()(const GeometryContext& gctx, traj_t& trajectory, + Result operator()(const GeometryContext& /*gctx*/, traj_t& trajectory, std::size_t entryIndex, const Logger& logger = getDummyLogger()) const { - (void)gctx; - using TrackStateProxy = typename traj_t::TrackStateProxy; GetParameters filtered; @@ -82,11 +79,8 @@ class GainMatrixSmoother { ACTS_VERBOSE("Getting previous track state"); auto prev_ts = trajectory.getTrackState(entryIndex); - // ensure the track state has a smoothed component - prev_ts.addComponents(TrackStatePropMask::Smoothed); - - prev_ts.smoothed() = prev_ts.filtered(); - prev_ts.smoothedCovariance() = prev_ts.filteredCovariance(); + prev_ts.shareFrom(TrackStatePropMask::Filtered, + TrackStatePropMask::Smoothed); // make sure there is more than one track state if (!prev_ts.hasPrevious()) { diff --git a/Core/include/Acts/TrackFitting/GainMatrixUpdater.hpp b/Core/include/Acts/TrackFitting/GainMatrixUpdater.hpp index 196e1e95064..265b8f49059 100644 --- a/Core/include/Acts/TrackFitting/GainMatrixUpdater.hpp +++ b/Core/include/Acts/TrackFitting/GainMatrixUpdater.hpp @@ -46,16 +46,14 @@ class GainMatrixUpdater { /// Run the Kalman update step for a single trajectory state. /// /// @tparam kMeasurementSizeMax - /// @param[in] gctx The current geometry context object, e.g. alignment /// @param[in,out] trackState The track state /// @param[in] direction The navigation direction /// @param[in] logger Where to write logging information to template - Result operator()(const GeometryContext& gctx, + Result operator()(const GeometryContext& /*gctx*/, typename traj_t::TrackStateProxy trackState, Direction direction = Direction::Forward, const Logger& logger = getDummyLogger()) const { - (void)gctx; ACTS_VERBOSE("Invoked GainMatrixUpdater"); // there should be a calibrated measurement diff --git a/Core/include/Acts/TrackFitting/GlobalChiSquareFitter.hpp b/Core/include/Acts/TrackFitting/GlobalChiSquareFitter.hpp index b7950994766..f6acef88ddd 100644 --- a/Core/include/Acts/TrackFitting/GlobalChiSquareFitter.hpp +++ b/Core/include/Acts/TrackFitting/GlobalChiSquareFitter.hpp @@ -201,6 +201,9 @@ struct Gx2FitterResult { // between the first and last measurements. std::size_t measurementHoles = 0; + // Counter for handled states + std::size_t processedStates = 0; + // Counter for handled measurements std::size_t processedMeasurements = 0; @@ -385,27 +388,45 @@ class Gx2Fitter { const Logger& /*logger*/) const { assert(result.fittedStates && "No MultiTrajectory set"); - if (state.navigation.navigationBreak) { - ACTS_INFO("Actor: finish: state.navigation.navigationBreak"); + // Check if we can stop to propagate + if (result.measurementStates == inputMeasurements->size()) { + ACTS_INFO("Actor: finish: All measurements have been found."); + result.finished = true; + } else if (state.navigation.navigationBreak) { + ACTS_INFO("Actor: finish: navigationBreak."); result.finished = true; } + // End the propagation and return to the fitter if (result.finished) { + // Remove the missing surfaces that occur after the last measurement + if (result.measurementStates > 0) { + result.missedActiveSurfaces.resize(result.measurementHoles); + } + return; } + // Add the measurement surface as external surface to the navigator. + // We will try to hit those surface by ignoring boundary checks. + if (state.navigation.externalSurfaces.size() == 0) { + for (auto measurementIt = inputMeasurements->begin(); + measurementIt != inputMeasurements->end(); measurementIt++) { + navigator.insertExternalSurface(state.navigation, + measurementIt->first); + } + } + // Update: // - Waiting for a current surface auto surface = navigator.currentSurface(state.navigation); - if (surface != nullptr && - surface->associatedDetectorElement() != nullptr) { + if (surface != nullptr) { ++result.surfaceCount; ACTS_VERBOSE("Surface " << surface->geometryId() << " detected."); - // check if measurement surface - auto sourcelink_it = inputMeasurements->find(surface->geometryId()); - - if (sourcelink_it != inputMeasurements->end()) { + // Check if we have a measurement surface + if (auto sourcelink_it = inputMeasurements->find(surface->geometryId()); + sourcelink_it != inputMeasurements->end()) { ACTS_VERBOSE("Measurement surface " << surface->geometryId() << " detected."); @@ -425,8 +446,9 @@ class Gx2Fitter { auto& fittedStates = *result.fittedStates; // Mask for the track states. We don't need Smoothed and Filtered - TrackStatePropMask mask = - ~(TrackStatePropMask::Smoothed | TrackStatePropMask::Filtered); + TrackStatePropMask mask = TrackStatePropMask::Predicted | + TrackStatePropMask::Jacobian | + TrackStatePropMask::Calibrated; ACTS_VERBOSE(" processSurface: addTrackState"); @@ -447,17 +469,14 @@ class Gx2Fitter { result.result = res.error(); return; } - auto& [boundParams, jacobian, pathLength] = *res; + const auto& [boundParams, jacobian, pathLength] = *res; // Fill the track state - trackStateProxy.predicted() = std::move(boundParams.parameters()); - if (boundParams.covariance().has_value()) { - trackStateProxy.predictedCovariance() = - std::move(*boundParams.covariance()); - } + trackStateProxy.predicted() = boundParams.parameters(); + trackStateProxy.predictedCovariance() = state.stepping.cov; - trackStateProxy.jacobian() = std::move(jacobian); - trackStateProxy.pathLength() = std::move(pathLength); + trackStateProxy.jacobian() = jacobian; + trackStateProxy.pathLength() = pathLength; } // We have predicted parameters, so calibrate the uncalibrated input @@ -505,6 +524,114 @@ class Gx2Fitter { << "currentTrackIndex: " << currentTrackIndex) result.lastMeasurementIndex = currentTrackIndex; result.lastTrackIndex = currentTrackIndex; + + // TODO check for outlier first + // We count the state with measurement + ++result.measurementStates; + + // We count the processed state + ++result.processedStates; + + // Update the number of holes count only when encountering a + // measurement + result.measurementHoles = result.missedActiveSurfaces.size(); + } else if (surface->associatedDetectorElement() != nullptr || + surface->surfaceMaterial() != nullptr) { + // Here we handle material and holes + // TODO add material handling + ACTS_VERBOSE("Non-Measurement surface " << surface->geometryId() + << " detected."); + + // We only create track states here if there is already a measurement + // detected or if the surface has material (no holes before the first + // measurement) + if (result.measurementStates > 0 + // || surface->surfaceMaterial() != nullptr + ) { + ACTS_VERBOSE("Handle hole."); + + auto& fittedStates = *result.fittedStates; + + // Mask for the track states. We don't need Smoothed and Filtered + TrackStatePropMask mask = TrackStatePropMask::Predicted | + TrackStatePropMask::Jacobian | + TrackStatePropMask::Calibrated; + + ACTS_VERBOSE(" processSurface: addTrackState"); + + // Add a TrackState entry multi trajectory. This allocates + // storage for all components, which we will set later. + typename traj_t::TrackStateProxy trackStateProxy = + fittedStates.makeTrackState(mask, result.lastTrackIndex); + std::size_t currentTrackIndex = trackStateProxy.index(); + { + // Set the trackStateProxy components with the state from the + // ongoing propagation + { + trackStateProxy.setReferenceSurface(surface->getSharedPtr()); + // Bind the transported state to the current surface + auto res = stepper.boundState(state.stepping, *surface, false, + freeToBoundCorrection); + if (!res.ok()) { + result.result = res.error(); + return; + } + const auto& [boundParams, jacobian, pathLength] = *res; + + // Fill the track state + trackStateProxy.predicted() = boundParams.parameters(); + trackStateProxy.predictedCovariance() = state.stepping.cov; + + trackStateProxy.jacobian() = jacobian; + trackStateProxy.pathLength() = pathLength; + } + + // Get and set the type flags + auto typeFlags = trackStateProxy.typeFlags(); + typeFlags.set(TrackStateFlag::ParameterFlag); + if (surface->surfaceMaterial() != nullptr) { + typeFlags.set(TrackStateFlag::MaterialFlag); + } + + // Set hole only, if we are on a sensitive surface + if (surface->associatedDetectorElement() != nullptr) { + ACTS_VERBOSE("Detected hole on " << surface->geometryId()); + // If the surface is sensitive, set the hole type flag + typeFlags.set(TrackStateFlag::HoleFlag); + } else { + ACTS_VERBOSE("Detected in-sensitive surface " + << surface->geometryId()); + } + } + + ACTS_VERBOSE( + "Actor - indices after processing, before over writing:" + << "\n " + << "result.lastMeasurementIndex: " + << result.lastMeasurementIndex << "\n " + << "trackStateProxy.index(): " << trackStateProxy.index() + << "\n " + << "result.lastTrackIndex: " << result.lastTrackIndex + << "\n " + << "currentTrackIndex: " << currentTrackIndex) + result.lastTrackIndex = currentTrackIndex; + + if (trackStateProxy.typeFlags().test(TrackStateFlag::HoleFlag)) { + // Count the missed surface + result.missedActiveSurfaces.push_back(surface); + } + + ++result.processedStates; + } else { + ACTS_VERBOSE("Ignoring hole, because no preceding measurements."); + } + + if (surface->surfaceMaterial() != nullptr) { + // TODO write similar to KF? + // Update state and stepper with material effects + // materialInteractor(surface, state, stepper, navigator, + // MaterialUpdateStage::FullUpdate); + } } else { ACTS_INFO("Actor: This case is not implemented yet") } @@ -667,16 +794,19 @@ class Gx2Fitter { // This check takes into account the evaluated dimensions of the // measurements. To fit, we need at least NDF+1 measurements. However, - // we n-dimensional measurements count for n measurements, reducing the + // we count n-dimensional measurements for n measurements, reducing the // effective number of needed measurements. // We might encounter the case, where we cannot use some (parts of a) // measurements, maybe if we do not support that kind of measurement. This // is also taken into account here. // `ndf = 4` is chosen, since this a minimum that makes sense for us, but // a more general approach is desired. + // We skip the check during the first iteration, since we cannot + // guarantee to hit all/enough measurement surfaces with the initial + // parameter guess. // TODO genernalize for n-dimensional fit constexpr std::size_t ndf = 4; - if (ndf + 1 > gx2fResult.collectorResiduals.size()) { + if ((nUpdate > 0) && (ndf + 1 > gx2fResult.collectorResiduals.size())) { ACTS_INFO("Not enough measurements. Require " << ndf + 1 << ", but only " << gx2fResult.collectorResiduals.size() << " could be used."); diff --git a/Core/include/Acts/TrackFitting/KalmanFitter.hpp b/Core/include/Acts/TrackFitting/KalmanFitter.hpp index 297cf3a6c74..f509aedcd24 100644 --- a/Core/include/Acts/TrackFitting/KalmanFitter.hpp +++ b/Core/include/Acts/TrackFitting/KalmanFitter.hpp @@ -726,7 +726,10 @@ class KalmanFitter { // Add a TrackState entry multi trajectory. This allocates // storage for all components, which we will set later. - TrackStatePropMask mask = TrackStatePropMask::All; + TrackStatePropMask mask = + TrackStatePropMask::Predicted | TrackStatePropMask::Filtered | + TrackStatePropMask::Smoothed | TrackStatePropMask::Jacobian | + TrackStatePropMask::Calibrated; const std::size_t currentTrackIndex = fittedStates.addTrackState( mask, Acts::MultiTrajectoryTraits::kInvalid); @@ -744,17 +747,14 @@ class KalmanFitter { if (!res.ok()) { return res.error(); } - auto& [boundParams, jacobian, pathLength] = *res; + const auto& [boundParams, jacobian, pathLength] = *res; // Fill the track state - trackStateProxy.predicted() = std::move(boundParams.parameters()); - if (boundParams.covariance().has_value()) { - trackStateProxy.predictedCovariance() = - std::move(*boundParams.covariance()); - } + trackStateProxy.predicted() = boundParams.parameters(); + trackStateProxy.predictedCovariance() = state.stepping.cov; - trackStateProxy.jacobian() = std::move(jacobian); - trackStateProxy.pathLength() = std::move(pathLength); + trackStateProxy.jacobian() = jacobian; + trackStateProxy.pathLength() = pathLength; } // We have predicted parameters, so calibrate the uncalibrated input diff --git a/Core/include/Acts/TrackFitting/detail/KalmanUpdateHelpers.hpp b/Core/include/Acts/TrackFitting/detail/KalmanUpdateHelpers.hpp index 5b7cc8785ef..66be52147f0 100644 --- a/Core/include/Acts/TrackFitting/detail/KalmanUpdateHelpers.hpp +++ b/Core/include/Acts/TrackFitting/detail/KalmanUpdateHelpers.hpp @@ -10,6 +10,7 @@ #include "Acts/EventData/MultiTrajectory.hpp" #include "Acts/EventData/SourceLink.hpp" +#include "Acts/EventData/TrackParameters.hpp" #include "Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Utilities/CalibrationContext.hpp" @@ -43,7 +44,10 @@ auto kalmanHandleMeasurement( false)) -> Result { // Add a TrackState entry multi trajectory. This allocates storage for // all components, which we will set later. - TrackStatePropMask mask = TrackStatePropMask::All; + TrackStatePropMask mask = + TrackStatePropMask::Predicted | TrackStatePropMask::Filtered | + TrackStatePropMask::Smoothed | TrackStatePropMask::Jacobian | + TrackStatePropMask::Calibrated; typename traj_t::TrackStateProxy trackStateProxy = fittedStates.makeTrackState(mask, lastTrackIndex); @@ -59,17 +63,14 @@ auto kalmanHandleMeasurement( << " failed: " << res.error()); return res.error(); } - auto &[boundParams, jacobian, pathLength] = *res; + const auto &[boundParams, jacobian, pathLength] = *res; // Fill the track state - trackStateProxy.predicted() = std::move(boundParams.parameters()); - if (boundParams.covariance().has_value()) { - trackStateProxy.predictedCovariance() = - std::move(*boundParams.covariance()); - } + trackStateProxy.predicted() = boundParams.parameters(); + trackStateProxy.predictedCovariance() = state.stepping.cov; - trackStateProxy.jacobian() = std::move(jacobian); - trackStateProxy.pathLength() = std::move(pathLength); + trackStateProxy.jacobian() = jacobian; + trackStateProxy.pathLength() = pathLength; } // We have predicted parameters, so calibrate the uncalibrated input @@ -139,8 +140,9 @@ auto kalmanHandleNoMeasurement( false)) -> Result { // Add a TrackState entry multi trajectory. This allocates storage for // all components, which we will set later. - TrackStatePropMask mask = - ~(TrackStatePropMask::Calibrated | TrackStatePropMask::Filtered); + TrackStatePropMask mask = TrackStatePropMask::Predicted | + TrackStatePropMask::Smoothed | + TrackStatePropMask::Jacobian; typename traj_t::TrackStateProxy trackStateProxy = fittedStates.makeTrackState(mask, lastTrackIndex); @@ -154,17 +156,14 @@ auto kalmanHandleNoMeasurement( if (!res.ok()) { return res.error(); } - auto &[boundParams, jacobian, pathLength] = *res; + const auto &[boundParams, jacobian, pathLength] = *res; // Fill the track state - trackStateProxy.predicted() = std::move(boundParams.parameters()); - if (boundParams.covariance().has_value()) { - trackStateProxy.predictedCovariance() = - std::move(*boundParams.covariance()); - } + trackStateProxy.predicted() = boundParams.parameters(); + trackStateProxy.predictedCovariance() = state.stepping.cov; - trackStateProxy.jacobian() = std::move(jacobian); - trackStateProxy.pathLength() = std::move(pathLength); + trackStateProxy.jacobian() = jacobian; + trackStateProxy.pathLength() = pathLength; // Set the filtered parameter index to be the same with predicted // parameter diff --git a/Core/include/Acts/Utilities/FiniteStateMachine.hpp b/Core/include/Acts/Utilities/FiniteStateMachine.hpp index 8dff97c9a26..9c170ede36e 100644 --- a/Core/include/Acts/Utilities/FiniteStateMachine.hpp +++ b/Core/include/Acts/Utilities/FiniteStateMachine.hpp @@ -155,11 +155,9 @@ class FiniteStateMachine { /// Returns whether the FSM is in the specified state /// @tparam State type to check against - /// @param state State instance to check against /// @return Whether the FSM is in the given state. template - bool is(const S& state) const noexcept { - (void)state; + bool is(const S& /*state*/) const noexcept { return is(); } diff --git a/Core/include/Acts/Utilities/Logger.hpp b/Core/include/Acts/Utilities/Logger.hpp index eb89026357f..f3715064670 100644 --- a/Core/include/Acts/Utilities/Logger.hpp +++ b/Core/include/Acts/Utilities/Logger.hpp @@ -592,11 +592,9 @@ class DefaultPrintPolicy final : public OutputPrintPolicy { }; /// Make a copy of this print policy with a new name - /// @param name the new name /// @return the copy std::unique_ptr clone( - const std::string& name) const override { - (void)name; + const std::string& /*name*/) const override { return std::make_unique(m_out); }; diff --git a/Core/include/Acts/Utilities/TransformRange.hpp b/Core/include/Acts/Utilities/TransformRange.hpp index 2c64fc17735..1ff8bcad6da 100644 --- a/Core/include/Acts/Utilities/TransformRange.hpp +++ b/Core/include/Acts/Utilities/TransformRange.hpp @@ -66,9 +66,13 @@ struct TransformRange { /// Construct a transforming range from a container. The first argument is /// only used for type-deduction /// @param container The container to wrap - explicit TransformRange(Callable&& /*callable*/, container_t& container) + TransformRange(Callable&& /*callable*/, container_t& container) : m_container(&container) {} + /// Construct a transforming range from a construct + /// @param container The container to wrap + explicit TransformRange(container_t& container) : m_container(&container) {} + /// Access the i-th element of the underlying container, applying the /// callable /// @param i The index of the element to access diff --git a/Core/src/Detector/detail/ProtoMaterialHelper.cpp b/Core/src/Detector/detail/ProtoMaterialHelper.cpp index 4293e2399f8..be3eeb167af 100644 --- a/Core/src/Detector/detail/ProtoMaterialHelper.cpp +++ b/Core/src/Detector/detail/ProtoMaterialHelper.cpp @@ -17,9 +17,6 @@ Acts::Experimental::BinningDescription Acts::Experimental::detail::ProtoMaterialHelper::attachProtoMaterial( const GeometryContext& gctx, Surface& surface, const BinningDescription& bDescription) { - // Shorthand definition - using ProtoGridSurfaceMaterial = ProtoSurfaceMaterialT; - // The binning description, with eventually fixed range BinningDescription fbDescription; // Measure the surface diff --git a/Core/src/Geometry/CuboidVolumeBuilder.cpp b/Core/src/Geometry/CuboidVolumeBuilder.cpp index 4edf66a0a44..7f5385fcd9b 100644 --- a/Core/src/Geometry/CuboidVolumeBuilder.cpp +++ b/Core/src/Geometry/CuboidVolumeBuilder.cpp @@ -230,7 +230,7 @@ Acts::MutableTrackingVolumePtr Acts::CuboidVolumeBuilder::trackingVolume( trafo.translation() = m_cfg.position; // Size of the volume - auto volume = std::make_shared( + auto volumeBounds = std::make_shared( m_cfg.length.x() * 0.5, m_cfg.length.y() * 0.5, m_cfg.length.z() * 0.5); // Build vector of confined volumes @@ -258,8 +258,9 @@ Acts::MutableTrackingVolumePtr Acts::CuboidVolumeBuilder::trackingVolume( new BinnedArrayXD(tapVec, std::move(bu))); // Create world volume - MutableTrackingVolumePtr mtvp( - std::make_shared(trafo, volume, trVolArr, "World")); + MutableTrackingVolumePtr mtvp(std::make_shared( + trafo, volumeBounds, nullptr, nullptr, trVolArr, + MutableTrackingVolumeVector{}, "World")); return mtvp; } diff --git a/Core/src/Geometry/CylinderVolumeHelper.cpp b/Core/src/Geometry/CylinderVolumeHelper.cpp index 519712e451e..3bb781b7ebc 100644 --- a/Core/src/Geometry/CylinderVolumeHelper.cpp +++ b/Core/src/Geometry/CylinderVolumeHelper.cpp @@ -389,7 +389,8 @@ Acts::CylinderVolumeHelper::createContainerTrackingVolume( } // we have the bounds and the volume array, create the volume std::shared_ptr topVolume = std::make_shared( - topVolumeTransform, topVolumeBounds, volumeArray, volumeName); + topVolumeTransform, topVolumeBounds, nullptr, nullptr, volumeArray, + MutableTrackingVolumeVector{}, volumeName); // glueing section // -------------------------------------------------------------------------------------- if (!interGlueTrackingVolume(gctx, topVolume, rCase, rMin, rGlueMin, rMax, diff --git a/Core/src/Geometry/TrackingVolume.cpp b/Core/src/Geometry/TrackingVolume.cpp index 7ede9c8eca0..c854d04df7e 100644 --- a/Core/src/Geometry/TrackingVolume.cpp +++ b/Core/src/Geometry/TrackingVolume.cpp @@ -9,7 +9,6 @@ #include "Acts/Geometry/TrackingVolume.hpp" #include "Acts/Definitions/Direction.hpp" -#include "Acts/Definitions/Tolerance.hpp" #include "Acts/Geometry/GeometryIdentifier.hpp" #include "Acts/Geometry/GlueVolumesDescriptor.hpp" #include "Acts/Geometry/VolumeBounds.hpp" @@ -20,54 +19,49 @@ #include "Acts/Surfaces/RegularSurface.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Utilities/BinningType.hpp" -#include "Acts/Utilities/Frustum.hpp" -#include "Acts/Utilities/Ray.hpp" +#include "Acts/Utilities/TransformRange.hpp" #include -#include -#include #include #include #include -#include #include namespace Acts { class ISurfaceMaterial; -TrackingVolume::TrackingVolume( - const Transform3& transform, std::shared_ptr volbounds, - const std::shared_ptr& containedVolumeArray, - const std::string& volumeName) - : Volume(transform, std::move(volbounds)), - m_volumeMaterial(nullptr), - m_boundarySurfaces(), - m_confinedLayers(nullptr), - m_confinedVolumes(containedVolumeArray), - m_name(volumeName) { - createBoundarySurfaces(); - interlinkLayers(); -} - // constructor for arguments TrackingVolume::TrackingVolume( - const Transform3& transform, std::shared_ptr volumeBounds, + const Transform3& transform, + std::shared_ptr volumeBounds, std::shared_ptr volumeMaterial, std::unique_ptr staticLayerArray, std::shared_ptr containedVolumeArray, MutableTrackingVolumeVector denseVolumeVector, const std::string& volumeName) : Volume(transform, std::move(volumeBounds)), - m_volumeMaterial(std::move(volumeMaterial)), m_confinedLayers(std::move(staticLayerArray)), m_confinedVolumes(std::move(containedVolumeArray)), m_confinedDenseVolumes({}), + m_volumeMaterial(std::move(volumeMaterial)), m_name(volumeName) { createBoundarySurfaces(); interlinkLayers(); connectDenseBoundarySurfaces(denseVolumeVector); } +TrackingVolume::TrackingVolume(const Volume& volume, + const std::string& volumeName) + : TrackingVolume(volume.transform(), volume.volumeBoundsPtr(), nullptr, + volumeName) {} + +TrackingVolume::TrackingVolume( + const Transform3& transform, std::shared_ptr volbounds, + const std::shared_ptr& containedVolumeArray, + const std::string& volumeName) + : TrackingVolume(transform, std::move(volbounds), nullptr, nullptr, + containedVolumeArray, {}, volumeName) {} + TrackingVolume::~TrackingVolume() { delete m_glueVolumeDescriptor; } @@ -645,4 +639,24 @@ const Acts::Layer* TrackingVolume::associatedLayer( // return the null pointer return nullptr; } + +TrackingVolume::VolumeRange TrackingVolume::volumes() const { + return VolumeRange{m_volumes}; +} + +TrackingVolume::MutableVolumeRange TrackingVolume::volumes() { + return MutableVolumeRange{m_volumes}; +} + +TrackingVolume& TrackingVolume::addVolume( + std::unique_ptr volume) { + if (volume->motherVolume() != nullptr) { + throw std::invalid_argument("Volume already has a mother volume"); + } + + volume->setMotherVolume(this); + m_volumes.push_back(std::move(volume)); + return *m_volumes.back(); +} + } // namespace Acts diff --git a/Core/src/Geometry/Volume.cpp b/Core/src/Geometry/Volume.cpp index f3af6701e12..a69154624b5 100644 --- a/Core/src/Geometry/Volume.cpp +++ b/Core/src/Geometry/Volume.cpp @@ -74,8 +74,18 @@ Volume::BoundingBox Volume::orientedBoundingBox() const { this); } -void Volume::assignVolumeBounds(std::shared_ptr volbounds) { - m_volumeBounds = std::move(volbounds); +void Volume::assignVolumeBounds(std::shared_ptr volbounds) { + update(std::move(volbounds)); +} + +void Volume::update(std::shared_ptr volbounds, + std::optional transform) { + if (volbounds) { + m_volumeBounds = std::move(volbounds); + } + if (transform.has_value()) { + setTransform(*transform); + } } const Transform3& Volume::transform() const { @@ -94,4 +104,22 @@ const VolumeBounds& Volume::volumeBounds() const { return *m_volumeBounds; } +std::shared_ptr Volume::volumeBoundsPtr() const { + return m_volumeBounds; +} + +void Volume::setTransform(const Transform3& transform) { + m_transform = transform; + m_itransform = m_transform.inverse(); + m_center = m_transform.translation(); +} + +bool Volume::operator==(const Volume& other) const { + return (m_transform.matrix() == other.m_transform.matrix()) && + (*m_volumeBounds == *other.m_volumeBounds); +} + +bool Volume::operator!=(const Volume& other) const { + return !(*this == other); +} } // namespace Acts diff --git a/Core/src/Material/BinnedSurfaceMaterialAccumulater.cpp b/Core/src/Material/BinnedSurfaceMaterialAccumulater.cpp index d09206dcf76..92d72ca0b0f 100644 --- a/Core/src/Material/BinnedSurfaceMaterialAccumulater.cpp +++ b/Core/src/Material/BinnedSurfaceMaterialAccumulater.cpp @@ -34,42 +34,52 @@ Acts::BinnedSurfaceMaterialAccumulater::createState() const { "Surface material is not set, inconsistent configuration."); } - // We need a dynamic_cast to either a surface material proxy or - // proper surface material + // First attempt from ProtoSurfaceMaterial auto psm = dynamic_cast(surfaceMaterial); - - // Get the bin utility: try proxy material first - const BinUtility* bu = (psm != nullptr) ? (&psm->binning()) : nullptr; - if (bu != nullptr) { + if (psm != nullptr) { + auto binUtility = psm->binning(); // Screen output for Binned Surface material - ACTS_DEBUG(" - (proto) binning is " << *bu); - // Now update - BinUtility buAdjusted = adjustBinUtility(*bu, *surface, m_cfg.geoContext); + ACTS_DEBUG(" - (proto) binning from ProtoSurfaceMateria is " + << binUtility); + // Now adjust to surface type + binUtility = adjustBinUtility(binUtility, *surface, m_cfg.geoContext); // Screen output for Binned Surface material - ACTS_DEBUG(" - adjusted binning is " << buAdjusted); + ACTS_DEBUG(" - adjusted binning is " << binUtility); state->accumulatedMaterial[geoID] = - AccumulatedSurfaceMaterial(buAdjusted); + AccumulatedSurfaceMaterial(binUtility); // Material accumulation is created for this continue; } - - // Second attempt: binned material - auto bmp = dynamic_cast(surfaceMaterial); - bu = (bmp != nullptr) ? (&bmp->binUtility()) : nullptr; - // Creaete a binned type of material - if (bu != nullptr) { + // Second attempt from ProtoGridSurfaceMaterial + auto psgm = dynamic_cast(surfaceMaterial); + if (psgm != nullptr) { + auto binUtility = psgm->binning().toBinUtility(); // Screen output for Binned Surface material - ACTS_DEBUG(" - binning is " << *bu); - state->accumulatedMaterial[geoID] = AccumulatedSurfaceMaterial(*bu); + ACTS_DEBUG(" - (proto) binning from ProtoGridSurfaceMaterial is " + << binUtility); + // Now adjust to surface type + binUtility = adjustBinUtility(binUtility, *surface, m_cfg.geoContext); + // Screen output for Binned Surface material + ACTS_DEBUG(" - adjusted binning is " << binUtility); + state->accumulatedMaterial[geoID] = + AccumulatedSurfaceMaterial(binUtility); // Material accumulation is created for this continue; - } else { - // Create a homogeneous type of material - ACTS_DEBUG(" - this is homogeneous material."); - state->accumulatedMaterial[geoID] = AccumulatedSurfaceMaterial(); + } + // Third attempt: binned material + auto bmp = dynamic_cast(surfaceMaterial); + if (bmp != nullptr) { + // Screen output for Binned Surface material + ACTS_DEBUG(" - binning from BinnedSurfaceMaterial is " + << bmp->binUtility()); + state->accumulatedMaterial[geoID] = + AccumulatedSurfaceMaterial(bmp->binUtility()); // Material accumulation is created for this continue; } + // Create a homogeneous type of material + ACTS_DEBUG(" - this is homogeneous material."); + state->accumulatedMaterial[geoID] = AccumulatedSurfaceMaterial(); } return state; } diff --git a/Core/src/Material/IntersectionMaterialAssigner.cpp b/Core/src/Material/IntersectionMaterialAssigner.cpp index c1007135363..01b8a95cd3b 100644 --- a/Core/src/Material/IntersectionMaterialAssigner.cpp +++ b/Core/src/Material/IntersectionMaterialAssigner.cpp @@ -10,6 +10,7 @@ #include "Acts/Surfaces/BoundaryCheck.hpp" #include "Acts/Surfaces/Surface.hpp" +#include "Acts/Utilities/StringHelpers.hpp" namespace { @@ -51,6 +52,9 @@ Acts::IntersectionMaterialAssigner::assignmentCandidates( std::vector> candidates; + ACTS_DEBUG("Finding material assignment from position " + << toString(position) << " and direction " << toString(direction)); + // Try the surfaces first auto sIntersections = forwardOrderedIntersections(gctx, position, direction, m_cfg.surfaces); @@ -102,6 +106,9 @@ Acts::IntersectionMaterialAssigner::assignmentCandidates( } } + ACTS_DEBUG("Found " << candidates.first.size() << " surface candidates and " + << candidates.second.size() << " volume candidates"); + // Return the result return candidates; } diff --git a/Core/src/Propagator/detail/CovarianceEngine.cpp b/Core/src/Propagator/detail/CovarianceEngine.cpp index 741b6ff71d6..984eae2f580 100644 --- a/Core/src/Propagator/detail/CovarianceEngine.cpp +++ b/Core/src/Propagator/detail/CovarianceEngine.cpp @@ -50,8 +50,6 @@ Result detail::boundState( // Covariance transport std::optional cov = std::nullopt; if (covTransport) { - // Initialize the jacobian from start local to final local - fullTransportJacobian = BoundMatrix::Identity(); // Calculate the jacobian and transport the covarianceMatrix to final local. // Then reinitialize the transportJacobian, derivatives and the // boundToFreeJacobian @@ -59,8 +57,6 @@ Result detail::boundState( fullTransportJacobian, freeTransportJacobian, freeToPathDerivatives, boundToFreeJacobian, freeParameters, freeToBoundCorrection); - } - if (boundCovariance != BoundSquareMatrix::Zero()) { cov = boundCovariance; } @@ -82,16 +78,12 @@ CurvilinearState detail::curvilinearState( // Covariance transport std::optional cov = std::nullopt; if (covTransport) { - // Initialize the jacobian from start local to final local - fullTransportJacobian = BoundMatrix::Identity(); // Calculate the jacobian and transport the covarianceMatrix to final local. // Then reinitialize the transportJacobian, derivatives and the // boundToFreeJacobian transportCovarianceToCurvilinear( boundCovariance, fullTransportJacobian, freeTransportJacobian, freeToPathDerivatives, boundToFreeJacobian, direction); - } - if (boundCovariance != BoundSquareMatrix::Zero()) { cov = boundCovariance; } diff --git a/Core/src/Propagator/detail/JacobianEngine.cpp b/Core/src/Propagator/detail/JacobianEngine.cpp index 4325aee8182..435bd1b1f98 100644 --- a/Core/src/Propagator/detail/JacobianEngine.cpp +++ b/Core/src/Propagator/detail/JacobianEngine.cpp @@ -76,8 +76,7 @@ void detail::boundToCurvilinearTransportJacobian( // @note jac(locA->locB) = jac(gloB->locB)*(1+ // pathCorrectionFactor(gloB))*jacTransport(gloA->gloB) *jac(locA->gloA) fullTransportJacobian = - blockedMult(freeToBoundJacobian, - blockedMult(freeTransportJacobian, boundToFreeJacobian)); + freeToBoundJacobian * freeTransportJacobian * boundToFreeJacobian; } BoundToFreeMatrix detail::boundToFreeTransportJacobian( diff --git a/Core/src/TrackFitting/GsfMixtureReduction.cpp b/Core/src/TrackFitting/GsfMixtureReduction.cpp index df364d46d00..6008ad66a81 100644 --- a/Core/src/TrackFitting/GsfMixtureReduction.cpp +++ b/Core/src/TrackFitting/GsfMixtureReduction.cpp @@ -51,7 +51,7 @@ namespace Acts { void reduceMixtureLargestWeights(std::vector &cmpCache, std::size_t maxCmpsAfterMerge, - const Surface & /*unused*/) { + const Surface & /*surface*/) { if (cmpCache.size() <= maxCmpsAfterMerge) { return; } diff --git a/Core/src/Vertexing/AdaptiveMultiVertexFinder.cpp b/Core/src/Vertexing/AdaptiveMultiVertexFinder.cpp index 87c8d8eed84..e410bc2fb01 100644 --- a/Core/src/Vertexing/AdaptiveMultiVertexFinder.cpp +++ b/Core/src/Vertexing/AdaptiveMultiVertexFinder.cpp @@ -521,6 +521,7 @@ Result AdaptiveMultiVertexFinder::isMergedVertex( auto sumCovZTInverse = safeInverse(sumCovZT); if (!sumCovZTInverse) { ACTS_ERROR("Vertex z-t covariance matrix is singular."); + ACTS_ERROR("sumCovZT:\n" << sumCovZT); return Result::failure(VertexingError::SingularMatrix); } significance = std::sqrt(deltaZT.dot(*sumCovZTInverse * deltaZT)); @@ -529,6 +530,7 @@ Result AdaptiveMultiVertexFinder::isMergedVertex( const double sumVarZ = otherCov(eZ, eZ) + candidateCov(eZ, eZ); if (sumVarZ <= 0) { ACTS_ERROR("Variance of the vertex's z-coordinate is not positive."); + ACTS_ERROR("sumVarZ:\n" << sumVarZ); return Result::failure(VertexingError::SingularMatrix); } // Use only z significance @@ -542,6 +544,7 @@ Result AdaptiveMultiVertexFinder::isMergedVertex( auto sumCovInverse = safeInverse(sumCov); if (!sumCovInverse) { ACTS_ERROR("Vertex 4D covariance matrix is singular."); + ACTS_ERROR("sumCov:\n" << sumCov); return Result::failure(VertexingError::SingularMatrix); } significance = std::sqrt(deltaPos.dot(*sumCovInverse * deltaPos)); @@ -553,6 +556,7 @@ Result AdaptiveMultiVertexFinder::isMergedVertex( auto sumCovInverse = safeInverse(sumCov); if (!sumCovInverse) { ACTS_ERROR("Vertex 3D covariance matrix is singular."); + ACTS_ERROR("sumCov:\n" << sumCov); return Result::failure(VertexingError::SingularMatrix); } significance = std::sqrt(deltaPos.dot(*sumCovInverse * deltaPos)); diff --git a/Examples/Algorithms/Digitization/scripts/smearing-config.py b/Examples/Algorithms/Digitization/scripts/smearing-config.py index 7ffde6781c0..3554c239535 100644 --- a/Examples/Algorithms/Digitization/scripts/smearing-config.py +++ b/Examples/Algorithms/Digitization/scripts/smearing-config.py @@ -65,7 +65,6 @@ def get_args_blocks(): i = add_switch(i, argv, current) if current: blocks.append(current) - current = [] return blocks diff --git a/Examples/Algorithms/Geant4/CMakeLists.txt b/Examples/Algorithms/Geant4/CMakeLists.txt index cc1a73d62c7..dc11b46f76a 100644 --- a/Examples/Algorithms/Geant4/CMakeLists.txt +++ b/Examples/Algorithms/Geant4/CMakeLists.txt @@ -6,6 +6,7 @@ set(ACTS_EXAMPLES_G4SOURCES src/MaterialPhysicsList.cpp src/MaterialSteppingAction.cpp src/ParticleTrackingAction.cpp + src/RegionCreator.cpp src/SensitiveSurfaceMapper.cpp src/SensitiveSteppingAction.cpp src/SimParticleTranslation.cpp diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp index cdf9dbcc17c..85237e94811 100644 --- a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp +++ b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2017-2021 CERN for the benefit of the Acts project +// Copyright (C) 2017-2024 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 @@ -9,6 +9,7 @@ #pragma once #include "ActsExamples/Geant4/DetectorConstructionFactory.hpp" +#include "ActsExamples/Geant4/RegionCreator.hpp" #include @@ -28,7 +29,9 @@ struct DD4hepDetector; /// Construct the Geant4 detector from a DD4hep description. class DDG4DetectorConstruction final : public G4VUserDetectorConstruction { public: - DDG4DetectorConstruction(std::shared_ptr detector); + DDG4DetectorConstruction( + std::shared_ptr detector, + std::vector> regionCreators = {}); ~DDG4DetectorConstruction() final; /// Convert the stored DD4hep detector to a Geant4 description. @@ -43,6 +46,8 @@ class DDG4DetectorConstruction final : public G4VUserDetectorConstruction { private: /// The Acts DD4hep detector instance std::shared_ptr m_detector; + /// Region creators + std::vector> m_regionCreators; /// The world volume G4VPhysicalVolume* m_world = nullptr; @@ -54,7 +59,8 @@ class DDG4DetectorConstructionFactory final : public DetectorConstructionFactory { public: DDG4DetectorConstructionFactory( - std::shared_ptr detector); + std::shared_ptr detector, + std::vector> regionCreators = {}); ~DDG4DetectorConstructionFactory() final; std::unique_ptr factorize() const override; @@ -62,6 +68,8 @@ class DDG4DetectorConstructionFactory final private: /// The Acts DD4hep detector instance std::shared_ptr m_detector; + /// Region creators + std::vector> m_regionCreators; }; } // namespace ActsExamples diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/EventStore.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/EventStore.hpp index c964305a8c7..56d36082bac 100644 --- a/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/EventStore.hpp +++ b/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/EventStore.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2021-2023 CERN for the benefit of the Acts project +// Copyright (C) 2021-2024 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 @@ -12,10 +12,8 @@ #include "ActsExamples/EventData/SimHit.hpp" #include "ActsExamples/EventData/SimParticle.hpp" #include "ActsExamples/Framework/DataHandle.hpp" -#include "ActsFatras/EventData/Barcode.hpp" +#include "ActsFatras/EventData/ParticleOutcome.hpp" -#include -#include #include #include #include @@ -56,6 +54,8 @@ struct EventStore { /// Particle hit count (for hit indexing) std::unordered_map particleHitCount; + /// Particle status + std::unordered_map particleOutcome; /// Geant4 Track ID to Barcode mapping std::unordered_map trackIdMapping; /// Geant4 Track ID subparticle counter (for subparticle indexing) diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/GdmlDetectorConstruction.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/GdmlDetectorConstruction.hpp index cdfcb72d1d2..5ce29404a01 100644 --- a/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/GdmlDetectorConstruction.hpp +++ b/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/GdmlDetectorConstruction.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2017-2020 CERN for the benefit of the Acts project +// Copyright (C) 2017-2024 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 @@ -9,6 +9,7 @@ #pragma once #include "ActsExamples/Geant4/DetectorConstructionFactory.hpp" +#include "ActsExamples/Geant4/RegionCreator.hpp" #include @@ -22,7 +23,10 @@ namespace ActsExamples { class GdmlDetectorConstruction final : public G4VUserDetectorConstruction { public: /// @param path is the path to the Gdml file - GdmlDetectorConstruction(std::string path); + /// @param regionCreators are the region creators + GdmlDetectorConstruction( + std::string path, + std::vector> regionCreators = {}); /// Read the file and parse it to construct the Geant4 description /// @@ -33,20 +37,26 @@ class GdmlDetectorConstruction final : public G4VUserDetectorConstruction { private: /// Path to the Gdml file std::string m_path; - /// Cached worled volume + /// Region creators + std::vector> m_regionCreators; + /// Cached world volume G4VPhysicalVolume* m_world = nullptr; }; class GdmlDetectorConstructionFactory final : public DetectorConstructionFactory { public: - GdmlDetectorConstructionFactory(std::string path); + GdmlDetectorConstructionFactory( + std::string path, + std::vector> regionCreators = {}); std::unique_ptr factorize() const override; private: /// Path to the Gdml file std::string m_path; + /// Region creators + std::vector> m_regionCreators; }; } // namespace ActsExamples diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/ParticleKillAction.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/ParticleKillAction.hpp index 6f720a95018..7802760e739 100644 --- a/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/ParticleKillAction.hpp +++ b/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/ParticleKillAction.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2023 CERN for the benefit of the Acts project +// Copyright (C) 2023-2024 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 @@ -10,6 +10,7 @@ #include "Acts/Geometry/Volume.hpp" #include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/Geant4/EventStore.hpp" #include #include @@ -31,6 +32,9 @@ class ParticleKillAction : public G4UserSteppingAction { public: /// Configuration of the Stepping action struct Config { + /// event store + std::shared_ptr eventStore; + /// particles outside this volume will be terminated std::shared_ptr volume; /// particles that exceed this global time limit will be terminated @@ -54,6 +58,9 @@ class ParticleKillAction : public G4UserSteppingAction { void UserSteppingAction(const G4Step* step) override; private: + /// Private access method to the event store + EventStore& eventStore() const { return *m_cfg.eventStore; } + const Acts::Logger& logger() const { return *m_logger; } Config m_cfg; diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/RegionCreator.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/RegionCreator.hpp new file mode 100644 index 00000000000..873859a27b1 --- /dev/null +++ b/Examples/Algorithms/Geant4/include/ActsExamples/Geant4/RegionCreator.hpp @@ -0,0 +1,71 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2024 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 http://mozilla.org/MPL/2.0/. + +#pragma once + +#include "Acts/Utilities/Logger.hpp" + +#include +#include + +namespace ActsExamples { + +/// Geant4 Region Creator +/// +/// Used to set process cuts in specified volumes. +/// Particles will not be created if their energy is below the cut in length +/// units. +class RegionCreator { + public: + /// Nested configuration struct for the Geant4 region creator + struct Config { + /// Process cut to be applied for gammas, in mm + double gammaCut{}; + + /// Process cut to be applied for electrons, in mm + double electronCut{}; + + /// Process cut to be applied for positrons, in mm + double positronCut{}; + + /// Process cut to be applied for protons, in mm + double protonCut{}; + + /// Volume list to be included in this region + std::vector volumes{}; + }; + + /// Region creator constructor + /// + /// @param cfg is the configuration struct + /// @param name is the region name + /// @param level is the logging level to be used + RegionCreator(const Config& cfg, std::string name, + Acts::Logging::Level level); + + /// Construct the region + void Construct(); + + /// Readonly access to the configuration + const Config& config() const { return m_cfg; } + + private: + /// Region name + std::string m_name; + + /// Config instance + Config m_cfg; + + /// Private access method to the logging instance + const Acts::Logger& logger() const { return *m_logger; } + + /// The looging instance + std::unique_ptr m_logger; +}; + +} // namespace ActsExamples diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/TelescopeDetector/TelescopeG4DetectorConstruction.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/TelescopeDetector/TelescopeG4DetectorConstruction.hpp index f9cd28eae87..cc3583a53c5 100644 --- a/Examples/Algorithms/Geant4/include/ActsExamples/TelescopeDetector/TelescopeG4DetectorConstruction.hpp +++ b/Examples/Algorithms/Geant4/include/ActsExamples/TelescopeDetector/TelescopeG4DetectorConstruction.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2022 CERN for the benefit of the Acts project +// Copyright (C) 2022-2024 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 @@ -9,6 +9,7 @@ #pragma once #include "ActsExamples/Geant4/DetectorConstructionFactory.hpp" +#include "ActsExamples/Geant4/RegionCreator.hpp" #include "ActsExamples/TelescopeDetector/TelescopeDetector.hpp" #include "G4VUserDetectorConstruction.hh" @@ -21,25 +22,35 @@ namespace ActsExamples::Telescope { class TelescopeG4DetectorConstruction final : public G4VUserDetectorConstruction { public: - TelescopeG4DetectorConstruction(const TelescopeDetector::Config& cfg); + TelescopeG4DetectorConstruction( + const TelescopeDetector::Config& cfg, + std::vector> regionCreators = {}); G4VPhysicalVolume* Construct() final; private: + /// The configuration of the telescope detector TelescopeDetector::Config m_cfg; - + /// Region creators + std::vector> m_regionCreators; + /// The world volume G4VPhysicalVolume* m_world{}; }; class TelescopeG4DetectorConstructionFactory final : public DetectorConstructionFactory { public: - TelescopeG4DetectorConstructionFactory(const TelescopeDetector::Config& cfg); + TelescopeG4DetectorConstructionFactory( + const TelescopeDetector::Config& cfg, + std::vector> regionCreators = {}); std::unique_ptr factorize() const override; private: + /// The configuration of the telescope detector TelescopeDetector::Config m_cfg; + /// Region creators + std::vector> m_regionCreators; }; } // namespace ActsExamples::Telescope diff --git a/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp b/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp index f87170b7718..74fa7831646 100644 --- a/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp +++ b/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2017-2021 CERN for the benefit of the Acts project +// Copyright (C) 2017-2024 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 @@ -11,7 +11,7 @@ #include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" #include -#include +#include #include #include @@ -23,8 +23,11 @@ class G4VPhysicalVolume; ActsExamples::DDG4DetectorConstruction::DDG4DetectorConstruction( - std::shared_ptr detector) - : G4VUserDetectorConstruction(), m_detector(std::move(detector)) {} + std::shared_ptr detector, + std::vector> regionCreators) + : G4VUserDetectorConstruction(), + m_detector(std::move(detector)), + m_regionCreators(std::move(regionCreators)) {} ActsExamples::DDG4DetectorConstruction::~DDG4DetectorConstruction() = default; @@ -46,18 +49,26 @@ G4VPhysicalVolume* ActsExamples::DDG4DetectorConstruction::Construct() { m_world = geo_info->world(); // Create Geant4 volume manager g4map.volumeManager(); + + // Create regions + for (const auto& regionCreator : m_regionCreators) { + regionCreator->Construct(); + } } return m_world; } ActsExamples::DDG4DetectorConstructionFactory::DDG4DetectorConstructionFactory( - std::shared_ptr detector) - : m_detector(std::move(detector)) {} + std::shared_ptr detector, + std::vector> regionCreators) + : m_detector(std::move(detector)), + m_regionCreators(std::move(regionCreators)) {} ActsExamples::DDG4DetectorConstructionFactory:: ~DDG4DetectorConstructionFactory() = default; std::unique_ptr ActsExamples::DDG4DetectorConstructionFactory::factorize() const { - return std::make_unique(m_detector); + return std::make_unique(m_detector, + m_regionCreators); } diff --git a/Examples/Algorithms/Geant4/src/GdmlDetectorConstruction.cpp b/Examples/Algorithms/Geant4/src/GdmlDetectorConstruction.cpp index 62d5e542012..b2846f33a3b 100644 --- a/Examples/Algorithms/Geant4/src/GdmlDetectorConstruction.cpp +++ b/Examples/Algorithms/Geant4/src/GdmlDetectorConstruction.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2017-2020 CERN for the benefit of the Acts project +// Copyright (C) 2017-2024 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 @@ -16,8 +16,12 @@ class G4VPhysicalVolume; using namespace ActsExamples; -GdmlDetectorConstruction::GdmlDetectorConstruction(std::string path) - : G4VUserDetectorConstruction(), m_path(std::move(path)) {} +GdmlDetectorConstruction::GdmlDetectorConstruction( + std::string path, + std::vector> regionCreators) + : G4VUserDetectorConstruction(), + m_path(std::move(path)), + m_regionCreators(std::move(regionCreators)) {} G4VPhysicalVolume* GdmlDetectorConstruction::Construct() { if (m_world == nullptr) { @@ -25,15 +29,21 @@ G4VPhysicalVolume* GdmlDetectorConstruction::Construct() { // TODO how to handle errors parser.Read(m_path); m_world = parser.GetWorldVolume(); + + // Create regions + for (const auto& regionCreator : m_regionCreators) { + regionCreator->Construct(); + } } return m_world; } GdmlDetectorConstructionFactory::GdmlDetectorConstructionFactory( - std::string path) - : m_path(std::move(path)) {} + std::string path, + std::vector> regionCreators) + : m_path(std::move(path)), m_regionCreators(std::move(regionCreators)) {} std::unique_ptr GdmlDetectorConstructionFactory::factorize() const { - return std::make_unique(m_path); + return std::make_unique(m_path, m_regionCreators); } diff --git a/Examples/Algorithms/Geant4/src/Geant4Simulation.cpp b/Examples/Algorithms/Geant4/src/Geant4Simulation.cpp index 0c263ae8016..19091551d66 100644 --- a/Examples/Algorithms/Geant4/src/Geant4Simulation.cpp +++ b/Examples/Algorithms/Geant4/src/Geant4Simulation.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2021 CERN for the benefit of the Acts project +// Copyright (C) 2021-2024 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 @@ -222,6 +222,7 @@ ActsExamples::Geant4Simulation::Geant4Simulation(const Config& cfg, } ParticleKillAction::Config particleKillCfg; + particleKillCfg.eventStore = m_eventStore; particleKillCfg.volume = cfg.killVolume; particleKillCfg.maxTime = cfg.killAfterTime; particleKillCfg.secondaries = cfg.killSecondaries; diff --git a/Examples/Algorithms/Geant4/src/ParticleKillAction.cpp b/Examples/Algorithms/Geant4/src/ParticleKillAction.cpp index 55629750f85..c27aeb87fd9 100644 --- a/Examples/Algorithms/Geant4/src/ParticleKillAction.cpp +++ b/Examples/Algorithms/Geant4/src/ParticleKillAction.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2021 CERN for the benefit of the Acts project +// Copyright (C) 2021-2024 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 @@ -10,7 +10,8 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Units.hpp" -#include "Acts/Geometry/Volume.hpp" +#include "ActsFatras/EventData/Barcode.hpp" +#include "ActsFatras/EventData/ParticleOutcome.hpp" #include #include @@ -49,4 +50,25 @@ void ActsExamples::ParticleKillAction::UserSteppingAction(const G4Step* step) { << isSecondary); track->SetTrackStatus(G4TrackStatus::fStopAndKill); } + + // store the outcome of the particle + auto trackIt = eventStore().trackIdMapping.find(track->GetTrackID()); + // check if we have a particle assigned to track + if (trackIt != eventStore().trackIdMapping.end()) { + // set the outcome of the particle + const ActsFatras::Barcode particleId = trackIt->second; + if (outOfVolume) { + eventStore().particleOutcome[particleId] = + ActsFatras::ParticleOutcome::KilledVolumeExit; + } else if (outOfTime) { + eventStore().particleOutcome[particleId] = + ActsFatras::ParticleOutcome::KilledTime; + } else if (invalidSecondary) { + eventStore().particleOutcome[particleId] = + ActsFatras::ParticleOutcome::KilledSecondaryParticle; + } else if (track->GetTrackStatus() == fStopAndKill) { + eventStore().particleOutcome[particleId] = + ActsFatras::ParticleOutcome::KilledInteraction; + } + } } diff --git a/Examples/Algorithms/Geant4/src/ParticleTrackingAction.cpp b/Examples/Algorithms/Geant4/src/ParticleTrackingAction.cpp index d2de5558b94..a284728bf53 100644 --- a/Examples/Algorithms/Geant4/src/ParticleTrackingAction.cpp +++ b/Examples/Algorithms/Geant4/src/ParticleTrackingAction.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2021 CERN for the benefit of the Acts project +// Copyright (C) 2021-2024 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 @@ -11,13 +11,11 @@ #include "Acts/Definitions/PdgParticle.hpp" #include "Acts/Definitions/Units.hpp" #include "Acts/Utilities/MultiIndex.hpp" -#include "ActsExamples/EventData/SimHit.hpp" #include "ActsExamples/Geant4/EventStore.hpp" #include "ActsFatras/EventData/Barcode.hpp" #include "ActsFatras/EventData/Particle.hpp" #include -#include #include #include #include @@ -125,6 +123,13 @@ ActsExamples::SimParticle ActsExamples::ParticleTrackingAction::convert( numberOfHits = it->second; } + ActsFatras::ParticleOutcome particleOutcome = + ActsFatras::ParticleOutcome::Alive; + if (auto it = eventStore().particleOutcome.find(particleId); + it != eventStore().particleOutcome.end()) { + particleOutcome = it->second; + } + // Now create the Particle ActsExamples::SimParticle aParticle(particleId, Acts::PdgParticle(pdg), charge, mass); @@ -132,6 +137,7 @@ ActsExamples::SimParticle ActsExamples::ParticleTrackingAction::convert( aParticle.setDirection(pDirection[0], pDirection[1], pDirection[2]); aParticle.setAbsoluteMomentum(p); aParticle.setNumberOfHits(numberOfHits); + aParticle.setOutcome(particleOutcome); return aParticle; } diff --git a/Examples/Algorithms/Geant4/src/RegionCreator.cpp b/Examples/Algorithms/Geant4/src/RegionCreator.cpp new file mode 100644 index 00000000000..f5d5fe3d7d4 --- /dev/null +++ b/Examples/Algorithms/Geant4/src/RegionCreator.cpp @@ -0,0 +1,71 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2024 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 http://mozilla.org/MPL/2.0/. + +#include "ActsExamples/Geant4/RegionCreator.hpp" + +#include +#include +#include +#include + +namespace ActsExamples { + +RegionCreator::RegionCreator(const Config& cfg, std::string name, + Acts::Logging::Level level) + : m_name(std::move(name)), + m_cfg(cfg), + m_logger(Acts::getDefaultLogger(m_name, level)) {} + +void RegionCreator::Construct() { + // create a new G4Region + G4Region* region = new G4Region(m_name); + + // loop over volumes and find the ones in the list + std::size_t nVolumes{0}; + G4LogicalVolumeStore* logStore = G4LogicalVolumeStore::GetInstance(); + for (const std::string& volumeName : m_cfg.volumes) { + std::size_t nVolumesCurrent{0}; + for (auto* it : *logStore) { + ACTS_DEBUG("Checking volume " << it->GetName() << " against " + << volumeName); + if (volumeName == static_cast(it->GetName())) { + nVolumesCurrent++; + it->SetRegion(region); + region->AddRootLogicalVolume(it); + ACTS_DEBUG("Volume " << it->GetName() << " added to region"); + } + } + if (nVolumesCurrent == 0) { + ACTS_WARNING("No volumes matching \"" + << volumeName << "\" found in G4 LogicalVolumeStore. " + << m_name << " G4PhysicsRegion may not behave as intended."); + } + nVolumes += nVolumesCurrent; + } + + ACTS_INFO("Created region " << m_name); + ACTS_INFO("A total of " << nVolumes << " volumes were assigned"); + + // create a G4ProductionCuts object and set appropriate values + G4ProductionCuts* cuts = new G4ProductionCuts(); + cuts->SetProductionCut(m_cfg.gammaCut, "gamma"); + cuts->SetProductionCut(m_cfg.electronCut, "e-"); + cuts->SetProductionCut(m_cfg.positronCut, "e+"); + cuts->SetProductionCut(m_cfg.protonCut, "proton"); + + ACTS_INFO("Setting production cuts to"); + ACTS_INFO(" gamma: " << m_cfg.gammaCut); + ACTS_INFO(" e-: " << m_cfg.electronCut); + ACTS_INFO(" e+: " << m_cfg.positronCut); + ACTS_INFO(" proton: " << m_cfg.protonCut); + + // assign cuts to the region + region->SetProductionCuts(cuts); +} + +} // namespace ActsExamples diff --git a/Examples/Algorithms/Geant4/src/TelescopeG4DetectorConstruction.cpp b/Examples/Algorithms/Geant4/src/TelescopeG4DetectorConstruction.cpp index f2e78cd859e..9fbda5c4c93 100644 --- a/Examples/Algorithms/Geant4/src/TelescopeG4DetectorConstruction.cpp +++ b/Examples/Algorithms/Geant4/src/TelescopeG4DetectorConstruction.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2022 CERN for the benefit of the Acts project +// Copyright (C) 2022-2024 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 @@ -20,19 +20,17 @@ #include #include "G4Box.hh" -#include "G4Cons.hh" #include "G4LogicalVolume.hh" #include "G4NistManager.hh" -#include "G4Orb.hh" #include "G4PVPlacement.hh" #include "G4RunManager.hh" -#include "G4Sphere.hh" #include "G4SystemOfUnits.hh" -#include "G4Trd.hh" ActsExamples::Telescope::TelescopeG4DetectorConstruction:: - TelescopeG4DetectorConstruction(const TelescopeDetector::Config& cfg) - : m_cfg(cfg) { + TelescopeG4DetectorConstruction( + const TelescopeDetector::Config& cfg, + std::vector> regionCreators) + : m_cfg(cfg), m_regionCreators(std::move(regionCreators)) { throw_assert(cfg.surfaceType == static_cast(Telescope::TelescopeSurfaceType::Plane), "only plan is supported right now"); @@ -162,15 +160,23 @@ ActsExamples::Telescope::TelescopeG4DetectorConstruction::Construct() { checkOverlaps); // overlaps checking } + // Create regions + for (const auto& regionCreator : m_regionCreators) { + regionCreator->Construct(); + } + return m_world; } ActsExamples::Telescope::TelescopeG4DetectorConstructionFactory:: - TelescopeG4DetectorConstructionFactory(const TelescopeDetector::Config& cfg) - : m_cfg(cfg) {} + TelescopeG4DetectorConstructionFactory( + const TelescopeDetector::Config& cfg, + std::vector> regionCreators) + : m_cfg(cfg), m_regionCreators(std::move(regionCreators)) {} std::unique_ptr ActsExamples::Telescope::TelescopeG4DetectorConstructionFactory::factorize() const { - return std::make_unique(m_cfg); + return std::make_unique(m_cfg, + m_regionCreators); } diff --git a/Examples/Algorithms/Generators/ActsExamples/Generators/EventGenerator.hpp b/Examples/Algorithms/Generators/ActsExamples/Generators/EventGenerator.hpp index a88979b3479..6f4a8260e97 100644 --- a/Examples/Algorithms/Generators/ActsExamples/Generators/EventGenerator.hpp +++ b/Examples/Algorithms/Generators/ActsExamples/Generators/EventGenerator.hpp @@ -6,10 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file -/// @date 2018-03-13 -/// @author Moritz Kiehn - #pragma once #include "Acts/Definitions/Algebra.hpp" diff --git a/Examples/Algorithms/Generators/ActsExamples/Generators/MultiplicityGenerators.hpp b/Examples/Algorithms/Generators/ActsExamples/Generators/MultiplicityGenerators.hpp index c09c3803a54..c859f24de4f 100644 --- a/Examples/Algorithms/Generators/ActsExamples/Generators/MultiplicityGenerators.hpp +++ b/Examples/Algorithms/Generators/ActsExamples/Generators/MultiplicityGenerators.hpp @@ -6,10 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file -/// @date 2018-03-13 -/// @author Moritz Kiehn - #pragma once #include "ActsExamples/Framework/RandomNumbers.hpp" @@ -26,9 +22,7 @@ struct FixedMultiplicityGenerator FixedMultiplicityGenerator(std::size_t _n) : n{_n} {} FixedMultiplicityGenerator() = default; - std::size_t operator()(RandomEngine& /* unused */) const override { - return n; - } + std::size_t operator()(RandomEngine& /*rng*/) const override { return n; } }; struct PoissonMultiplicityGenerator diff --git a/Examples/Algorithms/Generators/ActsExamples/Generators/VertexGenerators.hpp b/Examples/Algorithms/Generators/ActsExamples/Generators/VertexGenerators.hpp index 6735b372010..9602c0815ba 100644 --- a/Examples/Algorithms/Generators/ActsExamples/Generators/VertexGenerators.hpp +++ b/Examples/Algorithms/Generators/ActsExamples/Generators/VertexGenerators.hpp @@ -6,10 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file -/// @date 2018-03-13 -/// @author Moritz Kiehn - #pragma once #include "Acts/Definitions/Algebra.hpp" @@ -25,7 +21,7 @@ struct FixedPrimaryVertexPositionGenerator /// The fixed vertex position and time. Acts::Vector4 fixed = Acts::Vector4::Zero(); - Acts::Vector4 operator()(RandomEngine& /* unused */) const override { + Acts::Vector4 operator()(RandomEngine& /*rng*/) const override { return fixed; } }; diff --git a/Examples/Algorithms/MaterialMapping/CMakeLists.txt b/Examples/Algorithms/MaterialMapping/CMakeLists.txt index ce7fde4be46..f5d887955e5 100644 --- a/Examples/Algorithms/MaterialMapping/CMakeLists.txt +++ b/Examples/Algorithms/MaterialMapping/CMakeLists.txt @@ -1,6 +1,7 @@ add_library( ActsExamplesMaterialMapping SHARED - src/MaterialMapping.cpp) + src/MaterialMapping.cpp + src/CoreMaterialMapping.cpp) target_include_directories( ActsExamplesMaterialMapping PUBLIC $) diff --git a/Examples/Algorithms/MaterialMapping/include/ActsExamples/MaterialMapping/CoreMaterialMapping.hpp b/Examples/Algorithms/MaterialMapping/include/ActsExamples/MaterialMapping/CoreMaterialMapping.hpp new file mode 100644 index 00000000000..9233f67ad5b --- /dev/null +++ b/Examples/Algorithms/MaterialMapping/include/ActsExamples/MaterialMapping/CoreMaterialMapping.hpp @@ -0,0 +1,89 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2024 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 http://mozilla.org/MPL/2.0/. + +#pragma once + +#include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/Material/MaterialMapper.hpp" +#include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/Framework/DataHandle.hpp" +#include "ActsExamples/Framework/IAlgorithm.hpp" +#include "ActsExamples/Framework/ProcessCode.hpp" +#include "ActsExamples/MaterialMapping/IMaterialWriter.hpp" + +namespace ActsExamples { + +/// @class CoreMaterialMapping +/// +/// @brief Initiates and executes material mapping using the MaterialMapper +/// from the core component of ACTS +/// +/// By construction, the material mapping needs inter-event information +/// to build the material maps of accumulated single particle views. +/// However, running it in one single event, puts enormous pressure onto +/// the I/O structure. +/// +/// It therefore saves the mapping state/cache as a private member variable +/// and is designed to be executed in a single threaded mode. +class CoreMaterialMapping : public IAlgorithm { + public: + /// @class nested Config class + /// of the MaterialMapping algorithm + struct Config { + /// Input collection + std::string inputMaterialTracks = "material_tracks"; + + /// The actually mapped material tracks + std::string mappedMaterialTracks = "mapped_material_tracks"; + + /// Theunmapped part of the material tracks + std::string unmappedMaterialTracks = "unmapped_material_tracks"; + + /// The ACTS material mapper from the core component + std::shared_ptr materialMapper = nullptr; + + /// The writer of the material + std::vector> materiaMaplWriters{}; + }; + + /// Constructor + /// + /// @param cfg The configuration struct carrying the used tools + /// @param level The output logging level + CoreMaterialMapping(const Config& cfg, + Acts::Logging::Level level = Acts::Logging::INFO); + + /// Destructor + /// - it also writes out the file + ~CoreMaterialMapping() override; + + /// Framework execute method + /// + /// @param context The algorithm context for event consistency + ActsExamples::ProcessCode execute( + const AlgorithmContext& context) const override; + + /// Readonly access to the config + const Config& config() const { return m_cfg; } + + private: + Config m_cfg; //!< internal config object + + std::unique_ptr m_mappingState{nullptr}; + + ReadDataHandle> + m_inputMaterialTracks{this, "InputMaterialTracks"}; + + WriteDataHandle> + m_outputMappedMaterialTracks{this, "OutputMappedMaterialTracks"}; + + WriteDataHandle> + m_outputUnmappedMaterialTracks{this, "OutputUnmappedMaterialTracks"}; +}; + +} // namespace ActsExamples diff --git a/Examples/Algorithms/MaterialMapping/src/CoreMaterialMapping.cpp b/Examples/Algorithms/MaterialMapping/src/CoreMaterialMapping.cpp new file mode 100644 index 00000000000..b8d4e5df30d --- /dev/null +++ b/Examples/Algorithms/MaterialMapping/src/CoreMaterialMapping.cpp @@ -0,0 +1,81 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2020 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 http://mozilla.org/MPL/2.0/. + +#include "ActsExamples/MaterialMapping/CoreMaterialMapping.hpp" + +#include "Acts/Material/AccumulatedMaterialSlab.hpp" +#include "Acts/Material/AccumulatedSurfaceMaterial.hpp" +#include "ActsExamples/MaterialMapping/IMaterialWriter.hpp" + +#include +#include + +namespace ActsExamples { + +CoreMaterialMapping::CoreMaterialMapping(const CoreMaterialMapping::Config& cfg, + Acts::Logging::Level level) + : IAlgorithm("CoreMaterialMapping", level), m_cfg(cfg) { + // Prepare the I/O collections + m_inputMaterialTracks.initialize(m_cfg.inputMaterialTracks); + m_outputMappedMaterialTracks.initialize(m_cfg.mappedMaterialTracks); + m_outputUnmappedMaterialTracks.initialize(m_cfg.unmappedMaterialTracks); + + ACTS_INFO("This algorithm requires inter-event information, " + << "run in single-threaded mode!"); + + if (m_cfg.materialMapper == nullptr) { + throw std::invalid_argument("Missing material mapper"); + } + // Create the state object + m_mappingState = m_cfg.materialMapper->createState(); +} + +CoreMaterialMapping::~CoreMaterialMapping() { + Acts::DetectorMaterialMaps detectorMaterial = + m_cfg.materialMapper->finalizeMaps(*m_mappingState); + // Loop over the available writers and write the maps + for (auto& imw : m_cfg.materiaMaplWriters) { + imw->writeMaterial(detectorMaterial); + } +} + +ProcessCode CoreMaterialMapping::execute( + const AlgorithmContext& context) const { + // Take the collection from the EventStore: input collection + std::unordered_map + mtrackCollection = m_inputMaterialTracks(context); + + // Write the output collections to the Event store : mapped and unmapped + std::unordered_map + mappedTrackCollection; + + std::unordered_map + unmappedTrackCollection; + + // To make it work with the framework needs a lock guard + auto mappingState = + const_cast(m_mappingState.get()); + + for (auto& [idTrack, mTrack] : mtrackCollection) { + auto [mapped, unmapped] = m_cfg.materialMapper->mapMaterial( + *mappingState, context.geoContext, context.magFieldContext, mTrack); + + mappedTrackCollection.emplace_hint(mappedTrackCollection.end(), idTrack, + mapped); + unmappedTrackCollection.emplace_hint(unmappedTrackCollection.end(), idTrack, + unmapped); + } + + // Write the mapped and unmapped material tracks to the output + m_outputMappedMaterialTracks(context, std::move(mappedTrackCollection)); + m_outputUnmappedMaterialTracks(context, std::move(unmappedTrackCollection)); + + return ProcessCode::SUCCESS; +} + +} // namespace ActsExamples diff --git a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp index e75c0e4b6c1..58687466e85 100644 --- a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp +++ b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp @@ -118,6 +118,9 @@ class TrackFindingAlgorithm final : public IAlgorithm { /// Whether to use seed deduplication /// This is only available if `inputSeeds` is set. bool seedDeduplication = false; + /// Whether to stick on the seed measurements during track finding. + /// This is only available if `inputSeeds` is set. + bool stayOnSeed = false; /// Compute shared hit information bool computeSharedHits = false; }; @@ -164,6 +167,9 @@ class TrackFindingAlgorithm final : public IAlgorithm { mutable std::atomic m_nFailedSeeds{0}; mutable std::atomic m_nFailedSmoothing{0}; mutable std::atomic m_nFailedExtrapolation{0}; + mutable std::atomic m_nFoundTracks{0}; + mutable std::atomic m_nSelectedTracks{0}; + mutable std::atomic m_nStoppedBranches{0}; mutable tbb::combinable m_memoryStatistics{[]() { diff --git a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackParamsEstimationAlgorithm.hpp b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackParamsEstimationAlgorithm.hpp index 86b25e04689..202112f75e7 100644 --- a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackParamsEstimationAlgorithm.hpp +++ b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackParamsEstimationAlgorithm.hpp @@ -71,9 +71,25 @@ class TrackParamsEstimationAlgorithm final : public IAlgorithm { double bFieldMin = 0.1 * Acts::UnitConstants::T; /// Initial covariance matrix diagonal. std::array initialSigmas = { - 1 * Acts::UnitConstants::mm, 1 * Acts::UnitConstants::mm, - 1 * Acts::UnitConstants::degree, 1 * Acts::UnitConstants::degree, - 0.1 / Acts::UnitConstants::GeV, 1 * Acts::UnitConstants::ns}; + 1 * Acts::UnitConstants::mm, + 1 * Acts::UnitConstants::mm, + 1 * Acts::UnitConstants::degree, + 1 * Acts::UnitConstants::degree, + 0 * Acts::UnitConstants::e / Acts::UnitConstants::GeV, + 1 * Acts::UnitConstants::ns}; + /// Initial q/p coefficient covariance matrix diagonal. + std::array initialSimgaQoverPCoefficients = { + 0 * Acts::UnitConstants::mm / + (Acts::UnitConstants::e * Acts::UnitConstants::GeV), + 0 * Acts::UnitConstants::mm / + (Acts::UnitConstants::e * Acts::UnitConstants::GeV), + 0 * Acts::UnitConstants::degree / + (Acts::UnitConstants::e * Acts::UnitConstants::GeV), + 0 * Acts::UnitConstants::degree / + (Acts::UnitConstants::e * Acts::UnitConstants::GeV), + 0.1, + 0 * Acts::UnitConstants::ns / + (Acts::UnitConstants::e * Acts::UnitConstants::GeV)}; /// Inflate initial covariance. std::array initialVarInflation = {1., 1., 1., 1., 1., 1.}; /// Inflate time covariance if no time measurement is available. @@ -101,10 +117,6 @@ class TrackParamsEstimationAlgorithm final : public IAlgorithm { private: Config m_cfg; - /// The track parameters covariance (assumed to be the same for all estimated - /// track parameters for the moment) - Acts::BoundSquareMatrix m_covariance = Acts::BoundSquareMatrix::Zero(); - ReadDataHandle m_inputSeeds{this, "InputSeeds"}; ReadDataHandle m_inputTracks{this, "InputTracks"}; diff --git a/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp b/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp index 1cd7a2433b1..1eb961a0234 100644 --- a/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp +++ b/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp @@ -10,6 +10,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Direction.hpp" +#include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/EventData/MultiTrajectory.hpp" #include "Acts/EventData/ProxyAccessor.hpp" #include "Acts/EventData/SourceLink.hpp" @@ -54,9 +55,76 @@ #include +// Specialize std::hash for SeedIdentifier +// This is required to use SeedIdentifier as a key in an `std::unordered_map`. +template +struct std::hash> { + std::size_t operator()(const std::array& array) const { + std::hash hasher; + std::size_t result = 0; + for (auto&& element : array) { + boost::hash_combine(result, hasher(element)); + } + return result; + } +}; + namespace ActsExamples { + namespace { +class MeasurementSelector { + public: + using Traj = Acts::VectorMultiTrajectory; + + explicit MeasurementSelector(Acts::MeasurementSelector selector) + : m_selector(std::move(selector)) {} + + void setSeed(const std::optional& seed) { m_seed = seed; } + + Acts::Result::iterator, + std::vector::iterator>> + select(std::vector& candidates, bool& isOutlier, + const Acts::Logger& logger) const { + if (m_seed.has_value()) { + std::vector newCandidates; + + for (const auto& candidate : candidates) { + if (isSeedCandidate(candidate)) { + newCandidates.push_back(candidate); + } + } + + if (!newCandidates.empty()) { + candidates = std::move(newCandidates); + } + } + + return m_selector.select(candidates, isOutlier, + logger); + } + + private: + Acts::MeasurementSelector m_selector; + std::optional m_seed; + + bool isSeedCandidate(const Traj::TrackStateProxy& candidate) const { + assert(candidate.hasUncalibratedSourceLink()); + + const Acts::SourceLink& sourceLink = candidate.getUncalibratedSourceLink(); + + for (const auto& sp : m_seed->sp()) { + for (const auto& sl : sp->sourceLinks()) { + if (sourceLink.get() == sl.get()) { + return true; + } + } + } + + return false; + } +}; + /// Source link indices of the bottom, middle, top measurements. /// In case of strip seeds only the first source link of the pair is used. using SeedIdentifier = std::array; @@ -106,37 +174,79 @@ void visitSeedIdentifiers(const TrackProxy& track, Visitor visitor) { } } -} // namespace -} // namespace ActsExamples +class BranchStopper { + public: + using Config = + std::optional>; -// Specialize std::hash for SeedIdentifier -// This is required to use SeedIdentifier as a key in an `std::unordered_map`. -template -struct std::hash> { - std::size_t operator()(const std::array& array) const { - std::hash hasher; - std::size_t result = 0; - for (auto&& element : array) { - boost::hash_combine(result, hasher(element)); + mutable std::atomic m_nStoppedBranches{0}; + + explicit BranchStopper(const Config& config) : m_config(config) {} + + bool operator()( + const Acts::CombinatorialKalmanFilterTipState& tipState, + Acts::VectorMultiTrajectory::TrackStateProxy& trackState) const { + if (!m_config.has_value()) { + return false; } - return result; + + const Acts::TrackSelector::Config* singleConfig = std::visit( + [&](const auto& config) -> const Acts::TrackSelector::Config* { + using T = std::decay_t; + if constexpr (std::is_same_v) { + return &config; + } else if constexpr (std::is_same_v< + T, Acts::TrackSelector::EtaBinnedConfig>) { + double theta = trackState.parameters()[Acts::eBoundTheta]; + double eta = -std::log(std::tan(0.5 * theta)); + return config.hasCuts(eta) ? &config.getCuts(eta) : nullptr; + } + }, + *m_config); + + if (singleConfig == nullptr) { + ++m_nStoppedBranches; + return true; + } + + // Continue if the number of holes is below the maximum + if (tipState.nHoles <= singleConfig->maxHoles) { + return false; + } + + // Continue if the number of outliers is below the maximum + if (tipState.nOutliers <= singleConfig->maxOutliers) { + return false; + } + + // If there are not enough measurements but more holes than allowed we stop + if (tipState.nMeasurements < singleConfig->minMeasurements) { + ++m_nStoppedBranches; + return true; + } + + // Getting another measurement guarantees that the holes are in the middle + // of the track + if (trackState.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag)) { + ++m_nStoppedBranches; + return true; + } + + // We cannot be sure if the holes are just at the end of the track so we + // have to keep going + return false; } + + private: + Config m_config; }; -namespace ActsExamples { +} // namespace TrackFindingAlgorithm::TrackFindingAlgorithm(Config config, Acts::Logging::Level level) - : IAlgorithm("TrackFindingAlgorithm", level), - m_cfg(std::move(config)), - m_trackSelector( - m_cfg.trackSelectorCfg.has_value() - ? std::visit( - [](const auto& cfg) -> std::optional { - return {cfg}; - }, - m_cfg.trackSelectorCfg.value()) - : std::nullopt) { + : IAlgorithm("TrackFindingAlgorithm", level), m_cfg(std::move(config)) { if (m_cfg.inputMeasurements.empty()) { throw std::invalid_argument("Missing measurements input collection"); } @@ -156,6 +266,19 @@ TrackFindingAlgorithm::TrackFindingAlgorithm(Config config, "Missing seeds input collection. This is " "required for seed deduplication."); } + if (m_cfg.stayOnSeed && m_cfg.inputSeeds.empty()) { + throw std::invalid_argument( + "Missing seeds input collection. This is " + "required for staying on seed."); + } + + if (m_cfg.trackSelectorCfg.has_value()) { + m_trackSelector = std::visit( + [](const auto& cfg) -> std::optional { + return {cfg}; + }, + m_cfg.trackSelectorCfg.value()); + } m_inputMeasurements.initialize(m_cfg.inputMeasurements); m_inputSourceLinks.initialize(m_cfg.inputSourceLinks); @@ -187,18 +310,23 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { PassThroughCalibrator pcalibrator; MeasurementCalibratorAdapter calibrator(pcalibrator, measurements); Acts::GainMatrixUpdater kfUpdater; - Acts::MeasurementSelector measSel{m_cfg.measurementSelectorCfg}; + MeasurementSelector measSel{ + Acts::MeasurementSelector(m_cfg.measurementSelectorCfg)}; - Acts::CombinatorialKalmanFilterExtensions - extensions; + using Extensions = + Acts::CombinatorialKalmanFilterExtensions; + + BranchStopper branchStopper(m_cfg.trackSelectorCfg); + + Extensions extensions; extensions.calibrator.connect<&MeasurementCalibratorAdapter::calibrate>( &calibrator); extensions.updater.connect< &Acts::GainMatrixUpdater::operator()>( &kfUpdater); - extensions.measurementSelector - .connect<&Acts::MeasurementSelector::select>( - &measSel); + extensions.measurementSelector.connect<&MeasurementSelector::select>( + &measSel); + extensions.branchStopper.connect<&BranchStopper::operator()>(&branchStopper); IndexSourceLinkAccessor slAccessor; slAccessor.container = &sourceLinks; @@ -219,7 +347,7 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { ctx.geoContext, ctx.magFieldContext, ctx.calibContext, slAccessorDelegate, extensions, firstPropOptions); - ActsExamples::TrackFindingAlgorithm::TrackFinderOptions secondOptions( + TrackFindingAlgorithm::TrackFinderOptions secondOptions( ctx.geoContext, ctx.magFieldContext, ctx.calibContext, slAccessorDelegate, extensions, secondPropOptions); secondOptions.targetSurface = pSurface.get(); @@ -258,6 +386,8 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { std::unordered_map discoveredSeeds; auto addTrack = [&](const TrackProxy& track) { + ++m_nFoundTracks; + // flag seeds which are covered by the track visitSeedIdentifiers(track, [&](const SeedIdentifier& seedIdentifier) { if (auto it = discoveredSeeds.find(seedIdentifier); @@ -270,6 +400,8 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { return; } + ++m_nSelectedTracks; + auto destProxy = tracks.makeTrack(); // make sure we copy track states! destProxy.copyFrom(track, true); @@ -286,15 +418,22 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { for (std::size_t iSeed = 0; iSeed < initialParameters.size(); ++iSeed) { m_nTotalSeeds++; - if (seeds != nullptr && m_cfg.seedDeduplication) { + if (seeds != nullptr) { const SimSeed& seed = seeds->at(iSeed); - SeedIdentifier seedIdentifier = makeSeedIdentifier(seed); - // check if the seed has been discovered already - if (auto it = discoveredSeeds.find(seedIdentifier); - it != discoveredSeeds.end() && it->second) { - m_nDeduplicatedSeeds++; - ACTS_VERBOSE("Skipping seed " << iSeed << " due to deduplication."); - continue; + + if (m_cfg.seedDeduplication) { + SeedIdentifier seedIdentifier = makeSeedIdentifier(seed); + // check if the seed has been discovered already + if (auto it = discoveredSeeds.find(seedIdentifier); + it != discoveredSeeds.end() && it->second) { + m_nDeduplicatedSeeds++; + ACTS_VERBOSE("Skipping seed " << iSeed << " due to deduplication."); + continue; + } + } + + if (m_cfg.stayOnSeed) { + measSel.setSeed(seed); } } @@ -306,7 +445,6 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { auto firstResult = (*m_cfg.findTracks)(firstInitialParameters, firstOptions, tracksTemp); - nSeed++; if (!firstResult.ok()) { @@ -414,7 +552,6 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { << iSeed << " and track " << secondTrack.index() << " failed with error " << secondExtrapolationResult.error()); - continue; } @@ -459,6 +596,8 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { ACTS_DEBUG("Finalized track finding with " << tracks.size() << " track candidates."); + m_nStoppedBranches += branchStopper.m_nStoppedBranches; + m_memoryStatistics.local().hist += tracks.trackStateContainer().statistics().hist; @@ -485,6 +624,9 @@ ProcessCode TrackFindingAlgorithm::finalize() { ACTS_INFO("- failed extrapolation: " << m_nFailedExtrapolation); ACTS_INFO("- failure ratio seeds: " << static_cast(m_nFailedSeeds) / m_nTotalSeeds); + ACTS_INFO("- found tracks: " << m_nFoundTracks); + ACTS_INFO("- selected tracks: " << m_nSelectedTracks); + ACTS_INFO("- stopped branches: " << m_nStoppedBranches); auto memoryStatistics = m_memoryStatistics.combine([](const auto& a, const auto& b) { diff --git a/Examples/Algorithms/TrackFinding/src/TrackParamsEstimationAlgorithm.cpp b/Examples/Algorithms/TrackFinding/src/TrackParamsEstimationAlgorithm.cpp index e4d95feb075..a85ee184d39 100644 --- a/Examples/Algorithms/TrackFinding/src/TrackParamsEstimationAlgorithm.cpp +++ b/Examples/Algorithms/TrackFinding/src/TrackParamsEstimationAlgorithm.cpp @@ -9,6 +9,7 @@ #include "ActsExamples/TrackFinding/TrackParamsEstimationAlgorithm.hpp" #include "Acts/Definitions/Algebra.hpp" +#include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/EventData/ParticleHypothesis.hpp" #include "Acts/EventData/SourceLink.hpp" #include "Acts/Geometry/GeometryIdentifier.hpp" @@ -32,6 +33,40 @@ #include #include +namespace ActsExamples { + +namespace { + +Acts::BoundSquareMatrix makeInitialCovariance( + const TrackParamsEstimationAlgorithm::Config& config, + const Acts::BoundVector& params, const SimSpacePoint& sp) { + Acts::BoundSquareMatrix result = Acts::BoundSquareMatrix::Zero(); + + for (std::size_t i = Acts::eBoundLoc0; i < Acts::eBoundSize; ++i) { + double sigma = config.initialSigmas[i]; + + // Add momentum dependent uncertainties + sigma += + config.initialSimgaQoverPCoefficients[i] * params[Acts::eBoundQOverP]; + + double var = sigma * sigma; + + // Inflate the time uncertainty if no time measurement is available + if (i == Acts::eBoundTime && !sp.t().has_value()) { + var *= config.noTimeVarInflation; + } + + // Inflate the initial covariance + var *= config.initialVarInflation[i]; + + result(i, i) = var; + } + + return result; +} + +} // namespace + ActsExamples::TrackParamsEstimationAlgorithm::TrackParamsEstimationAlgorithm( ActsExamples::TrackParamsEstimationAlgorithm::Config cfg, Acts::Logging::Level lvl) @@ -56,12 +91,6 @@ ActsExamples::TrackParamsEstimationAlgorithm::TrackParamsEstimationAlgorithm( m_outputTrackParameters.initialize(m_cfg.outputTrackParameters); m_outputSeeds.maybeInitialize(m_cfg.outputSeeds); m_outputTracks.maybeInitialize(m_cfg.outputProtoTracks); - - // Set up the track parameters covariance (the same for all tracks) - for (std::size_t i = Acts::eBoundLoc0; i < Acts::eBoundSize; ++i) { - m_covariance(i, i) = m_cfg.initialVarInflation[i] * m_cfg.initialSigmas[i] * - m_cfg.initialSigmas[i]; - } } ActsExamples::ProcessCode ActsExamples::TrackParamsEstimationAlgorithm::execute( @@ -132,11 +161,8 @@ ActsExamples::ProcessCode ActsExamples::TrackParamsEstimationAlgorithm::execute( const auto& params = optParams.value(); - Acts::BoundSquareMatrix cov = m_covariance; - if (!bottomSP->t().has_value()) { - // Inflate the time uncertainty if no time measurement is available - cov(Acts::eBoundTime, Acts::eBoundTime) *= m_cfg.noTimeVarInflation; - } + Acts::BoundSquareMatrix cov = + makeInitialCovariance(m_cfg, params, *bottomSP); trackParameters.emplace_back(surface->getSharedPtr(), params, cov, m_cfg.particleHypothesis); @@ -161,3 +187,4 @@ ActsExamples::ProcessCode ActsExamples::TrackParamsEstimationAlgorithm::execute( return ProcessCode::SUCCESS; } +} // namespace ActsExamples diff --git a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.hpp b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.hpp index d6c9fba3bc9..86389fd8cfc 100644 --- a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.hpp +++ b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.hpp @@ -6,10 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file -/// @date 2018-03-14 -/// @author Moritz Kiehn - #pragma once #include "Acts/Geometry/GeometryIdentifier.hpp" diff --git a/Examples/Algorithms/Vertexing/include/ActsExamples/Vertexing/VertexFitterAlgorithm.hpp b/Examples/Algorithms/Vertexing/include/ActsExamples/Vertexing/VertexFitterAlgorithm.hpp index 366115c4c29..578f266865e 100644 --- a/Examples/Algorithms/Vertexing/include/ActsExamples/Vertexing/VertexFitterAlgorithm.hpp +++ b/Examples/Algorithms/Vertexing/include/ActsExamples/Vertexing/VertexFitterAlgorithm.hpp @@ -24,6 +24,7 @@ #include "ActsExamples/EventData/ProtoVertex.hpp" #include "ActsExamples/EventData/Track.hpp" #include "ActsExamples/EventData/Trajectories.hpp" +#include "ActsExamples/EventData/Vertex.hpp" #include "ActsExamples/Framework/DataHandle.hpp" #include "ActsExamples/Framework/IAlgorithm.hpp" #include "ActsExamples/Framework/ProcessCode.hpp" @@ -45,14 +46,6 @@ struct AlgorithmContext; class VertexFitterAlgorithm final : public IAlgorithm { public: - using Propagator = Acts::Propagator>; - using PropagatorOptions = Acts::PropagatorOptions<>; - using Linearizer = Acts::HelicalTrackLinearizer; - using VertexFitter = Acts::FullBilloirVertexFitter; - using VertexFitterOptions = Acts::VertexingOptions; - - using VertexCollection = std::vector; - struct Config { /// Optional. Input track parameters collection std::string inputTrackParameters; @@ -95,7 +88,7 @@ class VertexFitterAlgorithm final : public IAlgorithm { ReadDataHandle m_inputProtoVertices{ this, "InputProtoVertices"}; - WriteDataHandle m_outputVertices{this, "OutputVertices"}; + WriteDataHandle m_outputVertices{this, "OutputVertices"}; }; } // namespace ActsExamples diff --git a/Examples/Algorithms/Vertexing/src/VertexFitterAlgorithm.cpp b/Examples/Algorithms/Vertexing/src/VertexFitterAlgorithm.cpp index 1ce62fc90a3..15ab2b81860 100644 --- a/Examples/Algorithms/Vertexing/src/VertexFitterAlgorithm.cpp +++ b/Examples/Algorithms/Vertexing/src/VertexFitterAlgorithm.cpp @@ -16,6 +16,7 @@ #include "Acts/Vertexing/TrackAtVertex.hpp" #include "Acts/Vertexing/Vertex.hpp" #include "ActsExamples/EventData/ProtoVertex.hpp" +#include "ActsExamples/EventData/Vertex.hpp" #include "ActsExamples/Framework/AlgorithmContext.hpp" #include @@ -41,6 +42,12 @@ ActsExamples::VertexFitterAlgorithm::VertexFitterAlgorithm( ActsExamples::ProcessCode ActsExamples::VertexFitterAlgorithm::execute( const ActsExamples::AlgorithmContext& ctx) const { + using Propagator = Acts::Propagator>; + using PropagatorOptions = Acts::PropagatorOptions<>; + using Linearizer = Acts::HelicalTrackLinearizer; + using VertexFitter = Acts::FullBilloirVertexFitter; + using VertexFitterOptions = Acts::VertexingOptions; + // Set up EigenStepper Acts::EigenStepper<> stepper(m_cfg.bField); @@ -74,7 +81,7 @@ ActsExamples::ProcessCode ActsExamples::VertexFitterAlgorithm::execute( std::vector inputTracks; - VertexCollection fittedVertices; + VertexContainer fittedVertices; for (const auto& protoVertex : protoVertices) { // un-constrained fit requires at least two tracks diff --git a/Examples/Framework/include/ActsExamples/EventData/Vertex.hpp b/Examples/Framework/include/ActsExamples/EventData/Vertex.hpp new file mode 100644 index 00000000000..f808aa392ad --- /dev/null +++ b/Examples/Framework/include/ActsExamples/EventData/Vertex.hpp @@ -0,0 +1,20 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2024 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 http://mozilla.org/MPL/2.0/. + +#pragma once + +#include "Acts/Vertexing/Vertex.hpp" + +#include + +namespace ActsExamples { + +/// Container of vertices. +using VertexContainer = std::vector; + +} // namespace ActsExamples diff --git a/Examples/Framework/include/ActsExamples/Framework/IAlgorithm.hpp b/Examples/Framework/include/ActsExamples/Framework/IAlgorithm.hpp index 73992c579e7..29b6d894bae 100644 --- a/Examples/Framework/include/ActsExamples/Framework/IAlgorithm.hpp +++ b/Examples/Framework/include/ActsExamples/Framework/IAlgorithm.hpp @@ -6,12 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file -/// @date 2016-05-11 Initial version -/// @date 2017-07-27 Simplify interface -/// @author Andreas Salzburger -/// @author Moritz Kiehn - #pragma once #include "ActsExamples/Framework/ProcessCode.hpp" diff --git a/Examples/Framework/include/ActsExamples/Framework/IWriter.hpp b/Examples/Framework/include/ActsExamples/Framework/IWriter.hpp index b111ad56004..49a096da2e1 100644 --- a/Examples/Framework/include/ActsExamples/Framework/IWriter.hpp +++ b/Examples/Framework/include/ActsExamples/Framework/IWriter.hpp @@ -6,10 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file -/// @date 2017-07-25 -/// @author Moritz Kiehnn - #pragma once #include "ActsExamples/Framework/AlgorithmContext.hpp" diff --git a/Examples/Framework/include/ActsExamples/Framework/WriterT.hpp b/Examples/Framework/include/ActsExamples/Framework/WriterT.hpp index a07fcf68f6c..84b3bcbf571 100644 --- a/Examples/Framework/include/ActsExamples/Framework/WriterT.hpp +++ b/Examples/Framework/include/ActsExamples/Framework/WriterT.hpp @@ -6,10 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file -/// @date 2017-08-07 -/// @author Moritz Kiehnn - #pragma once #include "ActsExamples/Framework/DataHandle.hpp" diff --git a/Examples/Framework/src/Framework/Sequencer.cpp b/Examples/Framework/src/Framework/Sequencer.cpp index 940ab476f09..400f3bab352 100644 --- a/Examples/Framework/src/Framework/Sequencer.cpp +++ b/Examples/Framework/src/Framework/Sequencer.cpp @@ -313,7 +313,8 @@ std::pair Sequencer::determineEventsRange() const { // since we use event ranges (and not just num events) they might not // overlap if (end < beg) { - ACTS_ERROR("Available events ranges from readers do not overlap"); + ACTS_ERROR("Available events ranges from readers do not overlap (beg=" + << beg << ", end=" << end << ")"); return kInvalidEventsRange; } // configured readers without available events makes no sense diff --git a/Examples/HelloWorld/HelloWorld.cpp b/Examples/HelloWorld/HelloWorld.cpp index 535ad4d6e3c..391f5ab274a 100644 --- a/Examples/HelloWorld/HelloWorld.cpp +++ b/Examples/HelloWorld/HelloWorld.cpp @@ -6,9 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file -/// @brief An example tools that shows the sequencer functionality - #include "ActsExamples/Framework/RandomNumbers.hpp" #include "ActsExamples/Framework/Sequencer.hpp" @@ -19,9 +16,7 @@ #include "HelloRandomAlgorithm.hpp" #include "HelloWhiteBoardAlgorithm.hpp" -int main(int argc, char* argv[]) { - (void)argc; - (void)argv; +int main(void) { Acts::Logging::Level logLevel = Acts::Logging::INFO; // setup basic tools shared among algorithms diff --git a/Examples/Io/Csv/src/CsvOutputData.hpp b/Examples/Io/Csv/src/CsvOutputData.hpp index c06ba7144da..c3b7c3deafe 100644 --- a/Examples/Io/Csv/src/CsvOutputData.hpp +++ b/Examples/Io/Csv/src/CsvOutputData.hpp @@ -6,9 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file -/// @brief Plain structs that each define one row in a TrackML csv file - #pragma once #include diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.cpp b/Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.cpp index 6020f40a471..8454b153157 100644 --- a/Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.cpp +++ b/Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.cpp @@ -188,10 +188,14 @@ VertexPerformanceWriter::VertexPerformanceWriter( m_outputTree->Branch("vertex_primary", &m_vertexPrimary); m_outputTree->Branch("vertex_secondary", &m_vertexSecondary); + m_outputTree->Branch("nTracksTruthVtx", &m_nTracksOnTruthVertex); + + m_outputTree->Branch("truthPrimaryVertexDensity", + &m_truthPrimaryVertexDensity); + m_outputTree->Branch("truthVertexTrackWeights", &m_truthVertexTrackWeights); m_outputTree->Branch("truthVertexMatchRatio", &m_truthVertexMatchRatio); - - m_outputTree->Branch("nTracksTruthVtx", &m_nTracksOnTruthVertex); + m_outputTree->Branch("recoVertexContamination", &m_recoVertexContamination); m_outputTree->Branch("recoVertexClassification", &m_recoVertexClassification); @@ -358,6 +362,22 @@ ProcessCode VertexPerformanceWriter::writeT( return diff / std; }; + auto calculateTruthPrimaryVertexDensity = + [this, truthVertices](const Acts::Vertex& vtx) { + double z = vtx.fullPosition()[Acts::CoordinateIndices::eZ]; + int count = 0; + for (const SimVertex& truthVertex : truthVertices) { + if (truthVertex.vertexId().vertexSecondary() != 0) { + continue; + } + double zTruth = truthVertex.position4[Acts::CoordinateIndices::eZ]; + if (std::abs(z - zTruth) <= m_cfg.vertexDensityWindow) { + ++count; + } + } + return count / (2 * m_cfg.vertexDensityWindow); + }; + if (m_cfg.useTracks) { tracks = &m_inputTracks(ctx); @@ -421,6 +441,7 @@ ProcessCode VertexPerformanceWriter::writeT( struct ToTruthMatching { std::optional vertexId; double totalTrackWeight{}; + double truthMajorityTrackWeights{}; double matchFraction{}; RecoVertexClassification classification{RecoVertexClassification::Unknown}; @@ -473,19 +494,19 @@ ProcessCode VertexPerformanceWriter::writeT( ++fmap[vtxId].first; fmap[vtxId].second += weight; } - double maxOccurrence = -1; - SimVertexBarcode maxOccurrenceId = -1; + double truthMajorityVertexTrackWeights = 0; + SimVertexBarcode truthMajorityVertexId = 0; for (const auto& [vtxId, counter] : fmap) { - if (counter.second > maxOccurrence) { - maxOccurrenceId = vtxId; - maxOccurrence = counter.second; + if (counter.second > truthMajorityVertexTrackWeights) { + truthMajorityVertexId = vtxId; + truthMajorityVertexTrackWeights = counter.second; } } double sumPt2 = calcSumPt2(vtx); double vertexMatchFraction = - fmap[maxOccurrenceId].second / totalTrackWeight; + truthMajorityVertexTrackWeights / totalTrackWeight; RecoVertexClassification recoVertexClassification = RecoVertexClassification::Unknown; @@ -495,14 +516,15 @@ ProcessCode VertexPerformanceWriter::writeT( recoVertexClassification = RecoVertexClassification::Merged; } - recoToTruthMatching.push_back({maxOccurrenceId, totalTrackWeight, + recoToTruthMatching.push_back({truthMajorityVertexId, totalTrackWeight, + truthMajorityVertexTrackWeights, vertexMatchFraction, recoVertexClassification}); auto& recoToTruth = recoToTruthMatching.back(); // We have to decide if this reco vertex is a split vertex. - if (auto it = truthToRecoMatching.find(maxOccurrenceId); + if (auto it = truthToRecoMatching.find(truthMajorityVertexId); it != truthToRecoMatching.end()) { // This truth vertex is already matched to a reconstructed vertex so we // are dealing with a split vertex. @@ -527,7 +549,7 @@ ProcessCode VertexPerformanceWriter::writeT( it->second = {vtxIndex, sumPt2}; } } else { - truthToRecoMatching[maxOccurrenceId] = {vtxIndex, sumPt2}; + truthToRecoMatching[truthMajorityVertexId] = {vtxIndex, sumPt2}; } } @@ -541,41 +563,47 @@ ProcessCode VertexPerformanceWriter::writeT( const auto& toTruthMatching = recoToTruthMatching[vtxIndex]; - m_recoX.push_back(vtx.fullPosition()[Acts::FreeIndices::eFreePos0]); - m_recoY.push_back(vtx.fullPosition()[Acts::FreeIndices::eFreePos1]); - m_recoZ.push_back(vtx.fullPosition()[Acts::FreeIndices::eFreePos2]); - m_recoT.push_back(vtx.fullPosition()[Acts::FreeIndices::eFreeTime]); - - Acts::ActsScalar varX = vtx.fullCovariance()(Acts::FreeIndices::eFreePos0, - Acts::FreeIndices::eFreePos0); - Acts::ActsScalar varY = vtx.fullCovariance()(Acts::FreeIndices::eFreePos1, - Acts::FreeIndices::eFreePos1); - Acts::ActsScalar varZ = vtx.fullCovariance()(Acts::FreeIndices::eFreePos2, - Acts::FreeIndices::eFreePos2); + m_recoX.push_back(vtx.fullPosition()[Acts::CoordinateIndices::eX]); + m_recoY.push_back(vtx.fullPosition()[Acts::CoordinateIndices::eY]); + m_recoZ.push_back(vtx.fullPosition()[Acts::CoordinateIndices::eZ]); + m_recoT.push_back(vtx.fullPosition()[Acts::CoordinateIndices::eTime]); + + Acts::ActsScalar varX = vtx.fullCovariance()(Acts::CoordinateIndices::eX, + Acts::CoordinateIndices::eX); + Acts::ActsScalar varY = vtx.fullCovariance()(Acts::CoordinateIndices::eY, + Acts::CoordinateIndices::eY); + Acts::ActsScalar varZ = vtx.fullCovariance()(Acts::CoordinateIndices::eZ, + Acts::CoordinateIndices::eZ); Acts::ActsScalar varTime = vtx.fullCovariance()( - Acts::FreeIndices::eFreeTime, Acts::FreeIndices::eFreeTime); + Acts::CoordinateIndices::eTime, Acts::CoordinateIndices::eTime); m_covXX.push_back(varX); m_covYY.push_back(varY); m_covZZ.push_back(varZ); m_covTT.push_back(varTime); - m_covXY.push_back(vtx.fullCovariance()(Acts::FreeIndices::eFreePos0, - Acts::FreeIndices::eFreePos1)); - m_covXZ.push_back(vtx.fullCovariance()(Acts::FreeIndices::eFreePos0, - Acts::FreeIndices::eFreePos2)); - m_covXT.push_back(vtx.fullCovariance()(Acts::FreeIndices::eFreePos0, - Acts::FreeIndices::eFreeTime)); - m_covYZ.push_back(vtx.fullCovariance()(Acts::FreeIndices::eFreePos1, - Acts::FreeIndices::eFreePos2)); - m_covYT.push_back(vtx.fullCovariance()(Acts::FreeIndices::eFreePos1, - Acts::FreeIndices::eFreeTime)); - m_covZT.push_back(vtx.fullCovariance()(Acts::FreeIndices::eFreePos2, - Acts::FreeIndices::eFreeTime)); + m_covXY.push_back(vtx.fullCovariance()(Acts::CoordinateIndices::eX, + Acts::CoordinateIndices::eY)); + m_covXZ.push_back(vtx.fullCovariance()(Acts::CoordinateIndices::eX, + Acts::CoordinateIndices::eZ)); + m_covXT.push_back(vtx.fullCovariance()(Acts::CoordinateIndices::eX, + Acts::CoordinateIndices::eTime)); + m_covYZ.push_back(vtx.fullCovariance()(Acts::CoordinateIndices::eY, + Acts::CoordinateIndices::eZ)); + m_covYT.push_back(vtx.fullCovariance()(Acts::CoordinateIndices::eY, + Acts::CoordinateIndices::eTime)); + m_covZT.push_back(vtx.fullCovariance()(Acts::CoordinateIndices::eZ, + Acts::CoordinateIndices::eTime)); double sumPt2 = calcSumPt2(vtx); m_sumPt2.push_back(sumPt2); - double recoVertexTrackWeights = toTruthMatching.totalTrackWeight; + double recoVertexTrackWeights = 0; + for (const Acts::TrackAtVertex& trk : tracksAtVtx) { + if (trk.trackWeight < m_cfg.minTrkWeight) { + continue; + } + recoVertexTrackWeights += trk.trackWeight; + } m_recoVertexTrackWeights.push_back(recoVertexTrackWeights); unsigned int nTracksOnRecoVertex = @@ -593,6 +621,9 @@ ProcessCode VertexPerformanceWriter::writeT( } const SimVertex& truthVertex = *iTruthVertex; + m_vertexPrimary.push_back(truthVertex.vertexId().vertexPrimary()); + m_vertexSecondary.push_back(truthVertex.vertexId().vertexSecondary()); + // Count number of reconstructible tracks on truth vertex int nTracksOnTruthVertex = 0; for (const auto& particle : selectedParticles) { @@ -602,6 +633,20 @@ ProcessCode VertexPerformanceWriter::writeT( } m_nTracksOnTruthVertex.push_back(nTracksOnTruthVertex); + double truthPrimaryVertexDensity = + calculateTruthPrimaryVertexDensity(vtx); + m_truthPrimaryVertexDensity.push_back(truthPrimaryVertexDensity); + + double truthVertexTrackWeights = + toTruthMatching.truthMajorityTrackWeights; + m_truthVertexTrackWeights.push_back(truthVertexTrackWeights); + + double truthVertexMatchRatio = toTruthMatching.matchFraction; + m_truthVertexMatchRatio.push_back(truthVertexMatchRatio); + + double recoVertexContamination = 1 - truthVertexMatchRatio; + m_recoVertexContamination.push_back(recoVertexContamination); + RecoVertexClassification recoVertexClassification = toTruthMatching.classification; m_recoVertexClassification.push_back( @@ -613,39 +658,41 @@ ProcessCode VertexPerformanceWriter::writeT( ++m_nSplitVtx; } - m_truthVertexMatchRatio.push_back(toTruthMatching.matchFraction); - - m_vertexPrimary.push_back(truthVertex.vertexId().vertexPrimary()); - m_vertexSecondary.push_back(truthVertex.vertexId().vertexSecondary()); - const Acts::Vector4& truePos = truthVertex.position4; truthPos = truePos; - m_truthX.push_back(truePos[Acts::FreeIndices::eFreePos0]); - m_truthY.push_back(truePos[Acts::FreeIndices::eFreePos1]); - m_truthZ.push_back(truePos[Acts::FreeIndices::eFreePos2]); - m_truthT.push_back(truePos[Acts::FreeIndices::eFreeTime]); + m_truthX.push_back(truePos[Acts::CoordinateIndices::eX]); + m_truthY.push_back(truePos[Acts::CoordinateIndices::eY]); + m_truthZ.push_back(truePos[Acts::CoordinateIndices::eZ]); + m_truthT.push_back(truePos[Acts::CoordinateIndices::eTime]); const Acts::Vector4 diffPos = vtx.fullPosition() - truePos; - m_resX.push_back(diffPos[Acts::FreeIndices::eFreePos0]); - m_resY.push_back(diffPos[Acts::FreeIndices::eFreePos1]); - m_resZ.push_back(diffPos[Acts::FreeIndices::eFreePos2]); - m_resT.push_back(diffPos[Acts::FreeIndices::eFreeTime]); - - m_pullX.push_back(pull(diffPos[Acts::FreeIndices::eFreePos0], varX, "X")); - m_pullY.push_back(pull(diffPos[Acts::FreeIndices::eFreePos1], varY, "Y")); - m_pullZ.push_back(pull(diffPos[Acts::FreeIndices::eFreePos2], varZ, "Z")); + m_resX.push_back(diffPos[Acts::CoordinateIndices::eX]); + m_resY.push_back(diffPos[Acts::CoordinateIndices::eY]); + m_resZ.push_back(diffPos[Acts::CoordinateIndices::eZ]); + m_resT.push_back(diffPos[Acts::CoordinateIndices::eTime]); + + m_pullX.push_back(pull(diffPos[Acts::CoordinateIndices::eX], varX, "X")); + m_pullY.push_back(pull(diffPos[Acts::CoordinateIndices::eY], varY, "Y")); + m_pullZ.push_back(pull(diffPos[Acts::CoordinateIndices::eZ], varZ, "Z")); m_pullT.push_back( - pull(diffPos[Acts::FreeIndices::eFreeTime], varTime, "T")); + pull(diffPos[Acts::CoordinateIndices::eTime], varTime, "T")); truthInfoWritten = true; } if (!truthInfoWritten) { + m_vertexPrimary.push_back(-1); + m_vertexSecondary.push_back(-1); + m_nTracksOnTruthVertex.push_back(-1); - m_truthVertexMatchRatio.push_back(-1); + m_truthPrimaryVertexDensity.push_back(nan); - m_vertexPrimary.push_back(-1); - m_vertexSecondary.push_back(-1); + m_truthVertexTrackWeights.push_back(nan); + m_truthVertexMatchRatio.push_back(nan); + m_recoVertexContamination.push_back(nan); + + m_recoVertexClassification.push_back( + static_cast(RecoVertexClassification::Unknown)); m_truthX.push_back(nan); m_truthY.push_back(nan); @@ -910,9 +957,11 @@ ProcessCode VertexPerformanceWriter::writeT( m_seedT.clear(); m_vertexPrimary.clear(); m_vertexSecondary.clear(); + m_nTracksOnTruthVertex.clear(); + m_truthPrimaryVertexDensity.clear(); m_truthVertexTrackWeights.clear(); m_truthVertexMatchRatio.clear(); - m_nTracksOnTruthVertex.clear(); + m_recoVertexContamination.clear(); m_recoVertexClassification.clear(); m_truthX.clear(); m_truthY.clear(); diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.hpp b/Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.hpp index 5651506995a..d1071bb7414 100644 --- a/Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.hpp +++ b/Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.hpp @@ -8,6 +8,7 @@ #pragma once +#include "Acts/Definitions/Units.hpp" #include "Acts/EventData/TrackParameters.hpp" #include "Acts/MagneticField/MagneticFieldProvider.hpp" #include "Acts/Utilities/Logger.hpp" @@ -68,6 +69,7 @@ class VertexPerformanceWriter final std::string treeName = "vertextree"; /// File access mode. std::string fileMode = "RECREATE"; + /// Minimum fraction of track weight matched between truth /// and reco vertices to consider as truth matched. double vertexMatchThreshold = 0.7; @@ -76,8 +78,12 @@ class VertexPerformanceWriter final double trackMatchThreshold = 0.5; /// Whether information about tracks is available bool useTracks = true; - /// minimum track weight for track to be considered as part of the fit + /// Minimum track weight for track to be considered as part of the fit double minTrkWeight = 0.1; + /// Spatial window for vertex density calculation. + /// @note This is a Z-window + /// @note This is a half-window around the reconstructed vertex + double vertexDensityWindow = 1 * Acts::UnitConstants::mm; }; /// Constructor @@ -126,6 +132,7 @@ class VertexPerformanceWriter final /// Number of tracks associated with the reconstructed vertex std::vector m_nTracksOnRecoVertex; + /// Sum of the track weights associated with the reconstructed vertex std::vector m_recoVertexTrackWeights; // Sum pT^2 of all tracks associated with the vertex @@ -160,12 +167,19 @@ class VertexPerformanceWriter final std::vector m_vertexPrimary; std::vector m_vertexSecondary; - std::vector m_truthVertexTrackWeights; - std::vector m_truthVertexMatchRatio; - /// Number of tracks associated with the truth vertex std::vector m_nTracksOnTruthVertex; + /// Truth-based primary vertex density for the reconstructed vertex + std::vector m_truthPrimaryVertexDensity; + + /// Sum of the track weights associated with the truth vertex + std::vector m_truthVertexTrackWeights; + /// Fraction of track weight matched between truth and reco vertices + std::vector m_truthVertexMatchRatio; + /// Fraction of incorrectly assigned track weight to the reco vertex + std::vector m_recoVertexContamination; + /// Classification of the reconstructed vertex see RecoVertexClassification std::vector m_recoVertexClassification; diff --git a/Examples/Io/Root/CMakeLists.txt b/Examples/Io/Root/CMakeLists.txt index 926fbab9be7..1f3628f0a94 100644 --- a/Examples/Io/Root/CMakeLists.txt +++ b/Examples/Io/Root/CMakeLists.txt @@ -9,6 +9,7 @@ add_library( src/RootParticleWriter.cpp src/RootParticleReader.cpp src/RootPropagationStepsWriter.cpp + src/RootSeedWriter.cpp src/RootSimHitWriter.cpp src/RootSimHitReader.cpp src/RootSpacepointWriter.cpp diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/RootParticleWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/RootParticleWriter.hpp index 4d8eff9da31..ab73ac3e0b3 100644 --- a/Examples/Io/Root/include/ActsExamples/Io/Root/RootParticleWriter.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/RootParticleWriter.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2017-2023 CERN for the benefit of the Acts project +// Copyright (C) 2017-2024 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 @@ -9,7 +9,6 @@ #pragma once #include "Acts/Utilities/Logger.hpp" -#include "ActsExamples/EventData/SimHit.hpp" #include "ActsExamples/EventData/SimParticle.hpp" #include "ActsExamples/Framework/ProcessCode.hpp" #include "ActsExamples/Framework/WriterT.hpp" @@ -129,6 +128,8 @@ class RootParticleWriter final : public WriterT { std::vector m_pathInL0; /// Number of hits. std::vector m_numberOfHits; + /// Particle outcome + std::vector m_outcome; }; } // namespace ActsExamples diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/RootSeedWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/RootSeedWriter.hpp new file mode 100644 index 00000000000..857bfc5a8c6 --- /dev/null +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/RootSeedWriter.hpp @@ -0,0 +1,109 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2022 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 http://mozilla.org/MPL/2.0/. + +#pragma once + +#include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/EventData/SimSeed.hpp" +#include "ActsExamples/Framework/WriterT.hpp" + +#include +#include +#include + +class TFile; +class TTree; + +namespace ActsExamples { +struct AlgorithmContext; + +/// Write out seeds as a flat TTree. +/// +/// Each entry in the TTree corresponds to one seed for optimum writing +/// speed. The event number is part of the written data. +/// +/// Safe to use from multiple writer threads. To avoid thread-saftey issues, +/// the writer must be the sole owner of the underlying file. Thus, the +/// output file pointer can not be given from the outside. +class RootSeedWriter final : public WriterT { + public: + struct Config { + /// Input particle collection to write. + std::string inputSeeds; + /// Path to the output file. + std::string filePath; + /// Output file access mode. + std::string fileMode = "RECREATE"; + /// Name of the tree within the output file. + std::string treeName = "seeds"; + /// The writing mode + std::string writingMode = "small"; + }; + + /// Construct the seed writer. + /// + /// @param config is the configuration object + /// @param level is the logging level + RootSeedWriter(const Config& config, Acts::Logging::Level level); + + /// Ensure underlying file is closed. + ~RootSeedWriter() final; + + /// End-of-run hook + ProcessCode finalize() final; + + /// Get readonly access to the config parameters + const Config& config() const { return m_cfg; } + + protected: + /// Type-specific write implementation. + /// + /// @param[in] ctx is the algorithm context + /// @param[in] seeds are the seeds to be written + ProcessCode writeT(const AlgorithmContext& ctx, + const SimSeedContainer& seeds) final; + + private: + Config m_cfg; + std::mutex m_writeMutex; + TFile* m_outputFile = nullptr; + TTree* m_outputTree = nullptr; + /// Event identifier. + uint32_t m_eventId = 0; + /// Hit surface identifier. + uint64_t m_measurementId_1 = 0; + uint64_t m_measurementId_2 = 0; + uint64_t m_measurementId_3 = 0; + /// Space point surface identifier. + uint64_t m_geometryId_1 = 0; + uint64_t m_geometryId_2 = 0; + uint64_t m_geometryId_3 = 0; + /// Global space point position components in mm. init to NaN + float m_x_1 = std::numeric_limits::signaling_NaN(); + float m_x_2 = std::numeric_limits::signaling_NaN(); + float m_x_3 = std::numeric_limits::signaling_NaN(); + float m_y_1 = std::numeric_limits::signaling_NaN(); + float m_y_2 = std::numeric_limits::signaling_NaN(); + float m_y_3 = std::numeric_limits::signaling_NaN(); + float m_z_1 = std::numeric_limits::signaling_NaN(); + float m_z_2 = std::numeric_limits::signaling_NaN(); + float m_z_3 = std::numeric_limits::signaling_NaN(); + // Global space point position uncertainties + float m_var_r_1 = std::numeric_limits::signaling_NaN(); + float m_var_r_2 = std::numeric_limits::signaling_NaN(); + float m_var_r_3 = std::numeric_limits::signaling_NaN(); + float m_var_z_1 = std::numeric_limits::signaling_NaN(); + float m_var_z_2 = std::numeric_limits::signaling_NaN(); + float m_var_z_3 = std::numeric_limits::signaling_NaN(); + // Seed vertex position + double m_z_vertex = std::numeric_limits::signaling_NaN(); + // Seed quality + float m_seed_quality = std::numeric_limits::signaling_NaN(); +}; + +} // namespace ActsExamples diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/RootSpacepointWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/RootSpacepointWriter.hpp index b8ee11fa25f..64db4a9ab6c 100644 --- a/Examples/Io/Root/include/ActsExamples/Io/Root/RootSpacepointWriter.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/RootSpacepointWriter.hpp @@ -64,7 +64,7 @@ class RootSpacepointWriter final : public WriterT { /// Type-specific write implementation. /// /// @param[in] ctx is the algorithm context - /// @param[in] hits are the hits to be written + /// @param[in] spacepoints are the spacepoints to be written ProcessCode writeT(const AlgorithmContext& ctx, const SimSpacePointContainer& spacepoints) final; diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/RootVertexReader.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/RootVertexReader.hpp index 0c94cc88222..7523f91e436 100644 --- a/Examples/Io/Root/include/ActsExamples/Io/Root/RootVertexReader.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/RootVertexReader.hpp @@ -41,8 +41,6 @@ class RootVertexReader : public IReader { std::string treeName = "vertices"; /// The name of the input file std::string filePath; - /// Whether the events are ordered or not - bool orderedEvents = true; }; /// Constructor @@ -99,12 +97,13 @@ class RootVertexReader : public IReader { std::vector* m_vy = new std::vector; std::vector* m_vz = new std::vector; std::vector* m_vt = new std::vector; + std::vector>* m_outgoingParticles = + new std::vector>; + // Decoded vertex identifier; see Barcode definition for details. std::vector* m_vertexPrimary = new std::vector; std::vector* m_vertexSecondary = new std::vector; std::vector* m_generation = new std::vector; - std::vector>* m_outgoingParticles = - new std::vector>; }; } // namespace ActsExamples diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/RootVertexWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/RootVertexWriter.hpp index 3820e829481..5766b7b865e 100644 --- a/Examples/Io/Root/include/ActsExamples/Io/Root/RootVertexWriter.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/RootVertexWriter.hpp @@ -88,7 +88,7 @@ class RootVertexWriter final : public WriterT { std::vector m_vz; std::vector m_vt; /// Outgoing particles from the vertex. - std::vector> m_outgoingParticles; + std::vector> m_outgoingParticles; // Decoded vertex identifier; see Barcode definition for details. std::vector m_vertexPrimary; std::vector m_vertexSecondary; diff --git a/Examples/Io/Root/src/RootParticleWriter.cpp b/Examples/Io/Root/src/RootParticleWriter.cpp index 15c6fa4690a..311cccab91a 100644 --- a/Examples/Io/Root/src/RootParticleWriter.cpp +++ b/Examples/Io/Root/src/RootParticleWriter.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2023 CERN for the benefit of the Acts project +// Copyright (C) 2023-2024 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 @@ -15,13 +15,11 @@ #include "ActsFatras/EventData/Barcode.hpp" #include "ActsFatras/EventData/Particle.hpp" -#include #include #include #include #include #include -#include #include #include @@ -80,6 +78,7 @@ ActsExamples::RootParticleWriter::RootParticleWriter( m_outputTree->Branch("total_x0", &m_pathInX0); m_outputTree->Branch("total_l0", &m_pathInL0); m_outputTree->Branch("number_of_hits", &m_numberOfHits); + m_outputTree->Branch("outcome", &m_outcome); } } @@ -172,6 +171,10 @@ ActsExamples::ProcessCode ActsExamples::RootParticleWriter::writeT( Acts::UnitConstants::mm)); // get the number of hits m_numberOfHits.push_back(finalParticle.numberOfHits()); + // get the particle outcome + m_outcome.push_back( + static_cast(finalParticle.outcome())); + wroteFinalParticle = true; } } @@ -180,6 +183,7 @@ ActsExamples::ProcessCode ActsExamples::RootParticleWriter::writeT( m_pathInX0.push_back(nan); m_pathInL0.push_back(nan); m_numberOfHits.push_back(-1); + m_outcome.push_back(0); } } @@ -208,6 +212,7 @@ ActsExamples::ProcessCode ActsExamples::RootParticleWriter::writeT( m_subParticle.clear(); m_eLoss.clear(); m_numberOfHits.clear(); + m_outcome.clear(); m_pathInX0.clear(); m_pathInL0.clear(); diff --git a/Examples/Io/Root/src/RootSeedWriter.cpp b/Examples/Io/Root/src/RootSeedWriter.cpp new file mode 100644 index 00000000000..4219e9539ce --- /dev/null +++ b/Examples/Io/Root/src/RootSeedWriter.cpp @@ -0,0 +1,149 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2022 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 http://mozilla.org/MPL/2.0/. + +#include "ActsExamples/Io/Root/RootSeedWriter.hpp" + +#include "Acts/Definitions/Units.hpp" +#include "Acts/EventData/SourceLink.hpp" +#include "Acts/Geometry/GeometryIdentifier.hpp" +#include "ActsExamples/EventData/IndexSourceLink.hpp" +#include "ActsExamples/Framework/AlgorithmContext.hpp" + +#include +#include + +#include +#include + +ActsExamples::RootSeedWriter::RootSeedWriter( + const ActsExamples::RootSeedWriter::Config& config, + Acts::Logging::Level level) + : WriterT(config.inputSeeds, "RootSeedWriter", level), m_cfg(config) { + // inputParticles is already checked by base constructor + if (m_cfg.filePath.empty()) { + throw std::invalid_argument("Missing file path"); + } + if (m_cfg.treeName.empty()) { + throw std::invalid_argument("Missing tree name"); + } + + // open root file and create the tree + m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str()); + if (m_outputFile == nullptr) { + throw std::ios_base::failure("Could not open '" + m_cfg.filePath + "'"); + } + m_outputFile->cd(); + m_outputTree = new TTree(m_cfg.treeName.c_str(), m_cfg.treeName.c_str()); + if (m_outputTree == nullptr) { + throw std::bad_alloc(); + } + + // setup the branches + m_outputTree->Branch("event_id", &m_eventId); + m_outputTree->Branch("measurement_id_1", &m_measurementId_1, + "measurement_id_1/l"); + m_outputTree->Branch("measurement_id_2", &m_measurementId_2, + "measurement_id_2/l"); + m_outputTree->Branch("measurement_id_3", &m_measurementId_3, + "measurement_id_3/l"); + if (m_cfg.writingMode != "small") { + m_outputTree->Branch("geometry_id_1", &m_geometryId_1, "geometry_id_1/l"); + m_outputTree->Branch("geometry_id_2", &m_geometryId_2, "geometry_id_2/l"); + m_outputTree->Branch("geometry_id_3", &m_geometryId_3, "geometry_id_3/l"); + m_outputTree->Branch("x_1", &m_x_1); + m_outputTree->Branch("x_2", &m_x_2); + m_outputTree->Branch("x_3", &m_x_3); + m_outputTree->Branch("y_1", &m_y_1); + m_outputTree->Branch("y_2", &m_y_2); + m_outputTree->Branch("y_3", &m_y_3); + m_outputTree->Branch("z_1", &m_z_1); + m_outputTree->Branch("z_2", &m_z_2); + m_outputTree->Branch("z_3", &m_z_3); + m_outputTree->Branch("var_r_1", &m_var_r_1); + m_outputTree->Branch("var_r_2", &m_var_r_2); + m_outputTree->Branch("var_r_3", &m_var_r_3); + m_outputTree->Branch("var_z_1", &m_var_z_1); + m_outputTree->Branch("var_z_2", &m_var_z_2); + m_outputTree->Branch("var_z_3", &m_var_z_3); + m_outputTree->Branch("z_vertex", &m_z_vertex); + m_outputTree->Branch("seed_quality", &m_seed_quality); + } +} + +ActsExamples::RootSeedWriter::~RootSeedWriter() { + if (m_outputFile != nullptr) { + m_outputFile->Close(); + } +} + +ActsExamples::ProcessCode ActsExamples::RootSeedWriter::finalize() { + m_outputFile->cd(); + m_outputTree->Write(); + m_outputFile->Close(); + + ACTS_VERBOSE("Wrote seeds to tree '" << m_cfg.treeName << "' in '" + << m_cfg.filePath << "'"); + return ProcessCode::SUCCESS; +} + +ActsExamples::ProcessCode ActsExamples::RootSeedWriter::writeT( + const AlgorithmContext& ctx, const ActsExamples::SimSeedContainer& seeds) { + // ensure exclusive access to tree/file while writing + std::lock_guard lock(m_writeMutex); + + // Get the event number + m_eventId = ctx.eventNumber; + for (const auto& seed : seeds) { + const auto& spacepoints = seed.sp(); + + const auto slink_1 = + spacepoints[0]->sourceLinks()[0].get(); + const auto slink_2 = + spacepoints[1]->sourceLinks()[0].get(); + const auto slink_3 = + spacepoints[2]->sourceLinks()[0].get(); + + m_measurementId_1 = slink_1.index(); + if (m_cfg.writingMode != "small") { + m_geometryId_1 = slink_1.geometryId().value(); + m_x_1 = spacepoints[0]->x(); + m_y_1 = spacepoints[0]->y(); + m_z_1 = spacepoints[0]->z(); + m_var_r_1 = spacepoints[0]->varianceR(); + m_var_z_1 = spacepoints[0]->varianceZ(); + } + + m_measurementId_2 = slink_2.index(); + if (m_cfg.writingMode != "small") { + m_geometryId_2 = slink_2.geometryId().value(); + m_x_2 = spacepoints[1]->x(); + m_y_2 = spacepoints[1]->y(); + m_z_2 = spacepoints[1]->z(); + m_var_r_2 = spacepoints[1]->varianceR(); + m_var_z_2 = spacepoints[1]->varianceZ(); + } + + m_measurementId_3 = slink_3.index(); + if (m_cfg.writingMode != "small") { + m_geometryId_3 = slink_3.geometryId().value(); + m_x_3 = spacepoints[2]->x(); + m_y_3 = spacepoints[2]->y(); + m_z_3 = spacepoints[2]->z(); + m_var_r_3 = spacepoints[2]->varianceR(); + m_var_z_3 = spacepoints[2]->varianceZ(); + } + + if (m_cfg.writingMode != "small") { + m_z_vertex = seed.z(); + m_seed_quality = seed.seedQuality(); + } + // Fill the tree + m_outputTree->Fill(); + } + return ActsExamples::ProcessCode::SUCCESS; +} diff --git a/Examples/Io/Root/src/RootVertexReader.cpp b/Examples/Io/Root/src/RootVertexReader.cpp index 52bbfac698c..f9619c68a07 100644 --- a/Examples/Io/Root/src/RootVertexReader.cpp +++ b/Examples/Io/Root/src/RootVertexReader.cpp @@ -62,8 +62,8 @@ RootVertexReader::RootVertexReader(const RootVertexReader::Config& config, m_events = m_inputChain->GetEntries(); ACTS_DEBUG("The full chain has " << m_events << " entries."); - // If the events are not in order, get the entry numbers for ordered events - if (!m_cfg.orderedEvents) { + // Sort the entry numbers of the events + { m_entryNumbers.resize(m_events); m_inputChain->Draw("event_id", "", "goff"); // Sort to get the entry numbers of the ordered events @@ -104,13 +104,10 @@ ProcessCode RootVertexReader::read(const AlgorithmContext& context) { SimVertexContainer vertices; // Read the correct entry - auto entry = context.eventNumber; - if (!m_cfg.orderedEvents && entry < m_entryNumbers.size()) { - entry = m_entryNumbers[entry]; - } + auto entry = m_entryNumbers.at(context.eventNumber); m_inputChain->GetEntry(entry); - ACTS_INFO("Reading event: " << context.eventNumber - << " stored as entry: " << entry); + ACTS_DEBUG("Reading event: " << context.eventNumber + << " stored as entry: " << entry); unsigned int nVertices = m_vertexId->size(); @@ -133,6 +130,9 @@ ProcessCode RootVertexReader::read(const AlgorithmContext& context) { vertices.insert(v); } + ACTS_DEBUG("Read " << vertices.size() << " vertices for event " + << context.eventNumber); + // Write the collections to the EventStore m_outputVertices(context, std::move(vertices)); diff --git a/Examples/Io/Root/src/RootVertexWriter.cpp b/Examples/Io/Root/src/RootVertexWriter.cpp index 2764cf2e064..b6ee892d2e0 100644 --- a/Examples/Io/Root/src/RootVertexWriter.cpp +++ b/Examples/Io/Root/src/RootVertexWriter.cpp @@ -101,9 +101,9 @@ ProcessCode RootVertexWriter::writeT(const AlgorithmContext& ctx, Acts::UnitConstants::mm)); // TODO ingoing particles // outgoing particles - std::vector outgoing; + std::vector outgoing; for (const auto& particle : vertex.outgoing) { - outgoing.push_back(static_cast(particle.value())); + outgoing.push_back(particle.value()); } m_outgoingParticles.push_back(std::move(outgoing)); // decoded barcode components diff --git a/Examples/Python/python/acts/examples/__init__.py b/Examples/Python/python/acts/examples/__init__.py index 648b4ed7cb6..7f1f1e830e9 100644 --- a/Examples/Python/python/acts/examples/__init__.py +++ b/Examples/Python/python/acts/examples/__init__.py @@ -402,7 +402,6 @@ def __init__(self, *args, **kwargs): cfg = self.Config() if len(args) == 1 and isinstance(args[0], self.Config): cfg = args[0] - args = args[1:] if "config" in kwargs: cfg = kwargs.pop("config") diff --git a/Examples/Python/python/acts/examples/detector.py b/Examples/Python/python/acts/examples/detector.py index 03fd983fe32..d52c6795d5d 100644 --- a/Examples/Python/python/acts/examples/detector.py +++ b/Examples/Python/python/acts/examples/detector.py @@ -44,8 +44,8 @@ def __init__( :param name: name of the volume :param extent: extent of the volume :param provider: surface provider for the volume - :param binning: binning of surfces in this volume - :param support: support surface description + :param binnings: binning of surfces in this volume + :param supports: support surface description :param loglevel: logging level """ self._name = name diff --git a/Examples/Python/python/acts/examples/itk.py b/Examples/Python/python/acts/examples/itk.py index 04677fec99c..3e49033b526 100644 --- a/Examples/Python/python/acts/examples/itk.py +++ b/Examples/Python/python/acts/examples/itk.py @@ -379,7 +379,6 @@ def itkSeedingAlgConfig( # variables that change for pixel and strip SPs: if inputSpacePointsType is InputSpacePointsType.PixelSpacePoints: - outputSeeds = "PixelSeeds" allowSeparateRMax = False rMaxGridConfig = 320 * u.mm rMaxSeedFinderConfig = rMaxGridConfig @@ -431,12 +430,10 @@ def itkSeedingAlgConfig( ] deltaRMiddleMinSPRange = 10 * u.mm deltaRMiddleMaxSPRange = 10 * u.mm - seedConfirmationFilter = True impactWeightFactor = 100 compatSeedLimit = 3 numSeedIncrement = 100 seedWeightIncrement = 0 - useDetailedDoubleMeasurementInfo = False maxSeedsPerSpMConf = 5 maxQualitySeedsPerSpMConf = 5 useDeltaRorTopRadius = True @@ -447,7 +444,6 @@ def itkSeedingAlgConfig( zBinsCustomLooping = [2, 10, 3, 9, 6, 4, 8, 5, 7] elif inputSpacePointsType is InputSpacePointsType.StripSpacePoints: - outputSeeds = "StripSeeds" allowSeparateRMax = True rMaxGridConfig = 1000.0 * u.mm rMaxSeedFinderConfig = 1200.0 * u.mm @@ -487,12 +483,10 @@ def itkSeedingAlgConfig( ] deltaRMiddleMinSPRange = 30 * u.mm deltaRMiddleMaxSPRange = 150 * u.mm - seedConfirmationFilter = False impactWeightFactor = 1 compatSeedLimit = 4 numSeedIncrement = 1 seedWeightIncrement = 10100 - useDetailedDoubleMeasurementInfo = True maxSeedsPerSpMConf = 100 maxQualitySeedsPerSpMConf = 100 useDeltaRorTopRadius = False diff --git a/Examples/Python/python/acts/examples/odd_light.py b/Examples/Python/python/acts/examples/odd_light.py index f20168aa875..c12118ba970 100644 --- a/Examples/Python/python/acts/examples/odd_light.py +++ b/Examples/Python/python/acts/examples/odd_light.py @@ -1,4 +1,3 @@ -import math import acts import argparse import acts.examples @@ -356,10 +355,10 @@ def main(): geoContext = GeometryContext() # Convert the detector surfaces to GDML - [elements, ssurfaces, psurfaces] = acts_g4.convertSurfaces( + [_, ssurfaces, psurfaces] = acts_g4.convertSurfaces( args.input, [args.sensitives], [args.passives] ) - odd_light = get_detector(geoContext, ssurfaces, psurfaces, acts.logging.DEBUG) + get_detector(geoContext, ssurfaces, psurfaces, acts.logging.DEBUG) if "__main__" == __name__: diff --git a/Examples/Python/python/acts/examples/reconstruction.py b/Examples/Python/python/acts/examples/reconstruction.py index 37f49d5b078..c5b81be60d8 100644 --- a/Examples/Python/python/acts/examples/reconstruction.py +++ b/Examples/Python/python/acts/examples/reconstruction.py @@ -2,7 +2,6 @@ from typing import Optional, Union, List from enum import Enum from collections import namedtuple -import warnings import acts import acts.examples @@ -135,8 +134,14 @@ CkfConfig = namedtuple( "CkfConfig", - ["chi2CutOff", "numMeasurementsCutOff", "maxSteps", "seedDeduplication"], - defaults=[15.0, 10, None, None], + [ + "chi2CutOff", + "numMeasurementsCutOff", + "maxSteps", + "seedDeduplication", + "stayOnSeed", + ], + defaults=[15.0, 10, None, None, None], ) AmbiguityResolutionConfig = namedtuple( @@ -1260,7 +1265,9 @@ def addCKFTracks( inputMeasurements="measurements", inputSourceLinks="sourcelinks", inputInitialTrackParameters="estimatedparameters", - inputSeeds="estimatedseeds" if ckfConfig.seedDeduplication else "", + inputSeeds="estimatedseeds" + if ckfConfig.seedDeduplication or ckfConfig.stayOnSeed + else "", outputTracks="ckf_tracks", findTracks=acts.examples.TrackFindingAlgorithm.makeTrackFinderFunction( trackingGeometry, field, customLogLevel() @@ -1272,6 +1279,7 @@ def addCKFTracks( maxSteps=ckfConfig.maxSteps, twoWay=twoWay, seedDeduplication=ckfConfig.seedDeduplication, + stayOnSeed=ckfConfig.stayOnSeed, ), ) s.addAlgorithm(trackFinder) diff --git a/Examples/Python/python/acts/examples/simulation.py b/Examples/Python/python/acts/examples/simulation.py index f0ee2c8f62f..832f42aec74 100644 --- a/Examples/Python/python/acts/examples/simulation.py +++ b/Examples/Python/python/acts/examples/simulation.py @@ -365,7 +365,7 @@ def addParticleSelection( ---------- s: Sequencer the sequencer module to which we add the ParticleSelector - preselectedParticles: ParticleSelectorConfig + config: ParticleSelectorConfig the particle selection configuration inputParticles: str the identifier for the input particles to be selected @@ -586,13 +586,14 @@ def addSimWriters( def getG4DetectorConstructionFactory( detector: Any, + regionList: List[Any] = [], ) -> Any: try: from acts.examples import TelescopeDetector from acts.examples.geant4 import TelescopeG4DetectorConstructionFactory if type(detector) is TelescopeDetector: - return TelescopeG4DetectorConstructionFactory(detector) + return TelescopeG4DetectorConstructionFactory(detector, regionList) except Exception as e: print(e) @@ -601,7 +602,7 @@ def getG4DetectorConstructionFactory( from acts.examples.geant4.dd4hep import DDG4DetectorConstructionFactory if type(detector) is DD4hepDetector: - return DDG4DetectorConstructionFactory(detector) + return DDG4DetectorConstructionFactory(detector, regionList) except Exception as e: print(e) @@ -636,6 +637,7 @@ def addGeant4( killAfterTime: float = float("inf"), killSecondaries: bool = False, physicsList: str = "FTFP_BERT", + regionList: List[Any] = [], ) -> None: """This function steers the detector simulation using Geant4 @@ -684,7 +686,9 @@ def addGeant4( if g4DetectorConstructionFactory is None: if detector is None: raise AttributeError("detector not given") - g4DetectorConstructionFactory = getG4DetectorConstructionFactory(detector) + g4DetectorConstructionFactory = getG4DetectorConstructionFactory( + detector, regionList + ) global __geant4Handle diff --git a/Examples/Python/src/Geant4Component.cpp b/Examples/Python/src/Geant4Component.cpp index 11ef468c038..1c37c533f8c 100644 --- a/Examples/Python/src/Geant4Component.cpp +++ b/Examples/Python/src/Geant4Component.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2021 CERN for the benefit of the Acts project +// Copyright (C) 2021-2024 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 @@ -21,6 +21,7 @@ #include "ActsExamples/Geant4/GdmlDetectorConstruction.hpp" #include "ActsExamples/Geant4/Geant4Manager.hpp" #include "ActsExamples/Geant4/Geant4Simulation.hpp" +#include "ActsExamples/Geant4/RegionCreator.hpp" #include "ActsExamples/Geant4Detector/Geant4Detector.hpp" #include "ActsExamples/MuonSpectrometerMockupDetector/MockupSectorBuilder.hpp" #include "ActsExamples/TelescopeDetector/TelescopeDetector.hpp" @@ -149,7 +150,11 @@ PYBIND11_MODULE(ActsPythonBindingsGeant4, mod) { py::class_>( mod, "GdmlDetectorConstructionFactory") - .def(py::init()); + .def(py::init>>(), + py::arg("path"), + py::arg("regionCreators") = + std::vector>()); } { @@ -158,7 +163,11 @@ PYBIND11_MODULE(ActsPythonBindingsGeant4, mod) { DetectorConstructionFactory, std::shared_ptr>( mod, "TelescopeG4DetectorConstructionFactory") - .def(py::init()); + .def(py::init>>(), + py::arg("cfg"), + py::arg("regionCreators") = + std::vector>()); } { @@ -223,7 +232,7 @@ PYBIND11_MODULE(ActsPythonBindingsGeant4, mod) { } { - /// Helper function to test if the autmotaic geometry conversion works + /// Helper function to test if the automatic geometry conversion works /// /// @param gdmlFileName is the name of the GDML file /// @param sensitiveMatches is a list of strings to match sensitive volumes @@ -310,6 +319,25 @@ PYBIND11_MODULE(ActsPythonBindingsGeant4, mod) { ACTS_PYTHON_STRUCT_END(); } + { + using Tool = RegionCreator; + using Config = Tool::Config; + auto tool = py::class_>(mod, "RegionCreator") + .def(py::init(), + py::arg("config"), py::arg("name"), + py::arg("logLevel") = Logging::INFO) + .def_property_readonly("config", &Tool::config); + + auto c = py::class_(tool, "Config").def(py::init<>()); + ACTS_PYTHON_STRUCT_BEGIN(c, Config); + ACTS_PYTHON_MEMBER(gammaCut); + ACTS_PYTHON_MEMBER(electronCut); + ACTS_PYTHON_MEMBER(positronCut); + ACTS_PYTHON_MEMBER(protonCut); + ACTS_PYTHON_MEMBER(volumes); + ACTS_PYTHON_STRUCT_END(); + } + Acts::Python::Context ctx; ctx.modules["geant4"] = mod; diff --git a/Examples/Python/src/Geant4DD4hepComponent.cpp b/Examples/Python/src/Geant4DD4hepComponent.cpp index 69213669c25..a6684e7eab8 100644 --- a/Examples/Python/src/Geant4DD4hepComponent.cpp +++ b/Examples/Python/src/Geant4DD4hepComponent.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2021 CERN for the benefit of the Acts project +// Copyright (C) 2021-2024 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 @@ -10,6 +10,7 @@ #include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" #include "ActsExamples/DDG4/DDG4DetectorConstruction.hpp" #include "ActsExamples/Framework/ProcessCode.hpp" +#include "ActsExamples/Geant4/RegionCreator.hpp" #include #include @@ -28,5 +29,9 @@ PYBIND11_MODULE(ActsPythonBindingsDDG4, m) { py::class_>( m, "DDG4DetectorConstructionFactory") - .def(py::init>()); + .def(py::init, + std::vector>>(), + py::arg("detector"), + py::arg("regionCreators") = + std::vector>()); } diff --git a/Examples/Python/src/Geometry.cpp b/Examples/Python/src/Geometry.cpp index a50ff68efc6..57d128447d1 100644 --- a/Examples/Python/src/Geometry.cpp +++ b/Examples/Python/src/Geometry.cpp @@ -59,6 +59,21 @@ struct GeometryIdentifierHookBinding : public Acts::GeometryIdentifierHook { .cast(); } }; + +struct MaterialSurfaceSelector { + std::vector surfaces = {}; + + /// @param surface is the test surface + void operator()(const Acts::Surface* surface) { + if (surface->surfaceMaterial() != nullptr) { + if (std::find(surfaces.begin(), surfaces.end(), surface) == + surfaces.end()) { + surfaces.push_back(surface); + } + } + } +}; + } // namespace namespace Acts::Python { @@ -126,6 +141,12 @@ void addGeometry(Context& ctx) { [](Acts::TrackingGeometry& self, py::function& func) { self.visitSurfaces(func); }) + .def("extractMaterialSurfaces", + [](Acts::TrackingGeometry& self) { + MaterialSurfaceSelector selector; + self.visitSurfaces(selector, false); + return selector.surfaces; + }) .def_property_readonly( "worldVolume", &Acts::TrackingGeometry::highestTrackingVolumeShared); @@ -190,8 +211,13 @@ void addExperimentalGeometry(Context& ctx) { // Detector definition py::class_>(m, "Detector") - .def("number_volumes", - [](Detector& self) { return self.volumes().size(); }); + .def("numberVolumes", + [](Detector& self) { return self.volumes().size(); }) + .def("extractMaterialSurfaces", [](Detector& self) { + MaterialSurfaceSelector selector; + self.visitSurfaces(selector); + return selector.surfaces; + }); // Portal definition py::class_>(m, "Portal"); diff --git a/Examples/Python/src/Input.cpp b/Examples/Python/src/Input.cpp index 850b989574d..8d54c4f2588 100644 --- a/Examples/Python/src/Input.cpp +++ b/Examples/Python/src/Input.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2021-2024 CERN for the benefit of the Acts project +// Copyright (C) 2021 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 @@ -45,7 +45,7 @@ void addInput(Context& ctx) { ACTS_PYTHON_DECLARE_READER(ActsExamples::RootVertexReader, mex, "RootVertexReader", outputVertices, treeName, - filePath, orderedEvents); + filePath); ACTS_PYTHON_DECLARE_READER(ActsExamples::RootMaterialTrackReader, mex, "RootMaterialTrackReader", outputMaterialTracks, diff --git a/Examples/Python/src/Material.cpp b/Examples/Python/src/Material.cpp index cdabe0ff2c0..2aad1af3478 100644 --- a/Examples/Python/src/Material.cpp +++ b/Examples/Python/src/Material.cpp @@ -8,13 +8,18 @@ #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/MagneticField/MagneticFieldContext.hpp" +#include "Acts/Material/BinnedSurfaceMaterialAccumulater.hpp" #include "Acts/Material/IMaterialDecorator.hpp" +#include "Acts/Material/IntersectionMaterialAssigner.hpp" +#include "Acts/Material/MaterialMapper.hpp" +#include "Acts/Material/PropagatorMaterialAssigner.hpp" #include "Acts/Material/SurfaceMaterialMapper.hpp" #include "Acts/Material/VolumeMaterialMapper.hpp" #include "Acts/Plugins/Python/Utilities.hpp" #include "Acts/Utilities/Logger.hpp" #include "ActsExamples/Framework/ProcessCode.hpp" #include "ActsExamples/Io/Root/RootMaterialDecorator.hpp" +#include "ActsExamples/MaterialMapping/CoreMaterialMapping.hpp" #include "ActsExamples/MaterialMapping/MappingMaterialDecorator.hpp" #include "ActsExamples/MaterialMapping/MaterialMapping.hpp" @@ -164,5 +169,110 @@ void addMaterial(Context& ctx) { ACTS_PYTHON_MEMBER(mappingStep); ACTS_PYTHON_STRUCT_END(); } + + { + py::class_>(m, + "IAssignmentFinder"); + } + + { + auto isma = + py::class_>( + m, "IntersectionMaterialAssigner") + .def(py::init([](const Acts::IntersectionMaterialAssigner::Config& + config, + Acts::Logging::Level level) { + return std::make_shared( + config, + getDefaultLogger("IntersectionMaterialAssigner", level)); + }), + py::arg("config"), py::arg("level")) + .def("assignmentCandidates", + &Acts::IntersectionMaterialAssigner::assignmentCandidates); + + auto c = + py::class_(isma, "Config") + .def(py::init<>()); + ACTS_PYTHON_STRUCT_BEGIN(c, Acts::IntersectionMaterialAssigner::Config); + ACTS_PYTHON_MEMBER(surfaces); + ACTS_PYTHON_MEMBER(trackingVolumes); + ACTS_PYTHON_MEMBER(detectorVolumes); + ACTS_PYTHON_STRUCT_END(); + } + + { + py::class_>( + m, "ISurfaceMaterialAccumulater"); + } + + { + auto bsma = + py::class_>( + m, "BinnedSurfaceMaterialAccumulater") + .def( + py::init( + [](const BinnedSurfaceMaterialAccumulater::Config& config, + Acts::Logging::Level level) { + return std::make_shared( + config, + getDefaultLogger("BinnedSurfaceMaterialAccumulater", + level)); + }), + py::arg("config"), py::arg("level")) + .def("createState", &BinnedSurfaceMaterialAccumulater::createState) + .def("accumulate", &BinnedSurfaceMaterialAccumulater::accumulate) + .def("finalizeMaterial", + &BinnedSurfaceMaterialAccumulater::finalizeMaterial); + + auto c = + py::class_(bsma, "Config") + .def(py::init<>()); + ACTS_PYTHON_STRUCT_BEGIN(c, BinnedSurfaceMaterialAccumulater::Config); + ACTS_PYTHON_MEMBER(emptyBinCorrection); + ACTS_PYTHON_MEMBER(materialSurfaces); + ACTS_PYTHON_STRUCT_END(); + } + + { + auto mm = py::class_>( + m, "MaterialMapper") + .def(py::init([](const MaterialMapper::Config& config, + Acts::Logging::Level level) { + return std::make_shared( + config, getDefaultLogger("MaterialMapper", level)); + }), + py::arg("config"), py::arg("level")); + + auto c = py::class_(mm, "Config").def(py::init<>()); + ACTS_PYTHON_STRUCT_BEGIN(c, MaterialMapper::Config); + ACTS_PYTHON_MEMBER(assignmentFinder); + ACTS_PYTHON_MEMBER(surfaceMaterialAccumulater); + ACTS_PYTHON_STRUCT_END(); + } + + { + auto mmca = py::class_>( + mex, "CoreMaterialMapping") + .def(py::init(), + py::arg("config"), py::arg("level")); + + auto c = py::class_(mmca, "Config") + .def(py::init<>()); + ACTS_PYTHON_STRUCT_BEGIN(c, CoreMaterialMapping::Config); + ACTS_PYTHON_MEMBER(inputMaterialTracks); + ACTS_PYTHON_MEMBER(mappedMaterialTracks); + ACTS_PYTHON_MEMBER(unmappedMaterialTracks); + ACTS_PYTHON_MEMBER(materialMapper); + ACTS_PYTHON_MEMBER(materiaMaplWriters); + ACTS_PYTHON_STRUCT_END(); + } } + } // namespace Acts::Python diff --git a/Examples/Python/src/ModuleEntry.cpp b/Examples/Python/src/ModuleEntry.cpp index 3f0619946f3..68aa575ad77 100644 --- a/Examples/Python/src/ModuleEntry.cpp +++ b/Examples/Python/src/ModuleEntry.cpp @@ -91,6 +91,17 @@ PYBIND11_MODULE(ActsPythonBindings, m) { m.attr("__version__") = std::tuple{Acts::VersionMajor, Acts::VersionMinor, Acts::VersionPatch}; + { + auto mv = m.def_submodule("version"); + + mv.attr("major") = Acts::VersionMajor; + mv.attr("minor") = Acts::VersionMinor; + mv.attr("patch") = Acts::VersionPatch; + + mv.attr("commit_hash") = Acts::CommitHash; + mv.attr("commit_hash_short") = Acts::CommitHashShort; + } + addUnits(ctx); addFramework(ctx); addLogging(ctx); diff --git a/Examples/Python/src/OnnxStub.cpp b/Examples/Python/src/OnnxStub.cpp index 3c070e417d6..304ee45475e 100644 --- a/Examples/Python/src/OnnxStub.cpp +++ b/Examples/Python/src/OnnxStub.cpp @@ -11,7 +11,7 @@ struct Context; } // namespace Acts::Python namespace Acts::Python { -void addOnnx(Context& /*unused*/) { +void addOnnx(Context& /*ctx*/) { // dummy function } } // namespace Acts::Python diff --git a/Examples/Python/src/Output.cpp b/Examples/Python/src/Output.cpp index daa4c90cbe4..f37f7ea4da8 100644 --- a/Examples/Python/src/Output.cpp +++ b/Examples/Python/src/Output.cpp @@ -38,6 +38,7 @@ #include "ActsExamples/Io/Root/RootParticleWriter.hpp" #include "ActsExamples/Io/Root/RootPlanarClusterWriter.hpp" #include "ActsExamples/Io/Root/RootPropagationStepsWriter.hpp" +#include "ActsExamples/Io/Root/RootSeedWriter.hpp" #include "ActsExamples/Io/Root/RootSimHitWriter.hpp" #include "ActsExamples/Io/Root/RootSpacepointWriter.hpp" #include "ActsExamples/Io/Root/RootTrackParameterWriter.hpp" @@ -318,6 +319,10 @@ void addOutput(Context& ctx) { inputSimHits, filePath, fileMode, treeName, trackingGeometry); + ACTS_PYTHON_DECLARE_WRITER(ActsExamples::RootSeedWriter, mex, + "RootSeedWriter", inputSeeds, writingMode, + filePath, fileMode, treeName); + ACTS_PYTHON_DECLARE_WRITER(ActsExamples::RootSimHitWriter, mex, "RootSimHitWriter", inputSimHits, filePath, fileMode, treeName); diff --git a/Examples/Python/src/TrackFinding.cpp b/Examples/Python/src/TrackFinding.cpp index 290aeb0e052..c0a894a87f9 100644 --- a/Examples/Python/src/TrackFinding.cpp +++ b/Examples/Python/src/TrackFinding.cpp @@ -292,8 +292,8 @@ void addTrackFinding(Context& ctx) { ActsExamples::TrackParamsEstimationAlgorithm, mex, "TrackParamsEstimationAlgorithm", inputSeeds, inputProtoTracks, outputTrackParameters, outputSeeds, outputProtoTracks, trackingGeometry, - magneticField, bFieldMin, initialSigmas, initialVarInflation, - particleHypothesis); + magneticField, bFieldMin, initialSigmas, initialSimgaQoverPCoefficients, + initialVarInflation, noTimeVarInflation, particleHypothesis); { using Alg = ActsExamples::TrackFindingAlgorithm; @@ -335,6 +335,7 @@ void addTrackFinding(Context& ctx) { ACTS_PYTHON_MEMBER(maxSteps); ACTS_PYTHON_MEMBER(twoWay); ACTS_PYTHON_MEMBER(seedDeduplication); + ACTS_PYTHON_MEMBER(stayOnSeed); ACTS_PYTHON_STRUCT_END(); } diff --git a/Examples/Python/tests/conftest.py b/Examples/Python/tests/conftest.py index 4f7035515d1..90162055f39 100644 --- a/Examples/Python/tests/conftest.py +++ b/Examples/Python/tests/conftest.py @@ -87,7 +87,7 @@ def root_file_exp_hashes(): @pytest.fixture(name="assert_root_hash") -def assert_root_hash(request, root_file_exp_hashes, record_property): +def assert_root_hash(request, root_file_exp_hashes): if not helpers.doHashChecks: def fn(*args, **kwargs): @@ -220,7 +220,7 @@ def _basic_prop_seq_factory(geo, s=None): @pytest.fixture -def trk_geo(request): +def trk_geo(): detector, geo, contextDecorators = acts.examples.GenericDetector.create() yield geo diff --git a/Examples/Python/tests/helpers/hash_root.py b/Examples/Python/tests/helpers/hash_root.py index 39bdcf79d36..0e8d9b428ea 100755 --- a/Examples/Python/tests/helpers/hash_root.py +++ b/Examples/Python/tests/helpers/hash_root.py @@ -1,8 +1,6 @@ #!/usr/bin/env python3 import hashlib from pathlib import Path -import sys -from typing import Optional import argparse import uproot diff --git a/Examples/Python/tests/root_file_hashes.txt b/Examples/Python/tests/root_file_hashes.txt index 5f5b1b6b4f1..ed528c746b0 100644 --- a/Examples/Python/tests/root_file_hashes.txt +++ b/Examples/Python/tests/root_file_hashes.txt @@ -1,20 +1,20 @@ test_pythia8__pythia8_particles.root: 49b89c3458a51aa9407f887be50e6bbcd9a2a0c897e6f2be5a5d6a29d1bf3505 -test_fatras__particles_simulation.root: 1a6c045256bef18a991cea56529e6059927c0d06b5e4732a9eb44047b907ef4e +test_fatras__particles_simulation.root: bc970873fef0c2efd86ed5413623802353d2cd04abea72de14e8cdfc0e40076f test_fatras__hits.root: 821d9f3ce364bfea6c08df86b0204d7257cc1810f5b0bdfda45950e697ef5c52 -test_geant4__particles_simulation.root: 111f8b7c5c132545438bf42f92108507ab99478b7ae6a70f4c2d8c574d2ff2ca +test_geant4__particles_simulation.root: a51f15555abefec7e9d9de31f9d856a3026af1b991db73fefaec5ae160a4af2f test_geant4__hits.root: 794fbae710b8ec68089efb53c5722025bd2cfd961f2f1dc7102c55e65e75dc5f test_seeding__estimatedparams.root: 1fa2e879142059344e32ab62e3763dce14b5138b591c6e919073cb985782075f test_seeding__performance_seeding.root: 992f9c611d30dde0d3f3ab676bab19ada61ab6a4442828e27b65ec5e5b7a2880 test_seeding__particles.root: 7855b021f39ad238bca098e4282667be0666f2d1630e5bcb9d51d3b5ee39fa14 -test_seeding__particles_simulation.root: cc5dbe2f129d96233d622c476d75626f1027e882a200362c9ad1165442c0cda1 +test_seeding__particles_simulation.root: 87d9c6c82422ca381a17735096b36c547eacb5dda2f26d7377614bd97a70ab1a test_seeding_orthogonal__estimatedparams.root: 77bf34e870bce0e44942525214f1101ace6e423a92be1d270f9991ffaf81450a test_seeding_orthogonal__performance_seeding.root: 60fbedcf5cb2b37cd8e526251940564432890d3a159d231ed819e915a904682c test_seeding_orthogonal__particles.root: 7855b021f39ad238bca098e4282667be0666f2d1630e5bcb9d51d3b5ee39fa14 -test_seeding_orthogonal__particles_simulation.root: cc5dbe2f129d96233d622c476d75626f1027e882a200362c9ad1165442c0cda1 +test_seeding_orthogonal__particles_simulation.root: 87d9c6c82422ca381a17735096b36c547eacb5dda2f26d7377614bd97a70ab1a test_itk_seeding__estimatedparams.root: 7e3acb54fcaabae19fe5b8601bd5bd3e5f65d6a1e6d5a2b59c4e8affd27e526c test_itk_seeding__performance_seeding.root: 78ebda54cd0f026ba4b7f316724ffd946de56a932735914baf1b7bba9505c29d test_itk_seeding__particles.root: 0b6f4ad438010ac48803d48ed98e80b5e87d310bae6c2c02b16cd94d7a4d7d07 -test_itk_seeding__particles_simulation.root: c500abdd87a5c5915e6d706b61ed3d9d76d3b04a199841f9770147c7f6f3ee70 +test_itk_seeding__particles_simulation.root: ef0246069aa697019f28a8b270a68de95312cae5f2f2c74848566c3ce4f70363 test_propagation__propagation_steps.root: ba2e20d66f9f58850a9248bfaaafecbf0e8257020bb879b4572b783917f4d19b test_material_recording__geant4_material_tracks.root: 95dc92ab12a4389c3839f03878f366c45a0c4c0035a9f35478980da98ae0f6dd test_truth_tracking_kalman[generic-0.0]__trackstates_fitter.root: 26640d70f7fab870e59666b0915569a6f8f82af68c63e5505548ffa9d24a3212 @@ -31,7 +31,7 @@ test_truth_tracking_kalman[odd-1000.0]__tracksummary_fitter.root: 3d424dec9b172f test_truth_tracking_kalman[odd-1000.0]__performance_track_finder.root: 39aec6316cceb90e314e16b02947faa691c18f57c3a851a25e547a8fc05a4593 test_truth_tracking_gsf[generic]__trackstates_gsf.root: d4160a87b2f0f21cb19b8e3b0d07f97c343c830a535de4d33a186d5179ab5f06 test_truth_tracking_gsf[generic]__tracksummary_gsf.root: c110627dd7015c20b302273b5cba49f64a51e3450a722b064be1605f85a6bd6b -test_truth_tracking_gsf[odd]__trackstates_gsf.root: 3024647ef4b65859d1b5cf4a838dd8f24c4a6986fb1d34969b7033434a3dfb02 +test_truth_tracking_gsf[odd]__trackstates_gsf.root: a3b08c5c0497c85ce2280b4487bbbbb1c4a665d9917c0b1ca040f51524c9d1d4 test_truth_tracking_gsf[odd]__tracksummary_gsf.root: 84310dd790f3f43b5cf9cee0b08c4deed389171f4caaaa00412f62f7e9944e3b test_particle_gun__particles.root: 5fe7dda2933ee6b9615b064d192322fe07831133cd998e5ed99a3b992b713a10 test_material_mapping__material-map_tracks.root: b1138566d8d51579dce07f80166f05986942cf78c76b36875aea9b4b8b9bb957 @@ -44,22 +44,22 @@ test_digitization_example_input[smeared]__particles.root: 5fe7dda2933ee6b9615b06 test_digitization_example_input[smeared]__measurements.root: 95ef20bcdc349da5bc025faf41cb76855ac087ae75df4f4bf953db5b23927aa5 test_digitization_example_input[geometric]__particles.root: 5fe7dda2933ee6b9615b064d192322fe07831133cd998e5ed99a3b992b713a10 test_digitization_example_input[geometric]__measurements.root: fa4729e28fdbbc459400dc3b7cc896c7e0cca047ab889c55c2f148d13b361637 -test_ckf_tracks_example[generic-full_seeding]__trackstates_ckf.root: 6d632ce48408da81e79d494f9cd38d69457046bcb437b6a5df5a166e13e1f3db -test_ckf_tracks_example[generic-full_seeding]__tracksummary_ckf.root: b37e882b3760706c40893cb2df3de9ca2350907ba9122298cf3527c151426c51 +test_ckf_tracks_example[generic-full_seeding]__trackstates_ckf.root: 629e0d51e4a4e518fb6f6dcee0ee319ddca30ee0214ab3aaecd141fee9ba998a +test_ckf_tracks_example[generic-full_seeding]__tracksummary_ckf.root: 1d8c0517646660a82aad72f5ba5e16c70f089d120416342ceccce34fc2e3b425 test_ckf_tracks_example[generic-full_seeding]__performance_seeding_trees.root: 0e0676ffafdb27112fbda50d1cf627859fa745760f98073261dcf6db3f2f991e -test_ckf_tracks_example[generic-truth_estimated]__trackstates_ckf.root: c03ce2da814c3d85fb288693a62c3903a1d932cf6936044a15fbcc61572df3dd -test_ckf_tracks_example[generic-truth_estimated]__tracksummary_ckf.root: 269fbbedc2f7aa163d29bfc0bda18312cef953b89e97a638ebb94799a93411d5 +test_ckf_tracks_example[generic-truth_estimated]__trackstates_ckf.root: 9cf12f4cd8fa746a2a2309e5f73421c5b58825bc1e0454157e22fab7e81a0232 +test_ckf_tracks_example[generic-truth_estimated]__tracksummary_ckf.root: 74bc834cf220a16a96ce42a92eff3af1f0516362b68129ba98a85364237fd355 test_ckf_tracks_example[generic-truth_estimated]__performance_seeding.root: 1facb05c066221f6361b61f015cdf0918e94d9f3fce2269ec7b6a4dffeb2bc7e -test_ckf_tracks_example[generic-truth_smeared]__trackstates_ckf.root: 2a1569f867a155ed0034c6436d5b90550cbc0ae3d3dfa0be17a8a571dd338d7f -test_ckf_tracks_example[generic-truth_smeared]__tracksummary_ckf.root: f3d8b236e144e139a264964bfa2ba6807cbe977099448e2a7d4159d43d497228 -test_ckf_tracks_example[odd-full_seeding]__trackstates_ckf.root: 49df09e94671a042b8ecb3de394eba273cca7be1d5fcdab6f1127a36f1d6cf44 -test_ckf_tracks_example[odd-full_seeding]__tracksummary_ckf.root: 86b718b20553274933e90599918c0ebd3e97777d1c17dc20ad5facfe011916f2 +test_ckf_tracks_example[generic-truth_smeared]__trackstates_ckf.root: 0141affa2bd09b3ac2ccf715f00ff4a061f9e6505db654d993ecad8a0556ae93 +test_ckf_tracks_example[generic-truth_smeared]__tracksummary_ckf.root: 96ddae1bcab7b5bf79a4ba69e296420c2bed06aa7f0cc4f8d432c2271466c52d +test_ckf_tracks_example[odd-full_seeding]__trackstates_ckf.root: be43108e213bb2a36b568b3426e1632b54dff08a87545313544059450bdf4c02 +test_ckf_tracks_example[odd-full_seeding]__tracksummary_ckf.root: bdc38bafcd8a10586d2eb99c0de04afa6ecc43a5050f9faf48e322b8394d31cc test_ckf_tracks_example[odd-full_seeding]__performance_seeding_trees.root: 43c58577aafe07645e5660c4f43904efadf91d8cda45c5c04c248bbe0f59814f -test_ckf_tracks_example[odd-truth_estimated]__trackstates_ckf.root: a278382e1dfe4b3f037f12a62d0bd1ff06a005320ae7691e339b09269b3e6165 -test_ckf_tracks_example[odd-truth_estimated]__tracksummary_ckf.root: 6485e1daf43a2f40e2696c016a0e3dca61a462da7bd6b2a54305fb34a4377ed8 +test_ckf_tracks_example[odd-truth_estimated]__trackstates_ckf.root: 8d6d66d6a54f4677ff588529823fe209321353e906a9f5f2fc70ea2bc75dd495 +test_ckf_tracks_example[odd-truth_estimated]__tracksummary_ckf.root: 29eb102a8f56258400552ac8f714dad7bba6c506eb5ac461a3148be43ad827d4 test_ckf_tracks_example[odd-truth_estimated]__performance_seeding.root: 1a36b7017e59f1c08602ef3c2cb0483c51df248f112e3780c66594110719c575 -test_ckf_tracks_example[odd-truth_smeared]__trackstates_ckf.root: fbcad6efe99cc8bda41c49f1ee81fe48c817cbc01940f0577d0f1b93dbc7af55 -test_ckf_tracks_example[odd-truth_smeared]__tracksummary_ckf.root: 3bad4c3191fe62044df6c57dbe2c461943387b1cebba938c8400ef03cff83b72 +test_ckf_tracks_example[odd-truth_smeared]__trackstates_ckf.root: b1dfda803d9f8da98e76ae3565eaf915a03b7ffd740167e5c1cba6b934c18b5f +test_ckf_tracks_example[odd-truth_smeared]__tracksummary_ckf.root: 30d3a42a88646f1fa5a37429badf33fe0719c92b7864c9ef666b07af74af2ad4 test_vertex_fitting_reading[Truth-False-100]__performance_vertexing.root: 76ef6084d758dfdfc0151ddec2170e12d73394424e3dac4ffe46f0f339ec8293 test_vertex_fitting_reading[Iterative-False-100]__performance_vertexing.root: 60372210c830a04f95ceb78c6c68a9b0de217746ff59e8e73053750c837b57eb test_vertex_fitting_reading[Iterative-True-100]__performance_vertexing.root: e34f217d524a5051dbb04a811d3407df3ebe2cc4bb7f54f6bda0847dbd7b52c3 @@ -85,19 +85,19 @@ test_exatrkx[cpu-torch]__performance_track_finding.root: 36b3045589c4c17c038dbc8 test_exatrkx[gpu-onnx]__performance_track_finding.root: 9090de10ffb1489d3f1993e2a3081a3038227e3e5c453e98a9a4f33ea3d6d817 test_exatrkx[gpu-torch]__performance_track_finding.root: 36b3045589c4c17c038dbc87943366f4af4440f7eea6887afb763871ac149b05 test_ML_Ambiguity_Solver__performance_ambiML.root: 284ff5c3a08c0b810938e4ac2f8ba8fe2babb17d4c202b624ed69fff731a9006 -test_truth_tracking_kalman[generic-False-0.0]__trackstates_fitter.root: 093c0339e848c04e796f1dc9abe1a017a5d7450fae865ad354c71a46bbb34629 -test_truth_tracking_kalman[generic-False-0.0]__tracksummary_fitter.root: e3e6199e83a794ecc07a05cf61105c0ca726e1b73c0731663843b66cc22462e1 +test_truth_tracking_kalman[generic-False-0.0]__trackstates_fitter.root: 2ccfa7075529e8eef7d10e5ea6a4e83b6151bffbf109006d3e0e12533cdf87be +test_truth_tracking_kalman[generic-False-0.0]__tracksummary_fitter.root: bedccd1c0f3df8a9e037792eead3b9243c0ce671a29838740ad1816054c2cbd0 test_truth_tracking_kalman[generic-False-1000.0]__trackstates_fitter.root: b80ca323b0c3ec87559336ed1e9519f430f804aaf64f1cb7d05ffa9df00ae370 test_truth_tracking_kalman[generic-False-1000.0]__tracksummary_fitter.root: f1ebb0734350ab0857352987a66f6c77db67227a54a73d3524ccdef5e80bf952 -test_truth_tracking_kalman[generic-True-0.0]__trackstates_fitter.root: 093c0339e848c04e796f1dc9abe1a017a5d7450fae865ad354c71a46bbb34629 -test_truth_tracking_kalman[generic-True-0.0]__tracksummary_fitter.root: e3e6199e83a794ecc07a05cf61105c0ca726e1b73c0731663843b66cc22462e1 +test_truth_tracking_kalman[generic-True-0.0]__trackstates_fitter.root: 2ccfa7075529e8eef7d10e5ea6a4e83b6151bffbf109006d3e0e12533cdf87be +test_truth_tracking_kalman[generic-True-0.0]__tracksummary_fitter.root: bedccd1c0f3df8a9e037792eead3b9243c0ce671a29838740ad1816054c2cbd0 test_truth_tracking_kalman[generic-True-1000.0]__trackstates_fitter.root: b80ca323b0c3ec87559336ed1e9519f430f804aaf64f1cb7d05ffa9df00ae370 test_truth_tracking_kalman[generic-True-1000.0]__tracksummary_fitter.root: f1ebb0734350ab0857352987a66f6c77db67227a54a73d3524ccdef5e80bf952 -test_truth_tracking_kalman[odd-False-0.0]__trackstates_fitter.root: f6b2e1111798b29c1c1e958a711a17476838f51d601d7346b1f215458d3204ad -test_truth_tracking_kalman[odd-False-0.0]__tracksummary_fitter.root: de3d002f50aafc8b074dbd8f4e7135df7491c0463920710fbe39e29c4f20a200 -test_truth_tracking_kalman[odd-False-1000.0]__trackstates_fitter.root: e14a887ea509c0d140881fe88a1d607f0d29e938828d1cd72f4b41a550447aff +test_truth_tracking_kalman[odd-False-0.0]__trackstates_fitter.root: b13941f3b7aaf87fd34638ecc76b86aa5e820ac6d36133cb9e67bd7f57b040fc +test_truth_tracking_kalman[odd-False-0.0]__tracksummary_fitter.root: a7d6e0710b32219afc8879b4976c9bd388c4adb47b513b1cc8d0a3aaeba5c10b +test_truth_tracking_kalman[odd-False-1000.0]__trackstates_fitter.root: 82954b26640b124ae1136fe72d3e15ea92ed75c0e34f9d97327b20fc60a982d2 test_truth_tracking_kalman[odd-False-1000.0]__tracksummary_fitter.root: 3488f9e188faf706b312e0156a5d6c4a871163ed46cd6f35a1dc90f11aa3e93e -test_truth_tracking_kalman[odd-True-0.0]__trackstates_fitter.root: f6b2e1111798b29c1c1e958a711a17476838f51d601d7346b1f215458d3204ad -test_truth_tracking_kalman[odd-True-0.0]__tracksummary_fitter.root: de3d002f50aafc8b074dbd8f4e7135df7491c0463920710fbe39e29c4f20a200 -test_truth_tracking_kalman[odd-True-1000.0]__trackstates_fitter.root: e14a887ea509c0d140881fe88a1d607f0d29e938828d1cd72f4b41a550447aff +test_truth_tracking_kalman[odd-True-0.0]__trackstates_fitter.root: b13941f3b7aaf87fd34638ecc76b86aa5e820ac6d36133cb9e67bd7f57b040fc +test_truth_tracking_kalman[odd-True-0.0]__tracksummary_fitter.root: a7d6e0710b32219afc8879b4976c9bd388c4adb47b513b1cc8d0a3aaeba5c10b +test_truth_tracking_kalman[odd-True-1000.0]__trackstates_fitter.root: 82954b26640b124ae1136fe72d3e15ea92ed75c0e34f9d97327b20fc60a982d2 test_truth_tracking_kalman[odd-True-1000.0]__tracksummary_fitter.root: 3488f9e188faf706b312e0156a5d6c4a871163ed46cd6f35a1dc90f11aa3e93e diff --git a/Examples/Python/tests/test_base.py b/Examples/Python/tests/test_base.py index 50af8ee07ee..bf056a74021 100644 --- a/Examples/Python/tests/test_base.py +++ b/Examples/Python/tests/test_base.py @@ -5,6 +5,16 @@ import acts.examples +def test_version(): + assert hasattr(acts, "__version__") + assert hasattr(acts, "version") + assert hasattr(acts.version, "major") + assert hasattr(acts.version, "minor") + assert hasattr(acts.version, "patch") + assert hasattr(acts.version, "commit_hash") + assert hasattr(acts.version, "commit_hash_short") + + def test_logging(): for l in ("VERBOSE", "DEBUG", "INFO", "WARNING", "ERROR", "FATAL"): assert hasattr(acts.logging, l) diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index 10dcc4133cb..d1c67815629 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -376,10 +376,6 @@ def test_itk_seeding(tmp_path, trk_geo, field, assert_root_hash): rnd=rnd, ) - from acts.examples.reconstruction import ( - addSeeding, - TruthSeedRanges, - ) from acts.examples.reconstruction import ( addSeeding, TruthSeedRanges, @@ -1173,7 +1169,15 @@ def test_full_chain_odd_example_pythia_geant4(tmp_path): env["ACTS_LOG_FAILURE_THRESHOLD"] = "ERROR" try: stdout = subprocess.check_output( - [sys.executable, str(script), "-n1", "--geant4", "--ttbar"], + [ + sys.executable, + str(script), + "-n1", + "--geant4", + "--ttbar", + "--ttbar-pu", + "50", + ], cwd=tmp_path, env=env, stderr=subprocess.STDOUT, @@ -1215,7 +1219,7 @@ def test_ML_Ambiguity_Solver(tmp_path, assert_root_hash): env["ACTS_LOG_FAILURE_THRESHOLD"] = "ERROR" try: subprocess.check_call( - [sys.executable, str(script), "-n5", "--MLSolver"], + [sys.executable, str(script), "-n1", "--MLSolver"], cwd=tmp_path, env=env, stderr=subprocess.STDOUT, diff --git a/Examples/Scripts/Detectors/TGeoDetector/tgeo-response2json.py b/Examples/Scripts/Detectors/TGeoDetector/tgeo-response2json.py index 76dde34a850..a15df63dd4f 100755 --- a/Examples/Scripts/Detectors/TGeoDetector/tgeo-response2json.py +++ b/Examples/Scripts/Detectors/TGeoDetector/tgeo-response2json.py @@ -1,10 +1,12 @@ #!/usr/bin/env python # tgeo-response2json.py - convert TGeo response file options to ACTS v13.0.0 JSON format - -from __future__ import print_function - -import sys, os, re, getopt, json, subprocess +import sys +import os +import re +import getopt +import json +import subprocess from collections import OrderedDict diff --git a/Examples/Scripts/MaterialMapping/GeometryVisualisationAndMaterialHandling.py b/Examples/Scripts/MaterialMapping/GeometryVisualisationAndMaterialHandling.py index 8dba0cbbff2..c6271054d44 100644 --- a/Examples/Scripts/MaterialMapping/GeometryVisualisationAndMaterialHandling.py +++ b/Examples/Scripts/MaterialMapping/GeometryVisualisationAndMaterialHandling.py @@ -1,7 +1,5 @@ import json -import json - def dumper(obj): try: @@ -251,7 +249,6 @@ def dump_geo(filename, plot, output_folder, dump_steering, steering_file): plt.rcParams.update({"figure.max_open_warning": 0}) from matplotlib.pyplot import cm - from itertools import cycle import numpy as np color = cm.rainbow(np.linspace(0, 1, len(index_to_extends_layers_cylinders))) @@ -579,7 +576,6 @@ def read_and_modify(filename, plot, output_folder, steering_file, output_file): if plot and check_material_layers: import matplotlib.pyplot as plt from matplotlib.pyplot import cm - from itertools import cycle import numpy as np plt.figure(figsize=(20, 10)) diff --git a/Examples/Scripts/Optimization/Optuna_tuning.py b/Examples/Scripts/Optimization/Optuna_tuning.py index f4e26342f11..84ce906aa0b 100644 --- a/Examples/Scripts/Optimization/Optuna_tuning.py +++ b/Examples/Scripts/Optimization/Optuna_tuning.py @@ -1,43 +1,15 @@ #!/usr/bin/env python3 import sys - -import sys -import os -import yaml -import pprint -import time -import datetime -import warnings - import optuna import logging import uproot - -import pathlib import matplotlib - -matplotlib.use("pdf") -import matplotlib.pyplot as plt -import random import subprocess -import multiprocessing -import numpy as np import json -import array -import sys -import argparse import pandas as pd - -from typing import Optional, Union from pathlib import Path -from optuna.visualization import plot_contour -from optuna.visualization import plot_edf -from optuna.visualization import plot_intermediate_values -from optuna.visualization import plot_optimization_history -from optuna.visualization import plot_parallel_coordinate -from optuna.visualization import plot_param_importances -from optuna.visualization import plot_slice +matplotlib.use("pdf") srcDir = Path(__file__).resolve().parent @@ -192,7 +164,7 @@ def main(): # creating a new optuna study study = optuna.create_study( study_name=study_name, - storage="sqlite:///{}.db".format(study_name), + storage=storage_name, direction="maximize", load_if_exists=True, ) diff --git a/Examples/Scripts/Optimization/Orion_tuning.py b/Examples/Scripts/Optimization/Orion_tuning.py index 57942b0763e..9bdb05e5003 100644 --- a/Examples/Scripts/Optimization/Orion_tuning.py +++ b/Examples/Scripts/Optimization/Orion_tuning.py @@ -1,39 +1,15 @@ #!/usr/bin/env python3 -import sys - -import sys import os -import yaml -import pprint -import time -import datetime -import warnings - -import logging -import uproot - -import pathlib import matplotlib - -matplotlib.use("pdf") -import matplotlib.pyplot as plt -import random import subprocess -import multiprocessing -import numpy as np -import json -import array -import sys -import argparse -import pandas as pd - -from typing import Optional, Union from pathlib import Path from orion.client import build_experiment from Optuna_tuning import get_tracking_perf, run_ckf +matplotlib.use("pdf") + srcDir = Path(__file__).resolve().parent diff --git a/Examples/Scripts/Python/MLAmbiguityResolution/ambiguity_solver_network.py b/Examples/Scripts/Python/MLAmbiguityResolution/ambiguity_solver_network.py index cb0a63e6e42..12c5fd1e392 100644 --- a/Examples/Scripts/Python/MLAmbiguityResolution/ambiguity_solver_network.py +++ b/Examples/Scripts/Python/MLAmbiguityResolution/ambiguity_solver_network.py @@ -1,5 +1,4 @@ import pandas as pd -import numpy as np import torch.nn as nn import torch.nn.functional as F @@ -35,7 +34,6 @@ def prepareDataSet(data: pd.DataFrame) -> pd.DataFrame: data = data.set_index("particleId") # Transform the hit list from a string to an actual list hitsIds = [] - mergedIds = [] for list in data["Hits_ID"].values: hitsIds.append(ast.literal_eval(list)) data["Hits_ID"] = hitsIds diff --git a/Examples/Scripts/Python/MLAmbiguityResolution/ambiguity_solver_perf.py b/Examples/Scripts/Python/MLAmbiguityResolution/ambiguity_solver_perf.py index 1f1ba26d7c7..183ed24e851 100644 --- a/Examples/Scripts/Python/MLAmbiguityResolution/ambiguity_solver_perf.py +++ b/Examples/Scripts/Python/MLAmbiguityResolution/ambiguity_solver_perf.py @@ -1,6 +1,4 @@ import glob -import os -import math import pandas as pd import numpy as np diff --git a/Examples/Scripts/Python/MLAmbiguityResolution/match_good_track-seed.py b/Examples/Scripts/Python/MLAmbiguityResolution/match_good_track-seed.py index f917eaaf3cc..81c785ec4ed 100644 --- a/Examples/Scripts/Python/MLAmbiguityResolution/match_good_track-seed.py +++ b/Examples/Scripts/Python/MLAmbiguityResolution/match_good_track-seed.py @@ -1,7 +1,6 @@ import glob import pandas as pd -import numpy as np def matchGood(seed_files: list[str], ckf_files: list[str]): diff --git a/Examples/Scripts/Python/MLAmbiguityResolution/seed_filter_full_chain.py b/Examples/Scripts/Python/MLAmbiguityResolution/seed_filter_full_chain.py index 58aae10821e..96ebdcc8eb4 100644 --- a/Examples/Scripts/Python/MLAmbiguityResolution/seed_filter_full_chain.py +++ b/Examples/Scripts/Python/MLAmbiguityResolution/seed_filter_full_chain.py @@ -1,6 +1,4 @@ import glob -import os -import math import pandas as pd import numpy as np @@ -10,7 +8,7 @@ from sklearn.cluster import DBSCAN, KMeans from sklearn.preprocessing import LabelEncoder, OrdinalEncoder -from seed_solver_network import prepareDataSet, DuplicateClassifier, Normalise +from seed_solver_network import prepareDataSet def readDataSet(CKS_files: list[str]) -> pd.DataFrame: diff --git a/Examples/Scripts/Python/MLAmbiguityResolution/seed_solver_network.py b/Examples/Scripts/Python/MLAmbiguityResolution/seed_solver_network.py index 36de3db37f8..a0b4c74107e 100644 --- a/Examples/Scripts/Python/MLAmbiguityResolution/seed_solver_network.py +++ b/Examples/Scripts/Python/MLAmbiguityResolution/seed_solver_network.py @@ -1,5 +1,4 @@ import pandas as pd -import numpy as np import torch.nn as nn import torch.nn.functional as F @@ -20,7 +19,6 @@ def prepareDataSet(data: pd.DataFrame) -> pd.DataFrame: data = data.set_index("particleId") # Transform the hit list from a string to an actual list hitsIds = [] - mergedIds = [] for list in data["Hits_ID"].values: hitsIds.append(ast.literal_eval(list)) data["Hits_ID"] = hitsIds diff --git a/Examples/Scripts/Python/digitization_config.py b/Examples/Scripts/Python/digitization_config.py index 4c41aa5e550..dfad1913fd6 100755 --- a/Examples/Scripts/Python/digitization_config.py +++ b/Examples/Scripts/Python/digitization_config.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -import os from pathlib import Path import acts diff --git a/Examples/Scripts/Python/exatrkx.py b/Examples/Scripts/Python/exatrkx.py index 16cc606de20..b2a151fc4e7 100755 --- a/Examples/Scripts/Python/exatrkx.py +++ b/Examples/Scripts/Python/exatrkx.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 from pathlib import Path -from typing import Optional, Union import acts.examples import acts diff --git a/Examples/Scripts/Python/full_chain_itk_Gbts.py b/Examples/Scripts/Python/full_chain_itk_Gbts.py index 8d5fe028dbd..4829c741f79 100755 --- a/Examples/Scripts/Python/full_chain_itk_Gbts.py +++ b/Examples/Scripts/Python/full_chain_itk_Gbts.py @@ -16,10 +16,6 @@ TruthSeedRanges, addCKFTracks, TrackSelectorConfig, - addAmbiguityResolution, - AmbiguityResolutionConfig, - addVertexFitting, - VertexFinder, ) ttbar_pu200 = False diff --git a/Examples/Scripts/Python/full_chain_odd.py b/Examples/Scripts/Python/full_chain_odd.py index ce20bcf6b28..10f8c25bf58 100755 --- a/Examples/Scripts/Python/full_chain_odd.py +++ b/Examples/Scripts/Python/full_chain_odd.py @@ -58,6 +58,18 @@ help="Use Pythia8 (ttbar, pile-up 200) instead of particle gun", action="store_true", ) +parser.add_argument( + "--ttbar-pu", + help="Number of pile-up events for ttbar", + type=int, + default=200, +) +parser.add_argument( + "--gun-multiplicity", + help="Multiplicity of the particle gun", + type=int, + default=200, +) parser.add_argument( "--MLSolver", help="Use the Ml Ambiguity Solver instead of the classical one", @@ -135,7 +147,6 @@ inputParticles="particles", outputParticles="particles_selected", ) - else: if not ttbar: addParticleGun( @@ -150,14 +161,14 @@ 0.0125 * u.mm, 0.0125 * u.mm, 55.5 * u.mm, 1.0 * u.ns ), ), - multiplicity=200, + multiplicity=args["gun_multiplicity"], rnd=rnd, ) else: addPythia8( s, hardProcess=["Top:qqbar2ttbar=on"], - npileup=50, + npileup=args["ttbar_pu"], vtxGen=acts.examples.GaussianVertexGenerator( mean=acts.Vector4(0, 0, 0, 0), stddev=acts.Vector4( @@ -235,6 +246,7 @@ outputDirRoot=outputDir, # outputDirCsv=outputDir, ) + if seedFilter_ML: addSeedFilterML( s, @@ -256,9 +268,12 @@ absEta=(None, 3.0), loc0=(-4.0 * u.mm, 4.0 * u.mm), nMeasurementsMin=7, + maxHoles=2, + maxOutliers=2, ), CkfConfig( seedDeduplication=True, + stayOnSeed=True, ), outputDirRoot=outputDir, writeCovMat=True, diff --git a/Examples/Scripts/Python/geometry.py b/Examples/Scripts/Python/geometry.py index 9007163e3d1..d46246e10c5 100755 --- a/Examples/Scripts/Python/geometry.py +++ b/Examples/Scripts/Python/geometry.py @@ -28,7 +28,6 @@ def runGeometry( outputObj=True, outputCsv=True, outputJson=True, - outputRoot=True, ): for ievt in range(events): eventStore = WhiteBoard(name=f"EventStore#{ievt}", level=acts.logging.INFO) diff --git a/Examples/Scripts/Python/itk.py b/Examples/Scripts/Python/itk.py index a6239877758..ed9f0c1429a 100755 --- a/Examples/Scripts/Python/itk.py +++ b/Examples/Scripts/Python/itk.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -import sys from pathlib import Path import argparse @@ -16,7 +15,7 @@ import acts -from acts import MaterialMapJsonConverter, UnitConstants as u +from acts import MaterialMapJsonConverter def runITk( diff --git a/Examples/Scripts/Python/itk_seeding.py b/Examples/Scripts/Python/itk_seeding.py index 3cb7c7271fb..2e02430d881 100755 --- a/Examples/Scripts/Python/itk_seeding.py +++ b/Examples/Scripts/Python/itk_seeding.py @@ -11,9 +11,7 @@ SeedingPerformanceWriter, ) from acts.examples.reconstruction import ( - addSeeding, addStandardSeeding, - SeedingAlgorithm, ) from acts.examples.itk import itkSeedingAlgConfig, InputSpacePointsType diff --git a/Examples/Scripts/Python/material_mapping_core.py b/Examples/Scripts/Python/material_mapping_core.py new file mode 100644 index 00000000000..6b756185862 --- /dev/null +++ b/Examples/Scripts/Python/material_mapping_core.py @@ -0,0 +1,187 @@ +#!/usr/bin/env python3 + +import argparse + +import acts +from acts import ( + MaterialMapper, + IntersectionMaterialAssigner, + BinnedSurfaceMaterialAccumulater, + MaterialMapJsonConverter, +) + +from acts.examples import ( + Sequencer, + WhiteBoard, + AlgorithmContext, + RootMaterialTrackReader, + RootMaterialTrackWriter, + CoreMaterialMapping, + JsonMaterialWriter, + RootMaterialWriter, + JsonFormat, +) + +from acts.examples.dd4hep import ( + DD4hepDetector, + DD4hepDetectorOptions, + DD4hepGeometryService, +) + +from acts.examples.odd import getOpenDataDetector, getOpenDataDetectorDirectory + + +def runMaterialMapping(surfaces, inputFile, outputFile, outputMap, loglevel): + # Create a sequencer + print("Creating the sequencer with 1 thread (inter event information needed)") + + s = Sequencer(numThreads=1) + + # IO for material tracks reading + wb = WhiteBoard(acts.logging.INFO) + + # Read material step information from a ROOT TTRee + s.addReader( + RootMaterialTrackReader( + level=acts.logging.INFO, + outputMaterialTracks="material-tracks", + fileList=[inputFile], + readCachedSurfaceInformation=False, + ) + ) + + # Assignment setup : Intersection assigner + materialAssingerConfig = IntersectionMaterialAssigner.Config() + materialAssingerConfig.surfaces = surfaces + materialAssinger = IntersectionMaterialAssigner(materialAssingerConfig, loglevel) + + # Accumulation setup : Binned surface material accumulater + materialAccumulaterConfig = BinnedSurfaceMaterialAccumulater.Config() + materialAccumulaterConfig.materialSurfaces = surfaces + materialAccumulater = BinnedSurfaceMaterialAccumulater( + materialAccumulaterConfig, loglevel + ) + + # Mapper setup + materialMapperConfig = MaterialMapper.Config() + materialMapperConfig.assignmentFinder = materialAssinger + materialMapperConfig.surfaceMaterialAccumulater = materialAccumulater + materialMapper = MaterialMapper(materialMapperConfig, loglevel) + + # Add the map writer(s) + mapWriters = [] + # json map writer + context = AlgorithmContext(0, 0, wb) + jmConverterCfg = MaterialMapJsonConverter.Config( + processSensitives=True, + processApproaches=True, + processRepresenting=True, + processBoundaries=True, + processVolumes=True, + context=context.geoContext, + ) + mapWriters.append( + JsonMaterialWriter( + level=loglevel, + converterCfg=jmConverterCfg, + fileName=outputMap + "", + writeFormat=JsonFormat.Json, + ) + ) + mapWriters.append(RootMaterialWriter(level=loglevel, filePath=outputMap + ".root")) + + # Mapping Algorithm + coreMaterialMappingConfig = CoreMaterialMapping.Config() + coreMaterialMappingConfig.materialMapper = materialMapper + coreMaterialMappingConfig.inputMaterialTracks = "material-tracks" + coreMaterialMappingConfig.mappedMaterialTracks = "mapped-material-tracks" + coreMaterialMappingConfig.unmappedMaterialTracks = "unmapped-material-tracks" + coreMaterialMappingConfig.materiaMaplWriters = mapWriters + coreMaterialMapping = CoreMaterialMapping(coreMaterialMappingConfig, loglevel) + s.addAlgorithm(coreMaterialMapping) + + # Add the mapped material tracks writer + s.addWriter( + RootMaterialTrackWriter( + level=acts.logging.INFO, + inputMaterialTracks="mapped-material-tracks", + filePath=outputFile + "_mapped.root", + storeSurface=True, + storeVolume=True, + ) + ) + + # Add the unmapped material tracks writer + s.addWriter( + RootMaterialTrackWriter( + level=acts.logging.INFO, + inputMaterialTracks="unmapped-material-tracks", + filePath=outputFile + "_unmapped.root", + storeSurface=True, + storeVolume=True, + ) + ) + + return s + + +if "__main__" == __name__: + p = argparse.ArgumentParser() + + p.add_argument( + "-n", "--events", type=int, default=1000, help="Number of events to process" + ) + p.add_argument( + "-i", "--input", type=str, default="", help="Input file with material tracks" + ) + p.add_argument( + "-o", "--output", type=str, default="", help="Output file (core) name" + ) + p.add_argument( + "-m", "--map", type=str, default="", help="Output file for the material map" + ) + + p.add_argument( + "--matconfig", type=str, default="", help="Material configuration file" + ) + + p.add_argument( + "--experimental", + action=argparse.BooleanOptionalAction, + help="Construct experimental geometry", + ) + + args = p.parse_args() + + if args.experimental: + odd_xml = getOpenDataDetectorDirectory() / "xml" / "OpenDataDetector.xml" + + # Create the dd4hep geometry service and detector + dd4hepConfig = DD4hepGeometryService.Config() + dd4hepConfig.logLevel = acts.logging.INFO + dd4hepConfig.xmlFileNames = [str(odd_xml)] + dd4hepGeometryService = DD4hepGeometryService(dd4hepConfig) + dd4hepDetector = DD4hepDetector(dd4hepGeometryService) + + cOptions = DD4hepDetectorOptions(logLevel=acts.logging.INFO, emulateToGraph="") + + # Context and options + geoContext = acts.GeometryContext() + [detector, contextors, store] = dd4hepDetector.finalize(geoContext, cOptions) + + materialSurfaces = detector.extractMaterialSurfaces() + print("Extracted number of material surfaces: ", len(materialSurfaces)) + + else: + matDeco = None + if args.matconfig != "": + matDeco = acts.IMaterialDecorator.fromFile(args.matconfig) + + [detector, trackingGeometry, decorators] = getOpenDataDetector(matDeco) + + materialSurfaces = trackingGeometry.extractMaterialSurfaces() + print("Extracted number of material surfaces: ", len(materialSurfaces)) + + runMaterialMapping( + materialSurfaces, args.input, args.output, args.map, acts.logging.INFO + ).run() diff --git a/Examples/Scripts/Python/material_validation.py b/Examples/Scripts/Python/material_validation.py index 3234471fdb0..00db981c5cb 100755 --- a/Examples/Scripts/Python/material_validation.py +++ b/Examples/Scripts/Python/material_validation.py @@ -1,11 +1,9 @@ #!/usr/bin/env python3 import os +import argparse import acts -from acts import ( - UnitConstants as u, -) from acts.examples import Sequencer, RootMaterialTrackWriter from acts.examples.odd import getOpenDataDetector @@ -15,10 +13,13 @@ def runMaterialValidation( decorators, field, outputDir, + nevents=1000, + ntracks=1000, outputName="propagation-material", s=None, ): - s = s or Sequencer(events=1000, numThreads=-1) + # Create a sequencer + s = s or Sequencer(events=nevents, numThreads=-1) for decorator in decorators: s.addContextDecorator(decorator) @@ -36,7 +37,7 @@ def runMaterialValidation( propagatorImpl=prop, level=acts.logging.INFO, randomNumberSvc=rnd, - ntests=1000, + ntests=ntracks, sterileLogger=True, propagationStepCollection="propagation-steps", recordMaterialInteractions=True, @@ -60,12 +61,33 @@ def runMaterialValidation( if "__main__" == __name__: - matDeco = acts.IMaterialDecorator.fromFile("material-map.json") + p = argparse.ArgumentParser() + + p.add_argument( + "-n", "--events", type=int, default=1000, help="Number of events to process" + ) + p.add_argument( + "-t", "--tracks", type=int, default=1000, help="Number of tracks per event" + ) + p.add_argument( + "-m", "--map", type=str, default="", help="Input file for the material map" + ) + p.add_argument("-o", "--output", type=str, default="", help="Output file name") + + args = p.parse_args() + + matDeco = acts.IMaterialDecorator.fromFile(args.map) detector, trackingGeometry, decorators = getOpenDataDetector(mdecorator=matDeco) - field = acts.ConstantBField(acts.Vector3(0, 0, 2 * acts.UnitConstants.T)) + field = acts.ConstantBField(acts.Vector3(0, 0, 0 * acts.UnitConstants.T)) runMaterialValidation( - trackingGeometry, decorators, field, outputDir=os.getcwd() + trackingGeometry, + decorators, + field, + nevents=args.events, + ntracks=args.tracks, + outputDir=os.getcwd(), + outputName=args.output, ).run() diff --git a/Examples/Scripts/Python/material_validation_itk.py b/Examples/Scripts/Python/material_validation_itk.py index 000a6b2a0e6..4dbe1dbc1bf 100755 --- a/Examples/Scripts/Python/material_validation_itk.py +++ b/Examples/Scripts/Python/material_validation_itk.py @@ -6,9 +6,6 @@ from acts.examples import Sequencer, RootMaterialTrackWriter import acts -from acts import ( - UnitConstants as u, -) def runMaterialValidation( diff --git a/Examples/Scripts/Python/muon_hough.py b/Examples/Scripts/Python/muon_hough.py index 996309d2743..3b4bb98aac8 100755 --- a/Examples/Scripts/Python/muon_hough.py +++ b/Examples/Scripts/Python/muon_hough.py @@ -1,9 +1,8 @@ #!/usr/bin/env python3 import os import argparse -import tempfile -import pathlib, acts +import acts from acts.examples import CsvMuonSimHitReader, CsvDriftCircleReader, MuonHoughSeeder @@ -19,7 +18,7 @@ rnd = acts.examples.RandomNumbers(seed=42) -def runHoughFromCsv(inDir, outputDir): +def runHoughFromCsv(inDir): # create temporary file with pixel SPs and run the seeding s = acts.examples.Sequencer(events=8, numThreads=1, logLevel=acts.logging.VERBOSE) @@ -60,6 +59,4 @@ def runHoughFromCsv(inDir, outputDir): args = p.parse_args() - outputDir = pathlib.Path.cwd() / "muon_output" - - runHoughFromCsv(args.indir, outputDir) + runHoughFromCsv(args.indir) diff --git a/Examples/Scripts/Python/pythia8.py b/Examples/Scripts/Python/pythia8.py index 24cbc2de7fd..b103052dea7 100755 --- a/Examples/Scripts/Python/pythia8.py +++ b/Examples/Scripts/Python/pythia8.py @@ -1,7 +1,5 @@ #!/usr/bin/env python3 -from typing import Optional, Union from pathlib import Path -from collections.abc import Iterable import acts import acts.examples diff --git a/Examples/Scripts/Python/volume_association_test.py b/Examples/Scripts/Python/volume_association_test.py index 890070f9ebd..d9bcc00631f 100755 --- a/Examples/Scripts/Python/volume_association_test.py +++ b/Examples/Scripts/Python/volume_association_test.py @@ -58,7 +58,7 @@ def main(): geoContext = GeometryContext() # Convert the detector surfaces from GDML - [elements, ssurfaces, psurfaces] = acts_g4.convertSurfaces( + [_, ssurfaces, psurfaces] = acts_g4.convertSurfaces( args.input, [args.sensitives], [args.passives] ) odd = odd_light.get_detector(geoContext, ssurfaces, psurfaces, logging.INFO) diff --git a/Examples/Scripts/TrackingPerformance/ResidualsAndPulls.cpp b/Examples/Scripts/TrackingPerformance/ResidualsAndPulls.cpp index fdf04cafade..f0875b1a77f 100644 --- a/Examples/Scripts/TrackingPerformance/ResidualsAndPulls.cpp +++ b/Examples/Scripts/TrackingPerformance/ResidualsAndPulls.cpp @@ -70,19 +70,16 @@ int main(int argc, char** argv) { vm["filtered"].as(), vm["smoothed"].as(), vm["fit-predicted"].as(), vm["fit-filtered"].as(), vm["fit-smoothed"].as(), saveAs)) { - case -1: { + case -1: std::cout << "*** Input file could not be opened, check name/path." << std::endl; return -1; - } break; - case -2: { + case -2: std::cout << "*** Input tree could not be found, check name." << std::endl; return -2; - } break; - default: { + default: std::cout << "*** Successful run." << std::endl; - }; } if (tApp != nullptr) { diff --git a/Examples/Scripts/vertex_mu_scan.py b/Examples/Scripts/vertex_mu_scan.py index 46267400f2f..ee8977fe9df 100755 --- a/Examples/Scripts/vertex_mu_scan.py +++ b/Examples/Scripts/vertex_mu_scan.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 from pathlib import Path -from typing import List, Optional +from typing import List import re import uproot diff --git a/Fatras/CMakeLists.txt b/Fatras/CMakeLists.txt index 0edc77daf99..6ae0048f63f 100644 --- a/Fatras/CMakeLists.txt +++ b/Fatras/CMakeLists.txt @@ -5,6 +5,7 @@ add_library( src/Digitization/PlanarSurfaceMask.cpp src/Digitization/PlanarSurfaceDrift.cpp src/EventData/Particle.cpp + src/EventData/ParticleOutcome.cpp src/EventData/ProcessType.cpp src/Kernel/SimulationError.cpp src/Physics/BetheHeitler.cpp diff --git a/Fatras/include/ActsFatras/EventData/Particle.hpp b/Fatras/include/ActsFatras/EventData/Particle.hpp index 72357fae32a..9641ce29d36 100644 --- a/Fatras/include/ActsFatras/EventData/Particle.hpp +++ b/Fatras/include/ActsFatras/EventData/Particle.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2018-2021 CERN for the benefit of the Acts project +// Copyright (C) 2018-2024 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 @@ -18,13 +18,11 @@ #include "Acts/Surfaces/Surface.hpp" #include "Acts/Utilities/VectorHelpers.hpp" #include "ActsFatras/EventData/Barcode.hpp" +#include "ActsFatras/EventData/ParticleOutcome.hpp" #include "ActsFatras/EventData/ProcessType.hpp" -#include #include #include -#include -#include #include namespace ActsFatras { @@ -295,6 +293,17 @@ class Particle { /// Number of hits. constexpr std::uint32_t numberOfHits() const { return m_numberOfHits; } + /// Set the outcome of particle. + /// + /// @param outcome outcome code + constexpr Particle &setOutcome(ParticleOutcome outcome) { + m_outcome = outcome; + return *this; + } + + /// Particle outcome. + constexpr ParticleOutcome outcome() const { return m_outcome; } + private: // identity, i.e. things that do not change over the particle lifetime. /// Particle identifier within the event. @@ -319,6 +328,8 @@ class Particle { std::uint32_t m_numberOfHits = 0; /// reference surface const Acts::Surface *m_referenceSurface{nullptr}; + /// outcome + ParticleOutcome m_outcome = ParticleOutcome::Alive; }; std::ostream &operator<<(std::ostream &os, const Particle &particle); diff --git a/Fatras/include/ActsFatras/EventData/ParticleOutcome.hpp b/Fatras/include/ActsFatras/EventData/ParticleOutcome.hpp new file mode 100644 index 00000000000..ad15e5c73e7 --- /dev/null +++ b/Fatras/include/ActsFatras/EventData/ParticleOutcome.hpp @@ -0,0 +1,29 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2024 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 http://mozilla.org/MPL/2.0/. + +#pragma once + +#include +#include + +namespace ActsFatras { + +/// Particle outcome identifier. +/// +/// Encodes the outcome of the particle after the simulation +enum class ParticleOutcome : std::uint32_t { + Alive = 0, + KilledInteraction = 1, + KilledVolumeExit = 2, + KilledTime = 3, + KilledSecondaryParticle = 4, +}; + +std::ostream &operator<<(std::ostream &os, ParticleOutcome outcome); + +} // namespace ActsFatras diff --git a/Fatras/src/EventData/ParticleOutcome.cpp b/Fatras/src/EventData/ParticleOutcome.cpp new file mode 100644 index 00000000000..4c5fa59ad1d --- /dev/null +++ b/Fatras/src/EventData/ParticleOutcome.cpp @@ -0,0 +1,33 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2024 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 http://mozilla.org/MPL/2.0/. + +#include "ActsFatras/EventData/ParticleOutcome.hpp" + +#include +#include + +namespace ActsFatras { + +std::ostream &operator<<(std::ostream &os, ParticleOutcome outcome) { + switch (outcome) { + case ActsFatras::ParticleOutcome::Alive: + return (os << "Alive"); + case ActsFatras::ParticleOutcome::KilledInteraction: + return (os << "KilledInteraction"); + case ActsFatras::ParticleOutcome::KilledVolumeExit: + return (os << "KilledVolumeExit"); + case ActsFatras::ParticleOutcome::KilledTime: + return (os << "KilledTime"); + case ActsFatras::ParticleOutcome::KilledSecondaryParticle: + return (os << "KilledSecondaryParticle"); + } + + throw std::runtime_error("Unknown ParticleOutcome"); +} + +} // namespace ActsFatras diff --git a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepIdentifierMapper.hpp b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepIdentifierMapper.hpp index fc9c8ee3453..4463db89c79 100644 --- a/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepIdentifierMapper.hpp +++ b/Plugins/DD4hep/include/Acts/Plugins/DD4hep/DD4hepIdentifierMapper.hpp @@ -26,14 +26,14 @@ struct DD4hepIdentifierCapture { /// @brief Return an invalid identifier for volumes as they are not directly translated /// @return maximum value DD4hepIdentifier operator()( - const Acts::Experimental::DetectorVolume& /*unused*/) const { + const Acts::Experimental::DetectorVolume& /*volume*/) const { return std::numeric_limits::max(); } /// @brief Return an invalid identifier for portal objects as they are not directly translated /// @return maximum value DD4hepIdentifier operator()( - const Acts::Experimental::Portal& /*unused*/) const { + const Acts::Experimental::Portal& /*portal*/) const { return std::numeric_limits::max(); } diff --git a/Plugins/Json/include/Acts/Plugins/Json/IndexedGridJsonHelper.hpp b/Plugins/Json/include/Acts/Plugins/Json/IndexedGridJsonHelper.hpp index d94efc2752f..280342664ba 100644 --- a/Plugins/Json/include/Acts/Plugins/Json/IndexedGridJsonHelper.hpp +++ b/Plugins/Json/include/Acts/Plugins/Json/IndexedGridJsonHelper.hpp @@ -10,6 +10,7 @@ #include "Acts/Plugins/Json/AlgebraJsonConverter.hpp" #include "Acts/Plugins/Json/GridJsonConverter.hpp" +#include "Acts/Plugins/Json/UtilitiesJsonConverter.hpp" #include "Acts/Utilities/Grid.hpp" #include "Acts/Utilities/GridAxisGenerators.hpp" #include "Acts/Utilities/detail/AxisFwd.hpp" diff --git a/Plugins/Json/include/Acts/Plugins/Json/UtilitiesJsonConverter.hpp b/Plugins/Json/include/Acts/Plugins/Json/UtilitiesJsonConverter.hpp index 8f6e546b936..8fa33854b0d 100644 --- a/Plugins/Json/include/Acts/Plugins/Json/UtilitiesJsonConverter.hpp +++ b/Plugins/Json/include/Acts/Plugins/Json/UtilitiesJsonConverter.hpp @@ -11,6 +11,7 @@ #include "Acts/Plugins/Json/ActsJson.hpp" #include "Acts/Utilities/BinUtility.hpp" #include "Acts/Utilities/BinningData.hpp" +#include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/RangeXD.hpp" #include diff --git a/Plugins/Json/src/GridJsonConverter.cpp b/Plugins/Json/src/GridJsonConverter.cpp index 5569c932f7a..266c33d38ba 100644 --- a/Plugins/Json/src/GridJsonConverter.cpp +++ b/Plugins/Json/src/GridJsonConverter.cpp @@ -9,6 +9,7 @@ #include "Acts/Plugins/Json/GridJsonConverter.hpp" #include "Acts/Plugins/Json/AlgebraJsonConverter.hpp" +#include "Acts/Plugins/Json/UtilitiesJsonConverter.hpp" #include "Acts/Utilities/IAxis.hpp" nlohmann::json Acts::AxisJsonConverter::toJson(const IAxis& ia) { @@ -50,7 +51,7 @@ template void encodeSubspace( nlohmann::json& jGlobalToGridLocal, const Acts::GridAccess::IGlobalToGridLocal& globalToGridLocal, - const Subspace& /*unused*/) { + const Subspace& /*subspace*/) { const Subspace* subspace = dynamic_cast(&globalToGridLocal); if (subspace != nullptr) { jGlobalToGridLocal["type"] = "subspace"; @@ -97,7 +98,7 @@ void encodeSubspaces( template std::unique_ptr> decodeSubspace( - const nlohmann::json& /*unused*/) { + const nlohmann::json& /*j*/) { return std::make_unique>(); } diff --git a/Plugins/Json/src/UtilitiesJsonConverter.cpp b/Plugins/Json/src/UtilitiesJsonConverter.cpp index 8d528903d84..d43f87243cd 100644 --- a/Plugins/Json/src/UtilitiesJsonConverter.cpp +++ b/Plugins/Json/src/UtilitiesJsonConverter.cpp @@ -54,7 +54,6 @@ void Acts::from_json(const nlohmann::json& j, BinningData& bd) { float min = j["min"]; float max = j["max"]; int bins = j["bins"]; - std::string valueName = j["value"]; auto bValue = j["value"].get(); if (bins == 1 && !(j["type"] == "arbitrary")) { bd = BinningData(bValue, min, max); diff --git a/Plugins/Json/src/VolumeBoundsJsonConverter.cpp b/Plugins/Json/src/VolumeBoundsJsonConverter.cpp index eff3683aa59..af6c08eab8c 100644 --- a/Plugins/Json/src/VolumeBoundsJsonConverter.cpp +++ b/Plugins/Json/src/VolumeBoundsJsonConverter.cpp @@ -34,27 +34,20 @@ std::unique_ptr Acts::VolumeBoundsJsonConverter::fromJson( const auto type = jVolumeBounds["type"].get(); switch (type) { - case VolumeBounds::BoundsType::eCone: { + case VolumeBounds::BoundsType::eCone: return fromJson(jVolumeBounds); - } break; - case VolumeBounds::BoundsType::eCuboid: { + case VolumeBounds::BoundsType::eCuboid: return fromJson(jVolumeBounds); - } break; - case VolumeBounds::BoundsType::eCutoutCylinder: { + case VolumeBounds::BoundsType::eCutoutCylinder: return fromJson(jVolumeBounds); - } break; - case VolumeBounds::BoundsType::eCylinder: { + case VolumeBounds::BoundsType::eCylinder: return fromJson(jVolumeBounds); - } break; - case VolumeBounds::BoundsType::eTrapezoid: { + case VolumeBounds::BoundsType::eTrapezoid: return fromJson(jVolumeBounds); - } break; - case VolumeBounds::BoundsType::eGenericCuboid: { + case VolumeBounds::BoundsType::eGenericCuboid: return fromJson(jVolumeBounds); - } break; - default: { + default: throw std::invalid_argument("Unknown volume bounds type!"); - } } return nullptr; } // namespace Acts diff --git a/Plugins/Podio/edm.yml b/Plugins/Podio/edm.yml index bd07e7f5958..4509de3e6fa 100644 --- a/Plugins/Podio/edm.yml +++ b/Plugins/Podio/edm.yml @@ -1,4 +1,5 @@ --- +schema_version: 1 options: getSyntax: True exposePODMembers: False diff --git a/Plugins/Sycl/include/Acts/Plugins/Sycl/Seeding/DeviceExperimentCuts.hpp b/Plugins/Sycl/include/Acts/Plugins/Sycl/Seeding/DeviceExperimentCuts.hpp index 0ccdbe4dabe..b2a0eba55fe 100644 --- a/Plugins/Sycl/include/Acts/Plugins/Sycl/Seeding/DeviceExperimentCuts.hpp +++ b/Plugins/Sycl/include/Acts/Plugins/Sycl/Seeding/DeviceExperimentCuts.hpp @@ -25,9 +25,8 @@ class DeviceExperimentCuts { /// @param top top space point of the current seed /// @return seed weight to be added to the seed's weight float seedWeight(const detail::DeviceSpacePoint& bottom, - const detail::DeviceSpacePoint& middle, + const detail::DeviceSpacePoint& /*middle*/, const detail::DeviceSpacePoint& top) const { - (void)middle; float weight = 0; if (bottom.r > 150.f) { weight = 400.f; @@ -44,10 +43,8 @@ class DeviceExperimentCuts { /// @return true if the seed should be kept, false if the seed should be /// discarded bool singleSeedCut(float weight, const detail::DeviceSpacePoint& bottom, - const detail::DeviceSpacePoint& middle, - const detail::DeviceSpacePoint& top) const { - (void)middle; - (void)top; + const detail::DeviceSpacePoint& /*middle*/, + const detail::DeviceSpacePoint& /*top*/) const { return !(bottom.r > 150.f && weight < 380.f); }; }; diff --git a/README.md b/README.md index 8f678fe2af3..e211b7c8170 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ or *A Common Tracking Software* if you do not like recursive acronyms [![10.5281/zenodo.5141418](https://zenodo.org/badge/DOI/10.5281/zenodo.5141418.svg)](https://doi.org/10.5281/zenodo.5141418) [![Chat on Mattermost](https://badgen.net/badge/chat/on%20mattermost/cyan)](https://mattermost.web.cern.ch/acts/) -[![coverage](https://badgen.net/codecov/c/github/acts-project/acts/main)](https://codecov.io/gh/acts-project/acts/branch/main) +[![codecov](https://codecov.io/gh/acts-project/acts/branch/master/graph/badge.svg)](https://codecov.io/gh/acts-project/acts) [![Latest release](https://badgen.net/github/release/acts-project/acts)](https://github.com/acts-project/acts/releases) [![Status](https://badgen.net/github/checks/acts-project/acts/main)](https://github.com/acts-project/acts/actions) [![Metrics](https://badgen.net/badge/metric/tracker/purple)](https://acts-project.github.io/metrics/) diff --git a/Tests/Benchmarks/AtlasStepperBenchmark.cpp b/Tests/Benchmarks/AtlasStepperBenchmark.cpp index c7519abc68f..446b3aa67e1 100644 --- a/Tests/Benchmarks/AtlasStepperBenchmark.cpp +++ b/Tests/Benchmarks/AtlasStepperBenchmark.cpp @@ -69,19 +69,21 @@ int main(int argc, char* argv[]) { ACTS_INFO("propagating " << toys << " tracks with pT = " << ptInGeV << "GeV in a " << BzInT << "T B-field"); - using BField_type = ConstantBField; - using Stepper_type = AtlasStepper; - using Propagator_type = Propagator; + using BField = ConstantBField; + using Stepper = AtlasStepper; + using Propagator = Propagator; using Covariance = BoundSquareMatrix; auto bField = - std::make_shared(Vector3{0, 0, BzInT * UnitConstants::T}); - Stepper_type atlas_stepper(std::move(bField)); - Propagator_type propagator(std::move(atlas_stepper)); + std::make_shared(Vector3{0, 0, BzInT * UnitConstants::T}); + Stepper stepper(std::move(bField)); + Propagator propagator(std::move(stepper)); PropagatorOptions<> options(tgContext, mfContext); options.pathLimit = maxPathInM * UnitConstants::m; + Vector4 pos4(0, 0, 0, 0); + Vector3 dir(1, 0, 0); Covariance cov; // clang-format off cov << 10_mm, 0, 0, 0, 0, 0, @@ -92,17 +94,17 @@ int main(int argc, char* argv[]) { 0, 0, 0, 0, 0, 0; // clang-format on - std::optional optCov = std::nullopt; + std::optional covOpt = std::nullopt; if (withCov) { - optCov = cov; + covOpt = cov; } - CurvilinearTrackParameters pars(Vector4::Zero(), 0_degree, 90_degree, - 1_e / ptInGeV * UnitConstants::GeV, optCov, + CurvilinearTrackParameters pars(pos4, dir, +1 / ptInGeV, covOpt, ParticleHypothesis::pion()); double totalPathLength = 0; - std::size_t num_iters = 0; - const auto propagation_bench_result = Acts::Test::microBenchmark( + std::size_t numSteps = 0; + std::size_t numIters = 0; + const auto propagationBenchResult = Acts::Test::microBenchmark( [&] { auto r = propagator.propagate(pars, options).value(); if (totalPathLength == 0.) { @@ -111,13 +113,16 @@ int main(int argc, char* argv[]) { << " in " << r.steps << " steps"); } totalPathLength += r.pathLength; - ++num_iters; + numSteps += r.steps; + ++numIters; return r; }, 1, toys); - ACTS_INFO("Execution stats: " << propagation_bench_result); - ACTS_INFO("average path length = " << totalPathLength / num_iters / 1_mm + ACTS_INFO("Execution stats: " << propagationBenchResult); + ACTS_INFO("average path length = " << totalPathLength / numIters / 1_mm << "mm"); + ACTS_INFO("average number of steps = " << 1.0 * numSteps / numIters); + return 0; } diff --git a/Tests/Benchmarks/CMakeLists.txt b/Tests/Benchmarks/CMakeLists.txt index e452add9ed2..3bd4a69f07e 100644 --- a/Tests/Benchmarks/CMakeLists.txt +++ b/Tests/Benchmarks/CMakeLists.txt @@ -26,5 +26,6 @@ add_benchmark(BinUtility BinUtilityBenchmark.cpp) add_benchmark(EigenStepper EigenStepperBenchmark.cpp) add_benchmark(SolenoidField SolenoidFieldBenchmark.cpp) add_benchmark(SurfaceIntersection SurfaceIntersectionBenchmark.cpp) -add_benchmark(RayFrustumBenchmark RayFrustumBenchmark.cpp) -add_benchmark(AnnulusBoundsBenchmark AnnulusBoundsBenchmark.cpp) +add_benchmark(RayFrustum RayFrustumBenchmark.cpp) +add_benchmark(AnnulusBounds AnnulusBoundsBenchmark.cpp) +add_benchmark(StraightLineStepper StraightLineStepperBenchmark.cpp) diff --git a/Tests/Benchmarks/EigenStepperBenchmark.cpp b/Tests/Benchmarks/EigenStepperBenchmark.cpp index b1e9425b4e5..dc2762a993a 100644 --- a/Tests/Benchmarks/EigenStepperBenchmark.cpp +++ b/Tests/Benchmarks/EigenStepperBenchmark.cpp @@ -7,6 +7,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include "Acts/Definitions/Units.hpp" +#include "Acts/EventData/ParticleHypothesis.hpp" #include "Acts/EventData/TrackParameters.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/MagneticField/ConstantBField.hpp" @@ -68,15 +69,15 @@ int main(int argc, char* argv[]) { ACTS_INFO("propagating " << toys << " tracks with pT = " << ptInGeV << "GeV in a " << BzInT << "T B-field"); - using BField_type = ConstantBField; - using Stepper_type = EigenStepper<>; - using Propagator_type = Propagator; + using BField = ConstantBField; + using Stepper = EigenStepper<>; + using Propagator = Propagator; using Covariance = BoundSquareMatrix; auto bField = - std::make_shared(Vector3{0, 0, BzInT * UnitConstants::T}); - Stepper_type atlas_stepper(std::move(bField)); - Propagator_type propagator(std::move(atlas_stepper)); + std::make_shared(Vector3{0, 0, BzInT * UnitConstants::T}); + Stepper stepper(std::move(bField)); + Propagator propagator(std::move(stepper)); PropagatorOptions<> options(tgContext, mfContext); options.pathLimit = maxPathInM * UnitConstants::m; @@ -101,8 +102,9 @@ int main(int argc, char* argv[]) { ParticleHypothesis::pion()); double totalPathLength = 0; - std::size_t num_iters = 0; - const auto propagation_bench_result = Acts::Test::microBenchmark( + std::size_t numSteps = 0; + std::size_t numIters = 0; + const auto propagationBenchResult = Acts::Test::microBenchmark( [&] { auto r = propagator.propagate(pars, options).value(); if (totalPathLength == 0.) { @@ -111,14 +113,16 @@ int main(int argc, char* argv[]) { << " in " << r.steps << " steps"); } totalPathLength += r.pathLength; - ++num_iters; + numSteps += r.steps; + ++numIters; return r; }, 1, toys); - ACTS_INFO("Execution stats: " << propagation_bench_result); - ACTS_INFO("average path length = " << totalPathLength / num_iters / 1_mm + ACTS_INFO("Execution stats: " << propagationBenchResult); + ACTS_INFO("average path length = " << totalPathLength / numIters / 1_mm << "mm"); + ACTS_INFO("average number of steps = " << 1.0 * numSteps / numIters); return 0; } diff --git a/Tests/Benchmarks/StraightLineStepperBenchmark.cpp b/Tests/Benchmarks/StraightLineStepperBenchmark.cpp new file mode 100644 index 00000000000..5d2262c6068 --- /dev/null +++ b/Tests/Benchmarks/StraightLineStepperBenchmark.cpp @@ -0,0 +1,123 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2019 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 http://mozilla.org/MPL/2.0/. + +#include "Acts/Definitions/Units.hpp" +#include "Acts/EventData/ParticleHypothesis.hpp" +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/MagneticField/MagneticFieldContext.hpp" +#include "Acts/Propagator/Propagator.hpp" +#include "Acts/Propagator/StraightLineStepper.hpp" +#include "Acts/Tests/CommonHelpers/BenchmarkTools.hpp" +#include "Acts/Utilities/Logger.hpp" + +#include + +#include + +namespace po = boost::program_options; +using namespace Acts; +using namespace Acts::UnitLiterals; + +int main(int argc, char* argv[]) { + unsigned int toys = 1; + double ptInGeV = 1; + double BzInT = 1; + double maxPathInM = 1; + unsigned int lvl = Acts::Logging::INFO; + bool withCov = true; + + // Create a test context + GeometryContext tgContext = GeometryContext(); + MagneticFieldContext mfContext = MagneticFieldContext(); + + try { + po::options_description desc("Allowed options"); + // clang-format off + desc.add_options() + ("help", "produce help message") + ("toys",po::value(&toys)->default_value(20000),"number of tracks to propagate") + ("pT",po::value(&ptInGeV)->default_value(1),"transverse momentum in GeV") + ("path",po::value(&maxPathInM)->default_value(5),"maximum path length in m") + ("cov",po::value(&withCov)->default_value(true),"propagation with covariance matrix") + ("verbose",po::value(&lvl)->default_value(Acts::Logging::INFO),"logging level"); + // clang-format on + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help") != 0u) { + std::cout << desc << std::endl; + return 0; + } + } catch (std::exception& e) { + std::cerr << "error: " << e.what() << std::endl; + return 1; + } + + ACTS_LOCAL_LOGGER( + getDefaultLogger("ATLAS_Stepper", Acts::Logging::Level(lvl))); + + // print information about profiling setup + ACTS_INFO("propagating " << toys << " tracks with pT = " << ptInGeV + << "GeV in a " << BzInT << "T B-field"); + + using Stepper = StraightLineStepper; + using Propagator = Propagator; + using Covariance = BoundSquareMatrix; + + Stepper stepper; + Propagator propagator(stepper); + + PropagatorOptions<> options(tgContext, mfContext); + options.pathLimit = maxPathInM * UnitConstants::m; + + Vector4 pos4(0, 0, 0, 0); + Vector3 dir(1, 0, 0); + Covariance cov; + // clang-format off + cov << 10_mm, 0, 0, 0, 0, 0, + 0, 10_mm, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 1_e / 10_GeV, 0, + 0, 0, 0, 0, 0, 0; + // clang-format on + + std::optional covOpt = std::nullopt; + if (withCov) { + covOpt = cov; + } + CurvilinearTrackParameters pars(pos4, dir, +1 / ptInGeV, covOpt, + ParticleHypothesis::pion()); + + double totalPathLength = 0; + std::size_t numSteps = 0; + std::size_t numIters = 0; + const auto propagationBenchResult = Acts::Test::microBenchmark( + [&] { + auto r = propagator.propagate(pars, options).value(); + if (totalPathLength == 0.) { + ACTS_DEBUG("reached position " + << r.endParameters->position(tgContext).transpose() + << " in " << r.steps << " steps"); + } + totalPathLength += r.pathLength; + numSteps += r.steps; + ++numIters; + return r; + }, + 1, toys); + + ACTS_INFO("Execution stats: " << propagationBenchResult); + ACTS_INFO("average path length = " << totalPathLength / numIters / 1_mm + << "mm"); + ACTS_INFO("average number of steps = " << 1.0 * numSteps / numIters); + + return 0; +} diff --git a/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CubicTrackingGeometry.hpp b/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CubicTrackingGeometry.hpp index 7a24126db56..3993ed07346 100644 --- a/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CubicTrackingGeometry.hpp +++ b/Tests/CommonHelpers/Acts/Tests/CommonHelpers/CubicTrackingGeometry.hpp @@ -187,7 +187,8 @@ struct CubicTrackingGeometry { new BinnedArrayXD(tapVec, std::move(bu))); MutableTrackingVolumePtr mtvpWorld(std::make_shared( - trafoWorld, worldVolBds, trVolArr, "World")); + trafoWorld, worldVolBds, nullptr, nullptr, trVolArr, + MutableTrackingVolumeVector{}, "World")); // Build and return tracking geometry return std::make_shared(mtvpWorld); diff --git a/Tests/CommonHelpers/Acts/Tests/CommonHelpers/PredefinedMaterials.hpp b/Tests/CommonHelpers/Acts/Tests/CommonHelpers/PredefinedMaterials.hpp index 4ddf0a7e66d..b3a50971eae 100644 --- a/Tests/CommonHelpers/Acts/Tests/CommonHelpers/PredefinedMaterials.hpp +++ b/Tests/CommonHelpers/Acts/Tests/CommonHelpers/PredefinedMaterials.hpp @@ -6,9 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file -/// @brief Predefined materials for test - #pragma once #include "Acts/Definitions/Units.hpp" diff --git a/Tests/IntegrationTests/InterpolatedSolenoidBFieldTest.cpp b/Tests/IntegrationTests/InterpolatedSolenoidBFieldTest.cpp index 86276a36758..3987fceef7c 100644 --- a/Tests/IntegrationTests/InterpolatedSolenoidBFieldTest.cpp +++ b/Tests/IntegrationTests/InterpolatedSolenoidBFieldTest.cpp @@ -106,7 +106,6 @@ BOOST_DATA_TEST_CASE( M_PI))) ^ bdata::xrange(ntests), z, r, phi, index) { - (void)index; if (index % 1000 == 0) { std::cout << index << std::endl; } diff --git a/Tests/UnitTests/Core/Detector/GeometryIdGeneratorTests.cpp b/Tests/UnitTests/Core/Detector/GeometryIdGeneratorTests.cpp index 3bb4ccf137a..f06269fcb91 100644 --- a/Tests/UnitTests/Core/Detector/GeometryIdGeneratorTests.cpp +++ b/Tests/UnitTests/Core/Detector/GeometryIdGeneratorTests.cpp @@ -92,7 +92,7 @@ struct GeoIdIncrementer : public IGeometryIdGenerator { /// /// @param cache is the cache object for e.g. object counting /// @param dVolume the detector volume to assign the geometry id to - void assignGeometryId(IGeometryIdGenerator::GeoIdCache& /*unused*/, + void assignGeometryId(IGeometryIdGenerator::GeoIdCache& /*cache*/, DetectorVolume& dVolume) const final { auto vgid = dVolume.geometryId(); vgid.setVolume(vgid.volume() + 1); @@ -103,7 +103,7 @@ struct GeoIdIncrementer : public IGeometryIdGenerator { /// /// @param cache is the cache object for e.g. object counting /// @param portal the portal to assign the geometry id to - void assignGeometryId(IGeometryIdGenerator::GeoIdCache& /*unused*/, + void assignGeometryId(IGeometryIdGenerator::GeoIdCache& /*cache*/, Portal& portal) const final { auto pgid = portal.surface().geometryId(); pgid.setBoundary(pgid.boundary() + 1); @@ -114,7 +114,7 @@ struct GeoIdIncrementer : public IGeometryIdGenerator { /// /// @param cache is the cache object for e.g. object counting /// @param surface the surface to assign the geometry id to - void assignGeometryId(IGeometryIdGenerator::GeoIdCache& /*unused*/, + void assignGeometryId(IGeometryIdGenerator::GeoIdCache& /*cache*/, Surface& surface) const final { auto sgid = surface.geometryId(); if (sgid.sensitive() != 0u) { diff --git a/Tests/UnitTests/Core/Detector/ProtoBinningTests.cpp b/Tests/UnitTests/Core/Detector/ProtoBinningTests.cpp index dafb573efdc..3edc3a2b176 100644 --- a/Tests/UnitTests/Core/Detector/ProtoBinningTests.cpp +++ b/Tests/UnitTests/Core/Detector/ProtoBinningTests.cpp @@ -10,6 +10,8 @@ #include #include "Acts/Detector/ProtoBinning.hpp" +#include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" +#include "Acts/Utilities/BinUtility.hpp" using namespace Acts::Experimental; @@ -68,4 +70,42 @@ BOOST_AUTO_TEST_CASE(ProtoBinningVariable) { varEdges.begin(), varEdges.end()); } +BOOST_AUTO_TEST_CASE(BinningDescriptionFromAndToBinUtility) { + // A valid binning + Acts::BinUtility bUtility(5u, 0., 10., Acts::open, Acts::binR); + std::vector edges = {-M_PI, 0.1, M_PI}; + bUtility += Acts::BinUtility(edges, Acts::closed, Acts::binPhi); + + auto bDescription = BinningDescription::fromBinUtility(bUtility); + + BOOST_CHECK_EQUAL(bDescription.binning.size(), 2u); + + // Test the first entry + BOOST_CHECK_EQUAL(bDescription.binning[0].bins(), 5u); + BOOST_CHECK_EQUAL(bDescription.binning[0].binValue, Acts::binR); + BOOST_CHECK(bDescription.binning[0].axisType == + Acts::detail::AxisType::Equidistant); + BOOST_CHECK(bDescription.binning[0].boundaryType == + Acts::detail::AxisBoundaryType::Bound); + BOOST_CHECK_EQUAL(bDescription.binning[0].edges.size(), 6u); + + // Check the second entry + BOOST_CHECK_EQUAL(bDescription.binning[1].bins(), 2u); + BOOST_CHECK_EQUAL(bDescription.binning[1].binValue, Acts::binPhi); + BOOST_CHECK(bDescription.binning[1].axisType == + Acts::detail::AxisType::Variable); + BOOST_CHECK(bDescription.binning[1].boundaryType == + Acts::detail::AxisBoundaryType::Closed); + BOOST_CHECK_EQUAL(bDescription.binning[1].edges.size(), 3u); + + // Round-trip + auto binUtility = bDescription.toBinUtility(); + BOOST_CHECK_EQUAL(binUtility.binningData().size(), 2u); + BOOST_CHECK_EQUAL(binUtility.binningData()[0].bins(), 5u); + BOOST_CHECK_EQUAL(binUtility.binningData()[1].bins(), 2u); + BOOST_CHECK_EQUAL(binUtility.binningData()[1].boundaries().size(), 3u); + CHECK_CLOSE_ABS(binUtility.binningData()[1].boundaries()[0], -M_PI, 1e-5); + CHECK_CLOSE_ABS(binUtility.binningData()[1].boundaries()[1], 0.1, 1e-4); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/Tests/UnitTests/Core/Detector/SupportSurfacesHelperTests.cpp b/Tests/UnitTests/Core/Detector/SupportSurfacesHelperTests.cpp index 7f2263d4889..d60950c9b8d 100644 --- a/Tests/UnitTests/Core/Detector/SupportSurfacesHelperTests.cpp +++ b/Tests/UnitTests/Core/Detector/SupportSurfacesHelperTests.cpp @@ -339,7 +339,7 @@ BOOST_AUTO_TEST_CASE(addMisconfiguredSupportCase) { // Wrong surface type struct InvalidCreator { - auto operator()(const Acts::Extent& /*unused*/) const { + auto operator()(const Acts::Extent& /*e*/) const { return std::make_tuple(Acts::Surface::SurfaceType::Perigee, std::vector{}, Acts::Transform3::Identity()); diff --git a/Tests/UnitTests/Core/Geometry/TrackingVolumeCreation.hpp b/Tests/UnitTests/Core/Geometry/TrackingVolumeCreation.hpp index 2cb8411ba70..7522c3bb0e7 100644 --- a/Tests/UnitTests/Core/Geometry/TrackingVolumeCreation.hpp +++ b/Tests/UnitTests/Core/Geometry/TrackingVolumeCreation.hpp @@ -107,8 +107,9 @@ MutableTrackingVolumePtr constructContainerVolume(const GeometryContext& gctx, std::make_shared>( volumes, std::move(vUtility)); /// create the container volume - auto hVolume = std::make_shared(Transform3::Identity(), - hVolumeBounds, vArray, name); + auto hVolume = std::make_shared( + Transform3::Identity(), hVolumeBounds, nullptr, nullptr, vArray, + MutableTrackingVolumeVector{}, name); // return the container return hVolume; } diff --git a/Tests/UnitTests/Core/Geometry/TrackingVolumeTests.cpp b/Tests/UnitTests/Core/Geometry/TrackingVolumeTests.cpp index 7945d95a6c0..b2106b85589 100644 --- a/Tests/UnitTests/Core/Geometry/TrackingVolumeTests.cpp +++ b/Tests/UnitTests/Core/Geometry/TrackingVolumeTests.cpp @@ -9,33 +9,56 @@ #include #include -#include "Acts/EventData/TrackParameters.hpp" -#include "Acts/Geometry/CuboidVolumeBounds.hpp" -#include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/Definitions/Units.hpp" +#include "Acts/Geometry/CylinderVolumeBounds.hpp" #include "Acts/Geometry/TrackingVolume.hpp" -#include "Acts/Geometry/Volume.hpp" -#include "Acts/Propagator/ActionList.hpp" -#include "Acts/Propagator/ConstrainedStep.hpp" -#include "Acts/Propagator/Navigator.hpp" -#include "Acts/Propagator/Propagator.hpp" -#include "Acts/Propagator/StandardAborters.hpp" -#include "Acts/Propagator/StraightLineStepper.hpp" -#include "Acts/Propagator/detail/SteppingLogger.hpp" -#include "Acts/Utilities/BoundingBox.hpp" -#include "Acts/Utilities/Ray.hpp" - -namespace Acts { -namespace Test { + +namespace Acts::Test { + +using namespace Acts::UnitLiterals; BOOST_AUTO_TEST_SUITE(Geometry) +BOOST_AUTO_TEST_SUITE(TrackingVolumeTests) + +std::size_t countVolumes(const TrackingVolume& tv) { + std::size_t count = 0; + tv.visitVolumes([&count](const auto&) { ++count; }); + return count; +} + +BOOST_AUTO_TEST_CASE(TrackigVolumeChildren) { + auto cylBounds = + std::make_shared(10_mm, 20_mm, 100_mm); + + TrackingVolume tv{Transform3::Identity(), cylBounds}; + + BOOST_CHECK(tv.volumes().empty()); + BOOST_CHECK_EQUAL(countVolumes(tv), 1); + + auto& child1 = tv.addVolume( + std::make_unique(Transform3::Identity(), cylBounds)); -// @TODO: Add TrackingVolume tests + BOOST_CHECK_EQUAL(tv.volumes().size(), 1); -BOOST_AUTO_TEST_CASE(placeholder) { - BOOST_CHECK(true); + auto it = tv.volumes().begin(); + static_assert(std::is_same_v); + + const auto& tvConst = tv; + auto cit = tvConst.volumes().begin(); + static_assert(std::is_same_v); + + BOOST_CHECK_EQUAL(&*it, &child1); + + BOOST_CHECK_EQUAL(countVolumes(tv), 2); + + tv.addVolume( + std::make_unique(Transform3::Identity(), cylBounds)); + + BOOST_CHECK_EQUAL(countVolumes(tv), 3); } BOOST_AUTO_TEST_SUITE_END() -} // namespace Test -} // namespace Acts +BOOST_AUTO_TEST_SUITE_END() + +} // namespace Acts::Test diff --git a/Tests/UnitTests/Core/Geometry/VolumeTests.cpp b/Tests/UnitTests/Core/Geometry/VolumeTests.cpp index 0d98444fe7f..64d749cb38c 100644 --- a/Tests/UnitTests/Core/Geometry/VolumeTests.cpp +++ b/Tests/UnitTests/Core/Geometry/VolumeTests.cpp @@ -75,4 +75,25 @@ BOOST_AUTO_TEST_CASE(VolumeTest) { BOOST_CHECK_EQUAL(volume.binningPosition(gctx, binX), volume.center()); } +BOOST_AUTO_TEST_CASE(VolumeUpdateTest) { + using namespace Acts::UnitLiterals; + auto volBounds = std::make_shared(4_mm, 5_mm, 6_mm); + auto volBounds2 = std::make_shared(4_mm, 5_mm, 8_mm); + + Transform3 trf = Transform3::Identity(); + + Volume volume(trf, volBounds); + + // Only update the bounds, keep the transform the same + volume.update(volBounds2, std::nullopt); + BOOST_CHECK_EQUAL(&volume.volumeBounds(), volBounds2.get()); + BOOST_CHECK_EQUAL(volume.transform().matrix(), trf.matrix()); + + // Update the bounds and the transform + Transform3 trf2{Translation3{1_mm, 2_mm, 3_mm}}; + volume.update(volBounds, trf2); + BOOST_CHECK_EQUAL(&volume.volumeBounds(), volBounds.get()); + BOOST_CHECK_EQUAL(volume.transform().matrix(), trf2.matrix()); +} + } // namespace Acts::Test diff --git a/Tests/UnitTests/Core/MagneticField/ConstantBFieldTests.cpp b/Tests/UnitTests/Core/MagneticField/ConstantBFieldTests.cpp index 01f034369c0..4548cb94933 100644 --- a/Tests/UnitTests/Core/MagneticField/ConstantBFieldTests.cpp +++ b/Tests/UnitTests/Core/MagneticField/ConstantBFieldTests.cpp @@ -6,8 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file ConstantBField_tests.cpp - #include #include diff --git a/Tests/UnitTests/Core/MagneticField/InterpolatedBFieldMapTests.cpp b/Tests/UnitTests/Core/MagneticField/InterpolatedBFieldMapTests.cpp index 4a6ad3df443..2abb6c72d8f 100644 --- a/Tests/UnitTests/Core/MagneticField/InterpolatedBFieldMapTests.cpp +++ b/Tests/UnitTests/Core/MagneticField/InterpolatedBFieldMapTests.cpp @@ -6,8 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file InterpolatedBFieldMap_tests.cpp - #include #include "Acts/Definitions/Algebra.hpp" diff --git a/Tests/UnitTests/Core/MagneticField/MagneticFieldInterfaceConsistencyTests.cpp b/Tests/UnitTests/Core/MagneticField/MagneticFieldInterfaceConsistencyTests.cpp index 67e517d12a9..06debb0ebeb 100644 --- a/Tests/UnitTests/Core/MagneticField/MagneticFieldInterfaceConsistencyTests.cpp +++ b/Tests/UnitTests/Core/MagneticField/MagneticFieldInterfaceConsistencyTests.cpp @@ -6,8 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file MagneticFieldInterfaceConsistencyTests.cpp - #include #include #include diff --git a/Tests/UnitTests/Core/MagneticField/SolenoidBFieldTests.cpp b/Tests/UnitTests/Core/MagneticField/SolenoidBFieldTests.cpp index d66b8097060..2325ed6b6a4 100644 --- a/Tests/UnitTests/Core/MagneticField/SolenoidBFieldTests.cpp +++ b/Tests/UnitTests/Core/MagneticField/SolenoidBFieldTests.cpp @@ -6,8 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file SolenoidBFieldTests.cpp - #include #include diff --git a/Tests/UnitTests/Core/Material/InterpolatedMaterialMapTests.cpp b/Tests/UnitTests/Core/Material/InterpolatedMaterialMapTests.cpp index 912d76f9957..79a5c94cd81 100644 --- a/Tests/UnitTests/Core/Material/InterpolatedMaterialMapTests.cpp +++ b/Tests/UnitTests/Core/Material/InterpolatedMaterialMapTests.cpp @@ -6,8 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file InterpolatedMaterialdMapTests.cpp - #include #include diff --git a/Tests/UnitTests/Core/Material/MaterialInteractionAssignmentTests.cpp b/Tests/UnitTests/Core/Material/MaterialInteractionAssignmentTests.cpp index e0ed8a81f61..1cf35a058af 100644 --- a/Tests/UnitTests/Core/Material/MaterialInteractionAssignmentTests.cpp +++ b/Tests/UnitTests/Core/Material/MaterialInteractionAssignmentTests.cpp @@ -173,8 +173,9 @@ BOOST_AUTO_TEST_CASE(AssignToClosest_withLocalVeto) { // Veto in a specific one struct VetoThisOne { bool operator()( - const MaterialInteraction& /*unused*/, - const IAssignmentFinder::SurfaceAssignment& /*unused*/) const { + const MaterialInteraction& /*m*/, + const IAssignmentFinder::SurfaceAssignment& /*suggestedAssignment*/) + const { return true; } }; @@ -232,9 +233,10 @@ BOOST_AUTO_TEST_CASE(AssignToClosest_withReassignment) { // Veto in a specific one struct ReAssignToNeighbor { - void operator()(MaterialInteraction& m, - const IAssignmentFinder::SurfaceAssignment& /*unused*/, - const IAssignmentFinder::SurfaceAssignment& n) const { + void operator()( + MaterialInteraction& m, + const IAssignmentFinder::SurfaceAssignment& /*suggestedAssignment*/, + const IAssignmentFinder::SurfaceAssignment& n) const { auto [surface, position, direction] = n; m.surface = surface; m.position = position; diff --git a/Tests/UnitTests/Core/Material/PropagatorMaterialAssignerTests.cpp b/Tests/UnitTests/Core/Material/PropagatorMaterialAssignerTests.cpp index 7c1c031fb4b..785e840da3f 100644 --- a/Tests/UnitTests/Core/Material/PropagatorMaterialAssignerTests.cpp +++ b/Tests/UnitTests/Core/Material/PropagatorMaterialAssignerTests.cpp @@ -90,7 +90,8 @@ BOOST_AUTO_TEST_CASE(FindSurfaceIntersectionsTrackingGeometry) { auto vCylinderTop = std::make_shared(rMin, rMax, 110.); auto topVolume = std::make_shared( - Transform3::Identity(), vCylinderTop, volumes, "TopVolume"); + Transform3::Identity(), vCylinderTop, nullptr, nullptr, volumes, + MutableTrackingVolumeVector{}, "TopVolume"); auto tGeometry = std::make_shared(topVolume); diff --git a/Tests/UnitTests/Core/Propagator/CovarianceEngineTests.cpp b/Tests/UnitTests/Core/Propagator/CovarianceEngineTests.cpp index 7dbe9b979d9..a7cd0e2de39 100644 --- a/Tests/UnitTests/Core/Propagator/CovarianceEngineTests.cpp +++ b/Tests/UnitTests/Core/Propagator/CovarianceEngineTests.cpp @@ -110,12 +110,10 @@ BOOST_AUTO_TEST_CASE(covariance_engine_test) { BOOST_CHECK_EQUAL(parameters, startParameters); // Produce a curvilinear state without covariance matrix - auto covarianceBefore = covariance; auto curvResult = detail::curvilinearState( covariance, jacobian, transportJacobian, derivatives, boundToFreeJacobian, parameters, particleHypothesis, false, 1337.); - BOOST_CHECK(std::get<0>(curvResult).covariance().has_value()); - BOOST_CHECK_EQUAL(*(std::get<0>(curvResult).covariance()), covarianceBefore); + BOOST_CHECK(!std::get<0>(curvResult).covariance().has_value()); BOOST_CHECK_EQUAL(std::get<2>(curvResult), 1337.); // Reset @@ -136,7 +134,7 @@ BOOST_AUTO_TEST_CASE(covariance_engine_test) { BOOST_CHECK_EQUAL(std::get<2>(curvResult), 1337.); // Produce a bound state without covariance matrix - covarianceBefore = covariance; + auto covarianceBefore = covariance; auto boundResult = detail::boundState(tgContext, *surface, covariance, jacobian, transportJacobian, derivatives, boundToFreeJacobian, diff --git a/Tests/UnitTests/Core/TrackFitting/Gx2fTests.cpp b/Tests/UnitTests/Core/TrackFitting/Gx2fTests.cpp index 52b836d0fc7..a896d7b96a2 100644 --- a/Tests/UnitTests/Core/TrackFitting/Gx2fTests.cpp +++ b/Tests/UnitTests/Core/TrackFitting/Gx2fTests.cpp @@ -802,5 +802,116 @@ BOOST_AUTO_TEST_CASE(NotEnoughMeasurements) { ACTS_INFO("*** Test: NotEnoughMeasurements -- Finish"); } + +BOOST_AUTO_TEST_CASE(FindHoles) { + ACTS_INFO("*** Test: FindHoles -- Start"); + + std::default_random_engine rng(42); + + ACTS_DEBUG("Create the detector"); + // const std::size_t nSurfaces = 7; + const std::size_t nSurfaces = 8; + Detector detector; + detector.geometry = makeToyDetector(geoCtx, nSurfaces); + + ACTS_DEBUG("Set the start parameters for measurement creation and fit"); + const auto parametersMeasurements = makeParameters(); + const auto startParametersFit = makeParameters( + 7_mm, 11_mm, 15_mm, 42_ns, 10_degree, 80_degree, 1_GeV, 1_e); + + ACTS_DEBUG("Create the measurements"); + using SimPropagator = + Acts::Propagator; + const SimPropagator simPropagator = makeStraightPropagator(detector.geometry); + const auto measurements = + createMeasurements(simPropagator, geoCtx, magCtx, parametersMeasurements, + resMapAllPixel, rng); + auto sourceLinks = prepareSourceLinks(measurements.sourceLinks); + ACTS_VERBOSE("sourceLinks.size() [before] = " << sourceLinks.size()); + + // We remove the first measurement in the list. This does not create a hole. + sourceLinks.erase(std::next(sourceLinks.begin(), 0)); + ACTS_VERBOSE( + "sourceLinks.size() [after first erase] = " << sourceLinks.size()); + + // We remove the last measurement in the list. This does not create a hole. + sourceLinks.pop_back(); + ACTS_VERBOSE("sourceLinks.size() [after pop] = " << sourceLinks.size()); + + // We remove the second to last measurement in the list. This effectivly + // creates a hole on that surface. + const std::size_t indexHole = sourceLinks.size() - 2; + ACTS_VERBOSE("Remove measurement " << indexHole); + sourceLinks.erase(std::next(sourceLinks.begin(), indexHole)); + ACTS_VERBOSE("sourceLinks.size() [after second-to-last erase]= " + << sourceLinks.size()); + + // We removed 3 measurements + // const std::size_t nMeasurements = nSurfaces - 2; + const std::size_t nMeasurements = nSurfaces - 3; + BOOST_REQUIRE_EQUAL(sourceLinks.size(), nMeasurements); + + ACTS_DEBUG("Set up the fitter"); + const Surface* rSurface = ¶metersMeasurements.referenceSurface(); + + using RecoStepper = EigenStepper<>; + const auto recoPropagator = + makeConstantFieldPropagator(detector.geometry, 0_T); + + using RecoPropagator = decltype(recoPropagator); + using Gx2Fitter = + Experimental::Gx2Fitter; + const Gx2Fitter fitter(recoPropagator, gx2fLogger->clone()); + + Experimental::Gx2FitterExtensions extensions; + extensions.calibrator + .connect<&testSourceLinkCalibrator>(); + TestSourceLink::SurfaceAccessor surfaceAccessor{*detector.geometry}; + extensions.surfaceAccessor + .connect<&TestSourceLink::SurfaceAccessor::operator()>(&surfaceAccessor); + + const Experimental::Gx2FitterOptions gx2fOptions( + geoCtx, magCtx, calCtx, extensions, PropagatorPlainOptions(), rSurface, + false, false, FreeToBoundCorrection(false), 20, true, 1e-5); + + Acts::TrackContainer tracks{Acts::VectorTrackContainer{}, + Acts::VectorMultiTrajectory{}}; + + ACTS_DEBUG("Fit the track"); + ACTS_VERBOSE("startParameter unsmeared:\n" << parametersMeasurements); + ACTS_VERBOSE("startParameter fit:\n" << startParametersFit); + const auto res = fitter.fit(sourceLinks.begin(), sourceLinks.end(), + startParametersFit, gx2fOptions, tracks); + + BOOST_REQUIRE(res.ok()); + + const auto& track = *res; + + // -1, because the index starts at 0 + // -2, because the first and the last surface are not part of the track + BOOST_CHECK_EQUAL(track.tipIndex(), nSurfaces - 1 - 2); + BOOST_CHECK(track.hasReferenceSurface()); + + // Track quantities + CHECK_CLOSE_ABS(track.chi2(), 6.5, 2.); + BOOST_CHECK_EQUAL(track.nDoF(), 10u); + BOOST_CHECK_EQUAL(track.nHoles(), 1u); + BOOST_CHECK_EQUAL(track.nMeasurements(), nMeasurements); + BOOST_CHECK_EQUAL(track.nSharedHits(), 0u); + BOOST_CHECK_EQUAL(track.nOutliers(), 0u); + + // Parameters + // We need quite coarse checks here, since on different builds + // the created measurements differ in the randomness + BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc0], -11., 7e0); + BOOST_CHECK_CLOSE(track.parameters()[eBoundLoc1], -15., 6e0); + BOOST_CHECK_CLOSE(track.parameters()[eBoundPhi], 1e-5, 1e3); + BOOST_CHECK_CLOSE(track.parameters()[eBoundTheta], M_PI / 2, 1e-3); + BOOST_CHECK_EQUAL(track.parameters()[eBoundQOverP], 1); + BOOST_CHECK_CLOSE(track.parameters()[eBoundTime], 12591.2832360000, 1e-6); + BOOST_CHECK_CLOSE(track.covariance().determinant(), 4.7e-28, 2e0); + + ACTS_INFO("*** Test: FindHoles -- Finish"); +} BOOST_AUTO_TEST_SUITE_END() } // namespace Acts::Test diff --git a/Tests/UnitTests/Core/Utilities/GridTests.cpp b/Tests/UnitTests/Core/Utilities/GridTests.cpp index 55f57bd28aa..4f7ac787b04 100644 --- a/Tests/UnitTests/Core/Utilities/GridTests.cpp +++ b/Tests/UnitTests/Core/Utilities/GridTests.cpp @@ -1189,9 +1189,9 @@ BOOST_AUTO_TEST_CASE(neighborhood) { * |----|----|----|----|----| * 3 | 22 | 23 | 24 | 25 | 26 | * |----|----|----|----|----| - * 4 | 29 | 30 | 31 | 32 | 33 | + * 4 | 29 | 30 | 31 | 32 | 33 | * |----|----|----|----|----| - * 5 | 36 | 37 | 38 | 39 | 40 | + * 5 | 36 | 37 | 38 | 39 | 40 | * |------------------------| */ // clang-format on @@ -1291,7 +1291,7 @@ BOOST_AUTO_TEST_CASE(closestPoints) { == bins_t({8, 9, 15, 16})); BOOST_CHECK(g2Op.closestPointsIndices(Point({{0.95, 0.95}})).collectVector() == bins_t({75})); - + // @TODO: 3D checks would also be nice /* @@ -1303,19 +1303,19 @@ BOOST_AUTO_TEST_CASE(closestPoints) { * |----|----|----|----|----| * 3 | 22 | 23 | 24 | 25 | 26 | * |----|----|----|----|----| - * 4 | 29 | 30 | 31 | 32 | 33 | + * 4 | 29 | 30 | 31 | 32 | 33 | * |----|----|----|----|----| - * 5 | 36 | 37 | 38 | 39 | 40 | + * 5 | 36 | 37 | 38 | 39 | 40 | * |------------------------| - * 6 | 43 | 44 | 45 | 46 | 47 | + * 6 | 43 | 44 | 45 | 46 | 47 | * |------------------------| - * 7 | 50 | 51 | 52 | 53 | 54 | + * 7 | 50 | 51 | 52 | 53 | 54 | * |------------------------| - * 8 | 57 | 58 | 59 | 60 | 61 | + * 8 | 57 | 58 | 59 | 60 | 61 | * |------------------------| - * 9 | 64 | 65 | 66 | 67 | 68 | + * 9 | 64 | 65 | 66 | 67 | 68 | * |------------------------| - * 10 | 71 | 72 | 73 | 74 | 75 | + * 10 | 71 | 72 | 73 | 74 | 75 | * |------------------------| * 77 78 79 80 81 82 83 */ diff --git a/Tests/UnitTests/Core/Utilities/LoggerTests.cpp b/Tests/UnitTests/Core/Utilities/LoggerTests.cpp index e6451b547cf..b8e11273df7 100644 --- a/Tests/UnitTests/Core/Utilities/LoggerTests.cpp +++ b/Tests/UnitTests/Core/Utilities/LoggerTests.cpp @@ -6,8 +6,6 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -/// @file Logger_tests.cpp - #include #include "Acts/Utilities/Logger.hpp" diff --git a/Tests/UnitTests/Core/Utilities/ResultTests.cpp b/Tests/UnitTests/Core/Utilities/ResultTests.cpp index 73bc6f4659a..c5759703ed4 100644 --- a/Tests/UnitTests/Core/Utilities/ResultTests.cpp +++ b/Tests/UnitTests/Core/Utilities/ResultTests.cpp @@ -288,7 +288,6 @@ BOOST_AUTO_TEST_CASE(CopyBehaviour) { } Result void_res_func(int b) { - (void)b; if (b > 5) { return MyError::SomethingElse; } diff --git a/Tests/UnitTests/Core/Visualization/Visualization3DTester.hpp b/Tests/UnitTests/Core/Visualization/Visualization3DTester.hpp index 84f4c2046c2..6e44e73d459 100644 --- a/Tests/UnitTests/Core/Visualization/Visualization3DTester.hpp +++ b/Tests/UnitTests/Core/Visualization/Visualization3DTester.hpp @@ -120,7 +120,7 @@ struct PlyElement { /// /// @return a vector of failure messages inline static std::vector testPlyString(const std::string& tString, - bool triMesh = false) { + bool /*triMesh*/ = false) { std::vector errorStrings; const std::string w = "[ Invalid ply : "; @@ -219,8 +219,6 @@ inline static std::vector testPlyString(const std::string& tString, } } - (void)triMesh; - return errorStrings; } diff --git a/docs/conf.py b/docs/conf.py index 1cfc6fc39b3..fa9d4424d8c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -2,12 +2,10 @@ import os import sys -import re import subprocess from pathlib import Path import shutil import datetime -from typing import List, Tuple # check if we are running on readthedocs.org on_readthedocs = os.environ.get("READTHEDOCS", None) == "True" @@ -68,6 +66,8 @@ r"https://pythia.org.*", r"https://lcginfo.cern.ch/.*", r"https://.*\.?intel.com/.*", + r"https://www.conventionalcommits.org/.*", + r"https://cds.cern.ch/record/.*", ] # -- Options for HTML output -------------------------------------------------- diff --git a/docs/examples/howto/material_mapping.rst b/docs/examples/howto/material_mapping.rst index 2b73acf47a6..87a6c8ad699 100644 --- a/docs/examples/howto/material_mapping.rst +++ b/docs/examples/howto/material_mapping.rst @@ -49,7 +49,6 @@ Ideally the following options should be used in the python file: outputObj=False, outputCsv=False, outputJson=True, - outputRoot=False, ): For the following example we will be remapping the material of the ODD, we will thus get our detector via the following line: