Skip to content

Commit b7b93b4

Browse files
committed
Merge pull request #5023 from eteq/astrometric-tweaks
Make astrometric frames be on [-180, 180] and change their name to SkyOffsetFrame
1 parent ba428ef commit b7b93b4

File tree

5 files changed

+121
-114
lines changed

5 files changed

+121
-114
lines changed

astropy/coordinates/builtin_frames/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
from .itrs import ITRS
3737
from .hcrs import HCRS
3838
from .ecliptic import GeocentricTrueEcliptic, BarycentricTrueEcliptic, HeliocentricTrueEcliptic
39-
from .astrometric import AstrometricFrame
39+
from .skyoffset import SkyOffsetFrame
4040
# need to import transformations so that they get registered in the graph
4141
from . import icrs_fk5_transforms
4242
from . import fk4_fk5_transforms
@@ -52,7 +52,7 @@
5252
'Supergalactic', 'AltAz', 'GCRS', 'CIRS', 'ITRS', 'HCRS',
5353
'PrecessedGeocentric', 'GeocentricTrueEcliptic',
5454
'BarycentricTrueEcliptic', 'HeliocentricTrueEcliptic',
55-
'AstrometricFrame']
55+
'SkyOffsetFrame']
5656

5757

5858
def _make_transform_graph_docs():

astropy/coordinates/builtin_frames/astrometric.py renamed to astropy/coordinates/builtin_frames/skyoffset.py

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
from ..angles import rotation_matrix
1313
from ...utils.compat import namedtuple_asdict
1414

15-
_astrometric_cache = {}
15+
_skyoffset_cache = {}
1616

1717

18-
def make_astrometric_cls(framecls):
18+
def make_skyoffset_cls(framecls):
1919
"""
20-
Create a new class that is the Astrometric frame for a specific class of
20+
Create a new class that is the sky offset frame for a specific class of
2121
origin frame. If such a class has already been created for this frame, the
2222
same class will be returned.
2323
@@ -27,31 +27,31 @@ def make_astrometric_cls(framecls):
2727
Parameters
2828
----------
2929
framecls : coordinate frame class (i.e., subclass of `~astropy.coordinates.BaseCoordinateFrame`)
30-
The class to create the Astrometric frame of.
30+
The class to create the SkyOffsetFrame of.
3131
3232
Returns
3333
-------
34-
astrometricframecls : class
35-
The class for the new astrometric frame.
34+
skyoffsetframecls : class
35+
The class for the new skyoffset frame.
3636
3737
Notes
3838
-----
3939
This function is necessary because Astropy's frame transformations depend
4040
on connection between specific frame *classes*. So each type of frame
41-
needs its own distinct astrometric frame class. This function generates
41+
needs its own distinct skyoffset frame class. This function generates
4242
just that class, as well as ensuring that only one example of such a class
4343
actually gets created in any given python session.
4444
"""
4545

46-
if framecls in _astrometric_cache:
47-
return _astrometric_cache[framecls]
46+
if framecls in _skyoffset_cache:
47+
return _skyoffset_cache[framecls]
4848

4949
# the class of a class object is the metaclass
5050
framemeta = framecls.__class__
5151

52-
class AstrometricMeta(framemeta):
52+
class SkyOffsetMeta(framemeta):
5353
"""
54-
This metaclass renames the class to be "Astrometric<framecls>" and also
54+
This metaclass renames the class to be "SkyOffset<framecls>" and also
5555
adjusts the frame specific representation info so that spherical names
5656
are always "lon" and "lat" (instead of e.g. "ra" and "dec").
5757
"""
@@ -62,14 +62,14 @@ def __new__(cls, name, bases, members):
6262

6363
# This has to be done because FrameMeta will set these attributes
6464
# to the defaults from BaseCoordinateFrame when it creates the base
65-
# AstrometricFrame class initially.
65+
# SkyOffsetFrame class initially.
6666
members['_frame_specific_representation_info'] = framecls._frame_specific_representation_info
6767
members['_default_representation'] = framecls._default_representation
6868

