File indexing completed on 2025-07-14 08:14:45
0001
0002
0003
0004 #include <DD4hep/Detector.h>
0005 #include <DD4hep/IDDescriptor.h>
0006 #include <DD4hep/Readout.h>
0007 #include <Evaluator/DD4hepUnits.h>
0008 #include <algorithms/geo.h>
0009 #include <catch2/catch_test_macros.hpp>
0010 #include <edm4eic/CalorimeterHitCollection.h>
0011 #include <edm4eic/ProtoClusterCollection.h>
0012 #include <edm4hep/Vector3f.h>
0013 #include <spdlog/common.h>
0014 #include <spdlog/logger.h>
0015 #include <spdlog/spdlog.h>
0016 #include <gsl/pointers>
0017 #include <memory>
0018 #include <utility>
0019 #include <vector>
0020
0021 #include "algorithms/calorimetry/ImagingTopoCluster.h"
0022 #include "algorithms/calorimetry/ImagingTopoClusterConfig.h"
0023
0024 using eicrecon::ImagingTopoCluster;
0025 using eicrecon::ImagingTopoClusterConfig;
0026
0027 TEST_CASE("the clustering algorithm runs", "[ImagingTopoCluster]") {
0028 ImagingTopoCluster algo("ImagingTopoCluster");
0029
0030 std::shared_ptr<spdlog::logger> logger = spdlog::default_logger()->clone("ImagingTopoCluster");
0031 logger->set_level(spdlog::level::trace);
0032
0033 ImagingTopoClusterConfig cfg;
0034 cfg.layerMode = eicrecon::ImagingTopoClusterConfig::ELayerMode::xy;
0035 cfg.minClusterHitEdep = 0. * dd4hep::GeV;
0036 cfg.minClusterCenterEdep = 0. * dd4hep::GeV;
0037 cfg.localDistXY = {1.0 * dd4hep::mm, 1.0 * dd4hep::mm};
0038 cfg.layerDistXY = {1.0 * dd4hep::mm, 1.0 * dd4hep::mm};
0039 cfg.minClusterEdep = 9 * dd4hep::MeV;
0040
0041 cfg.minClusterNhits = 1;
0042 auto detector = algorithms::GeoSvc::instance().detector();
0043 auto id_desc = detector->readout("MockCalorimeterHits").idSpec();
0044
0045 SECTION("without splitting") {
0046 algo.applyConfig(cfg);
0047 algo.init();
0048
0049 SECTION("on a single cell") {
0050 edm4eic::CalorimeterHitCollection hits_coll;
0051 hits_coll.create(
0052 id_desc.encode(
0053 {{"system", 255}, {"x", 0}, {"y", 0}, {"layer", 0}}),
0054 5.0,
0055 0.0,
0056 0.0,
0057 0.0,
0058 edm4hep::Vector3f(0.0, 0.0, 0.0),
0059 edm4hep::Vector3f(0.0, 0.0, 0.0),
0060 0,
0061 0,
0062 edm4hep::Vector3f(0.0, 0.0, 0.0)
0063 );
0064 auto protoclust_coll = std::make_unique<edm4eic::ProtoClusterCollection>();
0065 algo.process({&hits_coll}, {protoclust_coll.get()});
0066
0067 REQUIRE((*protoclust_coll).size() == 1);
0068 REQUIRE((*protoclust_coll)[0].hits_size() == 1);
0069 REQUIRE((*protoclust_coll)[0].weights_size() == 1);
0070 }
0071
0072 SECTION("on two separated cells") {
0073 edm4eic::CalorimeterHitCollection hits_coll;
0074 hits_coll.create(
0075 id_desc.encode(
0076 {{"system", 255}, {"x", 0}, {"y", 0}, {"layer", 0}}),
0077 5.0,
0078 0.0,
0079 0.0,
0080 0.0,
0081 edm4hep::Vector3f(0.0, 0.0, 0.0),
0082 edm4hep::Vector3f(1.0, 1.0, 0.0),
0083 0,
0084 0,
0085 edm4hep::Vector3f(0.0, 0.0, 0.0)
0086 );
0087 hits_coll.create(
0088 id_desc.encode(
0089 {{"system", 255}, {"x", 2}, {"y", 2}, {"layer", 0}}),
0090 6.0,
0091 0.0,
0092 0.0,
0093 0.0,
0094 edm4hep::Vector3f(1.1, 1.1, 0.0),
0095 edm4hep::Vector3f(1.0, 1.0, 0.0),
0096 0,
0097 0,
0098 edm4hep::Vector3f(1.1 , 1.1 , 0.0)
0099 );
0100 auto protoclust_coll = std::make_unique<edm4eic::ProtoClusterCollection>();
0101 algo.process({&hits_coll}, {protoclust_coll.get()});
0102
0103 REQUIRE((*protoclust_coll).size() == 2);
0104 REQUIRE((*protoclust_coll)[0].hits_size() == 1);
0105 REQUIRE((*protoclust_coll)[0].weights_size() == 1);
0106 REQUIRE((*protoclust_coll)[1].hits_size() == 1);
0107 REQUIRE((*protoclust_coll)[1].weights_size() == 1);
0108 }
0109
0110 SECTION("on two adjacent cells (same layer)") {
0111 edm4eic::CalorimeterHitCollection hits_coll;
0112 hits_coll.create(
0113 id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}),
0114 5.0,
0115 0.0,
0116 0.0,
0117 0.0,
0118 edm4hep::Vector3f(0.0, 0.0, 0.0),
0119 edm4hep::Vector3f(1.0, 1.0, 0.0),
0120 0,
0121 0,
0122 edm4hep::Vector3f(0.0, 0.0, 0.0)
0123 );
0124 hits_coll.create(
0125 id_desc.encode({{"system", 255}, {"x", 1}, {"y", 0}}),
0126 6.0,
0127 0.0,
0128 0.0,
0129 0.0,
0130 edm4hep::Vector3f(0.9, 0.9, 0.0),
0131 edm4hep::Vector3f(1.0, 1.0, 0.0),
0132 0,
0133 0,
0134 edm4hep::Vector3f(0.9 , 0.9 , 0.0)
0135 );
0136 auto protoclust_coll = std::make_unique<edm4eic::ProtoClusterCollection>();
0137 algo.process({&hits_coll}, {protoclust_coll.get()});
0138
0139 REQUIRE((*protoclust_coll).size() == 1);
0140 REQUIRE((*protoclust_coll)[0].hits_size() == 2);
0141 REQUIRE((*protoclust_coll)[0].weights_size() == 2);
0142 }
0143 }
0144
0145 SECTION("run on three cells, two of which are on the same layer, and there is a third one on "
0146 "another layer acting as a bridge between them") {
0147
0148 cfg.localDistXY = {1 * dd4hep::mm, 1 * dd4hep::mm};
0149 algo.applyConfig(cfg);
0150 algo.init();
0151
0152 edm4eic::CalorimeterHitCollection hits_coll;
0153 hits_coll.create(
0154 id_desc.encode(
0155 {{"system", 255}, {"x", 0}, {"y", 0}, {"layer", 0}}),
0156 5.0,
0157 0.0,
0158 0.0,
0159 0.0,
0160 edm4hep::Vector3f(0.0, 0.0, 0.0),
0161 edm4hep::Vector3f(1.0, 1.0, 0.0),
0162 0,
0163 0,
0164 edm4hep::Vector3f(0.0, 0.0, 0.0)
0165 );
0166 hits_coll.create(
0167 id_desc.encode(
0168 {{"system", 255}, {"x", 1}, {"y", 0}, {"layer", 1}}),
0169 1.0,
0170 0.0,
0171 0.0,
0172 0.0,
0173 edm4hep::Vector3f(0.9, 0.9, 0.0),
0174 edm4hep::Vector3f(1.0, 1.0, 0.0),
0175 0,
0176 1,
0177 edm4hep::Vector3f(0.9 , 0.9 , 0.0)
0178 );
0179 hits_coll.create(
0180 id_desc.encode(
0181 {{"system", 255}, {"x", 2}, {"y", 0}, {"layer", 0}}),
0182 6.0,
0183 0.0,
0184 0.0,
0185 0.0,
0186 edm4hep::Vector3f(1.8, 1.8, 0.0),
0187 edm4hep::Vector3f(1.0, 1.0, 0.0),
0188 0,
0189 0,
0190 edm4hep::Vector3f(1.8 , 1.8 , 0.0)
0191 );
0192 auto protoclust_coll = std::make_unique<edm4eic::ProtoClusterCollection>();
0193 algo.process({&hits_coll}, {protoclust_coll.get()});
0194
0195 REQUIRE((*protoclust_coll).size() == 1);
0196 REQUIRE((*protoclust_coll)[0].hits_size() == 3);
0197 REQUIRE((*protoclust_coll)[0].weights_size() == 3);
0198 }
0199 }