Skip to content

Commit bb7ac5b

Browse files
committed
dev
1 parent 63ca9ce commit bb7ac5b

5 files changed

Lines changed: 113 additions & 48 deletions

File tree

cf/domain.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,10 @@ def indices(self, *config, **kwargs):
737737
738738
Metadata constructs are selected conditions are specified on
739739
their data. Indices for subspacing are then automatically
740-
inferred from where the conditions are met.
740+
inferred from where the conditions are met. If a condition is
741+
a callable function then if is automateically replaced with
742+
the result of calling that function with the Domain as its
743+
only argument.
741744
742745
Metadata constructs and the conditions on their data are
743746
defined by keyword parameters.
@@ -1092,7 +1095,10 @@ def subspace(self, *config, **kwargs):
10921095
10931096
Subspacing by metadata selects metadata constructs and
10941097
specifies conditions on their data. Indices for subspacing are
1095-
then automatically inferred from where the conditions are met.
1098+
then automatically inferred from where the conditions are
1099+
met. If a condition is a callable function then if is
1100+
automateically replaced with the result of calling that
1101+
function with the Domain as its only argument.
10961102
10971103
Metadata constructs and the conditions on their data are defined
10981104
by keyword parameters.

cf/field.py

Lines changed: 15 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5349,9 +5349,9 @@ def healpix_increase_refinement_level(self, refinement_level, quantity):
53495349
[[72.875 72.875 72.875 72.875 73.375 73.375 73.375 73.375]]
53505350

