Skip to content

Commit ad4960e

Browse files
committed
Fixes for data packing.
1 parent 1bcfb19 commit ad4960e

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
@@ -1737,6 +1737,7 @@ def _create_generic_cf_array_var(
17371737
element_dims=None,
17381738
fill_value=None,
17391739
compression_kwargs=None,
1740+
packing_controls: dict | None = None,
17401741
is_dataless=False,
17411742
):
17421743
"""Create theCF-netCDF variable given dimensional_metadata.
@@ -1864,7 +1865,10 @@ def _create_generic_cf_array_var(
18641865
else:
18651866
element_type = type(element).__name__
18661867
data = self._ensure_valid_dtype(data, element_type, element)
1867-
dtype = data.dtype.newbyteorder("=")
1868+
if not packing_controls:
1869+
dtype = data.dtype.newbyteorder("=")
1870+
else:
1871+
dtype = packing_controls["dtype"]
18681872

18691873
# Check if this is a dim-coord.
18701874
is_dimcoord = cube is not None and element in cube.dim_coords
@@ -1897,6 +1901,10 @@ def _create_generic_cf_array_var(
18971901

18981902
# Add the data to the CF-netCDF variable.
18991903
if not is_dataless:
1904+
if packing_controls:
1905+
# We must set packing attributes (if any), before assigning values.
1906+
for key, value in packing_controls["attributes"]:
1907+
_setncattr(cf_var, key, value)
19001908
self._lazy_stream_data(data=data, cf_var=cf_var)
19011909

19021910
# Add names + units
@@ -2331,11 +2339,10 @@ def _create_cf_data_variable(
23312339
# Get the values in a form which is valid for the file format.
23322340
is_dataless = cube.is_dataless()
23332341

2334-
if not is_dataless:
2342+
packing_controls = None
2343+
if packing and not is_dataless:
23352344
data = self._ensure_valid_dtype(cube.core_data(), "cube", cube)
2336-
if not packing:
2337-
dtype = data.dtype.newbyteorder("=")
2338-
elif isinstance(packing, dict):
2345+
if isinstance(packing, dict):
23392346
if "dtype" not in packing:
23402347
msg = "The dtype attribute is required for packing."
23412348
raise ValueError(msg)
@@ -2373,26 +2380,14 @@ def _create_cf_data_variable(
23732380
else:
23742381
add_offset = cmin + 2 ** (n - 1) * scale_factor
23752382

2376-
def set_packing_ncattrs(cfvar):
2377-
"""Set netCDF packing attributes.
2378-
2379-
NOTE: cfvar needs to be a _thread_safe_nc._ThreadSafeWrapper subclass.
2383+
packing_controls = {
2384+
"dtype": dtype,
2385+
"attributes": [
2386+
("scale_factor", scale_factor),
2387+
("add_offset", add_offset),
2388+
],
2389+
}
23802390

2381-
"""
2382-
assert hasattr(cfvar, "THREAD_SAFE_FLAG")
2383-
if packing:
2384-
if scale_factor:
2385-
_setncattr(cfvar, "scale_factor", scale_factor)
2386-
if add_offset:
2387-
_setncattr(cfvar, "add_offset", add_offset)
2388-
2389-
# cf_name = self._get_element_variable_name(cube_or_mesh=None, element=cube)
2390-
# while cf_name in self._dataset.variables:
2391-
# cf_name = self._increment_name(cf_name)
2392-
#
2393-
# cf_var = self._dataset.createVariable(
2394-
# cf_name, dtype, dimension_names, fill_value=fill_value, **kwargs
2395-
# )
23962391
# Create the cube CF-netCDF data variable with data payload.
23972392
cf_name = self._create_generic_cf_array_var(
23982393
cube,
@@ -2401,28 +2396,13 @@ def set_packing_ncattrs(cfvar):
24012396
element_dims=dimension_names,
24022397
fill_value=fill_value,
24032398
compression_kwargs=kwargs,
2399+
packing_controls=packing_controls,
24042400
is_dataless=is_dataless,
24052401
)
24062402
cf_var = self._dataset.variables[cf_name]
24072403

2408-
if not is_dataless:
2409-
set_packing_ncattrs(cf_var)
2410-
2411-
# if cube.standard_name:
2412-
# _setncattr(cf_var, "standard_name", cube.standard_name)
2413-
#
2414-
# if cube.long_name:
2415-
# _setncattr(cf_var, "long_name", cube.long_name)
2416-
#
2417-
# if cube.units.is_udunits():
2418-
# _setncattr(cf_var, "units", str(cube.units))
2419-
#
2420-
# # Add the CF-netCDF calendar attribute.
2421-
# if cube.units.calendar:
2422-
# _setncattr(cf_var, "calendar", cube.units.calendar)
2423-
2424-
# Set attributes: NB this part is cube-specific (not the same for components)
2425-
# - therefore 'set_cf_var_attributes' doesn't set attributes if element is a Cube
2404+
# Set general attrs: NB this part is cube-specific (not the same for components)
2405+
# - so 'set_cf_var_attributes' *doesn't* set these, if element is a Cube
24262406
if iris.FUTURE.save_split_attrs:
24272407
attr_names = cube.attributes.locals.keys()
24282408
else:

0 commit comments

Comments
 (0)