Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ghcr.io/acts-project/spack-container:24.1.0_linux-ubuntu26.04_gcc-15.2.0_cxx20
FROM ghcr.io/acts-project/spack-container:24.4.0_linux-ubuntu26.04_gcc-15.2.0_cxx20

RUN apt-get update && apt-get install -y clangd vim

Expand Down
2 changes: 1 addition & 1 deletion .github/actions/dependencies/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ inputs:
DEPENDENCY_TAG:
description: 'Dependency tag to pull from'
required: false
default: 'v24.1.0'
default: 'v24.4.0'
full_install:
description: 'Whether to do a full dependency installation including Geant4 datasets and Python packages'
required: false
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ jobs:
compiler: g++
flavor: cuda13
# Flavors need v24.0.0 or newer.
DEPENDENCY_TAG: v24.1.0
DEPENDENCY_TAG: v24.4.0
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
env_file: .env

Expand Down Expand Up @@ -624,7 +624,7 @@ jobs:
compiler: g++
flavor: cuda13
# Flavors need v24.0.0 or newer.
DEPENDENCY_TAG: v24.1.0
DEPENDENCY_TAG: v24.4.0
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
env_file: .env

Expand Down Expand Up @@ -690,7 +690,7 @@ jobs:
compiler: g++
flavor: cuda13
# Flavors need v24.0.0 or newer.
DEPENDENCY_TAG: v24.1.0
DEPENDENCY_TAG: v24.4.0
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
env_file: .env

Expand Down Expand Up @@ -758,7 +758,7 @@ jobs:
compiler: g++
flavor: cuda13
# Flavors need v24.0.0 or newer.
DEPENDENCY_TAG: v24.1.0
DEPENDENCY_TAG: v24.4.0
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
env_file: .env

Expand Down Expand Up @@ -832,7 +832,7 @@ jobs:
compiler: g++
flavor: cuda13
# Flavors need v24.0.0 or newer.
DEPENDENCY_TAG: v24.1.0
DEPENDENCY_TAG: v24.4.0
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
env_file: .env

Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/detray.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ jobs:
with:
compiler: g++
# Flavors need v24.0.0 or newer.
DEPENDENCY_TAG: v24.1.0
DEPENDENCY_TAG: v24.4.0
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
env_file: .env

Expand Down Expand Up @@ -247,7 +247,7 @@ jobs:
compiler: g++
flavor: ${{ matrix.PLATFORM.FLAVOR }}
# Flavors need v24.0.0 or newer.
DEPENDENCY_TAG: v24.1.0
DEPENDENCY_TAG: v24.4.0
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
env_file: .env

Expand Down Expand Up @@ -320,7 +320,7 @@ jobs:
compiler: g++
flavor: cuda13
# Flavors need v24.0.0 or newer.
DEPENDENCY_TAG: v24.1.0
DEPENDENCY_TAG: v24.4.0
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
env_file: .env

Expand Down Expand Up @@ -448,7 +448,7 @@ jobs:
with:
compiler: g++
flavor: cuda13
DEPENDENCY_TAG: v24.1.0
DEPENDENCY_TAG: v24.4.0
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
env_file: .env

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/traccc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ jobs:
compiler: ${{ matrix.platform.compiler || 'g++' }}
flavor: ${{ matrix.platform.flavor }}
# Flavors need v24.0.0 or newer.
DEPENDENCY_TAG: v24.1.0
DEPENDENCY_TAG: v24.4.0
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
env_file: .env

Expand Down Expand Up @@ -287,7 +287,7 @@ jobs:
with:
compiler: g++
flavor: cuda13
DEPENDENCY_TAG: v24.1.0
DEPENDENCY_TAG: v24.4.0
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
env_file: .env

