Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-06 07:54:19

0001 // SPDX-License-Identifier: LGPL-3.0-or-later
0002 // Copyright (C) 2023 - 2025, Dmitry Kalinkin
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 <algorithms/logger.h>
0010 #include <catch2/catch_test_macros.hpp>
0011 #include <catch2/matchers/catch_matchers.hpp>
0012 #include <catch2/matchers/catch_matchers_floating_point.hpp>
0013 #include <edm4eic/EDM4eicVersion.h>
0014 #include <edm4eic/MCRecoCalorimeterHitAssociationCollection.h>
0015 #if EDM4EIC_BUILD_VERSION >= EDM4EIC_VERSION(8, 7, 0)
0016 #include <edm4eic/MCRecoCalorimeterHitLinkCollection.h>
0017 #endif
0018 #include <edm4hep/CaloHitContributionCollection.h>
0019 #include <edm4hep/EventHeaderCollection.h>
0020 #include <edm4hep/RawCalorimeterHitCollection.h>
0021 #include <edm4hep/SimCalorimeterHitCollection.h>
0022 #include <edm4hep/Vector3f.h>
0023 #include <podio/detail/Link.h>
0024 #include <spdlog/common.h>
0025 #include <spdlog/logger.h>
0026 #include <spdlog/spdlog.h>
0027 #include <cmath>
0028 #include <deque>
0029 #include <gsl/pointers>
0030 #include <memory>
0031 #include <string>
0032 #include <utility>
0033 #include <vector>
0034 
0035 #include "algorithms/calorimetry/CalorimeterHitDigi.h"
0036 #include "algorithms/calorimetry/CalorimeterHitDigiConfig.h"
0037 
0038 using eicrecon::CalorimeterHitDigi;
0039 using eicrecon::CalorimeterHitDigiConfig;
0040 
0041 TEST_CASE("the clustering algorithm runs", "[CalorimeterHitDigi]") {
0042   [[maybe_unused]] const float EPSILON = 1e-5;
0043 
0044   std::shared_ptr<spdlog::logger> logger = spdlog::default_logger()->clone("CalorimeterHitDigi");
0045   logger->set_level(spdlog::level::trace);
0046 
0047   auto detector = algorithms::GeoSvc::instance().detector();
0048   auto id_desc  = detector->readout("MockCalorimeterHits").idSpec();
0049 
0050   CalorimeterHitDigi algo("test");
0051 
0052   CalorimeterHitDigiConfig cfg;
0053   cfg.threshold     = 0. /* GeV */;
0054   cfg.corrMeanScale = "1.";
0055 
0056   // Keep smearing parameters at zero
0057   cfg.pedSigmaADC = 0;
0058   cfg.tRes        = 0. * dd4hep::ns;
0059   cfg.eRes        = {0. * sqrt(dd4hep::GeV), 0., 0. * dd4hep::GeV};
0060   cfg.readout     = "MockCalorimeterHits";
0061 
0062   SECTION("single hit with couple contributions") {
0063     cfg.capADC        = 555;
0064     cfg.dyRangeADC    = 5.0 /* GeV */;
0065     cfg.pedMeanADC    = 123;
0066     cfg.resolutionTDC = 1.0 * dd4hep::ns;
0067     algo.level(algorithms::LogLevel(spdlog::level::trace));
0068     algo.applyConfig(cfg);
0069     algo.init();
0070 
0071     auto headers = std::make_unique<edm4hep::EventHeaderCollection>();
0072     auto header  = headers->create(1, 1, 12345678, 1.0);
0073 
0074     auto calohits = std::make_unique<edm4hep::CaloHitContributionCollection>();
0075     auto simhits  = std::make_unique<edm4hep::SimCalorimeterHitCollection>();
0076     auto mhit     = simhits->create(
0077         id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}),     // std::uint64_t cellID,
0078         1.0 /* GeV */,                                             // float energy
0079         edm4hep::Vector3f({0. /* mm */, 0. /* mm */, 0. /* mm */}) // edm4hep::Vector3f position
0080     );
0081     mhit.addToContributions(calohits->create(
0082         0,                                                         // std::int32_t PDG
0083         0.5 /* GeV */,                                             // float energy
0084         7.0 /* ns */,                                              // float time
0085         edm4hep::Vector3f({0. /* mm */, 0. /* mm */, 0. /* mm */}) // edm4hep::Vector3f stepPosition
0086         ));
0087     mhit.addToContributions(calohits->create(
0088         0,                                                         // std::int32_t PDG
0089         0.5 /* GeV */,                                             // float energy
0090         9.0 /* ns */,                                              // float time
0091         edm4hep::Vector3f({0. /* mm */, 0. /* mm */, 0. /* mm */}) // edm4hep::Vector3f stepPosition
0092         ));
0093 
0094     auto rawhits   = std::make_unique<edm4hep::RawCalorimeterHitCollection>();
0095     auto rawassocs = std::make_unique<edm4eic::MCRecoCalorimeterHitAssociationCollection>();
0096 #if EDM4EIC_BUILD_VERSION >= EDM4EIC_VERSION(8, 7, 0)
0097     edm4eic::MCRecoCalorimeterHitLinkCollection rawlinks;
0098     algo.process({headers.get(), simhits.get()}, {rawhits.get(), &rawlinks, rawassocs.get()});
0099 #else
0100     algo.process({headers.get(), simhits.get()}, {rawhits.get(), rawassocs.get()});
0101 #endif
0102 
0103     REQUIRE((*rawhits).size() == 1);
0104     REQUIRE((*rawhits)[0].getCellID() == id_desc.encode({{"system", 255}, {"x", 0}, {"y", 0}}));
0105     REQUIRE((*rawhits)[0].getAmplitude() == 123 + 111);
0106     REQUIRE((*rawhits)[0].getTimeStamp() == 7); // currently, earliest contribution is returned
0107 
0108     REQUIRE((*rawassocs).size() == 1);
0109     REQUIRE((*rawassocs)[0].getSimHit() == (*simhits)[0]);
0110     REQUIRE((*rawassocs)[0].getRawHit() == (*rawhits)[0]);
0111 
0112 #if EDM4EIC_BUILD_VERSION >= EDM4EIC_VERSION(8, 7, 0)
0113     // Validate links collection
0114     REQUIRE(rawlinks.size() == 1);
0115     REQUIRE(rawlinks.size() == (*rawassocs).size());
0116 
0117     // Check link from/to relationships match association sim/raw hits
0118     REQUIRE(rawlinks[0].getFrom() == (*rawhits)[0]);
0119     REQUIRE(rawlinks[0].getTo() == (*simhits)[0]);
0120 
0121     // Verify weights are normalized (should be 1.0 for single hit)
0122     REQUIRE_THAT(rawlinks[0].getWeight(), Catch::Matchers::WithinAbs(1.0, EPSILON));
0123 #endif
0124   }
0125 }