From d0dce887e52871c9b1cd70214c028a77dbe8093b Mon Sep 17 00:00:00 2001 From: beomki-yeo Date: Tue, 28 Nov 2023 19:41:01 +0100 Subject: [PATCH] Add a event tree writer --- examples/run/cpu/seeding_example.cpp | 7 + examples/run/cpu/truth_finding_example.cpp | 7 + examples/run/cpu/truth_fitting_example.cpp | 6 + examples/run/cuda/seeding_example_cuda.cpp | 6 + .../run/cuda/truth_finding_example_cuda.cpp | 5 + .../run/cuda/truth_fitting_example_cuda.cpp | 8 + performance/CMakeLists.txt | 8 +- .../traccc/event/event_tree_writer.hpp | 60 +++++++ performance/src/event/event_tree_tool.hpp | 146 ++++++++++++++++++ performance/src/event/event_tree_writer.cpp | 79 ++++++++++ 10 files changed, 330 insertions(+), 2 deletions(-) create mode 100644 performance/include/traccc/event/event_tree_writer.hpp create mode 100644 performance/src/event/event_tree_tool.hpp create mode 100644 performance/src/event/event_tree_writer.cpp diff --git a/examples/run/cpu/seeding_example.cpp b/examples/run/cpu/seeding_example.cpp index 8ba9104459..b6bf687919 100644 --- a/examples/run/cpu/seeding_example.cpp +++ b/examples/run/cpu/seeding_example.cpp @@ -24,6 +24,7 @@ // performance #include "traccc/efficiency/finding_performance_writer.hpp" #include "traccc/efficiency/seeding_performance_writer.hpp" +#include "traccc/event/event_tree_writer.hpp" #include "traccc/resolution/fitting_performance_writer.hpp" // options @@ -74,6 +75,8 @@ int seq_run(const traccc::seeding_input_config& /*i_cfg*/, vecmem::host_memory_resource host_mr; // Performance writer + traccc::event_tree_writer evt_tree_writer( + traccc::event_tree_writer::config{}); traccc::seeding_performance_writer sd_performance_writer( traccc::seeding_performance_writer::config{}); traccc::finding_performance_writer find_performance_writer( @@ -207,6 +210,9 @@ int seq_run(const traccc::seeding_input_config& /*i_cfg*/, traccc::event_map2 evt_map(event, common_opts.input_directory, common_opts.input_directory, common_opts.input_directory); + + evt_tree_writer.write(traccc::get_data(track_states), evt_map); + sd_performance_writer.write(vecmem::get_data(seeds), vecmem::get_data(spacepoints_per_event), evt_map); @@ -226,6 +232,7 @@ int seq_run(const traccc::seeding_input_config& /*i_cfg*/, } if (common_opts.check_performance) { + evt_tree_writer.finalize(); sd_performance_writer.finalize(); find_performance_writer.finalize(); fit_performance_writer.finalize(); diff --git a/examples/run/cpu/truth_finding_example.cpp b/examples/run/cpu/truth_finding_example.cpp index 9f7fa62ee4..ece926d82d 100644 --- a/examples/run/cpu/truth_finding_example.cpp +++ b/examples/run/cpu/truth_finding_example.cpp @@ -9,6 +9,7 @@ #include "traccc/definitions/common.hpp" #include "traccc/definitions/primitives.hpp" #include "traccc/efficiency/finding_performance_writer.hpp" +#include "traccc/event/event_tree_writer.hpp" #include "traccc/finding/finding_algorithm.hpp" #include "traccc/fitting/fitting_algorithm.hpp" #include "traccc/fitting/kalman_filter/kalman_fitter.hpp" @@ -65,6 +66,8 @@ int seq_run(const traccc::finding_input_config& i_cfg, vecmem::host_memory_resource host_mr; // Performance writer + traccc::event_tree_writer evt_tree_writer( + traccc::event_tree_writer::config{}); traccc::finding_performance_writer find_performance_writer( traccc::finding_performance_writer::config{}); traccc::fitting_performance_writer fit_performance_writer( @@ -172,6 +175,9 @@ int seq_run(const traccc::finding_input_config& i_cfg, const unsigned int n_fitted_tracks = track_states.size(); if (common_opts.check_performance) { + + evt_tree_writer.write(traccc::get_data(track_states), evt_map2); + find_performance_writer.write(traccc::get_data(track_candidates), evt_map2); @@ -187,6 +193,7 @@ int seq_run(const traccc::finding_input_config& i_cfg, } if (common_opts.check_performance) { + evt_tree_writer.finalize(); find_performance_writer.finalize(); fit_performance_writer.finalize(); } diff --git a/examples/run/cpu/truth_fitting_example.cpp b/examples/run/cpu/truth_fitting_example.cpp index 93f2d98178..d164b3420b 100644 --- a/examples/run/cpu/truth_fitting_example.cpp +++ b/examples/run/cpu/truth_fitting_example.cpp @@ -8,6 +8,7 @@ // Project include(s). #include "traccc/definitions/common.hpp" #include "traccc/definitions/primitives.hpp" +#include "traccc/event/event_tree_writer.hpp" #include "traccc/fitting/fitting_algorithm.hpp" #include "traccc/fitting/kalman_filter/kalman_fitter.hpp" #include "traccc/io/read_geometry.hpp" @@ -84,6 +85,8 @@ int main(int argc, char* argv[]) { vecmem::host_memory_resource host_mr; // Performance writer + traccc::event_tree_writer evt_tree_writer( + traccc::event_tree_writer::config{}); traccc::fitting_performance_writer fit_performance_writer( traccc::fitting_performance_writer::config{}); @@ -153,6 +156,8 @@ int main(int argc, char* argv[]) { if (common_opts.check_performance) { + evt_tree_writer.write(traccc::get_data(track_states), evt_map2); + for (unsigned int i = 0; i < n_fitted_tracks; i++) { const auto& trk_states_per_track = track_states.at(i).items; @@ -165,6 +170,7 @@ int main(int argc, char* argv[]) { } if (common_opts.check_performance) { + evt_tree_writer.finalize(); fit_performance_writer.finalize(); } diff --git a/examples/run/cuda/seeding_example_cuda.cpp b/examples/run/cuda/seeding_example_cuda.cpp index 1cc96f6094..5c03f9de02 100644 --- a/examples/run/cuda/seeding_example_cuda.cpp +++ b/examples/run/cuda/seeding_example_cuda.cpp @@ -17,6 +17,7 @@ #include "traccc/efficiency/nseed_performance_writer.hpp" #include "traccc/efficiency/seeding_performance_writer.hpp" #include "traccc/efficiency/track_filter.hpp" +#include "traccc/event/event_tree_writer.hpp" #include "traccc/finding/finding_algorithm.hpp" #include "traccc/fitting/fitting_algorithm.hpp" #include "traccc/io/read_geometry.hpp" @@ -92,6 +93,8 @@ int seq_run(const traccc::seeding_input_config& /*i_cfg*/, traccc::memory_resource mr{device_mr, &cuda_host_mr}; // Performance writer + traccc::event_tree_writer evt_tree_writer( + traccc::event_tree_writer::config{}); traccc::seeding_performance_writer sd_performance_writer( traccc::seeding_performance_writer::config{}); traccc::finding_performance_writer find_performance_writer( @@ -432,6 +435,8 @@ int seq_run(const traccc::seeding_input_config& /*i_cfg*/, traccc::event_map2 evt_map(event, common_opts.input_directory, common_opts.input_directory, common_opts.input_directory); + + evt_tree_writer.write(traccc::get_data(track_states), evt_map); sd_performance_writer.write( vecmem::get_data(seeds_cuda), vecmem::get_data(sp_reader_output.spacepoints), evt_map); @@ -452,6 +457,7 @@ int seq_run(const traccc::seeding_input_config& /*i_cfg*/, } if (common_opts.check_performance) { + evt_tree_writer.finalize(); sd_performance_writer.finalize(); nsd_performance_writer.finalize(); find_performance_writer.finalize(); diff --git a/examples/run/cuda/truth_finding_example_cuda.cpp b/examples/run/cuda/truth_finding_example_cuda.cpp index 699ccdd26b..2ef22171f9 100644 --- a/examples/run/cuda/truth_finding_example_cuda.cpp +++ b/examples/run/cuda/truth_finding_example_cuda.cpp @@ -14,6 +14,7 @@ #include "traccc/device/container_d2h_copy_alg.hpp" #include "traccc/device/container_h2d_copy_alg.hpp" #include "traccc/efficiency/finding_performance_writer.hpp" +#include "traccc/event/event_tree_writer.hpp" #include "traccc/finding/finding_algorithm.hpp" #include "traccc/fitting/fitting_algorithm.hpp" #include "traccc/fitting/kalman_filter/kalman_fitter.hpp" @@ -86,6 +87,8 @@ int seq_run(const traccc::finding_input_config& i_cfg, traccc::memory_resource mr{device_mr, &cuda_host_mr}; // Performance writer + traccc::event_tree_writer evt_tree_writer( + traccc::event_tree_writer::config{}); traccc::finding_performance_writer find_performance_writer( traccc::finding_performance_writer::config{}); traccc::fitting_performance_writer fit_performance_writer( @@ -318,6 +321,7 @@ int seq_run(const traccc::finding_input_config& i_cfg, n_fitted_tracks_cuda += track_states_cuda.size(); if (common_opts.check_performance) { + evt_tree_writer.write(traccc::get_data(track_states), evt_map2); find_performance_writer.write( traccc::get_data(track_candidates_cuda), evt_map2); @@ -334,6 +338,7 @@ int seq_run(const traccc::finding_input_config& i_cfg, } if (common_opts.check_performance) { + evt_tree_writer.finalize(); find_performance_writer.finalize(); fit_performance_writer.finalize(); } diff --git a/examples/run/cuda/truth_fitting_example_cuda.cpp b/examples/run/cuda/truth_fitting_example_cuda.cpp index 50fe6799a4..94f8addf85 100644 --- a/examples/run/cuda/truth_fitting_example_cuda.cpp +++ b/examples/run/cuda/truth_fitting_example_cuda.cpp @@ -12,6 +12,7 @@ #include "traccc/definitions/primitives.hpp" #include "traccc/device/container_d2h_copy_alg.hpp" #include "traccc/device/container_h2d_copy_alg.hpp" +#include "traccc/event/event_tree_writer.hpp" #include "traccc/fitting/fitting_algorithm.hpp" #include "traccc/fitting/kalman_filter/kalman_fitter.hpp" #include "traccc/io/read_geometry.hpp" @@ -107,6 +108,8 @@ int main(int argc, char* argv[]) { traccc::memory_resource mr{device_mr, &cuda_host_mr}; // Performance writer + traccc::event_tree_writer evt_tree_writer( + traccc::event_tree_writer::config{}); traccc::fitting_performance_writer fit_performance_writer( traccc::fitting_performance_writer::config{}); @@ -246,6 +249,10 @@ int main(int argc, char* argv[]) { n_fitted_tracks_cuda += track_states_cuda.size(); if (common_opts.check_performance) { + + evt_tree_writer.write(traccc::get_data(track_states_cuda), + evt_map2); + for (unsigned int i = 0; i < track_states_cuda.size(); i++) { const auto& trk_states_per_track = track_states_cuda.at(i).items; @@ -259,6 +266,7 @@ int main(int argc, char* argv[]) { } if (common_opts.check_performance) { + evt_tree_writer.finalize(); fit_performance_writer.finalize(); } diff --git a/performance/CMakeLists.txt b/performance/CMakeLists.txt index ecba6aec5e..4a626a5398 100644 --- a/performance/CMakeLists.txt +++ b/performance/CMakeLists.txt @@ -9,6 +9,10 @@ include( traccc-compiler-options-cpp ) # Set up the build of the traccc::performance library. traccc_add_library( traccc_performance performance TYPE SHARED + # Event plot code + "src/event/event_tree_tool.hpp" + "src/event/event_tree_writer.cpp" + "include/traccc/event/event_tree_writer.hpp" # Efficiency calculation code. "src/efficiency/duplication_plot_tool.hpp" "src/efficiency/eff_plot_tool.hpp" @@ -68,9 +72,9 @@ target_link_libraries( traccc_performance # Use ROOT in traccc::performance, if requested. if( TRACCC_USE_ROOT ) - find_package( ROOT COMPONENTS Core RIO Hist REQUIRED ) + find_package( ROOT COMPONENTS Core RIO Hist Tree REQUIRED ) target_link_libraries( traccc_performance - PRIVATE ROOT::Core ROOT::RIO ROOT::Hist ) + PRIVATE ROOT::Core ROOT::RIO ROOT::Hist ROOT::Tree ) target_compile_definitions( traccc_performance PRIVATE TRACCC_HAVE_ROOT ) endif() diff --git a/performance/include/traccc/event/event_tree_writer.hpp b/performance/include/traccc/event/event_tree_writer.hpp new file mode 100644 index 0000000000..4275d03d1b --- /dev/null +++ b/performance/include/traccc/event/event_tree_writer.hpp @@ -0,0 +1,60 @@ +/** TRACCC library, part of the ACTS project (R&D line) + * + * (c) 2023 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +#pragma once + +// Local include(s). +#include "traccc/utils/helpers.hpp" + +// Project include(s). +#include "traccc/edm/track_state.hpp" +#include "traccc/io/event_map2.hpp" + +namespace traccc { +namespace details { + +/// Data members that should not pollute the API of +/// @c traccc::event_tree_writer +struct event_tree_writer_data; + +} // namespace details + +class event_tree_writer { + + public: + /// Configuration for the tool + struct config { + + /// Output filename. + std::string file_path = "event_tree.root"; + /// Output file mode + std::string file_mode = "RECREATE"; + }; + + /// Construct from configuration and log level. + /// @param cfg The configuration + /// + event_tree_writer(const config& cfg); + + /// Destructor + ~event_tree_writer(); + + void write(const track_state_container_types::const_view& track_states_view, + const event_map2& evt_map); + + void finalize(); + + private: + /// Configuration for the tool + config m_cfg; + + /// Opaque data members for the class + std::unique_ptr m_data; + +}; // class event_tree_writer + +} // namespace traccc \ No newline at end of file diff --git a/performance/src/event/event_tree_tool.hpp b/performance/src/event/event_tree_tool.hpp new file mode 100644 index 0000000000..b8760fbaf2 --- /dev/null +++ b/performance/src/event/event_tree_tool.hpp @@ -0,0 +1,146 @@ +/** TRACCC library, part of the ACTS project (R&D line) + * + * (c) 2023 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +#pragma once + +// Local include(s). +#include "../utils/helpers.hpp" + +// Project include(s). +#include "traccc/edm/particle.hpp" +#include "traccc/edm/track_state.hpp" + +// ROOT include(s). +#ifdef TRACCC_HAVE_ROOT +#include +#include +#endif // TRACCC_HAVE_ROOT + +// System include(s). +#include + +namespace traccc { + +class event_tree_tool { + + public: + /// @brief Nested Cache struct + struct event_tree_cache { +#ifdef TRACCC_HAVE_ROOT + // Particles truth information + std::unique_ptr ptc_tree = + std::make_unique("ptc_tree", "Tree for truth particles"); + + // Fit results information + std::unique_ptr fit_tree = + std::make_unique("fit_tree", "Tree for fitting results"); +#endif // TRACCC_HAVE_ROOT + + float vx; + float vy; + float vz; + float vt; + float phi; + float theta; + float qop; + float qopT; + float qopz; + float charge; + + float fit_loc0; + float fit_loc1; + float fit_phi; + float fit_theta; + float fit_time; + float fit_qop; + float fit_qopT; + float fit_qopz; + float fit_ndf; + float fit_chi2; + }; + + void setup(event_tree_cache& cache) { + (void)cache; + +#ifdef TRACCC_HAVE_ROOT + cache.ptc_tree->Branch("vx", &cache.vx, "vx/F"); + cache.ptc_tree->Branch("vy", &cache.vy, "vy/F"); + cache.ptc_tree->Branch("vz", &cache.vz, "vz/F"); + cache.ptc_tree->Branch("vt", &cache.vt, "vt/F"); + cache.ptc_tree->Branch("phi", &cache.phi, "phi/F"); + cache.ptc_tree->Branch("theta", &cache.theta, "theta/F"); + cache.ptc_tree->Branch("charge", &cache.charge, "charge/F"); + cache.ptc_tree->Branch("qop", &cache.qop, "qop/F"); + cache.ptc_tree->Branch("qopT", &cache.qopT, "qopT/F"); + cache.ptc_tree->Branch("qopz", &cache.qopz, "qopz/F"); + + cache.fit_tree->Branch("fit_loc0", &cache.fit_loc0, "fit_loc0/F"); + cache.fit_tree->Branch("fit_loc1", &cache.fit_loc1, "fit_loc1/F"); + cache.fit_tree->Branch("fit_phi", &cache.fit_phi, "fit_phi/F"); + cache.fit_tree->Branch("fit_theta", &cache.fit_theta, "fit_theta/F"); + cache.fit_tree->Branch("fit_time", &cache.fit_time, "fit_time/F"); + cache.fit_tree->Branch("fit_qop", &cache.fit_qop, "fit_qop/F"); + cache.fit_tree->Branch("fit_qopT", &cache.fit_qopT, "fit_qopT/F"); + cache.fit_tree->Branch("fit_qopz", &cache.fit_qopz, "fit_qopz/F"); + cache.fit_tree->Branch("fit_ndf", &cache.fit_ndf, "fit_ndf/F"); + cache.fit_tree->Branch("fit_chi2", &cache.fit_chi2, "fit_chi2/F"); +#endif // TRACCC_HAVE_ROOT + } + + void fill(event_tree_cache& cache, const particle& truth_particle) const { + + cache.vx = truth_particle.pos[0]; + cache.vy = truth_particle.pos[1]; + cache.vz = truth_particle.pos[2]; + cache.vt = truth_particle.time; + cache.phi = getter::phi(truth_particle.mom); + cache.theta = getter::theta(truth_particle.mom); + cache.qop = truth_particle.charge / getter::norm(truth_particle.mom); + cache.qopT = truth_particle.charge / getter::perp(truth_particle.mom); + cache.qopz = truth_particle.charge / std::abs(truth_particle.mom[2]); + cache.charge = truth_particle.charge; + +#ifdef TRACCC_HAVE_ROOT + cache.ptc_tree->Fill(); +#endif // TRACCC_HAVE_ROOT + } + + void fill( + event_tree_cache& cache, + const traccc::track_state_container_types::const_device::element_view& + fit_track) const { + const auto& vec = fit_track.header.fit_params.vector(); + + cache.fit_loc0 = getter::element(vec, e_bound_loc0, 0u); + cache.fit_loc1 = getter::element(vec, e_bound_loc1, 0u); + cache.fit_phi = getter::element(vec, e_bound_phi, 0u); + cache.fit_theta = getter::element(vec, e_bound_theta, 0u); + cache.fit_time = getter::element(vec, e_bound_time, 0u); + cache.fit_qop = getter::element(vec, e_bound_qoverp, 0u); + cache.fit_qopT = fit_track.header.fit_params.qopT(); + cache.fit_qopz = fit_track.header.fit_params.qopz(); + cache.fit_ndf = fit_track.header.ndf; + cache.fit_chi2 = fit_track.header.chi2; + +#ifdef TRACCC_HAVE_ROOT + cache.fit_tree->Fill(); +#endif // TRACCC_HAVE_ROOT + } + + void write(const event_tree_cache& cache) const { + + // Avoid unused variable warnings when building the code without ROOT. + (void)cache; + +#ifdef TRACCC_HAVE_ROOT + cache.ptc_tree->Write(); + cache.fit_tree->Write(); +#endif // TRACCC_HAVE_ROOT + } +}; + +} // namespace traccc \ No newline at end of file diff --git a/performance/src/event/event_tree_writer.cpp b/performance/src/event/event_tree_writer.cpp new file mode 100644 index 0000000000..dd8f3f18b1 --- /dev/null +++ b/performance/src/event/event_tree_writer.cpp @@ -0,0 +1,79 @@ +/** TRACCC library, part of the ACTS project (R&D line) + * + * (c) 2023 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +// Local include(s). +#include "traccc/event/event_tree_writer.hpp" + +#include "event_tree_tool.hpp" + +// ROOT include(s). +#ifdef TRACCC_HAVE_ROOT +#include +#endif // TRACCC_HAVE_ROOT + +namespace traccc { + +namespace details { + +struct event_tree_writer_data { + + /// Plot tool for event data + event_tree_tool m_event_tree_tool; + event_tree_tool::event_tree_cache m_event_tree_cache; + +}; // struct event_tree_writer_data + +} // namespace details + +event_tree_writer::event_tree_writer(const config& cfg) + : m_cfg(cfg), m_data(std::make_unique()) { + + m_data->m_event_tree_tool.setup(m_data->m_event_tree_cache); +} + +event_tree_writer::~event_tree_writer() {} + +void event_tree_writer::write( + const track_state_container_types::const_view& track_states_view, + const event_map2& evt_map) { + + for (auto const& [key, ptc] : evt_map.ptc_map) { + m_data->m_event_tree_tool.fill(m_data->m_event_tree_cache, ptc); + } + + // Iterate over the track state container. + track_state_container_types::const_device track_states(track_states_view); + + const unsigned int n_tracks = track_states.size(); + + for (unsigned int i = 0; i < n_tracks; i++) { + m_data->m_event_tree_tool.fill(m_data->m_event_tree_cache, + track_states.at(i)); + } +} + +void event_tree_writer::finalize() { + +#ifdef TRACCC_HAVE_ROOT + // Open the output file. + std::unique_ptr ofile( + TFile::Open(m_cfg.file_path.c_str(), m_cfg.file_mode.c_str())); + if ((!ofile) || ofile->IsZombie()) { + throw std::runtime_error("Could not open output file \"" + + m_cfg.file_path + "\" in mode \"" + + m_cfg.file_mode + "\""); + } + ofile->cd(); +#else + std::cout << "ROOT file \"" << m_cfg.file_path << "\" is NOT created" + << std::endl; +#endif // TRACCC_HAVE_ROOT + + m_data->m_event_tree_tool.write(m_data->m_event_tree_cache); +} + +} // namespace traccc