6969
newname = name[:-5] if name.endswith('Frame') else name
7070
newname += framecls.__name__
7171

72-
res = super(AstrometricMeta, cls).__new__(cls, newname, bases, members)
72+
res = super(SkyOffsetMeta, cls).__new__(cls, newname, bases, members)
7373

7474
# now go through all the component names and make any spherical names be "lon" and "lat"
7575
# instead of e.g. "ra" and "dec"
@@ -105,51 +105,51 @@ def __new__(cls, name, bases, members):
105105
return res
106106

107107
# We need this to handle the intermediate metaclass correctly, otherwise we could
108-
# just subclass astrometric.
109-
_Astrometric = AstrometricMeta('AstrometricFrame', (AstrometricFrame, framecls),
110-
{'__doc__': AstrometricFrame.__doc__})
108+
# just subclass SkyOffsetFrame.
109+
_SkyOffsetFramecls = SkyOffsetMeta('SkyOffsetFrame', (SkyOffsetFrame, framecls),
110+
{'__doc__': SkyOffsetFrame.__doc__})
111111

112-
@frame_transform_graph.transform(FunctionTransform, _Astrometric, _Astrometric)
113-
def astrometric_to_astrometric(from_astrometric_coord, to_astrometric_frame):
114-
"""Transform between two astrometric frames."""
112+
@frame_transform_graph.transform(FunctionTransform, _SkyOffsetFramecls, _SkyOffsetFramecls)
113+
def skyoffset_to_skyoffset(from_skyoffset_coord, to_skyoffset_frame):
114+
"""Transform between two skyoffset frames."""
115115

116116
# This transform goes through the parent frames on each side.
117117
# from_frame -> from_frame.origin -> to_frame.origin -> to_frame
118-
intermediate_from = from_astrometric_coord.transform_to(from_astrometric_coord.origin)
119-
intermediate_to = intermediate_from.transform_to(to_astrometric_frame.origin)
120-
return intermediate_to.transform_to(to_astrometric_frame)
118+
intermediate_from = from_skyoffset_coord.transform_to(from_skyoffset_coord.origin)
119+
intermediate_to = intermediate_from.transform_to(to_skyoffset_frame.origin)
120+
return intermediate_to.transform_to(to_skyoffset_frame)
121121

122-
@frame_transform_graph.transform(DynamicMatrixTransform, framecls, _Astrometric)
123-
def reference_to_astrometric(reference_frame, astrometric_frame):
124-
"""Convert a reference coordinate to an Astrometric frame."""
122+
@frame_transform_graph.transform(DynamicMatrixTransform, framecls, _SkyOffsetFramecls)
123+
def reference_to_skyoffset(reference_frame, skyoffset_frame):
124+
"""Convert a reference coordinate to an sky offset frame."""
125125

126126
# Define rotation matrices along the position angle vector, and
127127
# relative to the origin.
128-
origin = astrometric_frame.origin.spherical
129-
mat1 = rotation_matrix(-astrometric_frame.rotation, 'x')
128+
origin = skyoffset_frame.origin.spherical
129+
mat1 = rotation_matrix(-skyoffset_frame.rotation, 'x')
130130
mat2 = rotation_matrix(-origin.lat, 'y')
131131
mat3 = rotation_matrix(origin.lon, 'z')
132132
R = mat1 * mat2 * mat3
133133
return R
134134

135-
@frame_transform_graph.transform(DynamicMatrixTransform, _Astrometric, framecls)
136-
def astrometric_to_reference(astrometric_coord, reference_frame):
137-
"""Convert an Astrometric frame coordinate to the reference frame"""
135+
@frame_transform_graph.transform(DynamicMatrixTransform, _SkyOffsetFramecls, framecls)
136+
def skyoffset_to_reference(skyoffset_coord, reference_frame):
137+
"""Convert an sky offset frame coordinate to the reference frame"""
138138