53515351
"""
5352-
from .data.dask_utils import cf_healpix_increase_refinement_indices
53535352
from .healpix import (
53545353
_healpix_increase_refinement_level,
5354+
_healpix_increase_refinement_level_indices,
53555355
healpix_max_refinement_level,
53565356
)
53575357

@@ -5470,46 +5470,11 @@ def healpix_increase_refinement_level(self, refinement_level, quantity):
54705470
f.del_construct(key)
54715471

54725472
# Create the healpix_index coordinates for the new refinement
5473-
# level, and put them into the Field.
5473+
# level
54745474
healpix_index = hp["healpix_index"]
5475-
5476-
# Save any cached data elements
5477-
data = healpix_index.data
5478-
cached = data._get_cached_elements().copy()
5479-
5480-
dx = data.to_dask_array(
5481-
_force_mask_hardness=False, _force_to_memory=False
5482-
)
5483-
5484-
# Set the data type to allow for the largest possible HEALPix
5485-
# index at the new refinement level
5486-
dtype = cfdm.integer_dtype(12 * (4**refinement_level) - 1)
5487-
if dx.dtype != dtype:
5488-
dx = dx.astype(dtype, copy=False)
5489-
5490-
# Each chunk is going to get larger by a factor of 'ncells'
5491-
chunks = [(np.array(dx.chunks[0]) * ncells).tolist()]
5492-
5493-
dx = dx.map_blocks(
5494-
cf_healpix_increase_refinement_indices,
5495-
chunks=tuple(chunks),
5496-
dtype=dtype,
5497-
meta=np.array((), dtype=dtype),
5498-
ncells=ncells,
5475+
_healpix_increase_refinement_level_indices(
5476+
healpix_index, ncells, refinement_level
54995477
)
5500-
5501-
healpix_index.set_data(dx, copy=False)
5502-
5503-
# Set new cached data elements
5504-
data = healpix_index.data
5505-
if 0 in cached:
5506-
x = np.array(cached[0], dtype=dtype) * ncells
5507-
data._set_cached_elements({0: x, 1: x + 1})
5508-
5509-
if -1 in cached:
5510-
x = np.array(cached[-1], dtype=dtype) * ncells + (ncells - 1)
5511-
data._set_cached_elements({-1: x})
5512-
55135478
hp_key = f.set_construct(healpix_index, axes=axis, copy=False)
55145479

55155480
# Update the healpix Coordinate Reference
@@ -9221,7 +9186,10 @@ def indices(self, *config, **kwargs):
92219186

92229187
Metadata constructs are selected by conditions specified on
92239188
their data. Indices for subspacing are then automatically
9224-
inferred from where the conditions are met.
9189+
inferred from where the conditions are met. If a condition is
9190+
a callable function then if is automateically replaced with
9191+
the result of calling that function with the Field as its only
9192+
argument.
92259193

92269194
The returned tuple of indices may be used to created a
92279195
subspace by indexing the original field construct with them.
@@ -13406,10 +13374,13 @@ def subspace(self):
1340613374

1340713375
**Subspacing by metadata**
1340813376

13409-
Subspacing by metadata, signified by the use of round brackets,
13410-
selects metadata constructs and specifies conditions on their
13411-
data. Indices for subspacing are then automatically inferred from
13412-
where the conditions are met.
13377+
Subspacing by metadata, signified by the use of round
13378+
brackets, selects metadata constructs and specifies conditions
13379+
on their data. Indices for subspacing are then automatically
13380+
inferred from where the conditions are met. If a condition is
13381+
a callable function then if is automateically replaced with
13382+
the result of calling that function with the Field as its only
13383+
argument.
1341313384

1341413385
Metadata constructs and the conditions on their data are defined
1341513386
by keyword parameters.

cf/healpix.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,85 @@ def _healpix_increase_refinement_level(x, ncells, iaxis, quantity):
227227
x.set_data(dx, copy=False)
228228

229229

230+
def _healpix_increase_refinement_level_indices(
231+
healpix_index, ncells, refinement_level
232+
):
233+
"""Increase the refinement level of HEALPix indices in-place.
234+
235+
K. Gorski, Eric Hivon, A. Banday, B. Wandelt, M. Bartelmann, et
236+
al.. HEALPix: A Framework for High-Resolution Discretization and
237+
Fast Analysis of Data Distributed on the Sphere. The Astrophysical
238+
Journal, 2005, 622 (2), pp.759-771.
239+
https://dx.doi.org/10.1086/427976
240+
241+
.. versionadded:: NEXTVERSION
242+
243+
.. seealso:: `cf.Field.healpix_increase_refinement_level`
244+
245+
:Parameters:
246+
247+
healpix_index: `Coordinate`
248+
The HEALPix indices to be changed. It is assumed they use
249+
the "nested" indexing scheme.
250+
251+
ncells: `int`
252+
The number of cells at the new higher refinement level
253+
which are contained in one cell at the original refinement
254+
level.
255+
256+
refinement_level: `int`
257+
The new higher refinement level.
258+
259+
:Returns:
260+
261+
`None`
262+
263+
"""
264+
from cfdm import integer_dtype
265+
266+
from .data.dask_utils import cf_healpix_increase_refinement_indices
267+
268+
# Save any cached data elements
269+
cached = healpix_index.data._get_cached_elements().copy()
270+
271+
# Get the Dask array.
272+
#
273+
# `cf_healpix_increase_refinement_indices` has its own call to
274+
# `cfdm_to_memory`, so we can set _force_to_memory=False.
275+
dx = healpix_index.data.to_dask_array(
276+
_force_mask_hardness=False, _force_to_memory=False
277+
)
278+
279+
# Set the data type to allow for the largest possible HEALPix
280+
# index at the new refinement level
281+
dtype = integer_dtype(12 * (4**refinement_level) - 1)
282+
if dx.dtype != dtype:
283+
dx = dx.astype(dtype, copy=False)
284+
285+
# Each chunk is going to get larger by a factor of 'ncells'
286+
chunks = [(np.array(dx.chunks[0]) * ncells).tolist()]
287+
288+
dx = dx.map_blocks(
289+
cf_healpix_increase_refinement_indices,
290+
chunks=tuple(chunks),
291+
dtype=dtype,
292+
meta=np.array((), dtype=dtype),
293+
ncells=ncells,
294+
)
295+
296+
healpix_index.set_data(dx, copy=False)
297+
298+
# Set new cached data elements
299+
data = healpix_index.data
300+
if 0 in cached:
301+
x = np.array(cached[0], dtype=dtype) * ncells
302+
data._set_cached_elements({0: x, 1: x + 1})
303+
304+
if -1 in cached:
305+
x = np.array(cached[-1], dtype=dtype) * ncells + (ncells - 1)
306+
data._set_cached_elements({-1: x})
307+
308+
230309
def _healpix_indexing_scheme(healpix_index, hp, new_indexing_scheme):
231310
"""Change the indexing scheme of HEALPix indices in-place.
232311

cf/mixin/fielddomain.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,17 @@ def _indices(self, config, data_axes, ancillary_mask, kwargs):
332332
f"defined by {identity!r}"
333333
)
334334

335+
# If the condition is a callable function, then call it
336+
# with 'self' as the only argument and replace the
337+
# condition with the result.
335338
if callable(value):
336-
value = value(self)
339+
try:
340+
value = value(self)
341+
except Exception as e:
342+
raise RuntimeError(
343+
f"Error encountered when calling condition "
344+
f"{identity}={value}: {e}"
345+
)
337346

338347
if axes in parsed:
339348
# The axes are the same as an existing key

cf/test/test_Domain.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ def test_Domain_create_healpix(self):
504504
self.assertEqual(len(d.coordinate_references()), 1)
505505

506506
hp = d.dimension_coordinate()
507-
self.assertEqual(hp.data._get_cached_elements(), {0: 0, -1: 11})
507+
self.assertEqual(hp.data._get_cached_elements(), {0: 0, 1: 1, -1: 11})
508508
self.assertTrue(np.array_equal(hp, np.arange(12)))
509509

510510
self.assertEqual(

0 commit comments

Comments
 (0)