-
Notifications
You must be signed in to change notification settings - Fork 23
Description
cf.Field.subspace has, to date, always disallowed setting two or more conditions for a single axis, e.g.
>>> import cf
>>> f = cf.example_field(0)
>>> f.subspace(Y=cf.lt(-10), latitude=cf.gt(20))
ValueError: Error: Can't specify 2 conditions for 1 axis: (<CF Query: (lt -10)>, <CF Query: (gt 20)>). Consider applying the conditions separately.To get around this you could either apply the conditions separately:
>>> f.subspace(Y=cf.lt(-10)).subspace(Y=cf.gt(20))or roll the conditions into one:
>>> f.subspace(Y=cf.lt(-10) & cf.gt(20))There is, I think, is no need for this restriction though, and removing it will make subspacing Fields with a discrete axis (such as DSGs, UGRID, etc) a more intuitive process. For such fields, we typically have have multiple 1-d coordinates (with different identities) for the same axis, and we'd like to be able to do this:
>>> u = cf.example_field(8)
>>> print(u)
Field: air_temperature (ncvar%ta)
---------------------------------
Data : air_temperature(time(2), ncdim%nMesh2_face(3)) K
Cell methods : time(2): point (interval: 3600 s)
Dimension coords: time(2) = [2016-01-02 01:00:00, 2016-01-02 11:00:00] gregorian
Auxiliary coords: longitude(ncdim%nMesh2_face(3)) = [-44.0, -44.0, -42.0] degrees_east
: latitude(ncdim%nMesh2_face(3)) = [34.0, 32.0, 34.0] degrees_north
Topologies : cell:face(ncdim%nMesh2_face(3), 4) = [[2, ..., --]]
Connectivities : connectivity:edge(ncdim%nMesh2_face(3), 5) = [[0, ..., --]]
>>> print(u.subspace(X=cf.gt(-43), Y=cf.wi(30, 40))) # X and Y refer to the same discrete axis
Field: air_temperature (ncvar%ta)
---------------------------------
Data : air_temperature(time(2), ncdim%nMesh2_face(1)) K
Cell methods : time(2): point (interval: 3600 s)
Dimension coords: time(2) = [2016-01-02 01:00:00, 2016-01-02 11:00:00] gregorian
Auxiliary coords: longitude(ncdim%nMesh2_face(1)) = [-42.0] degrees_east
: latitude(ncdim%nMesh2_face(1)) = [34.0] degrees_north
Topologies : cell:face(ncdim%nMesh2_face(1), 4) = [[1, ..., --]]
Connectivities : connectivity:edge(ncdim%nMesh2_face(1), 5) = [[2, ..., --]]Implementing this will be "straight forward", as we essentially just have to introduce a loop over multiple conditions, AND-ing the selected indices from the application of each condition to its corresponding coordinates.
This change will be wholly backwards compatible - no existing code will change its behaviour, but new API patterns will become possible.