<commit_before>.. include:: references.txt

.. _astropy-coordinates-separations-matching:

Separations, Catalog Matching, and Related Functionality
--------------------------------------------------------

`astropy.coordinates` contains commonly-used tools for comparing or
matching coordinate objects.  Of particular importance are those for
determining separations between coordinates and those for matching a
coordinate (or coordinates) to a catalog.  These are mainly implemented
as methods on the coordinate objects.

Separations
===========

The on-sky separation is easily computed with the
:meth:`astropy.coordinates.BaseCoordinateFrame.separation` or
:meth:`astropy.coordinates.SkyCoord.separation` methods,
which computes the great-circle distance (*not* the small-angle
approximation)::

    >>> import numpy as np
    >>> from astropy import units as u
    >>> from astropy.coordinates import SkyCoord
    >>> c1 = SkyCoord('5h23m34.5s', '-69d45m22s', frame='icrs')
    >>> c2 = SkyCoord('0h52m44.8s', '-72d49m43s', frame='fk5')
    >>> sep = c1.separation(c2)
    >>> sep  # doctest: +FLOAT_CMP
    <Angle 20.74611447604398 deg>

The returned object is an `~astropy.coordinates.Angle` instance, so it
is straightforward to access the angle in any of several equivalent angular
units::

    >>> sep.radian  # doctest: +FLOAT_CMP
    0.36208800460262575
    >>> sep.hour  # doctest: +FLOAT_CMP
    1.3830742984029323
    >>> sep.arcminute  # doctest: +FLOAT_CMP
    1244.7668685626388
    >>> sep.arcsecond  # doctest: +FLOAT_CMP
    74686.01211375833

Also note that the two input coordinates were not in the same frame -
one is  automatically converted to match the other, ensuring that even
though they are  in different frames, the separation is determined
consistently.

In addition to the on-sky separation described above,
:meth:`astropy.coordinates.BaseCoordinateFrame.separation_3d` or
:meth:`astropy.coordinates.SkyCoord.separation_3d` methods will
determine the 3D distance between two coordinates that have ``distance``
defined::

    >>> from astropy.coordinates import SkyCoord
    >>> c1 = SkyCoord('5h23m34.5s', '-69d45m22s', distance=70*u.kpc, frame='icrs')
    >>> c2 = SkyCoord('0h52m44.8s', '-72d49m43s', distance=80*u.kpc, frame='icrs')
    >>> sep = c1.separation_3d(c2)
    >>> sep  # doctest: +FLOAT_CMP
    <Distance 28.743988157814094 kpc>

There is also a :meth:`~astropy.coordinates.SkyCoord.spherical_offsets_to` method
for computing angular offsets (e.g., small shifts like you might give a
telescope operator to move from a bright star to a fainter target.)::

    >>> from astropy.coordinates import SkyCoord
    >>> bright_star = SkyCoord('8h50m59.75s', '+11d39m22.15s', frame='icrs')
    >>> faint_galaxy = SkyCoord('8h50m47.92s', '+11d39m32.74s', frame='icrs')
    >>> dra, ddec = bright_star.spherical_offsets_to(faint_galaxy)
    >>> dra.to(u.arcsec)  # doctest: +FLOAT_CMP
    <Angle -173.78873354064126 arcsec>
    >>> ddec.to(u.arcsec)  # doctest: +FLOAT_CMP
    <Angle 10.605103417374696 arcsec>

.. _astropy-astrometric-frames:

"Astrometric" Frames
====================

