Skip to content

Commit

Permalink
Measurement asdf (#70)
Browse files Browse the repository at this point in the history
* Add draft for mathematical function class based on SymPy
* Add serialization of mathematical function class
* Add measurement example notebook
* Add example notebook with quantities
* Add allOf syntax to validator testcase
* Add unit support to LCS
  • Loading branch information
CagtayFabry authored Jul 13, 2020
1 parent a5052f0 commit 930c5f9
Show file tree
Hide file tree
Showing 36 changed files with 1,336 additions and 21 deletions.
6 changes: 6 additions & 0 deletions .typo-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ excluded_words:
- pandas
- xarray
- scipy
- sympy
- pytest
- pydocstyle
- matplotlib
Expand Down Expand Up @@ -79,6 +80,9 @@ excluded_words:
- ipython
# scipy ---------------------------------------
- Slerp
# sympy ---------------------------------------
- lambdify
- sympify
# welding -------------------------------------
- weldment
# conda ---------------------------------------
Expand All @@ -101,3 +105,5 @@ excluded_words:
- xyz
- bamwelding
- netcdf
- msm
- Beckhoff
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,15 @@
`weldx.transformations.CoordinateSystemManager`.
- add test for `xarray.DataArray`, `xarray.Dataset`, `weldx.transformations.LocalCoordinateSystem` and
`weldx.transformations.CoordinateSystemManager` serialization.
- allow using `pint.Quantity` coordinates in `weldx.transformations.LocalCoordinateSystem` [#70]
- add measurement related ASDF serialization classes: [#70]
- `equipment/generic_equipment-1.0.0`
- `measurement/data-1.0.0`
- `data_transformation-1.0.0`
- `measurement/error-1.0.0`
- `measurement/measurement-1.0.0`
- `measurement/measurement_chain-1.0.0`
- `measurement/signal-1.0.0`
- `measurement/source-1.0.0`
- add ASDF support for `sympy` expressions with `core/mathematical_expression-1.0.0` [#70]
- add example notebook for measurement chains in tutorials [#70]
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dependencies:
- numpy>=1.18
- pandas>=1.0
- scipy>=1.4
- sympy>=1.6
- xarray>=0.15
- pint>=0.11
- bottleneck
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"pandas>=1.0",
"xarray>=0.15",
"scipy>=1.4",
"sympy>=1.6",
"pint>=0.11",
"asdf>=2.6",
"bottleneck>=1.3",
Expand Down
20 changes: 8 additions & 12 deletions tests/asdf_tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def get_local_coordinate_system(time_dep_orientation: bool, time_dep_coordinates
A local coordinate system
"""
coords = [2, 5, 1]
coords = Q_(np.asarray([2.0, 5.0, 1.0]), "mm")
orientation = tf.rotation_matrix_z(np.pi / 3)

if not time_dep_orientation and not time_dep_coordinates:
Expand Down Expand Up @@ -247,22 +247,18 @@ def are_coordinate_system_managers_equal(
def get_example_coordinate_system_manager():
"""Get a consistent CoordinateSystemManager instance for test purposes."""
csm = tf.CoordinateSystemManager("root")
csm.add_coordinate_system(
"lcs_01", "root", tf.LocalCoordinateSystem(coordinates=[1, 2, 3])
)
csm.add_coordinate_system(
csm.create_cs("lcs_01", "root", coordinates=[1, 2, 3])
csm.create_cs(
"lcs_02",
"root",
tf.LocalCoordinateSystem(
orientation=tf.rotation_matrix_z(np.pi / 3), coordinates=[4, -7, 8]
),
orientation=tf.rotation_matrix_z(np.pi / 3),
coordinates=[4, -7, 8],
)
csm.add_coordinate_system(
csm.create_cs(
"lcs_03",
"lcs_02",
tf.LocalCoordinateSystem(
orientation=tf.rotation_matrix_y(np.pi / 11), coordinates=[4, -7, 8]
),
orientation=tf.rotation_matrix_y(np.pi / 11),
coordinates=[4, -7, 8],
)
return csm

Expand Down
120 changes: 120 additions & 0 deletions tests/test_measurement.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
"""Test the measurement package."""
from io import BytesIO

import asdf
import sympy
import xarray as xr

import weldx.measurement as msm
from weldx.asdf.extension import WeldxAsdfExtension, WeldxExtension
from weldx.asdf.tags.weldx.core.mathematical_expression import MathematicalExpression
from weldx.constants import WELDX_QUANTITY as Q_


def test_generic_measurement():
"""Test basic measurement creation and ASDF read/write."""
data_01 = msm.Data(
name="Welding current", data=xr.DataArray([1, 2, 3, 4], dims=["time"])
)

data_02 = msm.Data(
name="Welding voltage", data=xr.DataArray([10, 20, 30, 40], dims=["time"])
)

src_01 = msm.Source(
name="Current Sensor",
output_signal=msm.Signal("analog", "V", data=None),
error=msm.Error(1337.42),
)

src_02 = msm.Source(
name="Voltage Sensor",
output_signal=msm.Signal("analog", "V", data=None),
error=msm.Error(1),
)

dp_01 = msm.DataTransformation(
name="AD conversion current measurement",
input_signal=src_01.output_signal,
output_signal=msm.Signal("digital", "V", data=None),
error=msm.Error(999.0),
)

dp_02 = msm.DataTransformation(
name="Calibration current measurement",
input_signal=dp_01.output_signal,
output_signal=msm.Signal("digital", "A", data=data_01),
error=msm.Error(43.0),
)

dp_03 = msm.DataTransformation(
name="AD conversion voltage measurement",
input_signal=dp_02.output_signal,
output_signal=msm.Signal("digital", "V", data=None),
error=msm.Error(2.0),
)

dp_04 = msm.DataTransformation(
name="Calibration voltage measurement",
input_signal=dp_03.output_signal,
output_signal=msm.Signal("digital", "V", data=data_02),
error=msm.Error(Q_(3.0, "percent")),
)

chn_01 = msm.MeasurementChain(
name="Current measurement", data_source=src_01, data_processors=[dp_01, dp_02]
)

chn_02 = msm.MeasurementChain(
name="Voltage measurement", data_source=src_02, data_processors=[dp_03, dp_04]
)

eqp_01 = msm.GenericEquipment(
"Current Sensor", sources=[src_01], data_transformations=[dp_02]
)
eqp_02 = msm.GenericEquipment(
"AD Converter", sources=None, data_transformations=[dp_01, dp_03]
)
eqp_03 = msm.GenericEquipment(
"Voltage Sensor", sources=None, data_transformations=[dp_04]
)

measurement_01 = msm.Measurement(
name="Current measurement", data=[data_01], measurement_chain=chn_01
)
measurement_02 = msm.Measurement(
name="Voltage measurement", data=[data_02], measurement_chain=chn_02
)

equipment = [eqp_01, eqp_02, eqp_03]
measurement_data = [data_01, data_02]
measurement_chains = [chn_01]
measurements = [measurement_01, measurement_02]
sources = [src_01]
processors = [dp_01, dp_02]

[a, x, b] = sympy.symbols("a x b")
expr_01 = MathematicalExpression(a * x + b)
expr_01.set_parameter("a", 2)
expr_01.set_parameter("b", 3)
print(expr_01.parameters)
print(expr_01.get_variable_names())
print(expr_01.evaluate(x=3))

tree = {
"equipment": equipment,
"data": measurement_data,
"measurements": measurements,
# "expression": expr_01,
"measurement_chains": measurement_chains,
"data_sources": sources,
"data_processors": processors,
}

asdf_buffer = BytesIO()

with asdf.AsdfFile(tree, extensions=[WeldxExtension(), WeldxAsdfExtension()]) as f:
f.write_to(asdf_buffer)
asdf_buffer.seek(0)

asdf.open(asdf_buffer, extensions=[WeldxExtension(), WeldxAsdfExtension()])
Loading

0 comments on commit 930c5f9

Please sign in to comment.