legend-pydataobj 1.2.1__py3-none-any.whl → 1.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {legend_pydataobj-1.2.1.dist-info → legend_pydataobj-1.4.0.dist-info}/METADATA +1 -1
- {legend_pydataobj-1.2.1.dist-info → legend_pydataobj-1.4.0.dist-info}/RECORD +15 -14
- lgdo/_version.py +2 -2
- lgdo/cli.py +56 -0
- lgdo/compression/base.py +2 -0
- lgdo/compression/generic.py +8 -2
- lgdo/compression/radware.py +226 -112
- lgdo/compression/varlen.py +30 -21
- lgdo/lh5_store.py +173 -64
- lgdo/types/scalar.py +1 -1
- lgdo/types/table.py +6 -3
- {legend_pydataobj-1.2.1.dist-info → legend_pydataobj-1.4.0.dist-info}/LICENSE +0 -0
- {legend_pydataobj-1.2.1.dist-info → legend_pydataobj-1.4.0.dist-info}/WHEEL +0 -0
- {legend_pydataobj-1.2.1.dist-info → legend_pydataobj-1.4.0.dist-info}/entry_points.txt +0 -0
- {legend_pydataobj-1.2.1.dist-info → legend_pydataobj-1.4.0.dist-info}/top_level.txt +0 -0
lgdo/compression/radware.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
import logging
|
3
4
|
from dataclasses import dataclass
|
4
5
|
|
5
6
|
import numba
|
@@ -8,7 +9,9 @@ from numpy import int16, int32, ubyte, uint16, uint32
|
|
8
9
|
from numpy.typing import NDArray
|
9
10
|
|
10
11
|
from .. import types as lgdo
|
11
|
-
from .base import WaveformCodec
|
12
|
+
from .base import WaveformCodec, numba_defaults
|
13
|
+
|
14
|
+
log = logging.getLogger(__name__)
|
12
15
|
|
13
16
|
# fmt: off
|
14
17
|
_radware_sigcompress_mask = uint16([0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023,
|
@@ -38,16 +41,27 @@ class RadwareSigcompress(WaveformCodec):
|
|
38
41
|
|
39
42
|
def encode(
|
40
43
|
sig_in: NDArray | lgdo.VectorOfVectors | lgdo.ArrayOfEqualSizedArrays,
|
41
|
-
sig_out: NDArray[ubyte]
|
42
|
-
| lgdo.VectorOfEncodedVectors
|
43
|
-
| lgdo.ArrayOfEncodedEqualSizedArrays = None,
|
44
|
+
sig_out: NDArray[ubyte] = None,
|
44
45
|
shift: int32 = 0,
|
45
|
-
) ->
|
46
|
+
) -> (
|
47
|
+
(NDArray[ubyte], NDArray[uint32])
|
48
|
+
| lgdo.VectorOfEncodedVectors
|
49
|
+
| lgdo.ArrayOfEncodedEqualSizedArrays
|
50
|
+
):
|
46
51
|
"""Compress digital signal(s) with `radware-sigcompress`.
|
47
52
|
|
48
53
|
Wraps :func:`._radware_sigcompress_encode` and adds support for encoding
|
49
54
|
LGDO arrays. Resizes the encoded array to its actual length.
|
50
55
|
|
56
|
+
Note
|
57
|
+
----
|
58
|
+
If `sig_in` is a NumPy array, no resizing of `sig_out` is performed. Not
|
59
|
+
even of the internally allocated one.
|
60
|
+
|
61
|
+
Because of the current (hardware vectorized) implementation, providing a
|
62
|
+
pre-allocated :class:`.VectorOfEncodedVectors` or
|
63
|
+
:class:`.ArrayOfEncodedEqualSizedArrays` as `sig_out` is not possible.
|
64
|
+
|
51
65
|
Note
|
52
66
|
----
|
53
67
|
The compression algorithm internally interprets the input waveform values as
|
@@ -66,99 +80,128 @@ def encode(
|
|
66
80
|
|
67
81
|
Returns
|
68
82
|
-------
|
69
|
-
sig_out
|
83
|
+
sig_out, nbytes | LGDO
|
70
84
|
given pre-allocated `sig_out` structure or new structure of unsigned
|
71
|
-
8-bit integers
|
85
|
+
8-bit integers, plus the number of bytes (length) of the encoded
|
86
|
+
signal. If `sig_in` is an :class:`.LGDO`, only a newly allocated
|
87
|
+
:class:`.VectorOfEncodedVectors` or
|
88
|
+
:class:`.ArrayOfEncodedEqualSizedArrays` is returned.
|
72
89
|
|
73
90
|
See Also
|
74
91
|
--------
|
75
92
|
._radware_sigcompress_encode
|
76
93
|
"""
|
77
|
-
|
78
|
-
|
79
|
-
max_out_len = 2 * len(sig_in)
|
80
|
-
if isinstance(sig_in, np.ndarray) and sig_in.ndim == 1:
|
94
|
+
if isinstance(sig_in, np.ndarray):
|
95
|
+
s = sig_in.shape
|
81
96
|
if len(sig_in) == 0:
|
82
|
-
return
|
97
|
+
return np.empty(s[:-1] + (0,), dtype=ubyte), np.empty(0, dtype=uint32)
|
83
98
|
|
84
|
-
if
|
85
|
-
#
|
86
|
-
|
99
|
+
if sig_out is None:
|
100
|
+
# the encoded signal is an array of bytes
|
101
|
+
# -> twice as long as a uint16
|
102
|
+
# pre-allocate ubyte (uint8) array, expand last dimension
|
103
|
+
sig_out = np.empty(s[:-1] + (s[-1] * 2,), dtype=ubyte)
|
87
104
|
|
88
105
|
if sig_out.dtype != ubyte:
|
89
106
|
raise ValueError("sig_out must be of type ubyte")
|
90
107
|
|
91
|
-
|
108
|
+
# nbytes has one dimension less (the last one)
|
109
|
+
nbytes = np.empty(s[:-1], dtype=uint32)
|
110
|
+
# shift too, but let the user specify one value for all waveforms
|
111
|
+
# and give it the right shape
|
112
|
+
if not hasattr(shift, "__len__"):
|
113
|
+
shift = np.full(s[:-1], shift, dtype=int32)
|
92
114
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
sig_out.resize(outlen, refcheck=True)
|
115
|
+
_radware_sigcompress_encode(
|
116
|
+
sig_in, sig_out, shift, nbytes, _radware_sigcompress_mask
|
117
|
+
)
|
97
118
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
119
|
+
# return without resizing
|
120
|
+
return sig_out, nbytes
|
121
|
+
|
122
|
+
elif isinstance(sig_in, lgdo.VectorOfVectors):
|
123
|
+
if sig_out is not None:
|
124
|
+
log.warning(
|
125
|
+
"a pre-allocated VectorOfEncodedVectors was given "
|
126
|
+
"to hold an encoded ArrayOfEqualSizedArrays. "
|
127
|
+
"This is not supported at the moment, so a new one "
|
128
|
+
"will be allocated to replace it"
|
107
129
|
)
|
108
|
-
|
109
|
-
|
130
|
+
# convert VectorOfVectors to ArrayOfEqualSizedArrays so it can be
|
131
|
+
# directly passed to the low-level encoding routine
|
132
|
+
sig_out_nda, nbytes = encode(sig_in.to_aoesa(), shift=shift)
|
110
133
|
|
111
|
-
#
|
112
|
-
|
113
|
-
|
134
|
+
# build the encoded LGDO
|
135
|
+
encoded_data = lgdo.ArrayOfEqualSizedArrays(nda=sig_out_nda).to_vov(
|
136
|
+
cumulative_length=np.cumsum(nbytes, dtype=uint32)
|
137
|
+
)
|
138
|
+
# decoded_size is an array, compute it by diff'ing the original VOV
|
139
|
+
decoded_size = np.diff(sig_in.cumulative_length, prepend=uint32(0))
|
114
140
|
|
115
|
-
|
116
|
-
# TODO: really even if user supplied? Maybe not
|
117
|
-
sig_out.resize(len(sig_in))
|
141
|
+
sig_out = lgdo.VectorOfEncodedVectors(encoded_data, decoded_size)
|
118
142
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
143
|
+
return sig_out
|
144
|
+
|
145
|
+
elif isinstance(sig_in, lgdo.ArrayOfEqualSizedArrays):
|
146
|
+
if sig_out is not None:
|
147
|
+
log.warning(
|
148
|
+
"a pre-allocated ArrayOfEncodedEqualSizedArrays was given "
|
149
|
+
"to hold an encoded ArrayOfEqualSizedArrays. "
|
150
|
+
"This is not supported at the moment, so a new one "
|
151
|
+
"will be allocated to replace it"
|
126
152
|
)
|
127
|
-
elif not isinstance(sig_out, lgdo.VectorOfEncodedVectors):
|
128
|
-
raise ValueError("sig_out must be a VectorOfEncodedVectors")
|
129
153
|
|
130
|
-
#
|
131
|
-
|
132
|
-
for i, wf in enumerate(sig_in):
|
133
|
-
sig_out.encoded_data._set_vector_unsafe(i, encode(wf, shift=shift))
|
134
|
-
sig_out.decoded_size[i] = len(wf)
|
154
|
+
# encode the internal numpy array
|
155
|
+
sig_out_nda, nbytes = encode(sig_in.nda, shift=shift)
|
135
156
|
|
136
|
-
|
137
|
-
|
157
|
+
# build the encoded LGDO
|
158
|
+
encoded_data = lgdo.ArrayOfEqualSizedArrays(nda=sig_out_nda).to_vov(
|
159
|
+
cumulative_length=np.cumsum(nbytes, dtype=uint32)
|
160
|
+
)
|
161
|
+
sig_out = lgdo.ArrayOfEncodedEqualSizedArrays(
|
162
|
+
encoded_data, decoded_size=sig_in.nda.shape[1]
|
163
|
+
)
|
138
164
|
|
139
|
-
|
140
|
-
# TODO: really even if user supplied? Maybe not
|
141
|
-
sig_out.resize(len(sig_in))
|
165
|
+
return sig_out
|
142
166
|
|
143
|
-
|
167
|
+
elif isinstance(sig_in, lgdo.Array):
|
168
|
+
# encode the internal numpy array
|
169
|
+
sig_out_nda, nbytes = encode(sig_in.nda, sig_out, shift=shift)
|
170
|
+
return lgdo.Array(sig_out_nda), nbytes
|
171
|
+
|
172
|
+
else:
|
173
|
+
raise ValueError(f"unsupported input signal type ({type(sig_in)})")
|
144
174
|
|
145
175
|
|
146
176
|
def decode(
|
147
177
|
sig_in: NDArray[ubyte]
|
148
178
|
| lgdo.VectorOfEncodedVectors
|
149
179
|
| lgdo.ArrayOfEncodedEqualSizedArrays,
|
150
|
-
sig_out: NDArray | lgdo.
|
180
|
+
sig_out: NDArray | lgdo.ArrayOfEqualSizedArrays = None,
|
151
181
|
shift: int32 = 0,
|
152
|
-
) -> NDArray | lgdo.VectorOfVectors | lgdo.ArrayOfEqualSizedArrays:
|
182
|
+
) -> (NDArray, NDArray[uint32]) | lgdo.VectorOfVectors | lgdo.ArrayOfEqualSizedArrays:
|
153
183
|
"""Decompress digital signal(s) with `radware-sigcompress`.
|
154
184
|
|
155
185
|
Wraps :func:`._radware_sigcompress_decode` and adds support for decoding
|
156
186
|
LGDOs. Resizes the decoded signals to their actual length.
|
157
187
|
|
188
|
+
Note
|
189
|
+
----
|
190
|
+
If `sig_in` is a NumPy array, no resizing (along the last dimension) of
|
191
|
+
`sig_out` to its actual length is performed. Not even of the internally
|
192
|
+
allocated one. If a pre-allocated :class:`.ArrayOfEqualSizedArrays` is
|
193
|
+
provided, it won't be resized too. The internally allocated
|
194
|
+
:class:`.ArrayOfEqualSizedArrays` `sig_out` has instead always the correct
|
195
|
+
size.
|
196
|
+
|
197
|
+
Because of the current (hardware vectorized) implementation, providing a
|
198
|
+
pre-allocated :class:`.VectorOfVectors` as `sig_out` is not possible.
|
199
|
+
|
158
200
|
Parameters
|
159
201
|
----------
|
160
202
|
sig_in
|
161
|
-
array(s) holding the input, compressed signal(s).
|
203
|
+
array(s) holding the input, compressed signal(s). Output of
|
204
|
+
:func:`.encode`.
|
162
205
|
sig_out
|
163
206
|
pre-allocated array(s) for the decompressed signal(s). If not
|
164
207
|
provided, will allocate a 32-bit integer array(s) structure.
|
@@ -168,62 +211,97 @@ def decode(
|
|
168
211
|
|
169
212
|
Returns
|
170
213
|
-------
|
171
|
-
sig_out
|
172
|
-
given pre-allocated structure or new structure of 32-bit integers
|
214
|
+
sig_out, nbytes | LGDO
|
215
|
+
given pre-allocated structure or new structure of 32-bit integers, plus
|
216
|
+
the number of bytes (length) of the decoded signal.
|
173
217
|
|
174
218
|
See Also
|
175
219
|
--------
|
176
220
|
._radware_sigcompress_decode
|
177
221
|
"""
|
178
|
-
|
179
|
-
|
180
|
-
|
222
|
+
# expect the output of encode()
|
223
|
+
if isinstance(sig_in, tuple):
|
224
|
+
s = sig_in[0].shape
|
225
|
+
if sig_out is None:
|
226
|
+
# allocate output array with lasd dim as large as the longest
|
227
|
+
# uncompressed wf
|
228
|
+
maxs = np.max(_get_hton_u16(sig_in[0], 0))
|
229
|
+
sig_out = np.empty(s[:-1] + (maxs,), dtype=int32)
|
181
230
|
|
182
|
-
siglen
|
183
|
-
|
184
|
-
# pre-allocate memory, use safe int32
|
185
|
-
sig_out = np.empty(siglen, dtype="int32")
|
186
|
-
elif len(sig_out) < siglen:
|
187
|
-
# TODO: really even if user supplied? Maybe not
|
188
|
-
sig_out.resize(siglen, refcheck=False)
|
231
|
+
# siglen has one dimension less (the last)
|
232
|
+
siglen = np.empty(s[:-1], dtype=uint32)
|
189
233
|
|
190
|
-
|
234
|
+
if len(sig_in[0]) == 0:
|
235
|
+
return sig_out, siglen
|
236
|
+
|
237
|
+
# call low-level routine
|
238
|
+
# does not need to know sig_in[1]
|
239
|
+
_radware_sigcompress_decode(
|
240
|
+
sig_in[0], sig_out, shift, siglen, _radware_sigcompress_mask
|
241
|
+
)
|
242
|
+
|
243
|
+
return sig_out, siglen
|
191
244
|
|
192
245
|
elif isinstance(sig_in, lgdo.ArrayOfEncodedEqualSizedArrays):
|
193
|
-
if
|
194
|
-
#
|
246
|
+
if sig_out is None:
|
247
|
+
# initialize output structure with decoded_size
|
195
248
|
sig_out = lgdo.ArrayOfEqualSizedArrays(
|
196
249
|
dims=(1, 1),
|
197
250
|
shape=(len(sig_in), sig_in.decoded_size.value),
|
198
|
-
dtype=
|
251
|
+
dtype=int32,
|
252
|
+
attrs=sig_in.getattrs(),
|
199
253
|
)
|
200
254
|
|
201
|
-
|
202
|
-
|
255
|
+
siglen = np.empty(len(sig_in), dtype=uint32)
|
256
|
+
# save original encoded vector lengths
|
257
|
+
nbytes = np.diff(sig_in.encoded_data.cumulative_length.nda, prepend=uint32(0))
|
203
258
|
|
204
|
-
|
205
|
-
sig_out
|
259
|
+
if len(sig_in) == 0:
|
260
|
+
return sig_out
|
261
|
+
|
262
|
+
# convert vector of vectors to array of equal sized arrays
|
263
|
+
# can now decode on the 2D matrix together with number of bytes to read per row
|
264
|
+
_, siglen = decode(
|
265
|
+
(sig_in.encoded_data.to_aoesa(preserve_dtype=True).nda, nbytes),
|
266
|
+
sig_out if isinstance(sig_out, np.ndarray) else sig_out.nda,
|
267
|
+
shift=shift,
|
268
|
+
)
|
269
|
+
|
270
|
+
# sanity check
|
271
|
+
assert np.all(sig_in.decoded_size.value == siglen)
|
272
|
+
|
273
|
+
return sig_out
|
206
274
|
|
207
275
|
elif isinstance(sig_in, lgdo.VectorOfEncodedVectors):
|
208
|
-
if
|
209
|
-
|
210
|
-
|
211
|
-
|
276
|
+
if sig_out:
|
277
|
+
log.warning(
|
278
|
+
"a pre-allocated VectorOfVectors was given "
|
279
|
+
"to hold an encoded VectorOfVectors. "
|
280
|
+
"This is not supported at the moment, so a new one "
|
281
|
+
"will be allocated to replace it"
|
212
282
|
)
|
213
283
|
|
214
|
-
|
215
|
-
|
284
|
+
siglen = np.empty(len(sig_in), dtype=uint32)
|
285
|
+
# save original encoded vector lengths
|
286
|
+
nbytes = np.diff(sig_in.encoded_data.cumulative_length.nda, prepend=uint32(0))
|
216
287
|
|
217
|
-
|
218
|
-
|
288
|
+
# convert vector of vectors to array of equal sized arrays
|
289
|
+
# can now decode on the 2D matrix together with number of bytes to read per row
|
290
|
+
sig_out, siglen = decode(
|
291
|
+
(sig_in.encoded_data.to_aoesa(preserve_dtype=True).nda, nbytes), shift=shift
|
292
|
+
)
|
219
293
|
|
220
|
-
|
221
|
-
|
294
|
+
# sanity check
|
295
|
+
assert np.array_equal(sig_in.decoded_size, siglen)
|
222
296
|
|
223
|
-
|
297
|
+
# converto to VOV before returning
|
298
|
+
return sig_out.to_vov(np.cumsum(siglen, dtype=uint32))
|
299
|
+
|
300
|
+
else:
|
301
|
+
raise ValueError("unsupported input signal type")
|
224
302
|
|
225
303
|
|
226
|
-
@numba.jit(
|
304
|
+
@numba.jit(**numba_defaults)
|
227
305
|
def _set_hton_u16(a: NDArray[ubyte], i: int, x: int) -> int:
|
228
306
|
"""Store an unsigned 16-bit integer value in an array of unsigned 8-bit integers.
|
229
307
|
|
@@ -238,7 +316,7 @@ def _set_hton_u16(a: NDArray[ubyte], i: int, x: int) -> int:
|
|
238
316
|
return x
|
239
317
|
|
240
318
|
|
241
|
-
@numba.jit(
|
319
|
+
@numba.jit(**numba_defaults)
|
242
320
|
def _get_hton_u16(a: NDArray[ubyte], i: int) -> uint16:
|
243
321
|
"""Read unsigned 16-bit integer values from an array of unsigned 8-bit integers.
|
244
322
|
|
@@ -247,36 +325,51 @@ def _get_hton_u16(a: NDArray[ubyte], i: int) -> uint16:
|
|
247
325
|
"""
|
248
326
|
i_1 = i * 2
|
249
327
|
i_2 = i_1 + 1
|
250
|
-
|
328
|
+
if a.ndim == 1:
|
329
|
+
return uint16(a[i_1] << 8 | a[i_2])
|
330
|
+
else:
|
331
|
+
return a[..., i_1].astype("uint16") << 8 | a[..., i_2]
|
251
332
|
|
252
333
|
|
253
|
-
@numba.jit("uint16(uint32)",
|
334
|
+
@numba.jit("uint16(uint32)", **numba_defaults)
|
254
335
|
def _get_high_u16(x: uint32) -> uint16:
|
255
336
|
return uint16(x >> 16)
|
256
337
|
|
257
338
|
|
258
|
-
@numba.jit("uint32(uint32, uint16)",
|
339
|
+
@numba.jit("uint32(uint32, uint16)", **numba_defaults)
|
259
340
|
def _set_high_u16(x: uint32, y: uint16) -> uint32:
|
260
341
|
return uint32(x & 0x0000FFFF | (y << 16))
|
261
342
|
|
262
343
|
|
263
|
-
@numba.jit("uint16(uint32)",
|
344
|
+
@numba.jit("uint16(uint32)", **numba_defaults)
|
264
345
|
def _get_low_u16(x: uint32) -> uint16:
|
265
346
|
return uint16(x >> 0)
|
266
347
|
|
267
348
|
|
268
|
-
@numba.jit("uint32(uint32, uint16)",
|
349
|
+
@numba.jit("uint32(uint32, uint16)", **numba_defaults)
|
269
350
|
def _set_low_u16(x: uint32, y: uint16) -> uint32:
|
270
351
|
return uint32(x & 0xFFFF0000 | (y << 0))
|
271
352
|
|
272
353
|
|
273
|
-
@numba.
|
354
|
+
@numba.guvectorize(
|
355
|
+
[
|
356
|
+
"void(uint16[:], byte[:], int32[:], uint32[:], uint16[:])",
|
357
|
+
"void(uint32[:], byte[:], int32[:], uint32[:], uint16[:])",
|
358
|
+
"void(uint64[:], byte[:], int32[:], uint32[:], uint16[:])",
|
359
|
+
"void( int16[:], byte[:], int32[:], uint32[:], uint16[:])",
|
360
|
+
"void( int32[:], byte[:], int32[:], uint32[:], uint16[:])",
|
361
|
+
"void( int64[:], byte[:], int32[:], uint32[:], uint16[:])",
|
362
|
+
],
|
363
|
+
"(n),(m),(),(),(o)",
|
364
|
+
**numba_defaults,
|
365
|
+
)
|
274
366
|
def _radware_sigcompress_encode(
|
275
367
|
sig_in: NDArray,
|
276
368
|
sig_out: NDArray[ubyte],
|
277
369
|
shift: int32,
|
370
|
+
siglen: uint32,
|
278
371
|
_mask: NDArray[uint16] = _radware_sigcompress_mask,
|
279
|
-
) ->
|
372
|
+
) -> None:
|
280
373
|
"""Compress a digital signal.
|
281
374
|
|
282
375
|
Shifts the signal values by ``+shift`` and internally interprets the result
|
@@ -297,7 +390,7 @@ def _radware_sigcompress_encode(
|
|
297
390
|
- Store encoded, :class:`numpy.uint16` signal as an array of bytes
|
298
391
|
(:class:`numpy.ubyte`), in big-endian ordering.
|
299
392
|
- Declare mask globally to avoid extra memory allocation.
|
300
|
-
-
|
393
|
+
- Enable hardware-vectorization with Numba (:func:`numba.guvectorize`).
|
301
394
|
- Add a couple of missing array boundary checks.
|
302
395
|
|
303
396
|
.. [1] `radware-sigcompress source code
|
@@ -313,6 +406,10 @@ def _radware_sigcompress_encode(
|
|
313
406
|
sig_out
|
314
407
|
pre-allocated array for the unsigned 8-bit encoded signal. In the
|
315
408
|
original C code, an array of unsigned 16-bit integers was expected.
|
409
|
+
shift
|
410
|
+
value to be added to `sig_in` before compression.
|
411
|
+
siglen
|
412
|
+
array that will hold the lengths of the compressed signals.
|
316
413
|
|
317
414
|
Returns
|
318
415
|
-------
|
@@ -320,6 +417,7 @@ def _radware_sigcompress_encode(
|
|
320
417
|
number of bytes in the encoded signal
|
321
418
|
"""
|
322
419
|
mask = _mask
|
420
|
+
shift = shift[0]
|
323
421
|
|
324
422
|
i = j = max1 = max2 = min1 = min2 = ds = int16(0)
|
325
423
|
nb1 = nb2 = iso = nw = bp = dd1 = dd2 = int16(0)
|
@@ -463,16 +561,28 @@ def _radware_sigcompress_encode(
|
|
463
561
|
if iso % 2 > 0:
|
464
562
|
iso += 1
|
465
563
|
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
@numba.
|
564
|
+
siglen[0] = 2 * iso # number of bytes in compressed signal data
|
565
|
+
|
566
|
+
|
567
|
+
@numba.guvectorize(
|
568
|
+
[
|
569
|
+
"void(byte[:], uint16[:], int32[:], uint32[:], uint16[:])",
|
570
|
+
"void(byte[:], uint32[:], int32[:], uint32[:], uint16[:])",
|
571
|
+
"void(byte[:], uint64[:], int32[:], uint32[:], uint16[:])",
|
572
|
+
"void(byte[:], int16[:], int32[:], uint32[:], uint16[:])",
|
573
|
+
"void(byte[:], int32[:], int32[:], uint32[:], uint16[:])",
|
574
|
+
"void(byte[:], int64[:], int32[:], uint32[:], uint16[:])",
|
575
|
+
],
|
576
|
+
"(n),(m),(),(),(o)",
|
577
|
+
**numba_defaults,
|
578
|
+
)
|
470
579
|
def _radware_sigcompress_decode(
|
471
580
|
sig_in: NDArray[ubyte],
|
472
581
|
sig_out: NDArray,
|
473
582
|
shift: int32,
|
583
|
+
siglen: uint32,
|
474
584
|
_mask: NDArray[uint16] = _radware_sigcompress_mask,
|
475
|
-
) ->
|
585
|
+
) -> None:
|
476
586
|
"""Deompress a digital signal.
|
477
587
|
|
478
588
|
After decoding, the signal values are shifted by ``-shift`` to restore the
|
@@ -491,6 +601,9 @@ def _radware_sigcompress_decode(
|
|
491
601
|
sig_out
|
492
602
|
pre-allocated array for the decompressed signal. In the original code,
|
493
603
|
an array of 16-bit integers was expected.
|
604
|
+
shift
|
605
|
+
the value the original signal(s) was shifted before compression. The
|
606
|
+
value is *subtracted* from samples in `sig_out` right after decoding.
|
494
607
|
|
495
608
|
Returns
|
496
609
|
-------
|
@@ -498,15 +611,16 @@ def _radware_sigcompress_decode(
|
|
498
611
|
length of output, decompressed signal.
|
499
612
|
"""
|
500
613
|
mask = _mask
|
614
|
+
shift = shift[0]
|
501
615
|
|
502
616
|
i = j = min_val = nb = isi = iso = nw = bp = int16(0)
|
503
617
|
dd = uint32(0)
|
504
618
|
|
505
619
|
sig_len_in = int(sig_in.size / 2)
|
506
|
-
|
620
|
+
_siglen = int16(_get_hton_u16(sig_in, isi)) # signal length
|
507
621
|
isi += 1
|
508
622
|
|
509
|
-
while (isi < sig_len_in) and (iso <
|
623
|
+
while (isi < sig_len_in) and (iso < _siglen):
|
510
624
|
if bp > 0:
|
511
625
|
isi += 1
|
512
626
|
bp = 0 # bit pointer
|
@@ -521,7 +635,7 @@ def _radware_sigcompress_decode(
|
|
521
635
|
isi += 1
|
522
636
|
dd = _set_low_u16(dd, _get_hton_u16(sig_in, isi))
|
523
637
|
i = 0
|
524
|
-
while (i < nw) and (iso <
|
638
|
+
while (i < nw) and (iso < _siglen):
|
525
639
|
if (bp + nb) > 15:
|
526
640
|
bp -= 16
|
527
641
|
dd = _set_high_u16(dd, _get_hton_u16(sig_in, isi))
|
@@ -549,7 +663,7 @@ def _radware_sigcompress_decode(
|
|
549
663
|
dd = _set_low_u16(dd, _get_hton_u16(sig_in, isi))
|
550
664
|
|
551
665
|
i = 1
|
552
|
-
while (i < nw) and (iso <
|
666
|
+
while (i < nw) and (iso < _siglen):
|
553
667
|
if (bp + nb) > 15:
|
554
668
|
bp -= 16
|
555
669
|
dd = _set_high_u16(dd, _get_hton_u16(sig_in, isi))
|
@@ -573,7 +687,7 @@ def _radware_sigcompress_decode(
|
|
573
687
|
i += 1
|
574
688
|
j += nw
|
575
689
|
|
576
|
-
if
|
690
|
+
if _siglen != iso:
|
577
691
|
raise RuntimeError("failure: unexpected signal length after decompression")
|
578
692
|
|
579
|
-
|
693
|
+
siglen[0] = _siglen # number of shorts in decompressed signal data
|