Try to fix #295 with better documentation

Hopefully this will encourage users to interpret Geocentric coordinates
as fixed in space instead of in a rotating frame of reference.
This commit is contained in:
Brandon Rhodes 2019-11-10 21:59:29 -05:00
parent 3ca19d6cf1
commit 6a9a6ea2e2
5 changed files with 96 additions and 37 deletions

View File

@ -48,30 +48,45 @@ Position measured from the Solar System barycenter
.. autoclass:: Barycentric
:members:
This class inherits the methods of is parent class :class:`ICRF` as
well as the orientation of its axes in space.
Astrometric position relative to an observer
============================================
.. autoclass:: Astrometric
:members:
This class inherits the methods of is parent class :class:`ICRF` as
well as the orientation of its axes in space.
Apparent position relative to an observer
=========================================
.. autoclass:: Apparent
:members:
This class inherits the methods of is parent class :class:`ICRF` as
well as the orientation of its axes in space.
Geocentric position relative to the Earth
=========================================
.. autoclass:: Geocentric
:members:
This class inherits the methods of is parent class :class:`ICRF` as
well as the orientation of its axes in space.
Geometric instantaneous position between two objects
====================================================
.. autoclass:: Geometric
:members:
This class inherits the methods of is parent class :class:`ICRF` as
well as the orientation of its axes in space.
Building a position from right ascension and declination
========================================================

View File

@ -208,8 +208,10 @@ Astronomical positions
.. currentmodule:: skyfield.positionlib
The `ICRF` three-dimensional position vector serves as the base class
for all other position classes, which share its axes but have more
specific meanings.
for all of the following position classes. Each class represents an
(x,y,z) ``.position`` and ``.velocity`` in the International Terrestrial
Reference Frame (ITRF), an inertial system that is an update to J2000
and that does not rotate with the Earth itself.
.. autosummary::
:nosignatures:

View File

