Skip to content

Commit

Permalink
Merge pull request #77 from asalzburger/feat-read-acts-surface-json
Browse files Browse the repository at this point in the history
feat: adding python-json  reading
  • Loading branch information
asalzburger authored Aug 6, 2024
2 parents 81e34ec + c6a13eb commit 21533bf
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 36 deletions.
16 changes: 13 additions & 3 deletions meta/include/actsvg/display/geometry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace display {
* @param s_ the surface type
* @param v_ the view type
* @param b_ draw the boolean
* @param fs_ draw as focus
* @param fs_ draw at focus
* @param sc_ draw at scale
* @param dt_ draw as template
*
Expand Down Expand Up @@ -202,13 +202,23 @@ svg::object surface(const std::string& id_, const surface_type& s_,
s._active = view_active;
return s;
}
auto view_vertices = v_.path(s_._vertices);

// Check if the vertices have to be transformed into global at first
// place
std::vector<typename surface_type::point3_type> vertices = s_._vertices;
if (s_._surface_transform.has_value()) {
const auto& sftr = s_._surface_transform.value();
std::for_each(vertices.begin(), vertices.end(),
[&sftr](auto& v) { v = sftr.point_to_global(v); });
}

auto view_vertices = v_.path(vertices);

if constexpr (std::is_same_v<view_type, views::z_rphi>) {
// Check if we have to split the surface in phi and
// draw wiggle
// - currently supported for rectangular surfaces only
if (s_._vertices.size() == 4u) {
if (vertices.size() == 4u) {
scalar min_phi = std::numeric_limits<scalar>::max();
scalar max_phi = std::numeric_limits<scalar>::min();
// Pre-emptively split the vertices
Expand Down
44 changes: 44 additions & 0 deletions meta/include/actsvg/proto/surface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,46 @@ namespace proto {
template <typename point3_container>
struct surface {

using point3 = typename point3_container::value_type;

/// A transform3 structure before placement
struct transform3 {
// original translation
point3 _translation = {0., 0., 0.};
// original rotation
std::array<point3, 3u> _rotation = {
{1., 0., 0.}, {0., 1., 0.}, {0., 0., 1.}};
// Rotate a point to the global frame
point3 rotate(const point3& p_) const {

point3 ret{0.f, 0.f, 0.f};

ret[0] += _rotation[0][0] * p_[0];
ret[1] += _rotation[1][0] * p_[0];
ret[2] += _rotation[2][0] * p_[0];

ret[0] += _rotation[0][1] * p_[1];
ret[1] += _rotation[1][1] * p_[1];
ret[2] += _rotation[2][1] * p_[1];

ret[0] += _rotation[0][2] * p_[2];
ret[1] += _rotation[1][2] * p_[2];
ret[2] += _rotation[2][2] * p_[2];

return ret;
}

/// Apply the translation and rotation
point3 point_to_global(const point3& p_) const {
// Apply the rotation
point3 ret = rotate(p_);
ret[0] += _translation[0];
ret[1] += _translation[1];
ret[2] += _translation[2];
return ret;
}
};

enum class type {
e_annulus,
e_cylinder,
Expand All @@ -56,6 +96,10 @@ struct surface {
/// The contained vertices - for polygon surfaces
point3_container _vertices = {};

/// This is the optional surface transform - to be applied at the
/// vertices before the view is created
std::optional<transform3> _surface_transform = std::nullopt;

/// Dedicated regular disc/cylinder descriptions
/// - if this is not applicable the _vertices view needs to be chosen
std::array<scalar, 2> _radii = {0., 0.};
Expand Down
2 changes: 1 addition & 1 deletion python/notebooks/barrel.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"# This part converts the point clouds into surface objects\n",
"barrel_modules = []\n",
"for i, polygon in enumerate(barrel_polygons):\n",
" barrel_modules.append(proto.surface.from_polygon('module_'+str(i), polygon, module_fill, module_stroke))"
" barrel_modules.append(proto.surface.polygon_from_vertices('module_'+str(i), polygon, module_fill, module_stroke))"
]
},
{
Expand Down
2 changes: 1 addition & 1 deletion python/notebooks/endcap.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"# This part converts the point clouds into surface objects\n",
"endcap_modules = []\n",
"for i, polygon in enumerate(endcap_polygons):\n",
" endcap_modules.append(proto.surface.from_polygon('module_'+str(i), polygon, module_fill, module_stroke))\n",
" endcap_modules.append(proto.surface.polygon_from_vertices('module_'+str(i), polygon, module_fill, module_stroke))\n",
"\n",
"modules_xy = display.surfaces(endcap_modules, 'xy')"
]
Expand Down
71 changes: 69 additions & 2 deletions python/python/actsvg/actsvg_json.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json as jsn
import actsvg
from actsvg import proto
from actsvg import style

""" read a grid axis from a json file"""

Expand Down Expand Up @@ -107,6 +108,72 @@ def read_surface_material_maps(json_surface_material_maps):


@staticmethod
def read_surface(json_surface):
ps = proto.surface()
def read_surface(json_surface, apply_transform=True):

# Construct the name
surface_name = (
"module_vol"
+ str(json_surface["volume"])
+ "_lay"
+ str(json_surface["layer"])
+ "_sen"
+ str(json_surface["sensitive"])
)

# Read the surface description

surface_description = json_surface["value"]
surface_translation = (0.0, 0.0, 0.0)
surface_rotation = (
(1, 0, 0),
(0, 1, 0),
(0, 0, 1),
)

if apply_transform:
surface_transform = surface_description["transform"]
surface_translation = surface_transform["translation"]
if surface_transform["rotation"] is not None:
surface_rotation = surface_transform["rotation"]
surface_rotation = (
(surface_rotation[0], surface_rotation[1], surface_rotation[2]),
(surface_rotation[3], surface_rotation[4], surface_rotation[5]),
(surface_rotation[6], surface_rotation[7], surface_rotation[8]),
)

surface_vertices = []
bounds_type = surface_description["bounds"]["type"]
bounds_values = surface_description["bounds"]["values"]
if bounds_type == "TrapezoidBounds":
hx_miny = bounds_values[0]
hx_maxy = bounds_values[1]
hy = bounds_values[2]
surface_vertices = [
(-hx_miny, -hy, 0.0),
(hx_miny, -hy, 0.0),
(hx_maxy, hy, 0.0),
(-hx_maxy, hy, 0.0),
]
elif bounds_type == "RectangleBounds":
hx = bounds_values[0]
hy = bounds_values[1]
surface_vertices = [
(-hx, -hy, 0.0),
(hx, -hy, 0.0),
(hx, hy, 0.0),
(-hx, hy, 0.0),
]
else:
print("** pyactsvg **: `json.read_surface` bounds type not (yet) supported")
raise ValueError

ps = proto.surface.polygon_from_vertices_and_transform(
surface_name,
surface_vertices,
surface_translation,
surface_rotation,
style.defaults.sensitive_fill(),
style.defaults.sensitive_stroke(),
)

return ps
43 changes: 21 additions & 22 deletions python/src/display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,17 +304,16 @@ void add_display_module(context& ctx) {
/// @note the surfaces will be copied to apply the style selection
///
/// @return an object (sterile if now matching view type is found)
d.def(
"surfaces_as_oriented_polygons",
[](const std::vector<surface>& ss, const std::string& view) {
std::vector<svg::object> polygons;
for (const auto& s : ss) {
polygons.push_back(surface_as_oriented_polygon(
s, s._fill, s._stroke, view));
}
// Return a sterile object
return polygons;
});
d.def("surfaces_as_oriented_polygons",
[](const std::vector<surface>& ss, const std::string& view) {
std::vector<svg::object> polygons;
for (const auto& s : ss) {
polygons.push_back(surface_as_oriented_polygon(
s, s._fill, s._stroke, view));
}
// Return a sterile object
return polygons;
});

/// View surfaces - with style appied
///
Expand Down Expand Up @@ -349,17 +348,17 @@ void add_display_module(context& ctx) {
/// @note the surfaces will be copied to apply the style selection
///
/// @return an object (sterile if now matching view type is found)
d.def("surfaces_as_oriented_polygons",
[](const std::vector<surface>& ss, const style::fill& f,
const style::stroke& str, const std::string& view) {
std::vector<svg::object> polygons;
for (const auto& s : ss) {
polygons.push_back(
surface_as_oriented_polygon(s, f, str, view));
}
// Return a sterile object
return polygons;
});
d.def("surfaces_as_oriented_polygons", [](const std::vector<surface>& ss,
const style::fill& f,
const style::stroke& str,
const std::string& view) {
std::vector<svg::object> polygons;
for (const auto& s : ss) {
polygons.push_back(surface_as_oriented_polygon(s, f, str, view));
}
// Return a sterile object
return polygons;
});

{
/// View step_tracks - with style appied
Expand Down
32 changes: 25 additions & 7 deletions python/src/proto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void add_proto_module(context& ctx) {
.def_readwrite("fill", &surface::_fill)
.def_readwrite("stroke", &surface::_stroke)
.def_static(
"from_polygon",
"polygon_from_vertices",
[](const std::string& name, const point3_collection& pcs,
const style::fill& f, const style::stroke& s) {
// Create the surface
Expand All @@ -63,8 +63,28 @@ void add_proto_module(context& ctx) {
sf._stroke = s;
return sf;
},
py::arg("name"), py::arg("points"), py::arg("fill"),
py::arg("stroke"));
py::arg("name"), py::arg("vertices"), py::arg("fill"),
py::arg("stroke"))
.def_static(
"polygon_from_vertices_and_transform",
[](const std::string& name, const point3_collection& pcs,
const point3& translation,
const std::array<point3, 3u>& rotation,
const style::fill& f, const style::stroke& s) {
// Create the surface
surface sf{};
// Set the predefined transform
sf._surface_transform =
surface::transform3{translation, rotation};
sf._vertices = pcs;
sf._fill = f;
sf._stroke = s;

return sf;
},
py::arg("name"), py::arg("vertices"),
py::arg("translation"), py::arg("rotation"),
py::arg("fill"), py::arg("stroke"));
}

{
Expand Down Expand Up @@ -157,7 +177,7 @@ void add_proto_module(context& ctx) {
}

{
// The channel class: 1D
// The channel class: 1D
py::class_<channel1>(p, "channel1")
.def(py::init<>())
.def_readwrite("_cid", &channel1::_cid)
Expand Down Expand Up @@ -191,10 +211,8 @@ void add_proto_module(context& ctx) {
.def_readwrite("_variance", &cluster2::_variance)
.def_readwrite("_correlation", &cluster2::_correlation)
.def_readwrite("_truth", &cluster2::_truth)
.def_readwrite("_mc", &cluster2::_mc);

.def_readwrite("_mc", &cluster2::_mc);
}

}

} // namespace python
Expand Down

0 comments on commit 21533bf

Please sign in to comment.