<commit_before>*******************************************************
Astronomical Coordinate Systems (`astropy.coordinates`)
*******************************************************

Introduction
============

The `~astropy.coordinates` package provides classes for representing celestial
coordinates, as well as tools for converting between standard systems in a
uniform way.

.. note::
    The current `~astropy.coordinates` framework only accepts scalar
    coordinates, i.e. one coordinate per object.  In the next release it will
    be expanded to accept arrays of coordinates.

.. warning::
    `~astropy.coordinates` is currently a work-in-progress, and thus it is
    possible there will be significant API changes in later versions of
    Astropy.


Getting Started
===============

Coordinate objects are instantiated with a flexible and natural approach that
supports both numeric angle values and (limited) string parsing::

    >>> from astropy import coordinates as coord
    >>> from astropy import units as u
    >>> coord.ICRSCoordinates(ra=10.68458, dec=41.26917, unit=(u.degree, u.degree))
    <ICRSCoordinates RA=10.68458 deg, Dec=41.26917 deg>
    >>> coord.ICRSCoordinates('00h42m44.3s +41d16m9s')
    <ICRSCoordinates RA=10.68458 deg, Dec=41.26917 deg>

The individual components of a coordinate are `~astropy.coordinates.angles.Angle`
objects, and their values are accessed using special attributes::

    >>> c = coord.ICRSCoordinates(ra=10.68458, dec=41.26917, unit=(u.degree, u.degree))
    >>> c.ra
    <RA 10.68458 deg>
    >>> c.ra.hours
    0.7123053333333333
    >>> c.ra.hms
    (0.0, 42, 44.2992000000001)
    >>> c.dec
    <Dec 41.26917 deg>
    >>> c.dec.radians
    0.7202828960652683

To convert to some other coordinate system, the easiest method is to use
attribute-style access with short names for the built-in systems, but explicit
transformations via the `transform_to` method are also available::

    >>> c.galactic
    <GalacticCoordinates l=121.17422 deg, b=-21.57283 deg>
    >>> c.transform_to(coord.GalacticCoordinates)
    <GalacticCoordinates l=121.17422 deg, b=-21.57283 deg>

Distances from the origin (which is system-dependent, but often the Earth
center) can also be assigned to a coordinate. This specifies a unique point
in 3D space, which also allows conversion to cartesian coordinates::

    >>> c = coord.ICRSCoordinates(ra=10.68458, dec=41.26917, unit=(u.degree, u.degree), distance=coord.Distance(770, u.kpc))
    >>> c.x
    568.7128654235232
    >>> c.y
    107.3008974042025
    >>> c.z
    507.88994291875713


Using `astropy.coordinates`
===========================

An exhaustive resource for the capabilities of this package is the
`astropy.coordinates.tests.test_api` testing file. It showcases most of the
major capabilities of the package, and hence is a useful supplement to this
document.  You can see it by either looking at it directly if you downloaded a
copy of the astropy source code, or typing the following in an IPython session::

    In [1]: from astropy.coordinates.tests import test_api
    In [2]: test_api??


Creating Coordinate Objects
---------------------------

Creating new coordinate objects is of course crucial to using
`~astropy.coordinates`.  The typical way to create a new coordinate object
is to directly initialize your preferred coordinate system using standard
python class creation, using the name of the class representing that
system.  For example::

    >>> from astropy.coordinates import ICRSCoordinates, FK4Coordinates, GalacticCoordinates
    >>> ICRSCoordinates(187.70592, 12.39112, unit=(u.degree, u.degree))
    <ICRSCoordinates RA=187.70592 deg, Dec=12.39112 deg>
    >>> FK4Coordinates(187.07317, 12.66715, unit=(u.degree, u.degree))
    <FK4Coordinates RA=187.07317 deg, Dec=12.66715 deg>
    >>> GalacticCoordinates(-76.22237, 74.49108, unit=(u.degree, u.degree))
    <GalacticCoordinates l=-76.22237 deg, b=74.49108 deg>

