
===========================
 Stars and Distant Objects
===========================

.. currentmodule:: skyfield.api

Skyfield can generate positions for stars or any other distant objects
for which you can provide barycentric ICRS coordinates.  Simply build a
:class:`Star` instance and then observe it from the Earth or another
Solar System body.  The position of Barnard’s Star, for example, at
right ascension 17ʰ57ᵐ48.49803ˢ and declination +4°41′36.2072″ can be
generated by:

.. testsetup::

   __import__('skyfield.tests.fixes').tests.fixes.setup(
       (2014, 1, 18, 23, 10, 9))

.. testcode::

    from skyfield.api import Star, load
    planets = load('de421.bsp')
    earth = planets['earth']

    barnard = Star(ra_hours=(17, 57, 48.49803),
                   dec_degrees=(4, 41, 36.2072))

    ts = load.timescale()
    t = ts.now()
    astrometric = earth.at(t).observe(barnard)
    ra, dec, distance = astrometric.radec()
    print(ra)
    print(dec)

.. testoutput::

    17h 57m 48.50s
    +04deg 41' 36.2"

Of course, this has simply returned the same position.  More interesting
is that we can ask for the position to be expressed in the dynamical
reference system of the moving Earth instead of in the same fixed ICRS
system in which we provided it:

.. testcode::

    ra, dec, distance = astrometric.radec(epoch=ts.now())
    print(ra)
    print(dec)

.. testoutput::

    17h 58m 30.80s
    +04deg 41' 41.9"

Distances to stars
==================

The distance that Skyfield computes to a particular star
might or might not be meaningful,
depending both on which star catalog you are using
and on which particular star you observe.

Skyfield has no way to even guess the distance to a star
if it has only been given its right ascension and declination,
as is the case for Barnard’s Star as we defined it above.
To represent this vector of unknown length,
Skyfield generates a vector exactly one gigaparsec long:

.. testcode::

    print(distance)  # exactly 1 gigaparsec

.. testoutput::

    2.06265e+14 au

This is so very far outside of our galaxy
that such positions should be easy
for you to tell apart from real distances to stars.
Real distances will all be within a few hundred parsecs or less,
because our telescopes cannot currently measure the parallax of stars
that are any further away than that.

In the next section,
we will redefine Barnard’s Star
and this time supply a real value for its parallax
from a recent star catalog.
You will see in that its ``distance``
switches to a realistic estimate.

Proper motion and parallax
==========================

There are other ways that a :class:`Star` object can generate a position
different than the plain old ICRS right ascension and declination with
which it is initialized.  First, Skyfield will recognize that an object
should change position over the years if we specify its proper motion in
milliarcseconds (“mas”) per year.  Second, Skyfield will shift its
apparent position relative to the location from which you observe it if
you provide a parallax indicating that the star is close enough to the
Solar System that we have been able to measure its distance.  Finally,
there is even a tiny effect from its radial velocity if it is known.

Here are all three effects applied to Barnard’s star:

.. testcode::

    from skyfield.api import T0

    barnard = Star(ra_hours=(17, 57, 48.49803),
                   dec_degrees=(4, 41, 36.2072),
                   ra_mas_per_year=-798.71,
                   dec_mas_per_year=+10337.77,
                   parallax_mas=545.4,
                   radial_km_per_s=-110.6)

    astrometric = earth.at(t).observe(barnard)
    ra, dec, distance = astrometric.radec()
    print(ra)
    print(dec)
    print(distance)

.. testoutput::

    17h 57m 47.76s
    +04deg 44' 01.3"
    3.77863e+05 au

Note that the above position is different than the input right ascension
and declination but not because we have asked for dynamic coordinates.
This position is in fixed ICRS coordinates and indicates real motion on
the part of Barnard’s star across our sky.

See the guide to :doc:`positions` to learn the operations that you can
perform with these astrometric positions after using a :class:`Star`
object to generate them.

Position at an epoch besides J2000
==================================

Some star catalogs provide positions at an epoch besides J2000.
For example, the catalog of stars observed by the Hipparcos space telescope
provides their positions as of J1991.25.

The epoch can be provided as an argument ``epoch`` to :class:`Star`.
Here are the right ascension and declination given for Barnard’s Star
in the Hipparcos catalog:

.. testcode::

    hipparcos_epoch = ts.tt(1991.25)
    barnard2 = Star(ra_hours=(17, 57, 48.97),
                    dec_degrees=(4, 40, 5.8),
                    ra_mas_per_year=-797.84,
                    dec_mas_per_year=+10326.93,
                    epoch=hipparcos_epoch)

    ra, dec, distance = earth.at(t).observe(barnard2).radec()
    print(ra)
    print(dec)

.. testoutput::

    17h 57m 47.75s
    +04deg 44' 01.3"

As you can see, the position returned for the date ``t`` is the same,
even though we initialized this :class:`Star` object
with a position for Barnard’s Star more than 8 years earlier
than the position we used in our first example.

.. testcleanup::

   __import__('skyfield.tests.fixes').tests.fixes.teardown()
