Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: move spline to helper in Visualization #3950

Merged
merged 9 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
53 changes: 53 additions & 0 deletions Core/include/Acts/Visualization/Interpolation3D.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// This file is part of the ACTS project.
//
// Copyright (C) 2016 CERN for the benefit of the ACTS project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Definitions/Algebra.hpp"

#include <unsupported/Eigen/Splines>
asalzburger marked this conversation as resolved.
Show resolved Hide resolved

namespace Acts::Interpolation3D {

/// @brief Helper function to interpolate points using a spline
/// from Eigen
///
/// @tparam input_vector_type
/// @param inputs input vector points
/// @param nPoints number of interpolation points
///
/// @return std::vector<Acts::Vector3> interpolated points
template <typename input_vector_type>
std::vector<Acts::Vector3> spline(const std::vector<input_vector_type>& inputs,
asalzburger marked this conversation as resolved.
Show resolved Hide resolved
std::size_t nPoints) {
std::vector<Acts::Vector3> output;
asalzburger marked this conversation as resolved.
Show resolved Hide resolved

if (nPoints < 2) {
// No interpolation done return simply the output vector
for (const auto& input : inputs) {
output.push_back(input.template head<3>());
}

asalzburger marked this conversation as resolved.
Show resolved Hide resolved
} else {
Eigen::MatrixXd points(3, inputs.size());
for (std::size_t i = 0; i < inputs.size(); ++i) {
points.col(i) = inputs[i].template head<3>().transpose();
}
Eigen::Spline<double, 3> spline3D =
Eigen::SplineFitting<Eigen::Spline<double, 3>>::Interpolate(points, 2);

double step = 1. / (nPoints - 1);
for (std::size_t i = 0; i < nPoints; ++i) {
double t = i * step;
output.push_back(spline3D(t));
}
}
return output;
}

} // namespace Acts::Interpolation3D
46 changes: 3 additions & 43 deletions Examples/Io/Obj/src/ObjSimHitWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Definitions/Common.hpp"
#include "Acts/Geometry/GeometryIdentifier.hpp"
#include "Acts/Visualization/Interpolation3D.hpp"
#include "ActsExamples/EventData/SimHit.hpp"
#include "ActsExamples/Framework/AlgorithmContext.hpp"
#include "ActsExamples/Utilities/Paths.hpp"
Expand All @@ -22,47 +23,6 @@
#include <unordered_map>
#include <vector>

#include <unsupported/Eigen/Splines>

namespace {

/// @brief Helper function to interpolate points
///
/// @tparam input_vector_type
/// @param inputs input vector points
/// @param nPoints number of interpolation points
///
/// @return std::vector<Acts::Vector3> interpolated points
template <typename input_vector_type>
std::vector<Acts::Vector3> interpolatedPoints(
const std::vector<input_vector_type>& inputs, std::size_t nPoints) {
std::vector<Acts::Vector3> output;

if (nPoints < 2) {
// No interpolation done return simply the output vector
for (const auto& input : inputs) {
output.push_back(input.template head<3>());
}

} else {
Eigen::MatrixXd points(3, inputs.size());
for (std::size_t i = 0; i < inputs.size(); ++i) {
points.col(i) = inputs[i].template head<3>().transpose();
}
Eigen::Spline<double, 3> spline3D =
Eigen::SplineFitting<Eigen::Spline<double, 3>>::Interpolate(points, 2);

double step = 1. / (nPoints - 1);
for (std::size_t i = 0; i < nPoints; ++i) {
double t = i * step;
output.push_back(spline3D(t));
}
}
return output;
}

} // namespace

ActsExamples::ObjSimHitWriter::ObjSimHitWriter(
const ActsExamples::ObjSimHitWriter::Config& config,
Acts::Logging::Level level)
Expand Down Expand Up @@ -159,8 +119,8 @@ ActsExamples::ProcessCode ActsExamples::ObjSimHitWriter::writeT(
trajectory.push_back(hit.template head<3>());
}
} else {
trajectory =
interpolatedPoints(pHits, pHits.size() * m_cfg.nInterpolatedPoints);
trajectory = Acts::Interpolation3D::spline(
pHits, pHits.size() * m_cfg.nInterpolatedPoints);
asalzburger marked this conversation as resolved.
Show resolved Hide resolved
}

osTrajectory << "o particle_trajectory_" << pId << std::endl;
Expand Down
1 change: 1 addition & 0 deletions Tests/UnitTests/Core/Visualization/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
add_unittest(Visualization3D Visualization3DTests.cpp)
add_unittest(EventDataView3D EventDataView3DTests.cpp)
add_unittest(Interpolation3D Interpolation3DTests.cpp)
add_unittest(PrimitivesView3D PrimitivesView3DTests.cpp)
add_unittest(SurfaceView3D SurfaceView3DTests.cpp)
add_unittest(TrackingGeometryView3D TrackingGeometryView3DTests.cpp)
Expand Down
51 changes: 51 additions & 0 deletions Tests/UnitTests/Core/Visualization/Interpolation3DTests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// This file is part of the ACTS project.
//
// Copyright (C) 2016 CERN for the benefit of the ACTS project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

#include <boost/test/unit_test.hpp>
#include <numbers>

#include "Acts/Visualization/Interpolation3D.hpp"
#include "Acts/Tests/CommonHelpers/FloatComparisons.hpp"

namespace Acts::Test {

BOOST_AUTO_TEST_SUITE(Visualization)

BOOST_AUTO_TEST_CASE(SplineInterpolation) {

/// Define the input vector
double R = 10.;
std::vector<Acts::Vector3> inputs;
for (double phi = 0; phi < 2 * std::numbers::pi; phi += std::numbers::pi / 4) {
inputs.push_back(Acts::Vector3(R * cos(phi), R * sin(phi), 0.));
}

// Interpolate the points options
std::vector<Acts::Vector3> trajectory;

// (0) - nothing happens
trajectory = Acts::Interpolation3D::spline(inputs, 1);
// Check input and output size are the same
BOOST_CHECK_EQUAL(trajectory.size(), inputs.size());

// (1) - interpolate between the points with 12 points in total
trajectory = Acts::Interpolation3D::spline(inputs, 12);
// Check the output size is correct
BOOST_CHECK_EQUAL(trajectory.size(), 12);

for (const auto& point : trajectory) {
// Check the interpolated points are on the circle
// with a tolerance of course
CHECK_CLOSE_ABS(point.norm(), R, 0.1);
}
asalzburger marked this conversation as resolved.
Show resolved Hide resolved

}

BOOST_AUTO_TEST_SUITE_END()

} // namespace Acts::Test
Loading