To extend the concept of spherical offsets, `~astropy.coordinates` has
a frame class :class:`~astropy.coordinates.builtin_frames.astrometric.AstrometricFrame` 
which creates distinct frames that are centered on a specific point.
These are known as "astrometric frames" (as they are a convenient way to create
a centered on an arbitrary position, suitable for computing positional offsets for
astrometry)::

    >>> from astropy.coordinates import AstrometricFrame, ICRS
    >>> center = ICRS(10*u.deg, 45*u.deg)
    >>> center.transform_to(AstrometricFrame(origin=center))  # doctest: +SKIP
    <AstrometricFrame Coordinate (origin=<ICRS Coordinate: (ra, dec) in deg
        (10.0, 45.0)>, rotation=0.0 deg): (dra, ddec) in deg
        (0.0, 0.0)>
    >>> target = ICRS(11*u.deg, 46*u.deg)
    >>> target.transform_to(AstrometricFrame(origin=center))  # doctest: +FLOAT_CMP
    <AstrometricFrame Coordinate (origin=<ICRS Coordinate: (ra, dec) in deg
        (10.0, 45.0)>, rotation=0.0 deg): (dra, ddec) in deg
        (0.69474685, 1.00428706)>



Alternatively, the convenience method 
:meth:`~astropy.coordinates.SkyCoord.astrometric_frame` lets you create an astrometric
frame from an already-existing |SkyCoord|::

    >>> center = SkyCoord(10*u.deg, 45*u.deg)
    >>> aframe = center.astrometric_frame()
    >>> target.transform_to(aframe)  # doctest: +FLOAT_CMP
    <AstrometricFrame Coordinate (origin=<ICRS Coordinate: (ra, dec) in deg
        (10.0, 45.0)>, rotation=0.0 deg): (dra, ddec) in deg
        (0.69474685, 1.00428706)>
    >>> other = SkyCoord(9*u.deg, 44*u.deg, frame='fk5')
    >>> other.transform_to(aframe)  # doctest: +FLOAT_CMP
    <SkyCoord (AstrometricFrame: origin=<ICRS Coordinate: (ra, dec) in deg
        (10.0, 45.0)>, rotation=0.0 deg): (dra, ddec) in deg
        (359.28056055, -0.99556216)>



.. _astropy-coordinates-matching:
<commit_msg>Fix doctests.<commit_after>.. include:: references.txt

.. _astropy-coordinates-separations-matching:

Separations, Catalog Matching, and Related Functionality
--------------------------------------------------------

`astropy.coordinates` contains commonly-used tools for comparing or
matching coordinate objects.  Of particular importance are those for
determining separations between coordinates and those for matching a
coordinate (or coordinates) to a catalog.  These are mainly implemented
as methods on the coordinate objects.

Separations
===========

The on-sky separation is easily computed with the
:meth:`astropy.coordinates.BaseCoordinateFrame.separation` or
:meth:`astropy.coordinates.SkyCoord.separation` methods,
which computes the great-circle distance (*not* the small-angle
approximation)::

    >>> import numpy as np
    >>> from astropy import units as u
    >>> from astropy.coordinates import SkyCoord
    >>> c1 = SkyCoord('5h23m34.5s', '-69d45m22s', frame='icrs')
    >>> c2 = SkyCoord('0h52m44.8s', '-72d49m43s', frame='fk5')
    >>> sep = c1.separation(c2)
    >>> sep  # doctest: +FLOAT_CMP
    <Angle 20.74611447604398 deg>

The returned object is an `~astropy.coordinates.Angle` instance, so it
is straightforward to access the angle in any of several equivalent angular
units::

    >>> sep.radian  # doctest: +FLOAT_CMP
    0.36208800460262575
    >>> sep.hour  # doctest: +FLOAT_CMP
    1.3830742984029323
    >>> sep.arcminute  # doctest: +FLOAT_CMP
    1244.7668685626388
    >>> sep.arcsecond  # doctest: +FLOAT_CMP
    74686.01211375833

Also note that the two input coordinates were not in the same frame -
one is  automatically converted to match the other, ensuring that even
though they are  in different frames, the separation is determined
consistently.

