Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SpatialSeries and DynamicTraceSegment #699

Merged
merged 76 commits into from
Feb 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
9f8f270
Add SpatialData
vhirtham Feb 2, 2022
95b5f21
Add notebooks
vhirtham Feb 2, 2022
b2e5a01
Refactor SpatialSeries
vhirtham Feb 4, 2022
50d2d72
Fix constraint behavior during evaluation
vhirtham Feb 4, 2022
ce6fa6b
Run pre-commit
vhirtham Feb 4, 2022
f1962fc
Add sympy length calculation
vhirtham Feb 7, 2022
6613907
Fix unit error
vhirtham Feb 8, 2022
7c1caa8
Fix test
vhirtham Feb 8, 2022
51a67c1
Fix all tests
vhirtham Feb 8, 2022
8691993
Add DynamicTraceSegment
vhirtham Feb 8, 2022
825d6fe
Run pre-commit
vhirtham Feb 8, 2022
54b132a
lint
CagtayFabry Feb 8, 2022
10f5987
add _k3d_line to Trace
CagtayFabry Feb 8, 2022
9c4fde0
Merge branch 'master' into 691_spatial_series
CagtayFabry Feb 8, 2022
74110dc
clean notebooks
CagtayFabry Feb 8, 2022
42074f7
mypy
CagtayFabry Feb 8, 2022
d6e1304
Use MathExpr for derivative
vhirtham Feb 14, 2022
993f39e
Add alternative length calculation
vhirtham Feb 14, 2022
ed12568
Add option to limit orientation to the xy plane
vhirtham Feb 15, 2022
34ed2ae
Add
vhirtham Feb 16, 2022
43752e7
Replace code with function
vhirtham Feb 17, 2022
3b805d2
Merge branch 'master' into 691_spatial_series
vhirtham Feb 17, 2022
e699f9b
Merge branch '691_spatial_series' of https://github.com/vhirtham/weld…
vhirtham Feb 17, 2022
c01f180
Fix tests
vhirtham Feb 18, 2022
f8d75b6
Add docstrings
vhirtham Feb 18, 2022
fe40639
Run cleanup scripts
vhirtham Feb 18, 2022
896cdd0
Fix pydocstyle issues
vhirtham Feb 18, 2022
6ececce
Fix a deepsource issue
vhirtham Feb 18, 2022
805cbbe
Remove unused code
vhirtham Feb 18, 2022
e514d3b
Express LinearHorizontalTraceSegment as DynamicSegment
vhirtham Feb 18, 2022
5890308
Express RadialHorizontalTraceSegment as DynamicSegment
vhirtham Feb 18, 2022
b2cff2d
Remove legacy code
vhirtham Feb 18, 2022
7b4596d
Fix notebook
vhirtham Feb 21, 2022
2b4ce61
run cleanup
vhirtham Feb 21, 2022
43c5c52
Fix deepsource issues
vhirtham Feb 21, 2022
e596c86
Fix deepsource issues
vhirtham Feb 21, 2022
e9bac02
add some doc fixes
vhirtham Feb 21, 2022
3a90ef9
Test docfix
vhirtham Feb 21, 2022
952e401
Add some quality of life functions to SpatialSeries
vhirtham Feb 21, 2022
c0ce76c
Fix linter issues
vhirtham Feb 21, 2022
93c516d
Add more quality of life functionality
vhirtham Feb 22, 2022
6080323
Simplify implementation of 'old' trace segments
vhirtham Feb 22, 2022
6734a99
Do some refactoring
vhirtham Feb 22, 2022
959429d
Take advantage of xarray
vhirtham Feb 22, 2022
c5f1f00
Prepare array evaluation
vhirtham Feb 22, 2022
be8c99f
Segment array evaluation works for expressions
vhirtham Feb 23, 2022
f3da1ab
Add full array support for segment lcs
vhirtham Feb 23, 2022
64712ec
Fix deepsource issues
vhirtham Feb 23, 2022
1fdce46
Update changelog
vhirtham Feb 23, 2022
ae9db90
Fix error in changelog
vhirtham Feb 23, 2022
88e7de9
Add function to calculate the length along the segment
vhirtham Feb 24, 2022
5731489
Rename variables and functions
vhirtham Feb 24, 2022
a5d1089
Replace obsolete function
vhirtham Feb 24, 2022
7d1c76d
Merge branch 'master' into 691_spatial_series
vhirtham Feb 24, 2022
7cb530d
Try fix doc
vhirtham Feb 24, 2022
ecc712b
Try fix docs
vhirtham Feb 24, 2022
149b705
Fix a doc error
vhirtham Feb 24, 2022
edc826a
Try more fixes
vhirtham Feb 25, 2022
6fc8368
Fix doc errors
vhirtham Feb 25, 2022
2309d16
Silence deepsource issues
vhirtham Feb 25, 2022
3a0b3e7
Test Sphinx fix
vhirtham Feb 25, 2022
7296d57
Test undoing some previous fixes
vhirtham Feb 25, 2022
de3828e
Undo changes
vhirtham Feb 25, 2022
3057330
assign array coords before calling evaluate
CagtayFabry Feb 25, 2022
6f577ec
Add type hint
vhirtham Feb 28, 2022
5ce033e
Merge branch '691_spatial_series' of https://github.com/vhirtham/weld…
vhirtham Feb 28, 2022
8c57089
Update weldx/geometry.py
vhirtham Feb 28, 2022
e83e3b0
Update weldx/core.py
vhirtham Feb 28, 2022
82bd7f1
Merge branch 'master' into 691_spatial_series
vhirtham Feb 28, 2022
2ee8051
Run pre-commit
vhirtham Feb 28, 2022
a92fc5a
Fix docs
vhirtham Feb 28, 2022
2c99112
Rename internal variable and add property
vhirtham Feb 28, 2022
92644b4
Generalize variable name in DynamicTraceSegment
vhirtham Feb 28, 2022
e314d79
Rename all variables related to 's'
vhirtham Feb 28, 2022
684b592
Remove obsolete function
vhirtham Feb 28, 2022
7c3123c
Fix todo
vhirtham Feb 28, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ repos:
- mdformat-config
# ----- Python formatting -----
- repo: https://github.com/sondrelg/pep585-upgrade
rev: v1
rev: v1.0.1
hooks:
- id: upgrade-type-hints
args: [ '--futures=true' ]
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
added
=====

