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
Ensure FrameAttribute not on present frame are set on SkyCoord, not on its frame #5750
Conversation
p.s. I found this while working on #5751 -- if we do allow setting the attributes, I would suggest it to be once-only, i.e., once one sets, e.g., |
@mhvk - I'm worried that the ability to update non-frame attributes has been around since
Yes, you can do this with |
@taldcroft - yes, I worried about that too, hence my postscript about maybe relaxing this to allow an attribute to be set if it hasn't been set already. Shall I change it to work like that? |
@mhvk - OK, the immutable-once-set idea sounds fine. |
I am heavily 👎 on this, either if it has been set or not, as changing the attributes of the solar frames is critical in allowing us to convert between systems with different observers. A full example of this is here: http://docs.sunpy.org/en/stable/generated/gallery/tutorials/SDO_to_STEREO_Coordinate_Conversion.html . Basically what happens is an image might have an observer for a satellite and another might have an observer for the Earth, if we change out of an observer centric frame then change the observer location frame attributes on the frame where they are not being used, and then transform back we end up in a frame from a different place, which is critical for comparing locations from different view points. |
I notice that this has been milestoned as 1.3.1, this change should not be in a bug fix release!! |
We could modify our internal transformation code (https://github.com/sunpy/sunpy/blob/master/sunpy/coordinates/transformations.py#L192) to use @taldcroft's |
@Cadair - To see why something like this is necessary, see #5751. But this really is two things: a frame should not have attributes that are not part of its regular definition (while a I think from the above, the consensus certainly is that one should be able to initialise other-frame attributes on an existing If we go that route, then this PR would only ensure that attributes get stored in the correct location, and #5751 would add that, whenever they get set, they also get validated. |
p.s. @taldcroft, @Cadair - if you both think it is OK, it is perhaps easier to just do this in the context of #5751 (I don't really know any more why I had the two PRs...). |
Yes, we use the fact you can change existing attributes on a I think limiting the setting of SkyCoord attributes to only ones that exist on frames is ok, as long as it's not a massive performance hit. I think we should keep the ability for the attributes to be modified if they are not the active frame though, as that's what we are using (exploiting?!) to do this observer switch-eroo. |
0e5d66d
to
e302575
Compare
@taldcroft, @Cadair - I now reversed the logic, and made this PR set any frame attribute that is not on its present frame on the Combining this with #5751 will ensure it will also be validated. Does this make sense? |
e302575
to
b47fbce
Compare
@Cadair - I think the present PR would not break anything, could you have a check? |
@mhvk - I like the present solution in this PR, if I'm understanding correctly... I actually thought this was the current behavior until seeing this PR and the associated issues. So in that sense I'm fine with calling this a bug fix (especially given #5751) But I would like to hear from @Cadair if this is compatible with the Sunpy use case before merging. |
I will try and test this tomorrow. |
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.
Finished my review. In its current state this doesn't seem controversial. I honestly don't know why I put "non-frame" attributes into the frame instance instead of the SkyCoord instance, but I agree this wasn't the best choice.
(not attr.startswith('_') and | ||
hasattr(self._sky_coord_frame, attr))): | ||
if not attr.startswith('_') and hasattr(self._sky_coord_frame, | ||
attr): |
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 personally think this is a nice example of where a strict 80 character line length limit makes the code less readable, not more. The existing style in this module is up to 100 characters, so in the future please feel free to let lines go somewhat past 80 if that avoids an awkward line break.
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.
Alternatively the previous version had a bit more logical line break
CHANGES.rst
Outdated
@@ -185,6 +185,12 @@ Bug Fixes | |||
- Fixed a bug where ``get_transform`` could sometimes produce confusing errors | |||
because of a typo in the input validation. [#5645] | |||
|
|||
- Ensured that frame attributes cannot be set on ``SkyCoord`` if the current |
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 is pretty confusing, and I think the first part was already true. What about:
Changed SkyCoord
so that frame attributes which are not valid for the current frame
(but are valid for other frames) are stored on the SkyCoord
instance instead of the underlying frame
instance. An example is setting relative_humidity
on an ICRS SkyCoord
instance.
Currently, if one defines, e.g., a SkyCoord with an ICRS frame, one can set any existing frame attribute that is not on that frame. Oddly, this gets set on the frame, without any validation: ``` sc = SkyCoord(ra=0., dec=0., unit='deg') sc.relative_humidity = 'bla' sc.frame.relative_humidity ``` This commit prevents one from setting any attribute that is a FrameAttribute of any frame.
Discussions showed that this is actually useful, so unlike in the previous commit, we should not forbid such setting. However, it still makes no sense to store those non-frame attributes on the frame; instead, they are now stored on the SkyCoord instance. (Validation of these is deferred to further commits.)
b47fbce
to
dcdb167
Compare
@taldcroft - OK, done both (much better text indeed). Rebased for good measure. |
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 doesn't seem to break anything in release SunPy. I have another problem that I discovered while testing this but it seems to be unrelated to this.
OK, I'll merge so that I can get my follow-up PR rebased on master, and it will be clearer what is new. |
Ensure FrameAttribute not on present frame are set on SkyCoord, not on its frame
Currently, if one defines, e.g., a SkyCoord with an ICRS frame, one can set any existing frame attribute that is not on that frame. Oddly, this gets set on the frame, without any validation:
This commit
prevents one from setting any attribute that is a[EDIT] ensures that possible frame attributes that are not on the present frame are stored on theFrameAttribute
of any frameSkyCoord
instance.EDIT: now went with alternative given that the setting is used in the wild (for sensible purposes).
@taldcroft, @eteq - please check this is in fact desired behaviour; the alternative would be to set the attribute on the
SkyCoord
itself, but my sense was that this violated the immutability.