iris icon indicating copy to clipboard operation
iris copied to clipboard

Provide a slice tuple equivalent to a coordinate constraint

Open jrackham-mo opened this issue 4 months ago • 3 comments

✨ Feature Request

Functionality to generate a slice tuple that can be used to subset a cube with a given constraint. This could be a standalone function, or a method on iris.Constraint. Usage might look like this:

height_constraint = iris.Constraint(height=9000)
slices_tuple = height_constraint.as_slices_tuple(cube)
subset_cube = cube[slices_tuple]
# Equivalent to:
subset_cube = height_contstraint.extract(cube)

Motivation

This would allow for assigning data to a subset of a cube directly, rather than operating on a copy of the cube region. For example, setting all points at height=9000 to zero:

cube[slices_tuple] = 0

Additional context

Click to expand this section...

It looks like ‎_ColumnIndexManager.as_slice already provides this functionality, but it is not part of the public API.

jrackham-mo avatar Aug 07 '25 12:08 jrackham-mo

This is an interesting idea. In principle, shouldn't be too hard as the implementation of constraints does effectively convert everything into a binary yes/no array over the points of the relevant dimension. So, converting that to a slice object would seem entirely possible.

A couple of queries come to mind...

Firstly, there are also cases where the result is not equivalent to a simple slice. I'd suggest that the API should offer to either treat that as an unexpected error, or return an array of booleans or list of indices which would also work.
Maybe something like this ? ... #6621

Interestingly, the capability is already "almost" there, but not public I think.

pp-mo avatar Aug 08 '25 15:08 pp-mo

Interestingly, the capability is already "almost" there, but not public I think.

I think that's the point @jrackham-mo is making in the additional context part of the original comment? i.e. that there is existing private functionality in iris that may provide the functionality. As downstream users, we're reluctant to rely on private functionality though.

hdyson avatar Aug 11 '25 11:08 hdyson

Note that Iris slicing in general returns copies rather than views, so you can't assign to a slice

import iris.cube

cube = iris.cube.Cube(range(5))

print(cube.data)

cube[1].data = 42

print(cube.data)
[0 1 2 3 4]
[0 1 2 3 4]

Though I think this would be OK if you use your returned slice like

cube.data[slices_tuple] = 0

rcomer avatar Aug 11 '25 11:08 rcomer