- `SpatialSeries` and `DynamicTraceSegment` [:pull:`699`]

- first draft of the ``multi_pass_weld`` schema for WelDX files [:pull:`667`]

- add `GenericSeries` as base class supporting arrays and equations [:pull:`618`]
Expand Down
2 changes: 1 addition & 1 deletion tutorials/01_03_geometry.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.12"
"version": "3.9.9"
}
},
"nbformat": 4,
Expand Down
12 changes: 6 additions & 6 deletions tutorials/welding_example_01_basics.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@
"metadata": {},
"outputs": [],
"source": [
"coords = [tcp_start_point.magnitude, tcp_end_point.magnitude]\n",
"coords = np.stack([tcp_start_point, tcp_end_point])\n",
"\n",
"tcp_wire = LocalCoordinateSystem(\n",
" coordinates=coords, orientation=rot, time=[t_start, t_end]\n",
Expand Down Expand Up @@ -398,7 +398,7 @@
"metadata": {},
"outputs": [],
"source": [
"tcp_contact = LocalCoordinateSystem(coordinates=[0, 0, -10])"
"tcp_contact = LocalCoordinateSystem(coordinates=Q_([0, 0, -10], \"mm\"))"
]
},
{
Expand Down Expand Up @@ -469,9 +469,9 @@
"outputs": [],
"source": [
"# add the workpiece coordinate system\n",
"csm.add_cs(\"T1\", \"workpiece\", LocalCoordinateSystem(coordinates=[200, 3, 5]))\n",
"csm.add_cs(\"T2\", \"T1\", LocalCoordinateSystem(coordinates=[0, 1, 0]))\n",
"csm.add_cs(\"T3\", \"T2\", LocalCoordinateSystem(coordinates=[0, 1, 0]))"
"csm.add_cs(\"T1\", \"workpiece\", LocalCoordinateSystem(coordinates=Q_([200, 3, 5], \"mm\")))\n",
"csm.add_cs(\"T2\", \"T1\", LocalCoordinateSystem(coordinates=Q_([0, 1, 0], \"mm\")))\n",
"csm.add_cs(\"T3\", \"T2\", LocalCoordinateSystem(coordinates=Q_([0, 1, 0], \"mm\")))"
]
},
{
Expand Down Expand Up @@ -581,7 +581,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.9"
"version": "3.8.12"
}
},
"nbformat": 4,
Expand Down
26 changes: 17 additions & 9 deletions weldx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
Time
TimeSeries
GenericSeries
SpatialSeries
MathematicalExpression
CoordinateSystemManager
LocalCoordinateSystem
Expand All @@ -72,6 +73,7 @@
Shape
Trace
SpatialData
DynamicTraceSegment

