From 72729a5a0f4749125f8884076cdef4d3f5b542b0 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Fri, 2 Aug 2024 13:42:24 +0200 Subject: [PATCH 01/32] fix: Ensure ODD cleanup if sequencer stops in Examples Python tests --- Examples/Python/tests/conftest.py | 9 ++- Examples/Python/tests/test_examples.py | 83 +++++++++++++++++------ Examples/Python/tests/test_propagation.py | 9 ++- Examples/Python/tests/test_reader.py | 16 ++++- Examples/Python/tests/test_writer.py | 8 ++- 5 files changed, 101 insertions(+), 24 deletions(-) diff --git a/Examples/Python/tests/conftest.py b/Examples/Python/tests/conftest.py index b288b51f9b3..1615e153083 100644 --- a/Examples/Python/tests/conftest.py +++ b/Examples/Python/tests/conftest.py @@ -374,7 +374,14 @@ def _do_material_recording(d: Path): s = acts.examples.Sequencer(events=2, numThreads=1) runMaterialRecording(detectorConstructionFactory, str(d), tracksPerEvent=100, s=s) - s.run() + + try: + s.run() + finally: + # make sure to clean up if the test fails (otherwise segfault with ODD) + # also + # files are closed in destructors, not great + del s @pytest.fixture(scope="session") diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index 8cfe4fb5abd..9f65c377889 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -520,7 +520,13 @@ def test_event_recording(tmp_path): ) s.addAlgorithm(alg) - s.run() + try: + s.run() + finally: + # make sure to clean up if the test fails (otherwise segfault with ODD) + # also + # files are closed in destructors, not great + del s assert alg.events_seen == 1 @@ -713,11 +719,13 @@ def test_material_mapping(material_recording, tmp_path, assert_root_hash): s=s, ) - s.run() - - # MaterialMapping alg only writes on destruct. - # See https://github.com/acts-project/acts/issues/881 - del s + try: + s.run() + finally: + # make sure to clean up if the test fails (otherwise segfault with ODD) + # also + # files are closed in destructors, not great + del s mat_file = tmp_path / "material-map.json" @@ -754,7 +762,13 @@ def test_material_mapping(material_recording, tmp_path, assert_root_hash): 10, 1000, trackingGeometry, decorators, field, outputDir=str(tmp_path), s=s ) - s.run() + try: + s.run() + finally: + # make sure to clean up if the test fails (otherwise segfault with ODD) + # also + # files are closed in destructors, not great + del s assert val_file.exists() assert_entries(val_file, "material-tracks", 10000) @@ -792,11 +806,13 @@ def test_volume_material_mapping(material_recording, tmp_path, assert_root_hash) s=s, ) - s.run() - - # MaterialMapping alg only writes on destruct. - # See https://github.com/acts-project/acts/issues/881 - del s + try: + s.run() + finally: + # make sure to clean up if the test fails (otherwise segfault with ODD) + # also + # files are closed in destructors, not great + del s mat_file = tmp_path / "material-map-volume.json" @@ -840,7 +856,13 @@ def test_volume_material_mapping(material_recording, tmp_path, assert_root_hash) s=s, ) - s.run() + try: + s.run() + finally: + # make sure to clean up if the test fails (otherwise segfault with ODD) + # also + # files are closed in destructors, not great + del s assert val_file.exists() assert_root_hash(val_file.name, val_file) @@ -947,7 +969,13 @@ def test_digitization_example(trk_geo, tmp_path, assert_root_hash, digi_config_f trk_geo, field, outputDir=tmp_path, digiConfigFile=digi_config_file, s=s ) - s.run() + try: + s.run() + finally: + # make sure to clean up if the test fails (otherwise segfault with ODD) + # also + # files are closed in destructors, not great + del s assert root_file.exists() assert csv_dir.exists() @@ -976,7 +1004,14 @@ def test_digitization_example_input( ptcl_dir.mkdir() pgs = Sequencer(events=20, numThreads=-1) runParticleGun(str(ptcl_dir), s=pgs) - pgs.run() + + try: + pgs.run() + finally: + # make sure to clean up if the test fails (otherwise segfault with ODD) + # also + # files are closed in destructors, not great + del s s = Sequencer(numThreads=-1) @@ -1002,7 +1037,13 @@ def test_digitization_example_input( doMerge=True, ) - s.run() + try: + s.run() + finally: + # make sure to clean up if the test fails (otherwise segfault with ODD) + # also + # files are closed in destructors, not great + del s assert root_file.exists() assert csv_dir.exists() @@ -1102,9 +1143,13 @@ def test_ckf_tracks_example( s=s, ) - s.run() - - del s # files are closed in destructors, not great + try: + s.run() + finally: + # make sure to clean up if the test fails (otherwise segfault with ODD) + # also + # files are closed in destructors, not great + del s assert csv.exists() for rf, tn in root_files: diff --git a/Examples/Python/tests/test_propagation.py b/Examples/Python/tests/test_propagation.py index fdd03cca688..491992da66e 100644 --- a/Examples/Python/tests/test_propagation.py +++ b/Examples/Python/tests/test_propagation.py @@ -64,6 +64,13 @@ def test_steppers(conf_const, trk_geo): "propagation_steps", "chk_alg", level=acts.logging.WARNING ) seq.addAlgorithm(chkAlg) - seq.run() + + try: + seq.run() + finally: + # make sure to clean up if the test fails (otherwise segfault with ODD) + # also + # files are closed in destructors, not great + del s assert acts.StraightLineStepper() diff --git a/Examples/Python/tests/test_reader.py b/Examples/Python/tests/test_reader.py index e7bae0b9721..ac2f6e3a521 100644 --- a/Examples/Python/tests/test_reader.py +++ b/Examples/Python/tests/test_reader.py @@ -155,7 +155,13 @@ def test_root_material_track_reader(material_recording): ) s.addAlgorithm(alg) - s.run() + try: + s.run() + finally: + # make sure to clean up if the test fails (otherwise segfault with ODD) + # also + # files are closed in destructors, not great + del s assert alg.events_seen == 2 @@ -331,7 +337,13 @@ def test_edm4hep_simhit_particle_reader(tmp_path): ) s.addAlgorithm(alg) - s.run() + try: + s.run() + finally: + # make sure to clean up if the test fails (otherwise segfault with ODD) + # also + # files are closed in destructors, not great + del s assert alg.events_seen == 10 diff --git a/Examples/Python/tests/test_writer.py b/Examples/Python/tests/test_writer.py index 18dac96e96f..df64ed6a71a 100644 --- a/Examples/Python/tests/test_writer.py +++ b/Examples/Python/tests/test_writer.py @@ -482,7 +482,13 @@ def test_hepmc3_histogram(hepmc_data, tmp_path): ) s.addAlgorithm(alg) - s.run() + try: + s.run() + finally: + # make sure to clean up if the test fails (otherwise segfault with ODD) + # also + # files are closed in destructors, not great + del s @pytest.mark.edm4hep From 897ea5c0a0a6a8f4a6b9257a6b2aa18ded5b8084 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Fri, 2 Aug 2024 14:14:27 +0200 Subject: [PATCH 02/32] fix silly --- Examples/Python/tests/test_examples.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index 9f65c377889..f38c3a3cb50 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -1011,7 +1011,7 @@ def test_digitization_example_input( # make sure to clean up if the test fails (otherwise segfault with ODD) # also # files are closed in destructors, not great - del s + del pgs s = Sequencer(numThreads=-1) From 7aea01ecb3605d537fa4c26f7c47f566207ea1f4 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Wed, 7 Aug 2024 15:12:57 +0200 Subject: [PATCH 03/32] try use context manager --- .../DDG4/DDG4DetectorConstruction.hpp | 6 +- .../Geant4/src/DDG4DetectorConstruction.cpp | 26 +-- .../DD4hepDetector/DD4hepDetector.hpp | 22 +- .../DD4hepDetector/src/DD4hepDetector.cpp | 20 +- Examples/Python/python/acts/examples/odd.py | 19 +- Examples/Python/src/DD4hepComponent.cpp | 4 +- Examples/Python/tests/conftest.py | 21 +- Examples/Python/tests/test_examples.py | 191 +++++++----------- Examples/Python/tests/test_reader.py | 19 +- Examples/Python/tests/test_writer.py | 12 +- 10 files changed, 144 insertions(+), 196 deletions(-) diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp index 85237e94811..fe35764bef3 100644 --- a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp +++ b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp @@ -23,7 +23,7 @@ class Detector; namespace ActsExamples { namespace DD4hep { -struct DD4hepDetector; +class DD4hepDetector; } /// Construct the Geant4 detector from a DD4hep description. @@ -32,7 +32,6 @@ class DDG4DetectorConstruction final : public G4VUserDetectorConstruction { DDG4DetectorConstruction( std::shared_ptr detector, std::vector> regionCreators = {}); - ~DDG4DetectorConstruction() final; /// Convert the stored DD4hep detector to a Geant4 description. /// @@ -50,9 +49,6 @@ class DDG4DetectorConstruction final : public G4VUserDetectorConstruction { std::vector> m_regionCreators; /// The world volume G4VPhysicalVolume* m_world = nullptr; - - /// The DD4hep detector instance - dd4hep::Detector& dd4hepDetector() const; }; class DDG4DetectorConstructionFactory final diff --git a/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp b/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp index 74fa7831646..c79770252d3 100644 --- a/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp +++ b/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp @@ -22,28 +22,23 @@ class G4VPhysicalVolume; -ActsExamples::DDG4DetectorConstruction::DDG4DetectorConstruction( +namespace ActsExamples { + +DDG4DetectorConstruction::DDG4DetectorConstruction( std::shared_ptr detector, std::vector> regionCreators) : G4VUserDetectorConstruction(), m_detector(std::move(detector)), m_regionCreators(std::move(regionCreators)) {} -ActsExamples::DDG4DetectorConstruction::~DDG4DetectorConstruction() = default; - -dd4hep::Detector& ActsExamples::DDG4DetectorConstruction::dd4hepDetector() - const { - return m_detector->geometryService->detector(); -} - // See DD4hep::Simulation::Geant4DetectorConstruction::Construct() -G4VPhysicalVolume* ActsExamples::DDG4DetectorConstruction::Construct() { +G4VPhysicalVolume* DDG4DetectorConstruction::Construct() { if (m_world == nullptr) { dd4hep::sim::Geant4Mapping& g4map = dd4hep::sim::Geant4Mapping::instance(); - auto conv = dd4hep::sim::Geant4Converter(dd4hepDetector(), + auto conv = dd4hep::sim::Geant4Converter(m_detector->dd4hepDetector(), dd4hep::PrintLevel::VERBOSE); dd4hep::sim::Geant4GeometryInfo* geo_info = - conv.create(dd4hepDetector().world()).detach(); + conv.create(m_detector->dd4hepDetector().world()).detach(); g4map.attach(geo_info); // All volumes are deleted in ~G4PhysicalVolumeStore() m_world = geo_info->world(); @@ -58,17 +53,18 @@ G4VPhysicalVolume* ActsExamples::DDG4DetectorConstruction::Construct() { return m_world; } -ActsExamples::DDG4DetectorConstructionFactory::DDG4DetectorConstructionFactory( +DDG4DetectorConstructionFactory::DDG4DetectorConstructionFactory( std::shared_ptr detector, std::vector> regionCreators) : m_detector(std::move(detector)), m_regionCreators(std::move(regionCreators)) {} -ActsExamples::DDG4DetectorConstructionFactory:: - ~DDG4DetectorConstructionFactory() = default; +DDG4DetectorConstructionFactory::~DDG4DetectorConstructionFactory() = default; std::unique_ptr -ActsExamples::DDG4DetectorConstructionFactory::factorize() const { +DDG4DetectorConstructionFactory::factorize() const { return std::make_unique(m_detector, m_regionCreators); } + +} // namespace ActsExamples diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp index bda365d6df9..a034fe9ce1d 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2018-2019 CERN for the benefit of the Acts project +// Copyright (C) 2018-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -37,7 +37,8 @@ class IContextDecorator; namespace ActsExamples::DD4hep { -struct DD4hepDetector { +class DD4hepDetector { + public: /// @brief The context decorators using ContextDecorators = std::vector>; @@ -52,16 +53,10 @@ struct DD4hepDetector { DD4hepDetector() = default; /// @brief Constructor from geometry service /// @param _geometryService the geometry service - DD4hepDetector(std::shared_ptr _geometryService); + DD4hepDetector(std::unique_ptr geometryService); /// @brief Default destructor ~DD4hepDetector() = default; - /// @brief The DD4hep geometry service - std::shared_ptr geometryService = nullptr; - - // @brief the compact file names - std::vector compactFiles = {}; - /// @brief Build the tracking geometry from the DD4hep geometry /// /// @param config is the configuration of the geometry service @@ -90,6 +85,15 @@ struct DD4hepDetector { /// @brief Access to the DD4hep field /// @return a shared pointer to the DD4hep field std::shared_ptr field() const; + + dd4hep::Detector& dd4hepDetector() const { + return m_geometryService->detector(); + } + + void free(); + + private: + std::unique_ptr m_geometryService = nullptr; }; } // namespace ActsExamples::DD4hep diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp index 919ff0668bc..9558b42a5f9 100644 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2019 CERN for the benefit of the Acts project +// Copyright (C) 2019-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -26,8 +26,8 @@ namespace ActsExamples::DD4hep { DD4hepDetector::DD4hepDetector( - std::shared_ptr _geometryService) - : geometryService(std::move(_geometryService)) {} + std::unique_ptr geometryService) + : m_geometryService(std::move(geometryService)) {} auto DD4hepDetector::finalize( ActsExamples::DD4hep::DD4hepGeometryService::Config config, @@ -35,10 +35,10 @@ auto DD4hepDetector::finalize( -> std::pair { Acts::GeometryContext dd4HepContext; config.matDecorator = std::move(mdecorator); - geometryService = - std::make_shared(config); + m_geometryService = + std::make_unique(config); TrackingGeometryPtr dd4tGeometry = - geometryService->trackingGeometry(dd4HepContext); + m_geometryService->trackingGeometry(dd4HepContext); if (!dd4tGeometry) { throw std::runtime_error{ "Did not receive tracking geometry from DD4hep geometry service"}; @@ -54,13 +54,13 @@ auto DD4hepDetector::finalize( const Acts::Experimental::DD4hepDetectorStructure::Options& options) -> std::tuple { - if (geometryService == nullptr) { + if (m_geometryService == nullptr) { throw std::runtime_error{ "No DD4hep geometry service configured, can not build " "TrackingGeometry."}; } - auto world = geometryService->geometry(); + auto world = m_geometryService->geometry(); // Build the detector structure Acts::Experimental::DD4hepDetectorStructure dd4hepStructure( Acts::getDefaultLogger("DD4hepDetectorStructure", options.logLevel)); @@ -76,9 +76,11 @@ auto DD4hepDetector::finalize( } std::shared_ptr DD4hepDetector::field() const { - const auto& detector = geometryService->detector(); + const auto& detector = m_geometryService->detector(); return std::make_shared(detector.field()); } +void DD4hepDetector::free() { m_geometryService.reset(); } + } // namespace ActsExamples::DD4hep diff --git a/Examples/Python/python/acts/examples/odd.py b/Examples/Python/python/acts/examples/odd.py index ec8cbcb9438..34bf9b9e77c 100644 --- a/Examples/Python/python/acts/examples/odd.py +++ b/Examples/Python/python/acts/examples/odd.py @@ -3,6 +3,7 @@ import math from pathlib import Path from typing import Optional +from collections import namedtuple import acts import acts.examples @@ -101,4 +102,20 @@ def geoid_hook(geoid, surface): trackingGeometry, deco = detector.finalize(dd4hepConfig, mdecorator) - return detector, trackingGeometry, deco + OpenDataDetector = namedtuple( + "OpenDataDetector", ["detector", "trackingGeometry", "decorator"] + ) + + class OpenDataDetectorWithContextManager(OpenDataDetector): + def __new__(cls, detector, trackingGeometry, decorator): + return super(OpenDataDetectorWithContextManager, cls).__new__( + cls, detector, trackingGeometry, decorator + ) + + def __enter__(self): + return self + + def __exit__(self): + self.detector.free() + + return OpenDataDetectorWithContextManager(detector, trackingGeometry, deco) diff --git a/Examples/Python/src/DD4hepComponent.cpp b/Examples/Python/src/DD4hepComponent.cpp index 091842f6783..65d433ed669 100644 --- a/Examples/Python/src/DD4hepComponent.cpp +++ b/Examples/Python/src/DD4hepComponent.cpp @@ -38,7 +38,7 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { { using Config = ActsExamples::DD4hep::DD4hepGeometryService::Config; auto s = py::class_>( + std::unique_ptr>( m, "DD4hepGeometryService") .def(py::init()); @@ -157,7 +157,6 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { py::class_>( m, "DD4hepDetector") .def(py::init<>()) - .def(py::init>()) .def("finalize", py::overload_cast>( @@ -167,6 +166,7 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { const Acts::GeometryContext&, const Acts::Experimental::DD4hepDetectorStructure::Options&>( &DD4hep::DD4hepDetector::finalize)) + .def("free", &DD4hep::DD4hepDetector::free) .def_property_readonly("field", &DD4hep::DD4hepDetector::field); } } diff --git a/Examples/Python/tests/conftest.py b/Examples/Python/tests/conftest.py index 1615e153083..afde1fe540c 100644 --- a/Examples/Python/tests/conftest.py +++ b/Examples/Python/tests/conftest.py @@ -365,23 +365,18 @@ def _factory(s): def _do_material_recording(d: Path): from material_recording import runMaterialRecording - detector, trackingGeometry, decorators = getOpenDataDetector() - - detectorConstructionFactory = ( - acts.examples.geant4.dd4hep.DDG4DetectorConstructionFactory(detector) - ) - s = acts.examples.Sequencer(events=2, numThreads=1) - runMaterialRecording(detectorConstructionFactory, str(d), tracksPerEvent=100, s=s) + with getOpenDataDetector() as (detector, trackingGeometry, decorators): + detectorConstructionFactory = ( + acts.examples.geant4.dd4hep.DDG4DetectorConstructionFactory(detector) + ) + + runMaterialRecording( + detectorConstructionFactory, str(d), tracksPerEvent=100, s=s + ) - try: s.run() - finally: - # make sure to clean up if the test fails (otherwise segfault with ODD) - # also - # files are closed in destructors, not great - del s @pytest.fixture(scope="session") diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index 5c29bbd3701..e17476f8915 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -520,13 +520,7 @@ def test_event_recording(tmp_path): ) s.addAlgorithm(alg) - try: - s.run() - finally: - # make sure to clean up if the test fails (otherwise segfault with ODD) - # also - # files are closed in destructors, not great - del s + s.run() assert alg.events_seen == 1 @@ -694,11 +688,12 @@ def test_particle_gun(tmp_path, assert_root_hash): @pytest.mark.odd @pytest.mark.skipif(not dd4hepEnabled, reason="DD4hep not set up") def test_material_mapping(material_recording, tmp_path, assert_root_hash): + from material_mapping import runMaterialMapping + from material_validation import runMaterialValidation + map_file = tmp_path / "material-map_tracks.root" assert not map_file.exists() - s = Sequencer(numThreads=1) - odd_dir = getOpenDataDetectorDirectory() config = acts.MaterialMapJsonConverter.Config() mdecorator = acts.JsonMaterialDecorator( @@ -706,24 +701,21 @@ def test_material_mapping(material_recording, tmp_path, assert_root_hash): rConfig=config, jFileName=str(odd_dir / "config/odd-material-mapping-config.json"), ) - detector, trackingGeometry, decorators = getOpenDataDetector(mdecorator) - from material_mapping import runMaterialMapping + s = Sequencer(numThreads=1) - runMaterialMapping( - trackingGeometry, - decorators, - outputDir=str(tmp_path), - inputDir=material_recording, - mappingStep=1, - s=s, - ) + with getOpenDataDetector(mdecorator) as (detector, trackingGeometry, decorators): + runMaterialMapping( + trackingGeometry, + decorators, + outputDir=str(tmp_path), + inputDir=material_recording, + mappingStep=1, + s=s, + ) - try: s.run() - finally: - # make sure to clean up if the test fails (otherwise segfault with ODD) - # also + # files are closed in destructors, not great del s @@ -744,29 +736,21 @@ def test_material_mapping(material_recording, tmp_path, assert_root_hash): # test the validation as well - # we need to destroy the ODD to reload with material - del trackingGeometry - del detector - - detector, trackingGeometry, decorators = getOpenDataDetector( - mdecorator=acts.IMaterialDecorator.fromFile(mat_file), - ) - - from material_validation import runMaterialValidation + field = acts.NullBField() s = Sequencer(events=10, numThreads=1) - field = acts.NullBField() - - runMaterialValidation( - 10, 1000, trackingGeometry, decorators, field, outputDir=str(tmp_path), s=s - ) + with getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(mat_file)) as ( + detector, + trackingGeometry, + decorators, + ): + runMaterialValidation( + 10, 1000, trackingGeometry, decorators, field, outputDir=str(tmp_path), s=s + ) - try: s.run() - finally: - # make sure to clean up if the test fails (otherwise segfault with ODD) - # also + # files are closed in destructors, not great del s @@ -779,40 +763,39 @@ def test_material_mapping(material_recording, tmp_path, assert_root_hash): @pytest.mark.odd @pytest.mark.skipif(not dd4hepEnabled, reason="DD4hep not set up") def test_volume_material_mapping(material_recording, tmp_path, assert_root_hash): + from material_mapping import runMaterialMapping + from material_validation import runMaterialValidation + map_file = tmp_path / "material-map-volume_tracks.root" assert not map_file.exists() - s = Sequencer(numThreads=1) - geo_map = Path(__file__).parent / "geometry-volume-map.json" assert geo_map.exists() assert geo_map.stat().st_size > 10 with geo_map.open() as fh: assert json.load(fh) - detector, trackingGeometry, decorators = getOpenDataDetector( - mdecorator=acts.IMaterialDecorator.fromFile(geo_map), - ) - - from material_mapping import runMaterialMapping + s = Sequencer(numThreads=1) - runMaterialMapping( + with getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(geo_map)) as ( + detector, trackingGeometry, decorators, - mapName="material-map-volume", - outputDir=str(tmp_path), - inputDir=material_recording, - mappingStep=1, - s=s, - ) + ): + runMaterialMapping( + trackingGeometry, + decorators, + mapName="material-map-volume", + outputDir=str(tmp_path), + inputDir=material_recording, + mappingStep=1, + s=s, + ) - try: s.run() - finally: - # make sure to clean up if the test fails (otherwise segfault with ODD) - # also - # files are closed in destructors, not great - del s + + # files are closed in destructors, not great + del s mat_file = tmp_path / "material-map-volume.json" @@ -831,38 +814,30 @@ def test_volume_material_mapping(material_recording, tmp_path, assert_root_hash) # test the validation as well - # we need to destroy the ODD to reload with material - del trackingGeometry - del detector - - detector, trackingGeometry, decorators = getOpenDataDetector( - mdecorator=acts.IMaterialDecorator.fromFile(mat_file), - ) - - from material_validation import runMaterialValidation + field = acts.NullBField() s = Sequencer(events=10, numThreads=1) - field = acts.NullBField() - - runMaterialValidation( - 10, - 1000, + with getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(mat_file)) as ( + detector, trackingGeometry, decorators, - field, - outputDir=str(tmp_path), - outputName="propagation-volume-material", - s=s, - ) + ): + runMaterialValidation( + 10, + 1000, + trackingGeometry, + decorators, + field, + outputDir=str(tmp_path), + outputName="propagation-volume-material", + s=s, + ) - try: s.run() - finally: - # make sure to clean up if the test fails (otherwise segfault with ODD) - # also - # files are closed in destructors, not great - del s + + # files are closed in destructors, not great + del s assert val_file.exists() assert_root_hash(val_file.name, val_file) @@ -969,13 +944,10 @@ def test_digitization_example(trk_geo, tmp_path, assert_root_hash, digi_config_f trk_geo, field, outputDir=tmp_path, digiConfigFile=digi_config_file, s=s ) - try: - s.run() - finally: - # make sure to clean up if the test fails (otherwise segfault with ODD) - # also - # files are closed in destructors, not great - del s + s.run() + + # files are closed in destructors, not great + del s assert root_file.exists() assert csv_dir.exists() @@ -1005,13 +977,10 @@ def test_digitization_example_input( pgs = Sequencer(events=20, numThreads=-1) runParticleGun(str(ptcl_dir), s=pgs) - try: - pgs.run() - finally: - # make sure to clean up if the test fails (otherwise segfault with ODD) - # also - # files are closed in destructors, not great - del pgs + pgs.run() + + # files are closed in destructors, not great + del pgs s = Sequencer(numThreads=-1) @@ -1037,13 +1006,10 @@ def test_digitization_example_input( doMerge=True, ) - try: - s.run() - finally: - # make sure to clean up if the test fails (otherwise segfault with ODD) - # also - # files are closed in destructors, not great - del s + s.run() + + # files are closed in destructors, not great + del s assert root_file.exists() assert csv_dir.exists() @@ -1143,13 +1109,10 @@ def test_ckf_tracks_example( s=s, ) - try: - s.run() - finally: - # make sure to clean up if the test fails (otherwise segfault with ODD) - # also - # files are closed in destructors, not great - del s + s.run() + + # files are closed in destructors, not great + del s assert csv.exists() for rf, tn in root_files: diff --git a/Examples/Python/tests/test_reader.py b/Examples/Python/tests/test_reader.py index ac2f6e3a521..5ece91d1681 100644 --- a/Examples/Python/tests/test_reader.py +++ b/Examples/Python/tests/test_reader.py @@ -132,10 +132,7 @@ def test_root_reader_interface(reader, conf_const, tmp_path): assert conf_const(reader, **kw) -@pytest.mark.slow @pytest.mark.root -@pytest.mark.odd -@pytest.mark.skipif(not geant4Enabled, reason="Geant4 not set up") def test_root_material_track_reader(material_recording): input_tracks = material_recording / "geant4_material_tracks.root" assert input_tracks.exists() @@ -155,13 +152,7 @@ def test_root_material_track_reader(material_recording): ) s.addAlgorithm(alg) - try: - s.run() - finally: - # make sure to clean up if the test fails (otherwise segfault with ODD) - # also - # files are closed in destructors, not great - del s + s.run() assert alg.events_seen == 2 @@ -337,13 +328,7 @@ def test_edm4hep_simhit_particle_reader(tmp_path): ) s.addAlgorithm(alg) - try: - s.run() - finally: - # make sure to clean up if the test fails (otherwise segfault with ODD) - # also - # files are closed in destructors, not great - del s + s.run() assert alg.events_seen == 10 diff --git a/Examples/Python/tests/test_writer.py b/Examples/Python/tests/test_writer.py index df64ed6a71a..476f696b79e 100644 --- a/Examples/Python/tests/test_writer.py +++ b/Examples/Python/tests/test_writer.py @@ -441,10 +441,6 @@ def hepmc_data(hepmc_data_impl: Path, tmp_path): @pytest.mark.skipif(not hepmc3Enabled, reason="HepMC3 plugin not available") -@pytest.mark.skipif(not dd4hepEnabled, reason="DD4hep not set up") -@pytest.mark.skipif(not geant4Enabled, reason="Geant4 not set up") -@pytest.mark.odd -@pytest.mark.slow def test_hepmc3_histogram(hepmc_data, tmp_path): from acts.examples.hepmc3 import ( HepMC3AsciiReader, @@ -482,13 +478,7 @@ def test_hepmc3_histogram(hepmc_data, tmp_path): ) s.addAlgorithm(alg) - try: - s.run() - finally: - # make sure to clean up if the test fails (otherwise segfault with ODD) - # also - # files are closed in destructors, not great - del s + s.run() @pytest.mark.edm4hep From bc8dc51da791a73a877b8437dc5db63e3d405921 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Wed, 7 Aug 2024 15:56:03 +0200 Subject: [PATCH 04/32] random stuff --- .../DD4hepDetector/DD4hepDetector.hpp | 21 +++++++------- .../DD4hepDetector/DD4hepGeometryService.hpp | 14 ++++++---- .../DD4hepDetector/src/DD4hepDetector.cpp | 8 +++++- .../src/DD4hepGeometryService.cpp | 28 +++++++++---------- 4 files changed, 39 insertions(+), 32 deletions(-) diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp index a034fe9ce1d..527e03531cc 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp @@ -26,11 +26,12 @@ namespace Acts { class TrackingGeometry; class IMaterialDecorator; class DD4hepFieldAdapter; -namespace Experimental { -class Detector; -} // namespace Experimental } // namespace Acts +namespace Acts::Examples { +class Detector; +} // namespace Acts::Examples + namespace ActsExamples { class IContextDecorator; } // namespace ActsExamples @@ -43,7 +44,7 @@ class DD4hepDetector { using ContextDecorators = std::vector>; - /// @brief The tracking geometry + /// @brief The tracking geometry using TrackingGeometryPtr = std::shared_ptr; /// @brief The detector geometry @@ -51,11 +52,11 @@ class DD4hepDetector { /// @brief Default constructor DD4hepDetector() = default; + /// @brief Constructor from geometry service - /// @param _geometryService the geometry service - DD4hepDetector(std::unique_ptr geometryService); - /// @brief Default destructor - ~DD4hepDetector() = default; + /// @param geometryService the geometry service + explicit DD4hepDetector( + std::unique_ptr geometryService); /// @brief Build the tracking geometry from the DD4hep geometry /// @@ -86,9 +87,7 @@ class DD4hepDetector { /// @return a shared pointer to the DD4hep field std::shared_ptr field() const; - dd4hep::Detector& dd4hepDetector() const { - return m_geometryService->detector(); - } + dd4hep::Detector& dd4hepDetector() const; void free(); diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp index 25415977e2f..dc2325d8b6c 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2017 CERN for the benefit of the Acts project +// Copyright (C) 2017-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -27,13 +27,15 @@ #include class TGeoNode; + +namespace dd4hep { +class Detector; +} // namespace dd4hep + namespace Acts { class IMaterialDecorator; class TrackingGeometry; } // namespace Acts -namespace dd4hep { -class Detector; -} // namespace dd4hep namespace ActsExamples::DD4hep { @@ -44,8 +46,8 @@ void sortFCChhDetElements(std::vector& det); /// @brief service creating geometries from dd4hep input /// /// The DD4hepGeometryService creates the DD4hep, the TGeo and the ACTS -/// TrackingGeometry -/// from DD4hep xml input. The geometries are created only on demand. +/// TrackingGeometry from DD4hep xml input. The geometries are created only on +/// demand. class DD4hepGeometryService { public: struct Config { diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp index 9558b42a5f9..9198c39ec61 100644 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp @@ -81,6 +81,12 @@ std::shared_ptr DD4hepDetector::field() const { return std::make_shared(detector.field()); } -void DD4hepDetector::free() { m_geometryService.reset(); } +dd4hep::Detector& DD4hepDetector::dd4hepDetector() const { + return m_geometryService->detector(); +} + +void DD4hepDetector::free() { + m_geometryService.reset(); +} } // namespace ActsExamples::DD4hep diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp index da57423a65f..821d3288fc5 100644 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2017 CERN for the benefit of the Acts project +// Copyright (C) 2017-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -25,8 +25,10 @@ class TGeoNode; -ActsExamples::DD4hep::DD4hepGeometryService::DD4hepGeometryService( - const ActsExamples::DD4hep::DD4hepGeometryService::Config& cfg) +namespace ActsExamples::DD4hep { + +DD4hepGeometryService::DD4hepGeometryService( + const DD4hepGeometryService::Config& cfg) : m_cfg(cfg), m_logger{Acts::getDefaultLogger("DD4hepGeometryService", cfg.logLevel)} { if (m_cfg.xmlFileNames.empty()) { @@ -34,14 +36,13 @@ ActsExamples::DD4hep::DD4hepGeometryService::DD4hepGeometryService( } } -ActsExamples::DD4hep::DD4hepGeometryService::~DD4hepGeometryService() { +DD4hepGeometryService::~DD4hepGeometryService() { if (m_detector != nullptr) { m_detector->destroyInstance(); } } -ActsExamples::ProcessCode -ActsExamples::DD4hep::DD4hepGeometryService::buildDD4hepGeometry() { +ActsExamples::ProcessCode DD4hepGeometryService::buildDD4hepGeometry() { const int old_gErrorIgnoreLevel = gErrorIgnoreLevel; switch (m_cfg.dd4hepLogLevel) { case Acts::Logging::Level::VERBOSE: @@ -89,30 +90,28 @@ ActsExamples::DD4hep::DD4hepGeometryService::buildDD4hepGeometry() { return ActsExamples::ProcessCode::SUCCESS; } -dd4hep::Detector& -ActsExamples::DD4hep::DD4hepGeometryService::DD4hepGeometryService::detector() { +dd4hep::Detector& DD4hepGeometryService::DD4hepGeometryService::detector() { if (m_detector == nullptr) { buildDD4hepGeometry(); } return *m_detector; } -dd4hep::DetElement& ActsExamples::DD4hep::DD4hepGeometryService::geometry() { +dd4hep::DetElement& DD4hepGeometryService::geometry() { if (!m_geometry) { buildDD4hepGeometry(); } return m_geometry; } -TGeoNode& ActsExamples::DD4hep::DD4hepGeometryService::tgeoGeometry() { +TGeoNode& DD4hepGeometryService::tgeoGeometry() { if (!m_geometry) { buildDD4hepGeometry(); } return *m_geometry.placement().ptr(); } -ActsExamples::ProcessCode -ActsExamples::DD4hep::DD4hepGeometryService::buildTrackingGeometry( +ActsExamples::ProcessCode DD4hepGeometryService::buildTrackingGeometry( const Acts::GeometryContext& gctx) { // Set the tracking geometry auto logger = Acts::getDefaultLogger("DD4hepConversion", m_cfg.logLevel); @@ -125,14 +124,15 @@ ActsExamples::DD4hep::DD4hepGeometryService::buildTrackingGeometry( } std::shared_ptr -ActsExamples::DD4hep::DD4hepGeometryService::trackingGeometry( - const Acts::GeometryContext& gctx) { +DD4hepGeometryService::trackingGeometry(const Acts::GeometryContext& gctx) { if (!m_trackingGeometry) { buildTrackingGeometry(gctx); } return m_trackingGeometry; } +} // namespace ActsExamples::DD4hep + void ActsExamples::DD4hep::sortFCChhDetElements( std::vector& det) { std::vector tracker; From cbb24c22d48f1c38e4cdd65fc2c3c31a1294592d Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Wed, 7 Aug 2024 16:57:28 +0200 Subject: [PATCH 05/32] fix edm4hep --- Examples/Io/EDM4hep/src/EDM4hepReader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Examples/Io/EDM4hep/src/EDM4hepReader.cpp b/Examples/Io/EDM4hep/src/EDM4hepReader.cpp index 34cbf1e345a..02e3148b346 100644 --- a/Examples/Io/EDM4hep/src/EDM4hepReader.cpp +++ b/Examples/Io/EDM4hep/src/EDM4hepReader.cpp @@ -325,8 +325,8 @@ ProcessCode EDM4hepReader::read(const AlgorithmContext& ctx) { [&](std::uint64_t cellId) { ACTS_VERBOSE("CellID: " << cellId); - const auto& vm = m_cfg.dd4hepDetector->geometryService->detector() - .volumeManager(); + const auto& vm = + m_cfg.dd4hepDetector->dd4hepDetector().volumeManager(); const auto detElement = vm.lookupDetElement(cellId); From 3520feea344628c5c2793aa6afeefc66fe071d34 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Wed, 7 Aug 2024 19:16:10 +0200 Subject: [PATCH 06/32] refactor dd4hep examples --- .../DDG4/DDG4DetectorConstruction.hpp | 11 ++- .../Geant4/src/DDG4DetectorConstruction.cpp | 17 ++-- .../Detectors/DD4hepDetector/CMakeLists.txt | 1 - .../DD4hepDetector/DD4hepDetector.hpp | 98 ------------------- .../DD4hepDetector/DD4hepGeometryService.hpp | 24 +++-- .../DD4hepDetector/src/DD4hepDetector.cpp | 92 ----------------- .../src/DD4hepGeometryService.cpp | 11 +++ Examples/Python/python/acts/examples/odd.py | 7 +- Examples/Python/src/DD4hepComponent.cpp | 29 ++---- Examples/Python/src/Geant4DD4hepComponent.cpp | 7 +- 10 files changed, 58 insertions(+), 239 deletions(-) delete mode 100644 Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp delete mode 100644 Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp index fe35764bef3..370d450309c 100644 --- a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp +++ b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp @@ -8,6 +8,7 @@ #pragma once +#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" #include "ActsExamples/Geant4/DetectorConstructionFactory.hpp" #include "ActsExamples/Geant4/RegionCreator.hpp" @@ -23,14 +24,14 @@ class Detector; namespace ActsExamples { namespace DD4hep { -class DD4hepDetector; +class DD4hepGeometryService; } /// Construct the Geant4 detector from a DD4hep description. class DDG4DetectorConstruction final : public G4VUserDetectorConstruction { public: DDG4DetectorConstruction( - std::shared_ptr detector, + std::shared_ptr geometryService, std::vector> regionCreators = {}); /// Convert the stored DD4hep detector to a Geant4 description. @@ -44,7 +45,7 @@ class DDG4DetectorConstruction final : public G4VUserDetectorConstruction { private: /// The Acts DD4hep detector instance - std::shared_ptr m_detector; + std::shared_ptr m_geometryService; /// Region creators std::vector> m_regionCreators; /// The world volume @@ -55,7 +56,7 @@ class DDG4DetectorConstructionFactory final : public DetectorConstructionFactory { public: DDG4DetectorConstructionFactory( - std::shared_ptr detector, + std::shared_ptr geometryService, std::vector> regionCreators = {}); ~DDG4DetectorConstructionFactory() final; @@ -63,7 +64,7 @@ class DDG4DetectorConstructionFactory final private: /// The Acts DD4hep detector instance - std::shared_ptr m_detector; + std::shared_ptr m_geometryService; /// Region creators std::vector> m_regionCreators; }; diff --git a/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp b/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp index c79770252d3..637ed3f7227 100644 --- a/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp +++ b/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp @@ -8,7 +8,7 @@ #include "ActsExamples/DDG4/DDG4DetectorConstruction.hpp" -#include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" +#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" #include #include @@ -18,27 +18,26 @@ #include #include #include -#include class G4VPhysicalVolume; namespace ActsExamples { DDG4DetectorConstruction::DDG4DetectorConstruction( - std::shared_ptr detector, + std::shared_ptr geometryService, std::vector> regionCreators) : G4VUserDetectorConstruction(), - m_detector(std::move(detector)), + m_geometryService(std::move(geometryService)), m_regionCreators(std::move(regionCreators)) {} // See DD4hep::Simulation::Geant4DetectorConstruction::Construct() G4VPhysicalVolume* DDG4DetectorConstruction::Construct() { if (m_world == nullptr) { dd4hep::sim::Geant4Mapping& g4map = dd4hep::sim::Geant4Mapping::instance(); - auto conv = dd4hep::sim::Geant4Converter(m_detector->dd4hepDetector(), + auto conv = dd4hep::sim::Geant4Converter(m_geometryService->detector(), dd4hep::PrintLevel::VERBOSE); dd4hep::sim::Geant4GeometryInfo* geo_info = - conv.create(m_detector->dd4hepDetector().world()).detach(); + conv.create(m_geometryService->detector().world()).detach(); g4map.attach(geo_info); // All volumes are deleted in ~G4PhysicalVolumeStore() m_world = geo_info->world(); @@ -54,16 +53,16 @@ G4VPhysicalVolume* DDG4DetectorConstruction::Construct() { } DDG4DetectorConstructionFactory::DDG4DetectorConstructionFactory( - std::shared_ptr detector, + std::shared_ptr geometryService, std::vector> regionCreators) - : m_detector(std::move(detector)), + : m_geometryService(std::move(geometryService)), m_regionCreators(std::move(regionCreators)) {} DDG4DetectorConstructionFactory::~DDG4DetectorConstructionFactory() = default; std::unique_ptr DDG4DetectorConstructionFactory::factorize() const { - return std::make_unique(m_detector, + return std::make_unique(m_geometryService, m_regionCreators); } diff --git a/Examples/Detectors/DD4hepDetector/CMakeLists.txt b/Examples/Detectors/DD4hepDetector/CMakeLists.txt index 88192fdbd4e..847ab8f4d23 100644 --- a/Examples/Detectors/DD4hepDetector/CMakeLists.txt +++ b/Examples/Detectors/DD4hepDetector/CMakeLists.txt @@ -1,6 +1,5 @@ add_library( ActsExamplesDetectorDD4hep SHARED - src/DD4hepDetector.cpp src/DD4hepGeometryService.cpp) diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp deleted file mode 100644 index 527e03531cc..00000000000 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp +++ /dev/null @@ -1,98 +0,0 @@ -// This file is part of the Acts project. -// -// Copyright (C) 2018-2024 CERN for the benefit of the Acts project -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#pragma once - -#include "Acts/MagneticField/MagneticFieldProvider.hpp" -#include "Acts/Plugins/DD4hep/DD4hepDetectorElement.hpp" -#include "Acts/Plugins/DD4hep/DD4hepDetectorStructure.hpp" -#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" - -#include -#include -#include -#include - -namespace dd4hep { -class Detector; -} // namespace dd4hep - -namespace Acts { -class TrackingGeometry; -class IMaterialDecorator; -class DD4hepFieldAdapter; -} // namespace Acts - -namespace Acts::Examples { -class Detector; -} // namespace Acts::Examples - -namespace ActsExamples { -class IContextDecorator; -} // namespace ActsExamples - -namespace ActsExamples::DD4hep { - -class DD4hepDetector { - public: - /// @brief The context decorators - using ContextDecorators = - std::vector>; - - /// @brief The tracking geometry - using TrackingGeometryPtr = std::shared_ptr; - - /// @brief The detector geometry - using DetectorPtr = std::shared_ptr; - - /// @brief Default constructor - DD4hepDetector() = default; - - /// @brief Constructor from geometry service - /// @param geometryService the geometry service - explicit DD4hepDetector( - std::unique_ptr geometryService); - - /// @brief Build the tracking geometry from the DD4hep geometry - /// - /// @param config is the configuration of the geometry service - /// @param mdecorator is the material decorator provided - /// - /// @return a pair of tracking geometry and context decorators - std::pair finalize( - DD4hepGeometryService::Config config, - std::shared_ptr mdecorator); - - /// @brief Build the detector from the DD4hep geometry - /// - /// @param gctx is the geometry context - /// @param options is the options struct for the building process - /// - /// @note the lifetime of the detector store has to exceed that of the - /// detector object as the converted surfaces point back to the - /// detector elements - /// - /// @return a tuple of detector, context decorators, and the element store - std::tuple - finalize( - const Acts::GeometryContext& gctx, - const Acts::Experimental::DD4hepDetectorStructure::Options& options = {}); - - /// @brief Access to the DD4hep field - /// @return a shared pointer to the DD4hep field - std::shared_ptr field() const; - - dd4hep::Detector& dd4hepDetector() const; - - void free(); - - private: - std::unique_ptr m_geometryService = nullptr; -}; - -} // namespace ActsExamples::DD4hep diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp index dc2325d8b6c..f1ba9c743ad 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp @@ -8,14 +8,14 @@ #pragma once +#include "Acts/Definitions/Units.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/GeometryIdentifier.hpp" +#include "Acts/Geometry/TrackingGeometry.hpp" +#include "Acts/Material/IMaterialDecorator.hpp" +#include "Acts/Utilities/BinningType.hpp" +#include "Acts/Utilities/Logger.hpp" #include "ActsExamples/Framework/ProcessCode.hpp" -#include -#include -#include -#include -#include #include #include @@ -37,6 +37,10 @@ class IMaterialDecorator; class TrackingGeometry; } // namespace Acts +namespace ActsExamples { +class IContextDecorator; +} // namespace ActsExamples + namespace ActsExamples::DD4hep { void sortFCChhDetElements(std::vector& det); @@ -50,6 +54,10 @@ void sortFCChhDetElements(std::vector& det); /// demand. class DD4hepGeometryService { public: + /// @brief The context decorators + using ContextDecorators = + std::vector>; + struct Config { /// Log level for the geometry service. Acts::Logging::Level logLevel = Acts::Logging::Level::INFO; @@ -78,7 +86,7 @@ class DD4hepGeometryService { /// the layers (e.g. barrel, endcap volumes) have no specific shape /// (assemblies) double envelopeZ = 1 * Acts::UnitConstants::mm; - double defaultLayerThickness = 10e-10; + double defaultLayerThickness = 1e-10; std::function& detectors)> sortDetectors = sortFCChhDetElements; /// Material decorator @@ -109,6 +117,10 @@ class DD4hepGeometryService { std::shared_ptr trackingGeometry( const Acts::GeometryContext& gctx); + ContextDecorators contextDecorators() const; + + void drop(); + private: /// Private method to initiate building of the DD4hep geometry ActsExamples::ProcessCode buildDD4hepGeometry(); diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp deleted file mode 100644 index 9198c39ec61..00000000000 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// This file is part of the Acts project. -// -// Copyright (C) 2019-2024 CERN for the benefit of the Acts project -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" - -#include "Acts/Geometry/GeometryContext.hpp" -#include "Acts/MagneticField/MagneticFieldProvider.hpp" -#include "Acts/Plugins/DD4hep/DD4hepFieldAdapter.hpp" -#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" - -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace ActsExamples::DD4hep { - -DD4hepDetector::DD4hepDetector( - std::unique_ptr geometryService) - : m_geometryService(std::move(geometryService)) {} - -auto DD4hepDetector::finalize( - ActsExamples::DD4hep::DD4hepGeometryService::Config config, - std::shared_ptr mdecorator) - -> std::pair { - Acts::GeometryContext dd4HepContext; - config.matDecorator = std::move(mdecorator); - m_geometryService = - std::make_unique(config); - TrackingGeometryPtr dd4tGeometry = - m_geometryService->trackingGeometry(dd4HepContext); - if (!dd4tGeometry) { - throw std::runtime_error{ - "Did not receive tracking geometry from DD4hep geometry service"}; - } - ContextDecorators dd4ContextDecorators = {}; - // return the pair of geometry and empty decorators - return std::make_pair( - std::move(dd4tGeometry), std::move(dd4ContextDecorators)); -} - -auto DD4hepDetector::finalize( - const Acts::GeometryContext& gctx, - const Acts::Experimental::DD4hepDetectorStructure::Options& options) - -> std::tuple { - if (m_geometryService == nullptr) { - throw std::runtime_error{ - "No DD4hep geometry service configured, can not build " - "TrackingGeometry."}; - } - - auto world = m_geometryService->geometry(); - // Build the detector structure - Acts::Experimental::DD4hepDetectorStructure dd4hepStructure( - Acts::getDefaultLogger("DD4hepDetectorStructure", options.logLevel)); - - /// @return a detector and the detector store - auto [detector, detectorElements] = - dd4hepStructure.construct(gctx, world, options); - - // Prepare the return objects - ContextDecorators contextDecorators = {}; - - return {detector, contextDecorators, detectorElements}; -} - -std::shared_ptr DD4hepDetector::field() const { - const auto& detector = m_geometryService->detector(); - - return std::make_shared(detector.field()); -} - -dd4hep::Detector& DD4hepDetector::dd4hepDetector() const { - return m_geometryService->detector(); -} - -void DD4hepDetector::free() { - m_geometryService.reset(); -} - -} // namespace ActsExamples::DD4hep diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp index 821d3288fc5..dc2e92e1cab 100644 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp @@ -131,6 +131,17 @@ DD4hepGeometryService::trackingGeometry(const Acts::GeometryContext& gctx) { return m_trackingGeometry; } +DD4hepGeometryService::ContextDecorators +DD4hepGeometryService::contextDecorators() const { + return ContextDecorators{}; +} + +void DD4hepGeometryService::drop() { + m_detector = nullptr; + m_geometry = dd4hep::DetElement(); + m_trackingGeometry.reset(); +} + } // namespace ActsExamples::DD4hep void ActsExamples::DD4hep::sortFCChhDetElements( diff --git a/Examples/Python/python/acts/examples/odd.py b/Examples/Python/python/acts/examples/odd.py index 34bf9b9e77c..3e631794eaa 100644 --- a/Examples/Python/python/acts/examples/odd.py +++ b/Examples/Python/python/acts/examples/odd.py @@ -92,7 +92,7 @@ def geoid_hook(geoid, surface): dd4hepLogLevel=customLogLevel(), geometryIdentifierHook=acts.GeometryIdentifierHook(geoid_hook), ) - detector = acts.examples.dd4hep.DD4hepDetector() + detector = acts.examples.dd4hep.DD4hepGeometryService(dd4hepConfig) if mdecorator is None: mdecorator = acts.examples.RootMaterialDecorator( @@ -100,7 +100,8 @@ def geoid_hook(geoid, surface): level=customLogLevel(minLevel=acts.logging.WARNING), ) - trackingGeometry, deco = detector.finalize(dd4hepConfig, mdecorator) + trackingGeometry = detector.trackingGeometry() + deco = detector.contextDecorators() OpenDataDetector = namedtuple( "OpenDataDetector", ["detector", "trackingGeometry", "decorator"] @@ -116,6 +117,6 @@ def __enter__(self): return self def __exit__(self): - self.detector.free() + self.detector.drop() return OpenDataDetectorWithContextManager(detector, trackingGeometry, deco) diff --git a/Examples/Python/src/DD4hepComponent.cpp b/Examples/Python/src/DD4hepComponent.cpp index 65d433ed669..9b272533535 100644 --- a/Examples/Python/src/DD4hepComponent.cpp +++ b/Examples/Python/src/DD4hepComponent.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2021 CERN for the benefit of the Acts project +// Copyright (C) 2021-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -13,7 +13,6 @@ #include "Acts/Plugins/DD4hep/DD4hepIdentifierMapper.hpp" #include "Acts/Plugins/Python/Utilities.hpp" #include "Acts/Utilities/Logger.hpp" -#include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" #include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" #include "ActsExamples/Framework/IContextDecorator.hpp" #include "ActsExamples/Framework/ProcessCode.hpp" @@ -40,7 +39,12 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { auto s = py::class_>( m, "DD4hepGeometryService") - .def(py::init()); + .def(py::init()) + .def("drop", &DD4hep::DD4hepGeometryService::drop) + .def("trackingGeometry", + &DD4hep::DD4hepGeometryService::trackingGeometry) + .def("contextDecorators", + &DD4hep::DD4hepGeometryService::contextDecorators); auto c = py::class_(s, "Config").def(py::init<>()); ACTS_PYTHON_STRUCT_BEGIN(c, Config); @@ -88,7 +92,7 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { const auto* dd4hepDetElement = dynamic_cast(dde); // Check if it is valid - if (dd4hepDetElement) { + if (dd4hepDetElement != nullptr) { dd4hep::DDSegmentation::VolumeID dd4hepID = dd4hepDetElement->sourceElement().volumeID(); auto geoID = surface->geometryId(); @@ -152,21 +156,4 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { options.geoIdGenerator = chainedGeoIdGenerator; }); } - - { - py::class_>( - m, "DD4hepDetector") - .def(py::init<>()) - .def("finalize", - py::overload_cast>( - &DD4hep::DD4hepDetector::finalize)) - .def("finalize", - py::overload_cast< - const Acts::GeometryContext&, - const Acts::Experimental::DD4hepDetectorStructure::Options&>( - &DD4hep::DD4hepDetector::finalize)) - .def("free", &DD4hep::DD4hepDetector::free) - .def_property_readonly("field", &DD4hep::DD4hepDetector::field); - } } diff --git a/Examples/Python/src/Geant4DD4hepComponent.cpp b/Examples/Python/src/Geant4DD4hepComponent.cpp index a6684e7eab8..0e29dc72266 100644 --- a/Examples/Python/src/Geant4DD4hepComponent.cpp +++ b/Examples/Python/src/Geant4DD4hepComponent.cpp @@ -6,8 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "Acts/Utilities/TypeTraits.hpp" -#include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" +#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" #include "ActsExamples/DDG4/DDG4DetectorConstruction.hpp" #include "ActsExamples/Framework/ProcessCode.hpp" #include "ActsExamples/Geant4/RegionCreator.hpp" @@ -29,9 +28,9 @@ PYBIND11_MODULE(ActsPythonBindingsDDG4, m) { py::class_>( m, "DDG4DetectorConstructionFactory") - .def(py::init, + .def(py::init, std::vector>>(), - py::arg("detector"), + py::arg("geometryService"), py::arg("regionCreators") = std::vector>()); } From af9ced1daf558528e1b2573f8d77a2e509eacc3d Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Wed, 7 Aug 2024 19:32:17 +0200 Subject: [PATCH 07/32] make full_chain_odd work again --- .../DD4hepDetector/DD4hepGeometryService.hpp | 2 ++ .../DD4hepDetector/src/DD4hepGeometryService.cpp | 9 +++++++++ Examples/Python/python/acts/_adapter.py | 12 +++++------- Examples/Python/python/acts/examples/dd4hep.py | 4 ++-- Examples/Python/src/DD4hepComponent.cpp | 7 ++++++- 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp index f1ba9c743ad..59488bcfff3 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp @@ -111,6 +111,8 @@ class DD4hepGeometryService { /// @return The world TGeoNode (physical volume) TGeoNode& tgeoGeometry(); + std::shared_ptr trackingGeometry(); + /// Interface method to access the ACTS TrackingGeometry /// /// @param gctx is the geometry context object diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp index dc2e92e1cab..6e477fb9cf1 100644 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp @@ -123,6 +123,15 @@ ActsExamples::ProcessCode DD4hepGeometryService::buildTrackingGeometry( return ActsExamples::ProcessCode::SUCCESS; } +std::shared_ptr +DD4hepGeometryService::trackingGeometry() { + Acts::GeometryContext gctx; + if (!m_trackingGeometry) { + buildTrackingGeometry(gctx); + } + return m_trackingGeometry; +} + std::shared_ptr DD4hepGeometryService::trackingGeometry(const Acts::GeometryContext& gctx) { if (!m_trackingGeometry) { diff --git a/Examples/Python/python/acts/_adapter.py b/Examples/Python/python/acts/_adapter.py index 112fbf7f631..d05e0d57bdc 100644 --- a/Examples/Python/python/acts/_adapter.py +++ b/Examples/Python/python/acts/_adapter.py @@ -109,14 +109,12 @@ def create(*args, mdecorator=None, **kwargs): cfg = cls.Config() else: cfg = config_class() - _kwargs = {} + setattr(cfg, "matDecorator", mdecorator) for k, v in kwargs.items(): - try: - setattr(cfg, k, v) - except AttributeError: - _kwargs[k] = v - det = cls() - tg, deco = det.finalize(cfg, mdecorator, *args, **_kwargs) + setattr(cfg, k, v) + det = cls(cfg) + tg = det.trackingGeometry() + deco = det.contextDecorators() return det, tg, deco return create diff --git a/Examples/Python/python/acts/examples/dd4hep.py b/Examples/Python/python/acts/examples/dd4hep.py index f68dc38453a..e19df7722b4 100644 --- a/Examples/Python/python/acts/examples/dd4hep.py +++ b/Examples/Python/python/acts/examples/dd4hep.py @@ -16,8 +16,8 @@ from acts import ActsPythonBindingsDD4hep _patch_config(ActsPythonBindingsDD4hep) -ActsPythonBindingsDD4hep.DD4hepDetector.create = _detector_create( - ActsPythonBindingsDD4hep.DD4hepDetector, +ActsPythonBindingsDD4hep.DD4hepGeometryService.create = _detector_create( + ActsPythonBindingsDD4hep.DD4hepGeometryService, ActsPythonBindingsDD4hep.DD4hepGeometryService.Config, ) diff --git a/Examples/Python/src/DD4hepComponent.cpp b/Examples/Python/src/DD4hepComponent.cpp index 9b272533535..aefef99c18c 100644 --- a/Examples/Python/src/DD4hepComponent.cpp +++ b/Examples/Python/src/DD4hepComponent.cpp @@ -7,6 +7,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include "Acts/Detector/GeometryIdGenerator.hpp" +#include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Plugins/DD4hep/DD4hepDetectorElement.hpp" #include "Acts/Plugins/DD4hep/DD4hepDetectorStructure.hpp" #include "Acts/Plugins/DD4hep/DD4hepFieldAdapter.hpp" @@ -42,7 +43,11 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { .def(py::init()) .def("drop", &DD4hep::DD4hepGeometryService::drop) .def("trackingGeometry", - &DD4hep::DD4hepGeometryService::trackingGeometry) + py::overload_cast<>( + &DD4hep::DD4hepGeometryService::trackingGeometry)) + .def("trackingGeometry", + py::overload_cast( + &DD4hep::DD4hepGeometryService::trackingGeometry)) .def("contextDecorators", &DD4hep::DD4hepGeometryService::contextDecorators); From b8d1fa10e5cdd876e91000119b915d24ae3a5887 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Wed, 7 Aug 2024 19:42:36 +0200 Subject: [PATCH 08/32] remove all `del s` --- CI/physmon/workflows/physmon_ckf_tracking.py | 1 - CI/physmon/workflows/physmon_simulation.py | 1 - .../workflows/physmon_track_finding_ttbar.py | 1 - .../workflows/physmon_truth_tracking_gsf.py | 1 - .../workflows/physmon_truth_tracking_gx2f.py | 1 - .../physmon_truth_tracking_kalman.py | 1 - CI/physmon/workflows/physmon_vertexing.py | 2 -- Examples/Python/tests/test_examples.py | 35 ------------------- Examples/Python/tests/test_propagation.py | 8 +---- Examples/Python/tests/test_reader.py | 4 --- Examples/Python/tests/test_writer.py | 1 - .../Orion/material_mapping_optimisation.py | 9 ----- Examples/Scripts/Python/geant4_parallel.py | 1 - 13 files changed, 1 insertion(+), 65 deletions(-) diff --git a/CI/physmon/workflows/physmon_ckf_tracking.py b/CI/physmon/workflows/physmon_ckf_tracking.py index 969224f14aa..b50269adb35 100755 --- a/CI/physmon/workflows/physmon_ckf_tracking.py +++ b/CI/physmon/workflows/physmon_ckf_tracking.py @@ -226,7 +226,6 @@ def run_ckf_tracking(truthSmearedSeeded, truthEstimatedSeeded, label): ) s.run() - del s for vertexing in ["ivf", "amvf"]: shutil.move( diff --git a/CI/physmon/workflows/physmon_simulation.py b/CI/physmon/workflows/physmon_simulation.py index f5e9069cb2e..060bc93478b 100755 --- a/CI/physmon/workflows/physmon_simulation.py +++ b/CI/physmon/workflows/physmon_simulation.py @@ -97,7 +97,6 @@ ) s.run() - del s for file, name in [ (tp / "fatras" / "particles_simulation.root", "particles_fatras.root"), diff --git a/CI/physmon/workflows/physmon_track_finding_ttbar.py b/CI/physmon/workflows/physmon_track_finding_ttbar.py index ad159a36380..67546422a79 100755 --- a/CI/physmon/workflows/physmon_track_finding_ttbar.py +++ b/CI/physmon/workflows/physmon_track_finding_ttbar.py @@ -157,7 +157,6 @@ ) s.run() - del s for vertexing in ["amvf", "amvf_gridseeder"]: shutil.move( diff --git a/CI/physmon/workflows/physmon_truth_tracking_gsf.py b/CI/physmon/workflows/physmon_truth_tracking_gsf.py index d56cd603f23..e2f85b20da5 100755 --- a/CI/physmon/workflows/physmon_truth_tracking_gsf.py +++ b/CI/physmon/workflows/physmon_truth_tracking_gsf.py @@ -27,7 +27,6 @@ ) s.run() - del s perf_file = tp / "performance_gsf.root" assert perf_file.exists(), "Performance file not found" diff --git a/CI/physmon/workflows/physmon_truth_tracking_gx2f.py b/CI/physmon/workflows/physmon_truth_tracking_gx2f.py index 019fc6b5114..76334bfed11 100755 --- a/CI/physmon/workflows/physmon_truth_tracking_gx2f.py +++ b/CI/physmon/workflows/physmon_truth_tracking_gx2f.py @@ -27,7 +27,6 @@ ) s.run() - del s perf_file = tp / "performance_gx2f.root" assert perf_file.exists(), "Performance file not found" diff --git a/CI/physmon/workflows/physmon_truth_tracking_kalman.py b/CI/physmon/workflows/physmon_truth_tracking_kalman.py index 712dca6ac43..430f2bb8e1b 100755 --- a/CI/physmon/workflows/physmon_truth_tracking_kalman.py +++ b/CI/physmon/workflows/physmon_truth_tracking_kalman.py @@ -27,7 +27,6 @@ ) s.run() - del s perf_file = tp / "performance_track_fitter.root" assert perf_file.exists(), "Performance file not found" diff --git a/CI/physmon/workflows/physmon_vertexing.py b/CI/physmon/workflows/physmon_vertexing.py index 2486923b019..2afd47437b1 100755 --- a/CI/physmon/workflows/physmon_vertexing.py +++ b/CI/physmon/workflows/physmon_vertexing.py @@ -148,8 +148,6 @@ def run_vertexing(fitter, mu, events): s.run() - del s - perf_file = tp / f"performance_vertexing.root" assert perf_file.exists(), "Performance file not found" shutil.copy( diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index e17476f8915..10c7815f71c 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -87,8 +87,6 @@ def test_pythia8(tmp_path, seq, assert_root_hash): runPythia8(str(tmp_path), outputRoot=True, outputCsv=True, s=seq).run() - del seq - fp = tmp_path / "pythia8_particles.root" assert fp.exists() assert fp.stat().st_size > 2**10 * 50 @@ -125,8 +123,6 @@ def test_fatras(trk_geo, tmp_path, field, assert_root_hash): seq = Sequencer(events=nevents) runFatras(trk_geo, field, str(tmp_path), s=seq).run() - del seq - assert_csv_output(csv, "particles_final") assert_csv_output(csv, "particles_initial") assert_csv_output(csv, "hits") @@ -228,8 +224,6 @@ def test_seeding(tmp_path, trk_geo, field, assert_root_hash): runSeeding(trk_geo, field, outputDir=str(tmp_path), s=seq).run() - del seq - for fn, tn in root_files: fp = tmp_path / fn assert fp.exists() @@ -287,8 +281,6 @@ def test_seeding_orthogonal(tmp_path, trk_geo, field, assert_root_hash): seedingAlgorithm=SeedingAlgorithm.Orthogonal, ).run() - del seq - for fn, tn in root_files: fp = tmp_path / fn assert fp.exists() @@ -397,8 +389,6 @@ def test_itk_seeding(tmp_path, trk_geo, field, assert_root_hash): seq.run() - del seq - for fn, tn in root_files: fp = tmp_path / fn assert fp.exists() @@ -558,8 +548,6 @@ def test_truth_tracking_kalman( seq.run() - del seq - for fn, tn, ee in root_files: fp = tmp_path / fn assert fp.exists() @@ -618,8 +606,6 @@ def test_truth_tracking_gsf(tmp_path, assert_root_hash, detector_config): with failure_threshold(acts.logging.FATAL): seq.run() - del seq - for fn, tn in root_files: fp = tmp_path / fn assert fp.exists() @@ -716,9 +702,6 @@ def test_material_mapping(material_recording, tmp_path, assert_root_hash): s.run() - # files are closed in destructors, not great - del s - mat_file = tmp_path / "material-map.json" assert mat_file.exists() @@ -751,9 +734,6 @@ def test_material_mapping(material_recording, tmp_path, assert_root_hash): s.run() - # files are closed in destructors, not great - del s - assert val_file.exists() assert_entries(val_file, "material-tracks", 10000) assert_root_hash(val_file.name, val_file) @@ -794,9 +774,6 @@ def test_volume_material_mapping(material_recording, tmp_path, assert_root_hash) s.run() - # files are closed in destructors, not great - del s - mat_file = tmp_path / "material-map-volume.json" assert mat_file.exists() @@ -836,9 +813,6 @@ def test_volume_material_mapping(material_recording, tmp_path, assert_root_hash) s.run() - # files are closed in destructors, not great - del s - assert val_file.exists() assert_root_hash(val_file.name, val_file) @@ -946,9 +920,6 @@ def test_digitization_example(trk_geo, tmp_path, assert_root_hash, digi_config_f s.run() - # files are closed in destructors, not great - del s - assert root_file.exists() assert csv_dir.exists() @@ -1008,9 +979,6 @@ def test_digitization_example_input( s.run() - # files are closed in destructors, not great - del s - assert root_file.exists() assert csv_dir.exists() @@ -1111,9 +1079,6 @@ def test_ckf_tracks_example( s.run() - # files are closed in destructors, not great - del s - assert csv.exists() for rf, tn in root_files: rp = tmp_path / rf diff --git a/Examples/Python/tests/test_propagation.py b/Examples/Python/tests/test_propagation.py index 491992da66e..fca8f851039 100644 --- a/Examples/Python/tests/test_propagation.py +++ b/Examples/Python/tests/test_propagation.py @@ -65,12 +65,6 @@ def test_steppers(conf_const, trk_geo): ) seq.addAlgorithm(chkAlg) - try: - seq.run() - finally: - # make sure to clean up if the test fails (otherwise segfault with ODD) - # also - # files are closed in destructors, not great - del s + seq.run() assert acts.StraightLineStepper() diff --git a/Examples/Python/tests/test_reader.py b/Examples/Python/tests/test_reader.py index 5ece91d1681..3f2c30ed49b 100644 --- a/Examples/Python/tests/test_reader.py +++ b/Examples/Python/tests/test_reader.py @@ -45,8 +45,6 @@ def test_root_particle_reader(tmp_path, conf_const, ptcl_gun): s.run() - del s # to properly close the root file - # reset sequencer for reading s2 = Sequencer(numThreads=1, logLevel=acts.logging.WARNING) @@ -418,8 +416,6 @@ def test_edm4hep_tracks_reader(tmp_path): s.run() - del s - s = Sequencer(numThreads=1) s.addReader( EDM4hepTrackReader( diff --git a/Examples/Python/tests/test_writer.py b/Examples/Python/tests/test_writer.py index 476f696b79e..f9c1ae0d6c4 100644 --- a/Examples/Python/tests/test_writer.py +++ b/Examples/Python/tests/test_writer.py @@ -398,7 +398,6 @@ def test_csv_multitrajectory_writer(tmp_path): ) ) s.run() - del s assert len([f for f in csv_dir.iterdir() if f.is_file()]) == 10 assert all(f.stat().st_size > 20 for f in csv_dir.iterdir()) diff --git a/Examples/Scripts/Python/Auto-tuning/Orion/material_mapping_optimisation.py b/Examples/Scripts/Python/Auto-tuning/Orion/material_mapping_optimisation.py index f459252b185..0ebdf68d537 100755 --- a/Examples/Scripts/Python/Auto-tuning/Orion/material_mapping_optimisation.py +++ b/Examples/Scripts/Python/Auto-tuning/Orion/material_mapping_optimisation.py @@ -199,10 +199,6 @@ def runMaterialMappingVariance( s=sMap, ) sMap.run() - del sMap # Need to be deleted to write the material map to cbor - del detector - del trackingGeometry - del decorators # Compute the variance by rerunning the mapping print( @@ -300,11 +296,6 @@ def runMaterialMappingVariance( ) pipeResult.send(score) - del mapping - del s - del detectorVar - del trackingGeometryVar - del decoratorsVar os.remove(cborMap) diff --git a/Examples/Scripts/Python/geant4_parallel.py b/Examples/Scripts/Python/geant4_parallel.py index 50c861be45f..1cb0fa0e894 100755 --- a/Examples/Scripts/Python/geant4_parallel.py +++ b/Examples/Scripts/Python/geant4_parallel.py @@ -59,7 +59,6 @@ def runGeant4EventRange(beginEvent, endEvent, outputDir): ) s.run() - del s if "__main__" == __name__: From 2de978e39932977c3a47f030280909b16b1898cb Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Wed, 7 Aug 2024 19:51:40 +0200 Subject: [PATCH 09/32] fix edm4hep --- .../ActsExamples/Io/EDM4hep/EDM4hepReader.hpp | 4 ++-- Examples/Io/EDM4hep/src/EDM4hepReader.cpp | 4 ++-- Examples/Python/src/EDM4hepComponent.cpp | 15 ++++++++------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp b/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp index 51c716aaa4b..9058dde8558 100644 --- a/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp +++ b/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp @@ -27,7 +27,7 @@ namespace ActsExamples { namespace DD4hep { -struct DD4hepDetector; +struct DD4hepGeometryService; } /// Read particles from EDM4hep. @@ -59,7 +59,7 @@ class EDM4hepReader final : public IReader { std::string graphvizOutput = ""; /// DD4hep detector for cellID resolution. - std::shared_ptr dd4hepDetector; + std::shared_ptr dd4hepGeometryService; /// Tracking geometry for cellID resolution. std::shared_ptr trackingGeometry; diff --git a/Examples/Io/EDM4hep/src/EDM4hepReader.cpp b/Examples/Io/EDM4hep/src/EDM4hepReader.cpp index 02e3148b346..506afd532fe 100644 --- a/Examples/Io/EDM4hep/src/EDM4hepReader.cpp +++ b/Examples/Io/EDM4hep/src/EDM4hepReader.cpp @@ -12,7 +12,7 @@ #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/GeometryIdentifier.hpp" #include "Acts/Plugins/DD4hep/DD4hepDetectorElement.hpp" -#include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" +#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" #include "ActsExamples/EventData/SimHit.hpp" #include "ActsExamples/EventData/SimParticle.hpp" #include "ActsExamples/Framework/WhiteBoard.hpp" @@ -326,7 +326,7 @@ ProcessCode EDM4hepReader::read(const AlgorithmContext& ctx) { ACTS_VERBOSE("CellID: " << cellId); const auto& vm = - m_cfg.dd4hepDetector->dd4hepDetector().volumeManager(); + m_cfg.dd4hepGeometryService->detector().volumeManager(); const auto detElement = vm.lookupDetElement(cellId); diff --git a/Examples/Python/src/EDM4hepComponent.cpp b/Examples/Python/src/EDM4hepComponent.cpp index 3f780230c4e..cce41213c84 100644 --- a/Examples/Python/src/EDM4hepComponent.cpp +++ b/Examples/Python/src/EDM4hepComponent.cpp @@ -1,13 +1,13 @@ // This file is part of the Acts project. // -// Copyright (C) 2022 CERN for the benefit of the Acts project +// Copyright (C) 2022-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include "Acts/Plugins/Python/Utilities.hpp" -#include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" +#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" #include "ActsExamples/Io/EDM4hep/EDM4hepMeasurementReader.hpp" #include "ActsExamples/Io/EDM4hep/EDM4hepMeasurementWriter.hpp" #include "ActsExamples/Io/EDM4hep/EDM4hepMultiTrajectoryWriter.hpp" @@ -29,11 +29,12 @@ using namespace Acts; using namespace Acts::Python; PYBIND11_MODULE(ActsPythonBindingsEDM4hep, m) { - ACTS_PYTHON_DECLARE_READER( - ActsExamples::EDM4hepReader, m, "EDM4hepReader", inputPath, - inputParticles, inputSimHits, outputParticlesInitial, - outputParticlesFinal, outputParticlesGenerator, outputSimHits, - graphvizOutput, dd4hepDetector, trackingGeometry, sortSimHitsInTime); + ACTS_PYTHON_DECLARE_READER(ActsExamples::EDM4hepReader, m, "EDM4hepReader", + inputPath, inputParticles, inputSimHits, + outputParticlesInitial, outputParticlesFinal, + outputParticlesGenerator, outputSimHits, + graphvizOutput, dd4hepGeometryService, + trackingGeometry, sortSimHitsInTime); ACTS_PYTHON_DECLARE_WRITER( ActsExamples::EDM4hepSimHitWriter, m, "EDM4hepSimHitWriter", inputSimHits, From 90ebfd98919586cf305895a78e1f699c09f622a7 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Wed, 7 Aug 2024 23:21:26 +0200 Subject: [PATCH 10/32] refactor again --- Examples/Python/python/acts/_adapter.py | 9 +-- Examples/Python/python/acts/examples/odd.py | 34 +++++------ Examples/Python/src/DD4hepComponent.cpp | 10 +++- Examples/Python/tests/conftest.py | 5 +- Examples/Python/tests/test_detectors.py | 7 ++- Examples/Python/tests/test_examples.py | 58 +++++++++++-------- Examples/Python/tests/test_reader.py | 57 +++++++++--------- .../Orion/material_mapping_optimisation.py | 7 --- .../train_seed_solver.py | 5 -- Examples/Scripts/Python/event_recording.py | 2 +- Examples/Scripts/Python/full_chain_odd.py | 2 +- Examples/Scripts/Python/geant4.py | 6 +- Examples/Scripts/Python/geant4_parallel.py | 9 +-- Examples/Scripts/Python/geometry.py | 6 +- Examples/Scripts/Python/material_recording.py | 2 +- Examples/Scripts/Python/seeding.py | 4 +- Examples/Scripts/Python/truth_tracking_gsf.py | 2 +- .../Python/truth_tracking_gsf_refitting.py | 4 +- .../Scripts/Python/truth_tracking_gx2f.py | 2 +- .../Scripts/Python/truth_tracking_kalman.py | 2 +- docs/examples/howto/material_mapping.rst | 2 +- 21 files changed, 118 insertions(+), 117 deletions(-) diff --git a/Examples/Python/python/acts/_adapter.py b/Examples/Python/python/acts/_adapter.py index d05e0d57bdc..ac5bd4a76cb 100644 --- a/Examples/Python/python/acts/_adapter.py +++ b/Examples/Python/python/acts/_adapter.py @@ -112,10 +112,11 @@ def create(*args, mdecorator=None, **kwargs): setattr(cfg, "matDecorator", mdecorator) for k, v in kwargs.items(): setattr(cfg, k, v) - det = cls(cfg) - tg = det.trackingGeometry() - deco = det.contextDecorators() - return det, tg, deco + detector = cls(cfg) + trackingGeometry = detector.trackingGeometry() + decorators = detector.contextDecorators() + contextManager = None + return detector, trackingGeometry, decorators, contextManager return create diff --git a/Examples/Python/python/acts/examples/odd.py b/Examples/Python/python/acts/examples/odd.py index 3e631794eaa..778837f71da 100644 --- a/Examples/Python/python/acts/examples/odd.py +++ b/Examples/Python/python/acts/examples/odd.py @@ -3,7 +3,6 @@ import math from pathlib import Path from typing import Optional -from collections import namedtuple import acts import acts.examples @@ -86,37 +85,32 @@ def geoid_hook(geoid, surface): return geoid + if mdecorator is None: + mdecorator = acts.examples.RootMaterialDecorator( + fileName=str(odd_dir / "data/odd-material-maps.root"), + level=customLogLevel(minLevel=acts.logging.WARNING), + ) + dd4hepConfig = acts.examples.dd4hep.DD4hepGeometryService.Config( xmlFileNames=[str(odd_xml)], logLevel=customLogLevel(), dd4hepLogLevel=customLogLevel(), geometryIdentifierHook=acts.GeometryIdentifierHook(geoid_hook), + matDecorator=mdecorator, ) detector = acts.examples.dd4hep.DD4hepGeometryService(dd4hepConfig) - if mdecorator is None: - mdecorator = acts.examples.RootMaterialDecorator( - fileName=str(odd_dir / "data/odd-material-maps.root"), - level=customLogLevel(minLevel=acts.logging.WARNING), - ) - trackingGeometry = detector.trackingGeometry() - deco = detector.contextDecorators() - - OpenDataDetector = namedtuple( - "OpenDataDetector", ["detector", "trackingGeometry", "decorator"] - ) - - class OpenDataDetectorWithContextManager(OpenDataDetector): - def __new__(cls, detector, trackingGeometry, decorator): - return super(OpenDataDetectorWithContextManager, cls).__new__( - cls, detector, trackingGeometry, decorator - ) + decorators = detector.contextDecorators() + class ContextManager: + def __init__(self, detector): + self.detector = detector def __enter__(self): return self - def __exit__(self): self.detector.drop() - return OpenDataDetectorWithContextManager(detector, trackingGeometry, deco) + contextManager = ContextManager(detector) + + return detector, trackingGeometry, decorators, contextManager diff --git a/Examples/Python/src/DD4hepComponent.cpp b/Examples/Python/src/DD4hepComponent.cpp index aefef99c18c..dbf91f34ada 100644 --- a/Examples/Python/src/DD4hepComponent.cpp +++ b/Examples/Python/src/DD4hepComponent.cpp @@ -36,12 +36,11 @@ using namespace Acts::Python; PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { { - using Config = ActsExamples::DD4hep::DD4hepGeometryService::Config; + using Config = DD4hep::DD4hepGeometryService::Config; auto s = py::class_>( m, "DD4hepGeometryService") .def(py::init()) - .def("drop", &DD4hep::DD4hepGeometryService::drop) .def("trackingGeometry", py::overload_cast<>( &DD4hep::DD4hepGeometryService::trackingGeometry)) @@ -49,7 +48,11 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { py::overload_cast( &DD4hep::DD4hepGeometryService::trackingGeometry)) .def("contextDecorators", - &DD4hep::DD4hepGeometryService::contextDecorators); + &DD4hep::DD4hepGeometryService::contextDecorators) + .def("drop", &DD4hep::DD4hepGeometryService::drop) + .def("__enter__", [](py::object self) { return self; }) + .def("__exit__", + [](DD4hep::DD4hepGeometryService& self) { self.drop(); }); auto c = py::class_(s, "Config").def(py::init<>()); ACTS_PYTHON_STRUCT_BEGIN(c, Config); @@ -63,6 +66,7 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { ACTS_PYTHON_MEMBER(envelopeR); ACTS_PYTHON_MEMBER(envelopeZ); ACTS_PYTHON_MEMBER(defaultLayerThickness); + ACTS_PYTHON_MEMBER(matDecorator); ACTS_PYTHON_MEMBER(geometryIdentifierHook); ACTS_PYTHON_STRUCT_END(); diff --git a/Examples/Python/tests/conftest.py b/Examples/Python/tests/conftest.py index afde1fe540c..5cc712b0299 100644 --- a/Examples/Python/tests/conftest.py +++ b/Examples/Python/tests/conftest.py @@ -280,7 +280,6 @@ def detector_config(request): ), name=request.param, ) - else: raise ValueError(f"Invalid detector {detector}") @@ -367,7 +366,9 @@ def _do_material_recording(d: Path): s = acts.examples.Sequencer(events=2, numThreads=1) - with getOpenDataDetector() as (detector, trackingGeometry, decorators): + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + + with contextManager: detectorConstructionFactory = ( acts.examples.geant4.dd4hep.DDG4DetectorConstructionFactory(detector) ) diff --git a/Examples/Python/tests/test_detectors.py b/Examples/Python/tests/test_detectors.py index a9574bee621..0f2278da3da 100644 --- a/Examples/Python/tests/test_detectors.py +++ b/Examples/Python/tests/test_detectors.py @@ -53,11 +53,12 @@ def test_telescope_geometry(): @pytest.mark.skipif(not dd4hepEnabled, reason="DD4hep is not set up") def test_odd(): - detector, trackingGeometry, decorators = getOpenDataDetector() + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() - trackingGeometry.visitSurfaces(check_extra_odd) + with contextManager: + trackingGeometry.visitSurfaces(check_extra_odd) - assert count_surfaces(trackingGeometry) == 18824 + assert count_surfaces(trackingGeometry) == 18824 def test_aligned_detector(): diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index 10c7815f71c..5e5dcaceaf9 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -141,7 +141,11 @@ def test_fatras(trk_geo, tmp_path, field, assert_root_hash): @pytest.mark.skipif(not dd4hepEnabled, reason="DD4hep not set up") def test_geant4(tmp_path, assert_root_hash): # This test literally only ensures that the geant 4 example can run without erroring out - getOpenDataDetector() # just to make sure it can build + + # just to make sure it can build the odd + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + with contextManager: + pass csv = tmp_path / "csv" csv.mkdir() @@ -690,7 +694,9 @@ def test_material_mapping(material_recording, tmp_path, assert_root_hash): s = Sequencer(numThreads=1) - with getOpenDataDetector(mdecorator) as (detector, trackingGeometry, decorators): + detector, trackingGeometry, decorators = getOpenDataDetector(mdecorator) + + with detector: runMaterialMapping( trackingGeometry, decorators, @@ -723,11 +729,9 @@ def test_material_mapping(material_recording, tmp_path, assert_root_hash): s = Sequencer(events=10, numThreads=1) - with getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(mat_file)) as ( - detector, - trackingGeometry, - decorators, - ): + detector, trackingGeometry, decorators = getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(mat_file)) + + with detector: runMaterialValidation( 10, 1000, trackingGeometry, decorators, field, outputDir=str(tmp_path), s=s ) @@ -757,11 +761,9 @@ def test_volume_material_mapping(material_recording, tmp_path, assert_root_hash) s = Sequencer(numThreads=1) - with getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(geo_map)) as ( - detector, - trackingGeometry, - decorators, - ): + detector, trackingGeometry, decorators = getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(geo_map)) + + with detector: runMaterialMapping( trackingGeometry, decorators, @@ -795,11 +797,9 @@ def test_volume_material_mapping(material_recording, tmp_path, assert_root_hash) s = Sequencer(events=10, numThreads=1) - with getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(mat_file)) as ( - detector, - trackingGeometry, - decorators, - ): + detector, trackingGeometry, decorators = getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(mat_file)) + + with detector: runMaterialValidation( 10, 1000, @@ -950,9 +950,6 @@ def test_digitization_example_input( pgs.run() - # files are closed in destructors, not great - del pgs - s = Sequencer(numThreads=-1) csv_dir = tmp_path / "csv" @@ -1097,7 +1094,11 @@ def test_ckf_tracks_example( @pytest.mark.slow def test_full_chain_odd_example(tmp_path): # This test literally only ensures that the full chain example can run without erroring out - getOpenDataDetector() # just to make sure it can build + + # just to make sure it can build the odd + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + with contextManager: + pass script = ( Path(__file__).parent.parent.parent.parent @@ -1127,7 +1128,11 @@ def test_full_chain_odd_example(tmp_path): @pytest.mark.slow def test_full_chain_odd_example_pythia_geant4(tmp_path): # This test literally only ensures that the full chain example can run without erroring out - getOpenDataDetector() # just to make sure it can build + + # just to make sure it can build the odd + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + with contextManager: + pass script = ( Path(__file__).parent.parent.parent.parent @@ -1173,11 +1178,16 @@ def test_full_chain_odd_example_pythia_geant4(tmp_path): @pytest.mark.skipif(not onnxEnabled, reason="ONNX plugin not enabled") @pytest.mark.slow def test_ML_Ambiguity_Solver(tmp_path, assert_root_hash): + # This test literally only ensures that the full chain example can run without erroring out + root_file = "performance_ambiML.root" output_dir = "odd_output" assert not (tmp_path / root_file).exists() - # This test literally only ensures that the full chain example can run without erroring out - getOpenDataDetector() # just to make sure it can build + + # just to make sure it can build the odd + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + with contextManager: + pass script = ( Path(__file__).parent.parent.parent.parent diff --git a/Examples/Python/tests/test_reader.py b/Examples/Python/tests/test_reader.py index 3f2c30ed49b..238f9019439 100644 --- a/Examples/Python/tests/test_reader.py +++ b/Examples/Python/tests/test_reader.py @@ -293,40 +293,41 @@ def test_edm4hep_simhit_particle_reader(tmp_path): assert os.path.exists(tmp_file) - detector, trackingGeometry, decorators = getOpenDataDetector() - s = Sequencer(numThreads=1) - s.addReader( - EDM4hepReader( - level=acts.logging.INFO, - inputPath=tmp_file, - inputSimHits=[ - "PixelBarrelReadout", - "PixelEndcapReadout", - "ShortStripBarrelReadout", - "ShortStripEndcapReadout", - "LongStripBarrelReadout", - "LongStripEndcapReadout", - ], - outputParticlesGenerator="particles_input", - outputParticlesInitial="particles_initial", - outputParticlesFinal="particles_final", - outputSimHits="simhits", - dd4hepDetector=detector, - trackingGeometry=trackingGeometry, + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + + with contextManager: + s.addReader( + EDM4hepReader( + level=acts.logging.INFO, + inputPath=tmp_file, + inputSimHits=[ + "PixelBarrelReadout", + "PixelEndcapReadout", + "ShortStripBarrelReadout", + "ShortStripEndcapReadout", + "LongStripBarrelReadout", + "LongStripEndcapReadout", + ], + outputParticlesGenerator="particles_input", + outputParticlesInitial="particles_initial", + outputParticlesFinal="particles_final", + outputSimHits="simhits", + dd4hepDetector=detector, + trackingGeometry=trackingGeometry, + ) ) - ) - alg = AssertCollectionExistsAlg("simhits", "check_alg", acts.logging.WARNING) - s.addAlgorithm(alg) + alg = AssertCollectionExistsAlg("simhits", "check_alg", acts.logging.WARNING) + s.addAlgorithm(alg) - alg = AssertCollectionExistsAlg( - "particles_input", "check_alg", acts.logging.WARNING - ) - s.addAlgorithm(alg) + alg = AssertCollectionExistsAlg( + "particles_input", "check_alg", acts.logging.WARNING + ) + s.addAlgorithm(alg) - s.run() + s.run() assert alg.events_seen == 10 diff --git a/Examples/Scripts/Python/Auto-tuning/Orion/material_mapping_optimisation.py b/Examples/Scripts/Python/Auto-tuning/Orion/material_mapping_optimisation.py index 0ebdf68d537..821320a33a2 100755 --- a/Examples/Scripts/Python/Auto-tuning/Orion/material_mapping_optimisation.py +++ b/Examples/Scripts/Python/Auto-tuning/Orion/material_mapping_optimisation.py @@ -174,10 +174,6 @@ def runMaterialMappingVariance( # Update the binning using the bin map corresponding to this trial matMapDeco.setBinningMap(binMap) - del detectorTemp - del trackingGeometryTemp - del decoratorsTemp - # Decorate the detector with the MappingMaterialDecorator detector, trackingGeometry, decorators = getOpenDataDetector(matMapDeco) @@ -474,7 +470,6 @@ def surfaceExperiment(key, nbJobs, pathDB, pathResult, pipeBin, pipeResult, doPl tGeometry=trackingGeometry, level=acts.logging.WARNING ) binDict = matMapDeco.binningMap() - del detector, decorators # Create the pipes that will be used to transfer data to/from the jobs from multiprocessing import Process, Pipe @@ -596,8 +591,6 @@ def surfaceExperiment(key, nbJobs, pathDB, pathResult, pipeBin, pipeResult, doPl s=rMap, ) rMap.run() - del rMap # Need to be deleted to write the material map to cbor - del resultDetector, resultTrackingGeometry, resultDecorators print( datetime.now().strftime("%H:%M:%S") + " Waiting for all the score to have been stored", diff --git a/Examples/Scripts/Python/MLAmbiguityResolution/train_seed_solver.py b/Examples/Scripts/Python/MLAmbiguityResolution/train_seed_solver.py index 3a0a54c6e9c..e4e9467e8af 100644 --- a/Examples/Scripts/Python/MLAmbiguityResolution/train_seed_solver.py +++ b/Examples/Scripts/Python/MLAmbiguityResolution/train_seed_solver.py @@ -329,11 +329,6 @@ def train( dynamic_axes={"x": {0: "batch_size"}, "y": {0: "batch_size"}}, ) -del CKF_files -del data -del x_train, y_train -del input, input_test -del duplicateClassifier # ================================================================== # ttbar events for the test, here we assume 40 events are availables diff --git a/Examples/Scripts/Python/event_recording.py b/Examples/Scripts/Python/event_recording.py index 04cbb135dbe..c1e43c1db5d 100755 --- a/Examples/Scripts/Python/event_recording.py +++ b/Examples/Scripts/Python/event_recording.py @@ -76,7 +76,7 @@ def runEventRecording(detectorConstructionFactory, outputDir, s=None): if "__main__" == __name__: - detector, trackingGeometry, decorators = getOpenDataDetector() + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() detectorConstructionFactory = ( acts.examples.geant4.dd4hep.DDG4DetectorConstructionFactory(detector) diff --git a/Examples/Scripts/Python/full_chain_odd.py b/Examples/Scripts/Python/full_chain_odd.py index 0c6b5fd1f38..10690e9a5ed 100755 --- a/Examples/Scripts/Python/full_chain_odd.py +++ b/Examples/Scripts/Python/full_chain_odd.py @@ -161,7 +161,7 @@ oddSeedingSel = geoDir / "config/odd-seeding-config.json" oddMaterialDeco = acts.IMaterialDecorator.fromFile(oddMaterialMap) -detector, trackingGeometry, decorators = getOpenDataDetector( +detector, trackingGeometry, decorators, contextManager = getOpenDataDetector( odd_dir=geoDir, mdecorator=oddMaterialDeco ) field = acts.ConstantBField(acts.Vector3(0.0, 0.0, 2.0 * u.T)) diff --git a/Examples/Scripts/Python/geant4.py b/Examples/Scripts/Python/geant4.py index 54600d98616..29fb53ddc1b 100755 --- a/Examples/Scripts/Python/geant4.py +++ b/Examples/Scripts/Python/geant4.py @@ -74,7 +74,7 @@ def runGeant4( # Context and options geoContext = acts.GeometryContext() [detector, contextors, store] = dd4hepDetector.finalize(geoContext, cOptions) - runGeant4(dd4hepDetector, detector, field, Path.cwd()).run() + runGeant4(detector, detector, field, Path.cwd()).run() else: - dd4hepDetector, trackingGeometry, decorators = getOpenDataDetector() - runGeant4(dd4hepDetector, trackingGeometry, field, Path.cwd()).run() + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + runGeant4(detector, trackingGeometry, field, Path.cwd()).run() diff --git a/Examples/Scripts/Python/geant4_parallel.py b/Examples/Scripts/Python/geant4_parallel.py index 1cb0fa0e894..6f195f9b70c 100755 --- a/Examples/Scripts/Python/geant4_parallel.py +++ b/Examples/Scripts/Python/geant4_parallel.py @@ -23,16 +23,13 @@ # -def runGeant4EventRange(beginEvent, endEvent, outputDir): +def runGeant4EventRange(detector, trackingGeometry, beginEvent, endEvent, outputDir): import acts import acts.examples from acts.examples.simulation import addParticleGun, addGeant4, EtaConfig - from acts.examples.odd import getOpenDataDetector u = acts.UnitConstants - detector, trackingGeometry, decorators = getOpenDataDetector() - field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T)) rnd = acts.examples.RandomNumbers(seed=42) @@ -62,6 +59,10 @@ def runGeant4EventRange(beginEvent, endEvent, outputDir): if "__main__" == __name__: + from acts.examples.odd import getOpenDataDetector + + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + n_events = 100 n_jobs = 8 diff --git a/Examples/Scripts/Python/geometry.py b/Examples/Scripts/Python/geometry.py index 396fec3151a..cd4d894776b 100755 --- a/Examples/Scripts/Python/geometry.py +++ b/Examples/Scripts/Python/geometry.py @@ -90,9 +90,9 @@ def runGeometry( if "__main__" == __name__: - # detector, trackingGeometry, decorators = AlignedDetector.create() - # detector, trackingGeometry, decorators = GenericDetector.create() - detector, trackingGeometry, decorators = getOpenDataDetector() + # detector, trackingGeometry, decorators, contextManager = AlignedDetector.create() + # detector, trackingGeometry, decorators, contextManager = GenericDetector.create() + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() runGeometry(trackingGeometry, decorators, outputDir=os.getcwd()) diff --git a/Examples/Scripts/Python/material_recording.py b/Examples/Scripts/Python/material_recording.py index f52bb8b2ab2..c91bc32fca2 100755 --- a/Examples/Scripts/Python/material_recording.py +++ b/Examples/Scripts/Python/material_recording.py @@ -104,7 +104,7 @@ def main(): detectorConstructionFactory = None if args.input == "": - detector, trackingGeometry, decorators = getOpenDataDetector() + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() detectorConstructionFactory = ( acts.examples.geant4.dd4hep.DDG4DetectorConstructionFactory(detector) diff --git a/Examples/Scripts/Python/seeding.py b/Examples/Scripts/Python/seeding.py index 076262fd194..4e14501cc39 100755 --- a/Examples/Scripts/Python/seeding.py +++ b/Examples/Scripts/Python/seeding.py @@ -147,8 +147,8 @@ def runSeeding( ) args = p.parse_args() - # detector, trackingGeometry, _ = getOpenDataDetector() - detector, trackingGeometry, _ = acts.examples.GenericDetector.create() + # detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + detector, trackingGeometry, decorators, contextManager = acts.examples.GenericDetector.create() field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T)) diff --git a/Examples/Scripts/Python/truth_tracking_gsf.py b/Examples/Scripts/Python/truth_tracking_gsf.py index bd95153c1ff..69e5fa829a2 100755 --- a/Examples/Scripts/Python/truth_tracking_gsf.py +++ b/Examples/Scripts/Python/truth_tracking_gsf.py @@ -160,7 +160,7 @@ def runTruthTrackingGsf( # ODD from acts.examples.odd import getOpenDataDetector - detector, trackingGeometry, _ = getOpenDataDetector() + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() digiConfigFile = ( srcdir / "thirdparty/OpenDataDetector/config/odd-digi-smearing-config.json" ) diff --git a/Examples/Scripts/Python/truth_tracking_gsf_refitting.py b/Examples/Scripts/Python/truth_tracking_gsf_refitting.py index d16784cefcb..72488181776 100755 --- a/Examples/Scripts/Python/truth_tracking_gsf_refitting.py +++ b/Examples/Scripts/Python/truth_tracking_gsf_refitting.py @@ -97,8 +97,8 @@ def runRefittingGsf( if __name__ == "__main__": outputDir = Path.cwd() - # detector, trackingGeometry, _ = getOpenDataDetector() - detector, trackingGeometry, decorators = acts.examples.GenericDetector.create() + # detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + detector, trackingGeometry, decorators, contextManager = acts.examples.GenericDetector.create() field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T)) runRefittingGsf(trackingGeometry, field, outputDir).run() diff --git a/Examples/Scripts/Python/truth_tracking_gx2f.py b/Examples/Scripts/Python/truth_tracking_gx2f.py index 6ef9cceecb8..a38f4091438 100644 --- a/Examples/Scripts/Python/truth_tracking_gx2f.py +++ b/Examples/Scripts/Python/truth_tracking_gx2f.py @@ -159,7 +159,7 @@ def runTruthTrackingGx2f( # ODD from acts.examples.odd import getOpenDataDetector - detector, trackingGeometry, _ = getOpenDataDetector() + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() digiConfigFile = ( srcdir / "thirdparty/OpenDataDetector/config/odd-digi-smearing-config.json" ) diff --git a/Examples/Scripts/Python/truth_tracking_kalman.py b/Examples/Scripts/Python/truth_tracking_kalman.py index e0956b46bd5..0ca9a8b3adc 100755 --- a/Examples/Scripts/Python/truth_tracking_kalman.py +++ b/Examples/Scripts/Python/truth_tracking_kalman.py @@ -163,7 +163,7 @@ def runTruthTrackingKalman( # ODD from acts.examples.odd import getOpenDataDetector - detector, trackingGeometry, _ = getOpenDataDetector() + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() digiConfigFile = ( srcdir / "thirdparty/OpenDataDetector/config/odd-digi-smearing-config.json" ) diff --git a/docs/examples/howto/material_mapping.rst b/docs/examples/howto/material_mapping.rst index 87a6c8ad699..f14a84336eb 100644 --- a/docs/examples/howto/material_mapping.rst +++ b/docs/examples/howto/material_mapping.rst @@ -55,7 +55,7 @@ For the following example we will be remapping the material of the ODD, we will .. code-block:: console - detector, trackingGeometry, decorators = getOpenDataDetector() + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() This algorithm is useful to obtain a visualisation of your detector using the different types of output available (``output-obj`` gives ``.obj`` with a 3D representation of the different subdetectors, for example). Here, we use ``output-json`` to obtain a map of all the surfaces and volumes in the detector with a ``ProtoSurfaceMaterial`` (or a ``ProtoVolumeMaterial``), ``mat-output-allmaterial`` ensure that a ``ProtoSurfaceMaterial`` (or a ``ProtoVolumeMaterial``) is associated to all the surfaces (or volumes), enforcing all of them to be written. Four types of surfaces exist: From a6d69fea32a7bc0bf807d4275a47dac8a5936d7b Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Wed, 7 Aug 2024 23:28:58 +0200 Subject: [PATCH 11/32] formatting --- Examples/Python/python/acts/examples/odd.py | 2 + Examples/Python/tests/conftest.py | 11 +- Examples/Python/tests/test_examples.py | 100 ++++++++++-------- Examples/Scripts/Python/seeding.py | 4 +- .../Python/truth_tracking_gsf_refitting.py | 4 +- 5 files changed, 72 insertions(+), 49 deletions(-) diff --git a/Examples/Python/python/acts/examples/odd.py b/Examples/Python/python/acts/examples/odd.py index 778837f71da..db5429a473b 100644 --- a/Examples/Python/python/acts/examples/odd.py +++ b/Examples/Python/python/acts/examples/odd.py @@ -106,8 +106,10 @@ def geoid_hook(geoid, surface): class ContextManager: def __init__(self, detector): self.detector = detector + def __enter__(self): return self + def __exit__(self): self.detector.drop() diff --git a/Examples/Python/tests/conftest.py b/Examples/Python/tests/conftest.py index 5cc712b0299..43ffafecc88 100644 --- a/Examples/Python/tests/conftest.py +++ b/Examples/Python/tests/conftest.py @@ -231,6 +231,7 @@ def trk_geo(): "detector", "trackingGeometry", "decorators", + "contextManager", "geometrySelection", "digiConfigFile", "name", @@ -243,11 +244,14 @@ def detector_config(request): srcdir = Path(__file__).resolve().parent.parent.parent.parent if request.param == "generic": - detector, trackingGeometry, decorators = acts.examples.GenericDetector.create() + detector, trackingGeometry, decorators, contextManager = ( + acts.examples.GenericDetector.create() + ) return DetectorConfig( detector, trackingGeometry, decorators, + contextManager, geometrySelection=( srcdir / "Examples/Algorithms/TrackFinding/share/geoSelection-genericDetector.json" @@ -266,11 +270,14 @@ def detector_config(request): srcdir / "thirdparty/OpenDataDetector/data/odd-material-maps.root", level=acts.logging.INFO, ) - detector, trackingGeometry, decorators = getOpenDataDetector(matDeco) + detector, trackingGeometry, decorators, contextManager = getOpenDataDetector( + matDeco + ) return DetectorConfig( detector, trackingGeometry, decorators, + contextManager, digiConfigFile=( srcdir / "thirdparty/OpenDataDetector/config/odd-digi-smearing-config.json" diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index 5e5dcaceaf9..c02e1566980 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -540,17 +540,18 @@ def test_truth_tracking_kalman( fp = tmp_path / fn assert not fp.exists() - runTruthTrackingKalman( - trackingGeometry=detector_config.trackingGeometry, - field=field, - digiConfigFile=detector_config.digiConfigFile, - outputDir=tmp_path, - reverseFilteringMomThreshold=revFiltMomThresh, - directNavigation=directNavigation, - s=seq, - ) + with detector_config.contextManager: + runTruthTrackingKalman( + trackingGeometry=detector_config.trackingGeometry, + field=field, + digiConfigFile=detector_config.digiConfigFile, + outputDir=tmp_path, + reverseFilteringMomThreshold=revFiltMomThresh, + directNavigation=directNavigation, + s=seq, + ) - seq.run() + seq.run() for fn, tn, ee in root_files: fp = tmp_path / fn @@ -597,18 +598,19 @@ def test_truth_tracking_gsf(tmp_path, assert_root_hash, detector_config): fp = tmp_path / fn assert not fp.exists() - runTruthTrackingGsf( - trackingGeometry=detector_config.trackingGeometry, - decorators=detector_config.decorators, - field=field, - digiConfigFile=detector_config.digiConfigFile, - outputDir=tmp_path, - s=seq, - ) + with detector_config.contextManager: + runTruthTrackingGsf( + trackingGeometry=detector_config.trackingGeometry, + decorators=detector_config.decorators, + field=field, + digiConfigFile=detector_config.digiConfigFile, + outputDir=tmp_path, + s=seq, + ) - # See https://github.com/acts-project/acts/issues/1300 - with failure_threshold(acts.logging.FATAL): - seq.run() + # See https://github.com/acts-project/acts/issues/1300 + with failure_threshold(acts.logging.FATAL): + seq.run() for fn, tn in root_files: fp = tmp_path / fn @@ -628,14 +630,15 @@ def test_refitting(tmp_path, detector_config, assert_root_hash): numThreads=1, ) - # Only check if it runs without errors right known - # Changes in fitter behaviour should be caught by other tests - runRefittingGsf( - trackingGeometry=detector_config.trackingGeometry, - field=field, - outputDir=tmp_path, - s=seq, - ).run() + with detector_config.contextManager: + # Only check if it runs without errors right known + # Changes in fitter behaviour should be caught by other tests + runRefittingGsf( + trackingGeometry=detector_config.trackingGeometry, + field=field, + outputDir=tmp_path, + s=seq, + ).run() root_files = [ ("trackstates_gsf_refit.root", "trackstates"), @@ -729,7 +732,9 @@ def test_material_mapping(material_recording, tmp_path, assert_root_hash): s = Sequencer(events=10, numThreads=1) - detector, trackingGeometry, decorators = getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(mat_file)) + detector, trackingGeometry, decorators = getOpenDataDetector( + mdecorator=acts.IMaterialDecorator.fromFile(mat_file) + ) with detector: runMaterialValidation( @@ -761,7 +766,9 @@ def test_volume_material_mapping(material_recording, tmp_path, assert_root_hash) s = Sequencer(numThreads=1) - detector, trackingGeometry, decorators = getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(geo_map)) + detector, trackingGeometry, decorators = getOpenDataDetector( + mdecorator=acts.IMaterialDecorator.fromFile(geo_map) + ) with detector: runMaterialMapping( @@ -797,7 +804,9 @@ def test_volume_material_mapping(material_recording, tmp_path, assert_root_hash) s = Sequencer(events=10, numThreads=1) - detector, trackingGeometry, decorators = getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(mat_file)) + detector, trackingGeometry, decorators = getOpenDataDetector( + mdecorator=acts.IMaterialDecorator.fromFile(mat_file) + ) with detector: runMaterialValidation( @@ -1061,20 +1070,21 @@ def test_ckf_tracks_example( from ckf_tracks import runCKFTracks - runCKFTracks( - detector_config.trackingGeometry, - detector_config.decorators, - field=field, - outputCsv=True, - outputDir=tmp_path, - geometrySelection=detector_config.geometrySelection, - digiConfigFile=detector_config.digiConfigFile, - truthSmearedSeeded=truthSmeared, - truthEstimatedSeeded=truthEstimated, - s=s, - ) + with detector_config.contextManager: + runCKFTracks( + detector_config.trackingGeometry, + detector_config.decorators, + field=field, + outputCsv=True, + outputDir=tmp_path, + geometrySelection=detector_config.geometrySelection, + digiConfigFile=detector_config.digiConfigFile, + truthSmearedSeeded=truthSmeared, + truthEstimatedSeeded=truthEstimated, + s=s, + ) - s.run() + s.run() assert csv.exists() for rf, tn in root_files: diff --git a/Examples/Scripts/Python/seeding.py b/Examples/Scripts/Python/seeding.py index 4e14501cc39..afca1567e98 100755 --- a/Examples/Scripts/Python/seeding.py +++ b/Examples/Scripts/Python/seeding.py @@ -148,7 +148,9 @@ def runSeeding( args = p.parse_args() # detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() - detector, trackingGeometry, decorators, contextManager = acts.examples.GenericDetector.create() + detector, trackingGeometry, decorators, contextManager = ( + acts.examples.GenericDetector.create() + ) field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T)) diff --git a/Examples/Scripts/Python/truth_tracking_gsf_refitting.py b/Examples/Scripts/Python/truth_tracking_gsf_refitting.py index 72488181776..64e94617790 100755 --- a/Examples/Scripts/Python/truth_tracking_gsf_refitting.py +++ b/Examples/Scripts/Python/truth_tracking_gsf_refitting.py @@ -98,7 +98,9 @@ def runRefittingGsf( outputDir = Path.cwd() # detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() - detector, trackingGeometry, decorators, contextManager = acts.examples.GenericDetector.create() + detector, trackingGeometry, decorators, contextManager = ( + acts.examples.GenericDetector.create() + ) field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T)) runRefittingGsf(trackingGeometry, field, outputDir).run() From 24b004581339fd96934237edde42cb40e6729cff Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Wed, 7 Aug 2024 23:45:12 +0200 Subject: [PATCH 12/32] couple of fixes --- .../Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp | 3 +++ .../EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp | 2 +- Examples/Python/tests/test_reader.py | 3 +++ Examples/Python/tests/test_writer.py | 4 ++++ 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp index 6e477fb9cf1..b0a2dd8d4b7 100644 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp @@ -146,6 +146,9 @@ DD4hepGeometryService::contextDecorators() const { } void DD4hepGeometryService::drop() { + if (m_detector != nullptr) { + m_detector->destroyInstance(); + } m_detector = nullptr; m_geometry = dd4hep::DetElement(); m_trackingGeometry.reset(); diff --git a/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp b/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp index 9058dde8558..b66e9ec8732 100644 --- a/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp +++ b/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp @@ -27,7 +27,7 @@ namespace ActsExamples { namespace DD4hep { -struct DD4hepGeometryService; +class DD4hepGeometryService; } /// Read particles from EDM4hep. diff --git a/Examples/Python/tests/test_reader.py b/Examples/Python/tests/test_reader.py index 238f9019439..1bb39a3c7db 100644 --- a/Examples/Python/tests/test_reader.py +++ b/Examples/Python/tests/test_reader.py @@ -130,7 +130,10 @@ def test_root_reader_interface(reader, conf_const, tmp_path): assert conf_const(reader, **kw) +@pytest.mark.slow @pytest.mark.root +@pytest.mark.odd +@pytest.mark.skipif(not geant4Enabled, reason="Geant4 not set up") def test_root_material_track_reader(material_recording): input_tracks = material_recording / "geant4_material_tracks.root" assert input_tracks.exists() diff --git a/Examples/Python/tests/test_writer.py b/Examples/Python/tests/test_writer.py index f9c1ae0d6c4..00a94fa072a 100644 --- a/Examples/Python/tests/test_writer.py +++ b/Examples/Python/tests/test_writer.py @@ -440,6 +440,10 @@ def hepmc_data(hepmc_data_impl: Path, tmp_path): @pytest.mark.skipif(not hepmc3Enabled, reason="HepMC3 plugin not available") +@pytest.mark.skipif(not dd4hepEnabled, reason="DD4hep not set up") +@pytest.mark.skipif(not geant4Enabled, reason="Geant4 not set up") +@pytest.mark.odd +@pytest.mark.slow def test_hepmc3_histogram(hepmc_data, tmp_path): from acts.examples.hepmc3 import ( HepMC3AsciiReader, From 1fd00d5b0b724e4502034b211990872f952a83c1 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Wed, 7 Aug 2024 23:45:51 +0200 Subject: [PATCH 13/32] clean --- Examples/Python/src/DD4hepComponent.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Examples/Python/src/DD4hepComponent.cpp b/Examples/Python/src/DD4hepComponent.cpp index dbf91f34ada..2a1510068ef 100644 --- a/Examples/Python/src/DD4hepComponent.cpp +++ b/Examples/Python/src/DD4hepComponent.cpp @@ -49,10 +49,7 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { &DD4hep::DD4hepGeometryService::trackingGeometry)) .def("contextDecorators", &DD4hep::DD4hepGeometryService::contextDecorators) - .def("drop", &DD4hep::DD4hepGeometryService::drop) - .def("__enter__", [](py::object self) { return self; }) - .def("__exit__", - [](DD4hep::DD4hepGeometryService& self) { self.drop(); }); + .def("drop", &DD4hep::DD4hepGeometryService::drop); auto c = py::class_(s, "Config").def(py::init<>()); ACTS_PYTHON_STRUCT_BEGIN(c, Config); From 1ac6043e6743edcad21568464ac7d7227192b981 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Thu, 8 Aug 2024 13:16:10 +0200 Subject: [PATCH 14/32] major refactor of examples detectors --- .../DDG4/DDG4DetectorConstruction.hpp | 12 +-- .../Geant4/src/DDG4DetectorConstruction.cpp | 16 +-- Examples/Detectors/CMakeLists.txt | 1 + Examples/Detectors/Common/CMakeLists.txt | 15 +++ .../ActsExamples/DetectorCommons/Detector.hpp | 67 +++++++++++++ Examples/Detectors/Common/src/Detector.cpp | 45 +++++++++ .../ContextualDetector/CMakeLists.txt | 6 +- .../ContextualDetector/AlignedDetector.hpp | 42 ++++---- .../src/AlignedDetector.cpp | 75 +++++++------- .../Detectors/DD4hepDetector/CMakeLists.txt | 8 +- ...GeometryService.hpp => DD4hepDetector.hpp} | 56 +++-------- ...GeometryService.cpp => DD4hepDetector.cpp} | 97 ++++++------------- .../Detectors/Geant4Detector/CMakeLists.txt | 16 ++- .../Geant4Detector/Geant4Detector.hpp | 47 ++++++--- .../Geant4Detector/src/Geant4Detector.cpp | 95 +++++++++++------- .../Detectors/GenericDetector/CMakeLists.txt | 10 +- .../GenericDetector/BuildGenericDetector.hpp | 2 +- .../GenericDetector/GenericDetector.hpp | 38 +++----- .../GenericDetector/src/GenericDetector.cpp | 41 +++++--- .../src/MockupSectorBuilder.cpp | 9 +- .../Detectors/TGeoDetector/CMakeLists.txt | 11 ++- .../TGeoDetector/JsonTGeoDetectorConfig.hpp | 34 +++---- .../TGeoDetector/TGeoDetector.hpp | 41 ++++---- .../TGeoDetector/TGeoITkModuleSplitter.hpp | 6 +- .../TGeoDetector/src/TGeoDetector.cpp | 40 ++++---- .../src/TGeoITkModuleSplitter.cpp | 25 ++--- .../TelescopeDetector/CMakeLists.txt | 7 +- .../BuildTelescopeDetector.hpp | 5 +- .../TelescopeDetector/TelescopeDetector.hpp | 40 +++----- .../src/BuildTelescopeDetector.cpp | 9 +- .../src/TelescopeDetector.cpp | 45 ++++----- .../ActsExamples/Io/EDM4hep/EDM4hepReader.hpp | 4 +- Examples/Io/EDM4hep/src/EDM4hepReader.cpp | 5 +- Examples/Python/python/acts/_adapter.py | 3 +- .../Python/python/acts/examples/dd4hep.py | 6 +- Examples/Python/python/acts/examples/odd.py | 13 +-- Examples/Python/src/DD4hepComponent.cpp | 37 +++---- Examples/Python/src/Detector.cpp | 91 +++++++++-------- Examples/Python/src/Geant4Component.cpp | 30 ++---- Examples/Python/src/Geant4DD4hepComponent.cpp | 4 +- Examples/Python/tests/test_examples.py | 14 +-- 41 files changed, 626 insertions(+), 542 deletions(-) create mode 100644 Examples/Detectors/Common/CMakeLists.txt create mode 100644 Examples/Detectors/Common/include/ActsExamples/DetectorCommons/Detector.hpp create mode 100644 Examples/Detectors/Common/src/Detector.cpp rename Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/{DD4hepGeometryService.hpp => DD4hepDetector.hpp} (72%) rename Examples/Detectors/DD4hepDetector/src/{DD4hepGeometryService.cpp => DD4hepDetector.cpp} (72%) diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp index 370d450309c..378151e8043 100644 --- a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp +++ b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp @@ -8,7 +8,7 @@ #pragma once -#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" +#include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" #include "ActsExamples/Geant4/DetectorConstructionFactory.hpp" #include "ActsExamples/Geant4/RegionCreator.hpp" @@ -24,14 +24,14 @@ class Detector; namespace ActsExamples { namespace DD4hep { -class DD4hepGeometryService; +class DD4hepDetector; } /// Construct the Geant4 detector from a DD4hep description. class DDG4DetectorConstruction final : public G4VUserDetectorConstruction { public: DDG4DetectorConstruction( - std::shared_ptr geometryService, + std::shared_ptr detector, std::vector> regionCreators = {}); /// Convert the stored DD4hep detector to a Geant4 description. @@ -45,7 +45,7 @@ class DDG4DetectorConstruction final : public G4VUserDetectorConstruction { private: /// The Acts DD4hep detector instance - std::shared_ptr m_geometryService; + std::shared_ptr m_detector; /// Region creators std::vector> m_regionCreators; /// The world volume @@ -56,7 +56,7 @@ class DDG4DetectorConstructionFactory final : public DetectorConstructionFactory { public: DDG4DetectorConstructionFactory( - std::shared_ptr geometryService, + std::shared_ptr detector, std::vector> regionCreators = {}); ~DDG4DetectorConstructionFactory() final; @@ -64,7 +64,7 @@ class DDG4DetectorConstructionFactory final private: /// The Acts DD4hep detector instance - std::shared_ptr m_geometryService; + std::shared_ptr m_detector; /// Region creators std::vector> m_regionCreators; }; diff --git a/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp b/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp index 637ed3f7227..c400b67761a 100644 --- a/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp +++ b/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp @@ -8,7 +8,7 @@ #include "ActsExamples/DDG4/DDG4DetectorConstruction.hpp" -#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" +#include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" #include #include @@ -24,20 +24,20 @@ class G4VPhysicalVolume; namespace ActsExamples { DDG4DetectorConstruction::DDG4DetectorConstruction( - std::shared_ptr geometryService, + std::shared_ptr detector, std::vector> regionCreators) : G4VUserDetectorConstruction(), - m_geometryService(std::move(geometryService)), + m_detector(std::move(detector)), m_regionCreators(std::move(regionCreators)) {} // See DD4hep::Simulation::Geant4DetectorConstruction::Construct() G4VPhysicalVolume* DDG4DetectorConstruction::Construct() { if (m_world == nullptr) { dd4hep::sim::Geant4Mapping& g4map = dd4hep::sim::Geant4Mapping::instance(); - auto conv = dd4hep::sim::Geant4Converter(m_geometryService->detector(), + auto conv = dd4hep::sim::Geant4Converter(m_detector->dd4hepDetector(), dd4hep::PrintLevel::VERBOSE); dd4hep::sim::Geant4GeometryInfo* geo_info = - conv.create(m_geometryService->detector().world()).detach(); + conv.create(m_detector->dd4hepGeometry()).detach(); g4map.attach(geo_info); // All volumes are deleted in ~G4PhysicalVolumeStore() m_world = geo_info->world(); @@ -53,16 +53,16 @@ G4VPhysicalVolume* DDG4DetectorConstruction::Construct() { } DDG4DetectorConstructionFactory::DDG4DetectorConstructionFactory( - std::shared_ptr geometryService, + std::shared_ptr detector, std::vector> regionCreators) - : m_geometryService(std::move(geometryService)), + : m_detector(std::move(detector)), m_regionCreators(std::move(regionCreators)) {} DDG4DetectorConstructionFactory::~DDG4DetectorConstructionFactory() = default; std::unique_ptr DDG4DetectorConstructionFactory::factorize() const { - return std::make_unique(m_geometryService, + return std::make_unique(m_detector, m_regionCreators); } diff --git a/Examples/Detectors/CMakeLists.txt b/Examples/Detectors/CMakeLists.txt index a04112d572c..cf12edad94b 100644 --- a/Examples/Detectors/CMakeLists.txt +++ b/Examples/Detectors/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(Common) add_subdirectory(ContextualDetector) add_subdirectory_if(DD4hepDetector ACTS_BUILD_EXAMPLES_DD4HEP) add_subdirectory(GenericDetector) diff --git a/Examples/Detectors/Common/CMakeLists.txt b/Examples/Detectors/Common/CMakeLists.txt new file mode 100644 index 00000000000..00b1ef197a0 --- /dev/null +++ b/Examples/Detectors/Common/CMakeLists.txt @@ -0,0 +1,15 @@ +add_library( + ActsExamplesDetectorCommons SHARED + src/Detector.cpp) +target_include_directories( + ActsExamplesDetectorCommons + PUBLIC $) +target_link_libraries( + ActsExamplesDetectorCommons + PUBLIC + ActsCore + ActsExamplesFramework) + +install( + TARGETS ActsExamplesDetectorCommons + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/Examples/Detectors/Common/include/ActsExamples/DetectorCommons/Detector.hpp b/Examples/Detectors/Common/include/ActsExamples/DetectorCommons/Detector.hpp new file mode 100644 index 00000000000..0be35112deb --- /dev/null +++ b/Examples/Detectors/Common/include/ActsExamples/DetectorCommons/Detector.hpp @@ -0,0 +1,67 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2024 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include "Acts/Geometry/GeometryContext.hpp" + +#include +#include + +namespace Acts { +class TrackingGeometry; +class DetectorElementBase; +class IMaterialDecorator; +class Logger; +namespace Experimental { +class Detector; +} // namespace Experimental +} // namespace Acts + +namespace ActsExamples { +class IContextDecorator; +} // namespace ActsExamples + +namespace ActsExamples::DetectorCommons { + +class Detector { + public: + using TrackingGeometryPtr = std::shared_ptr; + using DetectorPtr = std::shared_ptr; + using ContextDecorators = + std::vector>; + + using DetectorElement = Acts::DetectorElementBase; + using DetectorStore = std::vector>; + + explicit Detector(std::unique_ptr logger); + virtual ~Detector() = default; + + virtual std::tuple + trackingGeometry(); + + virtual std::tuple detector(); + + virtual void drop(); + + protected: + TrackingGeometryPtr m_trackingGeometry; + DetectorPtr m_detector; + ContextDecorators m_contextDecorators; + DetectorStore m_detectorStore; + + std::unique_ptr m_logger; + + const Acts::Logger& logger() const { return *m_logger; } + + virtual void buildTrackingGeometry() = 0; + + virtual void buildDetector(); +}; + +} // namespace ActsExamples::DetectorCommons diff --git a/Examples/Detectors/Common/src/Detector.cpp b/Examples/Detectors/Common/src/Detector.cpp new file mode 100644 index 00000000000..72fad92de80 --- /dev/null +++ b/Examples/Detectors/Common/src/Detector.cpp @@ -0,0 +1,45 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2024 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "ActsExamples/DetectorCommons/Detector.hpp" + +#include "Acts/Utilities/Logger.hpp" + +namespace ActsExamples::DetectorCommons { + +Detector::Detector(std::unique_ptr logger) + : m_logger(std::move(logger)) {} + +std::tuple +Detector::trackingGeometry() { + if (m_trackingGeometry == nullptr) { + buildTrackingGeometry(); + } + return {m_trackingGeometry, m_contextDecorators, m_detectorStore}; +} + +std::tuple +Detector::detector() { + if (m_detector == nullptr) { + buildDetector(); + } + return {m_detector, m_contextDecorators, m_detectorStore}; +} + +void Detector::drop() { + m_trackingGeometry.reset(); + m_detector.reset(); + m_contextDecorators.clear(); + m_detectorStore.clear(); +} + +void Detector::buildDetector() {} + +} // namespace ActsExamples::DetectorCommons diff --git a/Examples/Detectors/ContextualDetector/CMakeLists.txt b/Examples/Detectors/ContextualDetector/CMakeLists.txt index 7ffc1394e8e..2879d0b5ee5 100644 --- a/Examples/Detectors/ContextualDetector/CMakeLists.txt +++ b/Examples/Detectors/ContextualDetector/CMakeLists.txt @@ -3,14 +3,18 @@ add_library( src/AlignedDetector.cpp src/InternalAlignmentDecorator.cpp src/ExternalAlignmentDecorator.cpp) + target_include_directories( ActsExamplesDetectorContextual PUBLIC $) + target_link_libraries( ActsExamplesDetectorContextual PUBLIC ActsCore - ActsExamplesFramework ActsExamplesDetectorGeneric) + ActsExamplesFramework + ActsExamplesDetectorCommons + ActsExamplesDetectorGeneric) install( TARGETS ActsExamplesDetectorContextual diff --git a/Examples/Detectors/ContextualDetector/include/ActsExamples/ContextualDetector/AlignedDetector.hpp b/Examples/Detectors/ContextualDetector/include/ActsExamples/ContextualDetector/AlignedDetector.hpp index 82e4e0f7806..b554b296cd3 100644 --- a/Examples/Detectors/ContextualDetector/include/ActsExamples/ContextualDetector/AlignedDetector.hpp +++ b/Examples/Detectors/ContextualDetector/include/ActsExamples/ContextualDetector/AlignedDetector.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2019 CERN for the benefit of the Acts project +// Copyright (C) 2019-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -10,6 +10,7 @@ #include "Acts/Definitions/Units.hpp" #include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/DetectorCommons/Detector.hpp" #include "ActsExamples/GenericDetector/GenericDetector.hpp" #include @@ -17,29 +18,20 @@ #include #include -namespace Acts { -class TrackingGeometry; -class IMaterialDecorator; -} // namespace Acts - -namespace ActsExamples { -class IContextDecorator; -namespace Generic { -class GenericDetectorElement; -} // namespace Generic -} // namespace ActsExamples - namespace ActsExamples::Contextual { class InternallyAlignedDetectorElement; class InternalAlignmentDecorator; -class AlignedDetector { +class AlignedDetector : public DetectorCommons::Detector { public: + using TrackingGeometryPtr = std::shared_ptr; using ContextDecorators = std::vector>; - using TrackingGeometryPtr = std::shared_ptr; - struct Config : public GenericDetector::Config { + using DetectorStore = std::vector< + std::vector>>; + + struct Config : public Generic::GenericDetector::Config { /// Seed for the decorator random numbers. std::size_t seed = 1324354657; /// Size of a valid IOV. @@ -63,21 +55,21 @@ class AlignedDetector { enum class Mode { Internal, External }; Mode mode = Mode::Internal; + + std::shared_ptr materialDecorator; }; - std::pair finalize( - const Config& cfg, - std::shared_ptr mdecorator); + explicit AlignedDetector(const Config& cfg); - std::vector>>& - detectorStore() { - return m_detectorStore; - } + const DetectorStore& detectorStore() const { return m_detectorStore; } private: + Config m_cfg; + /// The Store of the detector elements (lifetime: job) - std::vector>> - m_detectorStore; + DetectorStore m_detectorStore; + + void buildTrackingGeometry() final; }; } // namespace ActsExamples::Contextual diff --git a/Examples/Detectors/ContextualDetector/src/AlignedDetector.cpp b/Examples/Detectors/ContextualDetector/src/AlignedDetector.cpp index e6459c2dbf4..1cc7c4fbc89 100644 --- a/Examples/Detectors/ContextualDetector/src/AlignedDetector.cpp +++ b/Examples/Detectors/ContextualDetector/src/AlignedDetector.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2019 CERN for the benefit of the Acts project +// Copyright (C) 2019-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -9,6 +9,7 @@ #include "ActsExamples/ContextualDetector/AlignedDetector.hpp" #include "Acts/Definitions/Units.hpp" +#include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/ILayerBuilder.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" #include "Acts/Utilities/Logger.hpp" @@ -17,44 +18,46 @@ #include "ActsExamples/ContextualDetector/ExternallyAlignedDetectorElement.hpp" #include "ActsExamples/ContextualDetector/InternalAlignmentDecorator.hpp" #include "ActsExamples/ContextualDetector/InternallyAlignedDetectorElement.hpp" +#include "ActsExamples/DetectorCommons/Detector.hpp" #include "ActsExamples/Framework/RandomNumbers.hpp" #include "ActsExamples/GenericDetector/BuildGenericDetector.hpp" #include "ActsExamples/GenericDetector/ProtoLayerCreatorT.hpp" using namespace Acts::UnitLiterals; + namespace ActsExamples::Contextual { -auto AlignedDetector::finalize( - const Config& cfg, - std::shared_ptr mdecorator) - -> std::pair { - ContextDecorators aContextDecorators; +AlignedDetector::AlignedDetector(const Config& cfg) + : DetectorCommons::Detector( + Acts::getDefaultLogger("AlignedDetector", m_cfg.logLevel)), + m_cfg(cfg) {} +void AlignedDetector::buildTrackingGeometry() { // Let's create a random number service ActsExamples::RandomNumbers::Config randomNumberConfig; - randomNumberConfig.seed = cfg.seed; + randomNumberConfig.seed = m_cfg.seed; auto randomNumberSvc = std::make_shared(randomNumberConfig); auto fillDecoratorConfig = [&](AlignmentDecorator::Config& config) { - config.iovSize = cfg.iovSize; - config.flushSize = cfg.flushSize; - config.doGarbageCollection = cfg.doGarbageCollection; + config.iovSize = m_cfg.iovSize; + config.flushSize = m_cfg.flushSize; + config.doGarbageCollection = m_cfg.doGarbageCollection; // The misalignments - config.gSigmaX = cfg.sigmaInPlane; - config.gSigmaY = cfg.sigmaInPlane; - config.gSigmaZ = cfg.sigmaOutPlane; - config.aSigmaX = cfg.sigmaOutRot; - config.aSigmaY = cfg.sigmaOutRot; - config.aSigmaZ = cfg.sigmaInRot; + config.gSigmaX = m_cfg.sigmaInPlane; + config.gSigmaY = m_cfg.sigmaInPlane; + config.gSigmaZ = m_cfg.sigmaOutPlane; + config.aSigmaX = m_cfg.sigmaOutRot; + config.aSigmaY = m_cfg.sigmaOutRot; + config.aSigmaZ = m_cfg.sigmaInRot; config.randomNumberSvc = randomNumberSvc; - config.firstIovNominal = cfg.firstIovNominal; + config.firstIovNominal = m_cfg.firstIovNominal; }; - TrackingGeometryPtr aTrackingGeometry; - if (cfg.mode == Config::Mode::External) { - ExternallyAlignedDetectorElement::ContextType nominalContext; + if (m_cfg.mode == Config::Mode::External) { + InternallyAlignedDetectorElement::ContextType nominalContext; + auto gctx = Acts::GeometryContext(nominalContext); ExternalAlignmentDecorator::Config agcsConfig; fillDecoratorConfig(agcsConfig); @@ -62,13 +65,12 @@ auto AlignedDetector::finalize( std::vector>> detectorStore; - aTrackingGeometry = + m_trackingGeometry = ActsExamples::Generic::buildDetector( - nominalContext, detectorStore, cfg.buildLevel, - std::move(mdecorator), cfg.buildProto, cfg.surfaceLogLevel, - cfg.layerLogLevel, cfg.volumeLogLevel); - - agcsConfig.trackingGeometry = aTrackingGeometry; + gctx, detectorStore, m_cfg.buildLevel, m_cfg.materialDecorator, + m_cfg.buildProto, m_cfg.surfaceLogLevel, m_cfg.layerLogLevel, + m_cfg.volumeLogLevel); + agcsConfig.trackingGeometry = m_trackingGeometry; // need to upcast to store in this object as well for (auto& lstore : detectorStore) { @@ -78,21 +80,22 @@ auto AlignedDetector::finalize( } } - aContextDecorators.push_back(std::make_shared( + m_contextDecorators.push_back(std::make_shared( std::move(agcsConfig), - Acts::getDefaultLogger("AlignmentDecorator", cfg.decoratorLogLevel))); + Acts::getDefaultLogger("AlignmentDecorator", m_cfg.decoratorLogLevel))); } else { InternallyAlignedDetectorElement::ContextType nominalContext; nominalContext.nominal = true; + auto gctx = Acts::GeometryContext(nominalContext); InternalAlignmentDecorator::Config agcsConfig; fillDecoratorConfig(agcsConfig); - aTrackingGeometry = + m_trackingGeometry = ActsExamples::Generic::buildDetector( - nominalContext, agcsConfig.detectorStore, cfg.buildLevel, - std::move(mdecorator), cfg.buildProto, cfg.surfaceLogLevel, - cfg.layerLogLevel, cfg.volumeLogLevel); + gctx, agcsConfig.detectorStore, m_cfg.buildLevel, + m_cfg.materialDecorator, m_cfg.buildProto, m_cfg.surfaceLogLevel, + m_cfg.layerLogLevel, m_cfg.volumeLogLevel); // need to upcast to store in this object as well for (auto& lstore : agcsConfig.detectorStore) { @@ -102,14 +105,10 @@ auto AlignedDetector::finalize( } } - aContextDecorators.push_back(std::make_shared( + m_contextDecorators.push_back(std::make_shared( std::move(agcsConfig), - Acts::getDefaultLogger("AlignmentDecorator", cfg.decoratorLogLevel))); + Acts::getDefaultLogger("AlignmentDecorator", m_cfg.decoratorLogLevel))); } - - // return the pair of geometry and the alignment decorator(s) - return std::make_pair( - std::move(aTrackingGeometry), std::move(aContextDecorators)); } } // namespace ActsExamples::Contextual diff --git a/Examples/Detectors/DD4hepDetector/CMakeLists.txt b/Examples/Detectors/DD4hepDetector/CMakeLists.txt index 847ab8f4d23..c4cf00a80d1 100644 --- a/Examples/Detectors/DD4hepDetector/CMakeLists.txt +++ b/Examples/Detectors/DD4hepDetector/CMakeLists.txt @@ -1,7 +1,6 @@ add_library( ActsExamplesDetectorDD4hep SHARED - src/DD4hepGeometryService.cpp) - + src/DD4hepDetector.cpp) target_include_directories( ActsExamplesDetectorDD4hep @@ -9,9 +8,10 @@ target_include_directories( target_link_libraries( ActsExamplesDetectorDD4hep PUBLIC - ActsCore ActsPluginDD4hep + ActsCore + ActsPluginDD4hep ActsExamplesFramework - ROOT::Geom ROOT::GenVector) + ActsExamplesDetectorCommons) if(${DD4hep_VERSION} VERSION_LESS 1.11) target_include_directories(ActsExamplesDetectorDD4hep PUBLIC ${DD4hep_INCLUDE_DIRS}) diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp similarity index 72% rename from Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp rename to Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp index 59488bcfff3..9c631df9f97 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp @@ -15,6 +15,7 @@ #include "Acts/Material/IMaterialDecorator.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/DetectorCommons/Detector.hpp" #include "ActsExamples/Framework/ProcessCode.hpp" #include @@ -24,35 +25,21 @@ #include #include -#include class TGeoNode; -namespace dd4hep { -class Detector; -} // namespace dd4hep - -namespace Acts { -class IMaterialDecorator; -class TrackingGeometry; -} // namespace Acts - -namespace ActsExamples { -class IContextDecorator; -} // namespace ActsExamples - namespace ActsExamples::DD4hep { void sortFCChhDetElements(std::vector& det); -/// @class DD4hepGeometryService +/// @class DD4hepDetector /// -/// @brief service creating geometries from dd4hep input +/// @brief geometries from dd4hep input /// -/// The DD4hepGeometryService creates the DD4hep, the TGeo and the ACTS +/// The DD4hepDetector creates the DD4hep, the TGeo and the ACTS /// TrackingGeometry from DD4hep xml input. The geometries are created only on /// demand. -class DD4hepGeometryService { +class DD4hepDetector : public DetectorCommons::Detector { public: /// @brief The context decorators using ContextDecorators = @@ -90,59 +77,42 @@ class DD4hepGeometryService { std::function& detectors)> sortDetectors = sortFCChhDetElements; /// Material decorator - std::shared_ptr matDecorator; + std::shared_ptr materialDecorator; /// Optional geometry identifier hook to be used during closure std::shared_ptr geometryIdentifierHook = std::make_shared(); }; - DD4hepGeometryService(const Config& cfg); - ~DD4hepGeometryService(); + explicit DD4hepDetector(const Config& cfg); /// Interface method to access to the DD4hep geometry - dd4hep::Detector& detector(); + dd4hep::Detector& dd4hepDetector(); /// Interface method to access the DD4hep geometry /// @return The world DD4hep DetElement - dd4hep::DetElement& geometry(); + dd4hep::DetElement& dd4hepGeometry(); /// Interface method to Access the TGeo geometry /// @return The world TGeoNode (physical volume) TGeoNode& tgeoGeometry(); - std::shared_ptr trackingGeometry(); - - /// Interface method to access the ACTS TrackingGeometry - /// - /// @param gctx is the geometry context object - std::shared_ptr trackingGeometry( - const Acts::GeometryContext& gctx); - - ContextDecorators contextDecorators() const; - - void drop(); + void drop() final; private: /// Private method to initiate building of the DD4hep geometry - ActsExamples::ProcessCode buildDD4hepGeometry(); + void buildDD4hepGeometry(); - /// Private method to initiate building of the ACTS tracking geometry - ActsExamples::ProcessCode buildTrackingGeometry( - const Acts::GeometryContext& gctx); + void buildTrackingGeometry() final; /// The config class Config m_cfg; /// Pointer to the interface to the DD4hep geometry - dd4hep::Detector* m_detector = nullptr; + std::unique_ptr m_detector; /// The world DD4hep DetElement dd4hep::DetElement m_geometry; /// The ACTS TrackingGeometry std::shared_ptr m_trackingGeometry; - - const Acts::Logger& logger() const { return *m_logger; } - - std::unique_ptr m_logger; }; } // namespace ActsExamples::DD4hep diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp similarity index 72% rename from Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp rename to Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp index b0a2dd8d4b7..beced812f0d 100644 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp @@ -6,11 +6,13 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" +#include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" +#include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" #include "Acts/Plugins/DD4hep/ConvertDD4hepDetector.hpp" #include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/DetectorCommons/Detector.hpp" #include #include @@ -27,22 +29,37 @@ class TGeoNode; namespace ActsExamples::DD4hep { -DD4hepGeometryService::DD4hepGeometryService( - const DD4hepGeometryService::Config& cfg) - : m_cfg(cfg), - m_logger{Acts::getDefaultLogger("DD4hepGeometryService", cfg.logLevel)} { +DD4hepDetector::DD4hepDetector(const DD4hepDetector::Config& cfg) + : DetectorCommons::Detector( + Acts::getDefaultLogger("DD4hepDetector", cfg.logLevel)), + m_cfg(cfg) { if (m_cfg.xmlFileNames.empty()) { throw std::invalid_argument("Missing DD4hep XML filenames"); } } -DD4hepGeometryService::~DD4hepGeometryService() { - if (m_detector != nullptr) { - m_detector->destroyInstance(); +dd4hep::Detector& DD4hepDetector::DD4hepDetector::dd4hepDetector() { + if (m_detector == nullptr) { + buildDD4hepGeometry(); + } + return *m_detector; +} + +dd4hep::DetElement& DD4hepDetector::dd4hepGeometry() { + if (!m_geometry) { + buildDD4hepGeometry(); } + return m_geometry; } -ActsExamples::ProcessCode DD4hepGeometryService::buildDD4hepGeometry() { +TGeoNode& DD4hepDetector::tgeoGeometry() { + if (!m_geometry) { + buildDD4hepGeometry(); + } + return *m_geometry.placement().ptr(); +} + +void DD4hepDetector::buildDD4hepGeometry() { const int old_gErrorIgnoreLevel = gErrorIgnoreLevel; switch (m_cfg.dd4hepLogLevel) { case Acts::Logging::Level::VERBOSE: @@ -75,7 +92,7 @@ ActsExamples::ProcessCode DD4hepGeometryService::buildDD4hepGeometry() { std::cout.setstate(std::ios_base::failbit); } - m_detector = &dd4hep::Detector::getInstance(); + m_detector = dd4hep::Detector::make_unique(m_cfg.name); for (auto& file : m_cfg.xmlFileNames) { m_detector->fromCompact(file.c_str()); } @@ -86,69 +103,19 @@ ActsExamples::ProcessCode DD4hepGeometryService::buildDD4hepGeometry() { // restore the logging gErrorIgnoreLevel = old_gErrorIgnoreLevel; std::cout.clear(); - - return ActsExamples::ProcessCode::SUCCESS; } -dd4hep::Detector& DD4hepGeometryService::DD4hepGeometryService::detector() { - if (m_detector == nullptr) { - buildDD4hepGeometry(); - } - return *m_detector; -} - -dd4hep::DetElement& DD4hepGeometryService::geometry() { - if (!m_geometry) { - buildDD4hepGeometry(); - } - return m_geometry; -} - -TGeoNode& DD4hepGeometryService::tgeoGeometry() { - if (!m_geometry) { - buildDD4hepGeometry(); - } - return *m_geometry.placement().ptr(); -} - -ActsExamples::ProcessCode DD4hepGeometryService::buildTrackingGeometry( - const Acts::GeometryContext& gctx) { - // Set the tracking geometry +void DD4hepDetector::buildTrackingGeometry() { + Acts::GeometryContext gctx; auto logger = Acts::getDefaultLogger("DD4hepConversion", m_cfg.logLevel); m_trackingGeometry = Acts::convertDD4hepDetector( - geometry(), *logger, m_cfg.bTypePhi, m_cfg.bTypeR, m_cfg.bTypeZ, + m_geometry, *logger, m_cfg.bTypePhi, m_cfg.bTypeR, m_cfg.bTypeZ, m_cfg.envelopeR, m_cfg.envelopeZ, m_cfg.defaultLayerThickness, - m_cfg.sortDetectors, gctx, m_cfg.matDecorator, + m_cfg.sortDetectors, gctx, m_cfg.materialDecorator, m_cfg.geometryIdentifierHook); - return ActsExamples::ProcessCode::SUCCESS; -} - -std::shared_ptr -DD4hepGeometryService::trackingGeometry() { - Acts::GeometryContext gctx; - if (!m_trackingGeometry) { - buildTrackingGeometry(gctx); - } - return m_trackingGeometry; } -std::shared_ptr -DD4hepGeometryService::trackingGeometry(const Acts::GeometryContext& gctx) { - if (!m_trackingGeometry) { - buildTrackingGeometry(gctx); - } - return m_trackingGeometry; -} - -DD4hepGeometryService::ContextDecorators -DD4hepGeometryService::contextDecorators() const { - return ContextDecorators{}; -} - -void DD4hepGeometryService::drop() { - if (m_detector != nullptr) { - m_detector->destroyInstance(); - } +void DD4hepDetector::drop() { m_detector = nullptr; m_geometry = dd4hep::DetElement(); m_trackingGeometry.reset(); diff --git a/Examples/Detectors/Geant4Detector/CMakeLists.txt b/Examples/Detectors/Geant4Detector/CMakeLists.txt index c10d4b682cb..a10cf038e2c 100644 --- a/Examples/Detectors/Geant4Detector/CMakeLists.txt +++ b/Examples/Detectors/Geant4Detector/CMakeLists.txt @@ -1,13 +1,19 @@ add_library( ActsExamplesDetectorGeant4 SHARED - src/Geant4Detector.cpp - ) + src/Geant4Detector.cpp) + target_include_directories( - ActsExamplesDetectorGeant4 + ActsExamplesDetectorGeant4 PUBLIC $) + target_link_libraries( - ActsExamplesDetectorGeant4 - PUBLIC ActsCore ActsExamplesFramework ActsExamplesGeant4 ActsPluginGeant4) + ActsExamplesDetectorGeant4 + PUBLIC + ActsCore + ActsExamplesFramework + ActsExamplesGeant4 + ActsPluginGeant4 + ActsExamplesDetectorCommons) install( TARGETS ActsExamplesDetectorGeant4 diff --git a/Examples/Detectors/Geant4Detector/include/ActsExamples/Geant4Detector/Geant4Detector.hpp b/Examples/Detectors/Geant4Detector/include/ActsExamples/Geant4Detector/Geant4Detector.hpp index 1899a1e035a..c88b70dab40 100644 --- a/Examples/Detectors/Geant4Detector/include/ActsExamples/Geant4Detector/Geant4Detector.hpp +++ b/Examples/Detectors/Geant4Detector/include/ActsExamples/Geant4Detector/Geant4Detector.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2022-2023 CERN for the benefit of the Acts project +// Copyright (C) 2022-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -12,6 +12,7 @@ #include "Acts/Geometry/GeometryIdentifier.hpp" #include "Acts/Plugins/Geant4/Geant4DetectorSurfaceFactory.hpp" #include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/DetectorCommons/Detector.hpp" #include #include @@ -32,18 +33,19 @@ class Detector; namespace ActsExamples { class IContextDecorator; +} // namespace ActsExamples -namespace Geant4 { +namespace ActsExamples::Geant4 { -struct Geant4Detector { - using DetectorElements = - std::vector>; +struct Geant4Detector : public DetectorCommons::Detector { + using TrackingGeometryPtr = std::shared_ptr; using DetectorPtr = std::shared_ptr; - using Surfaces = std::vector>; - using ContextDecorators = std::vector>; - using TrackingGeometryPtr = std::shared_ptr; + + using DetectorElements = + std::vector>; + using Surfaces = std::vector>; /// Nested configuration struct struct Config { @@ -62,12 +64,30 @@ struct Geant4Detector { Acts::Logging::Level logLevel = Acts::Logging::INFO; }; + explicit Geant4Detector(const Config& cfg); + + const DetectorElements& detectorElements() const; + + void drop() final; + + private: + Config m_cfg; + + DetectorElements m_detectorElements; + + std::unique_ptr m_logger; + + const Acts::Logger& logger() const { return *m_logger; } + + void buildTrackingGeometry() final; + void buildDetector() final; + /// @brief Construct an Acts::Detector from a Geant4 world volume /// @param cfg the configuration of the Geant4 detector /// @param logger a logger instance /// @return a tuple of an Acts::Detector object, a ContextDecorator & the created detector elements std::tuple - constructDetector(const Config& cfg, const Acts::Logger& logger); + constructDetector() const; /// @brief Construct a TrackingGeometry from a Geant4 world volume using the KDTreeTrackingGeometryBuilder builder /// @@ -77,18 +97,15 @@ struct Geant4Detector { /// /// @return a tuple of an Acts::TrackingGeometry object, a ContextDecorator & the created detector elements std::tuple - constructTrackingGeometry(const Config& cfg, const Acts::Logger& logger); + constructTrackingGeometry() const; - private: /// @brief Convert Geant4VPhysicalVolume objects into Acts components /// /// @param cfg the configuration of the Geant4 detector /// @param logger a logger instance /// /// @return a tuple of surfaces and detector elements - std::tuple convertGeant4Volumes( - const Config& cfg, const Acts::Logger& logger) const; + std::tuple convertGeant4Volumes() const; }; -} // namespace Geant4 -} // namespace ActsExamples +} // namespace ActsExamples::Geant4 diff --git a/Examples/Detectors/Geant4Detector/src/Geant4Detector.cpp b/Examples/Detectors/Geant4Detector/src/Geant4Detector.cpp index 828304e342c..42a8e4f2ce0 100644 --- a/Examples/Detectors/Geant4Detector/src/Geant4Detector.cpp +++ b/Examples/Detectors/Geant4Detector/src/Geant4Detector.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2022-2023 CERN for the benefit of the Acts project +// Copyright (C) 2022-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -16,6 +16,7 @@ #include "Acts/Geometry/SurfaceArrayCreator.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" #include "Acts/Geometry/TrackingVolumeArrayCreator.hpp" +#include "ActsExamples/DetectorCommons/Detector.hpp" #include #include @@ -23,97 +24,123 @@ #include "G4Transform3D.hh" #include "G4VPhysicalVolume.hh" -auto ActsExamples::Geant4::Geant4Detector::constructDetector( - const ActsExamples::Geant4::Geant4Detector::Config& cfg, - const Acts::Logger& logger) - -> std::tuple { - if (cfg.g4World == nullptr) { +namespace ActsExamples::Geant4 { + +Geant4Detector::Geant4Detector(const Geant4Detector::Config& cfg) + : DetectorCommons::Detector( + Acts::getDefaultLogger("Geant4Detector", m_cfg.logLevel)), + m_cfg(cfg) {} + +const Geant4Detector::DetectorElements& Geant4Detector::detectorElements() + const { + return m_detectorElements; +} + +void Geant4Detector::drop() { + Detector::drop(); + + m_detectorElements.clear(); +} + +void Geant4Detector::buildTrackingGeometry() { + std::tie(m_trackingGeometry, m_contextDecorators, m_detectorElements) = + constructTrackingGeometry(); +} + +void Geant4Detector::buildDetector() { + std::tie(m_detector, m_contextDecorators, m_detectorElements) = + constructDetector(); +} + +std::tuple +Geant4Detector::constructDetector() const { + if (m_cfg.g4World == nullptr) { throw std::invalid_argument( "Geant4Detector: no world Geant4 volume provided"); } ACTS_INFO("Building an Acts::Detector called '" - << cfg.name << "' from the Geant4PhysVolume '" - << cfg.g4World->GetName() << "'"); + << m_cfg.name << "' from the Geant4PhysVolume '" + << m_cfg.g4World->GetName() << "'"); DetectorPtr detector = nullptr; ContextDecorators decorators = {}; - auto [surfaces, elements] = convertGeant4Volumes(cfg, logger); + auto [surfaces, elements] = convertGeant4Volumes(); - return std::tie(detector, decorators, elements); + return {std::move(detector), std::move(decorators), std::move(elements)}; } -auto ActsExamples::Geant4::Geant4Detector::constructTrackingGeometry( - const ActsExamples::Geant4::Geant4Detector::Config& cfg, - const Acts::Logger& logger) - -> std::tuple { - if (cfg.g4World == nullptr) { +std::tuple +Geant4Detector::constructTrackingGeometry() const { + if (m_cfg.g4World == nullptr) { throw std::invalid_argument( "Geant4Detector: no world Geant4 volume provided"); } ACTS_INFO("Building an Acts::TrackingGeometry called '" - << cfg.name << "' from the Geant4PhysVolume '" - << cfg.g4World->GetName() << "'"); + << m_cfg.name << "' from the Geant4PhysVolume '" + << m_cfg.g4World->GetName() << "'"); ContextDecorators decorators = {}; - auto [surfaces, elements] = convertGeant4Volumes(cfg, logger); + auto [surfaces, elements] = convertGeant4Volumes(); // Surface array creator auto surfaceArrayCreator = std::make_shared( - Acts::SurfaceArrayCreator::Config(), logger.clone("SurfaceArrayCreator")); + Acts::SurfaceArrayCreator::Config(), + logger().clone("SurfaceArrayCreator")); // Layer Creator Acts::LayerCreator::Config lcConfig; lcConfig.surfaceArrayCreator = surfaceArrayCreator; auto layerCreator = std::make_shared( - lcConfig, logger.clone("LayerCreator")); + lcConfig, logger().clone("LayerCreator")); // Layer array creator Acts::LayerArrayCreator::Config lacConfig; auto layerArrayCreator = std::make_shared( - lacConfig, logger.clone("LayerArrayCreator")); + lacConfig, logger().clone("LayerArrayCreator")); // Tracking volume array creator Acts::TrackingVolumeArrayCreator::Config tvacConfig; auto tVolumeArrayCreator = std::make_shared( - tvacConfig, logger.clone("TrackingVolumeArrayCreator")); + tvacConfig, logger().clone("TrackingVolumeArrayCreator")); // configure the cylinder volume helper Acts::CylinderVolumeHelper::Config cvhConfig; cvhConfig.layerArrayCreator = layerArrayCreator; cvhConfig.trackingVolumeArrayCreator = tVolumeArrayCreator; auto cylinderVolumeHelper = std::make_shared( - cvhConfig, logger.clone("CylinderVolumeHelper")); + cvhConfig, logger().clone("CylinderVolumeHelper")); // Configure the tracking geometry builder, copy the surfaces in Acts::KDTreeTrackingGeometryBuilder::Config kdtCfg; kdtCfg.surfaces = surfaces; kdtCfg.layerCreator = layerCreator; kdtCfg.trackingVolumeHelper = cylinderVolumeHelper; - kdtCfg.protoDetector = cfg.protoDetector; - kdtCfg.geometryIdentifierHook = cfg.geometryIdentifierHook; + kdtCfg.protoDetector = m_cfg.protoDetector; + kdtCfg.geometryIdentifierHook = m_cfg.geometryIdentifierHook; // The KDT tracking geometry builder auto kdtBuilder = Acts::KDTreeTrackingGeometryBuilder( - kdtCfg, logger.clone("KDTreeTrackingGeometryBuilder")); + kdtCfg, logger().clone("KDTreeTrackingGeometryBuilder")); Acts::GeometryContext tContext; TrackingGeometryPtr trackingGeometry = kdtBuilder.trackingGeometry(tContext); - return std::tie(trackingGeometry, decorators, elements); + return {std::move(trackingGeometry), std::move(decorators), + std::move(elements)}; } -auto ActsExamples::Geant4::Geant4Detector::convertGeant4Volumes( - const Geant4Detector::Config& cfg, const Acts::Logger& logger) const - -> std::tuple { +std::tuple +Geant4Detector::convertGeant4Volumes() const { // Generate the surface cache Acts::Geant4DetectorSurfaceFactory::Cache g4SurfaceCache; G4Transform3D g4ToWorld; Acts::Geant4DetectorSurfaceFactory{}.construct( - g4SurfaceCache, g4ToWorld, *cfg.g4World, cfg.g4SurfaceOptions); + g4SurfaceCache, g4ToWorld, *m_cfg.g4World, m_cfg.g4SurfaceOptions); ACTS_INFO("Found " << g4SurfaceCache.matchedG4Volumes << " matching Geant4 Physical volumes."); @@ -141,5 +168,7 @@ auto ActsExamples::Geant4::Geant4Detector::convertGeant4Volumes( surfaces.insert(surfaces.end(), g4SurfaceCache.passiveSurfaces.begin(), g4SurfaceCache.passiveSurfaces.end()); - return std::tie(surfaces, elements); + return {std::move(surfaces), std::move(elements)}; } + +} // namespace ActsExamples::Geant4 diff --git a/Examples/Detectors/GenericDetector/CMakeLists.txt b/Examples/Detectors/GenericDetector/CMakeLists.txt index 28614c7ae7b..0df8532bc4b 100644 --- a/Examples/Detectors/GenericDetector/CMakeLists.txt +++ b/Examples/Detectors/GenericDetector/CMakeLists.txt @@ -3,15 +3,17 @@ add_library( src/BuildGenericDetector.cpp src/GenericDetector.cpp src/GenericDetectorElement.cpp) + target_include_directories( ActsExamplesDetectorGeneric PUBLIC $) + target_link_libraries( ActsExamplesDetectorGeneric - PUBLIC ActsCore) -target_link_libraries( - ActsExamplesDetectorGeneric - PUBLIC ActsExamplesFramework) + PUBLIC + ActsCore + ActsExamplesFramework + ActsExamplesDetectorCommons) install( TARGETS ActsExamplesDetectorGeneric diff --git a/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/BuildGenericDetector.hpp b/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/BuildGenericDetector.hpp index 9d42ad9441c..d8a9a96afec 100644 --- a/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/BuildGenericDetector.hpp +++ b/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/BuildGenericDetector.hpp @@ -108,7 +108,7 @@ std::vector> modulePositionsDisc( /// return a unique vector to the tracking geometry template std::unique_ptr buildDetector( - const typename detector_element_t::ContextType& gctxIn, + const Acts::GeometryContext& gctxIn, std::vector>>& detectorStore, std::size_t level, diff --git a/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/GenericDetector.hpp b/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/GenericDetector.hpp index 0279b91efef..a731ec547da 100644 --- a/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/GenericDetector.hpp +++ b/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/GenericDetector.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2019 CERN for the benefit of the Acts project +// Copyright (C) 2019-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -9,46 +9,40 @@ #pragma once #include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/DetectorCommons/Detector.hpp" #include #include #include #include -namespace Acts { -class TrackingGeometry; -class IMaterialDecorator; -} // namespace Acts - -namespace ActsExamples { -class IContextDecorator; -} // namespace ActsExamples - namespace ActsExamples::Generic { class GenericDetectorElement; -} // namespace ActsExamples::Generic - -struct GenericDetector { - using DetectorElement = ActsExamples::Generic::GenericDetectorElement; - using DetectorElementPtr = std::shared_ptr; - using DetectorStore = std::vector>; +class GenericDetector : public ActsExamples::DetectorCommons::Detector { + public: + using TrackingGeometryPtr = std::shared_ptr; using ContextDecorators = std::vector>; - using TrackingGeometryPtr = std::shared_ptr; + + using DetectorElement = ActsExamples::Generic::GenericDetectorElement; struct Config { std::size_t buildLevel{3}; + Acts::Logging::Level logLevel{Acts::Logging::INFO}; Acts::Logging::Level surfaceLogLevel{Acts::Logging::INFO}; Acts::Logging::Level layerLogLevel{Acts::Logging::INFO}; Acts::Logging::Level volumeLogLevel{Acts::Logging::INFO}; bool buildProto{false}; + std::shared_ptr materialDecorator; }; - /// The Store of the detector elements (lifetime: job) - DetectorStore detectorStore; + explicit GenericDetector(const Config& cfg); - std::pair finalize( - const Config& cfg, - std::shared_ptr mdecorator); + private: + Config m_cfg; + + void buildTrackingGeometry() final; }; + +} // namespace ActsExamples::Generic diff --git a/Examples/Detectors/GenericDetector/src/GenericDetector.cpp b/Examples/Detectors/GenericDetector/src/GenericDetector.cpp index 044f2e209fa..77dce6aea69 100644 --- a/Examples/Detectors/GenericDetector/src/GenericDetector.cpp +++ b/Examples/Detectors/GenericDetector/src/GenericDetector.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2019 CERN for the benefit of the Acts project +// Copyright (C) 2019-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,25 +8,34 @@ #include "ActsExamples/GenericDetector/GenericDetector.hpp" +#include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/ILayerBuilder.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" +#include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/DetectorCommons/Detector.hpp" #include "ActsExamples/GenericDetector/BuildGenericDetector.hpp" #include "ActsExamples/GenericDetector/GenericDetectorElement.hpp" #include "ActsExamples/GenericDetector/ProtoLayerCreatorT.hpp" -auto GenericDetector::finalize( - const Config& cfg, - std::shared_ptr mdecorator) - -> std::pair { - DetectorElement::ContextType nominalContext; - /// Return the generic detector - TrackingGeometryPtr gGeometry = - ActsExamples::Generic::buildDetector( - nominalContext, detectorStore, cfg.buildLevel, std::move(mdecorator), - cfg.buildProto, cfg.surfaceLogLevel, cfg.layerLogLevel, - cfg.volumeLogLevel); - ContextDecorators gContextDecorators = {}; - // return the pair of geometry and empty decorators - return std::make_pair( - std::move(gGeometry), std::move(gContextDecorators)); +namespace ActsExamples::Generic { + +GenericDetector::GenericDetector(const Config& cfg) + : DetectorCommons::Detector( + Acts::getDefaultLogger("GenericDetector", m_cfg.logLevel)), + m_cfg(cfg) {} + +void GenericDetector::buildTrackingGeometry() { + Acts::GeometryContext gctx; + std::vector>> detectorStore; + m_trackingGeometry = ActsExamples::Generic::buildDetector( + gctx, detectorStore, m_cfg.buildLevel, m_cfg.materialDecorator, + m_cfg.buildProto, m_cfg.surfaceLogLevel, m_cfg.layerLogLevel, + m_cfg.volumeLogLevel); + for (auto& something : detectorStore) { + for (auto& element : something) { + m_detectorStore.push_back(std::move(element)); + } + } } + +} // namespace ActsExamples::Generic diff --git a/Examples/Detectors/MuonSpectrometerMockupDetector/src/MockupSectorBuilder.cpp b/Examples/Detectors/MuonSpectrometerMockupDetector/src/MockupSectorBuilder.cpp index b9b6e3ec3b1..0659e185dab 100644 --- a/Examples/Detectors/MuonSpectrometerMockupDetector/src/MockupSectorBuilder.cpp +++ b/Examples/Detectors/MuonSpectrometerMockupDetector/src/MockupSectorBuilder.cpp @@ -77,10 +77,9 @@ ActsExamples::MockupSectorBuilder::buildChamber( g4SurfaceOptions.passiveSurfaceSelector = g4Passive; g4WorldConfig.g4SurfaceOptions = g4SurfaceOptions; - auto g4detector = ActsExamples::Geant4::Geant4Detector(); - - auto [detector, surfaces, detectorElements] = - g4detector.constructDetector(g4WorldConfig, Acts::getDummyLogger()); + auto g4detector = ActsExamples::Geant4::Geant4Detector(g4WorldConfig); + // Trigger the build of the detector + g4detector.detector(); // The vector that holds the converted sensitive surfaces of the chamber std::vector> strawSurfaces = {}; @@ -91,7 +90,7 @@ ActsExamples::MockupSectorBuilder::buildChamber( -std::numeric_limits::max())); // Convert the physical volumes of the detector elements to straw surfaces - for (auto& detectorElement : detectorElements) { + for (auto& detectorElement : g4detector.detectorElements()) { auto context = Acts::GeometryContext(); auto g4conv = Acts::Geant4PhysicalVolumeConverter(); diff --git a/Examples/Detectors/TGeoDetector/CMakeLists.txt b/Examples/Detectors/TGeoDetector/CMakeLists.txt index ff5d8e24b86..47a8ea0a7a7 100644 --- a/Examples/Detectors/TGeoDetector/CMakeLists.txt +++ b/Examples/Detectors/TGeoDetector/CMakeLists.txt @@ -6,11 +6,16 @@ add_library( target_include_directories( ActsExamplesDetectorTGeo PUBLIC $) + target_link_libraries( ActsExamplesDetectorTGeo PUBLIC - ActsCore ActsPluginTGeo ActsPluginJson - ActsExamplesFramework ActsExamplesDetectorGeneric) + ActsCore + ActsPluginTGeo + ActsPluginJson + ActsExamplesFramework + ActsExamplesDetectorGeneric + ActsExamplesDetectorCommons) install( TARGETS ActsExamplesDetectorTGeo @@ -18,4 +23,4 @@ install( install( DIRECTORY include/ActsExamples - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) \ No newline at end of file + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/JsonTGeoDetectorConfig.hpp b/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/JsonTGeoDetectorConfig.hpp index 634127fc9b3..928feb96760 100644 --- a/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/JsonTGeoDetectorConfig.hpp +++ b/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/JsonTGeoDetectorConfig.hpp @@ -53,29 +53,26 @@ NLOHMANN_JSON_SERIALIZE_ENUM(Acts::BinningType, } // namespace Acts -namespace ActsExamples { - -namespace Options { +namespace ActsExamples::Options { /// Read config for options interval -void from_json(const nlohmann::json& j, - ActsExamples::Options::Interval& interval) { +void from_json(const nlohmann::json& j, Interval& interval) { interval.lower = j.at("lower"); interval.upper = j.at("upper"); } /// Write config for options interval -void to_json(nlohmann::json& j, - const ActsExamples::Options::Interval& interval) { +void to_json(nlohmann::json& j, const Interval& interval) { // no direct conversion from std::optional to json j = nlohmann::json{{"lower", interval.lower.value_or(0)}, {"upper", interval.upper.value_or(0)}}; } -} // namespace Options +} // namespace ActsExamples::Options -void from_json(const nlohmann::json& j, - ActsExamples::TGeoITkModuleSplitter::Config& msc) { +namespace ActsExamples::TGeo { + +void from_json(const nlohmann::json& j, TGeoITkModuleSplitter::Config& msc) { msc.barrelMap = j["geo-tgeo-barrel-map"].get>(); msc.discMap = @@ -83,8 +80,7 @@ void from_json(const nlohmann::json& j, .get>>>(); } -void to_json(nlohmann::json& j, - const ActsExamples::TGeoITkModuleSplitter::Config& msc) { +void to_json(nlohmann::json& j, const TGeoITkModuleSplitter::Config& msc) { j["geo-tgeo-barrel-map"] = msc.barrelMap; j["geo-tgeo-disc-map"] = msc.discMap; } @@ -92,7 +88,7 @@ void to_json(nlohmann::json& j, /// Read layer configuration triplets template void from_json(const nlohmann::json& j, - ActsExamples::TGeoDetector::Config::LayerTriplet& ltr) { + TGeoDetector::Config::LayerTriplet& ltr) { ltr.negative = j.at("negative").get(); ltr.central = j.at("central").get(); ltr.positive = j.at("positive").get(); @@ -101,15 +97,14 @@ void from_json(const nlohmann::json& j, /// Write layer configuration triplets template void to_json(nlohmann::json& j, - const ActsExamples::TGeoDetector::Config::LayerTriplet& ltr) { + const TGeoDetector::Config::LayerTriplet& ltr) { j = nlohmann::json{{"negative", ltr.negative}, {"central", ltr.central}, {"positive", ltr.positive}}; } /// Read volume struct -void from_json(const nlohmann::json& j, - ActsExamples::TGeoDetector::Config::Volume& vol) { +void from_json(const nlohmann::json& j, TGeoDetector::Config::Volume& vol) { // subdetector selection vol.name = j.at("geo-tgeo-volume-name"); @@ -145,8 +140,7 @@ void from_json(const nlohmann::json& j, if (j.count("geo-tgeo-itk-module-split") != 0) { vol.itkModuleSplit = j.at("geo-tgeo-itk-module-split"); if (vol.itkModuleSplit) { - ActsExamples::TGeoITkModuleSplitter::Config itkConfig = - j.at("Splitters").at("ITk"); + TGeoITkModuleSplitter::Config itkConfig = j.at("Splitters").at("ITk"); vol.barrelMap = itkConfig.barrelMap; vol.discMap = itkConfig.discMap; } @@ -185,11 +179,11 @@ void to_json(nlohmann::json& j, const TGeoDetector::Config::Volume& vol) { j["Splitters"]["CylinderDisk"] = cdConfig; if (vol.itkModuleSplit) { - ActsExamples::TGeoITkModuleSplitter::Config itkConfig; + TGeoITkModuleSplitter::Config itkConfig; itkConfig.barrelMap = vol.barrelMap; itkConfig.discMap = vol.discMap; j["Splitters"]["ITk"] = itkConfig; } } -} // namespace ActsExamples +} // namespace ActsExamples::TGeo diff --git a/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoDetector.hpp b/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoDetector.hpp index cb0b8d90f7a..7e652741fce 100644 --- a/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoDetector.hpp +++ b/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoDetector.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2018 CERN for the benefit of the Acts project +// Copyright (C) 2018-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -9,9 +9,11 @@ #pragma once #include "Acts/Geometry/GeometryIdentifier.hpp" +#include "Acts/Material/IMaterialDecorator.hpp" #include "Acts/Plugins/TGeo/TGeoLayerBuilder.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/DetectorCommons/Detector.hpp" #include "ActsExamples/Utilities/Options.hpp" #include @@ -22,30 +24,18 @@ #include #include -namespace Acts { -class TGeoDetectorElement; -class TrackingGeometry; -class IMaterialDecorator; -} // namespace Acts - -namespace ActsExamples { -class IContextDecorator; -} // namespace ActsExamples - -namespace ActsExamples { - -struct TGeoDetector { - using DetectorElementPtr = std::shared_ptr; - using DetectorStore = std::vector; +namespace ActsExamples::TGeo { +class TGeoDetector : public DetectorCommons::Detector { + public: + using TrackingGeometryPtr = std::shared_ptr; using ContextDecorators = std::vector>; - using TrackingGeometryPtr = std::shared_ptr; - /// The Store of the detector elements (lifetime: job) - DetectorStore detectorStore; + using DetectorElement = Acts::TGeoDetectorElement; struct Config { + Acts::Logging::Level logLevel = Acts::Logging::WARNING; Acts::Logging::Level surfaceLogLevel = Acts::Logging::WARNING; Acts::Logging::Level layerLogLevel = Acts::Logging::WARNING; Acts::Logging::Level volumeLogLevel = Acts::Logging::WARNING; @@ -69,6 +59,8 @@ struct TGeoDetector { std::shared_ptr geometryIdentifierHook = std::make_shared(); + std::shared_ptr materialDecorator; + enum SubVolume : std::size_t { Negative = 0, Central, Positive }; template @@ -150,9 +142,12 @@ struct TGeoDetector { static void readTGeoLayerBuilderConfigsFile(const std::string& path, Config& config); - std::pair finalize( - const Config& cfg, - std::shared_ptr mdecorator); + explicit TGeoDetector(const Config& cfg); + + private: + Config m_cfg; + + void buildTrackingGeometry() final; }; -} // namespace ActsExamples +} // namespace ActsExamples::TGeo diff --git a/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoITkModuleSplitter.hpp b/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoITkModuleSplitter.hpp index a08dbebd661..0596100c0f7 100644 --- a/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoITkModuleSplitter.hpp +++ b/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoITkModuleSplitter.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2021 CERN for the benefit of the Acts project +// Copyright (C) 2021-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -26,7 +26,7 @@ namespace Acts { class TGeoDetectorElement; } -namespace ActsExamples { +namespace ActsExamples::TGeo { /// @brief TGeoITkModuleSplitter /// @@ -120,4 +120,4 @@ class TGeoITkModuleSplitter : public Acts::ITGeoDetectorElementSplitter { std::unique_ptr m_logger; }; -} // namespace ActsExamples +} // namespace ActsExamples::TGeo diff --git a/Examples/Detectors/TGeoDetector/src/TGeoDetector.cpp b/Examples/Detectors/TGeoDetector/src/TGeoDetector.cpp index 77edfa78e1a..2d3a26895d4 100644 --- a/Examples/Detectors/TGeoDetector/src/TGeoDetector.cpp +++ b/Examples/Detectors/TGeoDetector/src/TGeoDetector.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2019 CERN for the benefit of the Acts project +// Copyright (C) 2019-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -10,6 +10,7 @@ #include "Acts/Geometry/CylinderVolumeBuilder.hpp" #include "Acts/Geometry/CylinderVolumeHelper.hpp" +#include "Acts/Geometry/DetectorElementBase.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/ITrackingVolumeBuilder.hpp" #include "Acts/Geometry/LayerArrayCreator.hpp" @@ -26,7 +27,6 @@ #include "Acts/Utilities/Logger.hpp" #include "ActsExamples/TGeoDetector/JsonTGeoDetectorConfig.hpp" #include "ActsExamples/TGeoDetector/TGeoITkModuleSplitter.hpp" -#include "ActsExamples/Utilities/Options.hpp" #include #include @@ -43,8 +43,7 @@ #include "TGeoManager.h" -namespace ActsExamples { -using namespace Options; +namespace ActsExamples::TGeo { namespace { @@ -135,12 +134,12 @@ std::vector makeLayerBuilderConfigs( cdsConfig, logger.clone("TGeoCylinderDiscSplitter", config.layerLogLevel)); } else if (volume.itkModuleSplit) { - ActsExamples::TGeoITkModuleSplitter::Config itkConfig; + TGeoITkModuleSplitter::Config itkConfig; itkConfig.barrelMap = volume.barrelMap; itkConfig.discMap = volume.discMap; itkConfig.splitPatterns = volume.splitPatterns; layerBuilderConfig.detectorElementSplitter = - std::make_shared( + std::make_shared( itkConfig, logger.clone("TGeoITkModuleSplitter", config.layerLogLevel)); } @@ -162,7 +161,7 @@ std::vector makeLayerBuilderConfigs( /// @param vm is the variable map from the options std::shared_ptr buildTGeoDetector( const TGeoDetector::Config& config, const Acts::GeometryContext& context, - std::vector>& + std::vector>& detElementStore, std::shared_ptr mdecorator, const Acts::Logger& logger) { @@ -367,23 +366,20 @@ void TGeoDetector::readTGeoLayerBuilderConfigsFile(const std::string& path, } } -auto TGeoDetector::finalize( - const Config& cfg, - std::shared_ptr mdecorator) - -> std::pair { - Acts::GeometryContext tGeoContext; - auto logger = Acts::getDefaultLogger("TGeoDetector", Acts::Logging::INFO); - TrackingGeometryPtr tgeoTrackingGeometry = buildTGeoDetector( - cfg, tGeoContext, detectorStore, std::move(mdecorator), *logger); - - ContextDecorators tgeoContextDecorators = {}; - // Return the pair of geometry and empty decorators - return std::make_pair( - std::move(tgeoTrackingGeometry), std::move(tgeoContextDecorators)); -} +TGeoDetector::TGeoDetector(const Config& cfg) + : DetectorCommons::Detector( + Acts::getDefaultLogger("TGeoDetector", m_cfg.logLevel)), + m_cfg(cfg) {} void TGeoDetector::Config::readJson(const std::string& jsonFile) { readTGeoLayerBuilderConfigsFile(jsonFile, *this); } -} // namespace ActsExamples +void TGeoDetector::buildTrackingGeometry() { + Acts::GeometryContext tGeoContext; + + m_trackingGeometry = buildTGeoDetector(m_cfg, tGeoContext, m_detectorStore, + m_cfg.materialDecorator, logger()); +} + +} // namespace ActsExamples::TGeo diff --git a/Examples/Detectors/TGeoDetector/src/TGeoITkModuleSplitter.cpp b/Examples/Detectors/TGeoDetector/src/TGeoITkModuleSplitter.cpp index df88593ff7a..d169ef9ae9c 100644 --- a/Examples/Detectors/TGeoDetector/src/TGeoITkModuleSplitter.cpp +++ b/Examples/Detectors/TGeoDetector/src/TGeoITkModuleSplitter.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2016-2020 CERN for the benefit of the Acts project +// Copyright (C) 2016-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -20,14 +20,16 @@ #include #include -ActsExamples::TGeoITkModuleSplitter::TGeoITkModuleSplitter( - const ActsExamples::TGeoITkModuleSplitter::Config& cfg, +namespace ActsExamples::TGeo { + +TGeoITkModuleSplitter::TGeoITkModuleSplitter( + const TGeoITkModuleSplitter::Config& cfg, std::unique_ptr logger) : m_cfg(cfg), m_logger(std::move(logger)) { initSplitCategories(); } -void ActsExamples::TGeoITkModuleSplitter::initSplitCategories() { +void TGeoITkModuleSplitter::initSplitCategories() { m_splitCategories.reserve(m_cfg.splitPatterns.size()); for (const std::pair& pattern_split_category : m_cfg.splitPatterns) { @@ -51,7 +53,7 @@ void ActsExamples::TGeoITkModuleSplitter::initSplitCategories() { /// If applicable, returns a split detector element inline std::vector> -ActsExamples::TGeoITkModuleSplitter::split( +TGeoITkModuleSplitter::split( const Acts::GeometryContext& gctx, std::shared_ptr detElement) const { // Is the current node covered by this splitter? @@ -67,10 +69,10 @@ ActsExamples::TGeoITkModuleSplitter::split( " node " + sensorName + " using split ranges of category " + std::get<1>(split_category)); if (!std::get<2>(split_category)) { - return ActsExamples::TGeoITkModuleSplitter::splitBarrelModule( + return TGeoITkModuleSplitter::splitBarrelModule( gctx, detElement, m_cfg.barrelMap.at(std::get<1>(split_category))); } else { - return ActsExamples::TGeoITkModuleSplitter::splitDiscModule( + return TGeoITkModuleSplitter::splitDiscModule( gctx, detElement, m_cfg.discMap.at(std::get<1>(split_category))); } } @@ -84,7 +86,7 @@ ActsExamples::TGeoITkModuleSplitter::split( /// If applicable, returns a split detector element inline std::vector> -ActsExamples::TGeoITkModuleSplitter::splitBarrelModule( +TGeoITkModuleSplitter::splitBarrelModule( const Acts::GeometryContext& gctx, const std::shared_ptr& detElement, unsigned int nSegments) const { @@ -141,11 +143,10 @@ ActsExamples::TGeoITkModuleSplitter::splitBarrelModule( /// If applicable, returns a split detector element inline std::vector> -ActsExamples::TGeoITkModuleSplitter::splitDiscModule( +TGeoITkModuleSplitter::splitDiscModule( const Acts::GeometryContext& gctx, const std::shared_ptr& detElement, - const std::vector& - splitRanges) const { + const std::vector& splitRanges) const { // Retrieve the surface auto identifier = detElement->identifier(); const Acts::Surface& surface = detElement->surface(); @@ -198,3 +199,5 @@ ActsExamples::TGeoITkModuleSplitter::splitDiscModule( } return detElements; } + +} // namespace ActsExamples::TGeo diff --git a/Examples/Detectors/TelescopeDetector/CMakeLists.txt b/Examples/Detectors/TelescopeDetector/CMakeLists.txt index 08acae480b6..f19044c06af 100644 --- a/Examples/Detectors/TelescopeDetector/CMakeLists.txt +++ b/Examples/Detectors/TelescopeDetector/CMakeLists.txt @@ -3,12 +3,17 @@ add_library( src/TelescopeDetector.cpp src/TelescopeDetectorElement.cpp src/BuildTelescopeDetector.cpp) + target_include_directories( ActsExamplesDetectorTelescope PUBLIC $) + target_link_libraries( ActsExamplesDetectorTelescope - PUBLIC ActsCore ActsExamplesFramework) + PUBLIC + ActsCore + ActsExamplesFramework + ActsExamplesDetectorCommons) install( TARGETS ActsExamplesDetectorTelescope diff --git a/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/BuildTelescopeDetector.hpp b/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/BuildTelescopeDetector.hpp index 34656cc0a32..1e3b17cba60 100644 --- a/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/BuildTelescopeDetector.hpp +++ b/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/BuildTelescopeDetector.hpp @@ -46,8 +46,9 @@ enum class TelescopeSurfaceType { /// @param binValue indicates which axis the detector surface normals are /// parallel to std::unique_ptr buildDetector( - const typename TelescopeDetectorElement::ContextType& gctx, - std::vector>& detectorStore, + const Acts::GeometryContext& gctx, + std::vector>& + detectorStore, const std::vector& positions, const std::vector& stereoAngles, const std::array& offsets, const std::array& bounds, diff --git a/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/TelescopeDetector.hpp b/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/TelescopeDetector.hpp index 19bb2b700d1..5778b41b43b 100644 --- a/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/TelescopeDetector.hpp +++ b/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/TelescopeDetector.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2020 CERN for the benefit of the Acts project +// Copyright (C) 2020-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -10,6 +10,7 @@ #include "Acts/Definitions/Units.hpp" #include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/DetectorCommons/Detector.hpp" #include "ActsExamples/Utilities/Options.hpp" #include @@ -17,48 +18,37 @@ #include #include -using namespace Acts::UnitLiterals; - -namespace Acts { -class TrackingGeometry; -class IMaterialDecorator; -} // namespace Acts - -namespace ActsExamples { -class IContextDecorator; -} // namespace ActsExamples - namespace ActsExamples::Telescope { class TelescopeDetectorElement; class TelescopeG4DetectorConstruction; -struct TelescopeDetector { - using DetectorElement = ActsExamples::Telescope::TelescopeDetectorElement; - using DetectorElementPtr = std::shared_ptr; - using DetectorStore = std::vector; - +class TelescopeDetector : public ActsExamples::DetectorCommons::Detector { + public: + using TrackingGeometryPtr = std::shared_ptr; using ContextDecorators = std::vector>; - using TrackingGeometryPtr = std::shared_ptr; + + using DetectorElement = ActsExamples::Telescope::TelescopeDetectorElement; struct Config { std::vector positions{{0, 30, 60, 120, 150, 180}}; std::vector stereos{{0, 0, 0, 0, 0, 0}}; std::array offsets{{0, 0}}; std::array bounds{{25, 100}}; - double thickness{80_um}; + double thickness{80 * Acts::UnitConstants::um}; int surfaceType{0}; int binValue{2}; + std::shared_ptr materialDecorator; + Acts::Logging::Level logLevel{Acts::Logging::WARNING}; }; - Config config; - /// The store of the detector elements (lifetime: job) - DetectorStore detectorStore; + explicit TelescopeDetector(const Config& cfg); + + private: + Config m_cfg; - std::pair finalize( - const Config& cfg, - const std::shared_ptr& mdecorator); + void buildTrackingGeometry() final; }; } // namespace ActsExamples::Telescope diff --git a/Examples/Detectors/TelescopeDetector/src/BuildTelescopeDetector.cpp b/Examples/Detectors/TelescopeDetector/src/BuildTelescopeDetector.cpp index 35136911325..0983f6aa538 100644 --- a/Examples/Detectors/TelescopeDetector/src/BuildTelescopeDetector.cpp +++ b/Examples/Detectors/TelescopeDetector/src/BuildTelescopeDetector.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2020-2021 CERN for the benefit of the Acts project +// Copyright (C) 2020-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -12,6 +12,7 @@ #include "Acts/Definitions/Units.hpp" #include "Acts/Geometry/CuboidVolumeBounds.hpp" #include "Acts/Geometry/CylinderVolumeBounds.hpp" +#include "Acts/Geometry/DetectorElementBase.hpp" #include "Acts/Geometry/DiscLayer.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/ILayerArrayCreator.hpp" @@ -35,10 +36,8 @@ std::unique_ptr ActsExamples::Telescope::buildDetector( - const typename ActsExamples::Telescope::TelescopeDetectorElement:: - ContextType& gctx, - std::vector< - std::shared_ptr>& + const Acts::GeometryContext& gctx, + std::vector>& detectorStore, const std::vector& positions, const std::vector& stereoAngles, diff --git a/Examples/Detectors/TelescopeDetector/src/TelescopeDetector.cpp b/Examples/Detectors/TelescopeDetector/src/TelescopeDetector.cpp index 0d5c35800d5..8f82ba1a85e 100644 --- a/Examples/Detectors/TelescopeDetector/src/TelescopeDetector.cpp +++ b/Examples/Detectors/TelescopeDetector/src/TelescopeDetector.cpp @@ -8,55 +8,56 @@ #include "ActsExamples/TelescopeDetector/TelescopeDetector.hpp" +#include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" #include "Acts/Utilities/BinningType.hpp" #include "ActsExamples/TelescopeDetector/BuildTelescopeDetector.hpp" #include "ActsExamples/TelescopeDetector/TelescopeDetectorElement.hpp" #include +#include #include -auto ActsExamples::Telescope::TelescopeDetector::finalize( - const Config& cfg, const std::shared_ptr& - /*mdecorator*/) -> std::pair { - DetectorElement::ContextType nominalContext; +namespace ActsExamples::Telescope { - if (cfg.surfaceType > 1) { +TelescopeDetector::TelescopeDetector(const Config& cfg) + : DetectorCommons::Detector( + Acts::getDefaultLogger("TelescopeDetector", cfg.logLevel)), + m_cfg(cfg) {} + +void TelescopeDetector::buildTrackingGeometry() { + Acts::GeometryContext gctx; + + if (m_cfg.surfaceType > 1) { throw std::invalid_argument( "The surface type could either be 0 for plane surface or 1 for disc " "surface."); } - if (cfg.binValue > 2) { + if (m_cfg.binValue > 2) { throw std::invalid_argument("The axis value could only be 0, 1, or 2."); } // Check if the bounds values are valid - if (cfg.surfaceType == 1 && cfg.bounds[0] >= cfg.bounds[1]) { + if (m_cfg.surfaceType == 1 && m_cfg.bounds[0] >= m_cfg.bounds[1]) { throw std::invalid_argument( "The minR should be smaller than the maxR for disc surface bounds."); } - if (cfg.positions.size() != cfg.stereos.size()) { + if (m_cfg.positions.size() != m_cfg.stereos.size()) { throw std::invalid_argument( "The number of provided positions must match the number of " "provided stereo angles."); } - config = cfg; - // Sort the provided distances - std::vector positions = cfg.positions; - std::vector stereos = cfg.stereos; + std::vector positions = m_cfg.positions; + std::vector stereos = m_cfg.stereos; std::sort(positions.begin(), positions.end()); /// Return the telescope detector - TrackingGeometryPtr gGeometry = ActsExamples::Telescope::buildDetector( - nominalContext, detectorStore, positions, stereos, cfg.offsets, - cfg.bounds, cfg.thickness, - static_cast( - cfg.surfaceType), - static_cast(cfg.binValue)); - ContextDecorators gContextDecorators = {}; - // return the pair of geometry and empty decorators - return std::make_pair( - std::move(gGeometry), std::move(gContextDecorators)); + m_trackingGeometry = ActsExamples::Telescope::buildDetector( + gctx, m_detectorStore, positions, stereos, m_cfg.offsets, m_cfg.bounds, + m_cfg.thickness, static_cast(m_cfg.surfaceType), + static_cast(m_cfg.binValue)); } + +} // namespace ActsExamples::Telescope diff --git a/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp b/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp index b66e9ec8732..909a2bb37a5 100644 --- a/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp +++ b/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp @@ -27,7 +27,7 @@ namespace ActsExamples { namespace DD4hep { -class DD4hepGeometryService; +class DD4hepDetector; } /// Read particles from EDM4hep. @@ -59,7 +59,7 @@ class EDM4hepReader final : public IReader { std::string graphvizOutput = ""; /// DD4hep detector for cellID resolution. - std::shared_ptr dd4hepGeometryService; + std::shared_ptr dd4hepDetector; /// Tracking geometry for cellID resolution. std::shared_ptr trackingGeometry; diff --git a/Examples/Io/EDM4hep/src/EDM4hepReader.cpp b/Examples/Io/EDM4hep/src/EDM4hepReader.cpp index 506afd532fe..cc19104ac49 100644 --- a/Examples/Io/EDM4hep/src/EDM4hepReader.cpp +++ b/Examples/Io/EDM4hep/src/EDM4hepReader.cpp @@ -12,7 +12,7 @@ #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/GeometryIdentifier.hpp" #include "Acts/Plugins/DD4hep/DD4hepDetectorElement.hpp" -#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" +#include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" #include "ActsExamples/EventData/SimHit.hpp" #include "ActsExamples/EventData/SimParticle.hpp" #include "ActsExamples/Framework/WhiteBoard.hpp" @@ -325,8 +325,7 @@ ProcessCode EDM4hepReader::read(const AlgorithmContext& ctx) { [&](std::uint64_t cellId) { ACTS_VERBOSE("CellID: " << cellId); - const auto& vm = - m_cfg.dd4hepGeometryService->detector().volumeManager(); + const auto& vm = m_cfg.dd4hepDetector->detector().volumeManager(); const auto detElement = vm.lookupDetElement(cellId); diff --git a/Examples/Python/python/acts/_adapter.py b/Examples/Python/python/acts/_adapter.py index ac5bd4a76cb..2d56f046354 100644 --- a/Examples/Python/python/acts/_adapter.py +++ b/Examples/Python/python/acts/_adapter.py @@ -2,6 +2,7 @@ import functools from typing import Optional, Callable, Dict, Any from pathlib import Path +from contextlib import nullcontext import acts @@ -115,7 +116,7 @@ def create(*args, mdecorator=None, **kwargs): detector = cls(cfg) trackingGeometry = detector.trackingGeometry() decorators = detector.contextDecorators() - contextManager = None + contextManager = nullcontext() return detector, trackingGeometry, decorators, contextManager return create diff --git a/Examples/Python/python/acts/examples/dd4hep.py b/Examples/Python/python/acts/examples/dd4hep.py index e19df7722b4..3affbc00be8 100644 --- a/Examples/Python/python/acts/examples/dd4hep.py +++ b/Examples/Python/python/acts/examples/dd4hep.py @@ -16,9 +16,9 @@ from acts import ActsPythonBindingsDD4hep _patch_config(ActsPythonBindingsDD4hep) -ActsPythonBindingsDD4hep.DD4hepGeometryService.create = _detector_create( - ActsPythonBindingsDD4hep.DD4hepGeometryService, - ActsPythonBindingsDD4hep.DD4hepGeometryService.Config, +ActsPythonBindingsDD4hep.DD4hepDetector.create = _detector_create( + ActsPythonBindingsDD4hep.DD4hepDetector, + ActsPythonBindingsDD4hep.DD4hepDetector.Config, ) from acts.ActsPythonBindingsDD4hep import * diff --git a/Examples/Python/python/acts/examples/odd.py b/Examples/Python/python/acts/examples/odd.py index db5429a473b..03025563938 100644 --- a/Examples/Python/python/acts/examples/odd.py +++ b/Examples/Python/python/acts/examples/odd.py @@ -91,26 +91,27 @@ def geoid_hook(geoid, surface): level=customLogLevel(minLevel=acts.logging.WARNING), ) - dd4hepConfig = acts.examples.dd4hep.DD4hepGeometryService.Config( + dd4hepConfig = acts.examples.dd4hep.DD4hepDetector.Config( xmlFileNames=[str(odd_xml)], logLevel=customLogLevel(), dd4hepLogLevel=customLogLevel(), geometryIdentifierHook=acts.GeometryIdentifierHook(geoid_hook), - matDecorator=mdecorator, + materialDecorator=mdecorator, ) - detector = acts.examples.dd4hep.DD4hepGeometryService(dd4hepConfig) + detector = acts.examples.dd4hep.DD4hepDetector(dd4hepConfig) - trackingGeometry = detector.trackingGeometry() - decorators = detector.contextDecorators() + trackingGeometry, decorators, _ = detector.trackingGeometry() class ContextManager: def __init__(self, detector): self.detector = detector def __enter__(self): + print("!!!!!!!!!!!!!!!! Entering context !!!!!!!!!!!!!!!!") return self - def __exit__(self): + def __exit__(self, exc_type, exc_val, exc_tb): + print("!!!!!!!!!!!!!!!! Exiting context !!!!!!!!!!!!!!!!!") self.detector.drop() contextManager = ContextManager(detector) diff --git a/Examples/Python/src/DD4hepComponent.cpp b/Examples/Python/src/DD4hepComponent.cpp index 2a1510068ef..79068d9a4cc 100644 --- a/Examples/Python/src/DD4hepComponent.cpp +++ b/Examples/Python/src/DD4hepComponent.cpp @@ -14,7 +14,8 @@ #include "Acts/Plugins/DD4hep/DD4hepIdentifierMapper.hpp" #include "Acts/Plugins/Python/Utilities.hpp" #include "Acts/Utilities/Logger.hpp" -#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" +#include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" +#include "ActsExamples/DetectorCommons/Detector.hpp" #include "ActsExamples/Framework/IContextDecorator.hpp" #include "ActsExamples/Framework/ProcessCode.hpp" @@ -36,20 +37,18 @@ using namespace Acts::Python; PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { { - using Config = DD4hep::DD4hepGeometryService::Config; - auto s = py::class_>( - m, "DD4hepGeometryService") - .def(py::init()) - .def("trackingGeometry", - py::overload_cast<>( - &DD4hep::DD4hepGeometryService::trackingGeometry)) - .def("trackingGeometry", - py::overload_cast( - &DD4hep::DD4hepGeometryService::trackingGeometry)) - .def("contextDecorators", - &DD4hep::DD4hepGeometryService::contextDecorators) - .def("drop", &DD4hep::DD4hepGeometryService::drop); + py::class_>( + m, "DD4hepDetectorElement"); + } + + { + using Detector = DD4hep::DD4hepDetector; + using Config = Detector::Config; + + auto s = py::class_>(m, "DD4hepDetector") + .def(py::init()); auto c = py::class_(s, "Config").def(py::init<>()); ACTS_PYTHON_STRUCT_BEGIN(c, Config); @@ -63,7 +62,7 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { ACTS_PYTHON_MEMBER(envelopeR); ACTS_PYTHON_MEMBER(envelopeZ); ACTS_PYTHON_MEMBER(defaultLayerThickness); - ACTS_PYTHON_MEMBER(matDecorator); + ACTS_PYTHON_MEMBER(materialDecorator); ACTS_PYTHON_MEMBER(geometryIdentifierHook); ACTS_PYTHON_STRUCT_END(); @@ -76,12 +75,6 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { "DD4hepFieldAdapter"); } - { - py::class_>( - m, "DD4hepDetectorElement"); - } - { m.def("createDD4hepIdGeoIdMap", [](const Acts::TrackingGeometry& tGeometry) diff --git a/Examples/Python/src/Detector.cpp b/Examples/Python/src/Detector.cpp index 524aa867383..490f2fa9dd9 100644 --- a/Examples/Python/src/Detector.cpp +++ b/Examples/Python/src/Detector.cpp @@ -1,11 +1,14 @@ // This file is part of the Acts project. // -// Copyright (C) 2021 CERN for the benefit of the Acts project +// Copyright (C) 2021-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. +#include "ActsExamples/DetectorCommons/Detector.hpp" + +#include "Acts/Geometry/DetectorElementBase.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" #include "Acts/Material/IMaterialDecorator.hpp" #include "Acts/Plugins/Python/Utilities.hpp" @@ -36,6 +39,7 @@ using namespace ActsExamples; namespace Acts::Python { void addDetector(Context& ctx) { auto [m, mex] = ctx.get("main", "examples"); + { py::class_>( mex, "IContextDecorator") @@ -44,16 +48,25 @@ void addDetector(Context& ctx) { } { - using Config = GenericDetector::Config; + py::class_>( + mex, "DetectorElementBase"); + } - auto gd = py::class_>( - mex, "GenericDetector") - .def(py::init<>()) - .def("finalize", - py::overload_cast< - const Config&, - std::shared_ptr>( - &GenericDetector::finalize)); + { + using Detector = DetectorCommons::Detector; + + py::class_>(mex, "Detector") + .def("trackingGeometry", &Detector::trackingGeometry) + .def("drop", &Detector::drop); + } + + { + using Detector = Generic::GenericDetector; + using Config = Detector::Config; + + auto gd = + py::class_>(mex, "GenericDetector") + .def(py::init()); py::class_(gd, "Config") .def(py::init<>()) @@ -61,22 +74,17 @@ void addDetector(Context& ctx) { .def_readwrite("surfaceLogLevel", &Config::surfaceLogLevel) .def_readwrite("layerLogLevel", &Config::layerLogLevel) .def_readwrite("volumeLogLevel", &Config::volumeLogLevel) - .def_readwrite("buildProto", &Config::buildProto); + .def_readwrite("buildProto", &Config::buildProto) + .def_readwrite("materialDecorator", &Config::materialDecorator); } { - using TelescopeDetector = Telescope::TelescopeDetector; - using Config = TelescopeDetector::Config; - - auto td = - py::class_>( - mex, "TelescopeDetector") - .def(py::init<>()) - .def("finalize", - py::overload_cast< - const Config&, - const std::shared_ptr&>( - &TelescopeDetector::finalize)); + using Detector = Telescope::TelescopeDetector; + using Config = Detector::Config; + + auto td = py::class_>( + mex, "TelescopeDetector") + .def(py::init()); py::class_(td, "Config") .def(py::init<>()) @@ -90,19 +98,14 @@ void addDetector(Context& ctx) { } { - using AlignedDetector = Contextual::AlignedDetector; - using Config = AlignedDetector::Config; - - auto d = py::class_>( - mex, "AlignedDetector") - .def(py::init<>()) - .def("finalize", - py::overload_cast< - const Config&, - std::shared_ptr>( - &AlignedDetector::finalize)); - - auto c = py::class_(d, "Config") + using Detector = Contextual::AlignedDetector; + using Config = Detector::Config; + + auto d = + py::class_>(mex, "AlignedDetector") + .def(py::init()); + + auto c = py::class_(d, "Config") .def(py::init<>()); ACTS_PYTHON_STRUCT_BEGIN(c, Config); ACTS_PYTHON_MEMBER(seed); @@ -124,16 +127,12 @@ void addDetector(Context& ctx) { } { - using Config = TGeoDetector::Config; - - auto d = py::class_>( - mex, "TGeoDetector") - .def(py::init<>()) - .def("finalize", - py::overload_cast< - const Config&, - std::shared_ptr>( - &TGeoDetector::finalize)); + using Detector = TGeo::TGeoDetector; + using Config = Detector::Config; + + auto d = + py::class_>(mex, "TGeoDetector") + .def(py::init()); py::class_(mex, "Interval") .def(py::init<>()) diff --git a/Examples/Python/src/Geant4Component.cpp b/Examples/Python/src/Geant4Component.cpp index b366440c89f..6bd75e18689 100644 --- a/Examples/Python/src/Geant4Component.cpp +++ b/Examples/Python/src/Geant4Component.cpp @@ -258,31 +258,15 @@ PYBIND11_MODULE(ActsPythonBindingsGeant4, mod) { std::shared_ptr>( mod, "Geant4DetectorElement"); - using Geant4Detector = Geant4::Geant4Detector; + using Detector = Geant4::Geant4Detector; + using Config = Detector::Config; auto g = - py::class_>( - mod, "Geant4Detector") - .def(py::init<>()) - .def( - "constructDetector", - [](Geant4Detector& self, const Geant4Detector::Config& cfg, - Logging::Level logLevel) { - auto logger = getDefaultLogger("Geant4Detector", logLevel); - return self.constructDetector(cfg, *logger); - }, - py::arg("cfg"), py::arg("logLevel") = Logging::INFO) - .def( - "constructTrackingGeometry", - [](Geant4Detector& self, const Geant4Detector::Config& cfg, - Logging::Level logLevel) { - auto logger = getDefaultLogger("Geant4Detector", logLevel); - return self.constructTrackingGeometry(cfg, *logger); - }, - py::arg("cfg"), py::arg("logLevel") = Logging::INFO); - - auto c = py::class_(g, "Config").def(py::init<>()); - ACTS_PYTHON_STRUCT_BEGIN(c, Geant4Detector::Config); + py::class_>(mod, "Geant4Detector") + .def(py::init()); + + auto c = py::class_(g, "Config").def(py::init<>()); + ACTS_PYTHON_STRUCT_BEGIN(c, Config); ACTS_PYTHON_MEMBER(name); ACTS_PYTHON_MEMBER(g4World); ACTS_PYTHON_MEMBER(g4SurfaceOptions); diff --git a/Examples/Python/src/Geant4DD4hepComponent.cpp b/Examples/Python/src/Geant4DD4hepComponent.cpp index 0e29dc72266..2e0f9b4143d 100644 --- a/Examples/Python/src/Geant4DD4hepComponent.cpp +++ b/Examples/Python/src/Geant4DD4hepComponent.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" +#include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" #include "ActsExamples/DDG4/DDG4DetectorConstruction.hpp" #include "ActsExamples/Framework/ProcessCode.hpp" #include "ActsExamples/Geant4/RegionCreator.hpp" @@ -28,7 +28,7 @@ PYBIND11_MODULE(ActsPythonBindingsDDG4, m) { py::class_>( m, "DDG4DetectorConstructionFactory") - .def(py::init, + .def(py::init, std::vector>>(), py::arg("geometryService"), py::arg("regionCreators") = diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index c02e1566980..4f152a79078 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -524,12 +524,6 @@ def test_event_recording(tmp_path): def test_truth_tracking_kalman( tmp_path, assert_root_hash, revFiltMomThresh, directNavigation, detector_config ): - from truth_tracking_kalman import runTruthTrackingKalman - - field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T)) - - seq = Sequencer(events=10, numThreads=1) - root_files = [ ("trackstates_fitter.root", "trackstates", 19), ("tracksummary_fitter.root", "tracksummary", 10), @@ -540,7 +534,14 @@ def test_truth_tracking_kalman( fp = tmp_path / fn assert not fp.exists() + print("with") with detector_config.contextManager: + from truth_tracking_kalman import runTruthTrackingKalman + + field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T)) + + seq = Sequencer(events=10, numThreads=1) + runTruthTrackingKalman( trackingGeometry=detector_config.trackingGeometry, field=field, @@ -552,6 +553,7 @@ def test_truth_tracking_kalman( ) seq.run() + print("done") for fn, tn, ee in root_files: fp = tmp_path / fn From 913d598e921e4ffc259afd44d385c2a067c36e69 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Thu, 8 Aug 2024 13:53:43 +0200 Subject: [PATCH 15/32] fix odd --- .../DD4hepDetector/DD4hepDetector.hpp | 2 -- .../DD4hepDetector/src/DD4hepDetector.cpp | 4 ++++ Examples/Python/python/acts/examples/odd.py | 4 ---- Examples/Python/src/Detector.cpp | 22 +++++++++---------- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp index 9c631df9f97..4cfe4636e6a 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp @@ -111,8 +111,6 @@ class DD4hepDetector : public DetectorCommons::Detector { std::unique_ptr m_detector; /// The world DD4hep DetElement dd4hep::DetElement m_geometry; - /// The ACTS TrackingGeometry - std::shared_ptr m_trackingGeometry; }; } // namespace ActsExamples::DD4hep diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp index beced812f0d..03e72a95256 100644 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp @@ -106,6 +106,10 @@ void DD4hepDetector::buildDD4hepGeometry() { } void DD4hepDetector::buildTrackingGeometry() { + if (m_detector == nullptr) { + buildDD4hepGeometry(); + } + Acts::GeometryContext gctx; auto logger = Acts::getDefaultLogger("DD4hepConversion", m_cfg.logLevel); m_trackingGeometry = Acts::convertDD4hepDetector( diff --git a/Examples/Python/python/acts/examples/odd.py b/Examples/Python/python/acts/examples/odd.py index 03025563938..0a62967d462 100644 --- a/Examples/Python/python/acts/examples/odd.py +++ b/Examples/Python/python/acts/examples/odd.py @@ -105,13 +105,9 @@ def geoid_hook(geoid, surface): class ContextManager: def __init__(self, detector): self.detector = detector - def __enter__(self): - print("!!!!!!!!!!!!!!!! Entering context !!!!!!!!!!!!!!!!") return self - def __exit__(self, exc_type, exc_val, exc_tb): - print("!!!!!!!!!!!!!!!! Exiting context !!!!!!!!!!!!!!!!!") self.detector.drop() contextManager = ContextManager(detector) diff --git a/Examples/Python/src/Detector.cpp b/Examples/Python/src/Detector.cpp index 490f2fa9dd9..2a1fe21d874 100644 --- a/Examples/Python/src/Detector.cpp +++ b/Examples/Python/src/Detector.cpp @@ -64,9 +64,9 @@ void addDetector(Context& ctx) { using Detector = Generic::GenericDetector; using Config = Detector::Config; - auto gd = - py::class_>(mex, "GenericDetector") - .def(py::init()); + auto gd = py::class_>(mex, "GenericDetector") + .def(py::init()); py::class_(gd, "Config") .def(py::init<>()) @@ -82,8 +82,8 @@ void addDetector(Context& ctx) { using Detector = Telescope::TelescopeDetector; using Config = Detector::Config; - auto td = py::class_>( - mex, "TelescopeDetector") + auto td = py::class_>(mex, "TelescopeDetector") .def(py::init()); py::class_(td, "Config") @@ -101,9 +101,9 @@ void addDetector(Context& ctx) { using Detector = Contextual::AlignedDetector; using Config = Detector::Config; - auto d = - py::class_>(mex, "AlignedDetector") - .def(py::init()); + auto d = py::class_>(mex, "AlignedDetector") + .def(py::init()); auto c = py::class_(d, "Config") .def(py::init<>()); @@ -130,9 +130,9 @@ void addDetector(Context& ctx) { using Detector = TGeo::TGeoDetector; using Config = Detector::Config; - auto d = - py::class_>(mex, "TGeoDetector") - .def(py::init()); + auto d = py::class_>(mex, "TGeoDetector") + .def(py::init()); py::class_(mex, "Interval") .def(py::init<>()) From 6137989b45242f26aef0d23402657cdce84907e8 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Thu, 8 Aug 2024 14:36:26 +0200 Subject: [PATCH 16/32] revert detector changes --- Examples/Detectors/Common/CMakeLists.txt | 15 --- .../ActsExamples/DetectorCommons/Detector.hpp | 67 ------------- Examples/Detectors/Common/src/Detector.cpp | 45 --------- .../ContextualDetector/CMakeLists.txt | 6 +- .../ContextualDetector/AlignedDetector.hpp | 42 ++++---- .../src/AlignedDetector.cpp | 75 +++++++-------- .../Detectors/Geant4Detector/CMakeLists.txt | 16 +--- .../Geant4Detector/Geant4Detector.hpp | 47 +++------ .../Geant4Detector/src/Geant4Detector.cpp | 95 +++++++------------ .../Detectors/GenericDetector/CMakeLists.txt | 10 +- .../GenericDetector/BuildGenericDetector.hpp | 2 +- .../GenericDetector/GenericDetector.hpp | 38 ++++---- .../GenericDetector/src/GenericDetector.cpp | 41 ++++---- .../src/MockupSectorBuilder.cpp | 9 +- .../Detectors/TGeoDetector/CMakeLists.txt | 9 +- .../TGeoDetector/JsonTGeoDetectorConfig.hpp | 34 ++++--- .../TGeoDetector/TGeoDetector.hpp | 41 ++++---- .../TGeoDetector/TGeoITkModuleSplitter.hpp | 6 +- .../TGeoDetector/src/TGeoDetector.cpp | 40 ++++---- .../src/TGeoITkModuleSplitter.cpp | 25 +++-- .../TelescopeDetector/CMakeLists.txt | 7 +- .../BuildTelescopeDetector.hpp | 5 +- .../TelescopeDetector/TelescopeDetector.hpp | 40 +++++--- .../src/BuildTelescopeDetector.cpp | 9 +- .../src/TelescopeDetector.cpp | 45 +++++---- Examples/Python/python/acts/_adapter.py | 16 ++-- Examples/Python/src/DD4hepComponent.cpp | 46 +++++---- Examples/Python/src/Detector.cpp | 91 +++++++++--------- Examples/Python/src/EDM4hepComponent.cpp | 15 ++- Examples/Python/src/Geant4Component.cpp | 30 ++++-- 30 files changed, 415 insertions(+), 552 deletions(-) delete mode 100644 Examples/Detectors/Common/CMakeLists.txt delete mode 100644 Examples/Detectors/Common/include/ActsExamples/DetectorCommons/Detector.hpp delete mode 100644 Examples/Detectors/Common/src/Detector.cpp diff --git a/Examples/Detectors/Common/CMakeLists.txt b/Examples/Detectors/Common/CMakeLists.txt deleted file mode 100644 index 00b1ef197a0..00000000000 --- a/Examples/Detectors/Common/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -add_library( - ActsExamplesDetectorCommons SHARED - src/Detector.cpp) -target_include_directories( - ActsExamplesDetectorCommons - PUBLIC $) -target_link_libraries( - ActsExamplesDetectorCommons - PUBLIC - ActsCore - ActsExamplesFramework) - -install( - TARGETS ActsExamplesDetectorCommons - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/Examples/Detectors/Common/include/ActsExamples/DetectorCommons/Detector.hpp b/Examples/Detectors/Common/include/ActsExamples/DetectorCommons/Detector.hpp deleted file mode 100644 index 0be35112deb..00000000000 --- a/Examples/Detectors/Common/include/ActsExamples/DetectorCommons/Detector.hpp +++ /dev/null @@ -1,67 +0,0 @@ -// This file is part of the Acts project. -// -// Copyright (C) 2024 CERN for the benefit of the Acts project -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#pragma once - -#include "Acts/Geometry/GeometryContext.hpp" - -#include -#include - -namespace Acts { -class TrackingGeometry; -class DetectorElementBase; -class IMaterialDecorator; -class Logger; -namespace Experimental { -class Detector; -} // namespace Experimental -} // namespace Acts - -namespace ActsExamples { -class IContextDecorator; -} // namespace ActsExamples - -namespace ActsExamples::DetectorCommons { - -class Detector { - public: - using TrackingGeometryPtr = std::shared_ptr; - using DetectorPtr = std::shared_ptr; - using ContextDecorators = - std::vector>; - - using DetectorElement = Acts::DetectorElementBase; - using DetectorStore = std::vector>; - - explicit Detector(std::unique_ptr logger); - virtual ~Detector() = default; - - virtual std::tuple - trackingGeometry(); - - virtual std::tuple detector(); - - virtual void drop(); - - protected: - TrackingGeometryPtr m_trackingGeometry; - DetectorPtr m_detector; - ContextDecorators m_contextDecorators; - DetectorStore m_detectorStore; - - std::unique_ptr m_logger; - - const Acts::Logger& logger() const { return *m_logger; } - - virtual void buildTrackingGeometry() = 0; - - virtual void buildDetector(); -}; - -} // namespace ActsExamples::DetectorCommons diff --git a/Examples/Detectors/Common/src/Detector.cpp b/Examples/Detectors/Common/src/Detector.cpp deleted file mode 100644 index 72fad92de80..00000000000 --- a/Examples/Detectors/Common/src/Detector.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// This file is part of the Acts project. -// -// Copyright (C) 2024 CERN for the benefit of the Acts project -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "ActsExamples/DetectorCommons/Detector.hpp" - -#include "Acts/Utilities/Logger.hpp" - -namespace ActsExamples::DetectorCommons { - -Detector::Detector(std::unique_ptr logger) - : m_logger(std::move(logger)) {} - -std::tuple -Detector::trackingGeometry() { - if (m_trackingGeometry == nullptr) { - buildTrackingGeometry(); - } - return {m_trackingGeometry, m_contextDecorators, m_detectorStore}; -} - -std::tuple -Detector::detector() { - if (m_detector == nullptr) { - buildDetector(); - } - return {m_detector, m_contextDecorators, m_detectorStore}; -} - -void Detector::drop() { - m_trackingGeometry.reset(); - m_detector.reset(); - m_contextDecorators.clear(); - m_detectorStore.clear(); -} - -void Detector::buildDetector() {} - -} // namespace ActsExamples::DetectorCommons diff --git a/Examples/Detectors/ContextualDetector/CMakeLists.txt b/Examples/Detectors/ContextualDetector/CMakeLists.txt index 2879d0b5ee5..7ffc1394e8e 100644 --- a/Examples/Detectors/ContextualDetector/CMakeLists.txt +++ b/Examples/Detectors/ContextualDetector/CMakeLists.txt @@ -3,18 +3,14 @@ add_library( src/AlignedDetector.cpp src/InternalAlignmentDecorator.cpp src/ExternalAlignmentDecorator.cpp) - target_include_directories( ActsExamplesDetectorContextual PUBLIC $) - target_link_libraries( ActsExamplesDetectorContextual PUBLIC ActsCore - ActsExamplesFramework - ActsExamplesDetectorCommons - ActsExamplesDetectorGeneric) + ActsExamplesFramework ActsExamplesDetectorGeneric) install( TARGETS ActsExamplesDetectorContextual diff --git a/Examples/Detectors/ContextualDetector/include/ActsExamples/ContextualDetector/AlignedDetector.hpp b/Examples/Detectors/ContextualDetector/include/ActsExamples/ContextualDetector/AlignedDetector.hpp index b554b296cd3..82e4e0f7806 100644 --- a/Examples/Detectors/ContextualDetector/include/ActsExamples/ContextualDetector/AlignedDetector.hpp +++ b/Examples/Detectors/ContextualDetector/include/ActsExamples/ContextualDetector/AlignedDetector.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2019-2024 CERN for the benefit of the Acts project +// Copyright (C) 2019 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -10,7 +10,6 @@ #include "Acts/Definitions/Units.hpp" #include "Acts/Utilities/Logger.hpp" -#include "ActsExamples/DetectorCommons/Detector.hpp" #include "ActsExamples/GenericDetector/GenericDetector.hpp" #include @@ -18,20 +17,29 @@ #include #include +namespace Acts { +class TrackingGeometry; +class IMaterialDecorator; +} // namespace Acts + +namespace ActsExamples { +class IContextDecorator; +namespace Generic { +class GenericDetectorElement; +} // namespace Generic +} // namespace ActsExamples + namespace ActsExamples::Contextual { class InternallyAlignedDetectorElement; class InternalAlignmentDecorator; -class AlignedDetector : public DetectorCommons::Detector { +class AlignedDetector { public: - using TrackingGeometryPtr = std::shared_ptr; using ContextDecorators = std::vector>; + using TrackingGeometryPtr = std::shared_ptr; - using DetectorStore = std::vector< - std::vector>>; - - struct Config : public Generic::GenericDetector::Config { + struct Config : public GenericDetector::Config { /// Seed for the decorator random numbers. std::size_t seed = 1324354657; /// Size of a valid IOV. @@ -55,21 +63,21 @@ class AlignedDetector : public DetectorCommons::Detector { enum class Mode { Internal, External }; Mode mode = Mode::Internal; - - std::shared_ptr materialDecorator; }; - explicit AlignedDetector(const Config& cfg); + std::pair finalize( + const Config& cfg, + std::shared_ptr mdecorator); - const DetectorStore& detectorStore() const { return m_detectorStore; } + std::vector>>& + detectorStore() { + return m_detectorStore; + } private: - Config m_cfg; - /// The Store of the detector elements (lifetime: job) - DetectorStore m_detectorStore; - - void buildTrackingGeometry() final; + std::vector>> + m_detectorStore; }; } // namespace ActsExamples::Contextual diff --git a/Examples/Detectors/ContextualDetector/src/AlignedDetector.cpp b/Examples/Detectors/ContextualDetector/src/AlignedDetector.cpp index 1cc7c4fbc89..e6459c2dbf4 100644 --- a/Examples/Detectors/ContextualDetector/src/AlignedDetector.cpp +++ b/Examples/Detectors/ContextualDetector/src/AlignedDetector.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2019-2024 CERN for the benefit of the Acts project +// Copyright (C) 2019 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -9,7 +9,6 @@ #include "ActsExamples/ContextualDetector/AlignedDetector.hpp" #include "Acts/Definitions/Units.hpp" -#include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/ILayerBuilder.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" #include "Acts/Utilities/Logger.hpp" @@ -18,46 +17,44 @@ #include "ActsExamples/ContextualDetector/ExternallyAlignedDetectorElement.hpp" #include "ActsExamples/ContextualDetector/InternalAlignmentDecorator.hpp" #include "ActsExamples/ContextualDetector/InternallyAlignedDetectorElement.hpp" -#include "ActsExamples/DetectorCommons/Detector.hpp" #include "ActsExamples/Framework/RandomNumbers.hpp" #include "ActsExamples/GenericDetector/BuildGenericDetector.hpp" #include "ActsExamples/GenericDetector/ProtoLayerCreatorT.hpp" using namespace Acts::UnitLiterals; - namespace ActsExamples::Contextual { -AlignedDetector::AlignedDetector(const Config& cfg) - : DetectorCommons::Detector( - Acts::getDefaultLogger("AlignedDetector", m_cfg.logLevel)), - m_cfg(cfg) {} +auto AlignedDetector::finalize( + const Config& cfg, + std::shared_ptr mdecorator) + -> std::pair { + ContextDecorators aContextDecorators; -void AlignedDetector::buildTrackingGeometry() { // Let's create a random number service ActsExamples::RandomNumbers::Config randomNumberConfig; - randomNumberConfig.seed = m_cfg.seed; + randomNumberConfig.seed = cfg.seed; auto randomNumberSvc = std::make_shared(randomNumberConfig); auto fillDecoratorConfig = [&](AlignmentDecorator::Config& config) { - config.iovSize = m_cfg.iovSize; - config.flushSize = m_cfg.flushSize; - config.doGarbageCollection = m_cfg.doGarbageCollection; + config.iovSize = cfg.iovSize; + config.flushSize = cfg.flushSize; + config.doGarbageCollection = cfg.doGarbageCollection; // The misalignments - config.gSigmaX = m_cfg.sigmaInPlane; - config.gSigmaY = m_cfg.sigmaInPlane; - config.gSigmaZ = m_cfg.sigmaOutPlane; - config.aSigmaX = m_cfg.sigmaOutRot; - config.aSigmaY = m_cfg.sigmaOutRot; - config.aSigmaZ = m_cfg.sigmaInRot; + config.gSigmaX = cfg.sigmaInPlane; + config.gSigmaY = cfg.sigmaInPlane; + config.gSigmaZ = cfg.sigmaOutPlane; + config.aSigmaX = cfg.sigmaOutRot; + config.aSigmaY = cfg.sigmaOutRot; + config.aSigmaZ = cfg.sigmaInRot; config.randomNumberSvc = randomNumberSvc; - config.firstIovNominal = m_cfg.firstIovNominal; + config.firstIovNominal = cfg.firstIovNominal; }; - if (m_cfg.mode == Config::Mode::External) { - InternallyAlignedDetectorElement::ContextType nominalContext; - auto gctx = Acts::GeometryContext(nominalContext); + TrackingGeometryPtr aTrackingGeometry; + if (cfg.mode == Config::Mode::External) { + ExternallyAlignedDetectorElement::ContextType nominalContext; ExternalAlignmentDecorator::Config agcsConfig; fillDecoratorConfig(agcsConfig); @@ -65,12 +62,13 @@ void AlignedDetector::buildTrackingGeometry() { std::vector>> detectorStore; - m_trackingGeometry = + aTrackingGeometry = ActsExamples::Generic::buildDetector( - gctx, detectorStore, m_cfg.buildLevel, m_cfg.materialDecorator, - m_cfg.buildProto, m_cfg.surfaceLogLevel, m_cfg.layerLogLevel, - m_cfg.volumeLogLevel); - agcsConfig.trackingGeometry = m_trackingGeometry; + nominalContext, detectorStore, cfg.buildLevel, + std::move(mdecorator), cfg.buildProto, cfg.surfaceLogLevel, + cfg.layerLogLevel, cfg.volumeLogLevel); + + agcsConfig.trackingGeometry = aTrackingGeometry; // need to upcast to store in this object as well for (auto& lstore : detectorStore) { @@ -80,22 +78,21 @@ void AlignedDetector::buildTrackingGeometry() { } } - m_contextDecorators.push_back(std::make_shared( + aContextDecorators.push_back(std::make_shared( std::move(agcsConfig), - Acts::getDefaultLogger("AlignmentDecorator", m_cfg.decoratorLogLevel))); + Acts::getDefaultLogger("AlignmentDecorator", cfg.decoratorLogLevel))); } else { InternallyAlignedDetectorElement::ContextType nominalContext; nominalContext.nominal = true; - auto gctx = Acts::GeometryContext(nominalContext); InternalAlignmentDecorator::Config agcsConfig; fillDecoratorConfig(agcsConfig); - m_trackingGeometry = + aTrackingGeometry = ActsExamples::Generic::buildDetector( - gctx, agcsConfig.detectorStore, m_cfg.buildLevel, - m_cfg.materialDecorator, m_cfg.buildProto, m_cfg.surfaceLogLevel, - m_cfg.layerLogLevel, m_cfg.volumeLogLevel); + nominalContext, agcsConfig.detectorStore, cfg.buildLevel, + std::move(mdecorator), cfg.buildProto, cfg.surfaceLogLevel, + cfg.layerLogLevel, cfg.volumeLogLevel); // need to upcast to store in this object as well for (auto& lstore : agcsConfig.detectorStore) { @@ -105,10 +102,14 @@ void AlignedDetector::buildTrackingGeometry() { } } - m_contextDecorators.push_back(std::make_shared( + aContextDecorators.push_back(std::make_shared( std::move(agcsConfig), - Acts::getDefaultLogger("AlignmentDecorator", m_cfg.decoratorLogLevel))); + Acts::getDefaultLogger("AlignmentDecorator", cfg.decoratorLogLevel))); } + + // return the pair of geometry and the alignment decorator(s) + return std::make_pair( + std::move(aTrackingGeometry), std::move(aContextDecorators)); } } // namespace ActsExamples::Contextual diff --git a/Examples/Detectors/Geant4Detector/CMakeLists.txt b/Examples/Detectors/Geant4Detector/CMakeLists.txt index 337d05eec15..56b3b872930 100644 --- a/Examples/Detectors/Geant4Detector/CMakeLists.txt +++ b/Examples/Detectors/Geant4Detector/CMakeLists.txt @@ -1,19 +1,13 @@ add_library( ActsExamplesDetectorGeant4 SHARED - src/Geant4Detector.cpp) - + src/Geant4Detector.cpp + ) target_include_directories( - ActsExamplesDetectorGeant4 + ActsExamplesDetectorGeant4 PUBLIC $) - target_link_libraries( - ActsExamplesDetectorGeant4 - PUBLIC - ActsCore - ActsExamplesFramework - ActsExamplesGeant4 - ActsPluginGeant4 - ActsExamplesDetectorCommons) + ActsExamplesDetectorGeant4 + PUBLIC ActsCore ActsExamplesFramework ActsExamplesGeant4 ActsPluginGeant4) install( TARGETS ActsExamplesDetectorGeant4 diff --git a/Examples/Detectors/Geant4Detector/include/ActsExamples/Geant4Detector/Geant4Detector.hpp b/Examples/Detectors/Geant4Detector/include/ActsExamples/Geant4Detector/Geant4Detector.hpp index c88b70dab40..1899a1e035a 100644 --- a/Examples/Detectors/Geant4Detector/include/ActsExamples/Geant4Detector/Geant4Detector.hpp +++ b/Examples/Detectors/Geant4Detector/include/ActsExamples/Geant4Detector/Geant4Detector.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2022-2024 CERN for the benefit of the Acts project +// Copyright (C) 2022-2023 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -12,7 +12,6 @@ #include "Acts/Geometry/GeometryIdentifier.hpp" #include "Acts/Plugins/Geant4/Geant4DetectorSurfaceFactory.hpp" #include "Acts/Utilities/Logger.hpp" -#include "ActsExamples/DetectorCommons/Detector.hpp" #include #include @@ -33,20 +32,19 @@ class Detector; namespace ActsExamples { class IContextDecorator; -} // namespace ActsExamples - -namespace ActsExamples::Geant4 { -struct Geant4Detector : public DetectorCommons::Detector { - using TrackingGeometryPtr = std::shared_ptr; - using DetectorPtr = std::shared_ptr; - using ContextDecorators = - std::vector>; +namespace Geant4 { +struct Geant4Detector { using DetectorElements = std::vector>; + using DetectorPtr = std::shared_ptr; using Surfaces = std::vector>; + using ContextDecorators = + std::vector>; + using TrackingGeometryPtr = std::shared_ptr; + /// Nested configuration struct struct Config { /// The detector/geometry name @@ -64,30 +62,12 @@ struct Geant4Detector : public DetectorCommons::Detector { Acts::Logging::Level logLevel = Acts::Logging::INFO; }; - explicit Geant4Detector(const Config& cfg); - - const DetectorElements& detectorElements() const; - - void drop() final; - - private: - Config m_cfg; - - DetectorElements m_detectorElements; - - std::unique_ptr m_logger; - - const Acts::Logger& logger() const { return *m_logger; } - - void buildTrackingGeometry() final; - void buildDetector() final; - /// @brief Construct an Acts::Detector from a Geant4 world volume /// @param cfg the configuration of the Geant4 detector /// @param logger a logger instance /// @return a tuple of an Acts::Detector object, a ContextDecorator & the created detector elements std::tuple - constructDetector() const; + constructDetector(const Config& cfg, const Acts::Logger& logger); /// @brief Construct a TrackingGeometry from a Geant4 world volume using the KDTreeTrackingGeometryBuilder builder /// @@ -97,15 +77,18 @@ struct Geant4Detector : public DetectorCommons::Detector { /// /// @return a tuple of an Acts::TrackingGeometry object, a ContextDecorator & the created detector elements std::tuple - constructTrackingGeometry() const; + constructTrackingGeometry(const Config& cfg, const Acts::Logger& logger); + private: /// @brief Convert Geant4VPhysicalVolume objects into Acts components /// /// @param cfg the configuration of the Geant4 detector /// @param logger a logger instance /// /// @return a tuple of surfaces and detector elements - std::tuple convertGeant4Volumes() const; + std::tuple convertGeant4Volumes( + const Config& cfg, const Acts::Logger& logger) const; }; -} // namespace ActsExamples::Geant4 +} // namespace Geant4 +} // namespace ActsExamples diff --git a/Examples/Detectors/Geant4Detector/src/Geant4Detector.cpp b/Examples/Detectors/Geant4Detector/src/Geant4Detector.cpp index 42a8e4f2ce0..828304e342c 100644 --- a/Examples/Detectors/Geant4Detector/src/Geant4Detector.cpp +++ b/Examples/Detectors/Geant4Detector/src/Geant4Detector.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2022-2024 CERN for the benefit of the Acts project +// Copyright (C) 2022-2023 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -16,7 +16,6 @@ #include "Acts/Geometry/SurfaceArrayCreator.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" #include "Acts/Geometry/TrackingVolumeArrayCreator.hpp" -#include "ActsExamples/DetectorCommons/Detector.hpp" #include #include @@ -24,123 +23,97 @@ #include "G4Transform3D.hh" #include "G4VPhysicalVolume.hh" -namespace ActsExamples::Geant4 { - -Geant4Detector::Geant4Detector(const Geant4Detector::Config& cfg) - : DetectorCommons::Detector( - Acts::getDefaultLogger("Geant4Detector", m_cfg.logLevel)), - m_cfg(cfg) {} - -const Geant4Detector::DetectorElements& Geant4Detector::detectorElements() - const { - return m_detectorElements; -} - -void Geant4Detector::drop() { - Detector::drop(); - - m_detectorElements.clear(); -} - -void Geant4Detector::buildTrackingGeometry() { - std::tie(m_trackingGeometry, m_contextDecorators, m_detectorElements) = - constructTrackingGeometry(); -} - -void Geant4Detector::buildDetector() { - std::tie(m_detector, m_contextDecorators, m_detectorElements) = - constructDetector(); -} - -std::tuple -Geant4Detector::constructDetector() const { - if (m_cfg.g4World == nullptr) { +auto ActsExamples::Geant4::Geant4Detector::constructDetector( + const ActsExamples::Geant4::Geant4Detector::Config& cfg, + const Acts::Logger& logger) + -> std::tuple { + if (cfg.g4World == nullptr) { throw std::invalid_argument( "Geant4Detector: no world Geant4 volume provided"); } ACTS_INFO("Building an Acts::Detector called '" - << m_cfg.name << "' from the Geant4PhysVolume '" - << m_cfg.g4World->GetName() << "'"); + << cfg.name << "' from the Geant4PhysVolume '" + << cfg.g4World->GetName() << "'"); DetectorPtr detector = nullptr; ContextDecorators decorators = {}; - auto [surfaces, elements] = convertGeant4Volumes(); + auto [surfaces, elements] = convertGeant4Volumes(cfg, logger); - return {std::move(detector), std::move(decorators), std::move(elements)}; + return std::tie(detector, decorators, elements); } -std::tuple -Geant4Detector::constructTrackingGeometry() const { - if (m_cfg.g4World == nullptr) { +auto ActsExamples::Geant4::Geant4Detector::constructTrackingGeometry( + const ActsExamples::Geant4::Geant4Detector::Config& cfg, + const Acts::Logger& logger) + -> std::tuple { + if (cfg.g4World == nullptr) { throw std::invalid_argument( "Geant4Detector: no world Geant4 volume provided"); } ACTS_INFO("Building an Acts::TrackingGeometry called '" - << m_cfg.name << "' from the Geant4PhysVolume '" - << m_cfg.g4World->GetName() << "'"); + << cfg.name << "' from the Geant4PhysVolume '" + << cfg.g4World->GetName() << "'"); ContextDecorators decorators = {}; - auto [surfaces, elements] = convertGeant4Volumes(); + auto [surfaces, elements] = convertGeant4Volumes(cfg, logger); // Surface array creator auto surfaceArrayCreator = std::make_shared( - Acts::SurfaceArrayCreator::Config(), - logger().clone("SurfaceArrayCreator")); + Acts::SurfaceArrayCreator::Config(), logger.clone("SurfaceArrayCreator")); // Layer Creator Acts::LayerCreator::Config lcConfig; lcConfig.surfaceArrayCreator = surfaceArrayCreator; auto layerCreator = std::make_shared( - lcConfig, logger().clone("LayerCreator")); + lcConfig, logger.clone("LayerCreator")); // Layer array creator Acts::LayerArrayCreator::Config lacConfig; auto layerArrayCreator = std::make_shared( - lacConfig, logger().clone("LayerArrayCreator")); + lacConfig, logger.clone("LayerArrayCreator")); // Tracking volume array creator Acts::TrackingVolumeArrayCreator::Config tvacConfig; auto tVolumeArrayCreator = std::make_shared( - tvacConfig, logger().clone("TrackingVolumeArrayCreator")); + tvacConfig, logger.clone("TrackingVolumeArrayCreator")); // configure the cylinder volume helper Acts::CylinderVolumeHelper::Config cvhConfig; cvhConfig.layerArrayCreator = layerArrayCreator; cvhConfig.trackingVolumeArrayCreator = tVolumeArrayCreator; auto cylinderVolumeHelper = std::make_shared( - cvhConfig, logger().clone("CylinderVolumeHelper")); + cvhConfig, logger.clone("CylinderVolumeHelper")); // Configure the tracking geometry builder, copy the surfaces in Acts::KDTreeTrackingGeometryBuilder::Config kdtCfg; kdtCfg.surfaces = surfaces; kdtCfg.layerCreator = layerCreator; kdtCfg.trackingVolumeHelper = cylinderVolumeHelper; - kdtCfg.protoDetector = m_cfg.protoDetector; - kdtCfg.geometryIdentifierHook = m_cfg.geometryIdentifierHook; + kdtCfg.protoDetector = cfg.protoDetector; + kdtCfg.geometryIdentifierHook = cfg.geometryIdentifierHook; // The KDT tracking geometry builder auto kdtBuilder = Acts::KDTreeTrackingGeometryBuilder( - kdtCfg, logger().clone("KDTreeTrackingGeometryBuilder")); + kdtCfg, logger.clone("KDTreeTrackingGeometryBuilder")); Acts::GeometryContext tContext; TrackingGeometryPtr trackingGeometry = kdtBuilder.trackingGeometry(tContext); - return {std::move(trackingGeometry), std::move(decorators), - std::move(elements)}; + return std::tie(trackingGeometry, decorators, elements); } -std::tuple -Geant4Detector::convertGeant4Volumes() const { +auto ActsExamples::Geant4::Geant4Detector::convertGeant4Volumes( + const Geant4Detector::Config& cfg, const Acts::Logger& logger) const + -> std::tuple { // Generate the surface cache Acts::Geant4DetectorSurfaceFactory::Cache g4SurfaceCache; G4Transform3D g4ToWorld; Acts::Geant4DetectorSurfaceFactory{}.construct( - g4SurfaceCache, g4ToWorld, *m_cfg.g4World, m_cfg.g4SurfaceOptions); + g4SurfaceCache, g4ToWorld, *cfg.g4World, cfg.g4SurfaceOptions); ACTS_INFO("Found " << g4SurfaceCache.matchedG4Volumes << " matching Geant4 Physical volumes."); @@ -168,7 +141,5 @@ Geant4Detector::convertGeant4Volumes() const { surfaces.insert(surfaces.end(), g4SurfaceCache.passiveSurfaces.begin(), g4SurfaceCache.passiveSurfaces.end()); - return {std::move(surfaces), std::move(elements)}; + return std::tie(surfaces, elements); } - -} // namespace ActsExamples::Geant4 diff --git a/Examples/Detectors/GenericDetector/CMakeLists.txt b/Examples/Detectors/GenericDetector/CMakeLists.txt index 0df8532bc4b..28614c7ae7b 100644 --- a/Examples/Detectors/GenericDetector/CMakeLists.txt +++ b/Examples/Detectors/GenericDetector/CMakeLists.txt @@ -3,17 +3,15 @@ add_library( src/BuildGenericDetector.cpp src/GenericDetector.cpp src/GenericDetectorElement.cpp) - target_include_directories( ActsExamplesDetectorGeneric PUBLIC $) - target_link_libraries( ActsExamplesDetectorGeneric - PUBLIC - ActsCore - ActsExamplesFramework - ActsExamplesDetectorCommons) + PUBLIC ActsCore) +target_link_libraries( + ActsExamplesDetectorGeneric + PUBLIC ActsExamplesFramework) install( TARGETS ActsExamplesDetectorGeneric diff --git a/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/BuildGenericDetector.hpp b/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/BuildGenericDetector.hpp index d8a9a96afec..9d42ad9441c 100644 --- a/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/BuildGenericDetector.hpp +++ b/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/BuildGenericDetector.hpp @@ -108,7 +108,7 @@ std::vector> modulePositionsDisc( /// return a unique vector to the tracking geometry template std::unique_ptr buildDetector( - const Acts::GeometryContext& gctxIn, + const typename detector_element_t::ContextType& gctxIn, std::vector>>& detectorStore, std::size_t level, diff --git a/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/GenericDetector.hpp b/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/GenericDetector.hpp index a731ec547da..0279b91efef 100644 --- a/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/GenericDetector.hpp +++ b/Examples/Detectors/GenericDetector/include/ActsExamples/GenericDetector/GenericDetector.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2019-2024 CERN for the benefit of the Acts project +// Copyright (C) 2019 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -9,40 +9,46 @@ #pragma once #include "Acts/Utilities/Logger.hpp" -#include "ActsExamples/DetectorCommons/Detector.hpp" #include #include #include #include +namespace Acts { +class TrackingGeometry; +class IMaterialDecorator; +} // namespace Acts + +namespace ActsExamples { +class IContextDecorator; +} // namespace ActsExamples + namespace ActsExamples::Generic { class GenericDetectorElement; +} // namespace ActsExamples::Generic + +struct GenericDetector { + using DetectorElement = ActsExamples::Generic::GenericDetectorElement; + using DetectorElementPtr = std::shared_ptr; + using DetectorStore = std::vector>; -class GenericDetector : public ActsExamples::DetectorCommons::Detector { - public: - using TrackingGeometryPtr = std::shared_ptr; using ContextDecorators = std::vector>; - - using DetectorElement = ActsExamples::Generic::GenericDetectorElement; + using TrackingGeometryPtr = std::shared_ptr; struct Config { std::size_t buildLevel{3}; - Acts::Logging::Level logLevel{Acts::Logging::INFO}; Acts::Logging::Level surfaceLogLevel{Acts::Logging::INFO}; Acts::Logging::Level layerLogLevel{Acts::Logging::INFO}; Acts::Logging::Level volumeLogLevel{Acts::Logging::INFO}; bool buildProto{false}; - std::shared_ptr materialDecorator; }; - explicit GenericDetector(const Config& cfg); + /// The Store of the detector elements (lifetime: job) + DetectorStore detectorStore; - private: - Config m_cfg; - - void buildTrackingGeometry() final; + std::pair finalize( + const Config& cfg, + std::shared_ptr mdecorator); }; - -} // namespace ActsExamples::Generic diff --git a/Examples/Detectors/GenericDetector/src/GenericDetector.cpp b/Examples/Detectors/GenericDetector/src/GenericDetector.cpp index 77dce6aea69..044f2e209fa 100644 --- a/Examples/Detectors/GenericDetector/src/GenericDetector.cpp +++ b/Examples/Detectors/GenericDetector/src/GenericDetector.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2019-2024 CERN for the benefit of the Acts project +// Copyright (C) 2019 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,34 +8,25 @@ #include "ActsExamples/GenericDetector/GenericDetector.hpp" -#include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/ILayerBuilder.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" -#include "Acts/Utilities/Logger.hpp" -#include "ActsExamples/DetectorCommons/Detector.hpp" #include "ActsExamples/GenericDetector/BuildGenericDetector.hpp" #include "ActsExamples/GenericDetector/GenericDetectorElement.hpp" #include "ActsExamples/GenericDetector/ProtoLayerCreatorT.hpp" -namespace ActsExamples::Generic { - -GenericDetector::GenericDetector(const Config& cfg) - : DetectorCommons::Detector( - Acts::getDefaultLogger("GenericDetector", m_cfg.logLevel)), - m_cfg(cfg) {} - -void GenericDetector::buildTrackingGeometry() { - Acts::GeometryContext gctx; - std::vector>> detectorStore; - m_trackingGeometry = ActsExamples::Generic::buildDetector( - gctx, detectorStore, m_cfg.buildLevel, m_cfg.materialDecorator, - m_cfg.buildProto, m_cfg.surfaceLogLevel, m_cfg.layerLogLevel, - m_cfg.volumeLogLevel); - for (auto& something : detectorStore) { - for (auto& element : something) { - m_detectorStore.push_back(std::move(element)); - } - } +auto GenericDetector::finalize( + const Config& cfg, + std::shared_ptr mdecorator) + -> std::pair { + DetectorElement::ContextType nominalContext; + /// Return the generic detector + TrackingGeometryPtr gGeometry = + ActsExamples::Generic::buildDetector( + nominalContext, detectorStore, cfg.buildLevel, std::move(mdecorator), + cfg.buildProto, cfg.surfaceLogLevel, cfg.layerLogLevel, + cfg.volumeLogLevel); + ContextDecorators gContextDecorators = {}; + // return the pair of geometry and empty decorators + return std::make_pair( + std::move(gGeometry), std::move(gContextDecorators)); } - -} // namespace ActsExamples::Generic diff --git a/Examples/Detectors/MuonSpectrometerMockupDetector/src/MockupSectorBuilder.cpp b/Examples/Detectors/MuonSpectrometerMockupDetector/src/MockupSectorBuilder.cpp index 0659e185dab..b9b6e3ec3b1 100644 --- a/Examples/Detectors/MuonSpectrometerMockupDetector/src/MockupSectorBuilder.cpp +++ b/Examples/Detectors/MuonSpectrometerMockupDetector/src/MockupSectorBuilder.cpp @@ -77,9 +77,10 @@ ActsExamples::MockupSectorBuilder::buildChamber( g4SurfaceOptions.passiveSurfaceSelector = g4Passive; g4WorldConfig.g4SurfaceOptions = g4SurfaceOptions; - auto g4detector = ActsExamples::Geant4::Geant4Detector(g4WorldConfig); - // Trigger the build of the detector - g4detector.detector(); + auto g4detector = ActsExamples::Geant4::Geant4Detector(); + + auto [detector, surfaces, detectorElements] = + g4detector.constructDetector(g4WorldConfig, Acts::getDummyLogger()); // The vector that holds the converted sensitive surfaces of the chamber std::vector> strawSurfaces = {}; @@ -90,7 +91,7 @@ ActsExamples::MockupSectorBuilder::buildChamber( -std::numeric_limits::max())); // Convert the physical volumes of the detector elements to straw surfaces - for (auto& detectorElement : g4detector.detectorElements()) { + for (auto& detectorElement : detectorElements) { auto context = Acts::GeometryContext(); auto g4conv = Acts::Geant4PhysicalVolumeConverter(); diff --git a/Examples/Detectors/TGeoDetector/CMakeLists.txt b/Examples/Detectors/TGeoDetector/CMakeLists.txt index 60893a555d4..6bb8967f0b7 100644 --- a/Examples/Detectors/TGeoDetector/CMakeLists.txt +++ b/Examples/Detectors/TGeoDetector/CMakeLists.txt @@ -6,16 +6,11 @@ add_library( target_include_directories( ActsExamplesDetectorTGeo PUBLIC $) - target_link_libraries( ActsExamplesDetectorTGeo PUBLIC - ActsCore - ActsPluginTGeo - ActsPluginJson - ActsExamplesFramework - ActsExamplesDetectorGeneric - ActsExamplesDetectorCommons) + ActsCore ActsPluginTGeo ActsPluginJson + ActsExamplesFramework ActsExamplesDetectorGeneric) install( TARGETS ActsExamplesDetectorTGeo diff --git a/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/JsonTGeoDetectorConfig.hpp b/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/JsonTGeoDetectorConfig.hpp index 928feb96760..634127fc9b3 100644 --- a/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/JsonTGeoDetectorConfig.hpp +++ b/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/JsonTGeoDetectorConfig.hpp @@ -53,26 +53,29 @@ NLOHMANN_JSON_SERIALIZE_ENUM(Acts::BinningType, } // namespace Acts -namespace ActsExamples::Options { +namespace ActsExamples { + +namespace Options { /// Read config for options interval -void from_json(const nlohmann::json& j, Interval& interval) { +void from_json(const nlohmann::json& j, + ActsExamples::Options::Interval& interval) { interval.lower = j.at("lower"); interval.upper = j.at("upper"); } /// Write config for options interval -void to_json(nlohmann::json& j, const Interval& interval) { +void to_json(nlohmann::json& j, + const ActsExamples::Options::Interval& interval) { // no direct conversion from std::optional to json j = nlohmann::json{{"lower", interval.lower.value_or(0)}, {"upper", interval.upper.value_or(0)}}; } -} // namespace ActsExamples::Options - -namespace ActsExamples::TGeo { +} // namespace Options -void from_json(const nlohmann::json& j, TGeoITkModuleSplitter::Config& msc) { +void from_json(const nlohmann::json& j, + ActsExamples::TGeoITkModuleSplitter::Config& msc) { msc.barrelMap = j["geo-tgeo-barrel-map"].get>(); msc.discMap = @@ -80,7 +83,8 @@ void from_json(const nlohmann::json& j, TGeoITkModuleSplitter::Config& msc) { .get>>>(); } -void to_json(nlohmann::json& j, const TGeoITkModuleSplitter::Config& msc) { +void to_json(nlohmann::json& j, + const ActsExamples::TGeoITkModuleSplitter::Config& msc) { j["geo-tgeo-barrel-map"] = msc.barrelMap; j["geo-tgeo-disc-map"] = msc.discMap; } @@ -88,7 +92,7 @@ void to_json(nlohmann::json& j, const TGeoITkModuleSplitter::Config& msc) { /// Read layer configuration triplets template void from_json(const nlohmann::json& j, - TGeoDetector::Config::LayerTriplet& ltr) { + ActsExamples::TGeoDetector::Config::LayerTriplet& ltr) { ltr.negative = j.at("negative").get(); ltr.central = j.at("central").get(); ltr.positive = j.at("positive").get(); @@ -97,14 +101,15 @@ void from_json(const nlohmann::json& j, /// Write layer configuration triplets template void to_json(nlohmann::json& j, - const TGeoDetector::Config::LayerTriplet& ltr) { + const ActsExamples::TGeoDetector::Config::LayerTriplet& ltr) { j = nlohmann::json{{"negative", ltr.negative}, {"central", ltr.central}, {"positive", ltr.positive}}; } /// Read volume struct -void from_json(const nlohmann::json& j, TGeoDetector::Config::Volume& vol) { +void from_json(const nlohmann::json& j, + ActsExamples::TGeoDetector::Config::Volume& vol) { // subdetector selection vol.name = j.at("geo-tgeo-volume-name"); @@ -140,7 +145,8 @@ void from_json(const nlohmann::json& j, TGeoDetector::Config::Volume& vol) { if (j.count("geo-tgeo-itk-module-split") != 0) { vol.itkModuleSplit = j.at("geo-tgeo-itk-module-split"); if (vol.itkModuleSplit) { - TGeoITkModuleSplitter::Config itkConfig = j.at("Splitters").at("ITk"); + ActsExamples::TGeoITkModuleSplitter::Config itkConfig = + j.at("Splitters").at("ITk"); vol.barrelMap = itkConfig.barrelMap; vol.discMap = itkConfig.discMap; } @@ -179,11 +185,11 @@ void to_json(nlohmann::json& j, const TGeoDetector::Config::Volume& vol) { j["Splitters"]["CylinderDisk"] = cdConfig; if (vol.itkModuleSplit) { - TGeoITkModuleSplitter::Config itkConfig; + ActsExamples::TGeoITkModuleSplitter::Config itkConfig; itkConfig.barrelMap = vol.barrelMap; itkConfig.discMap = vol.discMap; j["Splitters"]["ITk"] = itkConfig; } } -} // namespace ActsExamples::TGeo +} // namespace ActsExamples diff --git a/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoDetector.hpp b/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoDetector.hpp index 7e652741fce..cb0b8d90f7a 100644 --- a/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoDetector.hpp +++ b/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoDetector.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2018-2024 CERN for the benefit of the Acts project +// Copyright (C) 2018 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -9,11 +9,9 @@ #pragma once #include "Acts/Geometry/GeometryIdentifier.hpp" -#include "Acts/Material/IMaterialDecorator.hpp" #include "Acts/Plugins/TGeo/TGeoLayerBuilder.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Logger.hpp" -#include "ActsExamples/DetectorCommons/Detector.hpp" #include "ActsExamples/Utilities/Options.hpp" #include @@ -24,18 +22,30 @@ #include #include -namespace ActsExamples::TGeo { +namespace Acts { +class TGeoDetectorElement; +class TrackingGeometry; +class IMaterialDecorator; +} // namespace Acts + +namespace ActsExamples { +class IContextDecorator; +} // namespace ActsExamples + +namespace ActsExamples { + +struct TGeoDetector { + using DetectorElementPtr = std::shared_ptr; + using DetectorStore = std::vector; -class TGeoDetector : public DetectorCommons::Detector { - public: - using TrackingGeometryPtr = std::shared_ptr; using ContextDecorators = std::vector>; + using TrackingGeometryPtr = std::shared_ptr; - using DetectorElement = Acts::TGeoDetectorElement; + /// The Store of the detector elements (lifetime: job) + DetectorStore detectorStore; struct Config { - Acts::Logging::Level logLevel = Acts::Logging::WARNING; Acts::Logging::Level surfaceLogLevel = Acts::Logging::WARNING; Acts::Logging::Level layerLogLevel = Acts::Logging::WARNING; Acts::Logging::Level volumeLogLevel = Acts::Logging::WARNING; @@ -59,8 +69,6 @@ class TGeoDetector : public DetectorCommons::Detector { std::shared_ptr geometryIdentifierHook = std::make_shared(); - std::shared_ptr materialDecorator; - enum SubVolume : std::size_t { Negative = 0, Central, Positive }; template @@ -142,12 +150,9 @@ class TGeoDetector : public DetectorCommons::Detector { static void readTGeoLayerBuilderConfigsFile(const std::string& path, Config& config); - explicit TGeoDetector(const Config& cfg); - - private: - Config m_cfg; - - void buildTrackingGeometry() final; + std::pair finalize( + const Config& cfg, + std::shared_ptr mdecorator); }; -} // namespace ActsExamples::TGeo +} // namespace ActsExamples diff --git a/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoITkModuleSplitter.hpp b/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoITkModuleSplitter.hpp index 0596100c0f7..a08dbebd661 100644 --- a/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoITkModuleSplitter.hpp +++ b/Examples/Detectors/TGeoDetector/include/ActsExamples/TGeoDetector/TGeoITkModuleSplitter.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2021-2024 CERN for the benefit of the Acts project +// Copyright (C) 2021 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -26,7 +26,7 @@ namespace Acts { class TGeoDetectorElement; } -namespace ActsExamples::TGeo { +namespace ActsExamples { /// @brief TGeoITkModuleSplitter /// @@ -120,4 +120,4 @@ class TGeoITkModuleSplitter : public Acts::ITGeoDetectorElementSplitter { std::unique_ptr m_logger; }; -} // namespace ActsExamples::TGeo +} // namespace ActsExamples diff --git a/Examples/Detectors/TGeoDetector/src/TGeoDetector.cpp b/Examples/Detectors/TGeoDetector/src/TGeoDetector.cpp index 2d3a26895d4..77edfa78e1a 100644 --- a/Examples/Detectors/TGeoDetector/src/TGeoDetector.cpp +++ b/Examples/Detectors/TGeoDetector/src/TGeoDetector.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2019-2024 CERN for the benefit of the Acts project +// Copyright (C) 2019 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -10,7 +10,6 @@ #include "Acts/Geometry/CylinderVolumeBuilder.hpp" #include "Acts/Geometry/CylinderVolumeHelper.hpp" -#include "Acts/Geometry/DetectorElementBase.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/ITrackingVolumeBuilder.hpp" #include "Acts/Geometry/LayerArrayCreator.hpp" @@ -27,6 +26,7 @@ #include "Acts/Utilities/Logger.hpp" #include "ActsExamples/TGeoDetector/JsonTGeoDetectorConfig.hpp" #include "ActsExamples/TGeoDetector/TGeoITkModuleSplitter.hpp" +#include "ActsExamples/Utilities/Options.hpp" #include #include @@ -43,7 +43,8 @@ #include "TGeoManager.h" -namespace ActsExamples::TGeo { +namespace ActsExamples { +using namespace Options; namespace { @@ -134,12 +135,12 @@ std::vector makeLayerBuilderConfigs( cdsConfig, logger.clone("TGeoCylinderDiscSplitter", config.layerLogLevel)); } else if (volume.itkModuleSplit) { - TGeoITkModuleSplitter::Config itkConfig; + ActsExamples::TGeoITkModuleSplitter::Config itkConfig; itkConfig.barrelMap = volume.barrelMap; itkConfig.discMap = volume.discMap; itkConfig.splitPatterns = volume.splitPatterns; layerBuilderConfig.detectorElementSplitter = - std::make_shared( + std::make_shared( itkConfig, logger.clone("TGeoITkModuleSplitter", config.layerLogLevel)); } @@ -161,7 +162,7 @@ std::vector makeLayerBuilderConfigs( /// @param vm is the variable map from the options std::shared_ptr buildTGeoDetector( const TGeoDetector::Config& config, const Acts::GeometryContext& context, - std::vector>& + std::vector>& detElementStore, std::shared_ptr mdecorator, const Acts::Logger& logger) { @@ -366,20 +367,23 @@ void TGeoDetector::readTGeoLayerBuilderConfigsFile(const std::string& path, } } -TGeoDetector::TGeoDetector(const Config& cfg) - : DetectorCommons::Detector( - Acts::getDefaultLogger("TGeoDetector", m_cfg.logLevel)), - m_cfg(cfg) {} +auto TGeoDetector::finalize( + const Config& cfg, + std::shared_ptr mdecorator) + -> std::pair { + Acts::GeometryContext tGeoContext; + auto logger = Acts::getDefaultLogger("TGeoDetector", Acts::Logging::INFO); + TrackingGeometryPtr tgeoTrackingGeometry = buildTGeoDetector( + cfg, tGeoContext, detectorStore, std::move(mdecorator), *logger); + + ContextDecorators tgeoContextDecorators = {}; + // Return the pair of geometry and empty decorators + return std::make_pair( + std::move(tgeoTrackingGeometry), std::move(tgeoContextDecorators)); +} void TGeoDetector::Config::readJson(const std::string& jsonFile) { readTGeoLayerBuilderConfigsFile(jsonFile, *this); } -void TGeoDetector::buildTrackingGeometry() { - Acts::GeometryContext tGeoContext; - - m_trackingGeometry = buildTGeoDetector(m_cfg, tGeoContext, m_detectorStore, - m_cfg.materialDecorator, logger()); -} - -} // namespace ActsExamples::TGeo +} // namespace ActsExamples diff --git a/Examples/Detectors/TGeoDetector/src/TGeoITkModuleSplitter.cpp b/Examples/Detectors/TGeoDetector/src/TGeoITkModuleSplitter.cpp index d169ef9ae9c..df88593ff7a 100644 --- a/Examples/Detectors/TGeoDetector/src/TGeoITkModuleSplitter.cpp +++ b/Examples/Detectors/TGeoDetector/src/TGeoITkModuleSplitter.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2016-2024 CERN for the benefit of the Acts project +// Copyright (C) 2016-2020 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -20,16 +20,14 @@ #include #include -namespace ActsExamples::TGeo { - -TGeoITkModuleSplitter::TGeoITkModuleSplitter( - const TGeoITkModuleSplitter::Config& cfg, +ActsExamples::TGeoITkModuleSplitter::TGeoITkModuleSplitter( + const ActsExamples::TGeoITkModuleSplitter::Config& cfg, std::unique_ptr logger) : m_cfg(cfg), m_logger(std::move(logger)) { initSplitCategories(); } -void TGeoITkModuleSplitter::initSplitCategories() { +void ActsExamples::TGeoITkModuleSplitter::initSplitCategories() { m_splitCategories.reserve(m_cfg.splitPatterns.size()); for (const std::pair& pattern_split_category : m_cfg.splitPatterns) { @@ -53,7 +51,7 @@ void TGeoITkModuleSplitter::initSplitCategories() { /// If applicable, returns a split detector element inline std::vector> -TGeoITkModuleSplitter::split( +ActsExamples::TGeoITkModuleSplitter::split( const Acts::GeometryContext& gctx, std::shared_ptr detElement) const { // Is the current node covered by this splitter? @@ -69,10 +67,10 @@ TGeoITkModuleSplitter::split( " node " + sensorName + " using split ranges of category " + std::get<1>(split_category)); if (!std::get<2>(split_category)) { - return TGeoITkModuleSplitter::splitBarrelModule( + return ActsExamples::TGeoITkModuleSplitter::splitBarrelModule( gctx, detElement, m_cfg.barrelMap.at(std::get<1>(split_category))); } else { - return TGeoITkModuleSplitter::splitDiscModule( + return ActsExamples::TGeoITkModuleSplitter::splitDiscModule( gctx, detElement, m_cfg.discMap.at(std::get<1>(split_category))); } } @@ -86,7 +84,7 @@ TGeoITkModuleSplitter::split( /// If applicable, returns a split detector element inline std::vector> -TGeoITkModuleSplitter::splitBarrelModule( +ActsExamples::TGeoITkModuleSplitter::splitBarrelModule( const Acts::GeometryContext& gctx, const std::shared_ptr& detElement, unsigned int nSegments) const { @@ -143,10 +141,11 @@ TGeoITkModuleSplitter::splitBarrelModule( /// If applicable, returns a split detector element inline std::vector> -TGeoITkModuleSplitter::splitDiscModule( +ActsExamples::TGeoITkModuleSplitter::splitDiscModule( const Acts::GeometryContext& gctx, const std::shared_ptr& detElement, - const std::vector& splitRanges) const { + const std::vector& + splitRanges) const { // Retrieve the surface auto identifier = detElement->identifier(); const Acts::Surface& surface = detElement->surface(); @@ -199,5 +198,3 @@ TGeoITkModuleSplitter::splitDiscModule( } return detElements; } - -} // namespace ActsExamples::TGeo diff --git a/Examples/Detectors/TelescopeDetector/CMakeLists.txt b/Examples/Detectors/TelescopeDetector/CMakeLists.txt index f19044c06af..08acae480b6 100644 --- a/Examples/Detectors/TelescopeDetector/CMakeLists.txt +++ b/Examples/Detectors/TelescopeDetector/CMakeLists.txt @@ -3,17 +3,12 @@ add_library( src/TelescopeDetector.cpp src/TelescopeDetectorElement.cpp src/BuildTelescopeDetector.cpp) - target_include_directories( ActsExamplesDetectorTelescope PUBLIC $) - target_link_libraries( ActsExamplesDetectorTelescope - PUBLIC - ActsCore - ActsExamplesFramework - ActsExamplesDetectorCommons) + PUBLIC ActsCore ActsExamplesFramework) install( TARGETS ActsExamplesDetectorTelescope diff --git a/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/BuildTelescopeDetector.hpp b/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/BuildTelescopeDetector.hpp index 1e3b17cba60..34656cc0a32 100644 --- a/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/BuildTelescopeDetector.hpp +++ b/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/BuildTelescopeDetector.hpp @@ -46,9 +46,8 @@ enum class TelescopeSurfaceType { /// @param binValue indicates which axis the detector surface normals are /// parallel to std::unique_ptr buildDetector( - const Acts::GeometryContext& gctx, - std::vector>& - detectorStore, + const typename TelescopeDetectorElement::ContextType& gctx, + std::vector>& detectorStore, const std::vector& positions, const std::vector& stereoAngles, const std::array& offsets, const std::array& bounds, diff --git a/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/TelescopeDetector.hpp b/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/TelescopeDetector.hpp index 5778b41b43b..19bb2b700d1 100644 --- a/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/TelescopeDetector.hpp +++ b/Examples/Detectors/TelescopeDetector/include/ActsExamples/TelescopeDetector/TelescopeDetector.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2020-2024 CERN for the benefit of the Acts project +// Copyright (C) 2020 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -10,7 +10,6 @@ #include "Acts/Definitions/Units.hpp" #include "Acts/Utilities/Logger.hpp" -#include "ActsExamples/DetectorCommons/Detector.hpp" #include "ActsExamples/Utilities/Options.hpp" #include @@ -18,37 +17,48 @@ #include #include +using namespace Acts::UnitLiterals; + +namespace Acts { +class TrackingGeometry; +class IMaterialDecorator; +} // namespace Acts + +namespace ActsExamples { +class IContextDecorator; +} // namespace ActsExamples + namespace ActsExamples::Telescope { class TelescopeDetectorElement; class TelescopeG4DetectorConstruction; -class TelescopeDetector : public ActsExamples::DetectorCommons::Detector { - public: - using TrackingGeometryPtr = std::shared_ptr; +struct TelescopeDetector { + using DetectorElement = ActsExamples::Telescope::TelescopeDetectorElement; + using DetectorElementPtr = std::shared_ptr; + using DetectorStore = std::vector; + using ContextDecorators = std::vector>; - - using DetectorElement = ActsExamples::Telescope::TelescopeDetectorElement; + using TrackingGeometryPtr = std::shared_ptr; struct Config { std::vector positions{{0, 30, 60, 120, 150, 180}}; std::vector stereos{{0, 0, 0, 0, 0, 0}}; std::array offsets{{0, 0}}; std::array bounds{{25, 100}}; - double thickness{80 * Acts::UnitConstants::um}; + double thickness{80_um}; int surfaceType{0}; int binValue{2}; - std::shared_ptr materialDecorator; - Acts::Logging::Level logLevel{Acts::Logging::WARNING}; }; - explicit TelescopeDetector(const Config& cfg); - - private: - Config m_cfg; + Config config; + /// The store of the detector elements (lifetime: job) + DetectorStore detectorStore; - void buildTrackingGeometry() final; + std::pair finalize( + const Config& cfg, + const std::shared_ptr& mdecorator); }; } // namespace ActsExamples::Telescope diff --git a/Examples/Detectors/TelescopeDetector/src/BuildTelescopeDetector.cpp b/Examples/Detectors/TelescopeDetector/src/BuildTelescopeDetector.cpp index 0983f6aa538..35136911325 100644 --- a/Examples/Detectors/TelescopeDetector/src/BuildTelescopeDetector.cpp +++ b/Examples/Detectors/TelescopeDetector/src/BuildTelescopeDetector.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2020-2024 CERN for the benefit of the Acts project +// Copyright (C) 2020-2021 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -12,7 +12,6 @@ #include "Acts/Definitions/Units.hpp" #include "Acts/Geometry/CuboidVolumeBounds.hpp" #include "Acts/Geometry/CylinderVolumeBounds.hpp" -#include "Acts/Geometry/DetectorElementBase.hpp" #include "Acts/Geometry/DiscLayer.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/ILayerArrayCreator.hpp" @@ -36,8 +35,10 @@ std::unique_ptr ActsExamples::Telescope::buildDetector( - const Acts::GeometryContext& gctx, - std::vector>& + const typename ActsExamples::Telescope::TelescopeDetectorElement:: + ContextType& gctx, + std::vector< + std::shared_ptr>& detectorStore, const std::vector& positions, const std::vector& stereoAngles, diff --git a/Examples/Detectors/TelescopeDetector/src/TelescopeDetector.cpp b/Examples/Detectors/TelescopeDetector/src/TelescopeDetector.cpp index 8f82ba1a85e..0d5c35800d5 100644 --- a/Examples/Detectors/TelescopeDetector/src/TelescopeDetector.cpp +++ b/Examples/Detectors/TelescopeDetector/src/TelescopeDetector.cpp @@ -8,56 +8,55 @@ #include "ActsExamples/TelescopeDetector/TelescopeDetector.hpp" -#include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" #include "Acts/Utilities/BinningType.hpp" #include "ActsExamples/TelescopeDetector/BuildTelescopeDetector.hpp" #include "ActsExamples/TelescopeDetector/TelescopeDetectorElement.hpp" #include -#include #include -namespace ActsExamples::Telescope { +auto ActsExamples::Telescope::TelescopeDetector::finalize( + const Config& cfg, const std::shared_ptr& + /*mdecorator*/) -> std::pair { + DetectorElement::ContextType nominalContext; -TelescopeDetector::TelescopeDetector(const Config& cfg) - : DetectorCommons::Detector( - Acts::getDefaultLogger("TelescopeDetector", cfg.logLevel)), - m_cfg(cfg) {} - -void TelescopeDetector::buildTrackingGeometry() { - Acts::GeometryContext gctx; - - if (m_cfg.surfaceType > 1) { + if (cfg.surfaceType > 1) { throw std::invalid_argument( "The surface type could either be 0 for plane surface or 1 for disc " "surface."); } - if (m_cfg.binValue > 2) { + if (cfg.binValue > 2) { throw std::invalid_argument("The axis value could only be 0, 1, or 2."); } // Check if the bounds values are valid - if (m_cfg.surfaceType == 1 && m_cfg.bounds[0] >= m_cfg.bounds[1]) { + if (cfg.surfaceType == 1 && cfg.bounds[0] >= cfg.bounds[1]) { throw std::invalid_argument( "The minR should be smaller than the maxR for disc surface bounds."); } - if (m_cfg.positions.size() != m_cfg.stereos.size()) { + if (cfg.positions.size() != cfg.stereos.size()) { throw std::invalid_argument( "The number of provided positions must match the number of " "provided stereo angles."); } + config = cfg; + // Sort the provided distances - std::vector positions = m_cfg.positions; - std::vector stereos = m_cfg.stereos; + std::vector positions = cfg.positions; + std::vector stereos = cfg.stereos; std::sort(positions.begin(), positions.end()); /// Return the telescope detector - m_trackingGeometry = ActsExamples::Telescope::buildDetector( - gctx, m_detectorStore, positions, stereos, m_cfg.offsets, m_cfg.bounds, - m_cfg.thickness, static_cast(m_cfg.surfaceType), - static_cast(m_cfg.binValue)); + TrackingGeometryPtr gGeometry = ActsExamples::Telescope::buildDetector( + nominalContext, detectorStore, positions, stereos, cfg.offsets, + cfg.bounds, cfg.thickness, + static_cast( + cfg.surfaceType), + static_cast(cfg.binValue)); + ContextDecorators gContextDecorators = {}; + // return the pair of geometry and empty decorators + return std::make_pair( + std::move(gGeometry), std::move(gContextDecorators)); } - -} // namespace ActsExamples::Telescope diff --git a/Examples/Python/python/acts/_adapter.py b/Examples/Python/python/acts/_adapter.py index 2d56f046354..112fbf7f631 100644 --- a/Examples/Python/python/acts/_adapter.py +++ b/Examples/Python/python/acts/_adapter.py @@ -2,7 +2,6 @@ import functools from typing import Optional, Callable, Dict, Any from pathlib import Path -from contextlib import nullcontext import acts @@ -110,14 +109,15 @@ def create(*args, mdecorator=None, **kwargs): cfg = cls.Config() else: cfg = config_class() - setattr(cfg, "matDecorator", mdecorator) + _kwargs = {} for k, v in kwargs.items(): - setattr(cfg, k, v) - detector = cls(cfg) - trackingGeometry = detector.trackingGeometry() - decorators = detector.contextDecorators() - contextManager = nullcontext() - return detector, trackingGeometry, decorators, contextManager + try: + setattr(cfg, k, v) + except AttributeError: + _kwargs[k] = v + det = cls() + tg, deco = det.finalize(cfg, mdecorator, *args, **_kwargs) + return det, tg, deco return create diff --git a/Examples/Python/src/DD4hepComponent.cpp b/Examples/Python/src/DD4hepComponent.cpp index 79068d9a4cc..091842f6783 100644 --- a/Examples/Python/src/DD4hepComponent.cpp +++ b/Examples/Python/src/DD4hepComponent.cpp @@ -1,13 +1,12 @@ // This file is part of the Acts project. // -// Copyright (C) 2021-2024 CERN for the benefit of the Acts project +// Copyright (C) 2021 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include "Acts/Detector/GeometryIdGenerator.hpp" -#include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Plugins/DD4hep/DD4hepDetectorElement.hpp" #include "Acts/Plugins/DD4hep/DD4hepDetectorStructure.hpp" #include "Acts/Plugins/DD4hep/DD4hepFieldAdapter.hpp" @@ -15,7 +14,7 @@ #include "Acts/Plugins/Python/Utilities.hpp" #include "Acts/Utilities/Logger.hpp" #include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" -#include "ActsExamples/DetectorCommons/Detector.hpp" +#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" #include "ActsExamples/Framework/IContextDecorator.hpp" #include "ActsExamples/Framework/ProcessCode.hpp" @@ -37,17 +36,10 @@ using namespace Acts::Python; PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { { - py::class_>( - m, "DD4hepDetectorElement"); - } - - { - using Detector = DD4hep::DD4hepDetector; - using Config = Detector::Config; - - auto s = py::class_>(m, "DD4hepDetector") + using Config = ActsExamples::DD4hep::DD4hepGeometryService::Config; + auto s = py::class_>( + m, "DD4hepGeometryService") .def(py::init()); auto c = py::class_(s, "Config").def(py::init<>()); @@ -62,7 +54,6 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { ACTS_PYTHON_MEMBER(envelopeR); ACTS_PYTHON_MEMBER(envelopeZ); ACTS_PYTHON_MEMBER(defaultLayerThickness); - ACTS_PYTHON_MEMBER(materialDecorator); ACTS_PYTHON_MEMBER(geometryIdentifierHook); ACTS_PYTHON_STRUCT_END(); @@ -75,6 +66,12 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { "DD4hepFieldAdapter"); } + { + py::class_>( + m, "DD4hepDetectorElement"); + } + { m.def("createDD4hepIdGeoIdMap", [](const Acts::TrackingGeometry& tGeometry) @@ -91,7 +88,7 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { const auto* dd4hepDetElement = dynamic_cast(dde); // Check if it is valid - if (dd4hepDetElement != nullptr) { + if (dd4hepDetElement) { dd4hep::DDSegmentation::VolumeID dd4hepID = dd4hepDetElement->sourceElement().volumeID(); auto geoID = surface->geometryId(); @@ -155,4 +152,21 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { options.geoIdGenerator = chainedGeoIdGenerator; }); } + + { + py::class_>( + m, "DD4hepDetector") + .def(py::init<>()) + .def(py::init>()) + .def("finalize", + py::overload_cast>( + &DD4hep::DD4hepDetector::finalize)) + .def("finalize", + py::overload_cast< + const Acts::GeometryContext&, + const Acts::Experimental::DD4hepDetectorStructure::Options&>( + &DD4hep::DD4hepDetector::finalize)) + .def_property_readonly("field", &DD4hep::DD4hepDetector::field); + } } diff --git a/Examples/Python/src/Detector.cpp b/Examples/Python/src/Detector.cpp index 2a1fe21d874..524aa867383 100644 --- a/Examples/Python/src/Detector.cpp +++ b/Examples/Python/src/Detector.cpp @@ -1,14 +1,11 @@ // This file is part of the Acts project. // -// Copyright (C) 2021-2024 CERN for the benefit of the Acts project +// Copyright (C) 2021 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "ActsExamples/DetectorCommons/Detector.hpp" - -#include "Acts/Geometry/DetectorElementBase.hpp" #include "Acts/Geometry/TrackingGeometry.hpp" #include "Acts/Material/IMaterialDecorator.hpp" #include "Acts/Plugins/Python/Utilities.hpp" @@ -39,7 +36,6 @@ using namespace ActsExamples; namespace Acts::Python { void addDetector(Context& ctx) { auto [m, mex] = ctx.get("main", "examples"); - { py::class_>( mex, "IContextDecorator") @@ -48,25 +44,16 @@ void addDetector(Context& ctx) { } { - py::class_>( - mex, "DetectorElementBase"); - } + using Config = GenericDetector::Config; - { - using Detector = DetectorCommons::Detector; - - py::class_>(mex, "Detector") - .def("trackingGeometry", &Detector::trackingGeometry) - .def("drop", &Detector::drop); - } - - { - using Detector = Generic::GenericDetector; - using Config = Detector::Config; - - auto gd = py::class_>(mex, "GenericDetector") - .def(py::init()); + auto gd = py::class_>( + mex, "GenericDetector") + .def(py::init<>()) + .def("finalize", + py::overload_cast< + const Config&, + std::shared_ptr>( + &GenericDetector::finalize)); py::class_(gd, "Config") .def(py::init<>()) @@ -74,17 +61,22 @@ void addDetector(Context& ctx) { .def_readwrite("surfaceLogLevel", &Config::surfaceLogLevel) .def_readwrite("layerLogLevel", &Config::layerLogLevel) .def_readwrite("volumeLogLevel", &Config::volumeLogLevel) - .def_readwrite("buildProto", &Config::buildProto) - .def_readwrite("materialDecorator", &Config::materialDecorator); + .def_readwrite("buildProto", &Config::buildProto); } { - using Detector = Telescope::TelescopeDetector; - using Config = Detector::Config; - - auto td = py::class_>(mex, "TelescopeDetector") - .def(py::init()); + using TelescopeDetector = Telescope::TelescopeDetector; + using Config = TelescopeDetector::Config; + + auto td = + py::class_>( + mex, "TelescopeDetector") + .def(py::init<>()) + .def("finalize", + py::overload_cast< + const Config&, + const std::shared_ptr&>( + &TelescopeDetector::finalize)); py::class_(td, "Config") .def(py::init<>()) @@ -98,14 +90,19 @@ void addDetector(Context& ctx) { } { - using Detector = Contextual::AlignedDetector; - using Config = Detector::Config; - - auto d = py::class_>(mex, "AlignedDetector") - .def(py::init()); - - auto c = py::class_(d, "Config") + using AlignedDetector = Contextual::AlignedDetector; + using Config = AlignedDetector::Config; + + auto d = py::class_>( + mex, "AlignedDetector") + .def(py::init<>()) + .def("finalize", + py::overload_cast< + const Config&, + std::shared_ptr>( + &AlignedDetector::finalize)); + + auto c = py::class_(d, "Config") .def(py::init<>()); ACTS_PYTHON_STRUCT_BEGIN(c, Config); ACTS_PYTHON_MEMBER(seed); @@ -127,12 +124,16 @@ void addDetector(Context& ctx) { } { - using Detector = TGeo::TGeoDetector; - using Config = Detector::Config; - - auto d = py::class_>(mex, "TGeoDetector") - .def(py::init()); + using Config = TGeoDetector::Config; + + auto d = py::class_>( + mex, "TGeoDetector") + .def(py::init<>()) + .def("finalize", + py::overload_cast< + const Config&, + std::shared_ptr>( + &TGeoDetector::finalize)); py::class_(mex, "Interval") .def(py::init<>()) diff --git a/Examples/Python/src/EDM4hepComponent.cpp b/Examples/Python/src/EDM4hepComponent.cpp index cce41213c84..3f780230c4e 100644 --- a/Examples/Python/src/EDM4hepComponent.cpp +++ b/Examples/Python/src/EDM4hepComponent.cpp @@ -1,13 +1,13 @@ // This file is part of the Acts project. // -// Copyright (C) 2022-2024 CERN for the benefit of the Acts project +// Copyright (C) 2022 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include "Acts/Plugins/Python/Utilities.hpp" -#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" +#include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" #include "ActsExamples/Io/EDM4hep/EDM4hepMeasurementReader.hpp" #include "ActsExamples/Io/EDM4hep/EDM4hepMeasurementWriter.hpp" #include "ActsExamples/Io/EDM4hep/EDM4hepMultiTrajectoryWriter.hpp" @@ -29,12 +29,11 @@ using namespace Acts; using namespace Acts::Python; PYBIND11_MODULE(ActsPythonBindingsEDM4hep, m) { - ACTS_PYTHON_DECLARE_READER(ActsExamples::EDM4hepReader, m, "EDM4hepReader", - inputPath, inputParticles, inputSimHits, - outputParticlesInitial, outputParticlesFinal, - outputParticlesGenerator, outputSimHits, - graphvizOutput, dd4hepGeometryService, - trackingGeometry, sortSimHitsInTime); + ACTS_PYTHON_DECLARE_READER( + ActsExamples::EDM4hepReader, m, "EDM4hepReader", inputPath, + inputParticles, inputSimHits, outputParticlesInitial, + outputParticlesFinal, outputParticlesGenerator, outputSimHits, + graphvizOutput, dd4hepDetector, trackingGeometry, sortSimHitsInTime); ACTS_PYTHON_DECLARE_WRITER( ActsExamples::EDM4hepSimHitWriter, m, "EDM4hepSimHitWriter", inputSimHits, diff --git a/Examples/Python/src/Geant4Component.cpp b/Examples/Python/src/Geant4Component.cpp index 6bd75e18689..b366440c89f 100644 --- a/Examples/Python/src/Geant4Component.cpp +++ b/Examples/Python/src/Geant4Component.cpp @@ -258,15 +258,31 @@ PYBIND11_MODULE(ActsPythonBindingsGeant4, mod) { std::shared_ptr>( mod, "Geant4DetectorElement"); - using Detector = Geant4::Geant4Detector; - using Config = Detector::Config; + using Geant4Detector = Geant4::Geant4Detector; auto g = - py::class_>(mod, "Geant4Detector") - .def(py::init()); - - auto c = py::class_(g, "Config").def(py::init<>()); - ACTS_PYTHON_STRUCT_BEGIN(c, Config); + py::class_>( + mod, "Geant4Detector") + .def(py::init<>()) + .def( + "constructDetector", + [](Geant4Detector& self, const Geant4Detector::Config& cfg, + Logging::Level logLevel) { + auto logger = getDefaultLogger("Geant4Detector", logLevel); + return self.constructDetector(cfg, *logger); + }, + py::arg("cfg"), py::arg("logLevel") = Logging::INFO) + .def( + "constructTrackingGeometry", + [](Geant4Detector& self, const Geant4Detector::Config& cfg, + Logging::Level logLevel) { + auto logger = getDefaultLogger("Geant4Detector", logLevel); + return self.constructTrackingGeometry(cfg, *logger); + }, + py::arg("cfg"), py::arg("logLevel") = Logging::INFO); + + auto c = py::class_(g, "Config").def(py::init<>()); + ACTS_PYTHON_STRUCT_BEGIN(c, Geant4Detector::Config); ACTS_PYTHON_MEMBER(name); ACTS_PYTHON_MEMBER(g4World); ACTS_PYTHON_MEMBER(g4SurfaceOptions); From 43370af6c4d07147bbffc63c39dad36a005c8f1e Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Thu, 8 Aug 2024 15:01:53 +0200 Subject: [PATCH 17/32] draft --- .../DDG4/DDG4DetectorConstruction.hpp | 2 +- Examples/Detectors/CMakeLists.txt | 1 - .../Detectors/DD4hepDetector/CMakeLists.txt | 6 +- .../DD4hepDetector/DD4hepDetector.hpp | 172 ++++++++-------- .../DD4hepDetector/DD4hepGeometryService.hpp | 134 ++++++++++++ .../DD4hepDetector/src/DD4hepDetector.cpp | 190 +++++------------- .../src/DD4hepGeometryService.cpp | 183 +++++++++++++++++ .../ActsExamples/Io/EDM4hep/EDM4hepReader.hpp | 2 +- 8 files changed, 454 insertions(+), 236 deletions(-) create mode 100644 Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp create mode 100644 Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp index 378151e8043..95d251eed51 100644 --- a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp +++ b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp @@ -24,7 +24,7 @@ class Detector; namespace ActsExamples { namespace DD4hep { -class DD4hepDetector; +struct DD4hepDetector; } /// Construct the Geant4 detector from a DD4hep description. diff --git a/Examples/Detectors/CMakeLists.txt b/Examples/Detectors/CMakeLists.txt index cf12edad94b..a04112d572c 100644 --- a/Examples/Detectors/CMakeLists.txt +++ b/Examples/Detectors/CMakeLists.txt @@ -1,4 +1,3 @@ -add_subdirectory(Common) add_subdirectory(ContextualDetector) add_subdirectory_if(DD4hepDetector ACTS_BUILD_EXAMPLES_DD4HEP) add_subdirectory(GenericDetector) diff --git a/Examples/Detectors/DD4hepDetector/CMakeLists.txt b/Examples/Detectors/DD4hepDetector/CMakeLists.txt index c4cf00a80d1..1a335363871 100644 --- a/Examples/Detectors/DD4hepDetector/CMakeLists.txt +++ b/Examples/Detectors/DD4hepDetector/CMakeLists.txt @@ -1,6 +1,7 @@ add_library( ActsExamplesDetectorDD4hep SHARED - src/DD4hepDetector.cpp) + src/DD4hepDetector.cpp + src/DD4hepGeometryService.cpp) target_include_directories( ActsExamplesDetectorDD4hep @@ -10,8 +11,7 @@ target_link_libraries( PUBLIC ActsCore ActsPluginDD4hep - ActsExamplesFramework - ActsExamplesDetectorCommons) + ActsExamplesFramework) if(${DD4hep_VERSION} VERSION_LESS 1.11) target_include_directories(ActsExamplesDetectorDD4hep PUBLIC ${DD4hep_INCLUDE_DIRS}) diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp index 4cfe4636e6a..16c1e23eb49 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2017-2024 CERN for the benefit of the Acts project +// Copyright (C) 2018-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,109 +8,95 @@ #pragma once -#include "Acts/Definitions/Units.hpp" -#include "Acts/Geometry/GeometryContext.hpp" -#include "Acts/Geometry/GeometryIdentifier.hpp" -#include "Acts/Geometry/TrackingGeometry.hpp" -#include "Acts/Material/IMaterialDecorator.hpp" -#include "Acts/Utilities/BinningType.hpp" -#include "Acts/Utilities/Logger.hpp" -#include "ActsExamples/DetectorCommons/Detector.hpp" -#include "ActsExamples/Framework/ProcessCode.hpp" - -#include +#include "Acts/MagneticField/MagneticFieldProvider.hpp" +#include "Acts/Plugins/DD4hep/DD4hepDetectorElement.hpp" +#include "Acts/Plugins/DD4hep/DD4hepDetectorStructure.hpp" +#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" + #include -#include +#include +#include #include -#include -#include +namespace dd4hep { +class Detector; +} // namespace dd4hep + +namespace Acts { +class TrackingGeometry; +class IMaterialDecorator; +class DD4hepFieldAdapter; +namespace Experimental { +class Detector; +} // namespace Experimental +} // namespace Acts -class TGeoNode; +namespace ActsExamples { +class IContextDecorator; +} // namespace ActsExamples namespace ActsExamples::DD4hep { -void sortFCChhDetElements(std::vector& det); - -/// @class DD4hepDetector -/// -/// @brief geometries from dd4hep input -/// -/// The DD4hepDetector creates the DD4hep, the TGeo and the ACTS -/// TrackingGeometry from DD4hep xml input. The geometries are created only on -/// demand. -class DD4hepDetector : public DetectorCommons::Detector { - public: +struct DD4hepDetector { /// @brief The context decorators using ContextDecorators = std::vector>; - struct Config { - /// Log level for the geometry service. - Acts::Logging::Level logLevel = Acts::Logging::Level::INFO; - /// Log level for DD4hep itself - Acts::Logging::Level dd4hepLogLevel = Acts::Logging::Level::INFO; - /// XML-file with the detector description - std::vector xmlFileNames; - /// The name of the service - std::string name; - /// Binningtype in phi - Acts::BinningType bTypePhi = Acts::equidistant; - /// Binningtype in r - Acts::BinningType bTypeR = Acts::arbitrary; - /// Binningtype in z - Acts::BinningType bTypeZ = Acts::equidistant; - /// The tolerance added to the geometrical extension in r - /// of the layers contained to build the volume envelope around - /// @note this parameter only needs to be set if the volumes containing - /// the - /// layers (e.g. barrel, endcap volumes) have no specific shape - /// (assemblies) - double envelopeR = 1 * Acts::UnitConstants::mm; - /// The tolerance added to the geometrical extension in z - /// of the layers contained to build the volume envelope around - /// @note this parameter only needs to be set if the volumes containing - /// the layers (e.g. barrel, endcap volumes) have no specific shape - /// (assemblies) - double envelopeZ = 1 * Acts::UnitConstants::mm; - double defaultLayerThickness = 1e-10; - std::function& detectors)> - sortDetectors = sortFCChhDetElements; - /// Material decorator - std::shared_ptr materialDecorator; - - /// Optional geometry identifier hook to be used during closure - std::shared_ptr geometryIdentifierHook = - std::make_shared(); - }; - - explicit DD4hepDetector(const Config& cfg); - - /// Interface method to access to the DD4hep geometry - dd4hep::Detector& dd4hepDetector(); - - /// Interface method to access the DD4hep geometry - /// @return The world DD4hep DetElement - dd4hep::DetElement& dd4hepGeometry(); - - /// Interface method to Access the TGeo geometry - /// @return The world TGeoNode (physical volume) - TGeoNode& tgeoGeometry(); - - void drop() final; - - private: - /// Private method to initiate building of the DD4hep geometry - void buildDD4hepGeometry(); - - void buildTrackingGeometry() final; - - /// The config class - Config m_cfg; - /// Pointer to the interface to the DD4hep geometry - std::unique_ptr m_detector; - /// The world DD4hep DetElement - dd4hep::DetElement m_geometry; + /// @brief The tracking geometry + using TrackingGeometryPtr = std::shared_ptr; + + /// @brief The detector geometry + using DetectorPtr = std::shared_ptr; + + /// @brief Default constructor + DD4hepDetector() = default; + /// @brief Constructor from geometry service + /// @param _geometryService the geometry service + DD4hepDetector(std::shared_ptr _geometryService); + /// @brief Default destructor + ~DD4hepDetector() = default; + + /// @brief The DD4hep geometry service + std::shared_ptr geometryService = nullptr; + + dd4hep::Detector& dd4hepDetector() const { + return geometryService->detector(); + } + + dd4hep::DetElement& dd4hepGeometry() const { + return geometryService->geometry(); + } + + /// @brief Build the tracking geometry from the DD4hep geometry + /// + /// @param config is the configuration of the geometry service + /// @param mdecorator is the material decorator provided + /// + /// @return a pair of tracking geometry and context decorators + std::pair finalize( + DD4hepGeometryService::Config config, + std::shared_ptr mdecorator); + + /// @brief Build the detector from the DD4hep geometry + /// + /// @param gctx is the geometry context + /// @param options is the options struct for the building process + /// + /// @note the lifetime of the detector store has to exceed that of the + /// detector object as the converted surfaces point back to the + /// detector elements + /// + /// @return a tuple of detector, context decorators, and the element store + std::tuple + finalize( + const Acts::GeometryContext& gctx, + const Acts::Experimental::DD4hepDetectorStructure::Options& options = {}); + + void drop(); + + /// @brief Access to the DD4hep field + /// @return a shared pointer to the DD4hep field + std::shared_ptr field() const; }; } // namespace ActsExamples::DD4hep diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp new file mode 100644 index 00000000000..53f5b66465d --- /dev/null +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp @@ -0,0 +1,134 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2024 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/Geometry/GeometryIdentifier.hpp" +#include "ActsExamples/Framework/ProcessCode.hpp" +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +class TGeoNode; +namespace Acts { +class IMaterialDecorator; +class TrackingGeometry; +} // namespace Acts +namespace dd4hep { +class Detector; +} // namespace dd4hep + +namespace ActsExamples::DD4hep { + +void sortFCChhDetElements(std::vector& det); + +/// @class DD4hepGeometryService +/// +/// @brief service creating geometries from dd4hep input +/// +/// The DD4hepGeometryService creates the DD4hep, the TGeo and the ACTS +/// TrackingGeometry +/// from DD4hep xml input. The geometries are created only on demand. +class DD4hepGeometryService { + public: + struct Config { + /// Log level for the geometry service. + Acts::Logging::Level logLevel = Acts::Logging::Level::INFO; + /// Log level for DD4hep itself + Acts::Logging::Level dd4hepLogLevel = Acts::Logging::Level::INFO; + /// XML-file with the detector description + std::vector xmlFileNames; + /// The name of the service + std::string name; + /// Binningtype in phi + Acts::BinningType bTypePhi = Acts::equidistant; + /// Binningtype in r + Acts::BinningType bTypeR = Acts::arbitrary; + /// Binningtype in z + Acts::BinningType bTypeZ = Acts::equidistant; + /// The tolerance added to the geometrical extension in r + /// of the layers contained to build the volume envelope around + /// @note this parameter only needs to be set if the volumes containing + /// the + /// layers (e.g. barrel, endcap volumes) have no specific shape + /// (assemblies) + double envelopeR = 1 * Acts::UnitConstants::mm; + /// The tolerance added to the geometrical extension in z + /// of the layers contained to build the volume envelope around + /// @note this parameter only needs to be set if the volumes containing + /// the layers (e.g. barrel, endcap volumes) have no specific shape + /// (assemblies) + double envelopeZ = 1 * Acts::UnitConstants::mm; + double defaultLayerThickness = 10e-10; + std::function& detectors)> + sortDetectors = sortFCChhDetElements; + /// Material decorator + std::shared_ptr matDecorator; + + /// Optional geometry identifier hook to be used during closure + std::shared_ptr geometryIdentifierHook = + std::make_shared(); + }; + + DD4hepGeometryService(const Config& cfg); + ~DD4hepGeometryService(); + + /// Interface method to access to the DD4hep geometry + dd4hep::Detector& detector(); + + /// Interface method to access the DD4hep geometry + /// @return The world DD4hep DetElement + dd4hep::DetElement& geometry(); + + /// Interface method to Access the TGeo geometry + /// @return The world TGeoNode (physical volume) + TGeoNode& tgeoGeometry(); + + /// Interface method to access the ACTS TrackingGeometry + /// + /// @param gctx is the geometry context object + std::shared_ptr trackingGeometry( + const Acts::GeometryContext& gctx); + + void drop(); + + private: + /// Private method to initiate building of the DD4hep geometry + ActsExamples::ProcessCode buildDD4hepGeometry(); + + /// Private method to initiate building of the ACTS tracking geometry + ActsExamples::ProcessCode buildTrackingGeometry( + const Acts::GeometryContext& gctx); + + /// The config class + Config m_cfg; + /// Pointer to the interface to the DD4hep geometry + std::unique_ptr m_detector; + /// The world DD4hep DetElement + dd4hep::DetElement m_geometry; + /// The ACTS TrackingGeometry + std::shared_ptr m_trackingGeometry; + + const Acts::Logger& logger() const { return *m_logger; } + + std::unique_ptr m_logger; +}; + +} // namespace ActsExamples::DD4hep diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp index 03e72a95256..16bf14a1bf6 100644 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2017-2024 CERN for the benefit of the Acts project +// Copyright (C) 2019-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -9,162 +9,78 @@ #include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" #include "Acts/Geometry/GeometryContext.hpp" -#include "Acts/Geometry/TrackingGeometry.hpp" -#include "Acts/Plugins/DD4hep/ConvertDD4hepDetector.hpp" -#include "Acts/Utilities/Logger.hpp" -#include "ActsExamples/DetectorCommons/Detector.hpp" +#include "Acts/MagneticField/MagneticFieldProvider.hpp" +#include "Acts/Plugins/DD4hep/DD4hepFieldAdapter.hpp" +#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" -#include +#include #include #include -#include +#include +#include #include -#include -#include -#include -#include - -class TGeoNode; +#include +#include namespace ActsExamples::DD4hep { -DD4hepDetector::DD4hepDetector(const DD4hepDetector::Config& cfg) - : DetectorCommons::Detector( - Acts::getDefaultLogger("DD4hepDetector", cfg.logLevel)), - m_cfg(cfg) { - if (m_cfg.xmlFileNames.empty()) { - throw std::invalid_argument("Missing DD4hep XML filenames"); +DD4hepDetector::DD4hepDetector( + std::shared_ptr _geometryService) + : geometryService(std::move(_geometryService)) {} + +auto DD4hepDetector::finalize( + ActsExamples::DD4hep::DD4hepGeometryService::Config config, + std::shared_ptr mdecorator) + -> std::pair { + Acts::GeometryContext dd4HepContext; + config.matDecorator = std::move(mdecorator); + geometryService = + std::make_shared(config); + TrackingGeometryPtr dd4tGeometry = + geometryService->trackingGeometry(dd4HepContext); + if (!dd4tGeometry) { + throw std::runtime_error{ + "Did not receive tracking geometry from DD4hep geometry service"}; } + ContextDecorators dd4ContextDecorators = {}; + // return the pair of geometry and empty decorators + return std::make_pair( + std::move(dd4tGeometry), std::move(dd4ContextDecorators)); } -dd4hep::Detector& DD4hepDetector::DD4hepDetector::dd4hepDetector() { - if (m_detector == nullptr) { - buildDD4hepGeometry(); +auto DD4hepDetector::finalize( + const Acts::GeometryContext& gctx, + const Acts::Experimental::DD4hepDetectorStructure::Options& options) + -> std::tuple { + if (geometryService == nullptr) { + throw std::runtime_error{ + "No DD4hep geometry service configured, can not build " + "TrackingGeometry."}; } - return *m_detector; -} -dd4hep::DetElement& DD4hepDetector::dd4hepGeometry() { - if (!m_geometry) { - buildDD4hepGeometry(); - } - return m_geometry; -} + auto world = geometryService->geometry(); + // Build the detector structure + Acts::Experimental::DD4hepDetectorStructure dd4hepStructure( + Acts::getDefaultLogger("DD4hepDetectorStructure", options.logLevel)); -TGeoNode& DD4hepDetector::tgeoGeometry() { - if (!m_geometry) { - buildDD4hepGeometry(); - } - return *m_geometry.placement().ptr(); -} + /// @return a detector and the detector store + auto [detector, detectorElements] = + dd4hepStructure.construct(gctx, world, options); -void DD4hepDetector::buildDD4hepGeometry() { - const int old_gErrorIgnoreLevel = gErrorIgnoreLevel; - switch (m_cfg.dd4hepLogLevel) { - case Acts::Logging::Level::VERBOSE: - dd4hep::setPrintLevel(dd4hep::PrintLevel::VERBOSE); - break; - case Acts::Logging::Level::DEBUG: - dd4hep::setPrintLevel(dd4hep::PrintLevel::DEBUG); - break; - case Acts::Logging::Level::INFO: - dd4hep::setPrintLevel(dd4hep::PrintLevel::INFO); - break; - case Acts::Logging::Level::WARNING: - dd4hep::setPrintLevel(dd4hep::PrintLevel::WARNING); - gErrorIgnoreLevel = kWarning; - break; - case Acts::Logging::Level::ERROR: - dd4hep::setPrintLevel(dd4hep::PrintLevel::ERROR); - gErrorIgnoreLevel = kError; - break; - case Acts::Logging::Level::FATAL: - dd4hep::setPrintLevel(dd4hep::PrintLevel::FATAL); - gErrorIgnoreLevel = kFatal; - break; - case Acts::Logging::Level::MAX: - dd4hep::setPrintLevel(dd4hep::PrintLevel::ALWAYS); - break; - } - // completely silence std::cout as DD4HEP is using it for logging - if (m_cfg.dd4hepLogLevel >= Acts::Logging::Level::WARNING) { - std::cout.setstate(std::ios_base::failbit); - } + // Prepare the return objects + ContextDecorators contextDecorators = {}; - m_detector = dd4hep::Detector::make_unique(m_cfg.name); - for (auto& file : m_cfg.xmlFileNames) { - m_detector->fromCompact(file.c_str()); - } - m_detector->volumeManager(); - m_detector->apply("DD4hepVolumeManager", 0, nullptr); - m_geometry = m_detector->world(); - - // restore the logging - gErrorIgnoreLevel = old_gErrorIgnoreLevel; - std::cout.clear(); + return {detector, contextDecorators, detectorElements}; } -void DD4hepDetector::buildTrackingGeometry() { - if (m_detector == nullptr) { - buildDD4hepGeometry(); - } +void DD4hepDetector::drop() { geometryService->drop(); } - Acts::GeometryContext gctx; - auto logger = Acts::getDefaultLogger("DD4hepConversion", m_cfg.logLevel); - m_trackingGeometry = Acts::convertDD4hepDetector( - m_geometry, *logger, m_cfg.bTypePhi, m_cfg.bTypeR, m_cfg.bTypeZ, - m_cfg.envelopeR, m_cfg.envelopeZ, m_cfg.defaultLayerThickness, - m_cfg.sortDetectors, gctx, m_cfg.materialDecorator, - m_cfg.geometryIdentifierHook); -} +std::shared_ptr DD4hepDetector::field() const { + const auto& detector = geometryService->detector(); -void DD4hepDetector::drop() { - m_detector = nullptr; - m_geometry = dd4hep::DetElement(); - m_trackingGeometry.reset(); + return std::make_shared(detector.field()); } } // namespace ActsExamples::DD4hep - -void ActsExamples::DD4hep::sortFCChhDetElements( - std::vector& det) { - std::vector tracker; - std::vector eCal; - std::vector hCal; - std::vector muon; - for (auto& detElement : det) { - std::string detName = detElement.name(); - if (detName.find("Muon") != std::string::npos) { - muon.push_back(detElement); - } else if (detName.find("ECal") != std::string::npos) { - eCal.push_back(detElement); - } else if (detName.find("HCal") != std::string::npos) { - hCal.push_back(detElement); - } else { - tracker.push_back(detElement); - } - } - sort(muon.begin(), muon.end(), - [](const dd4hep::DetElement& a, const dd4hep::DetElement& b) { - return (a.id() < b.id()); - }); - sort(eCal.begin(), eCal.end(), - [](const dd4hep::DetElement& a, const dd4hep::DetElement& b) { - return (a.id() < b.id()); - }); - sort(hCal.begin(), hCal.end(), - [](const dd4hep::DetElement& a, const dd4hep::DetElement& b) { - return (a.id() < b.id()); - }); - sort(tracker.begin(), tracker.end(), - [](const dd4hep::DetElement& a, const dd4hep::DetElement& b) { - return (a.id() < b.id()); - }); - det.clear(); - det = tracker; - - det.insert(det.end(), eCal.begin(), eCal.end()); - det.insert(det.end(), hCal.begin(), hCal.end()); - det.insert(det.end(), muon.begin(), muon.end()); -} diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp new file mode 100644 index 00000000000..d6cb4f0c302 --- /dev/null +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp @@ -0,0 +1,183 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2017-2024 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp" + +#include "Acts/Geometry/TrackingGeometry.hpp" +#include "Acts/Plugins/DD4hep/ConvertDD4hepDetector.hpp" +#include "Acts/Utilities/Logger.hpp" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +class TGeoNode; + +ActsExamples::DD4hep::DD4hepGeometryService::DD4hepGeometryService( + const ActsExamples::DD4hep::DD4hepGeometryService::Config& cfg) + : m_cfg(cfg), + m_logger{Acts::getDefaultLogger("DD4hepGeometryService", cfg.logLevel)} { + if (m_cfg.xmlFileNames.empty()) { + throw std::invalid_argument("Missing DD4hep XML filenames"); + } +} + +ActsExamples::DD4hep::DD4hepGeometryService::~DD4hepGeometryService() { + if (m_detector != nullptr) { + m_detector->destroyInstance(); + } +} + +ActsExamples::ProcessCode +ActsExamples::DD4hep::DD4hepGeometryService::buildDD4hepGeometry() { + const int old_gErrorIgnoreLevel = gErrorIgnoreLevel; + switch (m_cfg.dd4hepLogLevel) { + case Acts::Logging::Level::VERBOSE: + dd4hep::setPrintLevel(dd4hep::PrintLevel::VERBOSE); + break; + case Acts::Logging::Level::DEBUG: + dd4hep::setPrintLevel(dd4hep::PrintLevel::DEBUG); + break; + case Acts::Logging::Level::INFO: + dd4hep::setPrintLevel(dd4hep::PrintLevel::INFO); + break; + case Acts::Logging::Level::WARNING: + dd4hep::setPrintLevel(dd4hep::PrintLevel::WARNING); + gErrorIgnoreLevel = kWarning; + break; + case Acts::Logging::Level::ERROR: + dd4hep::setPrintLevel(dd4hep::PrintLevel::ERROR); + gErrorIgnoreLevel = kError; + break; + case Acts::Logging::Level::FATAL: + dd4hep::setPrintLevel(dd4hep::PrintLevel::FATAL); + gErrorIgnoreLevel = kFatal; + break; + case Acts::Logging::Level::MAX: + dd4hep::setPrintLevel(dd4hep::PrintLevel::ALWAYS); + break; + } + // completely silence std::cout as DD4HEP is using it for logging + if (m_cfg.dd4hepLogLevel >= Acts::Logging::Level::WARNING) { + std::cout.setstate(std::ios_base::failbit); + } + + m_detector = dd4hep::Detector::make_unique(m_cfg.name); + for (auto& file : m_cfg.xmlFileNames) { + m_detector->fromCompact(file.c_str()); + } + m_detector->volumeManager(); + m_detector->apply("DD4hepVolumeManager", 0, nullptr); + m_geometry = m_detector->world(); + + // restore the logging + gErrorIgnoreLevel = old_gErrorIgnoreLevel; + std::cout.clear(); + + return ActsExamples::ProcessCode::SUCCESS; +} + +dd4hep::Detector& +ActsExamples::DD4hep::DD4hepGeometryService::DD4hepGeometryService::detector() { + if (m_detector == nullptr) { + buildDD4hepGeometry(); + } + return *m_detector; +} + +dd4hep::DetElement& ActsExamples::DD4hep::DD4hepGeometryService::geometry() { + if (!m_geometry) { + buildDD4hepGeometry(); + } + return m_geometry; +} + +TGeoNode& ActsExamples::DD4hep::DD4hepGeometryService::tgeoGeometry() { + if (!m_geometry) { + buildDD4hepGeometry(); + } + return *m_geometry.placement().ptr(); +} + +ActsExamples::ProcessCode +ActsExamples::DD4hep::DD4hepGeometryService::buildTrackingGeometry( + const Acts::GeometryContext& gctx) { + // Set the tracking geometry + auto logger = Acts::getDefaultLogger("DD4hepConversion", m_cfg.logLevel); + m_trackingGeometry = Acts::convertDD4hepDetector( + geometry(), *logger, m_cfg.bTypePhi, m_cfg.bTypeR, m_cfg.bTypeZ, + m_cfg.envelopeR, m_cfg.envelopeZ, m_cfg.defaultLayerThickness, + m_cfg.sortDetectors, gctx, m_cfg.matDecorator, + m_cfg.geometryIdentifierHook); + return ActsExamples::ProcessCode::SUCCESS; +} + +std::shared_ptr +ActsExamples::DD4hep::DD4hepGeometryService::trackingGeometry( + const Acts::GeometryContext& gctx) { + if (!m_trackingGeometry) { + buildTrackingGeometry(gctx); + } + return m_trackingGeometry; +} + +void ActsExamples::DD4hep::DD4hepGeometryService::drop() { + m_detector->destroyInstance(); + m_detector = nullptr; + m_geometry = dd4hep::DetElement(); + m_trackingGeometry = nullptr; +} + +void ActsExamples::DD4hep::sortFCChhDetElements( + std::vector& det) { + std::vector tracker; + std::vector eCal; + std::vector hCal; + std::vector muon; + for (auto& detElement : det) { + std::string detName = detElement.name(); + if (detName.find("Muon") != std::string::npos) { + muon.push_back(detElement); + } else if (detName.find("ECal") != std::string::npos) { + eCal.push_back(detElement); + } else if (detName.find("HCal") != std::string::npos) { + hCal.push_back(detElement); + } else { + tracker.push_back(detElement); + } + } + sort(muon.begin(), muon.end(), + [](const dd4hep::DetElement& a, const dd4hep::DetElement& b) { + return (a.id() < b.id()); + }); + sort(eCal.begin(), eCal.end(), + [](const dd4hep::DetElement& a, const dd4hep::DetElement& b) { + return (a.id() < b.id()); + }); + sort(hCal.begin(), hCal.end(), + [](const dd4hep::DetElement& a, const dd4hep::DetElement& b) { + return (a.id() < b.id()); + }); + sort(tracker.begin(), tracker.end(), + [](const dd4hep::DetElement& a, const dd4hep::DetElement& b) { + return (a.id() < b.id()); + }); + det.clear(); + det = tracker; + + det.insert(det.end(), eCal.begin(), eCal.end()); + det.insert(det.end(), hCal.begin(), hCal.end()); + det.insert(det.end(), muon.begin(), muon.end()); +} diff --git a/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp b/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp index 909a2bb37a5..51c716aaa4b 100644 --- a/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp +++ b/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepReader.hpp @@ -27,7 +27,7 @@ namespace ActsExamples { namespace DD4hep { -class DD4hepDetector; +struct DD4hepDetector; } /// Read particles from EDM4hep. From 42591c0ece221a845709856f2f7887ecc3415c43 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Thu, 8 Aug 2024 15:23:36 +0200 Subject: [PATCH 18/32] clean --- .../DDG4/DDG4DetectorConstruction.hpp | 1 - .../Python/python/acts/examples/dd4hep.py | 2 +- Examples/Python/python/acts/examples/odd.py | 29 +++++++++---------- Examples/Python/src/Geant4DD4hepComponent.cpp | 2 +- Examples/Python/tests/conftest.py | 15 +++------- Examples/Python/tests/test_detectors.py | 4 +-- Examples/Python/tests/test_examples.py | 16 ++++------ Examples/Python/tests/test_reader.py | 4 +-- Examples/Scripts/Python/event_recording.py | 2 +- Examples/Scripts/Python/full_chain_odd.py | 2 +- Examples/Scripts/Python/geant4.py | 2 +- Examples/Scripts/Python/geant4_parallel.py | 2 +- Examples/Scripts/Python/geometry.py | 6 ++-- Examples/Scripts/Python/material_recording.py | 2 +- Examples/Scripts/Python/seeding.py | 6 ++-- Examples/Scripts/Python/truth_tracking_gsf.py | 2 +- .../Python/truth_tracking_gsf_refitting.py | 6 ++-- .../Scripts/Python/truth_tracking_gx2f.py | 2 +- .../Scripts/Python/truth_tracking_kalman.py | 2 +- docs/examples/howto/material_mapping.rst | 2 +- 20 files changed, 45 insertions(+), 64 deletions(-) diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp index 95d251eed51..6e2e6c9389c 100644 --- a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp +++ b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp @@ -8,7 +8,6 @@ #pragma once -#include "ActsExamples/DD4hepDetector/DD4hepDetector.hpp" #include "ActsExamples/Geant4/DetectorConstructionFactory.hpp" #include "ActsExamples/Geant4/RegionCreator.hpp" diff --git a/Examples/Python/python/acts/examples/dd4hep.py b/Examples/Python/python/acts/examples/dd4hep.py index 3affbc00be8..f68dc38453a 100644 --- a/Examples/Python/python/acts/examples/dd4hep.py +++ b/Examples/Python/python/acts/examples/dd4hep.py @@ -18,7 +18,7 @@ _patch_config(ActsPythonBindingsDD4hep) ActsPythonBindingsDD4hep.DD4hepDetector.create = _detector_create( ActsPythonBindingsDD4hep.DD4hepDetector, - ActsPythonBindingsDD4hep.DD4hepDetector.Config, + ActsPythonBindingsDD4hep.DD4hepGeometryService.Config, ) from acts.ActsPythonBindingsDD4hep import * diff --git a/Examples/Python/python/acts/examples/odd.py b/Examples/Python/python/acts/examples/odd.py index 0a62967d462..9fb1a41f5fc 100644 --- a/Examples/Python/python/acts/examples/odd.py +++ b/Examples/Python/python/acts/examples/odd.py @@ -85,31 +85,28 @@ def geoid_hook(geoid, surface): return geoid - if mdecorator is None: - mdecorator = acts.examples.RootMaterialDecorator( - fileName=str(odd_dir / "data/odd-material-maps.root"), - level=customLogLevel(minLevel=acts.logging.WARNING), - ) - - dd4hepConfig = acts.examples.dd4hep.DD4hepDetector.Config( + dd4hepConfig = acts.examples.dd4hep.DD4hepGeometryService.Config( xmlFileNames=[str(odd_xml)], logLevel=customLogLevel(), dd4hepLogLevel=customLogLevel(), geometryIdentifierHook=acts.GeometryIdentifierHook(geoid_hook), - materialDecorator=mdecorator, ) - detector = acts.examples.dd4hep.DD4hepDetector(dd4hepConfig) + detector = acts.examples.dd4hep.DD4hepDetector() - trackingGeometry, decorators, _ = detector.trackingGeometry() + if mdecorator is None: + mdecorator = acts.examples.RootMaterialDecorator( + fileName=str(odd_dir / "data/odd-material-maps.root"), + level=customLogLevel(minLevel=acts.logging.WARNING), + ) + + trackingGeometry, deco = detector.finalize(dd4hepConfig, mdecorator) - class ContextManager: + class DetectorAdapter: def __init__(self, detector): - self.detector = detector + self.__detector = detector def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): - self.detector.drop() - - contextManager = ContextManager(detector) + return self.__detector.drop() - return detector, trackingGeometry, decorators, contextManager + return DetectorAdapter(detector), trackingGeometry, deco diff --git a/Examples/Python/src/Geant4DD4hepComponent.cpp b/Examples/Python/src/Geant4DD4hepComponent.cpp index 2e0f9b4143d..cf2f5a87b8c 100644 --- a/Examples/Python/src/Geant4DD4hepComponent.cpp +++ b/Examples/Python/src/Geant4DD4hepComponent.cpp @@ -30,7 +30,7 @@ PYBIND11_MODULE(ActsPythonBindingsDDG4, m) { m, "DDG4DetectorConstructionFactory") .def(py::init, std::vector>>(), - py::arg("geometryService"), + py::arg("detector"), py::arg("regionCreators") = std::vector>()); } diff --git a/Examples/Python/tests/conftest.py b/Examples/Python/tests/conftest.py index 43ffafecc88..dbc775745f9 100644 --- a/Examples/Python/tests/conftest.py +++ b/Examples/Python/tests/conftest.py @@ -231,7 +231,6 @@ def trk_geo(): "detector", "trackingGeometry", "decorators", - "contextManager", "geometrySelection", "digiConfigFile", "name", @@ -244,14 +243,11 @@ def detector_config(request): srcdir = Path(__file__).resolve().parent.parent.parent.parent if request.param == "generic": - detector, trackingGeometry, decorators, contextManager = ( - acts.examples.GenericDetector.create() - ) + detector, trackingGeometry, decorators = acts.examples.GenericDetector.create() return DetectorConfig( detector, trackingGeometry, decorators, - contextManager, geometrySelection=( srcdir / "Examples/Algorithms/TrackFinding/share/geoSelection-genericDetector.json" @@ -270,14 +266,11 @@ def detector_config(request): srcdir / "thirdparty/OpenDataDetector/data/odd-material-maps.root", level=acts.logging.INFO, ) - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector( - matDeco - ) + detector, trackingGeometry, decorators = getOpenDataDetector(matDeco) return DetectorConfig( detector, trackingGeometry, decorators, - contextManager, digiConfigFile=( srcdir / "thirdparty/OpenDataDetector/config/odd-digi-smearing-config.json" @@ -373,9 +366,9 @@ def _do_material_recording(d: Path): s = acts.examples.Sequencer(events=2, numThreads=1) - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + detector, trackingGeometry, decorators = getOpenDataDetector() - with contextManager: + with detector: detectorConstructionFactory = ( acts.examples.geant4.dd4hep.DDG4DetectorConstructionFactory(detector) ) diff --git a/Examples/Python/tests/test_detectors.py b/Examples/Python/tests/test_detectors.py index 0f2278da3da..06b7e677334 100644 --- a/Examples/Python/tests/test_detectors.py +++ b/Examples/Python/tests/test_detectors.py @@ -53,9 +53,9 @@ def test_telescope_geometry(): @pytest.mark.skipif(not dd4hepEnabled, reason="DD4hep is not set up") def test_odd(): - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + detector, trackingGeometry, decorators = getOpenDataDetector() - with contextManager: + with detector: trackingGeometry.visitSurfaces(check_extra_odd) assert count_surfaces(trackingGeometry) == 18824 diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index eeec75cae53..360e81b852a 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -143,8 +143,8 @@ def test_geant4(tmp_path, assert_root_hash): # This test literally only ensures that the geant 4 example can run without erroring out # just to make sure it can build the odd - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() - with contextManager: + detector, trackingGeometry, decorators = getOpenDataDetector() + with detector: pass csv = tmp_path / "csv" @@ -1108,8 +1108,8 @@ def test_full_chain_odd_example(tmp_path): # This test literally only ensures that the full chain example can run without erroring out # just to make sure it can build the odd - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() - with contextManager: + detector, trackingGeometry, decorators = getOpenDataDetector() + with detector: pass script = ( @@ -1142,9 +1142,7 @@ def test_full_chain_odd_example_pythia_geant4(tmp_path): # This test literally only ensures that the full chain example can run without erroring out # just to make sure it can build the odd - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() - with contextManager: - pass + detector, trackingGeometry, decorators = getOpenDataDetector() script = ( Path(__file__).parent.parent.parent.parent @@ -1197,9 +1195,7 @@ def test_ML_Ambiguity_Solver(tmp_path, assert_root_hash): assert not (tmp_path / root_file).exists() # just to make sure it can build the odd - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() - with contextManager: - pass + detector, trackingGeometry, decorators = getOpenDataDetector() script = ( Path(__file__).parent.parent.parent.parent diff --git a/Examples/Python/tests/test_reader.py b/Examples/Python/tests/test_reader.py index 1bb39a3c7db..08f4b5aedfe 100644 --- a/Examples/Python/tests/test_reader.py +++ b/Examples/Python/tests/test_reader.py @@ -298,9 +298,9 @@ def test_edm4hep_simhit_particle_reader(tmp_path): s = Sequencer(numThreads=1) - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + detector, trackingGeometry, decorators = getOpenDataDetector() - with contextManager: + with detector: s.addReader( EDM4hepReader( level=acts.logging.INFO, diff --git a/Examples/Scripts/Python/event_recording.py b/Examples/Scripts/Python/event_recording.py index c1e43c1db5d..04cbb135dbe 100755 --- a/Examples/Scripts/Python/event_recording.py +++ b/Examples/Scripts/Python/event_recording.py @@ -76,7 +76,7 @@ def runEventRecording(detectorConstructionFactory, outputDir, s=None): if "__main__" == __name__: - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + detector, trackingGeometry, decorators = getOpenDataDetector() detectorConstructionFactory = ( acts.examples.geant4.dd4hep.DDG4DetectorConstructionFactory(detector) diff --git a/Examples/Scripts/Python/full_chain_odd.py b/Examples/Scripts/Python/full_chain_odd.py index 10690e9a5ed..0c6b5fd1f38 100755 --- a/Examples/Scripts/Python/full_chain_odd.py +++ b/Examples/Scripts/Python/full_chain_odd.py @@ -161,7 +161,7 @@ oddSeedingSel = geoDir / "config/odd-seeding-config.json" oddMaterialDeco = acts.IMaterialDecorator.fromFile(oddMaterialMap) -detector, trackingGeometry, decorators, contextManager = getOpenDataDetector( +detector, trackingGeometry, decorators = getOpenDataDetector( odd_dir=geoDir, mdecorator=oddMaterialDeco ) field = acts.ConstantBField(acts.Vector3(0.0, 0.0, 2.0 * u.T)) diff --git a/Examples/Scripts/Python/geant4.py b/Examples/Scripts/Python/geant4.py index 29fb53ddc1b..eb636c43bdd 100755 --- a/Examples/Scripts/Python/geant4.py +++ b/Examples/Scripts/Python/geant4.py @@ -76,5 +76,5 @@ def runGeant4( [detector, contextors, store] = dd4hepDetector.finalize(geoContext, cOptions) runGeant4(detector, detector, field, Path.cwd()).run() else: - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + detector, trackingGeometry, decorators = getOpenDataDetector() runGeant4(detector, trackingGeometry, field, Path.cwd()).run() diff --git a/Examples/Scripts/Python/geant4_parallel.py b/Examples/Scripts/Python/geant4_parallel.py index 6f195f9b70c..d9a8f59f8c2 100755 --- a/Examples/Scripts/Python/geant4_parallel.py +++ b/Examples/Scripts/Python/geant4_parallel.py @@ -61,7 +61,7 @@ def runGeant4EventRange(detector, trackingGeometry, beginEvent, endEvent, output if "__main__" == __name__: from acts.examples.odd import getOpenDataDetector - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + detector, trackingGeometry, decorators = getOpenDataDetector() n_events = 100 n_jobs = 8 diff --git a/Examples/Scripts/Python/geometry.py b/Examples/Scripts/Python/geometry.py index cd4d894776b..396fec3151a 100755 --- a/Examples/Scripts/Python/geometry.py +++ b/Examples/Scripts/Python/geometry.py @@ -90,9 +90,9 @@ def runGeometry( if "__main__" == __name__: - # detector, trackingGeometry, decorators, contextManager = AlignedDetector.create() - # detector, trackingGeometry, decorators, contextManager = GenericDetector.create() - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + # detector, trackingGeometry, decorators = AlignedDetector.create() + # detector, trackingGeometry, decorators = GenericDetector.create() + detector, trackingGeometry, decorators = getOpenDataDetector() runGeometry(trackingGeometry, decorators, outputDir=os.getcwd()) diff --git a/Examples/Scripts/Python/material_recording.py b/Examples/Scripts/Python/material_recording.py index c91bc32fca2..f52bb8b2ab2 100755 --- a/Examples/Scripts/Python/material_recording.py +++ b/Examples/Scripts/Python/material_recording.py @@ -104,7 +104,7 @@ def main(): detectorConstructionFactory = None if args.input == "": - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + detector, trackingGeometry, decorators = getOpenDataDetector() detectorConstructionFactory = ( acts.examples.geant4.dd4hep.DDG4DetectorConstructionFactory(detector) diff --git a/Examples/Scripts/Python/seeding.py b/Examples/Scripts/Python/seeding.py index afca1567e98..4c87ba9b82b 100755 --- a/Examples/Scripts/Python/seeding.py +++ b/Examples/Scripts/Python/seeding.py @@ -147,10 +147,8 @@ def runSeeding( ) args = p.parse_args() - # detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() - detector, trackingGeometry, decorators, contextManager = ( - acts.examples.GenericDetector.create() - ) + # detector, trackingGeometry, decorators = getOpenDataDetector() + detector, trackingGeometry, decorators = acts.examples.GenericDetector.create() field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T)) diff --git a/Examples/Scripts/Python/truth_tracking_gsf.py b/Examples/Scripts/Python/truth_tracking_gsf.py index 69e5fa829a2..82c99bb38aa 100755 --- a/Examples/Scripts/Python/truth_tracking_gsf.py +++ b/Examples/Scripts/Python/truth_tracking_gsf.py @@ -160,7 +160,7 @@ def runTruthTrackingGsf( # ODD from acts.examples.odd import getOpenDataDetector - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + detector, trackingGeometry, decorators = getOpenDataDetector() digiConfigFile = ( srcdir / "thirdparty/OpenDataDetector/config/odd-digi-smearing-config.json" ) diff --git a/Examples/Scripts/Python/truth_tracking_gsf_refitting.py b/Examples/Scripts/Python/truth_tracking_gsf_refitting.py index 64e94617790..138540db2af 100755 --- a/Examples/Scripts/Python/truth_tracking_gsf_refitting.py +++ b/Examples/Scripts/Python/truth_tracking_gsf_refitting.py @@ -97,10 +97,8 @@ def runRefittingGsf( if __name__ == "__main__": outputDir = Path.cwd() - # detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() - detector, trackingGeometry, decorators, contextManager = ( - acts.examples.GenericDetector.create() - ) + # detector, trackingGeometry, decorators = getOpenDataDetector() + detector, trackingGeometry, decorators = acts.examples.GenericDetector.create() field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T)) runRefittingGsf(trackingGeometry, field, outputDir).run() diff --git a/Examples/Scripts/Python/truth_tracking_gx2f.py b/Examples/Scripts/Python/truth_tracking_gx2f.py index a38f4091438..e20795b7010 100644 --- a/Examples/Scripts/Python/truth_tracking_gx2f.py +++ b/Examples/Scripts/Python/truth_tracking_gx2f.py @@ -159,7 +159,7 @@ def runTruthTrackingGx2f( # ODD from acts.examples.odd import getOpenDataDetector - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + detector, trackingGeometry, decorators = getOpenDataDetector() digiConfigFile = ( srcdir / "thirdparty/OpenDataDetector/config/odd-digi-smearing-config.json" ) diff --git a/Examples/Scripts/Python/truth_tracking_kalman.py b/Examples/Scripts/Python/truth_tracking_kalman.py index 051e4f66467..83d189c6bd6 100755 --- a/Examples/Scripts/Python/truth_tracking_kalman.py +++ b/Examples/Scripts/Python/truth_tracking_kalman.py @@ -163,7 +163,7 @@ def runTruthTrackingKalman( # ODD from acts.examples.odd import getOpenDataDetector - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + detector, trackingGeometry, decorators = getOpenDataDetector() digiConfigFile = ( srcdir / "thirdparty/OpenDataDetector/config/odd-digi-smearing-config.json" ) diff --git a/docs/examples/howto/material_mapping.rst b/docs/examples/howto/material_mapping.rst index ff870028dfa..a8657a470a6 100644 --- a/docs/examples/howto/material_mapping.rst +++ b/docs/examples/howto/material_mapping.rst @@ -55,7 +55,7 @@ For the following example we will be remapping the material of the ODD, we will .. code-block:: console - detector, trackingGeometry, decorators, contextManager = getOpenDataDetector() + detector, trackingGeometry, decorators = getOpenDataDetector() This algorithm is useful to obtain a visualisation of your detector using the different types of output available (``output-obj`` gives ``.obj`` with a 3D representation of the different subdetectors, for example). Here, we use ``output-json`` to obtain a map of all the surfaces and volumes in the detector with a ``ProtoSurfaceMaterial`` (or a ``ProtoVolumeMaterial``), ``mat-output-allmaterial`` ensure that a ``ProtoSurfaceMaterial`` (or a ``ProtoVolumeMaterial``) is associated to all the surfaces (or volumes), enforcing all of them to be written. Four types of surfaces exist: From 12b7f58bdb94136d26d6ad0659e8739071699d56 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Thu, 8 Aug 2024 16:07:43 +0200 Subject: [PATCH 19/32] fix --- Examples/Io/EDM4hep/src/EDM4hepReader.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Examples/Io/EDM4hep/src/EDM4hepReader.cpp b/Examples/Io/EDM4hep/src/EDM4hepReader.cpp index cc19104ac49..02e3148b346 100644 --- a/Examples/Io/EDM4hep/src/EDM4hepReader.cpp +++ b/Examples/Io/EDM4hep/src/EDM4hepReader.cpp @@ -325,7 +325,8 @@ ProcessCode EDM4hepReader::read(const AlgorithmContext& ctx) { [&](std::uint64_t cellId) { ACTS_VERBOSE("CellID: " << cellId); - const auto& vm = m_cfg.dd4hepDetector->detector().volumeManager(); + const auto& vm = + m_cfg.dd4hepDetector->dd4hepDetector().volumeManager(); const auto detElement = vm.lookupDetElement(cellId); From c95d907d4968e7030935b35d4f075e3523918cb3 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Thu, 8 Aug 2024 16:29:56 +0200 Subject: [PATCH 20/32] format --- Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp | 4 +++- Examples/Python/python/acts/examples/odd.py | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp index 16bf14a1bf6..e3b607d5fc5 100644 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepDetector.cpp @@ -75,7 +75,9 @@ auto DD4hepDetector::finalize( return {detector, contextDecorators, detectorElements}; } -void DD4hepDetector::drop() { geometryService->drop(); } +void DD4hepDetector::drop() { + geometryService->drop(); +} std::shared_ptr DD4hepDetector::field() const { const auto& detector = geometryService->detector(); diff --git a/Examples/Python/python/acts/examples/odd.py b/Examples/Python/python/acts/examples/odd.py index 9fb1a41f5fc..e3afada0965 100644 --- a/Examples/Python/python/acts/examples/odd.py +++ b/Examples/Python/python/acts/examples/odd.py @@ -104,8 +104,10 @@ def geoid_hook(geoid, surface): class DetectorAdapter: def __init__(self, detector): self.__detector = detector + def __enter__(self): return self + def __exit__(self, exc_type, exc_val, exc_tb): return self.__detector.drop() From df77555ffdbc2c57963ab213f8da6236eaa1aed5 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Fri, 9 Aug 2024 00:16:41 +0200 Subject: [PATCH 21/32] fix --- Examples/Python/tests/test_examples.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index 360e81b852a..3eec27516bc 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -535,7 +535,7 @@ def test_truth_tracking_kalman( assert not fp.exists() print("with") - with detector_config.contextManager: + with detector_config.detector: from truth_tracking_kalman import runTruthTrackingKalman field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T)) @@ -600,7 +600,7 @@ def test_truth_tracking_gsf(tmp_path, assert_root_hash, detector_config): fp = tmp_path / fn assert not fp.exists() - with detector_config.contextManager: + with detector_config.detector: runTruthTrackingGsf( trackingGeometry=detector_config.trackingGeometry, decorators=detector_config.decorators, @@ -632,7 +632,7 @@ def test_refitting(tmp_path, detector_config, assert_root_hash): numThreads=1, ) - with detector_config.contextManager: + with detector_config.detector: # Only check if it runs without errors right known # Changes in fitter behaviour should be caught by other tests runRefittingGsf( @@ -1072,7 +1072,7 @@ def test_ckf_tracks_example( from ckf_tracks import runCKFTracks - with detector_config.contextManager: + with detector_config.detector: runCKFTracks( detector_config.trackingGeometry, detector_config.decorators, From 1b73a1d21260d76d26f751f10b2bb1f7734c0bfe Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Fri, 9 Aug 2024 10:05:37 +0200 Subject: [PATCH 22/32] avoid double delete --- .../ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp | 1 - .../Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp | 7 ------- 2 files changed, 8 deletions(-) diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp index 53f5b66465d..61d805b3ad5 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp @@ -88,7 +88,6 @@ class DD4hepGeometryService { }; DD4hepGeometryService(const Config& cfg); - ~DD4hepGeometryService(); /// Interface method to access to the DD4hep geometry dd4hep::Detector& detector(); diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp index d6cb4f0c302..b7ee5f508e8 100644 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp @@ -34,12 +34,6 @@ ActsExamples::DD4hep::DD4hepGeometryService::DD4hepGeometryService( } } -ActsExamples::DD4hep::DD4hepGeometryService::~DD4hepGeometryService() { - if (m_detector != nullptr) { - m_detector->destroyInstance(); - } -} - ActsExamples::ProcessCode ActsExamples::DD4hep::DD4hepGeometryService::buildDD4hepGeometry() { const int old_gErrorIgnoreLevel = gErrorIgnoreLevel; @@ -134,7 +128,6 @@ ActsExamples::DD4hep::DD4hepGeometryService::trackingGeometry( } void ActsExamples::DD4hep::DD4hepGeometryService::drop() { - m_detector->destroyInstance(); m_detector = nullptr; m_geometry = dd4hep::DetElement(); m_trackingGeometry = nullptr; From bec084ebd886271eaba4ac28d2b2e94fc518ab85 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Fri, 9 Aug 2024 10:30:31 +0200 Subject: [PATCH 23/32] bind drop --- Examples/Python/src/DD4hepComponent.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Examples/Python/src/DD4hepComponent.cpp b/Examples/Python/src/DD4hepComponent.cpp index 091842f6783..223e9fec7f9 100644 --- a/Examples/Python/src/DD4hepComponent.cpp +++ b/Examples/Python/src/DD4hepComponent.cpp @@ -36,11 +36,12 @@ using namespace Acts::Python; PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { { - using Config = ActsExamples::DD4hep::DD4hepGeometryService::Config; + using Config = DD4hep::DD4hepGeometryService::Config; auto s = py::class_>( m, "DD4hepGeometryService") - .def(py::init()); + .def(py::init()) + .def("drop", &DD4hep::DD4hepGeometryService::drop); auto c = py::class_(s, "Config").def(py::init<>()); ACTS_PYTHON_STRUCT_BEGIN(c, Config); @@ -167,6 +168,7 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { const Acts::GeometryContext&, const Acts::Experimental::DD4hepDetectorStructure::Options&>( &DD4hep::DD4hepDetector::finalize)) + .def("drop", &DD4hep::DD4hepDetector::drop) .def_property_readonly("field", &DD4hep::DD4hepDetector::field); } } From c915037ca0ba048f4aa65288f8ac8981adb8db27 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Fri, 9 Aug 2024 10:54:55 +0200 Subject: [PATCH 24/32] patch detectors for context management --- Examples/Python/python/acts/_adapter.py | 6 ++++++ Examples/Python/python/acts/examples/dd4hep.py | 3 ++- Examples/Python/python/acts/examples/odd.py | 14 ++------------ 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/Examples/Python/python/acts/_adapter.py b/Examples/Python/python/acts/_adapter.py index 112fbf7f631..15e3d84a015 100644 --- a/Examples/Python/python/acts/_adapter.py +++ b/Examples/Python/python/acts/_adapter.py @@ -126,3 +126,9 @@ def _patch_detectors(m): for name, cls in inspect.getmembers(m, inspect.isclass): if name.endswith("Detector"): cls.create = _detector_create(cls) + + cls.__enter__ = lambda self: self + if hasattr(cls, "drop"): + cls.__exit__ = lambda self, *args: self.drop() + else: + cls.__exit__ = lambda self, *args: None diff --git a/Examples/Python/python/acts/examples/dd4hep.py b/Examples/Python/python/acts/examples/dd4hep.py index f68dc38453a..cd23533dfda 100644 --- a/Examples/Python/python/acts/examples/dd4hep.py +++ b/Examples/Python/python/acts/examples/dd4hep.py @@ -12,10 +12,11 @@ print("Error encountered importing DD4hep. Likely you need to set LD_LIBRARY_PATH.") sys.exit(1) -from acts._adapter import _patch_config, _detector_create +from acts._adapter import _patch_config, _detector_create, _patch_detectors from acts import ActsPythonBindingsDD4hep _patch_config(ActsPythonBindingsDD4hep) +_patch_detectors(ActsPythonBindingsDD4hep) ActsPythonBindingsDD4hep.DD4hepDetector.create = _detector_create( ActsPythonBindingsDD4hep.DD4hepDetector, ActsPythonBindingsDD4hep.DD4hepGeometryService.Config, diff --git a/Examples/Python/python/acts/examples/odd.py b/Examples/Python/python/acts/examples/odd.py index e3afada0965..b5d1b4c42a7 100644 --- a/Examples/Python/python/acts/examples/odd.py +++ b/Examples/Python/python/acts/examples/odd.py @@ -99,16 +99,6 @@ def geoid_hook(geoid, surface): level=customLogLevel(minLevel=acts.logging.WARNING), ) - trackingGeometry, deco = detector.finalize(dd4hepConfig, mdecorator) + trackingGeometry, decorators = detector.finalize(dd4hepConfig, mdecorator) - class DetectorAdapter: - def __init__(self, detector): - self.__detector = detector - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - return self.__detector.drop() - - return DetectorAdapter(detector), trackingGeometry, deco + return detector, trackingGeometry, decorators From 2553c8538b52532e18725b2c2bb0296328b8de23 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Fri, 9 Aug 2024 13:56:49 +0200 Subject: [PATCH 25/32] revert some changes --- .../ActsExamples/DDG4/DDG4DetectorConstruction.hpp | 1 - .../Geant4/src/DDG4DetectorConstruction.cpp | 14 ++++++-------- .../ActsExamples/DD4hepDetector/DD4hepDetector.hpp | 8 -------- .../DD4hepDetector/DD4hepGeometryService.hpp | 2 +- .../DD4hepDetector/src/DD4hepGeometryService.cpp | 2 +- Examples/Io/EDM4hep/src/EDM4hepReader.cpp | 4 ++-- 6 files changed, 10 insertions(+), 21 deletions(-) diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp index 6e2e6c9389c..a66b4d0c319 100644 --- a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp +++ b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp @@ -57,7 +57,6 @@ class DDG4DetectorConstructionFactory final DDG4DetectorConstructionFactory( std::shared_ptr detector, std::vector> regionCreators = {}); - ~DDG4DetectorConstructionFactory() final; std::unique_ptr factorize() const override; diff --git a/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp b/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp index c400b67761a..bb64446e158 100644 --- a/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp +++ b/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp @@ -34,13 +34,13 @@ DDG4DetectorConstruction::DDG4DetectorConstruction( G4VPhysicalVolume* DDG4DetectorConstruction::Construct() { if (m_world == nullptr) { dd4hep::sim::Geant4Mapping& g4map = dd4hep::sim::Geant4Mapping::instance(); - auto conv = dd4hep::sim::Geant4Converter(m_detector->dd4hepDetector(), - dd4hep::PrintLevel::VERBOSE); - dd4hep::sim::Geant4GeometryInfo* geo_info = - conv.create(m_detector->dd4hepGeometry()).detach(); - g4map.attach(geo_info); + auto conv = dd4hep::sim::Geant4Converter( + m_detector->geometryService->detector(), dd4hep::PrintLevel::VERBOSE); + dd4hep::sim::Geant4GeometryInfo* geoInfo = + conv.create(m_detector->geometryService->detector().world()).detach(); + g4map.attach(geoInfo); // All volumes are deleted in ~G4PhysicalVolumeStore() - m_world = geo_info->world(); + m_world = geoInfo->world(); // Create Geant4 volume manager g4map.volumeManager(); @@ -58,8 +58,6 @@ DDG4DetectorConstructionFactory::DDG4DetectorConstructionFactory( : m_detector(std::move(detector)), m_regionCreators(std::move(regionCreators)) {} -DDG4DetectorConstructionFactory::~DDG4DetectorConstructionFactory() = default; - std::unique_ptr DDG4DetectorConstructionFactory::factorize() const { return std::make_unique(m_detector, diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp index 16c1e23eb49..899df36fad9 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepDetector.hpp @@ -59,14 +59,6 @@ struct DD4hepDetector { /// @brief The DD4hep geometry service std::shared_ptr geometryService = nullptr; - dd4hep::Detector& dd4hepDetector() const { - return geometryService->detector(); - } - - dd4hep::DetElement& dd4hepGeometry() const { - return geometryService->geometry(); - } - /// @brief Build the tracking geometry from the DD4hep geometry /// /// @param config is the configuration of the geometry service diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp index 61d805b3ad5..d1c60b31d0c 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp @@ -94,7 +94,7 @@ class DD4hepGeometryService { /// Interface method to access the DD4hep geometry /// @return The world DD4hep DetElement - dd4hep::DetElement& geometry(); + dd4hep::DetElement geometry(); /// Interface method to Access the TGeo geometry /// @return The world TGeoNode (physical volume) diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp index b7ee5f508e8..a010d133667 100644 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp @@ -91,7 +91,7 @@ ActsExamples::DD4hep::DD4hepGeometryService::DD4hepGeometryService::detector() { return *m_detector; } -dd4hep::DetElement& ActsExamples::DD4hep::DD4hepGeometryService::geometry() { +dd4hep::DetElement ActsExamples::DD4hep::DD4hepGeometryService::geometry() { if (!m_geometry) { buildDD4hepGeometry(); } diff --git a/Examples/Io/EDM4hep/src/EDM4hepReader.cpp b/Examples/Io/EDM4hep/src/EDM4hepReader.cpp index 02e3148b346..34cbf1e345a 100644 --- a/Examples/Io/EDM4hep/src/EDM4hepReader.cpp +++ b/Examples/Io/EDM4hep/src/EDM4hepReader.cpp @@ -325,8 +325,8 @@ ProcessCode EDM4hepReader::read(const AlgorithmContext& ctx) { [&](std::uint64_t cellId) { ACTS_VERBOSE("CellID: " << cellId); - const auto& vm = - m_cfg.dd4hepDetector->dd4hepDetector().volumeManager(); + const auto& vm = m_cfg.dd4hepDetector->geometryService->detector() + .volumeManager(); const auto detElement = vm.lookupDetElement(cellId); From 888bf2e85bb4fec1f03d2f4298944f67e52b0aa5 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Fri, 9 Aug 2024 14:07:43 +0200 Subject: [PATCH 26/32] revert more --- .../DDG4/DDG4DetectorConstruction.hpp | 5 +++ .../Geant4/src/DDG4DetectorConstruction.cpp | 35 +++++++++++-------- .../DD4hepDetector/DD4hepGeometryService.hpp | 2 +- .../src/DD4hepGeometryService.cpp | 2 +- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp index a66b4d0c319..85237e94811 100644 --- a/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp +++ b/Examples/Algorithms/Geant4/include/ActsExamples/DDG4/DDG4DetectorConstruction.hpp @@ -32,6 +32,7 @@ class DDG4DetectorConstruction final : public G4VUserDetectorConstruction { DDG4DetectorConstruction( std::shared_ptr detector, std::vector> regionCreators = {}); + ~DDG4DetectorConstruction() final; /// Convert the stored DD4hep detector to a Geant4 description. /// @@ -49,6 +50,9 @@ class DDG4DetectorConstruction final : public G4VUserDetectorConstruction { std::vector> m_regionCreators; /// The world volume G4VPhysicalVolume* m_world = nullptr; + + /// The DD4hep detector instance + dd4hep::Detector& dd4hepDetector() const; }; class DDG4DetectorConstructionFactory final @@ -57,6 +61,7 @@ class DDG4DetectorConstructionFactory final DDG4DetectorConstructionFactory( std::shared_ptr detector, std::vector> regionCreators = {}); + ~DDG4DetectorConstructionFactory() final; std::unique_ptr factorize() const override; diff --git a/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp b/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp index bb64446e158..74fa7831646 100644 --- a/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp +++ b/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp @@ -18,29 +18,35 @@ #include #include #include +#include class G4VPhysicalVolume; -namespace ActsExamples { - -DDG4DetectorConstruction::DDG4DetectorConstruction( +ActsExamples::DDG4DetectorConstruction::DDG4DetectorConstruction( std::shared_ptr detector, std::vector> regionCreators) : G4VUserDetectorConstruction(), m_detector(std::move(detector)), m_regionCreators(std::move(regionCreators)) {} +ActsExamples::DDG4DetectorConstruction::~DDG4DetectorConstruction() = default; + +dd4hep::Detector& ActsExamples::DDG4DetectorConstruction::dd4hepDetector() + const { + return m_detector->geometryService->detector(); +} + // See DD4hep::Simulation::Geant4DetectorConstruction::Construct() -G4VPhysicalVolume* DDG4DetectorConstruction::Construct() { +G4VPhysicalVolume* ActsExamples::DDG4DetectorConstruction::Construct() { if (m_world == nullptr) { dd4hep::sim::Geant4Mapping& g4map = dd4hep::sim::Geant4Mapping::instance(); - auto conv = dd4hep::sim::Geant4Converter( - m_detector->geometryService->detector(), dd4hep::PrintLevel::VERBOSE); - dd4hep::sim::Geant4GeometryInfo* geoInfo = - conv.create(m_detector->geometryService->detector().world()).detach(); - g4map.attach(geoInfo); + auto conv = dd4hep::sim::Geant4Converter(dd4hepDetector(), + dd4hep::PrintLevel::VERBOSE); + dd4hep::sim::Geant4GeometryInfo* geo_info = + conv.create(dd4hepDetector().world()).detach(); + g4map.attach(geo_info); // All volumes are deleted in ~G4PhysicalVolumeStore() - m_world = geoInfo->world(); + m_world = geo_info->world(); // Create Geant4 volume manager g4map.volumeManager(); @@ -52,16 +58,17 @@ G4VPhysicalVolume* DDG4DetectorConstruction::Construct() { return m_world; } -DDG4DetectorConstructionFactory::DDG4DetectorConstructionFactory( +ActsExamples::DDG4DetectorConstructionFactory::DDG4DetectorConstructionFactory( std::shared_ptr detector, std::vector> regionCreators) : m_detector(std::move(detector)), m_regionCreators(std::move(regionCreators)) {} +ActsExamples::DDG4DetectorConstructionFactory:: + ~DDG4DetectorConstructionFactory() = default; + std::unique_ptr -DDG4DetectorConstructionFactory::factorize() const { +ActsExamples::DDG4DetectorConstructionFactory::factorize() const { return std::make_unique(m_detector, m_regionCreators); } - -} // namespace ActsExamples diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp index d1c60b31d0c..61d805b3ad5 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp @@ -94,7 +94,7 @@ class DD4hepGeometryService { /// Interface method to access the DD4hep geometry /// @return The world DD4hep DetElement - dd4hep::DetElement geometry(); + dd4hep::DetElement& geometry(); /// Interface method to Access the TGeo geometry /// @return The world TGeoNode (physical volume) diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp index a010d133667..b7ee5f508e8 100644 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp @@ -91,7 +91,7 @@ ActsExamples::DD4hep::DD4hepGeometryService::DD4hepGeometryService::detector() { return *m_detector; } -dd4hep::DetElement ActsExamples::DD4hep::DD4hepGeometryService::geometry() { +dd4hep::DetElement& ActsExamples::DD4hep::DD4hepGeometryService::geometry() { if (!m_geometry) { buildDD4hepGeometry(); } From 734f4ecd0226b7827cd67ec7eff84cc56ac354bc Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Fri, 9 Aug 2024 15:39:05 +0200 Subject: [PATCH 27/32] camelCase --- Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp b/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp index 74fa7831646..a09314c919c 100644 --- a/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp +++ b/Examples/Algorithms/Geant4/src/DDG4DetectorConstruction.cpp @@ -42,11 +42,11 @@ G4VPhysicalVolume* ActsExamples::DDG4DetectorConstruction::Construct() { dd4hep::sim::Geant4Mapping& g4map = dd4hep::sim::Geant4Mapping::instance(); auto conv = dd4hep::sim::Geant4Converter(dd4hepDetector(), dd4hep::PrintLevel::VERBOSE); - dd4hep::sim::Geant4GeometryInfo* geo_info = + dd4hep::sim::Geant4GeometryInfo* geoInfo = conv.create(dd4hepDetector().world()).detach(); - g4map.attach(geo_info); + g4map.attach(geoInfo); // All volumes are deleted in ~G4PhysicalVolumeStore() - m_world = geo_info->world(); + m_world = geoInfo->world(); // Create Geant4 volume manager g4map.volumeManager(); From 4ee76c5ec5470781d6426ee75528a9103ff2fddc Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Fri, 9 Aug 2024 16:15:02 +0200 Subject: [PATCH 28/32] final fix --- .../DD4hepDetector/DD4hepGeometryService.hpp | 5 +++-- .../DD4hepDetector/src/DD4hepGeometryService.cpp | 12 +++++++++++- Examples/Python/src/DD4hepComponent.cpp | 4 ++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp index 61d805b3ad5..f4397c92c7e 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp @@ -56,7 +56,7 @@ class DD4hepGeometryService { /// XML-file with the detector description std::vector xmlFileNames; /// The name of the service - std::string name; + std::string name = "default"; /// Binningtype in phi Acts::BinningType bTypePhi = Acts::equidistant; /// Binningtype in r @@ -88,6 +88,7 @@ class DD4hepGeometryService { }; DD4hepGeometryService(const Config& cfg); + ~DD4hepGeometryService(); /// Interface method to access to the DD4hep geometry dd4hep::Detector& detector(); @@ -119,7 +120,7 @@ class DD4hepGeometryService { /// The config class Config m_cfg; /// Pointer to the interface to the DD4hep geometry - std::unique_ptr m_detector; + dd4hep::Detector* m_detector = nullptr; /// The world DD4hep DetElement dd4hep::DetElement m_geometry; /// The ACTS TrackingGeometry diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp index b7ee5f508e8..dc4d0dd018d 100644 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp @@ -34,6 +34,12 @@ ActsExamples::DD4hep::DD4hepGeometryService::DD4hepGeometryService( } } +ActsExamples::DD4hep::DD4hepGeometryService::~DD4hepGeometryService() { + if (m_detector != nullptr) { + dd4hep::Detector::destroyInstance(m_cfg.name); + } +} + ActsExamples::ProcessCode ActsExamples::DD4hep::DD4hepGeometryService::buildDD4hepGeometry() { const int old_gErrorIgnoreLevel = gErrorIgnoreLevel; @@ -68,7 +74,7 @@ ActsExamples::DD4hep::DD4hepGeometryService::buildDD4hepGeometry() { std::cout.setstate(std::ios_base::failbit); } - m_detector = dd4hep::Detector::make_unique(m_cfg.name); + m_detector = &dd4hep::Detector::getInstance(); for (auto& file : m_cfg.xmlFileNames) { m_detector->fromCompact(file.c_str()); } @@ -128,6 +134,10 @@ ActsExamples::DD4hep::DD4hepGeometryService::trackingGeometry( } void ActsExamples::DD4hep::DD4hepGeometryService::drop() { + if (m_detector == nullptr) { + return; + } + dd4hep::Detector::destroyInstance(m_cfg.name); m_detector = nullptr; m_geometry = dd4hep::DetElement(); m_trackingGeometry = nullptr; diff --git a/Examples/Python/src/DD4hepComponent.cpp b/Examples/Python/src/DD4hepComponent.cpp index 223e9fec7f9..be4d30b5f5e 100644 --- a/Examples/Python/src/DD4hepComponent.cpp +++ b/Examples/Python/src/DD4hepComponent.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2021 CERN for the benefit of the Acts project +// Copyright (C) 2021-2024 CERN for the benefit of the Acts project // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -89,7 +89,7 @@ PYBIND11_MODULE(ActsPythonBindingsDD4hep, m) { const auto* dd4hepDetElement = dynamic_cast(dde); // Check if it is valid - if (dd4hepDetElement) { + if (dd4hepDetElement != nullptr) { dd4hep::DDSegmentation::VolumeID dd4hepID = dd4hepDetElement->sourceElement().volumeID(); auto geoID = surface->geometryId(); From 86417a208450fd148ded6a72e71aab3a49f2f7b6 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Fri, 9 Aug 2024 16:48:22 +0200 Subject: [PATCH 29/32] explicit delete copy&move; use `drop` in destructor --- .../ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp | 4 ++++ .../Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp index f4397c92c7e..cfef3becff0 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp @@ -88,7 +88,11 @@ class DD4hepGeometryService { }; DD4hepGeometryService(const Config& cfg); + DD4hepGeometryService(const DD4hepGeometryService&) = delete; + DD4hepGeometryService(DD4hepGeometryService&&) = delete; ~DD4hepGeometryService(); + DD4hepGeometryService& operator=(const DD4hepGeometryService&) = delete; + DD4hepGeometryService& operator=(DD4hepGeometryService&&) = delete; /// Interface method to access to the DD4hep geometry dd4hep::Detector& detector(); diff --git a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp index dc4d0dd018d..780fbca385a 100644 --- a/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp +++ b/Examples/Detectors/DD4hepDetector/src/DD4hepGeometryService.cpp @@ -35,9 +35,7 @@ ActsExamples::DD4hep::DD4hepGeometryService::DD4hepGeometryService( } ActsExamples::DD4hep::DD4hepGeometryService::~DD4hepGeometryService() { - if (m_detector != nullptr) { - dd4hep::Detector::destroyInstance(m_cfg.name); - } + drop(); } ActsExamples::ProcessCode From ebf287009715cb39d3cdfc6b16d0ee7188ec72d5 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Sat, 10 Aug 2024 09:25:59 +0200 Subject: [PATCH 30/32] context manager on detector tuple --- Examples/Python/python/acts/_adapter.py | 19 +++++--- Examples/Python/python/acts/examples/odd.py | 19 +++++++- Examples/Python/tests/conftest.py | 20 +++------ Examples/Python/tests/test_detectors.py | 4 +- Examples/Python/tests/test_examples.py | 50 +++++++++------------ Examples/Python/tests/test_reader.py | 4 +- 6 files changed, 58 insertions(+), 58 deletions(-) diff --git a/Examples/Python/python/acts/_adapter.py b/Examples/Python/python/acts/_adapter.py index 15e3d84a015..e102032cae7 100644 --- a/Examples/Python/python/acts/_adapter.py +++ b/Examples/Python/python/acts/_adapter.py @@ -2,6 +2,7 @@ import functools from typing import Optional, Callable, Dict, Any from pathlib import Path +from collections import namedtuple import acts @@ -117,7 +118,17 @@ def create(*args, mdecorator=None, **kwargs): _kwargs[k] = v det = cls() tg, deco = det.finalize(cfg, mdecorator, *args, **_kwargs) - return det, tg, deco + Detector = namedtuple("Detector", ["detector", "trackingGeometry", "decorators"]) + class DetectorContextManager(Detector): + def __new__(cls, detector, trackingGeometry, decorators): + return super(DetectorContextManager, cls).__new__( + cls, detector, trackingGeometry, decorators + ) + def __enter__(self): + return self + def __exit__(self, *args): + pass + return DetectorContextManager(det, tg, deco) return create @@ -126,9 +137,3 @@ def _patch_detectors(m): for name, cls in inspect.getmembers(m, inspect.isclass): if name.endswith("Detector"): cls.create = _detector_create(cls) - - cls.__enter__ = lambda self: self - if hasattr(cls, "drop"): - cls.__exit__ = lambda self, *args: self.drop() - else: - cls.__exit__ = lambda self, *args: None diff --git a/Examples/Python/python/acts/examples/odd.py b/Examples/Python/python/acts/examples/odd.py index b5d1b4c42a7..4e1efb1c783 100644 --- a/Examples/Python/python/acts/examples/odd.py +++ b/Examples/Python/python/acts/examples/odd.py @@ -1,6 +1,7 @@ import os import sys import math +from collections import namedtuple from pathlib import Path from typing import Optional import acts @@ -101,4 +102,20 @@ def geoid_hook(geoid, surface): trackingGeometry, decorators = detector.finalize(dd4hepConfig, mdecorator) - return detector, trackingGeometry, decorators + OpenDataDetector = namedtuple( + "OpenDataDetector", ["detector", "trackingGeometry", "decorators"] + ) + + class OpenDataDetectorContextManager(OpenDataDetector): + def __new__(cls, detector, trackingGeometry, decorators): + return super(OpenDataDetectorContextManager, cls).__new__( + cls, detector, trackingGeometry, decorators + ) + + def __enter__(self): + return self + + def __exit__(self, *args): + self.detector.drop() + + return OpenDataDetectorContextManager(detector, trackingGeometry, decorators) diff --git a/Examples/Python/tests/conftest.py b/Examples/Python/tests/conftest.py index c7077c91e24..352155fb6a3 100644 --- a/Examples/Python/tests/conftest.py +++ b/Examples/Python/tests/conftest.py @@ -253,9 +253,7 @@ def trk_geo(): DetectorConfig = namedtuple( "DetectorConfig", [ - "detector", - "trackingGeometry", - "decorators", + "detectorTuple", "geometrySelection", "digiConfigFile", "name", @@ -268,11 +266,9 @@ def detector_config(request): srcdir = Path(__file__).resolve().parent.parent.parent.parent if request.param == "generic": - detector, trackingGeometry, decorators = acts.examples.GenericDetector.create() + detectorTuple = acts.examples.GenericDetector.create() return DetectorConfig( - detector, - trackingGeometry, - decorators, + detectorTuple, geometrySelection=( srcdir / "Examples/Algorithms/TrackFinding/share/geoSelection-genericDetector.json" @@ -291,11 +287,9 @@ def detector_config(request): srcdir / "thirdparty/OpenDataDetector/data/odd-material-maps.root", level=acts.logging.INFO, ) - detector, trackingGeometry, decorators = getOpenDataDetector(matDeco) + detectorTuple = getOpenDataDetector(matDeco) return DetectorConfig( - detector, - trackingGeometry, - decorators, + detectorTuple, digiConfigFile=( srcdir / "thirdparty/OpenDataDetector/config/odd-digi-smearing-config.json" @@ -391,9 +385,7 @@ def _do_material_recording(d: Path): s = acts.examples.Sequencer(events=2, numThreads=1) - detector, trackingGeometry, decorators = getOpenDataDetector() - - with detector: + with getOpenDataDetector() as (detector, trackingGeometry, decorators): detectorConstructionFactory = ( acts.examples.geant4.dd4hep.DDG4DetectorConstructionFactory(detector) ) diff --git a/Examples/Python/tests/test_detectors.py b/Examples/Python/tests/test_detectors.py index 06b7e677334..e99406c69d6 100644 --- a/Examples/Python/tests/test_detectors.py +++ b/Examples/Python/tests/test_detectors.py @@ -53,9 +53,7 @@ def test_telescope_geometry(): @pytest.mark.skipif(not dd4hepEnabled, reason="DD4hep is not set up") def test_odd(): - detector, trackingGeometry, decorators = getOpenDataDetector() - - with detector: + with getOpenDataDetector() as (detector, trackingGeometry, decorators): trackingGeometry.visitSurfaces(check_extra_odd) assert count_surfaces(trackingGeometry) == 18824 diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index bbf10432caa..3cc4a500790 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -143,8 +143,7 @@ def test_geant4(tmp_path, assert_root_hash): # This test literally only ensures that the geant 4 example can run without erroring out # just to make sure it can build the odd - detector, trackingGeometry, decorators = getOpenDataDetector() - with detector: + with getOpenDataDetector() as (detector, trackingGeometry, decorators): pass csv = tmp_path / "csv" @@ -528,7 +527,7 @@ def test_truth_tracking_kalman( assert not fp.exists() print("with") - with detector_config.detector: + with detector_config.detectorTuple as (detector, trackingGeometry, decorators): from truth_tracking_kalman import runTruthTrackingKalman field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T)) @@ -536,7 +535,7 @@ def test_truth_tracking_kalman( seq = Sequencer(events=10, numThreads=1) runTruthTrackingKalman( - trackingGeometry=detector_config.trackingGeometry, + trackingGeometry=trackingGeometry, field=field, digiConfigFile=detector_config.digiConfigFile, outputDir=tmp_path, @@ -593,10 +592,10 @@ def test_truth_tracking_gsf(tmp_path, assert_root_hash, detector_config): fp = tmp_path / fn assert not fp.exists() - with detector_config.detector: + with detector_config.detectorTuple as (detector, trackingGeometry, decorators): runTruthTrackingGsf( - trackingGeometry=detector_config.trackingGeometry, - decorators=detector_config.decorators, + trackingGeometry=trackingGeometry, + decorators=decorators, field=field, digiConfigFile=detector_config.digiConfigFile, outputDir=tmp_path, @@ -625,11 +624,11 @@ def test_refitting(tmp_path, detector_config, assert_root_hash): numThreads=1, ) - with detector_config.detector: + with detector_config.detectorTuple as (detector, trackingGeometry, decorators): # Only check if it runs without errors right known # Changes in fitter behaviour should be caught by other tests runRefittingGsf( - trackingGeometry=detector_config.trackingGeometry, + trackingGeometry=trackingGeometry, field=field, outputDir=tmp_path, s=seq, @@ -692,9 +691,7 @@ def test_material_mapping(material_recording, tmp_path, assert_root_hash): s = Sequencer(numThreads=1) - detector, trackingGeometry, decorators = getOpenDataDetector(mdecorator) - - with detector: + with getOpenDataDetector(mdecorator) as (detector, trackingGeometry, decorators): runMaterialMapping( trackingGeometry, decorators, @@ -727,11 +724,9 @@ def test_material_mapping(material_recording, tmp_path, assert_root_hash): s = Sequencer(events=10, numThreads=1) - detector, trackingGeometry, decorators = getOpenDataDetector( + with getOpenDataDetector( mdecorator=acts.IMaterialDecorator.fromFile(mat_file) - ) - - with detector: + ) as (detector, trackingGeometry, decorators): runMaterialValidation( 10, 1000, trackingGeometry, decorators, field, outputDir=str(tmp_path), s=s ) @@ -761,11 +756,9 @@ def test_volume_material_mapping(material_recording, tmp_path, assert_root_hash) s = Sequencer(numThreads=1) - detector, trackingGeometry, decorators = getOpenDataDetector( - mdecorator=acts.IMaterialDecorator.fromFile(geo_map) - ) - - with detector: + with getOpenDataDetector( + mdecorator=acts.IMaterialDecorator.fromFile(mat_file) + ) as (detector, trackingGeometry, decorators): runMaterialMapping( trackingGeometry, decorators, @@ -799,11 +792,9 @@ def test_volume_material_mapping(material_recording, tmp_path, assert_root_hash) s = Sequencer(events=10, numThreads=1) - detector, trackingGeometry, decorators = getOpenDataDetector( + with getOpenDataDetector( mdecorator=acts.IMaterialDecorator.fromFile(mat_file) - ) - - with detector: + ) as (detector, trackingGeometry, decorators): runMaterialValidation( 10, 1000, @@ -1066,10 +1057,10 @@ def test_ckf_tracks_example( from ckf_tracks import runCKFTracks - with detector_config.detector: + with detector_config.detectorTuple as (detector, trackingGeometry, decorators): runCKFTracks( - detector_config.trackingGeometry, - detector_config.decorators, + trackingGeometry, + decorators, field=field, outputCsv=True, outputDir=tmp_path, @@ -1102,8 +1093,7 @@ def test_full_chain_odd_example(tmp_path): # This test literally only ensures that the full chain example can run without erroring out # just to make sure it can build the odd - detector, trackingGeometry, decorators = getOpenDataDetector() - with detector: + with getOpenDataDetector() as (detector, trackingGeometry, decorators): pass script = ( diff --git a/Examples/Python/tests/test_reader.py b/Examples/Python/tests/test_reader.py index 08f4b5aedfe..f4e803776d5 100644 --- a/Examples/Python/tests/test_reader.py +++ b/Examples/Python/tests/test_reader.py @@ -298,9 +298,7 @@ def test_edm4hep_simhit_particle_reader(tmp_path): s = Sequencer(numThreads=1) - detector, trackingGeometry, decorators = getOpenDataDetector() - - with detector: + with getOpenDataDetector() as (detector, trackingGeometry, decorators): s.addReader( EDM4hepReader( level=acts.logging.INFO, From d9e19b9b2d93b381d810ba3d14b852bfc559ce85 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Sat, 10 Aug 2024 09:29:10 +0200 Subject: [PATCH 31/32] format --- Examples/Python/python/acts/_adapter.py | 8 +++++++- Examples/Python/tests/test_examples.py | 24 +++++++++++++++--------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Examples/Python/python/acts/_adapter.py b/Examples/Python/python/acts/_adapter.py index e102032cae7..493fb53b508 100644 --- a/Examples/Python/python/acts/_adapter.py +++ b/Examples/Python/python/acts/_adapter.py @@ -118,16 +118,22 @@ def create(*args, mdecorator=None, **kwargs): _kwargs[k] = v det = cls() tg, deco = det.finalize(cfg, mdecorator, *args, **_kwargs) - Detector = namedtuple("Detector", ["detector", "trackingGeometry", "decorators"]) + Detector = namedtuple( + "Detector", ["detector", "trackingGeometry", "decorators"] + ) + class DetectorContextManager(Detector): def __new__(cls, detector, trackingGeometry, decorators): return super(DetectorContextManager, cls).__new__( cls, detector, trackingGeometry, decorators ) + def __enter__(self): return self + def __exit__(self, *args): pass + return DetectorContextManager(det, tg, deco) return create diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index 3cc4a500790..7faa1ab09a7 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -724,9 +724,11 @@ def test_material_mapping(material_recording, tmp_path, assert_root_hash): s = Sequencer(events=10, numThreads=1) - with getOpenDataDetector( - mdecorator=acts.IMaterialDecorator.fromFile(mat_file) - ) as (detector, trackingGeometry, decorators): + with getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(mat_file)) as ( + detector, + trackingGeometry, + decorators, + ): runMaterialValidation( 10, 1000, trackingGeometry, decorators, field, outputDir=str(tmp_path), s=s ) @@ -756,9 +758,11 @@ def test_volume_material_mapping(material_recording, tmp_path, assert_root_hash) s = Sequencer(numThreads=1) - with getOpenDataDetector( - mdecorator=acts.IMaterialDecorator.fromFile(mat_file) - ) as (detector, trackingGeometry, decorators): + with getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(mat_file)) as ( + detector, + trackingGeometry, + decorators, + ): runMaterialMapping( trackingGeometry, decorators, @@ -792,9 +796,11 @@ def test_volume_material_mapping(material_recording, tmp_path, assert_root_hash) s = Sequencer(events=10, numThreads=1) - with getOpenDataDetector( - mdecorator=acts.IMaterialDecorator.fromFile(mat_file) - ) as (detector, trackingGeometry, decorators): + with getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(mat_file)) as ( + detector, + trackingGeometry, + decorators, + ): runMaterialValidation( 10, 1000, From 47cd065f325b80fb2db58cfdc4e8feaf8806b0cc Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Sat, 10 Aug 2024 10:20:49 +0200 Subject: [PATCH 32/32] fix c&p bug --- Examples/Python/tests/test_examples.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index 7faa1ab09a7..291dca8ac85 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -758,7 +758,7 @@ def test_volume_material_mapping(material_recording, tmp_path, assert_root_hash) s = Sequencer(numThreads=1) - with getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(mat_file)) as ( + with getOpenDataDetector(mdecorator=acts.IMaterialDecorator.fromFile(geo_map)) as ( detector, trackingGeometry, decorators,