Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chunk control modes #5575

Merged
36 changes: 33 additions & 3 deletions lib/iris/fileformats/netcdf/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,12 @@ def _get_cf_var_data(cf_var, filename):
# Get the chunking specified for the variable : this is either a shape, or
# maybe the string "contiguous".
chunks = cf_var.cf_data.chunking()
if chunks is None and CHUNK_CONTROL.file_mode:
raise KeyError(
f"{cf_var.cf_name} does not contain pre-existing chunk specifications."
f"Instead, you might wish to use CHUNK_CONTROL.set(), or just use default"
f" behaviour outside of a context manager. "
)
# In the "contiguous" case, pass chunks=None to 'as_lazy_data'.
if chunks == "contiguous":
# Equivalent to chunks=None, but value required by chunking control
Expand All @@ -247,17 +253,22 @@ def _get_cf_var_data(cf_var, filename):
dim_chunks = CHUNK_CONTROL.var_dim_chunksizes.get(
cf_var.cf_name
) or CHUNK_CONTROL.var_dim_chunksizes.get("*")
if not dim_chunks:
dims = cf_var.cf_data.dimensions
if CHUNK_CONTROL.file_mode:
dims_fixed = np.ones(len(dims), dtype=bool)
elif not dim_chunks:
dims_fixed = None
else:
# Modify the chunks argument, and pass in a list of 'fixed' dims, for
# any of our dims which are controlled.
dims = cf_var.cf_data.dimensions
dims_fixed = np.zeros(len(dims), dtype=bool)
for i_dim, dim_name in enumerate(dims):
dim_chunksize = dim_chunks.get(dim_name)
if dim_chunksize:
chunks[i_dim] = dim_chunksize
if dim_chunksize == -1:
chunks[i_dim] = cf_var.shape[i_dim]
else:
chunks[i_dim] = dim_chunksize
dims_fixed[i_dim] = True
if dims_fixed is None:
dims_fixed = [dims_fixed]
Expand Down Expand Up @@ -673,6 +684,7 @@ def __init__(self, var_dim_chunksizes=None):

"""
self.var_dim_chunksizes = var_dim_chunksizes or {}
self.file_mode = False
trexfeathers marked this conversation as resolved.
Show resolved Hide resolved

@contextmanager
def set(
Expand Down Expand Up @@ -751,6 +763,24 @@ def set(
finally:
self.var_dim_chunksizes = old_settings

@contextmanager
def from_file(self) -> None:
"""
Ensures the chunks are loaded in from file variables, else will throw an error.

Notes
-----
This function acts as a contextmanager, for use in a 'with' block.
"""
try:
old_file_mode = self.file_mode
old_var_dim_chunksizes = self.var_dim_chunksizes
trexfeathers marked this conversation as resolved.
Show resolved Hide resolved
self.file_mode = True
yield
finally:
self.file_mode = old_file_mode
trexfeathers marked this conversation as resolved.
Show resolved Hide resolved
self.var_dim_chunksizes = old_var_dim_chunksizes


# Note: the CHUNK_CONTROL object controls chunk sizing in the
# :meth:`_get_cf_var_data` method.
Expand Down
Loading