From e59014066cc1830cd5d42d343f1f5f6e86c452c7 Mon Sep 17 00:00:00 2001 From: Andreas Salzburger Date: Thu, 12 Sep 2024 19:29:27 +0200 Subject: [PATCH] feat: add counters to propagation summary (#3602) This PR adds statistics counters for sensitives, portals and material surfaces to the Propagation summary and adds a little script to plot those. ![ITK-sensitive-modules](https://github.com/user-attachments/assets/8695f61c-b1bb-4966-af48-ab235c8f5b5b) It also adapts the `geomodel.py` to recent changes to be able to make this plot. Changes to references are expected. --- .../Io/Root/RootPropagationSummaryWriter.hpp | 9 +++++-- .../Root/src/RootPropagationSummaryWriter.cpp | 26 +++++++++++++++++++ Examples/Python/tests/root_file_hashes.txt | 2 +- Examples/Scripts/Python/geomodel.py | 10 +++---- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/RootPropagationSummaryWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/RootPropagationSummaryWriter.hpp index b55db747128..84781680240 100644 --- a/Examples/Io/Root/include/ActsExamples/Io/Root/RootPropagationSummaryWriter.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/RootPropagationSummaryWriter.hpp @@ -92,7 +92,7 @@ class RootPropagationSummaryWriter : public WriterT { /// track number int m_trackNr = 0; - // initial trajectory parameters + /// initial trajectory parameters float m_d0 = 0; float m_z0 = 0; float m_phi = 0; @@ -100,11 +100,16 @@ class RootPropagationSummaryWriter : public WriterT { float m_qOverP = 0; float m_t = 0; - // derived initial trajectory parameters + /// derived initial trajectory parameters float m_eta = 0; float m_pt = 0; float m_p = 0; + /// Propagation summary statstics + int m_nSensitives = 0; + int m_nMaterials = 0; + int m_nPortals = 0; + // steper statistics int m_nSteps = 0; int m_nStepTrials = 0; diff --git a/Examples/Io/Root/src/RootPropagationSummaryWriter.cpp b/Examples/Io/Root/src/RootPropagationSummaryWriter.cpp index 561d1bdc9e8..ea2fa3191e4 100644 --- a/Examples/Io/Root/src/RootPropagationSummaryWriter.cpp +++ b/Examples/Io/Root/src/RootPropagationSummaryWriter.cpp @@ -73,6 +73,10 @@ RootPropagationSummaryWriter::RootPropagationSummaryWriter( m_outputTree->Branch("pt", &m_pt); m_outputTree->Branch("p", &m_p); + m_outputTree->Branch("nSensitives", &m_nSensitives); + m_outputTree->Branch("nMaterials", &m_nMaterials); + m_outputTree->Branch("nPortals", &m_nPortals); + m_outputTree->Branch("nSteps", &m_nSteps); m_outputTree->Branch("nStepTrials", &m_nStepTrials); m_outputTree->Branch("pathLength", &m_pathLength); @@ -134,6 +138,28 @@ ProcessCode RootPropagationSummaryWriter::writeT( m_nStepTrials = static_cast(summary.nStepTrials); m_pathLength = static_cast(summary.pathLength); + m_nMaterials = 0; + m_nSensitives = 0; + m_nPortals = 0; + + // Loop over the steps & count for the statistics + std::ranges::for_each(summary.steps, [&](const auto& step) { + // Check if the step is a sensitive step + if (step.geoID.sensitive() > 0) { + m_nSensitives++; + } + // Check if the step is a portal step + if (step.geoID.boundary() > 0) { + m_nPortals++; + } + + if (step.surface != nullptr) { + // Check if the step is a material step + if (step.surface->surfaceMaterial() != nullptr) { + m_nMaterials++; + } + } + }); m_outputTree->Fill(); } diff --git a/Examples/Python/tests/root_file_hashes.txt b/Examples/Python/tests/root_file_hashes.txt index f46e52e5aa1..547d53b9a78 100644 --- a/Examples/Python/tests/root_file_hashes.txt +++ b/Examples/Python/tests/root_file_hashes.txt @@ -16,7 +16,7 @@ test_itk_seeding__estimatedparams.root: 7e3acb54fcaabae19fe5b8601bd5bd3e5f65d6a1 test_itk_seeding__performance_seeding.root: 78ebda54cd0f026ba4b7f316724ffd946de56a932735914baf1b7bba9505c29d test_itk_seeding__particles.root: 0b6f4ad438010ac48803d48ed98e80b5e87d310bae6c2c02b16cd94d7a4d7d07 test_itk_seeding__particles_simulation.root: ef0246069aa697019f28a8b270a68de95312cae5f2f2c74848566c3ce4f70363 -test_propagation__propagation_summary.root: 85d877c3a48a6235d3d5a398b47130d5d17d4d3724128ccb339d8174e71a5bb0 +test_propagation__propagation_summary.root: 280c1a6fcfe71974ac39587b4afad27a31640bec42ca6537cc92e2d5e09d7ed6 test_material_recording__geant4_material_tracks.root: c022b9362249b29f57a07926b20644e3ab4ab8ebcf03f773fbf46c446fc1a0a1 test_truth_tracking_gsf[generic]__trackstates_gsf.root: 974968d9c867a18e2477fb241288e8d8a4a5e7499495d3e1a7b9cafa26c6dda5 test_truth_tracking_gsf[generic]__tracksummary_gsf.root: b698e3d21eacc34fc8b0ce1d3fbe07405a4b8b549e07f0160573e64c3b401f04 diff --git a/Examples/Scripts/Python/geomodel.py b/Examples/Scripts/Python/geomodel.py index 9cfca061b24..8bc49d59090 100644 --- a/Examples/Scripts/Python/geomodel.py +++ b/Examples/Scripts/Python/geomodel.py @@ -129,16 +129,16 @@ def main(): # Read the geometry model from the database gmTree = acts.geomodel.readFromDb(args.input) - gmFactoryConfig = gm.GeoModelDetectorSurfaceFactory.Config() + gmFactoryConfig = gm.GeoModelDetectorObjectFactory.Config() gmFactoryConfig.materialList = args.material_list gmFactoryConfig.nameList = args.name_list gmFactoryConfig.convertSubVolumes = args.convert_subvols - gmFactory = gm.GeoModelDetectorSurfaceFactory(gmFactoryConfig, logLevel) + gmFactory = gm.GeoModelDetectorObjectFactory(gmFactoryConfig, logLevel) # The options - gmFactoryOptions = gm.GeoModelDetectorSurfaceFactory.Options() + gmFactoryOptions = gm.GeoModelDetectorObjectFactory.Options() gmFactoryOptions.queries = args.queries # The Cache & construct call - gmFactoryCache = gm.GeoModelDetectorSurfaceFactory.Cache() + gmFactoryCache = gm.GeoModelDetectorObjectFactory.Cache() gmFactory.construct(gmFactoryCache, gContext, gmTree, gmFactoryOptions) # All surfaces from GeoModel @@ -236,7 +236,7 @@ def main(): [[ivol, volumeOptions] for ivol in range(detector.numberVolumes())], [ ["xy", ["sensitives", "portals"], xyRange], - ["zr", ["", "", "materials"], zrRange], + ["zr", ["sensitives", "portals", "materials"], zrRange], ], args.output + "_detector", )