Note that for equatorial coordinates (those with `ra` and `dec`), the `unit` is necessary
any time there might be an ambiguity between a radian, degree, or hour representation of
the RA component.  For example::

    >>> ICRSCoordinates(25, 1)
    <ICRSCoordinates RA=25.00000 deg, Dec=1.00000 deg>
    >>> ICRSCoordinates(23, 1)
    UnitsError: No units were specified, and the angle value was ambiguous between hours and degrees.

The latter case results in an exception because '23' could be degrees *or* hours.  When in doubt, it's
probably better to explicitly provide a `unit`.

While the above example uses python numerical types, you can also provide strings to create coordinates.
These strings will be interpreted using the `Angle` class' parsing scheme, and has a guiding principal of
being able to interpret any *unambiguous* string a human would interpret.  For the exact rules for how
each string is parsed, see the `~astropy.coordinates.angles.Angle` documentation.  Some examples
include::

    >>> ICRSCoordinates(54.12412, "-41:08:15.162342", unit=(u.degree, u.degree))
    <ICRSCoordinates RA=54.12412 deg, Dec=-41.13755 deg>
    >>> ICRSCoordinates("3:36:29.7888 -41:08:15.162342", unit=(u.hour, u.degree))
    <ICRSCoordinates RA=54.12412 deg, Dec=-41.13755 deg>
    >>> ICRSCoordinates("54.12412 -41:08:15.162342")
    <ICRSCoordinates RA=54.12412 deg, Dec=-41.13755 deg>
    >>> ICRSCoordinates("14.12412 -41:08:15.162342")
    UnitsError: No units were specified, and the angle value was ambiguous between hours and degrees.

You can also directly specify the units for both to resolve ambiguities.  This, will also give you
an error if you give a string with units that conflict with your desired units::

    >>> ICRSCoordinates('3 4 5 +6 7 8', unit=(u.hour, u.degree))
    <ICRSCoordinates RA=46.02083 deg, Dec=6.11889 deg>
    >>> ICRSCoordinates('3h4m5s +6d7m8s', unit=(u.hour, u.degree))
    <ICRSCoordinates RA=46.02083 deg, Dec=6.11889 deg>
    >>> ICRSCoordinates('3d4m5s +6h7m8s', unit=(u.hour, u.degree))
    ValueError: parse_hours: Invalid input string, can't parse to HMS. (3d4m5s)



Working with Angles
-------------------

The angular components of a coordinate are represented by objects of the
`~astropy.coordinates.angles.Angle` class. These objects can be instantiated on
their own anywhere a representation of an angle is needed, and support a variety
of ways of representing the value of the angle::

    >>> from astropy.coordinates import Angle
    >>> a = Angle(1, u.radian)
    >>> a
    <astropy.coordinates.angles.Angle 57.29578 deg>
    >>> a.radians
    1
    >>> a.degrees
    57.29577951308232
    >>> a.hours
    3.819718634205488
    >>> a.hms
    (3.0, 49, 10.987083139757061)
    >>> a.dms
    (57.0, 17, 44.80624709636231)
    >>> a.string()
    '57 17 44.80625'
    >>> a.string(sep=':')
    '57:17:44.80625'
    >>> a.string(sep='dms')
    '57d17m44.80625s'
    >>> a.string(u.hour, sep='hms')
    '3h49m10.98708s'