139139
# use the forward transform, but just invert it
140-
R = reference_to_astrometric(reference_frame, astrometric_coord)
140+
R = reference_to_skyoffset(reference_frame, skyoffset_coord)
141141
return R.T # this is the inverse because R is a rotation matrix
142142

143-
_astrometric_cache[framecls] = _Astrometric
144-
return _Astrometric
143+
_skyoffset_cache[framecls] = _SkyOffsetFramecls
144+
return _SkyOffsetFramecls
145145

146146

147-
class AstrometricFrame(BaseCoordinateFrame):
147+
class SkyOffsetFrame(BaseCoordinateFrame):
148148
"""
149149
A frame which is relative to some specific position and oriented to match
150150
its frame.
151151
152-
AstrometricFrames always have component names for spherical coordinates
152+
SkyOffsetFrames always have component names for spherical coordinates
153153
of ``lon``/``lat``, *not* the component names for the frame of ``origin``.
154154
155155
This is useful for calculating offsets and dithers in the frame of the sky
@@ -159,7 +159,7 @@ class AstrometricFrame(BaseCoordinateFrame):
159159
object's ``lat`` will be pointed in the direction of Dec, while ``lon``
160160
will point in the direction of RA.
161161
162-
For more on astrometric frames, see :ref:`astropy-astrometric-frames`.
162+
For more on skyoffset frames, see :ref:`astropy-skyoffset-frames`.
163163
164164
Parameters
165165
----------
@@ -176,8 +176,8 @@ class AstrometricFrame(BaseCoordinateFrame):
176176
177177
Notes
178178
-----
179-
``AstrometricFrame`` is a factory class. That is, the objects that it
180-
yields are *not* actually objects of class ``AstrometricFrame``. Instead,
179+
``SkyOffsetFrame`` is a factory class. That is, the objects that it
180+
yields are *not* actually objects of class ``SkyOffsetFrame``. Instead,
181181
distinct classes are created on-the-fly for whatever the frame class is
182182
of ``origin``.
183183
"""
@@ -187,28 +187,30 @@ class AstrometricFrame(BaseCoordinateFrame):
187187

188188
def __new__(cls, *args, **kwargs):
189189
# We don't want to call this method if we've already set up
190-
# an astrometric frame for this class.
191-
if not (issubclass(cls, AstrometricFrame) and cls is not AstrometricFrame):
190+
# an skyoffset frame for this class.
191+
if not (issubclass(cls, SkyOffsetFrame) and cls is not SkyOffsetFrame):
192192
# We get the origin argument, and handle it here.
193193
try:
194194
origin_frame = kwargs['origin']
195195
except KeyError:
196-
raise TypeError("Can't initialize an AstrometricFrame without origin= keyword.")
196+
raise TypeError("Can't initialize an SkyOffsetFrame without origin= keyword.")
197197
if hasattr(origin_frame, 'frame'):
198198
origin_frame = origin_frame.frame
199-
newcls = make_astrometric_cls(origin_frame.__class__)
199+
newcls = make_skyoffset_cls(origin_frame.__class__)
200200
return newcls.__new__(newcls, *args, **kwargs)
201201

202202
# http://stackoverflow.com/questions/19277399/why-does-object-new-work-differently-in-these-three-cases
203203
# See above for why this is necessary. Basically, because some child
204204
# may override __new__, we must override it here to never pass
205205
# arguments to the object.__new__ method.
206-
if super(AstrometricFrame, cls).__new__ is object.__new__:
207-
return super(AstrometricFrame, cls).__new__(cls)
208-
return super(AstrometricFrame, cls).__new__(cls, *args, **kwargs)
206+
if super(SkyOffsetFrame, cls).__new__ is object.__new__:
207+
return super(SkyOffsetFrame, cls).__new__(cls)
208+
return super(SkyOffsetFrame, cls).__new__(cls, *args, **kwargs)
209209

