This notebook serves to enlighten the reader about how Astropy's coordinates API can be used. It does so by putting forward some relevant use-cases and the comments describe what is happening in those use-cases. This API is central to the re-implementation project. The coordinate frames and their transformations, as well as preferred representations will be subject to what we register in the coordinates transformation graph or registry - which stores each and every transformation between coordinate reference frames.
This APE has brought some much needed changes to the coordinates framework. It defines very clearly what a coordinate object represents, i.e.,
Earlier versions of Astropy did not address the ambiguity behind coordinates as well as this version does. It also divides the framework into the following logical pieces -:
SkyCoord
.I shall be describing the API as follows -:
SkyCoord
and BaseCoordinateFrame
properties are then discussed.BaseCoordinateFrame
and its child, GenericFrame
, are overviewed.# Simple example of a reference system and a specific representation.
# According to APE5, a coordinate object consists of a coordinate
# representation, a reference system and if required, a coordinate
# frame.
from astropy import units as u
from astropy.coordinates import ICRS, CartesianRepresentation, \
CylindricalRepresentation
from astropy.coordinates import SkyCoord
# One may instantiate a reference frame/system with data.
# This makes it a coordinate frame.
coord = SkyCoord(ICRS(0*u.deg, 0*u.deg))
coord.to_string()
u'0 0'
# We can convert between different coordinate representations.
print(coord.represent_as(CartesianRepresentation), "and",\
coord.represent_as(CylindricalRepresentation))
(<CartesianRepresentation x=1.0 , y=0.0 , z=0.0 >, 'and', <CylindricalRepresentation rho=1.0 , phi=0.0 rad, z=0.0 >)
# Or we can convert between frames too, by first checking
# if it is possible.
from astropy.coordinates import FK5
if coord.is_transformable_to(FK5):
print('Can has transform')
newcr = coord.transform_to(FK5)
print(newcr.frame)
else:
print('Cannot has')
Can has transform <FK5 Coordinate: equinox=J2000.000, ra=6.3611113319e-06 deg, dec=2.52777716407e-06 deg>
# Separation, or even 3D separation can be calculated as shown.
drooc = SkyCoord(ICRS(10*u.deg, 15*u.deg))
coord.separation(drooc)
# This tells us the on-sky angle (east of north)
# between two SkyCoord objects.
coord.position_angle(drooc)
# There are cases where one may not instantiate a reference frame
# with data. This means it is not a coordinate frame - yet.
sc = SkyCoord(ICRS)
# SkyCoord acts as a wrapper over BaseCoordinateFrame and uses its
# methods.
# SkyCoord objects have a frame property -:
print(coord.frame)
print(drooc.frame)
print(sc.frame) # Not a coordinate frame.
<ICRS Coordinate: ra=0.0 deg, dec=0.0 deg> <ICRS Coordinate: ra=10.0 deg, dec=15.0 deg> <ICRS Frame>
# The data property of the underlying frame object
# can be used to obtain coordinate data.
if coord.has_data:
print(coord.data)
(0.0, 0.0) deg
# One can create a new reference/coordinate frame from another
# frame object that may or may not have data. Once again, underlying
# BaseCoordinateFrame methods allow this.
newcr2 = coord.realize_frame(newcr.transform_to(ICRS))
# The reference frames need to be the same for realization.
if newcr2.has_data:
print(newcr2.data)
(0.0, -2.2447333620363583e-21) deg
# BaseCoordinateFrame also has properties to check for whether
# the object is scalar and what is its shape type.
print(coord.shape)
print(coord.isscalar)
() True
# Check if a frame attribute has a value because its the
# default one available, or because it was created with that
# value.
coord.is_frame_attr_default('isscalar')
False
# The GenericFrame class can be used to hold an arbitrary number
# of frame attributes, but no data. It is useful for the high-level
# class to store intermediate frame attributes.
# The constructor takes a dict of attributes and their values.
from astropy.coordinates.baseframe import GenericFrame
frame_attrs = {'i can has': True, 'i can not has': False}
gf = GenericFrame(frame_attrs)
print(gf)
<GenericFrame Frame: i can not has=False, i can has=True> <GenericFrame Frame: i can not has=False, i can has=True>