diff --git a/io/CMakeLists.txt b/io/CMakeLists.txt index 6c3c6bbe5..0b3c04b3e 100644 --- a/io/CMakeLists.txt +++ b/io/CMakeLists.txt @@ -70,6 +70,10 @@ traccc_add_library( traccc_io io TYPE SHARED "src/csv/make_particle_reader.cpp" "src/csv/read_particles.hpp" "src/csv/read_particles.cpp" + "src/json/read_digitization_config.hpp" + "src/json/read_digitization_config.cpp" + "src/json/write_digitization_config.hpp" + "src/json/write_digitization_config.cpp" "src/obj/write_seeds.hpp" "src/obj/write_seeds.cpp" "src/obj/write_spacepoints.hpp" diff --git a/io/include/traccc/io/write.hpp b/io/include/traccc/io/write.hpp index 64de9f32f..9d6ed8cc4 100644 --- a/io/include/traccc/io/write.hpp +++ b/io/include/traccc/io/write.hpp @@ -13,6 +13,7 @@ #include "traccc/edm/spacepoint.hpp" #include "traccc/edm/track_candidate.hpp" #include "traccc/io/data_format.hpp" +#include "traccc/io/digitization_config.hpp" // Detray include(s). #include "detray/core/detector.hpp" @@ -81,4 +82,13 @@ void write(std::size_t event, std::string_view directory, track_candidate_container_types::const_view tracks, const detray::detector<>& detector); +/// Write a digitization configuration to a file +/// +/// @param filename The name of the file to write the data to +/// @param format The format of the output file +/// @param config The digitization configuration to write +/// +void write(std::string_view filename, data_format format, + const digitization_config& config); + } // namespace traccc::io diff --git a/io/src/json/read_digitization_config.cpp b/io/src/json/read_digitization_config.cpp new file mode 100644 index 000000000..f52f29beb --- /dev/null +++ b/io/src/json/read_digitization_config.cpp @@ -0,0 +1,71 @@ +/** TRACCC library, part of the ACTS project (R&D line) + * + * (c) 2022-2024 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +// Local include(s). +#include "read_digitization_config.hpp" + +// Acts include(s). +#include +#include +#include + +// System include(s). +#include + +namespace traccc { + +/// Function allowing the read of @c traccc::module_digitization_config objects +/// +/// Note that this function must be declared in the same namespace as +/// @c traccc::module_digitization_config for nlohmann_json to work correctly. +/// +void from_json(const nlohmann::json& json, module_digitization_config& cfg) { + + // Names/keywords used in the JSON file. + static const char* geometric = "geometric"; + static const char* segmentation = "segmentation"; + static const char* binningdata = "binningdata"; + static const char* bins = "bins"; + + // Read the binning information, if possible. + if (json.find(geometric) != json.end()) { + const auto& json_geom = json[geometric]; + if (json_geom.find(segmentation) != json_geom.end()) { + Acts::from_json(json_geom[segmentation], cfg.segmentation); + // If we only have 1 bins along any axis, then this is a 1D module. + const auto& json_segm = json_geom[segmentation]; + for (const auto& bindata : json_segm[binningdata]) { + if (bindata[bins].get() == 1) { + cfg.dimensions = 1; + break; + } + } + } + } +} + +namespace io::json { + +digitization_config read_digitization_config(std::string_view filename) { + + // Open the input file. Relying on exceptions for the error handling. + std::ifstream infile(filename.data(), std::ifstream::binary); + infile.exceptions(std::ofstream::failbit | std::ofstream::badbit); + + // Read the contents of the file into a JSON object. + nlohmann::json json; + infile >> json; + + // Construct the object from the JSON configuration. + static const Acts::GeometryHierarchyMapJsonConverter< + module_digitization_config> + converter{"digitization-configuration"}; + return converter.fromJson(json); +} + +} // namespace io::json +} // namespace traccc diff --git a/io/src/json/read_digitization_config.hpp b/io/src/json/read_digitization_config.hpp new file mode 100644 index 000000000..364d4d1fe --- /dev/null +++ b/io/src/json/read_digitization_config.hpp @@ -0,0 +1,26 @@ +/** TRACCC library, part of the ACTS project (R&D line) + * + * (c) 2022-2024 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +#pragma once + +// Project include(s). +#include "traccc/io/digitization_config.hpp" + +// System include(s). +#include + +namespace traccc::io::json { + +/// Read the detector digitization configuration from a JSON input file +/// +/// @param filename The name of the file to read the data from +/// @return An object describing the digitization configuration of the +/// detector +/// +digitization_config read_digitization_config(std::string_view filename); + +} // namespace traccc::io::json diff --git a/io/src/json/write_digitization_config.cpp b/io/src/json/write_digitization_config.cpp new file mode 100644 index 000000000..4482aaaf1 --- /dev/null +++ b/io/src/json/write_digitization_config.cpp @@ -0,0 +1,59 @@ +/** TRACCC library, part of the ACTS project (R&D line) + * + * (c) 2024 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +// Local include(s). +#include "write_digitization_config.hpp" + +// Acts include(s). +#include +#include +#include + +// System include(s). +#include + +namespace traccc { + +/// Function allowing the write of @c traccc::module_digitization_config objects +/// +/// Note that this function must be declared in the same namespace as +/// @c traccc::module_digitization_config for nlohmann_json to work correctly. +/// +void to_json(nlohmann::json& json, const module_digitization_config& cfg) { + + // Names/keywords used in the JSON file. + static const char* geometric = "geometric"; + static const char* segmentation = "segmentation"; + + // Write the binning information. + json[geometric][segmentation] = cfg.segmentation; + + // The dimensions variable is determined on reading from the segmentation + // information, so it does not need to be written separately. +} + +namespace io::json { + +void write_digitization_config(std::string_view filename, + const digitization_config& config) { + + // Construct the JSON object to be written. + static const Acts::GeometryHierarchyMapJsonConverter< + module_digitization_config> + converter{"digitization-configuration"}; + const nlohmann::json json = converter.toJson(config, nullptr); + + // Open the input file. Relying on exceptions for the error handling. + std::ofstream outfile(filename.data(), std::ifstream::binary); + outfile.exceptions(std::ofstream::failbit | std::ofstream::badbit); + + // Write the JSON object to the file. + outfile << json.dump(4); +} + +} // namespace io::json +} // namespace traccc diff --git a/io/src/json/write_digitization_config.hpp b/io/src/json/write_digitization_config.hpp new file mode 100644 index 000000000..ed21d94cf --- /dev/null +++ b/io/src/json/write_digitization_config.hpp @@ -0,0 +1,26 @@ +/** TRACCC library, part of the ACTS project (R&D line) + * + * (c) 2024 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +#pragma once + +// Project include(s). +#include "traccc/io/digitization_config.hpp" + +// System include(s). +#include + +namespace traccc::io::json { + +/// Write a digitization configuration to a file +/// +/// @param filename The name of the file to write the data to +/// @param config The digitization configuration to write +/// +void write_digitization_config(std::string_view filename, + const digitization_config& config); + +} // namespace traccc::io::json diff --git a/io/src/read_digitization_config.cpp b/io/src/read_digitization_config.cpp index fbba17ae6..a4b2a1c8d 100644 --- a/io/src/read_digitization_config.cpp +++ b/io/src/read_digitization_config.cpp @@ -8,71 +8,13 @@ // Local include(s). #include "traccc/io/read_digitization_config.hpp" +#include "json/read_digitization_config.hpp" #include "traccc/io/utils.hpp" -// Acts include(s). -#include -#include -#include - // System include(s). -#include -#include #include -namespace traccc { - -/// Function allowing the read of @c traccc::module_digitization_config objects -/// -/// Note that this function must be declared in the same namespace as -/// @c traccc::module_digitization_config for nlohmann_json to work correctly. -/// -void from_json(const nlohmann::json& json, module_digitization_config& cfg) { - - // Names/keywords used in the JSON file. - static const char* geometric = "geometric"; - static const char* segmentation = "segmentation"; - static const char* binningdata = "binningdata"; - static const char* bins = "bins"; - - // Read the binning information, if possible. - if (json.find(geometric) != json.end()) { - const auto& json_geom = json[geometric]; - if (json_geom.find(segmentation) != json_geom.end()) { - Acts::from_json(json_geom[segmentation], cfg.segmentation); - // If we only have 1 bins along any axis, then this is a 1D module. - const auto& json_segm = json_geom[segmentation]; - for (const auto& bindata : json_segm[binningdata]) { - if (bindata[bins].get() == 1) { - cfg.dimensions = 1; - break; - } - } - } - } -} - -namespace io { -namespace json { - -digitization_config read_digitization_config(std::string_view filename) { - - // Open the input file. Relying on exceptions for the error handling. - std::ifstream infile(filename.data(), std::ifstream::binary); - infile.exceptions(std::ofstream::failbit | std::ofstream::badbit); - - // Read the contents of the file into a JSON object. - nlohmann::json json; - infile >> json; - - // Construct the object from the JSON configuration. - static const Acts::GeometryHierarchyMapJsonConverter< - module_digitization_config> - converter{"digitization-configuration"}; - return converter.fromJson(json); -} - -} // namespace json +namespace traccc::io { digitization_config read_digitization_config(std::string_view filename, data_format format) { @@ -89,5 +31,4 @@ digitization_config read_digitization_config(std::string_view filename, } } -} // namespace io -} // namespace traccc +} // namespace traccc::io diff --git a/io/src/write.cpp b/io/src/write.cpp index 7b053daee..39d3f6953 100644 --- a/io/src/write.cpp +++ b/io/src/write.cpp @@ -8,6 +8,7 @@ // Local include(s). #include "traccc/io/write.hpp" +#include "json/write_digitization_config.hpp" #include "obj/write_seeds.hpp" #include "obj/write_spacepoints.hpp" #include "obj/write_track_candidates.hpp" @@ -120,4 +121,17 @@ void write(std::size_t event, std::string_view directory, } } +void write(std::string_view filename, data_format format, + const digitization_config& config) { + + switch (format) { + case data_format::json: + json::write_digitization_config(get_absolute_path(filename), + config); + break; + default: + throw std::invalid_argument("Unsupported data format"); + } +} + } // namespace traccc::io diff --git a/tests/io/CMakeLists.txt b/tests/io/CMakeLists.txt index 6ac73b3db..3bceb3719 100644 --- a/tests/io/CMakeLists.txt +++ b/tests/io/CMakeLists.txt @@ -1,14 +1,15 @@ # TRACCC library, part of the ACTS project (R&D line) # -# (c) 2021-2022 CERN for the benefit of the ACTS project +# (c) 2021-2024 CERN for the benefit of the ACTS project # # Mozilla Public License Version 2.0 # Declare the io library test(s). -traccc_add_test( io - "test_binary.cpp" - "test_csv.cpp" +traccc_add_test( io + "test_binary.cpp" + "test_csv.cpp" "test_event_data.cpp" + "test_json.cpp" LINK_LIBRARIES GTest::gtest_main traccc_tests_common traccc::core traccc::io traccc::performance ) diff --git a/tests/io/test_json.cpp b/tests/io/test_json.cpp new file mode 100644 index 000000000..31bb942f1 --- /dev/null +++ b/tests/io/test_json.cpp @@ -0,0 +1,56 @@ +/** TRACCC library, part of the ACTS project (R&D line) + * + * (c) 2024 CERN for the benefit of the ACTS project + * + * Mozilla Public License Version 2.0 + */ + +// Project include(s). +#include "traccc/io/read_digitization_config.hpp" +#include "traccc/io/utils.hpp" +#include "traccc/io/write.hpp" + +// GTest include(s). +#include + +// System include(s). +#include +#include +#include + +TEST(io_json, digitization_config) { + + // Read in the ODD digitization configuration. + const traccc::digitization_config orig = + traccc::io::read_digitization_config( + traccc::io::get_absolute_path( + (std::filesystem::path("geometries") / + std::filesystem::path("odd") / + std::filesystem::path("odd-digi-geometric-config.json")) + .native()), + traccc::data_format::json); + + // Write the digitization configuration to a temporary file. + const std::string tempfile = + (std::filesystem::temp_directory_path() / + std::filesystem::path("traccc-odd-digi-config-io-test.json")) + .native(); + traccc::io::write(tempfile, traccc::data_format::json, orig); + + // Read in the digitization configuration from the temporary file. + const traccc::digitization_config copy = + traccc::io::read_digitization_config(tempfile, + traccc::data_format::json); + + // Remove the temporary file. + std::remove(tempfile.c_str()); + + // Check that the two configurations are the same. + ASSERT_EQ(orig.size(), copy.size()); + auto orig_it = orig.begin(); + auto copy_it = copy.begin(); + for (; orig_it != orig.end(); ++orig_it, ++copy_it) { + EXPECT_EQ(orig_it->segmentation, copy_it->segmentation); + EXPECT_EQ(orig_it->dimensions, copy_it->dimensions); + } +}