Expand Down
23 changes: 14 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ set(_acts_doxygen_version 1.9.4)
set(_acts_hepmc3_version 3.2.4)
set(_acts_nlohmanjson_version 3.11.3)
set(_acts_gbl_version 04.00.05)
set(_acts_mille_version 01.00.05)
set(_acts_mille_version 01.01.01)
set(_acts_mp2_version 05.01.05)
set(_acts_onnxruntime_version 1.12.0)
set(_acts_geomodel_version 6.8.0)
Expand All @@ -363,22 +363,27 @@ include(ActsExternSources)
if(ACTS_SETUP_BOOST)
# Enable both program_options and unit_test_framework to reduce complexity
# Also Cuda tests seem to use program_options
set(_acts_boost_components)
if(
ACTS_BUILD_ANALYSIS_APPS
OR ACTS_BUILD_UNITTESTS
OR ACTS_BUILD_INTEGRATIONTESTS
OR ACTS_BUILD_BENCHMARKS
)
find_package(
Boost
${_acts_boost_version}
REQUIRED
COMPONENTS program_options unit_test_framework
)
else()
find_package(Boost ${_acts_boost_version} REQUIRED COMPONENTS)
list(APPEND _acts_boost_components program_options unit_test_framework)
endif()

# Only the Mille plugin needs process/filesystem, and neither is part of
# every Boost installation (Boost.Process is a compiled library since Boost
# 1.88). The plugin reports if the one it needs is missing.
find_package(
Boost
${_acts_boost_version}
REQUIRED
COMPONENTS ${_acts_boost_components}
OPTIONAL_COMPONENTS process filesystem
)

if(Boost_VERSION VERSION_EQUAL "1.85.0")
set(_boost_version_severity WARNING)
if(ACTS_BUILD_EXAMPLES)
Expand Down
44 changes: 43 additions & 1 deletion Plugins/Mille/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ acts_add_library(
PluginMille
src/Helpers.cpp
src/ActsToMille.cpp
src/MillePedeSolver.cpp
src/MillePedeError.cpp
src/runChildProcess.cpp
ACTS_INCLUDE_FOLDER include/ActsPlugins
)

