@@ -586,21 +586,28 @@ def write(
586
586
# data-vars in the file.
587
587
cf_mesh_name = self ._add_mesh (cube )
588
588
589
+ # Group the generic compression keyword arguments together for
590
+ # convenience, as they will be applied to other cube metadata
591
+ # as well as the cube data payload.
592
+ compression_kwargs = {
593
+ "complevel" : complevel ,
594
+ "fletcher32" : fletcher32 ,
595
+ "shuffle" : shuffle ,
596
+ "zlib" : zlib ,
597
+ }
598
+
589
599
# Create the associated cube CF-netCDF data variable.
590
600
cf_var_cube = self ._create_cf_data_variable (
591
601
cube ,
592
602
cube_dimensions ,
593
- local_keys ,
594
- zlib = zlib ,
595
- complevel = complevel ,
596
- shuffle = shuffle ,
597
- fletcher32 = fletcher32 ,
603
+ local_keys = local_keys ,
604
+ packing = packing ,
605
+ fill_value = fill_value ,
598
606
contiguous = contiguous ,
599
607
chunksizes = chunksizes ,
600
608
endian = endian ,
601
609
least_significant_digit = least_significant_digit ,
602
- packing = packing ,
603
- fill_value = fill_value ,
610
+ ** compression_kwargs ,
604
611
)
605
612
606
613
# Associate any mesh with the data-variable.
@@ -615,15 +622,19 @@ def write(
615
622
616
623
# Add the auxiliary coordinate variables and associate the data
617
624
# variable to them
618
- self ._add_aux_coords (cube , cf_var_cube , cube_dimensions )
625
+ self ._add_aux_coords (
626
+ cube , cf_var_cube , cube_dimensions , compression_kwargs = compression_kwargs
627
+ )
619
628
620
629
# Add the cell_measures variables and associate the data
621
630
# variable to them
622
631
self ._add_cell_measures (cube , cf_var_cube , cube_dimensions )
623
632
624
633
# Add the ancillary_variables variables and associate the data variable
625
634
# to them
626
- self ._add_ancillary_variables (cube , cf_var_cube , cube_dimensions )
635
+ self ._add_ancillary_variables (
636
+ cube , cf_var_cube , cube_dimensions , compression_kwargs = compression_kwargs
637
+ )
627
638
628
639
# Add the formula terms to the appropriate cf variables for each
629
640
# aux factory in the cube.
@@ -883,7 +894,14 @@ def _add_mesh(self, cube_or_mesh):
883
894
return cf_mesh_name
884
895
885
896
def _add_inner_related_vars (
886
- self , cube , cf_var_cube , dimension_names , coordlike_elements
897
+ self ,
898
+ cube ,
899
+ cf_var_cube ,
900
+ dimension_names ,
901
+ coordlike_elements ,
902
+ / ,
903
+ * ,
904
+ compression_kwargs = None ,
887
905
):
888
906
"""Create a set of variables for aux-coords, ancillaries or cell-measures.
889
907
@@ -913,7 +931,10 @@ def _add_inner_related_vars(
913
931
if cf_name is None :
914
932
# Not already present : create it
915
933
cf_name = self ._create_generic_cf_array_var (
916
- cube , dimension_names , element
934
+ cube ,
935
+ dimension_names ,
936
+ element ,
937
+ compression_kwargs = compression_kwargs ,
917
938
)
918
939
self ._name_coord_map .append (cf_name , element )
919
940
@@ -929,7 +950,9 @@ def _add_inner_related_vars(
929
950
variable_names = " " .join (sorted (element_names ))
930
951
_setncattr (cf_var_cube , role_attribute_name , variable_names )
931
952
932
- def _add_aux_coords (self , cube , cf_var_cube , dimension_names ):
953
+ def _add_aux_coords (
954
+ self , cube , cf_var_cube , dimension_names , / , * , compression_kwargs = None
955
+ ):
933
956
"""Add aux. coordinate to the dataset and associate with the data variable.
934
957
935
958
Parameters
@@ -940,6 +963,9 @@ def _add_aux_coords(self, cube, cf_var_cube, dimension_names):
940
963
A cf variable cube representation.
941
964
dimension_names : list
942
965
Names associated with the dimensions of the cube.
966
+ compression_kwargs : dict, optional
967
+ NetCDF data compression keyword arguments.
968
+
943
969
"""
944
970
from iris .mesh .components import (
945
971
MeshEdgeCoords ,
@@ -967,6 +993,7 @@ def _add_aux_coords(self, cube, cf_var_cube, dimension_names):
967
993
cf_var_cube ,
968
994
dimension_names ,
969
995
coords_to_add ,
996
+ compression_kwargs = compression_kwargs ,
970
997
)
971
998
972
999
def _add_cell_measures (self , cube , cf_var_cube , dimension_names ):
@@ -988,7 +1015,9 @@ def _add_cell_measures(self, cube, cf_var_cube, dimension_names):
988
1015
cube .cell_measures (),
989
1016
)
990
1017
991
- def _add_ancillary_variables (self , cube , cf_var_cube , dimension_names ):
1018
+ def _add_ancillary_variables (
1019
+ self , cube , cf_var_cube , dimension_names , / , * , compression_kwargs = None
1020
+ ):
992
1021
"""Add ancillary variables measures to the dataset and associate with the data variable.
993
1022
994
1023
Parameters
@@ -999,12 +1028,16 @@ def _add_ancillary_variables(self, cube, cf_var_cube, dimension_names):
999
1028
A cf variable cube representation.
1000
1029
dimension_names : list
1001
1030
Names associated with the dimensions of the cube.
1031
+ compression_kwargs : dict, optional
1032
+ NetCDF data compression keyword arguments.
1033
+
1002
1034
"""
1003
1035
return self ._add_inner_related_vars (
1004
1036
cube ,
1005
1037
cf_var_cube ,
1006
1038
dimension_names ,
1007
1039
cube .ancillary_variables (),
1040
+ compression_kwargs = compression_kwargs ,
1008
1041
)
1009
1042
1010
1043
def _add_dim_coords (self , cube , dimension_names ):
@@ -1439,7 +1472,7 @@ def _ensure_valid_dtype(self, values, src_name, src_object):
1439
1472
values = values .astype (np .int32 )
1440
1473
return values
1441
1474
1442
- def _create_cf_bounds (self , coord , cf_var , cf_name ):
1475
+ def _create_cf_bounds (self , coord , cf_var , cf_name , / , * , compression_kwargs = None ):
1443
1476
"""Create the associated CF-netCDF bounds variable.
1444
1477
1445
1478
Parameters
@@ -1450,13 +1483,18 @@ def _create_cf_bounds(self, coord, cf_var, cf_name):
1450
1483
CF-netCDF variable.
1451
1484
cf_name : str
1452
1485
Name of the CF-NetCDF variable.
1486
+ compression_kwargs : dict, optional
1487
+ NetCDF data compression keyword arguments.
1453
1488
1454
1489
Returns
1455
1490
-------
1456
1491
None
1457
1492
1458
1493
"""
1459
1494
if hasattr (coord , "has_bounds" ) and coord .has_bounds ():
1495
+ if compression_kwargs is None :
1496
+ compression_kwargs = {}
1497
+
1460
1498
# Get the values in a form which is valid for the file format.
1461
1499
bounds = self ._ensure_valid_dtype (
1462
1500
coord .core_bounds (), "the bounds of coordinate" , coord
@@ -1489,6 +1527,7 @@ def _create_cf_bounds(self, coord, cf_var, cf_name):
1489
1527
boundsvar_name ,
1490
1528
bounds .dtype .newbyteorder ("=" ),
1491
1529
cf_var .dimensions + (bounds_dimension_name ,),
1530
+ ** compression_kwargs ,
1492
1531
)
1493
1532
self ._lazy_stream_data (data = bounds , cf_var = cf_var_bounds )
1494
1533
@@ -1685,8 +1724,11 @@ def _create_generic_cf_array_var(
1685
1724
cube_or_mesh ,
1686
1725
cube_dim_names ,
1687
1726
element ,
1727
+ / ,
1728
+ * ,
1688
1729
element_dims = None ,
1689
1730
fill_value = None ,
1731
+ compression_kwargs = None ,
1690
1732
):
1691
1733
"""Create theCF-netCDF variable given dimensional_metadata.
1692
1734
@@ -1718,6 +1760,8 @@ def _create_generic_cf_array_var(
1718
1760
If not set, standard netcdf4-python behaviour : the variable has no
1719
1761
'_FillValue' property, and uses the "standard" fill-value for its
1720
1762
type.
1763
+ compression_kwargs : dict, optional
1764
+ NetCDF data compression keyword arguments.
1721
1765
1722
1766
Returns
1723
1767
-------
@@ -1732,6 +1776,9 @@ def _create_generic_cf_array_var(
1732
1776
else :
1733
1777
cube = None
1734
1778
1779
+ if compression_kwargs is None :
1780
+ compression_kwargs = {}
1781
+
1735
1782
# Work out the var-name to use.
1736
1783
# N.B. the only part of this routine that may use a mesh _or_ a cube.
1737
1784
cf_name = self ._get_coord_variable_name (cube_or_mesh , element )
@@ -1749,6 +1796,9 @@ def _create_generic_cf_array_var(
1749
1796
# (e.g. =points if a coord, =data if an ancillary, etc)
1750
1797
data = element ._core_values ()
1751
1798
1799
+ if cube is None or cube .shape != data .shape :
1800
+ compression_kwargs = {}
1801
+
1752
1802
if np .issubdtype (data .dtype , np .str_ ):
1753
1803
# Deal with string-type variables.
1754
1804
# Typically CF label variables, but also possibly ancil-vars ?
@@ -1811,6 +1861,7 @@ def _create_generic_cf_array_var(
1811
1861
data .dtype .newbyteorder ("=" ),
1812
1862
element_dims ,
1813
1863
fill_value = fill_value ,
1864
+ ** compression_kwargs ,
1814
1865
)
1815
1866
1816
1867
# Add the axis attribute for spatio-temporal CF-netCDF coordinates.
@@ -1820,7 +1871,9 @@ def _create_generic_cf_array_var(
1820
1871
_setncattr (cf_var , "axis" , axis .upper ())
1821
1872
1822
1873
# Create the associated CF-netCDF bounds variable, if any.
1823
- self ._create_cf_bounds (element , cf_var , cf_name )
1874
+ self ._create_cf_bounds (
1875
+ element , cf_var , cf_name , compression_kwargs = compression_kwargs
1876
+ )
1824
1877
1825
1878
# Add the data to the CF-netCDF variable.
1826
1879
self ._lazy_stream_data (data = data , cf_var = cf_var )
@@ -2784,16 +2837,16 @@ def is_valid_packspec(p):
2784
2837
for cube , packspec , fill_value in zip (cubes , packspecs , fill_values ):
2785
2838
sman .write (
2786
2839
cube ,
2787
- local_keys ,
2788
- unlimited_dimensions ,
2789
- zlib ,
2790
- complevel ,
2791
- shuffle ,
2792
- fletcher32 ,
2793
- contiguous ,
2794
- chunksizes ,
2795
- endian ,
2796
- least_significant_digit ,
2840
+ local_keys = local_keys ,
2841
+ unlimited_dimensions = unlimited_dimensions ,
2842
+ zlib = zlib ,
2843
+ complevel = complevel ,
2844
+ shuffle = shuffle ,
2845
+ fletcher32 = fletcher32 ,
2846
+ contiguous = contiguous ,
2847
+ chunksizes = chunksizes ,
2848
+ endian = endian ,
2849
+ least_significant_digit = least_significant_digit ,
2797
2850
packing = packspec ,
2798
2851
fill_value = fill_value ,
2799
2852
)
0 commit comments