From 2cbc1113bcf7c6174c65ad4bd89a28e9c2e42cc2 Mon Sep 17 00:00:00 2001 From: Andreas Salzburger Date: Tue, 10 Sep 2024 09:48:52 +0200 Subject: [PATCH 1/7] adding sensitives/portals/material counts to propagation summary --- .../Io/Root/RootPropagationSummaryWriter.hpp | 9 +- .../Root/src/RootPropagationSummaryWriter.cpp | 26 +++++ .../Propagation/propagation_summary.py | 102 ++++++++++++++++++ Examples/Scripts/Python/geomodel.py | 10 +- 4 files changed, 140 insertions(+), 7 deletions(-) create mode 100644 Examples/Scripts/Propagation/propagation_summary.py diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/RootPropagationSummaryWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/RootPropagationSummaryWriter.hpp index b55db747128..213f815ce06 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..cf0e2274a50 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/Scripts/Propagation/propagation_summary.py b/Examples/Scripts/Propagation/propagation_summary.py new file mode 100644 index 00000000000..3a522131146 --- /dev/null +++ b/Examples/Scripts/Propagation/propagation_summary.py @@ -0,0 +1,102 @@ +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import argparse +import uproot +import seaborn as sns + +p = argparse.ArgumentParser() + +p.add_argument( + "-i", + "--input", + nargs="+", + type=str, + default="", + help="Input file(s) with propagation summary", + ) + +p.add_argument( + "-l", + "--label", + nargs="+", + type=str, + default="", + help="Input label(s) for the propagation summary", + ) + +p.add_argument( + "-c", + "--color", + nargs="+", + type=str, + default="", + help="Input label(s) for the propagation summary", + ) + +p.add_argument( + "-m", + "--marker", + nargs="+", + type=str, + default=["o"], + choices=["o", "s", "D", "v", "^", "<", ">", "p", "P", "*", "h", "H", "+", "x", "X", "d"], + help="Input label(s) for the propagation summary", + ) + +p.add_argument( + "-o", + "--output", + type=str, + default="", + help="Output file base name", + ) + +args = p.parse_args() + +try : + + fig, ax = plt.subplots(1, 1, figsize=(11, 10)) + + eta_bins = np.linspace(-4, 4, 100) + eta_centers = 0.5 * (eta_bins[:-1] + eta_bins[1:]) + eta_width = 8./100 + + for ir, irfile in enumerate(args.input): + # load the tree + tree = uproot.open(args.input[ir] + ":" + "propagation_summary") + # get the numpy arrays + eta = tree["eta"].array(library="np") + phi = tree["phi"].array(library="np") + sens = tree["nSensitives"].array(library="np") + portals = tree["nPortals"].array(library="np") + materials = tree["nMaterials"].array(library="np") + + df = pd.DataFrame({'eta': eta, 'phi': phi, 'sens': sens, 'portals': portals, 'materials': materials}) + + df['eta_bin'] = np.digitize(eta, bins=eta_bins) + + # grouby bin, so we can calculate stuff + eta_binned = df.groupby('eta_bin') + sens_result = eta_binned['sens'].agg(['mean', 'sem']) + sens_result['eta'] = eta_centers + sens_result['xerr'] = eta_width / 2 + + sens_result.plot( + x='eta', + y='mean', + xerr='xerr', + yerr='sem', + linestyle='none', + capsize=1, + marker=args.marker[ir], + label=args.label[ir], + ax=ax) + ax.set_xlabel(r'$\eta$') + ax.set_ylabel('Avg. Number of sensitive modules / track') + + fig.show() + +except: + print("The number of input files and labels must match") + exit() 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", ) From 9227d4b4937ba1fa9c057c712d85d44688e5e3b3 Mon Sep 17 00:00:00 2001 From: Andreas Salzburger Date: Tue, 10 Sep 2024 09:52:30 +0200 Subject: [PATCH 2/7] adding counters --- .../Io/Root/RootPropagationSummaryWriter.hpp | 2 +- .../Root/src/RootPropagationSummaryWriter.cpp | 16 +-- .../Propagation/propagation_summary.py | 132 +++++++++++------- 3 files changed, 88 insertions(+), 62 deletions(-) diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/RootPropagationSummaryWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/RootPropagationSummaryWriter.hpp index 213f815ce06..84781680240 100644 --- a/Examples/Io/Root/include/ActsExamples/Io/Root/RootPropagationSummaryWriter.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/RootPropagationSummaryWriter.hpp @@ -107,7 +107,7 @@ class RootPropagationSummaryWriter : public WriterT { /// Propagation summary statstics int m_nSensitives = 0; - int m_nMaterials = 0; + int m_nMaterials = 0; int m_nPortals = 0; // steper statistics diff --git a/Examples/Io/Root/src/RootPropagationSummaryWriter.cpp b/Examples/Io/Root/src/RootPropagationSummaryWriter.cpp index cf0e2274a50..ea2fa3191e4 100644 --- a/Examples/Io/Root/src/RootPropagationSummaryWriter.cpp +++ b/Examples/Io/Root/src/RootPropagationSummaryWriter.cpp @@ -144,14 +144,14 @@ ProcessCode RootPropagationSummaryWriter::writeT( // 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++; - } + // 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 diff --git a/Examples/Scripts/Propagation/propagation_summary.py b/Examples/Scripts/Propagation/propagation_summary.py index 3a522131146..2e4d330af35 100644 --- a/Examples/Scripts/Propagation/propagation_summary.py +++ b/Examples/Scripts/Propagation/propagation_summary.py @@ -8,59 +8,76 @@ p = argparse.ArgumentParser() p.add_argument( - "-i", - "--input", - nargs="+", - type=str, - default="", - help="Input file(s) with propagation summary", - ) + "-i", + "--input", + nargs="+", + type=str, + default="", + help="Input file(s) with propagation summary", +) p.add_argument( - "-l", - "--label", - nargs="+", - type=str, - default="", - help="Input label(s) for the propagation summary", - ) + "-l", + "--label", + nargs="+", + type=str, + default="", + help="Input label(s) for the propagation summary", +) p.add_argument( - "-c", - "--color", - nargs="+", - type=str, - default="", - help="Input label(s) for the propagation summary", - ) + "-c", + "--color", + nargs="+", + type=str, + default="", + help="Input label(s) for the propagation summary", +) p.add_argument( - "-m", - "--marker", - nargs="+", - type=str, - default=["o"], - choices=["o", "s", "D", "v", "^", "<", ">", "p", "P", "*", "h", "H", "+", "x", "X", "d"], - help="Input label(s) for the propagation summary", - ) + "-m", + "--marker", + nargs="+", + type=str, + default=["o"], + choices=[ + "o", + "s", + "D", + "v", + "^", + "<", + ">", + "p", + "P", + "*", + "h", + "H", + "+", + "x", + "X", + "d", + ], + help="Input label(s) for the propagation summary", +) p.add_argument( - "-o", - "--output", - type=str, - default="", - help="Output file base name", - ) + "-o", + "--output", + type=str, + default="", + help="Output file base name", +) args = p.parse_args() -try : - +try: + fig, ax = plt.subplots(1, 1, figsize=(11, 10)) eta_bins = np.linspace(-4, 4, 100) eta_centers = 0.5 * (eta_bins[:-1] + eta_bins[1:]) - eta_width = 8./100 + eta_width = 8.0 / 100 for ir, irfile in enumerate(args.input): # load the tree @@ -72,31 +89,40 @@ portals = tree["nPortals"].array(library="np") materials = tree["nMaterials"].array(library="np") - df = pd.DataFrame({'eta': eta, 'phi': phi, 'sens': sens, 'portals': portals, 'materials': materials}) + df = pd.DataFrame( + { + "eta": eta, + "phi": phi, + "sens": sens, + "portals": portals, + "materials": materials, + } + ) - df['eta_bin'] = np.digitize(eta, bins=eta_bins) + df["eta_bin"] = np.digitize(eta, bins=eta_bins) # grouby bin, so we can calculate stuff - eta_binned = df.groupby('eta_bin') - sens_result = eta_binned['sens'].agg(['mean', 'sem']) - sens_result['eta'] = eta_centers - sens_result['xerr'] = eta_width / 2 + eta_binned = df.groupby("eta_bin") + sens_result = eta_binned["sens"].agg(["mean", "sem"]) + sens_result["eta"] = eta_centers + sens_result["xerr"] = eta_width / 2 sens_result.plot( - x='eta', - y='mean', - xerr='xerr', - yerr='sem', - linestyle='none', + x="eta", + y="mean", + xerr="xerr", + yerr="sem", + linestyle="none", capsize=1, marker=args.marker[ir], label=args.label[ir], - ax=ax) - ax.set_xlabel(r'$\eta$') - ax.set_ylabel('Avg. Number of sensitive modules / track') + ax=ax, + ) + ax.set_xlabel(r"$\eta$") + ax.set_ylabel("Avg. Number of sensitive modules / track") fig.show() - + except: print("The number of input files and labels must match") exit() From 2221c71d3aba529864c9048db0767cbc58b3658b Mon Sep 17 00:00:00 2001 From: Andreas Salzburger Date: Tue, 10 Sep 2024 10:20:22 +0200 Subject: [PATCH 3/7] update root file hashes --- Examples/Python/tests/root_file_hashes.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 3a2c69998744bcec7d608cf1f0efadb94b6235ce Mon Sep 17 00:00:00 2001 From: Andreas Salzburger Date: Thu, 12 Sep 2024 12:01:49 +0200 Subject: [PATCH 4/7] Update Examples/Scripts/Propagation/propagation_summary.py Co-authored-by: Benjamin Huth <37871400+benjaminhuth@users.noreply.github.com> --- Examples/Scripts/Propagation/propagation_summary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Scripts/Propagation/propagation_summary.py b/Examples/Scripts/Propagation/propagation_summary.py index 2e4d330af35..ed8fc1cdab0 100644 --- a/Examples/Scripts/Propagation/propagation_summary.py +++ b/Examples/Scripts/Propagation/propagation_summary.py @@ -79,7 +79,7 @@ eta_centers = 0.5 * (eta_bins[:-1] + eta_bins[1:]) eta_width = 8.0 / 100 - for ir, irfile in enumerate(args.input): + for irfile, label, marker in zip(args.input, args.label, args.marker): # load the tree tree = uproot.open(args.input[ir] + ":" + "propagation_summary") # get the numpy arrays From 06eaa8c35dce8ebe6aa734f41fa19c6843725003 Mon Sep 17 00:00:00 2001 From: Andreas Salzburger Date: Thu, 12 Sep 2024 12:02:45 +0200 Subject: [PATCH 5/7] Update propagation_summary.py --- Examples/Scripts/Propagation/propagation_summary.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Examples/Scripts/Propagation/propagation_summary.py b/Examples/Scripts/Propagation/propagation_summary.py index ed8fc1cdab0..bf00b949f26 100644 --- a/Examples/Scripts/Propagation/propagation_summary.py +++ b/Examples/Scripts/Propagation/propagation_summary.py @@ -73,6 +73,8 @@ try: + assert (len(args.input) == len(args.label) == len(args.marker)) + fig, ax = plt.subplots(1, 1, figsize=(11, 10)) eta_bins = np.linspace(-4, 4, 100) From b442ec4bf421252ce22ba190384079fe0a7b6afc Mon Sep 17 00:00:00 2001 From: Andreas Salzburger Date: Thu, 12 Sep 2024 13:46:14 +0200 Subject: [PATCH 6/7] Update propagation_summary.py --- Examples/Scripts/Propagation/propagation_summary.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Scripts/Propagation/propagation_summary.py b/Examples/Scripts/Propagation/propagation_summary.py index bf00b949f26..223e0a8278d 100644 --- a/Examples/Scripts/Propagation/propagation_summary.py +++ b/Examples/Scripts/Propagation/propagation_summary.py @@ -73,7 +73,7 @@ try: - assert (len(args.input) == len(args.label) == len(args.marker)) + assert len(args.input) == len(args.label) == len(args.marker) fig, ax = plt.subplots(1, 1, figsize=(11, 10)) From fed634461044b5fed764753d984b7061cd1d8566 Mon Sep 17 00:00:00 2001 From: Andreas Salzburger Date: Thu, 12 Sep 2024 15:58:45 +0200 Subject: [PATCH 7/7] Delete Examples/Scripts/Propagation/propagation_summary.py --- .../Propagation/propagation_summary.py | 130 ------------------ 1 file changed, 130 deletions(-) delete mode 100644 Examples/Scripts/Propagation/propagation_summary.py diff --git a/Examples/Scripts/Propagation/propagation_summary.py b/Examples/Scripts/Propagation/propagation_summary.py deleted file mode 100644 index 223e0a8278d..00000000000 --- a/Examples/Scripts/Propagation/propagation_summary.py +++ /dev/null @@ -1,130 +0,0 @@ -import matplotlib.pyplot as plt -import numpy as np -import pandas as pd -import argparse -import uproot -import seaborn as sns - -p = argparse.ArgumentParser() - -p.add_argument( - "-i", - "--input", - nargs="+", - type=str, - default="", - help="Input file(s) with propagation summary", -) - -p.add_argument( - "-l", - "--label", - nargs="+", - type=str, - default="", - help="Input label(s) for the propagation summary", -) - -p.add_argument( - "-c", - "--color", - nargs="+", - type=str, - default="", - help="Input label(s) for the propagation summary", -) - -p.add_argument( - "-m", - "--marker", - nargs="+", - type=str, - default=["o"], - choices=[ - "o", - "s", - "D", - "v", - "^", - "<", - ">", - "p", - "P", - "*", - "h", - "H", - "+", - "x", - "X", - "d", - ], - help="Input label(s) for the propagation summary", -) - -p.add_argument( - "-o", - "--output", - type=str, - default="", - help="Output file base name", -) - -args = p.parse_args() - -try: - - assert len(args.input) == len(args.label) == len(args.marker) - - fig, ax = plt.subplots(1, 1, figsize=(11, 10)) - - eta_bins = np.linspace(-4, 4, 100) - eta_centers = 0.5 * (eta_bins[:-1] + eta_bins[1:]) - eta_width = 8.0 / 100 - - for irfile, label, marker in zip(args.input, args.label, args.marker): - # load the tree - tree = uproot.open(args.input[ir] + ":" + "propagation_summary") - # get the numpy arrays - eta = tree["eta"].array(library="np") - phi = tree["phi"].array(library="np") - sens = tree["nSensitives"].array(library="np") - portals = tree["nPortals"].array(library="np") - materials = tree["nMaterials"].array(library="np") - - df = pd.DataFrame( - { - "eta": eta, - "phi": phi, - "sens": sens, - "portals": portals, - "materials": materials, - } - ) - - df["eta_bin"] = np.digitize(eta, bins=eta_bins) - - # grouby bin, so we can calculate stuff - eta_binned = df.groupby("eta_bin") - sens_result = eta_binned["sens"].agg(["mean", "sem"]) - sens_result["eta"] = eta_centers - sens_result["xerr"] = eta_width / 2 - - sens_result.plot( - x="eta", - y="mean", - xerr="xerr", - yerr="sem", - linestyle="none", - capsize=1, - marker=args.marker[ir], - label=args.label[ir], - ax=ax, - ) - ax.set_xlabel(r"$\eta$") - ax.set_ylabel("Avg. Number of sensitive modules / track") - - fig.show() - -except: - print("The number of input files and labels must match") - exit()