From fc1e1813512b3e129c26b7ec0d2a7a9fd56514a3 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Sat, 26 Apr 2025 13:13:25 -0500 Subject: [PATCH 01/11] feat: DetectorChecksumRunAction to write checksums to podio --- src/dd4pod/python/npsim.py | 8 ++ src/plugins/CMakeLists.txt | 3 +- .../include/npdet/DetectorChecksumRunAction.h | 91 +++++++++++++++++++ src/plugins/src/DetectorChecksumRunAction.cxx | 5 + src/tools/src/dd_web_display.cxx | 2 +- 5 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 src/plugins/include/npdet/DetectorChecksumRunAction.h create mode 100644 src/plugins/src/DetectorChecksumRunAction.cxx diff --git a/src/dd4pod/python/npsim.py b/src/dd4pod/python/npsim.py index 396f676..1ace4d9 100755 --- a/src/dd4pod/python/npsim.py +++ b/src/dd4pod/python/npsim.py @@ -66,6 +66,14 @@ def setupCerenkov(kernel): RUNNER.action.mapActions['RICHEndcapN'] = 'Geant4OpticalTrackerAction' RUNNER.action.mapActions['DIRC'] = 'Geant4OpticalTrackerAction' + # Store detector checksum in run action + RUNNER.action.run = [ + { + "name": "DetectorChecksumRunAction", + "parameter": {} + } + ] + # Use the optical photon efficiency stacking action for hpDIRC RUNNER.action.stack = [ { diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index 6216894..5900e2f 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -2,11 +2,12 @@ cmake_minimum_required(VERSION 3.12 FATAL_ERROR) dd4hep_add_plugin(NPDetPlugins SOURCES + src/DetectorChecksumRunAction.cxx src/EICInteractionVertexBoost.cxx src/EICInteractionVertexSmear.cxx src/OpticalPhotonEfficiencyStackingAction.cxx INCLUDES $ - USES DD4hep::DDCore DD4hep::DDG4 + USES DD4hep::DDCore DD4hep::DDCorePlugins DD4hep::DDG4 ) install(TARGETS NPDetPlugins diff --git a/src/plugins/include/npdet/DetectorChecksumRunAction.h b/src/plugins/include/npdet/DetectorChecksumRunAction.h new file mode 100644 index 0000000..813c222 --- /dev/null +++ b/src/plugins/include/npdet/DetectorChecksumRunAction.h @@ -0,0 +1,91 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +#ifndef DETECTORCHECKSUMRUNACTION_H +#define DETECTORCHECKSUMRUNACTION_H + +#include "DDG4/Geant4Random.h" +#include "DDG4/Geant4RunAction.h" +#include + +#if __has_include() +#include +#endif + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + +/// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit +namespace sim { + + using dd4hep::detail::DetectorChecksum; + using hashMap_t = std::map; + + template void RunParameters::ingestParameters(T const& hashMap) { + for (auto& [name, hash] : hashMap) { + // hashes are 64 bit, so we have to cast to string + // FIXME: should be hex string since that's printed + // FIXME: suffix or prefix with "hash" + m_strValues[name.c_str()] = {std::to_string(hash)}; + } + } + + class DetectorChecksumRunAction: public Geant4RunAction { + public: + /// Standard constructor with initializing arguments + DetectorChecksumRunAction(Geant4Context* c, const std::string& n) + : Geant4RunAction(c, n) {}; + /// Default destructor + virtual ~DetectorChecksumRunAction() {}; + + void begin(const G4Run* run); + private: + hashMap_t getHashMap(Detector& detector); + }; + +void DetectorChecksumRunAction::begin(const G4Run* /* run */) { + try { + auto *parameters = new RunParameters(); + parameters->ingestParameters(getHashMap(context()->detectorDescription())); + context()->run().addExtension(parameters); + } catch(std::exception &e) { + printout(ERROR,"DetectorChecksumRunAction::begin","Failed to register run parameters: %s", e.what()); + } +} + +std::map +DetectorChecksumRunAction::getHashMap(Detector& detector) { + std::map hashMap; +#if __has_include() + // Determine detector checksum + // FIXME: ctor expects non-const detector + DetectorChecksum checksum(detector); + checksum.debug = 0; + checksum.precision = 3; + checksum.hash_meshes = true; + checksum.hash_readout = true; + for (const auto& [name, det] : detector.world().children()) { + checksum.analyzeDetector(det); + DetectorChecksum::hashes_t hash_vec{checksum.handleHeader().hash}; + checksum.checksumDetElement(0, det, hash_vec, true); + DetectorChecksum::hash_t hash = + dd4hep::detail::hash64(&hash_vec[0], hash_vec.size() * sizeof(DetectorChecksum::hash_t)); + hashMap[name] = hash; + } +#endif + return hashMap; +} + +} // End namespace sim +} // End namespace dd4hep + +#endif // DETECTORCHECKSUMRUNACTION_H diff --git a/src/plugins/src/DetectorChecksumRunAction.cxx b/src/plugins/src/DetectorChecksumRunAction.cxx new file mode 100644 index 0000000..55c744d --- /dev/null +++ b/src/plugins/src/DetectorChecksumRunAction.cxx @@ -0,0 +1,5 @@ +#include "DDG4/Factories.h" + +#include "npdet/DetectorChecksumRunAction.h" + +DECLARE_GEANT4ACTION(DetectorChecksumRunAction) diff --git a/src/tools/src/dd_web_display.cxx b/src/tools/src/dd_web_display.cxx index 5dbfa5e..97c2edb 100644 --- a/src/tools/src/dd_web_display.cxx +++ b/src/tools/src/dd_web_display.cxx @@ -221,7 +221,7 @@ void run_http_server(const settings& s) { std::string("?top=geometry&thrds=1;rw;noglobal")) .c_str()); - spdlog::info("Creating display server at http://{}:{}",s.http_host,s.http_port); + //spdlog::info("Creating display server at http://{}:{}",s.http_host,s.http_port); if( !(serv->IsAnyEngine()) ) { spdlog::error("Failed to start http server."); std::exit(-1); From cb1d0efb578fd74bcd7187bc7766f410b94cb841 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Sat, 26 Apr 2025 16:31:37 -0500 Subject: [PATCH 02/11] feat: add property ignoreDetectors to skip detectors with failing checksum --- src/dd4pod/python/npsim.py | 8 +++++++- src/plugins/include/npdet/DetectorChecksumRunAction.h | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/dd4pod/python/npsim.py b/src/dd4pod/python/npsim.py index 1ace4d9..cfd2fb5 100755 --- a/src/dd4pod/python/npsim.py +++ b/src/dd4pod/python/npsim.py @@ -70,7 +70,13 @@ def setupCerenkov(kernel): RUNNER.action.run = [ { "name": "DetectorChecksumRunAction", - "parameter": {} + "parameter": { + "ignoreDetectors": [ + "ForwardRomanPot_Station_1", + "ForwardRomanPot_Station_2", + "RICHEndcapN" + ] + } } ] diff --git a/src/plugins/include/npdet/DetectorChecksumRunAction.h b/src/plugins/include/npdet/DetectorChecksumRunAction.h index 813c222..88e7f5b 100644 --- a/src/plugins/include/npdet/DetectorChecksumRunAction.h +++ b/src/plugins/include/npdet/DetectorChecksumRunAction.h @@ -43,13 +43,16 @@ namespace sim { public: /// Standard constructor with initializing arguments DetectorChecksumRunAction(Geant4Context* c, const std::string& n) - : Geant4RunAction(c, n) {}; + : Geant4RunAction(c, n) { + declareProperty("ignoreDetectors", m_ignoreDetectors); + }; /// Default destructor virtual ~DetectorChecksumRunAction() {}; void begin(const G4Run* run); private: hashMap_t getHashMap(Detector& detector); + std::set m_ignoreDetectors; }; void DetectorChecksumRunAction::begin(const G4Run* /* run */) { @@ -74,6 +77,9 @@ DetectorChecksumRunAction::getHashMap(Detector& detector) { checksum.hash_meshes = true; checksum.hash_readout = true; for (const auto& [name, det] : detector.world().children()) { + if (m_ignoreDetectors.contains(name)) { + continue; + } checksum.analyzeDetector(det); DetectorChecksum::hashes_t hash_vec{checksum.handleHeader().hash}; checksum.checksumDetElement(0, det, hash_vec, true); From 86b8ab3d45619c94a6a9c18eb872a9fce20d7bea Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Sun, 27 Apr 2025 10:08:38 -0500 Subject: [PATCH 03/11] fix fmt as hex, suffix hash --- .../include/npdet/DetectorChecksumRunAction.h | 60 +++++++++++-------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/src/plugins/include/npdet/DetectorChecksumRunAction.h b/src/plugins/include/npdet/DetectorChecksumRunAction.h index 88e7f5b..b5d6ae5 100644 --- a/src/plugins/include/npdet/DetectorChecksumRunAction.h +++ b/src/plugins/include/npdet/DetectorChecksumRunAction.h @@ -13,9 +13,10 @@ #ifndef DETECTORCHECKSUMRUNACTION_H #define DETECTORCHECKSUMRUNACTION_H -#include "DDG4/Geant4Random.h" -#include "DDG4/Geant4RunAction.h" +#include +#include #include +#include #if __has_include() #include @@ -33,9 +34,7 @@ namespace sim { template void RunParameters::ingestParameters(T const& hashMap) { for (auto& [name, hash] : hashMap) { // hashes are 64 bit, so we have to cast to string - // FIXME: should be hex string since that's printed - // FIXME: suffix or prefix with "hash" - m_strValues[name.c_str()] = {std::to_string(hash)}; + m_strValues[name + "_hash"] = {std::format("{:x}",hash)}; } } @@ -51,42 +50,51 @@ namespace sim { void begin(const G4Run* run); private: - hashMap_t getHashMap(Detector& detector); + hashMap_t getHashMap(Detector& detector) const; std::set m_ignoreDetectors; }; void DetectorChecksumRunAction::begin(const G4Run* /* run */) { try { - auto *parameters = new RunParameters(); + bool newParameters{false}; + RunParameters* parameters = nullptr; + try { + parameters = context()->run().extension(); + } catch (std::exception& e) { + parameters = new RunParameters(); + newParameters = true; + } parameters->ingestParameters(getHashMap(context()->detectorDescription())); - context()->run().addExtension(parameters); + if (newParameters) { + context()->run().addExtension(parameters); + } } catch(std::exception &e) { printout(ERROR,"DetectorChecksumRunAction::begin","Failed to register run parameters: %s", e.what()); } } std::map -DetectorChecksumRunAction::getHashMap(Detector& detector) { +DetectorChecksumRunAction::getHashMap(Detector& detector) const { std::map hashMap; #if __has_include() - // Determine detector checksum - // FIXME: ctor expects non-const detector - DetectorChecksum checksum(detector); - checksum.debug = 0; - checksum.precision = 3; - checksum.hash_meshes = true; - checksum.hash_readout = true; - for (const auto& [name, det] : detector.world().children()) { - if (m_ignoreDetectors.contains(name)) { - continue; - } - checksum.analyzeDetector(det); - DetectorChecksum::hashes_t hash_vec{checksum.handleHeader().hash}; - checksum.checksumDetElement(0, det, hash_vec, true); - DetectorChecksum::hash_t hash = - dd4hep::detail::hash64(&hash_vec[0], hash_vec.size() * sizeof(DetectorChecksum::hash_t)); - hashMap[name] = hash; + // Determine detector checksum + // FIXME: ctor expects non-const detector + DetectorChecksum checksum(detector); + checksum.debug = 0; + checksum.precision = 3; + checksum.hash_meshes = true; + checksum.hash_readout = true; + for (const auto& [name, det] : detector.world().children()) { + if (m_ignoreDetectors.contains(name)) { + continue; } + checksum.analyzeDetector(det); + DetectorChecksum::hashes_t hash_vec{checksum.handleHeader().hash}; + checksum.checksumDetElement(0, det, hash_vec, true); + DetectorChecksum::hash_t hash = + dd4hep::detail::hash64(&hash_vec[0], hash_vec.size() * sizeof(DetectorChecksum::hash_t)); + hashMap[name] = hash; + } #endif return hashMap; } From 06bc29d0c11649bdb9f0e9230f52f97dc17a762a Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Sun, 27 Apr 2025 10:38:56 -0500 Subject: [PATCH 04/11] fix: briefer extensions setting --- .../include/npdet/DetectorChecksumRunAction.h | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/plugins/include/npdet/DetectorChecksumRunAction.h b/src/plugins/include/npdet/DetectorChecksumRunAction.h index b5d6ae5..18c597d 100644 --- a/src/plugins/include/npdet/DetectorChecksumRunAction.h +++ b/src/plugins/include/npdet/DetectorChecksumRunAction.h @@ -56,18 +56,12 @@ namespace sim { void DetectorChecksumRunAction::begin(const G4Run* /* run */) { try { - bool newParameters{false}; - RunParameters* parameters = nullptr; - try { - parameters = context()->run().extension(); - } catch (std::exception& e) { + auto* parameters = context()->run().extension(false); + if (!parameters) { parameters = new RunParameters(); - newParameters = true; - } - parameters->ingestParameters(getHashMap(context()->detectorDescription())); - if (newParameters) { context()->run().addExtension(parameters); } + parameters->ingestParameters(getHashMap(context()->detectorDescription())); } catch(std::exception &e) { printout(ERROR,"DetectorChecksumRunAction::begin","Failed to register run parameters: %s", e.what()); } From 347e082861f351b8f69d74753d256070d633c575 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Wed, 30 Apr 2025 15:36:38 -0500 Subject: [PATCH 05/11] fix: revert comment out of dd_web_display logging line --- src/tools/src/dd_web_display.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/src/dd_web_display.cxx b/src/tools/src/dd_web_display.cxx index 97c2edb..5dbfa5e 100644 --- a/src/tools/src/dd_web_display.cxx +++ b/src/tools/src/dd_web_display.cxx @@ -221,7 +221,7 @@ void run_http_server(const settings& s) { std::string("?top=geometry&thrds=1;rw;noglobal")) .c_str()); - //spdlog::info("Creating display server at http://{}:{}",s.http_host,s.http_port); + spdlog::info("Creating display server at http://{}:{}",s.http_host,s.http_port); if( !(serv->IsAnyEngine()) ) { spdlog::error("Failed to start http server."); std::exit(-1); From ebd86a18c34cda6cf5aa1206f184ed97a2bfbf3f Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Wed, 30 Apr 2025 15:37:02 -0500 Subject: [PATCH 06/11] fix: revert ignoreDetectors --- src/dd4pod/python/npsim.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/dd4pod/python/npsim.py b/src/dd4pod/python/npsim.py index cfd2fb5..d2aba04 100755 --- a/src/dd4pod/python/npsim.py +++ b/src/dd4pod/python/npsim.py @@ -67,18 +67,15 @@ def setupCerenkov(kernel): RUNNER.action.mapActions['DIRC'] = 'Geant4OpticalTrackerAction' # Store detector checksum in run action - RUNNER.action.run = [ - { - "name": "DetectorChecksumRunAction", - "parameter": { - "ignoreDetectors": [ - "ForwardRomanPot_Station_1", - "ForwardRomanPot_Station_2", - "RICHEndcapN" - ] + if len(RUNNER.action.run) == 0: + RUNNER.action.run = [ + { + "name": "DetectorChecksumRunAction", + "parameter": { + "ignoreDetectors": [] + } } - } - ] + ] # Use the optical photon efficiency stacking action for hpDIRC RUNNER.action.stack = [ From 8ecaf793982c99ab28bff09ea94ac56358fd68fa Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Wed, 30 Apr 2025 16:45:26 -0500 Subject: [PATCH 07/11] fix: add proper argparse to npsim, stop the hackiness (mostly) --- src/dd4pod/python/npsim.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/dd4pod/python/npsim.py b/src/dd4pod/python/npsim.py index d2aba04..73a3a27 100755 --- a/src/dd4pod/python/npsim.py +++ b/src/dd4pod/python/npsim.py @@ -8,6 +8,7 @@ Modified with standard EIC EPIC requirements. """ from __future__ import absolute_import, unicode_literals +import argparse import logging import sys @@ -20,6 +21,13 @@ RUNNER = DD4hepSimulation() + # Parse our own options + parser = argparse.ArgumentParser() + parser.add_argument("--disableChecksum", action="store_true", default=False, + help="Disable the detector checksum calculations") + args, unknown = parser.parse_known_args() + sys.argv = [sys.argv[0]] + unknown + # Parse remaining options (command line and steering file override above) # This is done before updating the settings to workaround issue reported in # https://github.com/AIDASoft/DD4hep/pull/1376 @@ -67,8 +75,8 @@ def setupCerenkov(kernel): RUNNER.action.mapActions['DIRC'] = 'Geant4OpticalTrackerAction' # Store detector checksum in run action - if len(RUNNER.action.run) == 0: - RUNNER.action.run = [ + if not args.disableChecksum: + RUNNER.action.run += [ { "name": "DetectorChecksumRunAction", "parameter": { From 4ecd9ecaad4ae5a43b8bb8cecc695b010f3943c4 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Mon, 18 Aug 2025 14:24:53 -0500 Subject: [PATCH 08/11] fix: don't intercept npsim --help prematurely --- src/dd4pod/python/npsim.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dd4pod/python/npsim.py b/src/dd4pod/python/npsim.py index 73a3a27..2496106 100755 --- a/src/dd4pod/python/npsim.py +++ b/src/dd4pod/python/npsim.py @@ -22,11 +22,15 @@ RUNNER = DD4hepSimulation() # Parse our own options - parser = argparse.ArgumentParser() + parser = argparse.ArgumentParser("Running ePIC/EIC Simulations:", add_help=False) parser.add_argument("--disableChecksum", action="store_true", default=False, help="Disable the detector checksum calculations") args, unknown = parser.parse_known_args() sys.argv = [sys.argv[0]] + unknown + if "--help" in unknown: + parser.print_help() + print() + print() # Parse remaining options (command line and steering file override above) # This is done before updating the settings to workaround issue reported in From 818d1b1352402e154da7f24f644b00b4d3daf8bf Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Mon, 18 Aug 2025 14:25:35 -0500 Subject: [PATCH 09/11] feat: add chrono duration timer --- src/plugins/include/npdet/DetectorChecksumRunAction.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/plugins/include/npdet/DetectorChecksumRunAction.h b/src/plugins/include/npdet/DetectorChecksumRunAction.h index 18c597d..d09d2d1 100644 --- a/src/plugins/include/npdet/DetectorChecksumRunAction.h +++ b/src/plugins/include/npdet/DetectorChecksumRunAction.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #if __has_include() @@ -73,6 +74,7 @@ DetectorChecksumRunAction::getHashMap(Detector& detector) const { #if __has_include() // Determine detector checksum // FIXME: ctor expects non-const detector + const auto start{std::chrono::steady_clock::now()}; DetectorChecksum checksum(detector); checksum.debug = 0; checksum.precision = 3; @@ -89,6 +91,9 @@ DetectorChecksumRunAction::getHashMap(Detector& detector) const { dd4hep::detail::hash64(&hash_vec[0], hash_vec.size() * sizeof(DetectorChecksum::hash_t)); hashMap[name] = hash; } + const auto finish{std::chrono::steady_clock::now()}; + const std::chrono::duration elapsed_seconds{finish - start}; + printout(INFO,"DetectorChecksumRunAction::getHashMap", "duration: %f seconds", elapsed_seconds.count()); #endif return hashMap; } From 4cc48969a5fefde7daec065f964d0a98ea1924a0 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Mon, 18 Aug 2025 14:25:57 -0500 Subject: [PATCH 10/11] feat: suppress logging; bool for recursive det element traversal --- src/plugins/include/npdet/DetectorChecksumRunAction.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/include/npdet/DetectorChecksumRunAction.h b/src/plugins/include/npdet/DetectorChecksumRunAction.h index d09d2d1..30b29af 100644 --- a/src/plugins/include/npdet/DetectorChecksumRunAction.h +++ b/src/plugins/include/npdet/DetectorChecksumRunAction.h @@ -77,16 +77,18 @@ DetectorChecksumRunAction::getHashMap(Detector& detector) const { const auto start{std::chrono::steady_clock::now()}; DetectorChecksum checksum(detector); checksum.debug = 0; + checksum.max_level = -1; checksum.precision = 3; checksum.hash_meshes = true; checksum.hash_readout = true; + bool checksum_det_element_recursive = true; for (const auto& [name, det] : detector.world().children()) { if (m_ignoreDetectors.contains(name)) { continue; } checksum.analyzeDetector(det); DetectorChecksum::hashes_t hash_vec{checksum.handleHeader().hash}; - checksum.checksumDetElement(0, det, hash_vec, true); + checksum.checksumDetElement(0, det, hash_vec, checksum_det_element_recursive); DetectorChecksum::hash_t hash = dd4hep::detail::hash64(&hash_vec[0], hash_vec.size() * sizeof(DetectorChecksum::hash_t)); hashMap[name] = hash; From fff3bbaf82e6a203d67495849bc114fdaed4aa1a Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Mon, 18 Aug 2025 16:06:56 -0500 Subject: [PATCH 11/11] fix: avoid header warnings by not hashing; add help to disable --- src/plugins/include/npdet/DetectorChecksumRunAction.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/include/npdet/DetectorChecksumRunAction.h b/src/plugins/include/npdet/DetectorChecksumRunAction.h index 30b29af..c20dd7c 100644 --- a/src/plugins/include/npdet/DetectorChecksumRunAction.h +++ b/src/plugins/include/npdet/DetectorChecksumRunAction.h @@ -73,6 +73,7 @@ DetectorChecksumRunAction::getHashMap(Detector& detector) const { std::map hashMap; #if __has_include() // Determine detector checksum + printout(INFO,"DetectorChecksumRunAction::getHashMap", "determining checksum... (disable with --disableChecksum)"); // FIXME: ctor expects non-const detector const auto start{std::chrono::steady_clock::now()}; DetectorChecksum checksum(detector); @@ -87,7 +88,7 @@ DetectorChecksumRunAction::getHashMap(Detector& detector) const { continue; } checksum.analyzeDetector(det); - DetectorChecksum::hashes_t hash_vec{checksum.handleHeader().hash}; + DetectorChecksum::hashes_t hash_vec{}; checksum.checksumDetElement(0, det, hash_vec, checksum_det_element_recursive); DetectorChecksum::hash_t hash = dd4hep::detail::hash64(&hash_vec[0], hash_vec.size() * sizeof(DetectorChecksum::hash_t));