Skip to content

Commit 771a049

Browse files
committed
dev
2 parents 715ee82 + 4692dbb commit 771a049

17 files changed

Lines changed: 403 additions & 43 deletions

Changelog.rst

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Version NEXTVERSION
22
--------------
33

4-
**2025-??-??**
4+
**2026-??-??**
55

66
* Support for HEALPix grids
77
(https://github.com/NCAS-CMS/cf-python/issues/909)
@@ -17,11 +17,23 @@ Version NEXTVERSION
1717
(https://github.com/NCAS-CMS/cf-python/issues/909)
1818
* New function: `cf.locate`
1919
(https://github.com/NCAS-CMS/cf-python/issues/909)
20-
* Reduce the time taken to import `cf`
21-
(https://github.com/NCAS-CMS/cf-python/issues/902)
2220
* New optional dependency: ``healpix>=2025.1``
2321
* Changed dependency: ``cfdm>=1.13.0.0, <1.13.1.0``
2422

23+
Version 3.18.3
24+
--------------
25+
26+
**2026-01-??**
27+
28+
* Write Zarr v3 datasets with `cf.write`, and allow the reading of
29+
grouped Zarr v2 and v3 datasets with `cf.read`
30+
(https://github.com/NCAS-CMS/cf-python/issues/895)
31+
* Read Zarr v2 and v3 datasets that contain a group hierarchy with
32+
`cf.read` (https://github.com/NCAS-CMS/cf-python/issues/894)
33+
* Reduce the time taken to import `cf`
34+
(https://github.com/NCAS-CMS/cf-python/issues/902)
35+
* New optional dependency: ``zarr>=3.1.3``
36+
2537
----
2638

2739
Version 3.18.2

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ of its array manipulation and can:
8787
* read field constructs from netCDF, CDL, Zarr, PP and UM datasets with a
8888
choice of netCDF backends,and in local, http, and s3 locations,
8989
* create new field constructs in memory,
90-
* write and append field and domain constructs to netCDF datasets on disk,
90+
* write and append field and domain constructs to netCDF and Zarr v3
91+
datasets on disk,
9192
* read, create, and manipulate UGRID mesh topologies,
9293
* read, write, and manipulate HEALPix grids,
9394
* read, write, and create coordinates defined by geometry cells,

cf/field.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5166,7 +5166,7 @@ def healpix_decrease_refinement_level(
51665166
)
51675167

51685168
# ------------------------------------------------------------
5169-
# Chenge the refinement level of the Field's data
5169+
# Change the refinement level of the Field's data
51705170
# ------------------------------------------------------------
51715171

51725172
# Note: Using 'Data.coarsen' works because a) the HEALPix

cf/functions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3184,7 +3184,7 @@ def environment(display=True, paths=True):
31843184
netCDF4: 1.7.2 /home/miniconda3/lib/python3.12/site-packages/netCDF4/__init__.py
31853185
h5netcdf: 1.3.0 /home/miniconda3/lib/python3.12/site-packages/h5netcdf/__init__.py
31863186
h5py: 3.12.1 /home/miniconda3/lib/python3.12/site-packages/h5py/__init__.py
3187-
zarr: 3.0.8 /home/miniconda3/lib/python3.12/site-packages/zarr/__init__.py
3187+
zarr: 3.1.3 /home/miniconda3/lib/python3.12/site-packages/zarr/__init__.py
31883188
s3fs: 2024.12.0 /home/miniconda3/lib/python3.12/site-packages/s3fs/__init__.py
31893189
scipy: 1.15.1 /home/miniconda3/lib/python3.12/site-packages/scipy/__init__.py
31903190
dask: 2025.5.1 /home/miniconda3/lib/python3.12/site-packages/dask/__init__.py
@@ -3210,7 +3210,7 @@ def environment(display=True, paths=True):
32103210
netCDF4: 1.7.2
32113211
h5netcdf: 1.3.0
32123212
h5py: 3.12.1
3213-
zarr: 3.0.8
3213+
zarr: 3.1.3
32143214
s3fs: 2024.12.0
32153215
scipy: 1.15.1
32163216
dask: 2025.5.1

cf/mixin/fielddomain.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2328,7 +2328,7 @@ def healpix_to_ugrid(self, cache=True, inplace=False):
23282328
)
23292329

23302330
# Create the UGRID Domain Topology construct, by creating a
2331-
# unique integer identifer for each unique node location.
2331+
# unique integer identifier for each unique node location.
23322332
bounds_y = bounds_y.data.to_dask_array(_force_mask_hardness=False)
23332333
bounds_x = bounds_x.data.to_dask_array(_force_mask_hardness=False)
23342334

@@ -2466,15 +2466,15 @@ def create_latlon_coordinates(
24662466
# See if any lat/lon coordinates could be created
24672467
# ------------------------------------------------------------
24682468

2469-
# See if there are any existing latitude/longutude coordinates
2469+
# See if there are any existing latitude/longitude coordinates
24702470
latlon_coordinates = {
24712471
key: c
24722472
for key, c in f.coordinates(todict=True).items()
24732473
if c.Units.islatitude or c.Units.islongitude
24742474
}
24752475
if latlon_coordinates:
24762476
if overwrite:
2477-
# Remove existing latitude/longutude coordinates
2477+
# Remove existing latitude/longitude coordinates
24782478
# before carrying on
24792479
for key in latlon_coordinates:
24802480
f.del_construct(key)
@@ -2542,7 +2542,7 @@ def create_latlon_coordinates(
25422542
# coordinates.
25432543
# ------------------------------------------------------------
25442544

2545-
# Initialize the flag that tells us if any new coordinates
2545+
# Initialise the flag that tells us if any new coordinates
25462546
# have been created
25472547
coords_created = False
25482548

cf/read_write/read.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,10 @@ class read(cfdm.read):
316316
317317
.. versionadded:: 3.17.0
318318
319+
{{read store_dataset_shards: `bool`, optional}}
320+
321+
.. versionadded:: NEXTVERSION
322+
319323
{{read cfa: `dict`, optional}}
320324
321325
.. versionadded:: 3.15.0
@@ -328,6 +332,10 @@ class read(cfdm.read):
328332
329333
.. versionadded:: 3.17.0
330334
335+
{{read group_dimension_search: `str`, optional}}
336+
337+
.. versionadded:: (cfdm) NEXTVERSION
338+
331339
umversion: deprecated at version 3.0.0
332340
Use the *um* parameter instead.
333341
@@ -434,6 +442,7 @@ def __new__(
434442
warn_valid=False,
435443
dask_chunks="storage-aligned",
436444
store_dataset_chunks=True,
445+
store_dataset_shards=True,
437446
domain=False,
438447
cfa=None,
439448
cfa_write=None,
@@ -445,6 +454,7 @@ def __new__(
445454
ignore_read_error=False,
446455
fmt=None,
447456
file_type=None,
457+
group_dimension_search="closest_ancestor",
448458
):
449459
"""Read field or domain constructs from a dataset."""
450460
kwargs = locals()

cf/read_write/um/umread.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3575,7 +3575,7 @@ def read(
35753575
# Return now if there are valid file types
35763576
return []
35773577

3578-
f = self.file_open(filename, parse=True)
3578+
f = self.dataset_open(filename, parse=True)
35793579

35803580
info = is_log_level_info(logger)
35813581

@@ -3598,7 +3598,7 @@ def read(
35983598
for var in f.vars
35993599
]
36003600

3601-
self.file_close()
3601+
self.dataset_close()
36023602

36033603
return [field for x in um for field in x.fields if field]
36043604

@@ -3632,7 +3632,7 @@ def _open_um_file(
36323632
The open PP or FF file object.
36333633
36343634
"""
3635-
self.file_close()
3635+
self.dataset_close()
36363636
try:
36373637
f = File(
36383638
filename,
@@ -3678,15 +3678,15 @@ def is_um_file(self, filename):
36783678
try:
36793679
# Note: No need to completely parse the file to ascertain
36803680
# if it's PP or FF.
3681-
self.file_open(filename, parse=False)
3681+
self.dataset_open(filename, parse=False)
36823682
except Exception:
3683-
self.file_close()
3683+
self.dataset_close()
36843684
return False
36853685
else:
3686-
self.file_close()
3686+
self.dataset_close()
36873687
return True
36883688

3689-
def file_close(self):
3689+
def dataset_close(self):
36903690
"""Close the file that has been read.
36913691
36923692
:Returns:
@@ -3700,7 +3700,7 @@ def file_close(self):
37003700

37013701
self._um_file = None
37023702

3703-
def file_open(self, filename, parse=True):
3703+
def dataset_open(self, filename, parse=True):
37043704
"""Open the file for reading.
37053705
37063706
:Paramters:

cf/test/test_Data.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4717,12 +4717,12 @@ def test_Data_coarsen(self):
47174717
self.assertEqual(e.shape, (2, 2))
47184718
self.assertTrue((e.array == [[0, 3], [12, 15]]).all())
47194719

4720-
# Non-full caorsening neighbourhood with trim_excess=True
4720+
# Non-full coarsening neighbourhood with trim_excess=True
47214721
e = d.coarsen(np.max, {-1: 5}, trim_excess=True)
47224722
self.assertEqual(e.shape, (4, 1))
47234723
self.assertTrue((e.array == [[4], [10], [16], [22]]).all())
47244724

4725-
# Non-full caorsening neighbourhood with trim_excess=False
4725+
# Non-full coarsening neighbourhood with trim_excess=False
47264726
with self.assertRaises(ValueError):
47274727
d.coarsen(np.max, {-1: 5})
47284728

cf/test/test_functions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ def test_locate(self):
451451
with self.assertRaises(ValueError):
452452
cf.locate(lat, 30, f)
453453

454-
# Invalid grid types (regulat lat/lon, geometry, UGRID)
454+
# Invalid grid types (regular lat/lon, geometry, UGRID)
455455
for f in cf.example_fields(0, 6, 8):
456456
with self.assertRaises(ValueError):
457457
cf.locate(60, 30, f)

cf/test/test_regrid_healpix.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def setUp(self):
5656

5757
@unittest.skipUnless(esmpy_imported, "Requires esmpy package.")
5858
def test_Field_regrid_mesh_to_healpix(self):
59-
# Check that UGRID -> healpix is the same as UGRID -> UGRUD
59+
# Check that UGRID -> healpix is the same as UGRID -> UGRID
6060
self.assertFalse(cf.regrid_logging())
6161

6262
dst = cf.Domain.create_healpix(3) # 768 cells
@@ -85,7 +85,7 @@ def test_Field_regrid_mesh_to_healpix(self):
8585

8686
@unittest.skipUnless(esmpy_imported, "Requires esmpy package.")
8787
def test_Field_regrid_healpix_to_mesh(self):
88-
# Check that healpix -> UGRID is the same as UGRID -> UGRUD
88+
# Check that healpix -> UGRID is the same as UGRID -> UGRID
8989
self.assertFalse(cf.regrid_logging())
9090

9191
src = cf.Field(source=cf.Domain.create_healpix(3)) # 768 cells

0 commit comments

Comments
 (0)