**Full API Reference**

Expand Down Expand Up @@ -130,17 +132,21 @@
from weldx.constants import Q_, U_

# main modules
import weldx.time
import weldx.time # skipcq: PY-W2000

# skipcq: PY-W2000
import weldx.util # import this second to avoid circular dependencies
import weldx.core
import weldx.transformations
import weldx.core # skipcq: PY-W2000
import weldx.transformations # skipcq: PY-W2000
import weldx.config
import weldx.geometry
import weldx.welding
import weldx.geometry # skipcq: PY-W2000
import weldx.welding # skipcq: PY-W2000

# class imports to weldx namespace
from weldx.config import Config
from weldx.core import GenericSeries, MathematicalExpression, TimeSeries

# skipcq: PY-W2000
from weldx.core import GenericSeries, MathematicalExpression, TimeSeries, SpatialSeries
from weldx.geometry import (
ArcSegment,
Geometry,
Expand All @@ -150,8 +156,9 @@
Shape,
Trace,
SpatialData,
DynamicTraceSegment,
)
from weldx.transformations import (
from weldx.transformations import ( # skipcq: PY-W2000
CoordinateSystemManager,
LocalCoordinateSystem,
WXRotation,
Expand All @@ -161,10 +168,10 @@
from weldx.time import Time

# tags (this will partially import weldx.asdf but not the extension)
from weldx import tags
from weldx import tags # skipcq: PY-W2000

# asdf extensions
import weldx.asdf
import weldx.asdf # skipcq: PY-W2000
from weldx.asdf.file import WeldxFile

__all__ = (
Expand All @@ -190,6 +197,7 @@
"util",
"welding",
"TimeSeries",
"DynamicTraceSegment",
"LinearHorizontalTraceSegment",
"Config",
"Time",
Expand Down
95 changes: 88 additions & 7 deletions weldx/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

from weldx.types import UnitLike

__all__ = ["GenericSeries", "MathematicalExpression", "TimeSeries"]
__all__ = ["GenericSeries", "MathematicalExpression", "TimeSeries", "SpatialSeries"]

_me_parameter_types = Union[pint.Quantity, str, Tuple[pint.Quantity, str], xr.DataArray]

Expand Down Expand Up @@ -276,7 +276,6 @@ def evaluate(self, **kwargs) -> Any:
k: v if isinstance(v, xr.DataArray) else xr.DataArray(v)
for k, v in self._parameters.items()
}

return self.function(**variables, **parameters)


Expand Down Expand Up @@ -1026,7 +1025,6 @@ def _init_discrete(
else:
# todo check data structure
pass

# check the constraints of derived types
self._check_constraints_discrete(data)
self._obj = data
Expand Down Expand Up @@ -1254,9 +1252,14 @@ def _evaluate_preprocessor(self, **kwargs) -> list[SeriesParameter]:
def _evaluate_expr(self, coords: list[SeriesParameter]) -> GenericSeries:
"""Evaluate the expression at the passed coordinates."""
if len(coords) == self._obj.num_variables:
eval_args = {v.symbol: v.data_array for v in coords}
data = self._obj.evaluate(**eval_args)
return self.__class__(data)
eval_args = {
v.symbol: v.data_array.assign_coords(
{v.dim: v.data_array.pint.dequantify()}
)
for v in coords
}
da = self._obj.evaluate(**eval_args)
return self.__class__(da)

# turn passed coords into parameters of the expression
new_series = deepcopy(self)
Expand Down Expand Up @@ -1430,7 +1433,6 @@ def _check_constraints_discrete(cls, data_array: xr.DataArray):
ref[k]["dimensionality"] = _units[k]
if k in _vals:
ref[k]["values"] = _vals[k]

ut.xr_check_coords(data_array, ref)

@classmethod
Expand Down Expand Up @@ -1546,3 +1548,82 @@ def interp_like(

"""
return NotImplemented


# --------------------------------------------------------------------------------------
# SpatialSeries
# --------------------------------------------------------------------------------------


class SpatialSeries(GenericSeries):
"""Describes a line in 3d space depending on the positional coordinate ``s``."""

_position_dim_name = "s"

_required_variables: list[str] = [_position_dim_name]
"""Required variable names"""

_required_dimensions: list[str] = [_position_dim_name, "c"]
"""Required dimensions"""
_required_dimension_units: dict[str, pint.Unit] = {_position_dim_name: ""}
"""Required units of a dimension"""
_required_dimension_coordinates: dict[str, list] = {"c": ["x", "y", "z"]}
"""Required coordinates of a dimension."""

def __init__(
self,
obj: Union[pint.Quantity, xr.DataArray, str, MathematicalExpression],
dims: Union[list[str], dict[str, str]] = None,
coords: dict[str, pint.Quantity] = None,
units: dict[str, Union[str, pint.Unit]] = None,
interpolation: str = None,
parameters: dict[str, Union[str, pint.Quantity, xr.DataArray]] = None,
):
if isinstance(obj, Q_):
obj = self._process_quantity(obj, dims, coords)
dims = None
coords = None
if parameters is not None:
parameters = self._process_parameters(parameters)
super().__init__(obj, dims, coords, units, interpolation, parameters)

@classmethod
def _process_quantity(
cls,
obj: Union[pint.Quantity, xr.DataArray, str, MathematicalExpression],
dims: Union[list[str], dict[str, str]],
coords: dict[str, pint.Quantity],
) -> xr.DataArray:
"""Turn a quantity into a a correctly formatted data array."""
if isinstance(coords, dict):
s = coords[cls._position_dim_name]
else:
s = coords
coords = {cls._position_dim_name: s}

if not isinstance(s, xr.DataArray):
if not isinstance(s, Q_):
s = Q_(s, "")
s = xr.DataArray(s, dims=[cls._position_dim_name]).pint.dequantify()
coords[cls._position_dim_name] = s

if "c" not in coords:
coords["c"] = ["x", "y", "z"]

if dims is None:
dims = [cls._position_dim_name, "c"]

return xr.DataArray(obj, dims=dims, coords=coords)

@staticmethod
def _process_parameters(params):
"""Turn quantity parameters into the correctly formatted data arrays."""
for k, v in params.items():
if isinstance(v, Q_) and v.size == 3:
params[k] = xr.DataArray(v, dims=["c"], coords=dict(c=["x", "y", "z"]))
return params

@property
def position_dim_name(self):
"""Return the name of the dimension that determines the position on the line."""
return self._position_dim_name
Loading