Expand All @@ -12,6 +15,45 @@ target_include_directories(
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

target_link_libraries(ActsPluginMille PUBLIC ActsAlignment Mille2)
# The solver runs `pede` as a child process via Boost.Process: the compiled
# library from Boost 1.88 on, the header-only v1 API (which builds on
# Boost.Filesystem) before that. Both are probed as optional components at the
# top level, since only this plugin needs them.
if(Boost_VERSION VERSION_GREATER_EQUAL 1.88.0)
set(_mille_boost_component process)
set(_mille_boost_reason "which is a compiled library since Boost 1.88")
else()
set(_mille_boost_component filesystem)
set(_mille_boost_reason "whose pre-1.88 API is built on Boost.Filesystem")
endif()

if(NOT TARGET Boost::${_mille_boost_component})
foreach(_component process filesystem)
if(TARGET Boost::${_component})
string(APPEND _mille_boost_found " ${_component}")
endif()
endforeach()
if(NOT _mille_boost_found)
set(_mille_boost_found " none of them")
endif()

message(
FATAL_ERROR
"The Mille plugin runs `pede` as a child process via Boost.Process, "
"${_mille_boost_reason}, so it needs the Boost "
"${_mille_boost_component} library. The Boost ${Boost_VERSION} "
"installation in ${Boost_DIR} provides:${_mille_boost_found}. Please "
"enable ${_mille_boost_component} in the Boost build (with spack: "
"`boost +${_mille_boost_component}`), or set "
"ACTS_BUILD_PLUGIN_MILLE=OFF."
)
endif()

# Boost is only used by the solver implementation, not by any public header
target_link_libraries(
ActsPluginMille
PUBLIC ActsAlignment Mille2
PRIVATE Boost::boost Boost::${_mille_boost_component}
)

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

#pragma once

#include <system_error>
#include <type_traits>

namespace ActsPlugins::ActsToMille {
/// Error codes for Millepede run
/// @ingroup errors
enum class MillePedeError {
InstallationNotFound = 1, // no valid install found
SteeringNotFound = 2, // steering file not found
SolverCrash = 3, // solver crashed
InvalidSolution = 4, // solver finished but the solution is invalid
SolutionNotReadable = 5, // solution file could not be read
};

/// @cond
/// Create error code from MillePedeError
/// @param e The error code enum value
/// @return Standard error code
std::error_code make_error_code(ActsToMille::MillePedeError e);
/// @endcond

} // namespace ActsPlugins::ActsToMille

namespace std {
// register with STL
template <>
struct is_error_code_enum<ActsPlugins::ActsToMille::MillePedeError>
: std::true_type {};
} // namespace std
107 changes: 107 additions & 0 deletions Plugins/Mille/include/ActsPlugins/Mille/MillePedeSolver.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// This file is part of the ACTS project.
//
// Copyright (C) 2016 CERN for the benefit of the ACTS project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

#pragma once
#include "Acts/Utilities/Logger.hpp"
#include "Acts/Utilities/Result.hpp"
#include "ActsPlugins/Mille/MillePedeError.hpp"

#include <filesystem>
#include <vector>

namespace ActsPlugins::ActsToMille {

/// class wrapping an external call to the 'pede' solver
/// program of the Millepede-II alignment toolkit.
class MillePedeSolver {
public:
/// @brief abstract summary of the exit codes returned by pede.
enum class mpExitStatus {
notFinishedOrCrashed, /// job is still running or crashed before exiting
nominalExit, /// nominal exit
tolerableWarnings, /// exit with tolerable warnings, considered ok
seriousWarnings, /// exit with serious warnings, should investigate
noSolution, /// exit without solution (usually: rank deficit)
aborted /// aborted due to errors
};

/// @brief configuration for running pede.
/// Currently, most details are delegated to the steering file syntax.
struct Config {
std::string steeringFile =
"pedeSteerMaster.txt"; /// steering file with run options
std::filesystem::path workDir = ""; /// directory to run in
std::vector<std::string> extraOpts = {}; /// extra CLI options
std::string resFileName =
""; /// destination for result file - if empty, keep original
std::string redirectStdout = ""; /// destination for the cout/cerr printout
/// from pede - if empty, send to parent
std::string logFileName =
""; /// destination for the log file - if empty, keep original
std::string histoFileName =
""; /// destination for the histogram file - if empty, keep original
std::string evFileName =
""; /// destination for the eigenvector file - if empty, keep original
};

/// @brief package the result of the alignment fit
struct mpResult {
int exitCode = -1; /// raw pede exit code
mpExitStatus exitStatus =
mpExitStatus::notFinishedOrCrashed; /// summary exit status
std::string exitMessage = ""; /// detailed exit message
std::filesystem::path resultsFile; /// file containing parameter results
std::filesystem::path logFile; /// log file
std::filesystem::path histoFile; /// file with validation histograms
std::filesystem::path evFile; /// file with eigenvectors
};

/// @brief constructor - nothing to do as minimal internal state carried
explicit MillePedeSolver(Acts::Logging::Level level = Acts::Logging::INFO)
: m_logger(Acts::getDefaultLogger("MillePedeSolver", level)) {}

/// @brief Runs the solving.
/// Can take some time for large fits.
/// Will invoke pede, await the exit, and parse
/// the output.
/// @param cfg: The configuration to use
Acts::Result<mpResult> solve(Config cfg) const;

private:
/// @brief translation of the detailed pede code to a summary status
/// Will translate the range of ~30 possible MP exit codes to a simplified
/// enum value that gives a high-level summary of the status.
/// @param theExitCode: The integer exit code found in the millepede.end file
static mpExitStatus interpretExit(int theExitCode);

/// @brief Reads the `millepede.end` file and parses its content
/// @param mpend: The file to read, assumed that the user has checked for existence before
/// @return a tuple containing the original integer exit code, a simplified exit status enum,
/// and the additional status message emitted by pede.
std::tuple<int, mpExitStatus, std::string> readDetailedExit(
const std::filesystem::path& mpend) const;

/// @brief Utility method to check if an output exists, copy it if the user requested a relocation,
/// and returns the final resolved output location, which will be:
/// - if the output does not exist: empty path
/// - if the output does exist and was not relocated: original location
/// - if the output does exist, and was relocated: user-specified location
/// - if the output does exist, was requested for relocation but the copy
/// failed: original location
/// @param originalLoc: Original expected location of the file
/// @param userLoc: Desired final location of the file. If empty, no copy will be made.
std::filesystem::path copyIfRequested(
const std::filesystem::path& originalLoc,
const std::filesystem::path& userLoc) const;

std::unique_ptr<const Acts::Logger> m_logger; /// logger

/// Private access to the logger
const Acts::Logger& logger() const { return *m_logger; }
};
} // namespace ActsPlugins::ActsToMille
Loading
Loading