-
Notifications
You must be signed in to change notification settings - Fork 300
enforce non-masked dimension coordinate points/bounds #3427
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
Conversation
|
Happy to add more tests as a review action... |
| # NB. Returns the *same object* if result.ndim >= ndmin | ||
| result = np.array(result, ndmin=ndmin, copy=False) | ||
| func = ma.array if ma.isMaskedArray(result) else np.array | ||
| result = func(result, ndmin=ndmin, copy=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As @rcomer points out, this is indeed the nub of the issue 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This bit will applies to AuxCoords rather than DimCoords, which was the point of the original issue.
I'll try and remember to edit the squashed commit for that.
| raise ValueError(emsg.format(self.name(), self.__class__.__name__)) | ||
| if ma.isMaskedArray(points) and ma.count_masked(points): | ||
| emsg = 'A {!r} {} points array must not be masked.' | ||
| raise TypeError(emsg.format(self.name(), self.__class__.__name__)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Raise a TypeError exceptions here to explicitly catch those masked points. Hence the need for the change here.
| [ nan 494.44452 588.8889 683.33325 777.77783 872.2222 | ||
| 966.66675 1061.1111 1155.5554 nan] | ||
| [-- 494.44451904296875 588.888916015625 683.333251953125 777.77783203125 | ||
| 872.2222290039062 966.666748046875 1061.111083984375 1155.555419921875 --] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This really makes sense to me now for coordinate behaviour...
We've asked for an extrapolation_mode=mask, so now we get a masked array for the altitude derived coordinate for the extrapolated points, and not just an array with nans injected.
If the extrapolation_mode=nan, then we (quite rightly) instead get:
[ nan 494.44452 588.8889 683.33325 777.77783 872.2222
966.66675 1061.1111 1155.5554 nan]
|
@pp-mo Yup, I definitely want to add some extra test coverage here. I think that our masked array test coverage (in gerneral) is pretty poor (at least an after thought). I just want to convince myself that I've not broken anything here for |
lib/iris/coords.py
Outdated
| raise ValueError('The points array must be numeric.') | ||
| emsg = 'The {!r} {} points array must be numeric.' | ||
| raise ValueError(emsg.format(self.name(), self.__class__.__name__)) | ||
| if ma.isMaskedArray(points) and ma.count_masked(points): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably be using 'is_masked' for this : https://docs.scipy.org/doc/numpy/reference/generated/numpy.ma.is_masked.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, thanks @pp-mo ... I always forget that pattern, and it gives us the same behaviour that we want, namely:
>>> import numpy as np
>>> import numpy.ma as ma
>>> a = np.arange(5)
>>> b = ma.arange(5)
>>> c = ma.arange(5)
>>> c[0] = ma.masked
>>> ma.is_masked(a)
False
>>> ma.is_masked(b)
False
>>> ma.is_masked(c)
TrueThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pp-mo Done 👍
lib/iris/coords.py
Outdated
| emsg = 'The {!r} {} bounds array must be numeric.' | ||
| raise ValueError(emsg.format(self.name(), self.__class__.__name__)) | ||
| # Check not masked. | ||
| if ma.isMaskedArray(bounds) and ma.count_masked(bounds): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above, use 'is_masked'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pp-mo Done 👍
|
One thought that springs to mind: do methods such as |
pp-mo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All makes good sense, but clearly we have no testing for these behaviours : e.g.
- errors for bad creation / assignment
- successful AuxCoord creation with masked data
- error making DimCoord with masked points
- success making DimCoord from masked array with no masked points.
Maybe we should address these, just as regression checks ?
| # NB. Returns the *same object* if result.ndim >= ndmin | ||
| result = np.array(result, ndmin=ndmin, copy=False) | ||
| func = ma.array if ma.isMaskedArray(result) else np.array | ||
| result = func(result, ndmin=ndmin, copy=False) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This bit will applies to AuxCoords rather than DimCoords, which was the point of the original issue.
I'll try and remember to edit the squashed commit for that.
I think we have considered masking in most operations now, but it is not all tested. |
|
|
||
| from __future__ import (absolute_import, division, print_function) | ||
| from six.moves import (filter, input, map, range, zip) # noqa | ||
| import six |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
F401 'six' imported but unused
3ea2f1f to
91ceae9
Compare
@pp-mo After pushing commits 9f9a553 and 91ceae9, I'm pretty satified that we've got reasonable test coverage for both Did we want to extend this further? Pragmatically, perhaps we create an issue with areas of the code base that require masking test coverage outside this PR? Kinda feels like slow, long burner... |
|
This need a |
pp-mo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some silly little points, but generally all GTG, OWOK, LGTM ...
.../iris/src/whatsnew/contributions_2.3.0/bugfix_2019-Oct-01_masked_dimcoords_and_auxcoords.txt
Outdated
Show resolved
Hide resolved
|
@pp-mo Over to you 👍 |
|
Nice @bjlittle |
This PR addresses #3419.