Skip to content

Commit 86ccbc6

Browse files
committed
Fixes for data packing.
1 parent 536c932 commit 86ccbc6

File tree

1 file changed

+22
-42
lines changed

1 file changed

+22
-42
lines changed

lib/iris/fileformats/netcdf/saver.py

Lines changed: 22 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,6 +1738,7 @@ def _create_generic_cf_array_var(
17381738
element_dims=None,
17391739
fill_value=None,
17401740
compression_kwargs=None,
1741+
packing_controls: dict | None = None,
17411742
is_dataless=False,
17421743
):
17431744
"""Create theCF-netCDF variable given dimensional_metadata.
@@ -1904,7 +1905,10 @@ def _create_generic_cf_array_var(
19041905
else:
19051906
element_type = type(element).__name__
19061907
data = self._ensure_valid_dtype(data, element_type, element)
1907-
dtype = data.dtype.newbyteorder("=")
1908+
if not packing_controls:
1909+
dtype = data.dtype.newbyteorder("=")
1910+
else:
1911+
dtype = packing_controls["dtype"]
19081912

19091913
# Check if this is a dim-coord.
19101914
is_dimcoord = cube is not None and element in cube.dim_coords
@@ -1937,6 +1941,10 @@ def _create_generic_cf_array_var(
19371941

19381942
# Add the data to the CF-netCDF variable.
19391943
if not is_dataless:
1944+
if packing_controls:
1945+
# We must set packing attributes (if any), before assigning values.
1946+
for key, value in packing_controls["attributes"]:
1947+
_setncattr(cf_var, key, value)
19401948
self._lazy_stream_data(data=data, cf_var=cf_var)
19411949

19421950
# Add names + units
@@ -2371,11 +2379,10 @@ def _create_cf_data_variable(
23712379
# Get the values in a form which is valid for the file format.
23722380
is_dataless = cube.is_dataless()
23732381

2374-
if not is_dataless:
2382+
packing_controls = None
2383+
if packing and not is_dataless:
23752384
data = self._ensure_valid_dtype(cube.core_data(), "cube", cube)
2376-
if not packing:
2377-
dtype = data.dtype.newbyteorder("=")
2378-
elif isinstance(packing, dict):
2385+
if isinstance(packing, dict):
23792386
if "dtype" not in packing:
23802387
msg = "The dtype attribute is required for packing."
23812388
raise ValueError(msg)
@@ -2413,26 +2420,14 @@ def _create_cf_data_variable(
24132420
else:
24142421
add_offset = cmin + 2 ** (n - 1) * scale_factor
24152422

2416-
def set_packing_ncattrs(cfvar):
2417-
"""Set netCDF packing attributes.
2418-
2419-
NOTE: cfvar needs to be a _thread_safe_nc._ThreadSafeWrapper subclass.
2423+
packing_controls = {
2424+
"dtype": dtype,
2425+
"attributes": [
2426+
("scale_factor", scale_factor),
2427+
("add_offset", add_offset),
2428+
],
2429+
}
24202430

2421-
"""
2422-
assert hasattr(cfvar, "THREAD_SAFE_FLAG")
2423-
if packing:
2424-
if scale_factor:
2425-
_setncattr(cfvar, "scale_factor", scale_factor)
2426-
if add_offset:
2427-
_setncattr(cfvar, "add_offset", add_offset)
2428-
2429-
# cf_name = self._get_element_variable_name(cube_or_mesh=None, element=cube)
2430-
# while cf_name in self._dataset.variables:
2431-
# cf_name = self._increment_name(cf_name)
2432-
#
2433-
# cf_var = self._dataset.createVariable(
2434-
# cf_name, dtype, dimension_names, fill_value=fill_value, **kwargs
2435-
# )
24362431
# Create the cube CF-netCDF data variable with data payload.
24372432
cf_name = self._create_generic_cf_array_var(
24382433
cube,
@@ -2441,28 +2436,13 @@ def set_packing_ncattrs(cfvar):
24412436
element_dims=dimension_names,
24422437
fill_value=fill_value,
24432438
compression_kwargs=kwargs,
2439+
packing_controls=packing_controls,
24442440
is_dataless=is_dataless,
24452441
)
24462442
cf_var = self._dataset.variables[cf_name]
24472443

2448-
if not is_dataless:
2449-
set_packing_ncattrs(cf_var)
2450-
2451-
# if cube.standard_name:
2452-
# _setncattr(cf_var, "standard_name", cube.standard_name)
2453-
#
2454-
# if cube.long_name:
2455-
# _setncattr(cf_var, "long_name", cube.long_name)
2456-
#
2457-
# if cube.units.is_udunits():
2458-
# _setncattr(cf_var, "units", str(cube.units))
2459-
#
2460-
# # Add the CF-netCDF calendar attribute.
2461-
# if cube.units.calendar:
2462-
# _setncattr(cf_var, "calendar", cube.units.calendar)
2463-
2464-
# Set attributes: NB this part is cube-specific (not the same for components)
2465-
# - therefore 'set_cf_var_attributes' doesn't set attributes if element is a Cube
2444+
# Set general attrs: NB this part is cube-specific (not the same for components)
2445+
# - so 'set_cf_var_attributes' *doesn't* set these, if element is a Cube
24662446
if iris.FUTURE.save_split_attrs:
24672447
attr_names = cube.attributes.locals.keys()
24682448
else:

0 commit comments

Comments
 (0)