Skip to content

Commit 4516126

Browse files
committed
Add SZ3.from_filter_options
1 parent a9b00c7 commit 4516126

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

src/hdf5plugin/_filters.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,30 @@ def __init__(
968968

969969
self.filter_options = compression_opts
970970

971+
@classmethod
972+
def from_filter_options(cls, filter_options: tuple[int, ...]) -> SZ3:
973+
if len(filter_options) < 13:
974+
raise ValueError(f"Expected 13 values, got {len(filter_options)}")
975+
976+
sz_mode = filter_options[4]
977+
if sz_mode == 0:
978+
return cls(
979+
absolute=cls.__unpack_float64(filter_options[5], filter_options[6])
980+
)
981+
if sz_mode == 1:
982+
return cls(
983+
relative=cls.__unpack_float64(filter_options[7], filter_options[8])
984+
)
985+
if sz_mode == 2:
986+
return cls(
987+
norm2=cls.__unpack_float64(filter_options[9], filter_options[10])
988+
)
989+
if sz_mode == 3:
990+
psnr = cls.__unpack_float64(filter_options[11], filter_options[12])
991+
return cls(peak_signal_to_noise_ratio=psnr)
992+
993+
raise ValueError(f"Unsupported sz_mode: {sz_mode}")
994+
971995
@staticmethod
972996
def __pack_float64(error: float) -> tuple[int, int]:
973997
# Pack as big-endian IEEE 754 double
@@ -978,6 +1002,13 @@ def __pack_float64(error: float) -> tuple[int, int]:
9781002
low = struct.unpack(">I", packed[4:8])[0]
9791003
return high, low
9801004

1005+
@staticmethod
1006+
def __unpack_float64(high: int, low: int) -> float:
1007+
# Pack most-significant & least-significant bits
1008+
packed = struct.pack(">II", high, low)
1009+
# Unpack as big-endian IEEE 754 double
1010+
return float(struct.unpack(">d", packed)[0])
1011+
9811012

9821013
class Zstd(FilterBase):
9831014
"""``h5py.Group.create_dataset``'s compression arguments for using FciDecomp filter.

src/hdf5plugin/test.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,35 @@ def testSperr(self):
598598
compression_filter.filter_options, expected_filter.filter_options
599599
)
600600

601+
def testSZ3(self):
602+
for filter_options, expected_filter in (
603+
(
604+
(1, 0, 0, 256, 0, 1058682594, 3944497965, 0, 0, 0, 0, 0, 0),
605+
hdf5plugin.SZ3(),
606+
),
607+
(
608+
(1, 0, 0, 256, 0, 1051772663, 2696277389, 0, 0, 0, 0, 0, 0),
609+
hdf5plugin.SZ3(absolute=1e-6),
610+
),
611+
(
612+
(1, 0, 0, 256, 1, 0, 0, 1062232653, 3539053052, 0, 0, 0, 0),
613+
hdf5plugin.SZ3(relative=1e-3),
614+
),
615+
(
616+
(1, 0, 0, 256, 2, 0, 0, 0, 0, 1062232653, 3539053052, 0, 0),
617+
hdf5plugin.SZ3(norm2=1e-3),
618+
),
619+
(
620+
(1, 0, 0, 256, 3, 0, 0, 0, 0, 0, 0, 1062232653, 3539053052),
621+
hdf5plugin.SZ3(peak_signal_to_noise_ratio=1e-3),
622+
),
623+
):
624+
with self.subTest(filter_options=filter_options):
625+
compression_filter = hdf5plugin.SZ3.from_filter_options(filter_options)
626+
self.assertEqual(
627+
compression_filter.filter_options, expected_filter.filter_options
628+
)
629+
601630
def testZstd(self):
602631
for filter_options, expected_options in (
603632
# (clevel,)
@@ -669,6 +698,11 @@ def testSperr(self):
669698
data = numpy.arange(256**2, dtype=numpy.float32).reshape(256, 256)
670699
self._test(hdf5plugin.Sperr(), data)
671700

701+
@unittest.skipUnless(should_test("sz3"), "SZ3 filter not available")
702+
def testSZ3(self):
703+
data = numpy.arange(256**2, dtype=numpy.float32).reshape(256, 256)
704+
self._test(hdf5plugin.SZ3(), data)
705+
672706
@unittest.skipUnless(should_test("zstd"), "Zstd filter not available")
673707
def testZstd(self):
674708
data = numpy.arange(256**2, dtype=numpy.float32).reshape(256, 256)

0 commit comments

Comments
 (0)