In addition to the on-sky separation described above,
:meth:`astropy.coordinates.BaseCoordinateFrame.separation_3d` or
:meth:`astropy.coordinates.SkyCoord.separation_3d` methods will
determine the 3D distance between two coordinates that have ``distance``
defined::

    >>> from astropy.coordinates import SkyCoord
    >>> c1 = SkyCoord('5h23m34.5s', '-69d45m22s', distance=70*u.kpc, frame='icrs')
    >>> c2 = SkyCoord('0h52m44.8s', '-72d49m43s', distance=80*u.kpc, frame='icrs')
    >>> sep = c1.separation_3d(c2)
    >>> sep  # doctest: +FLOAT_CMP
    <Distance 28.743988157814094 kpc>

There is also a :meth:`~astropy.coordinates.SkyCoord.spherical_offsets_to` method
for computing angular offsets (e.g., small shifts like you might give a
telescope operator to move from a bright star to a fainter target.)::

    >>> from astropy.coordinates import SkyCoord
    >>> bright_star = SkyCoord('8h50m59.75s', '+11d39m22.15s', frame='icrs')
    >>> faint_galaxy = SkyCoord('8h50m47.92s', '+11d39m32.74s', frame='icrs')
    >>> dra, ddec = bright_star.spherical_offsets_to(faint_galaxy)
    >>> dra.to(u.arcsec)  # doctest: +FLOAT_CMP
    <Angle -173.78873354064126 arcsec>
    >>> ddec.to(u.arcsec)  # doctest: +FLOAT_CMP
    <Angle 10.605103417374696 arcsec>

.. _astropy-astrometric-frames:

"Astrometric" Frames
====================

To extend the concept of spherical offsets, `~astropy.coordinates` has
a frame class :class:`~astropy.coordinates.builtin_frames.astrometric.AstrometricFrame` 
which creates distinct frames that are centered on a specific point.
These are known as "astrometric frames" (as they are a convenient way to create
a centered on an arbitrary position, suitable for computing positional offsets for
astrometry)::

    >>> from astropy.coordinates import AstrometricFrame, ICRS
    >>> center = ICRS(10*u.deg, 45*u.deg)
    >>> center.transform_to(AstrometricFrame(origin=center))  # doctest: +SKIP
    <AstrometricFrame Coordinate (rotation=0.0 deg, origin=<ICRS Coordinate: (ra, dec) in deg
        (10.0, 45.0)>): (dra, ddec) in deg
        (0.0, 0.0)>
    >>> target = ICRS(11*u.deg, 46*u.deg)
    >>> target.transform_to(AstrometricFrame(origin=center))  # doctest: +FLOAT_CMP
    <AstrometricFrame Coordinate (rotation=0.0 deg, origin=<ICRS Coordinate: (ra, dec) in deg
        (10.0, 45.0)>): (dra, ddec) in deg
        (0.69474685, 1.00428706)>



Alternatively, the convenience method 
:meth:`~astropy.coordinates.SkyCoord.astrometric_frame` lets you create an astrometric
frame from an already-existing |SkyCoord|::

    >>> center = SkyCoord(10*u.deg, 45*u.deg)
    >>> aframe = center.astrometric_frame()
    >>> target.transform_to(aframe)  # doctest: +FLOAT_CMP
    <AstrometricFrame Coordinate (rotation=0.0 deg, origin=<ICRS Coordinate: (ra, dec) in deg
        (10.0, 45.0)>): (dra, ddec) in deg
        (0.69474685, 1.00428706)>
    >>> other = SkyCoord(9*u.deg, 44*u.deg, frame='fk5')
    >>> other.transform_to(aframe)  # doctest: +FLOAT_CMP
    <SkyCoord (AstrometricFrame: rotation=0.0 deg, origin=<ICRS Coordinate: (ra, dec) in deg
        (10.0, 45.0)>): (dra, ddec) in deg
        (359.28056055, -0.99556216)>



.. _astropy-coordinates-matching:

{'fraction_non_alphanumeric': 0.13587282543491302, 'fraction_numerical': 0.06758648270345931, 'mean_word_length': 4.069944247339078, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 219, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6485397', 'n_tokens_mistral': 3762, 'n_tokens_neox': 3296, 'n_words': 907}