Skip to content

Commit

Permalink
Add utility to generate detector files for the detray inbuilt detectors
Browse files Browse the repository at this point in the history
  • Loading branch information
niermann999 committed Oct 29, 2023
1 parent 4bd5b98 commit ebed7e8
Show file tree
Hide file tree
Showing 14 changed files with 368 additions and 20 deletions.
3 changes: 3 additions & 0 deletions core/include/detray/intersection/detail/trajectories.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ class ray {
return this->dir();
}

/// @param dir new direction of the ray
DETRAY_HOST_DEVICE void set_dir(vector3 dir) { _dir = dir; }

/// @returns overstep tolerance to comply with track interface
DETRAY_HOST_DEVICE
scalar_type overstep_tolerance() const { return _overstep_tolerance; }
Expand Down
7 changes: 4 additions & 3 deletions io/include/detray/io/common/detail/detector_components_io.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,16 @@ class detector_component_writers final {
/// writers, while using the name map @param names for the detector
virtual void write(const detector_t& det,
const typename detector_t::name_map& names,
const std::ios_base::openmode mode) {
const std::ios_base::openmode mode,
const std::filesystem::path& file_path) {
// We have to at least write a geometry
assert(m_writers.size() != 0u &&
"No writers registered! Need at least a geometry writer");

// Call the write method on all optional writers
std::for_each(m_writers.begin(), m_writers.end(),
[&det, &names, mode](writer_ptr_t& writer) {
writer->write(det, names, mode);
[&det, &names, mode, &file_path](writer_ptr_t& writer) {
writer->write(det, names, mode, file_path);
});
}

Expand Down
22 changes: 14 additions & 8 deletions io/include/detray/io/common/detail/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,27 @@

// System include(s).
#include <ctime>
#include <filesystem>
#include <iomanip>
#include <locale>
#include <sstream>
#include <string>

namespace detray::detail {

/// Generate the filename for every distinct event
inline std::string get_event_filename(std::size_t event,
const std::string& suffix) {
std::stringstream stream;
stream << "event";
stream << std::setfill('0') << std::setw(9) << event;
stream << suffix;
return stream.str();
/// Check if a given file path exists and generate it if not
inline auto create_path(const std::string& outdir) {

auto path = std::filesystem::path(outdir);

if (not std::filesystem::exists(path)) {
std::error_code err;
if (!std::filesystem::create_directories(path, err)) {
throw std::runtime_error(err.message());
}
}

return path;
}

/// @returns a string that contains the current date and time
Expand Down
16 changes: 14 additions & 2 deletions io/include/detray/io/common/detector_writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
// Project include(s)
#include "detray/io/common/detail/detector_components_io.hpp"
#include "detray/io/common/detail/type_traits.hpp"
#include "detray/io/common/detail/utils.hpp"
#include "detray/io/json/json_writer.hpp"

// System include(s)
#include <filesystem>
#include <ios>

namespace detray {
Expand All @@ -21,6 +23,8 @@ namespace io {

/// @brief config struct for detector writing.
struct detector_writer_config {
/// The path to the output files
std::string m_path{"./"};
/// The output file format
detray::io::format m_format = detray::io::format::json;
/// Replace files in case they already exists
Expand All @@ -34,6 +38,7 @@ struct detector_writer_config {

/// Getters
/// @{
const std::string& path() const { return m_path; }
detray::io::format format() const { return m_format; }
bool replace_files() const { return m_replace; }
bool compactify_json() const { return m_compact_io; }
Expand All @@ -43,6 +48,10 @@ struct detector_writer_config {

/// Setters
/// @{
detector_writer_config& path(std::string p) {
m_path = std::move(p);
return *this;
}
detector_writer_config& format(detray::io::format f) {
m_format = f;
return *this;
Expand Down Expand Up @@ -114,12 +123,15 @@ void write_detector(detector_t& det, const typename detector_t::name_map& names,
// How to open the file
const std::ios_base::openmode out_mode{std::ios_base::out |
std::ios_base::binary};
auto mode = cfg.m_replace ? (out_mode | std::ios_base::trunc) : out_mode;
auto mode =
cfg.replace_files() ? (out_mode | std::ios_base::trunc) : out_mode;

const auto file_path = detray::detail::create_path(cfg.path());

// Get the writer
auto writer = detray::detail::assemble_writer<detector_t>(cfg);

writer.write(det, names, mode);
writer.write(det, names, mode, file_path);
}

} // namespace io
Expand Down
5 changes: 4 additions & 1 deletion io/include/detray/io/common/io_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "detray/tools/detector_builder.hpp"

// System include(s)
#include <filesystem>
#include <ios>
#include <string>
#include <string_view>
Expand Down Expand Up @@ -66,9 +67,11 @@ class writer_interface {

/// Writes the respective detector component to file. Since the detector
/// does not provide the volume names, the name map is also passed.
/// @note The existence of the file path has to be guaranteed by the caller
virtual std::string write(const detector_t&,
const typename detector_t::name_map&,
const std::ios_base::openmode) = 0;
const std::ios_base::openmode,
const std::filesystem::path&) = 0;

protected:
/// Serialize the common header information using the detector name
Expand Down
11 changes: 7 additions & 4 deletions io/include/detray/io/json/json_writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

// System include(s)
#include <cassert>
#include <filesystem>
#include <ios>
#include <stdexcept>
#include <string>
Expand All @@ -43,9 +44,10 @@ class json_writer final : public common_writer_t<detector_t, Args...> {
json_writer() : base_writer(".json") {}

/// Writes the geometry to file with a given name
virtual std::string write(const detector_t &det,
const typename detector_t::name_map &names,
const std::ios_base::openmode mode) override {
virtual std::string write(
const detector_t &det, const typename detector_t::name_map &names,
const std::ios_base::openmode mode = std::ios::out | std::ios::binary,
const std::filesystem::path &file_path = {"./"}) override {
// Assert output stream
assert(((mode == std::ios_base::out) or
(mode == (std::ios_base::out | std::ios_base::binary)) or
Expand All @@ -62,7 +64,8 @@ class json_writer final : public common_writer_t<detector_t, Args...> {

// Create a new file
std::string file_stem{det_name + "_" + base_writer::tag};
io::detail::file_handle file{file_stem, this->m_file_extension, mode};
io::detail::file_handle file{file_path / file_stem,
this->m_file_extension, mode};

// Write some general information
nlohmann::ordered_json out_json;
Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ if( DETRAY_BENCHMARKS )
add_subdirectory( benchmarks )
endif()
add_subdirectory( common )
add_subdirectory( detectors )
add_subdirectory( unit_tests )
add_subdirectory( validation )
7 changes: 7 additions & 0 deletions tests/detectors/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Detray library, part of the ACTS project (R&D line)
#
# (c) 2021-2023 CERN for the benefit of the ACTS project
#
# Mozilla Public License Version 2.0

add_subdirectory( src )
24 changes: 24 additions & 0 deletions tests/detectors/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#Detray 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

include( CMakeFindDependencyMacro )

find_dependency( Boost COMPONENTS program_options )

detray_add_executable(generate_toy_detector
"generate_toy_detector.cpp"
LINK_LIBRARIES Boost::program_options
detray::io detray::utils detray::core_array)

detray_add_executable(generate_wire_chamber
"generate_wire_chamber.cpp"
LINK_LIBRARIES Boost::program_options
detray::io detray::utils detray::core_array)

detray_add_executable(generate_telescope_detector
"generate_telescope_detector.cpp"
LINK_LIBRARIES Boost::program_options
detray::io detray::utils detray::core_array)
132 changes: 132 additions & 0 deletions tests/detectors/src/generate_telescope_detector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/** Detray 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
*/

// Project include(s)
#include "detray/definitions/units.hpp"
#include "detray/detectors/create_telescope_detector.hpp"
#include "detray/io/common/detector_writer.hpp"

// Vecmem include(s)
#include <vecmem/memory/host_memory_resource.hpp>

// Boost
#include <boost/program_options.hpp>

namespace po = boost::program_options;
using namespace detray;

namespace {

/// Generate and write a telescope detector, given the commandline variables
/// and a configuration for the detector writer @param writer_cfg
template <typename mask_shape_t, typename value_t>
void write_telecope(const po::variables_map &vm,
io::detector_writer_config &writer_cfg,
std::vector<value_t> &mask_params) {

using detector_t = detector<telescope_metadata<mask_shape_t>>;
using scalar_t = typename detector_t::scalar_type;
using transform3_t = typename detector_t::transform3;

detray::tel_det_config<mask_shape_t> tel_cfg{mask_params};

tel_cfg.n_surfaces(vm["modules"].as<unsigned int>());
tel_cfg.length(vm["length"].as<scalar_t>());
tel_cfg.mat_thickness(vm["thickness"].as<scalar_t>());

std::string direction{vm["direction"].as<std::string>()};
detray::detail::ray<transform3_t> r{};
if (direction == "x") {
r.set_dir({1.f, 0.f, 0.f});
} else if (direction == "y") {
r.set_dir({0.f, 1.f, 0.f});
} else if (direction == "z") {
r.set_dir({0.f, 0.f, 1.f});
}
tel_cfg.pilot_track(r);

// Build the detector
vecmem::host_memory_resource host_mr;
auto [tel_det, tel_names] = create_telescope_detector(host_mr, tel_cfg);

// Write to file
detray::io::write_detector(tel_det, tel_names, writer_cfg);
}

} // anonymous namespace

int main(int argc, char **argv) {

using scalar_t = detray::scalar;

// Options parsing
po::options_description desc("\nTelescope detector generation options");

std::vector<scalar_t> mask_params{
20.f * unit<scalar_t>::mm,
20.f * unit<scalar_t>::mm}; // < default values for rectangles
desc.add_options()("help", "produce help message")(
"outdir", po::value<std::string>(), "Output directory for files")(
"write_volume_graph", "writes the volume graph to file")(
"compactify_json", "not implemented")(
"write_material", "toggle material output")("write_grids",
"toggle grid output")(
"modules", po::value<unsigned int>()->default_value(10u),
"number of modules in telescope [1-20]")(
"type", po::value<std::string>()->default_value("rectangle"),
"type of the telescope modules [rectangle, trapezoid, annulus, ring, "
"cylinder]")(
"params", po::value<std::vector<scalar_t>>(&mask_params)->multitoken(),
"Mask values for the shape given in 'type'")(
"length",
po::value<scalar_t>()->default_value(500.f * unit<scalar_t>::mm),
"length of the telescope [mm]")(
"thickness",
po::value<scalar_t>()->default_value(1.f * unit<scalar_t>::mm),
"thickness of the module silicon material")(
"direction", po::value<std::string>()->default_value("z"),
"direction of the telescope in global frame [x, y, z]");

po::variables_map vm;
po::store(parse_command_line(argc, argv, desc,
po::command_line_style::unix_style ^
po::command_line_style::allow_short),
vm);
po::notify(vm);

// Help message
if (vm.count("help")) {
std::cout << desc << std::endl;
return EXIT_FAILURE;
}

// Configuration
detray::io::detector_writer_config writer_cfg{};
writer_cfg.format(detray::io::format::json).replace_files(false);

// General options
std::string outdir{vm.count("outdir") ? vm["outdir"].as<std::string>()
: "./telescope_detector/"};
writer_cfg.path(std::move(outdir));
writer_cfg.compactify_json(vm.count("compactify_json"));
writer_cfg.write_material(vm.count("write_material"));
writer_cfg.write_grids(vm.count("write_grids"));

// Build the geometry
std::string type{vm["type"].as<std::string>()};
if (type == "rectangle") {
write_telecope<rectangle2D<>>(vm, writer_cfg, mask_params);
} else if (type == "trapezoid") {
write_telecope<trapezoid2D<>>(vm, writer_cfg, mask_params);
} else if (type == "annulus") {
write_telecope<annulus2D<>>(vm, writer_cfg, mask_params);
} else if (type == "ring") {
write_telecope<ring2D<>>(vm, writer_cfg, mask_params);
} else if (type == "cylinder") {
write_telecope<cylinder2D<>>(vm, writer_cfg, mask_params);
}
}
Loading

0 comments on commit ebed7e8

Please sign in to comment.