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<scipp::index_pair> =
54 44248 : [](const std::string &key) {
55 0 : static std::map<std::string, scipp::index> offsets{{"begin", 0},
56 44256 : {"end", 1}};
57 44248 : return offsets.at(key);
58 : };
59 :
60 62 : std::vector<std::string> element_keys(const Variable &var) {
61 62 : if (variableFactory().elem_dtype(var) == dtype<Eigen::Vector3d>)
62 128 : return {"x", "y", "z"};
63 30 : if (variableFactory().elem_dtype(var) == dtype<Eigen::Matrix3d>)
64 300 : return {"xx", "xy", "xz", "yx", "yy", "yz", "zx", "zy", "zz"};
65 0 : if (variableFactory().elem_dtype(var) == dtype<Eigen::Affine3d>)
66 0 : throw except::TypeError("Not supported for Affine3d types");
67 0 : if (variableFactory().elem_dtype(var) == dtype<scipp::index_pair>)
68 0 : return {"begin", "end"};
69 0 : throw except::TypeError("dtype is not structured");
70 : }
71 :
72 : // Defining the destructor here ensures that all users of StructureArrayModel
73 : // use the same visibility of that class. Otherwise, instantiating the
74 : // StructureArrayModel template creates a class without visibility attribute.
75 : // But INSTANTIATE_STRUCTURE_ARRAY_VARIABLE below gives it SCIPP_EXPORT
76 : // visibility which would cause a mismatch.
77 : // With this explicit definition, instantiation is deferred.
78 : // This was observed with Apple Clang 13 and using
79 : // std::make_shared<StructureArrayModel<T, Elem>> in structures.cpp
80 : template <class T_, class Elem_>
81 349973 : StructureArrayModel<T_, Elem_>::~StructureArrayModel() = default;
82 :
83 : INSTANTIATE_STRUCTURE_ARRAY_VARIABLE(vector3, Eigen::Vector3d, double)
84 : INSTANTIATE_STRUCTURE_ARRAY_VARIABLE(linear_transform3, Eigen::Matrix3d, double)
85 : INSTANTIATE_STRUCTURE_ARRAY_VARIABLE(affine_transform3, Eigen::Affine3d, double)
86 : INSTANTIATE_STRUCTURE_ARRAY_VARIABLE(rotation3, scipp::core::Quaternion, double)
87 : INSTANTIATE_STRUCTURE_ARRAY_VARIABLE(translation3, scipp::core::Translation,
88 : double)
89 : INSTANTIATE_STRUCTURE_ARRAY_VARIABLE(index_pair, scipp::index_pair,
90 : scipp::index)
91 :
92 : } // namespace scipp::variable
|