Skip to content

Don't preserve equinox when transforming with SkyCoord#3106

Merged
taldcroft merged 4 commits intoastropy:masterfrom
taldcroft:coordinates-attrs
Nov 18, 2014
Merged

Don't preserve equinox when transforming with SkyCoord#3106
taldcroft merged 4 commits intoastropy:masterfrom
taldcroft:coordinates-attrs

Conversation

@taldcroft
Copy link
Copy Markdown
Member

I find the following example confused me and it cost me a fair amount of time to debug vs kapteyn:

In [5]: c = SkyCoord(1. * u.deg, 1. * u.deg, frame=FK5, obstime=Time('J2000', scale='utc'))

In [6]: c.transform_to(FK4)
Out[6]: <SkyCoord (FK4: equinox=J2000.000, obstime=J2000.000): ra=0.999659097220236 deg, dec=0.9999930797297883 deg>

The issue is that while there is no sensible default for obstime, and it makes sense to keep the one defined before, the default equinox for FK4 should be B1950 and it should really only be changed explicitly, so I would expect the final SkyCoord above to be in B1950.

Basically I'm advocating for two different kinds of attributes in frames - attributes that default to None, and attributes that default to a value B1950. In the above case, the FK4 frame would assume the default equinox of B1950 while for obstime it would be default to None so then SkyCoord would just use the value specified before.

@eteq @taldcroft @cdeil - what do you think?

@astrofrog astrofrog added this to the v1.0.0 milestone Nov 15, 2014
@taldcroft
Copy link
Copy Markdown
Member

I think this seems sensible. If I am understanding then the machinery to make this happen is all there because we keep track of whether an attribute was explicitly set or is just coming from the defaults. The relevant code is here:

            # Set the keyword args for making a new frame instance for the
            # transform.  If the supplied frame instance has a non-default
            # value set then use that, otherwise use the self attribute value
            # if it is not None.
            for attr in FRAME_ATTR_NAMES_SET():
                self_val = getattr(self, attr, None)
                frame_val = getattr(frame, attr, None)
                if (frame_val is not None and
                        attr not in frame._attr_names_with_defaults):
                    frame_kwargs[attr] = frame_val
                elif self_val is not None:
                    frame_kwargs[attr] = self_val

I haven't tested, but maybe in the final elif we can have another check of whether self_val is from a default (if self.is_frame_attr_default(attr):) then fall back to the frame_val. I haven't thought through the logic to see if there is a cleaner way to write this all.

BTW the check attr not in frame._attr_names_with_defaults) should also use the public method frame.is_frame_attr_default(attr) for better style.

@cdeil
Copy link
Copy Markdown
Member

cdeil commented Nov 15, 2014

I'm luck ... so far I've never had to write science code that uses FK4 ... not sure which default behaviour for it's equinox would be better / less error-prone.

Might be worth asking on the mailing list which equinox people expect (without showing what the current behaviour is).

@taldcroft
Copy link
Copy Markdown
Member

I do think if you just make an FK5 coordinate and then transform to FK4 that most people would expect B1950 at the end.

EDIT: in the case where no equinox is ever explicitly specified.

@astrofrog
Copy link
Copy Markdown
Member Author

I agree with @taldcroft and this is the behavior in e.g. kapteyn. The equinox for FK4 is always B1950 unless specified otherwise, and for FK5 it is always J2000 unless specified otherwise.

@cdeil
Copy link
Copy Markdown
Member

cdeil commented Nov 15, 2014

👍 , then.

@eteq
Copy link
Copy Markdown
Member

eteq commented Nov 15, 2014

I don't think this is supposed to be happening at all, so I think this is actually a bug rather than a "proposed change".

What's supposed to happen is that SkyCoord only "shadows" a frame attribute if it's explicitly specified at creation of the SkyCoord. So because you never explicitly specified the equinox, it's supposed to take whatever frame attribute is in the instance you passed. But that's not what's happening:

>>> FK4()
<FK4 Frame (equinox=B1950.000, obstime=B1950.000)>
>>> c.transform_to(FK4(equinox='B1950'))
<SkyCoord (FK4: equinox=B1950.000, obstime=J2000.000): ra=0.359230685957 deg, dec=0.721667458859 deg>

The default FK4 equinox is B1950, so it shouldn't be different to specify it given that the SkyCoord never specified it.

So if @taldcroft's suggestion resolves this, I'm 👍 for it.

@astrofrog
Copy link
Copy Markdown
Member Author

Ok - it would be great if someone could implement a fix for this since I'm short on time in the next few days (but otherwise I'll get to it before 1.0)

@taldcroft taldcroft self-assigned this Nov 15, 2014
@taldcroft
Copy link
Copy Markdown
Member

Code attached. Based on @eteq's statement that this is a bug (I agree), I've put this for 0.4.3.

@astrofrog
Copy link
Copy Markdown
Member Author

👍

@taldcroft
Copy link
Copy Markdown
Member

This is passing tests now. Do you want to look at this @eteq ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this numbered list format of the precedence. This should probably go somewhere fairly prominent in the docs. Maybe either in the "using" section on SkyCoord, or the SkyCoord docstring itself?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(With one clarification in the docs: "self instance" should be replaced with "SkyCoord instance" or something like that.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add one final test where you do

c2 = c.transform_to(FK5(equinox='J1990'))
assert c2.equinox.value == 'J1990.000'
assert c2.obstime.value == 'J1980.000'

that is, make sure to catch the case of explicitly overwriting with the transform_to frame. I checked and it looks like it works, but it would make sense to add to the tests.

@taldcroft
Copy link
Copy Markdown
Member

@eteq - how does d856c4b look?

@eteq
Copy link
Copy Markdown
Member

eteq commented Nov 17, 2014

@taldcroft - looks good! You might want to put backticks around "SkyCoord", but it's a bit ambiguous given it's referring to that thing itself, so whatever's you think is fine.

Other than that and my additional test suggestion above, I'm 👍 on merging. Thanks!

taldcroft added a commit that referenced this pull request Nov 18, 2014
Fix frame attribute inheritance in SkyCoord.transform_to
@taldcroft taldcroft merged commit 71ba9a1 into astropy:master Nov 18, 2014
@taldcroft taldcroft deleted the coordinates-attrs branch November 18, 2014 11:33
taldcroft added a commit that referenced this pull request Dec 31, 2014
Fix frame attribute inheritance in SkyCoord.transform_to
Conflicts:
	astropy/coordinates/tests/test_sky_coord.py
dmopalmer added a commit to dmopalmer/astropy that referenced this pull request Jan 22, 2017
dmopalmer pushed a commit to dmopalmer/astropy that referenced this pull request Jan 23, 2017
Remove deprecated sigma_clip keywords

SkyCoord.position_angle bug fix
Fix for  bug in astropy#5702.  Also affects astropy#5722, astropy#3106.

Attempting to commit changes for coord_offset before trying to merge changes from posang_fix

position_offset before merging in cache_frame_attrs

Revert "position_offset before merging in cache_frame_attrs"

This reverts commit 9ef159218b746720a3d2134b5449bfb2f1a68f4f.

`SkyCoord.offset_by()` and `.directional_offset_to()` functions.
Simplistic treatment of coordinate offsets.
Definition of position_angle at poles must be refined.

Change in FIXME comment.
dmopalmer added a commit to dmopalmer/astropy that referenced this pull request Jan 31, 2017
mhvk pushed a commit to mhvk/astropy that referenced this pull request Feb 17, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants