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