@ -44,12 +44,17 @@ def position_from_radec(ra_hours, dec_degrees, distance=1.0, epoch=None,
return build_position(position_au, None, t, center, target, observer_data)
class ICRF(object):
"""An (x, y, z) position and velocity oriented to the ICRF axes.
"""An (x,y,z) position and velocity oriented to the ICRF axes.
The ICRF is a permanent coordinate system that has superseded the
old series of equinox-based systems like B1900 and B1950. Its axes
are aligned with the axes of J2000 to within 0.02 arcseconds, which
is tighter than the accuracy of J2000 itself.
The International Coordinate Reference Frame (ICRF) is a permanent
reference frame that is the replacement for J2000. Their axes agree
to within 0.02 arcseconds. It also supersedes older equinox-based
systems like B1900 and B1950.
Each instance of this class provides a ``.position`` vector and a
``.velocity`` vector that specify (x,y,z) coordinates along the axes
of the ICRF. A specific time ``.t`` might be specified or might be
``None``.
"""
_default_center = None
@ -68,8 +73,19 @@ class ICRF(object):
self.observer_data = observer_data
def __repr__(self):
return '<{0} position{1}{2}{3}{4}>'.format(
self.__class__.__name__,
name = self.__class__.__name__
center = self.center
if name == 'Barycentric' and center == 0:
suffix = ' BCRS'
elif name == 'Apparent' and center == 399:
suffix = ' GCRS'
elif name != 'ICRF':
suffix = ' ICRS'
else:
suffix = ''
return '<{0}{1} position{2}{3}{4}{5}>'.format(
name,
suffix,
'' if (self.velocity is None) else ' and velocity',
'' if self.t is None else ' at date t',
'' if self.center is None else ' center={0}'.format(self.center),
@ -183,7 +199,7 @@ class ICRF(object):
return Angle(radians=arccos(clip(c, -1.0, 1.0)))
def cirs_xyz(self, epoch):
"""Compute cartesian CIRS coordinates at a given epoch (x, y, z).
"""Compute cartesian CIRS coordinates at a given epoch (x,y,z).
Calculate coordinates in the Celestial Intermediate Reference System
(CIRS), a dynamical coordinate system referenced to the Celestial
@ -219,7 +235,7 @@ class ICRF(object):
Distance(r_au))
def ecliptic_xyz(self, epoch=None):
"""Compute J2000 ecliptic position vector (x, y, z).
"""Compute J2000 ecliptic position vector (x,y,z).
If you instead want the coordinates referenced to the dynamical
system defined by the Earth's true equator and equinox, provide
@ -269,7 +285,7 @@ class ICRF(object):
Distance(au=d))
def galactic_xyz(self):
"""Compute galactic coordinates (x, y, z)"""
"""Compute galactic coordinates (x,y,z)"""
vector = _GALACTIC.dot(self.position.au)
return Distance(vector)
@ -343,6 +359,10 @@ class Geometric(ICRF):
corrected for the fact that, in real physics, it will take time for
light to travel from one position to the other.
Both the ``.position`` and ``.velocity`` are (x,y,z) vectors
oriented along the axes of the International Terrestrial Reference
Frame (ITRF), the modern replacement for J2000 coordinates.
"""
def altaz(self, temperature_C=None, pressure_mbar='standard'):
"""Compute (alt, az, distance) relative to the observer's horizon
@ -357,19 +377,19 @@ class Geometric(ICRF):
class Barycentric(ICRF):
"""An (x, y, z) position measured from the Solar System barycenter.
"""An (x,y,z) position measured from the Solar System barycenter.
Each barycentric position is an ICRS position vector, meaning that
the coordinate axes are defined by the high-precision ICRF that has
replaced the old J2000.0 reference frame, and the coordinate origin
is the BCRS gravitational center of the Solar System.
Skyfield generates a `Barycentric` position whenever you ask a Solar
System body for its location at a particular time:
Skyfield generates a `Barycentric` position measured from the
gravitational center of the Solar System whenever you ask a body for
its location at a particular time:
>>> t = ts.utc(2003, 8, 29)
>>> mars.at(t)
<Barycentric position and velocity at date t center=0 target=499>
<Barycentric BCRS position and velocity at date t center=0 target=499>
Both the ``.position`` and ``.velocity`` are (x,y,z) vectors
oriented along the axes of the International Terrestrial Reference
Frame (ITRF), the modern replacement for J2000 coordinates.
"""
def observe(self, body):
@ -384,11 +404,13 @@ class Barycentric(ICRF):
when it emitted the light that is now reaching this position.
>>> earth.at(t).observe(mars)
<Astrometric position and velocity at date t>
<Astrometric ICRS position and velocity at date t center=399 target=499>
"""
p, v, t, light_time = body._observe_from_bcrs(self)
astrometric = Astrometric(p, v, t, observer_data=self.observer_data)
astrometric = Astrometric(p, v, t,
center=self.target, target=body.target,
observer_data=self.observer_data)
astrometric.light_time = light_time
return astrometric
@ -396,12 +418,16 @@ class Barycentric(ICRF):
# it possible for it to observe() a planet.
class Astrometric(ICRF):
"""An astrometric (x, y, z) position relative to a particular observer.
"""An astrometric (x,y,z) position relative to a particular observer.
The *astrometric position* of a body is its position relative to an
observer, adjusted for light-time delay: the position of the body
back when it emitted (or reflected) the light that is now reaching
the observer's eyes or telescope.
observer, adjusted for light-time delay. It is the position of the
body back when it emitted (or reflected) the light that is now
reaching the observer's eyes or telescope.
Both the ``.position`` and ``.velocity`` are (x,y,z) vectors
oriented along the axes of the International Terrestrial Reference
Frame (ITRF), the modern replacement for J2000 coordinates.
Astrometric positions are usually generated in Skyfield by calling
the `Barycentric` method `observe()` to determine where a body will
@ -418,7 +444,7 @@ class Astrometric(ICRF):
aberration of light caused by the observer's own velocity.
>>> earth.at(t).observe(mars).apparent()
<Apparent position and velocity at date t>
<Apparent GCRS position and velocity at date t center=399 target=499>
These transforms convert the position from the BCRS reference
frame of the Solar System barycenter and to the reference frame
@ -457,11 +483,13 @@ class Astrometric(ICRF):
add_aberration(target_au, bcrs_velocity, self.light_time)
return Apparent(target_au, t=t, observer_data=observer_data)
return Apparent(target_au, t=t,
center=self.center, target=self.target,
observer_data=observer_data)
class Apparent(ICRF):
"""An apparent (x, y, z) position relative to a particular observer.
"""An apparent (x,y,z) position relative to a particular observer.
The *apparent position* of a body is its position relative to an
observer adjusted for light-time delay, deflection (light rays
@ -470,9 +498,10 @@ class Apparent(ICRF):
space).
Included in aberration is the relativistic transformation that takes
the position out of the BCRS centered on the solar system barycenter
and into the reference frame of the observer. In the case of an
Earth observer, the transform takes the coordinate into the GCRS.
the ``.position`` and ``.velocity`` (x,y,z) vectors out of the BCRS,
centered on the Solar System barycenter, and into the reference
frame of the observer. In the case of an Earth observer, the
transform takes the coordinate into the GCRS.
"""
def altaz(self, temperature_C=None, pressure_mbar='standard'):
@ -488,8 +517,19 @@ class Apparent(ICRF):
class Geocentric(ICRF):
"""An (x,y,z) position measured from the geocenter."""
"""An (x,y,z) position measured from the center of the Earth.
A geocentric position is the difference between the position of the
Earth at a given instant and the position of a target body at the
same instant, without accounting for light-travel time or the effect
of relativity on the light itself.
Its ``.position`` and ``.velocity`` vectors have (x,y,z) axes that
are those of the International Terrestrial Reference Frame (ITRF),
an inertial system that is an update to J2000 and that does not
rotate with the Earth itself.
"""
_default_center = 399
def itrf_xyz(self):
@ -498,7 +538,8 @@ class Geocentric(ICRF):
Returns a :class:`~skyfield.units.Distance` object giving the
(x,y,z) of this coordinate in the International Terrestrial
Reference Frame (ITRF), an internationally agreed upon
Earth-centered Earth-fixed (ECEF) coordinate system.
Earth-centered Earth-fixed (ECEF) coordinate system that
rotates with the surface of the Earth itself.
"""
if self.center != 399:

View File

@ -38,6 +38,7 @@ class Star(object):
"""
au_km = AU_KM
target = None
def __init__(self, ra=None, dec=None, ra_hours=None, dec_degrees=None,
ra_mas_per_year=0.0, dec_mas_per_year=0.0,

View File

@ -49,7 +49,7 @@ Sum of 2 vectors:
<VectorSum of 2 vectors 0 SOLAR SYSTEM BARYCENTER -> 399 EARTH>"
assert str(v.at(t)) == "\
<Barycentric position and velocity at date t center=0 target=399>"
<Barycentric BCRS position and velocity at date t center=0 target=399>"
v = earth - mars
@ -64,7 +64,7 @@ Sum of 4 vectors:
<VectorSum of 4 vectors 499 MARS -> 399 EARTH>"
assert str(v.at(t)) == "\
<Geometric position and velocity at date t center=499 target=399>"
<Geometric ICRS position and velocity at date t center=499 target=399>"
geocentric = Geocentric([0,0,0])
assert geocentric.center == 399