`~astropy.corodinates.angles.Angle` objects can also have bounds.  These specify
either a limited range in which the angle is valid (if it's <360 degrees), or
the limit at which an angle is wrapped back around to 0::

    >>> Angle(90, unit=u.degree, bounds=(0,180))
    <Angle 90.00000 deg>
    >>> Angle(-270, unit=u.degree, bounds=(0,180))
    <Angle 90.00000 deg>
    >>> Angle(181, unit=u.degree, bounds=(0,180))
    BoundsError: The angle given falls outside of the specified bounds.
    >>> Angle(361, unit=u.degree, bounds=(0,360))
    <Angle 1.00000 deg>

Angles will also behave correctly for appropriate arithmetic operations::<commit_msg>updated docs to reflect new coordinate initializer behavior, as pointed out by @astrofrog<commit_after>*******************************************************
Astronomical Coordinate Systems (`astropy.coordinates`)
*******************************************************

Introduction
============

The `~astropy.coordinates` package provides classes for representing celestial
coordinates, as well as tools for converting between standard systems in a
uniform way.

.. note::
    The current `~astropy.coordinates` framework only accepts scalar
    coordinates, i.e. one coordinate per object.  In the next release it will
    be expanded to accept arrays of coordinates.

.. warning::
    `~astropy.coordinates` is currently a work-in-progress, and thus it is
    possible there will be significant API changes in later versions of
    Astropy.


Getting Started
===============

Coordinate objects are instantiated with a flexible and natural approach that
supports both numeric angle values and (limited) string parsing::

    >>> from astropy import coordinates as coord
    >>> from astropy import units as u
    >>> coord.ICRSCoordinates(ra=10.68458, dec=41.26917, unit=(u.degree, u.degree))
    <ICRSCoordinates RA=10.68458 deg, Dec=41.26917 deg>
    >>> coord.ICRSCoordinates('00h42m44.3s +41d16m9s')
    <ICRSCoordinates RA=10.68458 deg, Dec=41.26917 deg>

The individual components of a coordinate are `~astropy.coordinates.angles.Angle`
objects, and their values are accessed using special attributes::

    >>> c = coord.ICRSCoordinates(ra=10.68458, dec=41.26917, unit=(u.degree, u.degree))
    >>> c.ra
    <RA 10.68458 deg>
    >>> c.ra.hours
    0.7123053333333333
    >>> c.ra.hms
    (0.0, 42, 44.2992000000001)
    >>> c.dec
    <Dec 41.26917 deg>
    >>> c.dec.radians
    0.7202828960652683

To convert to some other coordinate system, the easiest method is to use
attribute-style access with short names for the built-in systems, but explicit
transformations via the `transform_to` method are also available::

    >>> c.galactic
    <GalacticCoordinates l=121.17422 deg, b=-21.57283 deg>
    >>> c.transform_to(coord.GalacticCoordinates)
    <GalacticCoordinates l=121.17422 deg, b=-21.57283 deg>

Distances from the origin (which is system-dependent, but often the Earth
center) can also be assigned to a coordinate. This specifies a unique point
in 3D space, which also allows conversion to cartesian coordinates::

    >>> c = coord.ICRSCoordinates(ra=10.68458, dec=41.26917, unit=(u.degree, u.degree), distance=coord.Distance(770, u.kpc))
    >>> c.x
    568.7128654235232
    >>> c.y
    107.3008974042025
    >>> c.z
    507.88994291875713


Using `astropy.coordinates`
===========================

An exhaustive resource for the capabilities of this package is the
`astropy.coordinates.tests.test_api` testing file. It showcases most of the
major capabilities of the package, and hence is a useful supplement to this
document.  You can see it by either looking at it directly if you downloaded a
copy of the astropy source code, or typing the following in an IPython session::

    In [1]: from astropy.coordinates.tests import test_api
    In [2]: test_api??


Creating Coordinate Objects
---------------------------

Creating new coordinate objects is of course crucial to using
`~astropy.coordinates`.  The typical way to create a new coordinate object
is to directly initialize your preferred coordinate system using standard
python class creation, using the name of the class representing that
system.  For example::

    >>> from astropy.coordinates import ICRSCoordinates, FK4Coordinates, GalacticCoordinates
    >>> ICRSCoordinates(187.70592, 12.39112, unit=(u.degree, u.degree))
    <ICRSCoordinates RA=187.70592 deg, Dec=12.39112 deg>
    >>> FK4Coordinates(187.07317, 12.66715, unit=(u.degree, u.degree))
    <FK4Coordinates RA=187.07317 deg, Dec=12.66715 deg>
    >>> GalacticCoordinates(-76.22237, 74.49108, unit=(u.degree, u.degree))
    <GalacticCoordinates l=-76.22237 deg, b=74.49108 deg>

Note that if you do not provide units explicitly, this will fail::

    >>> ICRSCoordinates(23, 1)
    UnitsError: No unit was specified in Angle initializer; the unit parameter should be an object from the  astropy.units module (e.g. 'from astropy import units as u', then use 'u.degree').

While the above example uses python numerical types, you can also provide strings to create coordinates.
If the `unit` parameter is ``(None, None)`` (the default), strings will be interpreted using the `Angle` 
class' parsing scheme, and has a guiding principal of being able to interpret any *unambiguous* string 
specifying an angle. For the exact rules for how each string is parsed, see the 
`~astropy.coordinates.angles.Angle` documentation.  Some examples::

    >>> ICRSCoordinates("3h36m29.7888s -41d08m15.162342s", unit=(None, None))
    <ICRSCoordinates RA=54.12412 deg, Dec=-41.13755 deg>
    >>> ICRSCoordinates("3h36m29.7888s -41d08m15.162342s")
    <ICRSCoordinates RA=54.12412 deg, Dec=-41.13755 deg>
    >>> ICRSCoordinates("14.12412 hours", "-41:08:15.162342 degrees")
    <ICRSCoordinates RA=211.86180 deg, Dec=-41.13755 deg>
    >>> ICRSCoordinates("14.12412 -41:08:15.162342")
    UnitsError: Could not infer Angle units from provided string 14.12412

You can also directly specify the units for both to resolve ambiguities::

    >>> ICRSCoordinates("14.12412 -41:08:15.162342", unit=(u.hour, u.degree))
    <ICRSCoordinates RA=211.86180 deg, Dec=-41.13755 deg>
    >>> ICRSCoordinates("54:7:26.832 -41:08:15.162342", unit=(u.degree, u.degree))
    <ICRSCoordinates RA=54.12412 deg, Dec=-41.13755 deg>
    >>> ICRSCoordinates('3 4 5 +6 7 8', unit=(u.hour, u.degree))
    <ICRSCoordinates RA=46.02083 deg, Dec=6.11889 deg>
    >>> ICRSCoordinates('3h4m5s +6d7m8s', unit=(u.hour, u.degree))
    <ICRSCoordinates RA=46.02083 deg, Dec=6.11889 deg>

This will also give you an error if you give a string with units that conflict with your desired units::

    >>> ICRSCoordinates('3d4m5s +6h7m8s', unit=(u.hour, u.degree))
    ValueError: parse_hours: Invalid input string, can't parse to HMS. (3d4m5s)



Working with Angles
-------------------

The angular components of a coordinate are represented by objects of the
`~astropy.coordinates.angles.Angle` class. These objects can be instantiated on
their own anywhere a representation of an angle is needed, and support a variety
of ways of representing the value of the angle::

    >>> from astropy.coordinates import Angle
    >>> a = Angle(1, u.radian)
    >>> a
    <astropy.coordinates.angles.Angle 57.29578 deg>
    >>> a.radians
    1
    >>> a.degrees
    57.29577951308232
    >>> a.hours
    3.819718634205488
    >>> a.hms
    (3.0, 49, 10.987083139757061)
    >>> a.dms
    (57.0, 17, 44.80624709636231)
    >>> a.format()
    '57d17m44.80625s'
    >>> a.format(sep=':')
    '57:17:44.80625'
    >>> a.format(sep=('deg','m','s'))
    '57deg17m44.80625s'
    >>> a.format(u.hour)
    '3h49m10.98708s'

`~astropy.corodinates.angles.Angle` objects can also have bounds.  These specify
either a limited range in which the angle is valid (if it's <360 degrees), or
the limit at which an angle is wrapped back around to 0::

    >>> Angle(90, unit=u.degree, bounds=(0,180))
    <Angle 90.00000 deg>
    >>> Angle(-270, unit=u.degree, bounds=(0,180))
    <Angle 90.00000 deg>
    >>> Angle(181, unit=u.degree, bounds=(0,180))
    BoundsError: The angle given falls outside of the specified bounds.
    >>> Angle(361, unit=u.degree, bounds=(0,360))
    <Angle 1.00000 deg>

Angles will also behave correctly for appropriate arithmetic operations::
{'fraction_non_alphanumeric': 0.13101727195113944, 'fraction_numerical': 0.09456885794969462, 'mean_word_length': 3.958645392380332, 'pattern_counts': {'":': 0, '<': 44, '<?xml version=': 0, '>': 315, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2457053', 'n_tokens_mistral': 5728, 'n_tokens_neox': 4764, 'n_words': 1625}