Skip to content

Commit

Permalink
feat: unit tests for MergeTracks
Browse files Browse the repository at this point in the history
fix: add the test
  • Loading branch information
c-dilks committed Jun 1, 2023
1 parent 78b70d0 commit e04cac5
Show file tree
Hide file tree
Showing 2 changed files with 179 additions and 3 deletions.
8 changes: 5 additions & 3 deletions src/tests/algorithms_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ get_filename_component(TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME)

# These tests can use the Catch2-provided main
add_executable(${TEST_NAME}
calorimetry_CalorimeterIslandCluster.cc
)
calorimetry_CalorimeterIslandCluster.cc
pid_MergeTracks.cc
)

# Explicit linking to podio::podio is needed due to https://github.com/JeffersonLab/JANA2/issues/151
target_link_libraries(${TEST_NAME} PRIVATE Catch2::Catch2WithMain algorithms_calorimetry_library podio::podio podio::podioRootIO)
target_link_libraries(${TEST_NAME} PRIVATE Catch2::Catch2WithMain algorithms_calorimetry_library algorithms_pid_library podio::podio podio::podioRootIO)

# Install executable
install(TARGETS ${TEST_NAME} DESTINATION bin)
Expand Down
174 changes: 174 additions & 0 deletions src/tests/algorithms_test/pid_MergeTracks.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright (C) 2023, Christopher Dilks

#include <cmath>

#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_floating_point.hpp>
#include <spdlog/logger.h>

#include <algorithms/pid/MergeTracks.cc>