210210
def __init__(self, *args, **kwargs):
211-
super(AstrometricFrame, self).__init__(*args, **kwargs)
211+
super(SkyOffsetFrame, self).__init__(*args, **kwargs)
212212
if self.origin is not None and not self.origin.has_data:
213-
raise ValueError('The origin supplied to AstrometricFrame has no '
213+
raise ValueError('The origin supplied to SkyOffsetFrame has no '
214214
'data.')
215+
if self.has_data and hasattr(self.data, 'lon'):
216+
self.data.lon.wrap_angle = 180*u.deg

astropy/coordinates/sky_coordinate.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from .distances import Distance
1919
from .angles import Angle
2020
from .baseframe import BaseCoordinateFrame, frame_transform_graph, GenericFrame, _get_repr_cls
21-
from .builtin_frames import ICRS, AstrometricFrame
21+
from .builtin_frames import ICRS, SkyOffsetFrame
2222
from .representation import (BaseRepresentation, SphericalRepresentation,
2323
UnitSphericalRepresentation)
2424

@@ -731,8 +731,8 @@ def spherical_offsets_to(self, tocoord):
731731
732732
Notes
733733
-----
734-
This uses the astrometric frame machinery, and hence will produce a new
735-
astrometric frame if one does not already exist for this object's frame
734+
This uses the sky offset frame machinery, and hence will produce a new
735+
sky offset frame if one does not already exist for this object's frame
736736
class.
737737
738738
See Also
@@ -743,10 +743,10 @@ def spherical_offsets_to(self, tocoord):
743743
if not self.is_equivalent_frame(tocoord):
744744
raise ValueError('Tried to use spherical_offsets_to with two non-matching frames!')
745745

746-
aframe = self.astrometric_frame()
746+
aframe = self.skyoffset_frame()
747747
acoord = tocoord.transform_to(aframe)
748748

749-
dlon = acoord.spherical.lon.wrap_at(180*u.deg)
749+
dlon = acoord.spherical.lon.view(Angle)
750750
dlat = acoord.spherical.lat.view(Angle)
751751
return dlon, dlat
752752

@@ -1037,23 +1037,23 @@ def position_angle(self, other):
10371037

10381038
return angle_utilities.position_angle(slon, slat, olon, olat)
10391039

1040-
def astrometric_frame(self, rotation=None):
1040+
def skyoffset_frame(self, rotation=None):
10411041
"""
1042-
Returns the astrometric frame with this `SkyCoord` at the origin.
1042+
Returns the sky offset frame with this `SkyCoord` at the origin.
10431043
10441044
Returns
10451045
-------
1046-
astrframe : `~astropy.coordinates.AstrometricFrame`
1047-
An astrometric frame of the same type as this `SkyCoord` (e.g., if
1046+
astrframe : `~astropy.coordinates.SkyOffsetFrame`
1047+
A sky offset frame of the same type as this `SkyCoord` (e.g., if
10481048
this object has an ICRS coordinate, the resulting frame is
1049-
AstrometricFrame with an ICRS origin)
1049+
SkyOffsetICRS, with the origin set to this object)
10501050
rotation : `~astropy.coordinates.Angle` or `~astropy.units.Quantity` with angle units
10511051
The final rotation of the frame about the ``origin``. The sign of
10521052
the rotation is the left-hand rule. That is, an object at a
10531053
particular position angle in the un-rotated system will be sent to
10541054
the positive latitude (z) direction in the final frame.
10551055
"""
1056-
return AstrometricFrame(origin=self, rotation=rotation)
1056+
return SkyOffsetFrame(origin=self, rotation=rotation)
10571057

10581058
def get_constellation(self, short_name=False, constellation_list='iau'):
10591059
"""

0 commit comments

Comments
 (0)