Skip to content

Commit 3766ade

Browse files
authored
Add Conversion functions for Spectrum Waveform (#23)
* add converters for spectrum waveform * shorten test name * use from_array_1d * PR feedback
1 parent 8386932 commit 3766ade

File tree

2 files changed

+126
-11
lines changed

2 files changed

+126
-11
lines changed

packages/ni.protobuf.types/src/ni/protobuf/types/waveform_conversion.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,17 @@
1414
ExtendedPropertyDictionary,
1515
ExtendedPropertyValue,
1616
NoneScaleMode,
17+
Spectrum,
1718
Timing,
1819
)
1920

2021
from ni.protobuf.types.precision_timestamp_conversion import (
21-
bintime_datetime_to_protobuf,
2222
bintime_datetime_from_protobuf,
23+
bintime_datetime_to_protobuf,
2324
)
2425
from ni.protobuf.types.waveform_pb2 import (
2526
DoubleAnalogWaveform,
27+
DoubleSpectrum,
2628
WaveformAttributeValue,
2729
)
2830

@@ -82,20 +84,45 @@ def float64_analog_waveform_from_protobuf(
8284
raise ValueError("Could not determine the datatype of 'attribute'.")
8385
extended_properties[key] = getattr(value, attr_type)
8486

85-
data_array = np.array(message.y_data)
86-
return AnalogWaveform(
87-
sample_count=data_array.size,
87+
return AnalogWaveform.from_array_1d(
88+
message.y_data,
8889
dtype=np.float64,
89-
raw_data=data_array,
90-
start_index=0,
91-
capacity=data_array.size,
9290
extended_properties=extended_properties,
93-
copy_extended_properties=True,
9491
timing=timing,
9592
scale_mode=NoneScaleMode(),
9693
)
9794

9895

96+
def float64_spectrum_to_protobuf(value: Spectrum[np.float64], /) -> DoubleSpectrum:
97+
"""Convert the Python Spectrum to a protobuf DoubleSpectrum."""
98+
attributes = _extended_properties_to_attributes(value.extended_properties)
99+
100+
return DoubleSpectrum(
101+
start_frequency=value.start_frequency,
102+
frequency_increment=value.frequency_increment,
103+
data=value.data,
104+
attributes=attributes,
105+
)
106+
107+
108+
def float64_spectrum_from_protobuf(message: DoubleSpectrum, /) -> Spectrum[np.float64]:
109+
"""Convert the protobuf DoubleSpectrum to a Python Spectrum."""
110+
extended_properties = {}
111+
for key, value in message.attributes.items():
112+
attr_type = value.WhichOneof("attribute")
113+
if attr_type is None:
114+
raise ValueError("Could not determine the datatype of 'attribute'.")
115+
extended_properties[key] = getattr(value, attr_type)
116+
117+
return Spectrum.from_array_1d(
118+
message.data,
119+
dtype=np.float64,
120+
start_frequency=message.start_frequency,
121+
frequency_increment=message.frequency_increment,
122+
extended_properties=extended_properties,
123+
)
124+
125+
99126
def _extended_properties_to_attributes(
100127
extended_properties: ExtendedPropertyDictionary,
101128
) -> Mapping[str, WaveformAttributeValue]:

packages/ni.protobuf.types/tests/unit/test_waveform_conversion.py

Lines changed: 91 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,26 @@
22

33
import numpy
44
from nitypes.bintime import DateTime
5-
from nitypes.waveform import AnalogWaveform, NoneScaleMode, SampleIntervalMode, Timing
5+
from nitypes.waveform import (
6+
AnalogWaveform,
7+
NoneScaleMode,
8+
SampleIntervalMode,
9+
Spectrum,
10+
Timing,
11+
)
612

7-
from ni.protobuf.types.precision_timestamp_conversion import bintime_datetime_to_protobuf
13+
from ni.protobuf.types.precision_timestamp_conversion import (
14+
bintime_datetime_to_protobuf,
15+
)
816
from ni.protobuf.types.waveform_conversion import (
9-
float64_analog_waveform_to_protobuf,
1017
float64_analog_waveform_from_protobuf,
18+
float64_analog_waveform_to_protobuf,
19+
float64_spectrum_from_protobuf,
20+
float64_spectrum_to_protobuf,
1121
)
1222
from ni.protobuf.types.waveform_pb2 import (
1323
DoubleAnalogWaveform,
24+
DoubleSpectrum,
1425
WaveformAttributeValue,
1526
)
1627

@@ -139,3 +150,80 @@ def test___dbl_analog_wfm_with_timing_no_dt___convert___valid_python_object() ->
139150
assert analog_waveform.timing.start_time == t0_dt._to_datetime_datetime()
140151
assert not analog_waveform.timing.has_sample_interval
141152
assert analog_waveform.timing.sample_interval_mode == SampleIntervalMode.NONE
153+
154+
155+
# ========================================================
156+
# Spectrum to DoubleSpectrum
157+
# ========================================================
158+
def test___default_spectrum___convert___valid_protobuf() -> None:
159+
spectrum = Spectrum()
160+
161+
dbl_spectrum = float64_spectrum_to_protobuf(spectrum)
162+
163+
assert not dbl_spectrum.attributes
164+
assert spectrum.start_frequency == 0.0
165+
assert spectrum.frequency_increment == 0.0
166+
assert list(dbl_spectrum.data) == []
167+
168+
169+
def test___spectrum_with_data___convert___valid_protobuf() -> None:
170+
spectrum = Spectrum.from_array_1d(numpy.array([1.0, 2.0, 3.0]))
171+
spectrum.start_frequency = 100.0
172+
spectrum.frequency_increment = 10.0
173+
174+
dbl_spectrum = float64_spectrum_to_protobuf(spectrum)
175+
176+
assert list(dbl_spectrum.data) == [1.0, 2.0, 3.0]
177+
assert dbl_spectrum.start_frequency == 100.0
178+
assert dbl_spectrum.frequency_increment == 10.0
179+
180+
181+
def test___spectrum_with_extended_properties___convert___valid_protobuf() -> None:
182+
spectrum = Spectrum()
183+
spectrum.channel_name = "Dev1/ai0"
184+
spectrum.unit_description = "Volts"
185+
186+
dbl_spectrum = float64_spectrum_to_protobuf(spectrum)
187+
188+
assert dbl_spectrum.attributes["NI_ChannelName"].string_value == "Dev1/ai0"
189+
assert dbl_spectrum.attributes["NI_UnitDescription"].string_value == "Volts"
190+
191+
192+
# ========================================================
193+
# DoubleSpectrum to Spectrum
194+
# ========================================================
195+
def test___default_dbl_spectrum___convert___valid_python_object() -> None:
196+
dbl_spectrum = DoubleSpectrum()
197+
198+
spectrum = float64_spectrum_from_protobuf(dbl_spectrum)
199+
200+
assert not spectrum.extended_properties
201+
assert spectrum.start_frequency == 0.0
202+
assert spectrum.frequency_increment == 0.0
203+
assert spectrum.sample_count == 0
204+
assert spectrum.data.size == 0
205+
206+
207+
def test___dbl_spectrum_with_data___convert___valid_python_object() -> None:
208+
dbl_spectrum = DoubleSpectrum(
209+
data=[1.0, 2.0, 3.0], start_frequency=100.0, frequency_increment=10.0
210+
)
211+
212+
spectrum = float64_spectrum_from_protobuf(dbl_spectrum)
213+
214+
assert list(spectrum.data) == [1.0, 2.0, 3.0]
215+
assert spectrum.start_frequency == 100.0
216+
assert spectrum.frequency_increment == 10.0
217+
218+
219+
def test___dbl_spectrum_with_attributes___convert___valid_python_object() -> None:
220+
attributes = {
221+
"NI_ChannelName": WaveformAttributeValue(string_value="Dev1/ai0"),
222+
"NI_UnitDescription": WaveformAttributeValue(string_value="Volts"),
223+
}
224+
dbl_spectrum = DoubleSpectrum(attributes=attributes)
225+
226+
spectrum = float64_spectrum_from_protobuf(dbl_spectrum)
227+
228+
assert spectrum.channel_name == "Dev1/ai0"
229+
assert spectrum.unit_description == "Volts"

0 commit comments

Comments
 (0)