TEST_CASE("the PID MergeTracks algorithm runs", "[MergeTracks]") {
eicrecon::MergeTracks algo;

// initialize algorithm
//----------------------------------------------------------
std::shared_ptr<spdlog::logger> logger = spdlog::default_logger()->clone("MergeTracks");
logger->set_level(spdlog::level::debug);
algo.AlgorithmInit(logger);

// helper functions and objects
//----------------------------------------------------------
const float EPSILON = 1e-5;

struct Point {
decltype(edm4eic::TrackPoint::position) position;
decltype(edm4eic::TrackPoint::momentum) momentum;
decltype(edm4eic::TrackPoint::time) time;
};

auto make_track = [] (auto& coll, std::vector<Point> points) {
auto trk = coll->create();
for(auto& point : points) {
edm4eic::TrackPoint trk_point;
trk_point.position = point.position;
trk_point.momentum = point.momentum;
trk_point.time = point.time;
trk.addToPoints(trk_point);
}
};

auto track_length = [] (auto trk) {
auto a = trk.getPoints(0);
auto b = trk.getPoints(trk.points_size()-1);
return std::hypot(
a.position.x - b.position.x,
a.position.y - b.position.y,
a.position.z - b.position.z
);
};

// inputs
//----------------------------------------------------------
/*
| | collection0 | collection1 | collection2 |
| ------ | ----------- | ----------- | ----------- |
| track0 | horizontal | horizontal | horizontal |
| track1 | horizontal | empty | one point |
| track2 | vertical | horizontal | vertical |
| track3 | horizontal | horizontal | horizontal | // time disordered
*/

// collections
auto collection0 = std::make_unique<edm4eic::TrackSegmentCollection>();
auto collection1 = std::make_unique<edm4eic::TrackSegmentCollection>();
auto collection2 = std::make_unique<edm4eic::TrackSegmentCollection>();

// track0
make_track(collection0, { // horizontal
{ {0, 0, 0}, {1, 0, 0}, 1 }, // { position, momentum, time }
{ {1, 0, 0}, {1, 0, 0}, 2 }
});
make_track(collection1, { // horizontal
{ {2, 0, 0}, {1, 0, 0}, 3 },
{ {3, 0, 0}, {1, 0, 0}, 4 }
});
make_track(collection2, { // horizontal
{ {4, 0, 0}, {1, 0, 0}, 5 },
{ {5, 0, 0}, {1, 0, 0}, 6 }
});

// track1
make_track(collection0, { // horizontal
{ {0, 0, 0}, {1, 0, 0}, 1 },
{ {1, 0, 0}, {1, 0, 0}, 2 }
});
make_track(collection1, { // empty
{ }
});
make_track(collection2, { // horizontal
{ {2, 0, 0}, {1, 0, 0}, 3 },
{ {3, 0, 0}, {1, 0, 0}, 4 }
});

// track2
make_track(collection0, { // vertical
{ {0, 0, 0}, {0, 1, 0}, 1 },
{ {0, 1, 0}, {0, 1, 0}, 2 }
});
make_track(collection1, { // horizontal
{ {0, 1, 0}, {1, 0, 0}, 3 },
{ {1, 1, 0}, {1, 0, 0}, 4 }
});
make_track(collection2, { // vertical
{ {1, 1, 0}, {0, 1, 0}, 5 },
{ {1, 2, 0}, {0, 1, 0}, 6 }
});

// track3
make_track(collection0, { // horizontal
{ {1, 0, 0}, {1, 0, 0}, 2 },
{ {0, 0, 0}, {1, 0, 0}, 1 }
});
make_track(collection1, { // horizontal
{ {3, 0, 0}, {1, 0, 0}, 4 },
{ {4, 0, 0}, {1, 0, 0}, 5 }
});
make_track(collection2, { // horizontal
{ {5, 0, 0}, {1, 0, 0}, 6 },
{ {2, 0, 0}, {1, 0, 0}, 3 }
});

// tests
//----------------------------------------------------------

SECTION("merge tracks from 1 collection") {
// run algorithm
std::vector<const edm4eic::TrackSegmentCollection*> colls = { collection0.get() };
auto trks = algo.AlgorithmProcess(colls);
// input collection(s) size == output collection size
REQUIRE(trks->size() == colls.front()->size());
// track length: from endpoints
REQUIRE_THAT( track_length(trks->at(0)), Catch::Matchers::WithinAbs(1, EPSILON) );
REQUIRE_THAT( track_length(trks->at(1)), Catch::Matchers::WithinAbs(1, EPSILON) );
REQUIRE_THAT( track_length(trks->at(2)), Catch::Matchers::WithinAbs(1, EPSILON) );
REQUIRE_THAT( track_length(trks->at(3)), Catch::Matchers::WithinAbs(1, EPSILON) );
// track length: from algorithm // FIXME when implemented in `MergeTracks`
for(const auto& trk : *trks)
REQUIRE_THAT( trk.getLength(), Catch::Matchers::WithinAbs(0, EPSILON) );
}

SECTION("merge tracks from 2 collections") {
// run algorithm
std::vector<const edm4eic::TrackSegmentCollection*> colls = { collection0.get(), collection1.get() };
auto trks = algo.AlgorithmProcess(colls);
// input collection(s) size == output collection size
REQUIRE(trks->size() == colls.front()->size());
// track length: from endpoints
REQUIRE_THAT( track_length(trks->at(0)), Catch::Matchers::WithinAbs(3, EPSILON) );
REQUIRE_THAT( track_length(trks->at(1)), Catch::Matchers::WithinAbs(1, EPSILON) );
REQUIRE_THAT( track_length(trks->at(2)), Catch::Matchers::WithinAbs(std::hypot(1,1), EPSILON) );
REQUIRE_THAT( track_length(trks->at(3)), Catch::Matchers::WithinAbs(4, EPSILON) );
// track length: from algorithm // FIXME when implemented in `MergeTracks`
for(const auto& trk : *trks)
REQUIRE_THAT( trk.getLength(), Catch::Matchers::WithinAbs(0, EPSILON) );
}

SECTION("merge tracks from 3 collections") {
// run algorithm
std::vector<const edm4eic::TrackSegmentCollection*> colls = { collection0.get(), collection1.get(), collection2.get() };
auto trks = algo.AlgorithmProcess(colls);
// input collection(s) size == output collection size
REQUIRE(trks->size() == colls.front()->size());
// track length: from endpoints
REQUIRE_THAT( track_length(trks->at(0)), Catch::Matchers::WithinAbs(5, EPSILON) );
REQUIRE_THAT( track_length(trks->at(1)), Catch::Matchers::WithinAbs(3, EPSILON) );
REQUIRE_THAT( track_length(trks->at(2)), Catch::Matchers::WithinAbs(std::hypot(1,2), EPSILON) );
REQUIRE_THAT( track_length(trks->at(3)), Catch::Matchers::WithinAbs(5, EPSILON) );
// track length: from algorithm // FIXME when implemented in `MergeTracks`
for(const auto& trk : *trks)
REQUIRE_THAT( trk.getLength(), Catch::Matchers::WithinAbs(0, EPSILON) );
}

}

0 comments on commit e04cac5

Please sign in to comment.