File indexing completed on 2025-07-11 07:53:44
0001
0002
0003
0004 #include <DD4hep/Detector.h>
0005 #include <DD4hep/IDDescriptor.h>
0006 #include <DD4hep/Readout.h>
0007 #include <algorithms/geo.h>
0008 #include <algorithms/logger.h>
0009 #include <catch2/catch_test_macros.hpp>
0010 #include <catch2/generators/catch_generators.hpp>
0011 #include <edm4eic/CovDiag3f.h>
0012 #include <edm4eic/Measurement2DCollection.h>
0013 #include <edm4eic/TrackerHitCollection.h>
0014 #include <edm4eic/unit_system.h>
0015 #include <edm4hep/Vector2f.h>
0016 #include <edm4hep/Vector3f.h>
0017 #include <podio/RelationRange.h>
0018 #include <gsl/pointers>
0019 #include <utility>
0020 #include <vector>
0021
0022 #include "algorithms/fardetectors/FarDetectorTrackerCluster.h"
0023 #include "algorithms/fardetectors/FarDetectorTrackerClusterConfig.h"
0024
0025 TEST_CASE("the clustering algorithm runs", "[FarDetectorTrackerCluster]") {
0026 eicrecon::FarDetectorTrackerCluster algo("FarDetectorTrackerCluster");
0027
0028 eicrecon::FarDetectorTrackerClusterConfig cfg;
0029 cfg.hit_time_limit = 10.0 * edm4eic::unit::ns;
0030 cfg.readout = "MockTrackerHits";
0031 cfg.x_field = "x";
0032 cfg.y_field = "y";
0033
0034 auto detector = algorithms::GeoSvc::instance().detector();
0035 auto id_desc = detector->readout(cfg.readout).idSpec();
0036
0037 algo.applyConfig(cfg);
0038 algo.level(algorithms::LogLevel::kTrace);
0039 algo.init();
0040
0041 SECTION("on a single pixel") {
0042 edm4eic::TrackerHitCollection hits_coll;
0043 hits_coll.create(id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}),
0044 edm4hep::Vector3f(0.0, 0.0, 0.0),
0045 edm4eic::CovDiag3f(),
0046 0.0,
0047 0.0,
0048 5.0,
0049 0.0
0050 );
0051
0052 edm4eic::Measurement2DCollection clusterPositions;
0053 algo.ClusterHits(hits_coll, clusterPositions);
0054
0055 REQUIRE(clusterPositions.size() == 1);
0056 REQUIRE(clusterPositions[0].getHits().size() == 1);
0057 REQUIRE(clusterPositions[0].getLoc()[0] == 0.0);
0058 REQUIRE(clusterPositions[0].getLoc()[1] == 0.0);
0059 REQUIRE(clusterPositions[0].getTime() == 0.0);
0060 }
0061
0062 SECTION("on two separated pixels") {
0063 edm4eic::TrackerHitCollection hits_coll;
0064 hits_coll.create(
0065 id_desc.encode({{"system", 255}, {"x", 0}, {"y", 10}}),
0066 edm4hep::Vector3f(0.0, 0.0, 0.0),
0067 edm4eic::CovDiag3f(),
0068 5.0,
0069 0.0,
0070 5.0,
0071 0.0
0072 );
0073 hits_coll.create(
0074 id_desc.encode({{"system", 255}, {"x", 10}, {"y", 0}}),
0075 edm4hep::Vector3f(0.0, 0.0, 0.0),
0076 edm4eic::CovDiag3f(),
0077 5.0,
0078 0.0,
0079 5.0,
0080 0.0
0081 );
0082
0083 edm4eic::Measurement2DCollection clusterPositions;
0084 algo.ClusterHits(hits_coll, clusterPositions);
0085
0086 REQUIRE(clusterPositions.size() == 2);
0087 REQUIRE(clusterPositions[0].getHits().size() == 1);
0088 REQUIRE(clusterPositions[1].getHits().size() == 1);
0089 }
0090
0091 SECTION("on two adjacent pixels") {
0092 edm4eic::TrackerHitCollection hits_coll;
0093 hits_coll.create(id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}),
0094 edm4hep::Vector3f(0.0, 0.0, 0.0),
0095 edm4eic::CovDiag3f(),
0096 5.0,
0097 0.0,
0098 5.0,
0099 0.0
0100 );
0101 hits_coll.create(id_desc.encode({{"system", 255}, {"x", 1}, {"y", 0}}),
0102 edm4hep::Vector3f(0.0, 0.0, 0.0),
0103 edm4eic::CovDiag3f(),
0104 5.0,
0105 0.0,
0106 5.0,
0107 0.0
0108 );
0109
0110 edm4eic::Measurement2DCollection clusterPositions;
0111 algo.ClusterHits(hits_coll, clusterPositions);
0112
0113 REQUIRE(clusterPositions.size() == 1);
0114 REQUIRE(clusterPositions[0].getHits().size() == 2);
0115 REQUIRE(clusterPositions[0].getLoc()[0] == 0.5);
0116 }
0117
0118 SECTION("on two adjacent pixels outwith the time separation") {
0119 edm4eic::TrackerHitCollection hits_coll;
0120 hits_coll.create(id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}),
0121 edm4hep::Vector3f(0.0, 0.0, 0.0),
0122 edm4eic::CovDiag3f(),
0123 0.0,
0124 0.0,
0125 5.0,
0126 0.0
0127 );
0128 hits_coll.create(id_desc.encode({{"system", 255}, {"x", 1}, {"y", 0}}),
0129 edm4hep::Vector3f(0.0, 0.0, 0.0),
0130 edm4eic::CovDiag3f(),
0131 1.1 * cfg.hit_time_limit,
0132 0.0,
0133 5.0,
0134 0.0
0135 );
0136
0137 edm4eic::Measurement2DCollection clusterPositions;
0138 algo.ClusterHits(hits_coll, clusterPositions);
0139
0140 REQUIRE(clusterPositions.size() == 2);
0141 REQUIRE(clusterPositions[0].getHits().size() == 1);
0142 REQUIRE(clusterPositions[1].getHits().size() == 1);
0143 }
0144
0145 SECTION("run on three adjacent pixels") {
0146
0147
0148 auto pixel3 = GENERATE(std::vector<int>{2, 0}, std::vector<int>{1, 1});
0149 auto pixelCharges = GENERATE(std::vector<int>{5, 10, 5}, std::vector<int>{10, 5, 5});
0150 float pixel2Time = GENERATE_COPY(0, 1.1 * cfg.hit_time_limit);
0151
0152 edm4eic::TrackerHitCollection hits_coll;
0153 hits_coll.create(id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}),
0154 edm4hep::Vector3f(0.0, 0.0, 0.0),
0155 edm4eic::CovDiag3f(),
0156 0.0,
0157 0.0,
0158 pixelCharges[0],
0159 0.0
0160 );
0161 hits_coll.create(id_desc.encode({{"system", 255}, {"x", 1}, {"y", 0}}),
0162 edm4hep::Vector3f(0.0, 0.0, 0.0),
0163 edm4eic::CovDiag3f(),
0164 pixel2Time,
0165 0.0,
0166 pixelCharges[1],
0167 0.0
0168 );
0169 hits_coll.create(
0170 id_desc.encode(
0171 {{"system", 255}, {"x", pixel3[0]}, {"y", pixel3[1]}}),
0172 edm4hep::Vector3f(0.0, 0.0, 0.0),
0173 edm4eic::CovDiag3f(),
0174 0.0,
0175 0.0,
0176 pixelCharges[2],
0177 0.0
0178 );
0179
0180 edm4eic::Measurement2DCollection clusterPositions;
0181 algo.ClusterHits(hits_coll, clusterPositions);
0182
0183 if (pixel2Time < cfg.hit_time_limit) {
0184 REQUIRE(clusterPositions.size() == 1);
0185 REQUIRE(clusterPositions[0].getHits().size() == 3);
0186 } else if (pixel3[0] == 2) {
0187 REQUIRE(clusterPositions.size() == 3);
0188 REQUIRE(clusterPositions[0].getHits().size() == 1);
0189 REQUIRE(clusterPositions[1].getHits().size() == 1);
0190 REQUIRE(clusterPositions[2].getHits().size() == 1);
0191 } else {
0192 REQUIRE(clusterPositions.size() == 2);
0193 }
0194 }
0195 }