@@ -499,6 +499,156 @@ def testStringsZstd(self):
499499 self ._test_strings ("zstd" )
500500
501501
502+ class TestFromFilterOptions (unittest .TestCase ):
503+ """Test from_filter_options methods"""
504+
505+ def testBitshuffle (self ):
506+ for filter_options , expected_options in (
507+ # (_, _, _, nelems, compression_id, clevel)
508+ ((), (0 , 0 )), # Default: no compression
509+ ((0 , 2 , 4 , 256 ), (256 , 0 )), # custom nelems
510+ ((0 , 2 , 4 , 0 , 2 ), (0 , 2 )), # LZ4
511+ ((0 , 2 , 4 , 0 , 3 ), (0 , 3 , 3 )), # Zstd with default clevel
512+ ((0 , 2 , 4 , 0 , 3 , 5 ), (0 , 3 , 5 )), # Zstd with custom clevel
513+ ):
514+ with self .subTest (filter_options = filter_options ):
515+ compression_filter = hdf5plugin .Bitshuffle .from_filter_options (
516+ filter_options
517+ )
518+ self .assertEqual (compression_filter .filter_options , expected_options )
519+
520+ def testBlosc (self ):
521+ for filter_options , expected_options in (
522+ # (_, _, _, _, clevel, shuffle, compression_id)
523+ ((), (0 , 0 , 0 , 0 , 5 , 1 , 0 )), # Default: no compression
524+ ((2 , 2 , 4 , 40000 , 3 ), (0 , 0 , 0 , 0 , 3 , 1 , 0 )), # custom clevel
525+ (
526+ (2 , 2 , 4 , 40000 , 3 , 2 ),
527+ (0 , 0 , 0 , 0 , 3 , 2 , 0 ),
528+ ), # custom clevel and shuffle
529+ ((2 , 2 , 4 , 40000 , 8 , 2 , 1 ), (0 , 0 , 0 , 0 , 8 , 2 , 1 )), # all custom
530+ ):
531+ with self .subTest (filter_options = filter_options ):
532+ compression_filter = hdf5plugin .Blosc .from_filter_options (
533+ filter_options
534+ )
535+ self .assertEqual (compression_filter .filter_options , expected_options )
536+
537+ def testBlosc2 (self ):
538+ for filter_options , expected_options in (
539+ # (_, _, _, _, clevel, filters, compression_id)
540+ ((), (0 , 0 , 0 , 0 , 5 , 1 , 0 )), # Default: no compression
541+ ((2 , 2 , 4 , 40000 , 3 ), (0 , 0 , 0 , 0 , 3 , 1 , 0 )), # custom clevel
542+ (
543+ (2 , 2 , 4 , 40000 , 3 , 2 ),
544+ (0 , 0 , 0 , 0 , 3 , 2 , 0 ),
545+ ), # custom clevel and filters
546+ ((2 , 2 , 4 , 40000 , 8 , 2 , 1 ), (0 , 0 , 0 , 0 , 8 , 2 , 1 )), # all custom
547+ ):
548+ with self .subTest (filter_options = filter_options ):
549+ compression_filter = hdf5plugin .Blosc2 .from_filter_options (
550+ filter_options
551+ )
552+ self .assertEqual (compression_filter .filter_options , expected_options )
553+
554+ def testBZip2 (self ):
555+ for filter_options , expected_options in (
556+ # (blocksize,)
557+ ((), (9 ,)),
558+ ((5 ,), (5 ,)),
559+ ):
560+ with self .subTest (filter_options = filter_options ):
561+ compression_filter = hdf5plugin .BZip2 .from_filter_options (
562+ filter_options
563+ )
564+ self .assertEqual (compression_filter .filter_options , expected_options )
565+
566+ def testFciDecomp (self ):
567+ compression_filter = hdf5plugin .FciDecomp .from_filter_options ((1 , 2 , 3 ))
568+ self .assertEqual (compression_filter .filter_options , ())
569+
570+ def testLZ4 (self ):
571+ for filter_options , expected_options in (
572+ # (nbytes,)
573+ ((), (0 ,)),
574+ ((1024 ,), (1024 ,)),
575+ ):
576+ with self .subTest (filter_options = filter_options ):
577+ compression_filter = hdf5plugin .LZ4 .from_filter_options (filter_options )
578+ self .assertEqual (compression_filter .filter_options , expected_options )
579+
580+ def testZstd (self ):
581+ for filter_options , expected_options in (
582+ # (clevel,)
583+ ((), (3 ,)),
584+ ((10 ,), (10 ,)),
585+ ):
586+ with self .subTest (filter_options = filter_options ):
587+ compression_filter = hdf5plugin .Zstd .from_filter_options (filter_options )
588+ self .assertEqual (compression_filter .filter_options , expected_options )
589+
590+
591+ class TestFromFilterOptionsRoundtrip (unittest .TestCase ):
592+ """Test from_filter_options function roundtrip"""
593+
594+ def _test (
595+ self , compression_filter : _filters .FilterBase , data : numpy .ndarray [Any , Any ]
596+ ):
597+ with h5py .File ("in_memory" , "w" , driver = "core" , backing_store = False ) as h5f :
598+ h5f .create_dataset (
599+ "data" ,
600+ data = data ,
601+ chunks = data .shape ,
602+ compression = compression_filter ,
603+ )
604+ h5f .flush ()
605+
606+ plist = h5f ["data" ].id .get_create_plist ()
607+ filters = [plist .get_filter (i ) for i in range (plist .get_nfilters ())]
608+
609+ self .assertEqual (len (filters ), 1 )
610+ filter_id , _ , filter_options , _ = filters [0 ]
611+
612+ retrieved_filter = hdf5plugin .from_filter_options (filter_id , filter_options )
613+
614+ self .assertEqual (compression_filter , retrieved_filter )
615+
616+ @unittest .skipUnless (should_test ("bshuf" ), "Bitshuffle filter not available" )
617+ def testBitshuffle (self ):
618+ data = numpy .arange (256 ** 2 , dtype = numpy .float32 ).reshape (256 , 256 )
619+ self ._test (hdf5plugin .Bitshuffle (), data )
620+
621+ @unittest .skipUnless (should_test ("blosc" ), "Blosc filter not available" )
622+ def testBlosc (self ):
623+ data = numpy .arange (256 ** 2 , dtype = numpy .float32 ).reshape (256 , 256 )
624+ self ._test (hdf5plugin .Blosc (), data )
625+
626+ @unittest .skipUnless (should_test ("blosc2" ), "Blosc2 filter not available" )
627+ def testBlosc2 (self ):
628+ data = numpy .arange (256 ** 2 , dtype = numpy .float32 ).reshape (256 , 256 )
629+ self ._test (hdf5plugin .Blosc2 (), data )
630+
631+ @unittest .skipUnless (should_test ("bzip2" ), "BZip2 filter not available" )
632+ def testBZip2 (self ):
633+ data = numpy .arange (256 ** 2 , dtype = numpy .float32 ).reshape (256 , 256 )
634+ self ._test (hdf5plugin .BZip2 (), data )
635+
636+ @unittest .skipUnless (should_test ("fcidecomp" ), "FCIDECOMP filter not available" )
637+ def testFciDecomp (self ):
638+ data = numpy .arange (256 ** 2 , dtype = numpy .uint16 ).reshape (256 , 256 )
639+ self ._test (hdf5plugin .FciDecomp (), data )
640+
641+ @unittest .skipUnless (should_test ("lz4" ), "LZ4 filter not available" )
642+ def testLZ4 (self ):
643+ data = numpy .arange (256 ** 2 , dtype = numpy .float32 ).reshape (256 , 256 )
644+ self ._test (hdf5plugin .LZ4 (), data )
645+
646+ @unittest .skipUnless (should_test ("zstd" ), "Zstd filter not available" )
647+ def testZstd (self ):
648+ data = numpy .arange (256 ** 2 , dtype = numpy .float32 ).reshape (256 , 256 )
649+ self ._test (hdf5plugin .Zstd (), data )
650+
651+
502652class TestPackage (unittest .TestCase ):
503653 """Test general features of the hdf5plugin package"""
504654
@@ -742,6 +892,8 @@ def suite() -> unittest.TestSuite:
742892 for cls in (
743893 TestHDF5PluginRW ,
744894 TestStrings ,
895+ TestFromFilterOptions ,
896+ TestFromFilterOptionsRoundtrip ,
745897 TestPackage ,
746898 TestRegisterFilter ,
747899 TestGetFilters ,
0 commit comments