-
Notifications
You must be signed in to change notification settings - Fork 153
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
Fix export to Python script to correctly use Coordinates
or WCS
in reference_data
#2335
Conversation
OK, looks like the problem was using the wrong |
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.
Looks good but I think we could actually be more general as described below.
glue/viewers/image/viewer.py
Outdated
if hasattr(ref_coords, 'wcs'): | ||
script += "ax.reset_wcs(slices={0}, wcs=ref_data.coords.wcs)\n".format(self.state.wcsaxes_slice) | ||
if isinstance(ref_coords, WCS): | ||
script += f"ax.reset_wcs(slices={self.state.wcsaxes_slice}, wcs=ref_data.coords)\n" |
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.
In principle we should be able to pass any Coordinates
subclass to reset_wcs
- after all this is what we do in the actual image viewer:
ref_coords = getattr(self.state.reference_data, 'coords', None)
if ref_coords is None or isinstance(ref_coords, LegacyCoordinates):
self.axes.reset_wcs(slices=self.state.wcsaxes_slice,
wcs=get_identity_wcs(self.state.reference_data.ndim))
else:
self.axes.reset_wcs(slices=self.state.wcsaxes_slice, wcs=ref_coords)
If we don't care about legacy coordinates in the script export, we might be able to get away with just doing:
self.axes.reset_wcs(slices=self.state.wcsaxes_slice, wcs=ref_coords)
if ref_coords
is defined? (and not have the case below either)
We could test that this works using e.g. AffineCoordinates
.
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.
If we don't care about legacy coordinates in the script export, we might be able to get away with just doing:
Basically those are what the else
case already covered, but if all the rest can be treated the same way, it becomes much easier of course (I haven't seen an example using coords.wcs
or coords.wcs_dict
).
No idea if those AffineCoordinates
make any sense at all, but they work – apart from the _slice
and simple_att
tests, that suffer from some fuzziness in the (lower axis) labels. Looks like the exported version does not get the 3D look quite right – can probably live with that?
12cc837
to
aa0d5b1
Compare
aa0d5b1
to
a7dae6e
Compare
data.coords
if a WCSCoordinates
or WCS
in reference_data
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 looks good to me - see comment below about using a fixture to avoid all the boilerplate code added at the start of each test. If you think this can be done, feel free to do it, otherwise you can just merge.
else: | ||
data = getattr(self, f'data_{coords}') | ||
self.viewer.add_data(data) | ||
self.viewer.remove_data(self.data) |
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.
I wonder if this could perhaps be implemented as a pytest fixture to avoid the repetition in each test?
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.
@astrofrog I implemented this as a helper function now, but could not figure out yet how to use it as a fixture in light of https://docs.pytest.org/en/stable/deprecations.html#calling-fixtures-directly (or if that would actually be helpful).
self.viewer.state.slices = (2, 3, 4) | ||
if coords == 'affine': | ||
pytest.xfail('Known issue with axis label rendering') |
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.
Can you open an issue in the repo to keep track of this?
Thanks for adding the helper method! That'll be fine for now, no need to make it a fixture. |
Description
This fixes an issue I found when trying to use the
Save Python script
function on a viewer using a dataset with a standard (Astropy) WCS, such as the examplew5.fits
data. The script thus created failed with anon
ax.reset_wcs(slices=['x', 'y', 0], wcs=ref_data.coords.wcs)
asref_data.coords
itself is already the WCS.The fix, to test for that case first in the exporter, seems quite straightforward.
I've parametrised some test to run on a dataset with WCS; could think about running this with all tests, or always adding a WCS in
self.data.coords
; howevertest_subset_legend
still fails with this patch, as the version with WCS somehow is not including the subset label:Basically in the latter case the script is missing these lines:
so this looks like another actual bug in the exporter (those lines were already missing before this change), as if in
glue/glue/viewers/common/viewer.py
Line 447 in aabb5eb
the subset layer is not
visible and enabled
when a WCS ist present (indeedlayer.enabled = False
), but I could not yet figure out why.Actually comparing to the non-WCS plot it does not seem like the subset is really displayed in the WCS version: