Line data Source code
1 : // SPDX-License-Identifier: BSD-3-Clause
2 : // Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
3 : /// @file
4 : /// @author Simon Heybrock
5 : #include "scipp/core/eigen.h"
6 : #include "scipp/core/spatial_transforms.h"
7 : #include "scipp/variable/structure_array_variable.tcc"
8 : #include "scipp/variable/structures.h"
9 : #include "scipp/variable/variable.h"
10 :
11 : namespace scipp::variable {
12 :
13 : // TODO For now we use hard-coded field names and offsets. The intention is to
14 : // generalize StructureArrayModel to support more general structures. Field
15 : // names and sizes/offsets would then be stored as part of the model, and would
16 : // be initialized dynamically at runtime.
17 : template <>
18 : constexpr auto structure_element_offset<Eigen::Vector3d> =
19 43 : [](const std::string &key) {
20 : static std::map<std::string, scipp::index> offsets{
21 52 : {"x", 0}, {"y", 1}, {"z", 2}};
22 43 : return offsets.at(key);
23 : };
24 :
25 : template <>
26 : constexpr auto structure_element_offset<Eigen::Matrix3d> =
27 45 : [](const std::string &key) {
28 : static std::map<std::string, scipp::index> offsets{
29 0 : {"xx", 0}, {"xy", 3}, {"xz", 6}, {"yx", 1}, {"yy", 4},
30 63 : {"yz", 7}, {"zx", 2}, {"zy", 5}, {"zz", 8}};
31 45 : return offsets.at(key);
32 : };
33 :
34 : template <>
35 : constexpr auto structure_element_offset<Eigen::Affine3d> =
36 0 : []([[maybe_unused]] const std::string &key) -> scipp::index {
37 0 : throw except::TypeError("Not supported for Affine3d types");
38 : };
39 :
40 : template <>
41 : constexpr auto structure_element_offset<scipp::core::Quaternion> =
42 0 : []([[maybe_unused]] const std::string &key) -> scipp::index {
43 0 : throw except::TypeError("Not supported for Affine3d types");
44 : };
45 :
46 : template <>
47 : constexpr auto structure_element_offset<scipp::core::Translation> =
48 0 : []([[maybe_unused]] const std::string &key) -> scipp::index {
49 0 : throw except::TypeError("Not supported for Affine3d types");
50 : };
51 :
52 : template <>
53 : constexpr auto structure_element_offset<
54 40848 : scipp::index_pair> = [](const std::string &key) {
55 40856 : static std::map<std::string, scipp::index> offsets{{"begin", 0}, {"end", 1}};
56 40848 : return offsets.at(key);
57 : };
58 :
59 62 : std::vector<std::string> element_keys(const Variable &var) {
60 62 : if (variableFactory().elem_dtype(var) == dtype<Eigen::Vector3d>)
61 128 : return {"x", "y", "z"};
62 30 : if (variableFactory().elem_dtype(var) == dtype<Eigen::Matrix3d>)
63 300 : return {"xx", "xy", "xz", "yx", "yy", "yz", "zx", "zy", "zz"};
64 0 : if (variableFactory().elem_dtype(var) == dtype<Eigen::Affine3d>)
65 0 : throw except::TypeError("Not supported for Affine3d types");
66 0 : if (variableFactory().elem_dtype(var) == dtype<scipp::index_pair>)
67 0 : return {"begin", "end"};
68 0 : throw except::TypeError("dtype is not structured");
69 : }
70 :
71 : // Defining the destructor here ensures that all users of StructureArrayModel
72 : // use the same visibility of that class. Otherwise, instantiating the
73 : // StructureArrayModel template creates a class without visibility attribute.
74 : // But INSTANTIATE_STRUCTURE_ARRAY_VARIABLE below gives it SCIPP_EXPORT
75 : // visibility which would cause a mismatch.
76 : // With this explicit definition, instantiation is deferred.
77 : // This was observed with Apple Clang 13 and using
78 : // std::make_shared<StructureArrayModel<T, Elem>> in structures.cpp
79 : template <class T_, class Elem_>
80 348203 : StructureArrayModel<T_, Elem_>::~StructureArrayModel() = default;
81 :
82 : INSTANTIATE_STRUCTURE_ARRAY_VARIABLE(vector3, Eigen::Vector3d, double)
83 : INSTANTIATE_STRUCTURE_ARRAY_VARIABLE(linear_transform3, Eigen::Matrix3d, double)
84 : INSTANTIATE_STRUCTURE_ARRAY_VARIABLE(affine_transform3, Eigen::Affine3d, double)
85 : INSTANTIATE_STRUCTURE_ARRAY_VARIABLE(rotation3, scipp::core::Quaternion, double)
86 : INSTANTIATE_STRUCTURE_ARRAY_VARIABLE(translation3, scipp::core::Translation,
87 : double)
88 : INSTANTIATE_STRUCTURE_ARRAY_VARIABLE(index_pair, scipp::index_pair,
89 : scipp::index)
90 :
91 : } // namespace scipp::variable
|