Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-10-17 08:03:47

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2023, Christopher Dilks
0003 
0004 #include <algorithms/logger.h>
0005 #include <catch2/catch_test_macros.hpp>
0006 #include <catch2/matchers/catch_matchers.hpp>
0007 #include <catch2/matchers/catch_matchers_floating_point.hpp>
0008 #include <cmath>
0009 #include <edm4eic/TrackPoint.h>
0010 #include <edm4eic/TrackSegmentCollection.h>
0011 #include <edm4hep/Vector3f.h>
0012 #include <gsl/pointers>
0013 #include <memory>
0014 #include <vector>
0015 
0016 #include "algorithms/pid/MergeTracks.h"
0017 
0018 TEST_CASE("the PID MergeTracks algorithm runs", "[MergeTracks]") {
0019   eicrecon::MergeTracks algo("test");
0020 
0021   // initialize algorithm
0022   //----------------------------------------------------------
0023   algo.level(algorithms::LogLevel::kDebug);
0024   algo.init();
0025 
0026   // helper functions and objects
0027   //----------------------------------------------------------
0028   const float EPSILON = 1e-5;
0029 
0030   struct Point {
0031     decltype(edm4eic::TrackPoint::position) position;
0032     decltype(edm4eic::TrackPoint::momentum) momentum;
0033     decltype(edm4eic::TrackPoint::time) time;
0034   };
0035 
0036   auto make_track = [](auto& coll, std::vector<Point> points) {
0037     auto trk = coll->create();
0038     for (auto& point : points) {
0039       edm4eic::TrackPoint trk_point;
0040       trk_point.position = point.position;
0041       trk_point.momentum = point.momentum;
0042       trk_point.time     = point.time;
0043       trk.addToPoints(trk_point);
0044     }
0045   };
0046 
0047   auto track_length = [](auto trk) {
0048     auto a = trk.getPoints(0);
0049     auto b = trk.getPoints(trk.points_size() - 1);
0050     return std::hypot(a.position.x - b.position.x, a.position.y - b.position.y,
0051                       a.position.z - b.position.z);
0052   };
0053 
0054   // inputs
0055   //----------------------------------------------------------
0056   /*
0057      |        | collection0 | collection1 | collection2 |
0058      | ------ | ----------- | ----------- | ----------- |
0059      | track0 | horizontal  | horizontal  | horizontal  |
0060      | track1 | horizontal  | empty       | one point   |
0061      | track2 | vertical    | horizontal  | vertical    |
0062      | track3 | horizontal  | horizontal  | horizontal  | // time disordered
0063   */
0064 
0065   // collections
0066   auto collection0 = std::make_unique<edm4eic::TrackSegmentCollection>();
0067   auto collection1 = std::make_unique<edm4eic::TrackSegmentCollection>();
0068   auto collection2 = std::make_unique<edm4eic::TrackSegmentCollection>();
0069 
0070   // track0
0071   make_track(
0072       collection0,
0073       {                                                           // horizontal
0074        {.position = {0, 0, 0}, .momentum = {1, 0, 0}, .time = 1}, // { position, momentum, time }
0075        {.position = {1, 0, 0}, .momentum = {1, 0, 0}, .time = 2}});
0076   make_track(collection1, {// horizontal
0077                            {.position = {2, 0, 0}, .momentum = {1, 0, 0}, .time = 3},
0078                            {.position = {3, 0, 0}, .momentum = {1, 0, 0}, .time = 4}});
0079   make_track(collection2, {// horizontal
0080                            {.position = {4, 0, 0}, .momentum = {1, 0, 0}, .time = 5},
0081                            {.position = {5, 0, 0}, .momentum = {1, 0, 0}, .time = 6}});
0082 
0083   // track1
0084   make_track(collection0, {// horizontal
0085                            {.position = {0, 0, 0}, .momentum = {1, 0, 0}, .time = 1},
0086                            {.position = {1, 0, 0}, .momentum = {1, 0, 0}, .time = 2}});
0087   make_track(collection1, {// empty
0088                            {}});
0089   make_track(collection2, {// one point
0090                            {.position = {2, 0, 0}, .momentum = {1, 0, 0}, .time = 3}});
0091 
0092   // track2
0093   make_track(collection0, {// vertical
0094                            {.position = {0, 0, 0}, .momentum = {0, 1, 0}, .time = 1},
0095                            {.position = {0, 1, 0}, .momentum = {0, 1, 0}, .time = 2}});
0096   make_track(collection1, {// horizontal
0097                            {.position = {0, 1, 0}, .momentum = {1, 0, 0}, .time = 3},
0098                            {.position = {1, 1, 0}, .momentum = {1, 0, 0}, .time = 4}});
0099   make_track(collection2, {// vertical
0100                            {.position = {1, 1, 0}, .momentum = {0, 1, 0}, .time = 5},
0101                            {.position = {1, 2, 0}, .momentum = {0, 1, 0}, .time = 6}});
0102 
0103   // track3
0104   make_track(collection0, {// horizontal
0105                            {.position = {1, 0, 0}, .momentum = {1, 0, 0}, .time = 2},
0106                            {.position = {0, 0, 0}, .momentum = {1, 0, 0}, .time = 1}});
0107   make_track(collection1, {// horizontal
0108                            {.position = {3, 0, 0}, .momentum = {1, 0, 0}, .time = 4},
0109                            {.position = {4, 0, 0}, .momentum = {1, 0, 0}, .time = 5}});
0110   make_track(collection2, {// horizontal
0111                            {.position = {5, 0, 0}, .momentum = {1, 0, 0}, .time = 6},
0112                            {.position = {2, 0, 0}, .momentum = {1, 0, 0}, .time = 3}});
0113 
0114   // tests
0115   //----------------------------------------------------------
0116 
0117   SECTION("merge tracks from 1 collection") {
0118     // run algorithm
0119     std::vector<gsl::not_null<const edm4eic::TrackSegmentCollection*>> colls = {collection0.get()};
0120     // create output collection
0121     auto trks = std::make_unique<edm4eic::TrackSegmentCollection>();
0122     algo.process({colls}, {trks.get()});
0123     // input collection(s) size == output collection size
0124     REQUIRE(trks->size() == colls.front()->size());
0125     // track length: from endpoints
0126     REQUIRE_THAT(track_length(trks->at(0)), Catch::Matchers::WithinAbs(1, EPSILON));
0127     REQUIRE_THAT(track_length(trks->at(1)), Catch::Matchers::WithinAbs(1, EPSILON));
0128     REQUIRE_THAT(track_length(trks->at(2)), Catch::Matchers::WithinAbs(1, EPSILON));
0129     REQUIRE_THAT(track_length(trks->at(3)), Catch::Matchers::WithinAbs(1, EPSILON));
0130     // track length: from algorithm // FIXME when implemented in `MergeTracks`
0131     for (const auto& trk : *trks) {
0132       REQUIRE_THAT(trk.getLength(), Catch::Matchers::WithinAbs(0, EPSILON));
0133     }
0134   }
0135 
0136   SECTION("merge tracks from 2 collections") {
0137     // run algorithm
0138     std::vector<gsl::not_null<const edm4eic::TrackSegmentCollection*>> colls = {collection0.get(),
0139                                                                                 collection1.get()};
0140     auto trks = std::make_unique<edm4eic::TrackSegmentCollection>();
0141     algo.process({colls}, {trks.get()});
0142     // input collection(s) size == output collection size
0143     REQUIRE(trks->size() == colls.front()->size());
0144     // track length: from endpoints
0145     REQUIRE_THAT(track_length(trks->at(0)), Catch::Matchers::WithinAbs(3, EPSILON));
0146     REQUIRE_THAT(track_length(trks->at(1)), Catch::Matchers::WithinAbs(1, EPSILON));
0147     REQUIRE_THAT(track_length(trks->at(2)), Catch::Matchers::WithinAbs(std::hypot(1, 1), EPSILON));
0148     REQUIRE_THAT(track_length(trks->at(3)), Catch::Matchers::WithinAbs(4, EPSILON));
0149     // track length: from algorithm // FIXME when implemented in `MergeTracks`
0150     for (const auto& trk : *trks) {
0151       REQUIRE_THAT(trk.getLength(), Catch::Matchers::WithinAbs(0, EPSILON));
0152     }
0153   }
0154 
0155   SECTION("merge tracks from 3 collections") {
0156     // run algorithm
0157     std::vector<gsl::not_null<const edm4eic::TrackSegmentCollection*>> colls = {
0158         collection0.get(), collection1.get(), collection2.get()};
0159     auto trks = std::make_unique<edm4eic::TrackSegmentCollection>();
0160     algo.process({colls}, {trks.get()});
0161     // input collection(s) size == output collection size
0162     REQUIRE(trks->size() == colls.front()->size());
0163     // track length: from endpoints
0164     REQUIRE_THAT(track_length(trks->at(0)), Catch::Matchers::WithinAbs(5, EPSILON));
0165     REQUIRE_THAT(track_length(trks->at(1)), Catch::Matchers::WithinAbs(2, EPSILON));
0166     REQUIRE_THAT(track_length(trks->at(2)), Catch::Matchers::WithinAbs(std::hypot(1, 2), EPSILON));
0167     REQUIRE_THAT(track_length(trks->at(3)), Catch::Matchers::WithinAbs(5, EPSILON));
0168     // track length: from algorithm // FIXME when implemented in `MergeTracks`
0169     for (const auto& trk : *trks) {
0170       REQUIRE_THAT(trk.getLength(), Catch::Matchers::WithinAbs(0, EPSILON));
0171     }
0172   }
0173 }