Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 12 additions & 12 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ requires-poetry = '>=2.1,<3.0'
[tool.poetry.dependencies]
python = "^3.10"
protobuf = {version=">=4.21"}
ni-measurements-data-v1-client = { version = ">=1.1.0", allow-prereleases = true }
ni-measurements-data-v1-client = { version = ">=1.2.0.dev0", allow-prereleases = true }
ni-measurements-metadata-v1-client = { version = ">=1.0.0" }
ni-protobuf-types = { version = ">=1.2.0", allow-prereleases = true }
ni-protobuf-types = { version = ">=1.3.0.dev0", allow-prereleases = true }
hightime = { version = ">=1.0.0" }

[tool.poetry.group.dev.dependencies]
Expand Down
13 changes: 8 additions & 5 deletions src/ni/datastore/data/_data_store_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,15 @@ def publish_measurement(

- Scalar: Single float, int, str or boolean
- Vector: Array of float, int, str or boolean values
- DoubleAnalogWaveform: Analog waveform with double precision
- AnalogWaveform[np.float64]: Analog waveform with double precision
- AnalogWaveform[np.float32]: Analog waveform with single precision
- DoubleXYData: XY coordinate data with double precision
- I16AnalogWaveform: Analog waveform with 16-bit integer precision
- DoubleComplexWaveform: Complex waveform with double precision
- I16ComplexWaveform: Complex waveform with 16-bit integer precision
- DoubleSpectrum: Frequency spectrum data with double precision
- AnalogWaveform[np.int16]: Analog waveform with 16-bit integer precision
- ComplexWaveform[np.complex128]: Complex waveform with double precision
- ComplexWaveform[np.complex64]: Complex waveform with single precision
- ComplexWaveform[ComplexInt32DType]: Complex waveform with 16-bit integer precision
- Spectrum[np.float64]: Frequency spectrum data with double precision
- Spectrum[np.float32]: Frequency spectrum data with single precision
- DigitalWaveform: Digital waveform data

step_id: The ID of the step associated with this measurement. This
Expand Down
22 changes: 22 additions & 0 deletions src/ni/datastore/data/_grpc_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
from ni.protobuf.types.waveform_conversion import (
digital_waveform_from_protobuf,
digital_waveform_to_protobuf,
float32_analog_waveform_from_protobuf,
float32_analog_waveform_to_protobuf,
float32_complex_waveform_from_protobuf,
float32_complex_waveform_to_protobuf,
float32_spectrum_from_protobuf,
float32_spectrum_to_protobuf,
float64_analog_waveform_from_protobuf,
float64_analog_waveform_to_protobuf,
float64_complex_waveform_from_protobuf,
Expand Down Expand Up @@ -241,6 +247,10 @@ def populate_publish_measurement_request_value(
publish_request.double_analog_waveform.CopyFrom(
float64_analog_waveform_to_protobuf(value)
)
elif value.dtype == np.float32:
publish_request.float_analog_waveform.CopyFrom(
float32_analog_waveform_to_protobuf(value)
)
Comment thread
mjohanse-emr marked this conversation as resolved.
elif value.dtype == np.int16:
publish_request.i16_analog_waveform.CopyFrom(int16_analog_waveform_to_protobuf(value))
else:
Expand All @@ -250,13 +260,19 @@ def populate_publish_measurement_request_value(
publish_request.double_complex_waveform.CopyFrom(
float64_complex_waveform_to_protobuf(value)
)
elif value.dtype == np.complex64:
publish_request.float_complex_waveform.CopyFrom(
float32_complex_waveform_to_protobuf(value)
)
elif value.dtype == ComplexInt32DType:
publish_request.i16_complex_waveform.CopyFrom(int16_complex_waveform_to_protobuf(value))
else:
raise TypeError(f"Unsupported ComplexWaveform dtype: {value.dtype}")
elif isinstance(value, Spectrum):
if value.dtype == np.float64:
publish_request.double_spectrum.CopyFrom(float64_spectrum_to_protobuf(value))
elif value.dtype == np.float32:
publish_request.float_spectrum.CopyFrom(float32_spectrum_to_protobuf(value))
else:
raise TypeError(f"Unsupported Spectrum dtype: {value.dtype}")
elif isinstance(value, DigitalWaveform):
Expand Down Expand Up @@ -338,10 +354,16 @@ def convert_read_measurement_response_from_protobuf(
return digital_waveform_from_protobuf(response.digital_waveform)
elif read_data_type == "double_analog_waveform":
return float64_analog_waveform_from_protobuf(response.double_analog_waveform)
elif read_data_type == "float_analog_waveform":
return float32_analog_waveform_from_protobuf(response.float_analog_waveform)
elif read_data_type == "double_complex_waveform":
return float64_complex_waveform_from_protobuf(response.double_complex_waveform)
elif read_data_type == "float_complex_waveform":
return float32_complex_waveform_from_protobuf(response.float_complex_waveform)
elif read_data_type == "double_spectrum":
return float64_spectrum_from_protobuf(response.double_spectrum)
elif read_data_type == "float_spectrum":
return float32_spectrum_from_protobuf(response.float_spectrum)
elif read_data_type == "i16_analog_waveform":
return int16_analog_waveform_from_protobuf(response.i16_analog_waveform)
elif read_data_type == "i16_complex_waveform":
Expand Down
91 changes: 82 additions & 9 deletions tests/acceptance/test_publish_measurement_and_read_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@ def test___publish_xydata___read_measurement_value_returns_xydata(
assert xydata == expected_xydata


def test___publish_spectrum___read_measurement_value_returns_spectrum(
def test___publish_float64_spectrum___read_measurement_value_returns_spectrum(
acceptance_test_context: DataStoreContext,
) -> None:
with DataStoreClient() as data_store_client:
step_id = _create_step(data_store_client, "spectrum")
step_id = _create_step(data_store_client, "float64 spectrum")
expected_spectrum = Spectrum.from_array_1d(
array=[1.0, 10.0, 100.0],
dtype=np.float64,
Expand All @@ -101,7 +101,7 @@ def test___publish_spectrum___read_measurement_value_returns_spectrum(
)

published_measurement_id = data_store_client.publish_measurement(
name="python publish spectrum",
name="python publish float64 spectrum",
value=expected_spectrum,
step_id=step_id,
)
Expand All @@ -113,19 +113,69 @@ def test___publish_spectrum___read_measurement_value_returns_spectrum(
assert spectrum == expected_spectrum


def test___publish_analog_waveform___read_measurement_value_returns_analog_waveform(
def test___publish_float32_spectrum___read_measurement_value_returns_spectrum(
acceptance_test_context: DataStoreContext,
) -> None:
with DataStoreClient() as data_store_client:
step_id = _create_step(data_store_client, "analog waveform")
step_id = _create_step(data_store_client, "float32 spectrum")
expected_spectrum = Spectrum.from_array_1d(
array=[1.0, 10.0, 100.0],
dtype=np.float32,
start_frequency=1.0,
frequency_increment=1.0,
)

published_measurement_id = data_store_client.publish_measurement(
name="python publish spectrum float",
value=expected_spectrum,
step_id=step_id,
)

published_measurement = data_store_client.get_measurement(published_measurement_id)
spectrum = data_store_client.read_measurement_value(
published_measurement, expected_type=Spectrum
)
assert spectrum == expected_spectrum


def test___publish_float64_analog_waveform___read_measurement_value_returns_float64_analog_waveform(
acceptance_test_context: DataStoreContext,
) -> None:
with DataStoreClient() as data_store_client:
step_id = _create_step(data_store_client, "float64 analog waveform")
expected_waveform = AnalogWaveform(
sample_count=3,
raw_data=np.array([1.0, 2.0, 3.0]),
timing=Timing(SampleIntervalMode.NONE, time_offset=ht.timedelta()),
)

published_measurement_id = data_store_client.publish_measurement(
name="python publish analog waveform",
name="python publish float64 analog waveform",
value=expected_waveform,
step_id=step_id,
)

published_measurement = data_store_client.get_measurement(published_measurement_id)
waveform = data_store_client.read_measurement_value(
published_measurement, expected_type=AnalogWaveform
)
assert waveform == expected_waveform


def test___publish_float32_analog_waveform___read_measurement_value_returns_float32_analog_waveform(
acceptance_test_context: DataStoreContext,
) -> None:
with DataStoreClient() as data_store_client:
step_id = _create_step(data_store_client, "float32 analog waveform")
expected_waveform = AnalogWaveform(
sample_count=3,
dtype=np.float32,
raw_data=np.array([1.0, 2.0, 3.0], dtype=np.float32),
timing=Timing(SampleIntervalMode.NONE, time_offset=ht.timedelta()),
)

published_measurement_id = data_store_client.publish_measurement(
name="python publish float32 analog waveform",
value=expected_waveform,
step_id=step_id,
)
Expand Down Expand Up @@ -159,17 +209,40 @@ def test___publish_digital_waveform___read_measurement_value_returns_digital_wav
assert waveform == expected_waveform


def test___publish_complex_waveform___read_measurement_value_returns_complex_waveform(
def test___publish_float64_complex_waveform___read_measurement_value_returns_float64_complex_waveform(
acceptance_test_context: DataStoreContext,
) -> None:
with DataStoreClient() as data_store_client:
step_id = _create_step(data_store_client, "float64 complex waveform")
expected_waveform = ComplexWaveform(
10,
timing=Timing(SampleIntervalMode.NONE, time_offset=ht.timedelta()),
)
published_measurement_id = data_store_client.publish_measurement(
name="python publish float64 complex waveform",
value=expected_waveform,
step_id=step_id,
)

published_measurement = data_store_client.get_measurement(published_measurement_id)
waveform = data_store_client.read_measurement_value(
published_measurement, expected_type=ComplexWaveform
)
assert waveform == expected_waveform


def test___publish_float32_complex_waveform___read_measurement_value_returns_float32_complex_waveform(
acceptance_test_context: DataStoreContext,
) -> None:
with DataStoreClient() as data_store_client:
step_id = _create_step(data_store_client, "complex waveform")
step_id = _create_step(data_store_client, "float32 complex waveform")
expected_waveform = ComplexWaveform(
10,
dtype=np.complex64,
timing=Timing(SampleIntervalMode.NONE, time_offset=ht.timedelta()),
)
published_measurement_id = data_store_client.publish_measurement(
name="python publish complex waveform",
name="python publish float32 complex waveform",
value=expected_waveform,
step_id=step_id,
)
Expand Down
36 changes: 36 additions & 0 deletions tests/unit/data/test_grpc_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,17 @@ def test___python_float64_analog_waveform___populate_measurement___measurement_u
assert list(request.double_analog_waveform.y_data) == [0.0, 0.0, 0.0]


def test___python_float32_analog_waveform___populate_measurement___measurement_updated_correctly() -> (
None
):
wfm_obj = AnalogWaveform(3, np.float32)
request = PublishMeasurementRequest()
populate_publish_measurement_request_value(request, wfm_obj)

assert isinstance(request.float_analog_waveform, waveform_pb2.FloatAnalogWaveform)
assert list(request.float_analog_waveform.y_data) == [0.0, 0.0, 0.0]


def test___python_int16_analog_waveform___populate_measurement___measurement_updated_correctly() -> (
None
):
Expand All @@ -208,6 +219,17 @@ def test___python_float64_complex_waveform___populate_measurement___measurement_
assert list(request.double_complex_waveform.y_data) == [0.0, 0.0, 0.0, 0.0]


def test___python_float32_complex_waveform___populate_measurement___measurement_updated_correctly() -> (
None
):
wfm_obj = ComplexWaveform(2, np.complex64)
request = PublishMeasurementRequest()
populate_publish_measurement_request_value(request, wfm_obj)

assert isinstance(request.float_complex_waveform, waveform_pb2.FloatComplexWaveform)
assert list(request.float_complex_waveform.y_data) == [0.0, 0.0, 0.0, 0.0]


def test___python_int16_complex_waveform___populate_measurement___measurement_updated_correctly() -> (
None
):
Expand Down Expand Up @@ -261,6 +283,20 @@ def test___python_float64_spectrum___populate_measurement___measurement_updated_
assert request.double_spectrum.frequency_increment == 10.0


def test___python_float32_spectrum___populate_measurement___measurement_updated_correctly() -> None:
spectrum = Spectrum.from_array_1d(np.array([1.0, 2.0, 3.0]), dtype=np.float32)
spectrum.start_frequency = 100.0
spectrum.frequency_increment = 10.0

request = PublishMeasurementRequest()
populate_publish_measurement_request_value(request, spectrum)

assert isinstance(request.float_spectrum, waveform_pb2.FloatSpectrum)
assert list(request.float_spectrum.data) == [1.0, 2.0, 3.0]
assert request.float_spectrum.start_frequency == 100.0
assert request.float_spectrum.frequency_increment == 10.0


def test___python_float64_xydata___populate_measurement___measurement_updated_correctly() -> None:
xydata = XYData.from_arrays_1d(
[1.0, 2.0], [3.0, 4.0], np.float64, x_units="Volts", y_units="Seconds"
Expand Down
Loading