
    R1i+                        d Z ddlmZmZmZmZmZmZmZ ddl	m
Z
 ddlmZmZmZmZmZmZmZmZ ddlmZ ddlmZ ddlmZmZmZmZmZmZmZm Z m!Z!m"Z" dd	l#m$Z$ dd
l%m&Z&m'Z' ddl(m)Z) ddl*m+Z+m,Z,m-Z-m.Z.m/Z/ dZ0	 	 d%dZ1e0ddddfdZ2	 	 d&dZ3 G d de4      Z5e5Z6 G d de5      Z7 G d de5      Z8 G d de5      Z9 G d de5      Z: G d de5      Z;d Z<dZ=d Z> G d! d"e5      Z?d# Z@d'd$ZAy)(z>Classes representing different kinds of astronomical position.    )arraycoseinsumfullreshapenan
nan_to_num   )framelib)ANGVELAU_MCERADDAY_SRAD2DEGpitau)reify)compute_limb_angle)
_T	_to_array_to_spherical_and_ratesangle_betweenfrom_spherical	length_ofmxmmxvrot_zto_spherical)intersect_line_and_sphere)add_aberrationadd_deflection)Time)Angle	AngleRateDistanceVelocity_interpret_anglegW1sBNc                 V    |dk(  rt         }n|dk(  rt        }nt        } || ||||      S )Nr     )Barycentric
GeocentricICRF)position_auvelocity_au_per_dtcentertargetclss         X/home/cursorai/projects/iching/venv/lib/python3.12/site-packages/skyfield/positionlib.pybuild_positionr5      s3    {	3{-q&&AA    c                     t        |      dz  t        z  }t        |       dz  t        z  }t        |||      }	|t        |j                  |	      }	t        |	d|||      S )a   Build a position object from a right ascension and declination.

    If a specific ``distance_au`` is not provided, Skyfield returns a
    position vector a gigaparsec in length.  This puts the position at a
    great enough distance that it will stand at the same right ascension
    and declination from any viewing position in the Solar System, to
    very high precision (within a few hundredths of a microarcsecond).

    If an ``epoch`` is specified, the input coordinates are understood
    to be in the dynamical system of that particular date.  Otherwise,
    they will be assumed to be ICRS (the modern replacement for J2000).

    .. versionadded:: 1.21
       This replaces a deprecated function ``position_from_radec()``
       whose ``distance`` argument was not as well designed.

         v@      8@N)r   r   r   r   MTr5   )
ra_hoursdec_degreesdistance_auepochr0   r1   r2   thetaphir.   s
             r4   position_of_radecrA      sc    & k"U*S0E
H

$s
*C eS9K%((K0+tQ??r6   c           	      $    t        | ||||||      S )uo  DEPRECATED version of ``position_of_radec()``.

    Problems:

    * The ``distance`` parameter specifies no unit, contrary to Skyfield
      best practices.  I have no idea what I was thinking.

    * The default ``distance`` is far too small, since most objects for
      which users specify an RA and declination are out on the celestial
      sphere.  The hope was that users would see the length 1.0 and
      think, “ah, yes, that’s obviously a fake placeholder value.”  But
      it’s more likely that users will not even check the distance, or
      maybe not even realize that a distance is involved.

    )rA   )r;   r<   distancer>   r0   r1   r2   s          r4   position_from_radecrD   8   s     " X{He0 0r6   c                   @   e Zd ZdZdZdZdZdZ	 	 d%dZe	e
dfd       Ze	d        Zd Zd Zd Zd	 Zd
 Zd Zed        Zd&dZd Zd'dZd Zd Zd Zd&dZd Zd&dZd Zd ZeZ eZ!d Z"d Z#d Z$d Z%d&dZ&d Z'd Z(d Z)d  Z*ed!        Z+dddd e,d"#      fd$Z-y)(r-   a  An |xyz| position and velocity oriented to the ICRF axes.

    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 |xyz| coordinates along the axes
    of the ICRF.  A specific time ``.t`` might be specified or might be
    ``None``.

    Nc                    || _         t        |      x| _        | _        |.t	        | j                  j
                  j                  t              }t        |      | _	        || j                  n|| _        || _        |dk(  r| | _        y y )Nr   )r0   r&   positionxyzr   aushaper   r'   velocity_default_centerr1   r2   center_barycentric)selfr.   r/   r0   r1   r2   s         r4   __init__zICRF.__init___   sz    #+K#88$ $T]]%5%5%;%;S A !23.4nd**&Q;&*D# r6   c                     t        |      dz  t        z  }t        |      dz  t        z  }t        |||      }|t        |j                  |      } | |      S )Nr8   r9   )r   r   r   r   r:   )r3   r;   r<   r=   r>   r?   r@   r.   s           r4   
from_radeczICRF.from_radeck   s[     +&.4!D(3.$[%=ehh4K;r6   c                     |j                   |j                  }}t        |dd      }| ||      }|t        ||      z
  }t	        |j                  |            }	t        |	|      }t        |	|      } | |||      S )uw  Constructor: build a position from two vectors in a reference frame.

        * ``t`` — The :class:`~skyfield.timelib.Time` of the position.
        * ``frame`` — A reference frame listed at `reference_frames`.
        * ``distance`` — A `Distance` |xyz| vector in the given frame.
        * ``velocity`` — A `Velocity` ẋ,ẏ,ż vector in the given frame.

        _dRdt_times_RT_atN)rI   au_per_dgetattrr   r   rotation_at)
r3   r0   framerC   rK   rvatVRTs
             r4   from_time_and_frame_vectorsz ICRF.from_time_and_frame_vectorsu   s|     {{H--1U/6>1AC1IA!!!$%AJAJ1a|r6   c           
         | j                   j                  }| j                  }|dk(  r|dk(  rd}n|dk(  r|dk(  rd}n
|dk7  rd}nd	}| j                  }| j                  }t	        |d
d       }|t        |      }t	        |d
d       }|t        |      }dj                  ||| j                  d	nd| j                  d	nd| j                  d	ndj                  |      | j                  d	      S dj                  |            S )Nr+   r   z BCRSApparentr*   z GCRSr-   z ICRS target_namez<{0}{1} position{2}{3}{4}{5}>z and velocityz
 at date tz center={0}z target={0})		__class____name__r1   r2   rU   strformatrK   r0   )rN   namer1   suffixr2   center_namera   s          r4   __repr__zICRF.__repr__   s   ~~&&= Vq[FZFcMFV^FFfmT:f+KfmT:f+K.55==(B&&.Bl++%B=+?+?+L++%B
 	
 ,9+?+?+L
 	
r6   c                 F   | j                   j                  |j                   j                  z
  }| j                  |j                  d}n-| j                  j                  |j                  j                  z
  }t	        ||| j
                  |j                  | j                        S )z-Subtract two ICRF vectors to produce a third.N)rG   rI   rK   rT   r5   r0   r2   )rN   bodyprY   s       r4   __sub__zICRF.__sub__   su    MMt}}///== DMM$9A&&)?)??AaDFFDKKEEr6   c                      t        |       | j                  j                  d d |f   | j                  j                  d d |f   | j
                  |   | j                  | j                        S N)typerG   rI   rK   rT   r0   r1   r2   )rN   is     r4   __getitem__zICRF.__getitem__   sZ    tDzMMQqS!MM""1Q3'FF1IKKKK
 	
r6   c                      t        |       | j                  j                   | j                  j                   | j
                  | j                  | j                        S ro   )rp   rG   rI   rK   rT   r0   r2   r1   rN   s    r4   __neg__zICRF.__neg__   sJ    tDz]]]]###FFKKKK
 	
r6   c                 R    t        t        | j                  j                              S )a  Compute the distance from the origin to this position.

        The return value is a :class:`~skyfield.units.Distance` that
        prints itself out in astronomical units (au) but that also
        offers attributes ``au``, ``km``, and ``m`` if you want to
        access its magnitude as a number.

        >>> v = ICRF([1, 1, 0])
        >>> print(v.distance())
        1.41421 au

        )r&   r   rG   rI   rt   s    r4   rC   zICRF.distance   s     	$--"2"2344r6   c                 R    t        t        | j                  j                              S )zCompute the magnitude of the velocity vector.

        >>> v = ICRF([0, 0, 0], [1, 2, 3])
        >>> print(v.speed())
        3.74166 au/day

        )r'   r   rK   rT   rt   s    r4   speedz
ICRF.speed   s     	$--"8"89::r6   c                 R    | j                         j                  t        z  t        z  S )z3Length of this vector in days of light travel time.)rC   mr   r   rt   s    r4   
light_timezICRF.light_time   s      }}  1$u,,r6   c                 \   | j                   j                  }|bt        |t              rn;t        |t              rt        d|      }n|dk(  r| j
                  }nt        d      t        |j                  |      }t        |      \  }}}t        |d      t        |d      t        |      fS )	a  Compute equatorial RA, declination, and distance.

        When called without a parameter, this returns standard ICRF
        right ascension and declination:

        >>> from skyfield.api import load
        >>> ts = load.timescale()
        >>> t = ts.utc(2020, 5, 13, 10, 32)
        >>> eph = load('de421.bsp')
        >>> astrometric = eph['earth'].at(t).observe(eph['sun'])
        >>> ra, dec, distance = astrometric.radec()
        >>> print(ra, dec, sep='\n')
        03h 21m 47.67s
        +18deg 28' 55.3"

        If you instead want the coordinates referenced to the dynamical
        system defined by the Earth's true equator and equinox, provide
        a specific epoch time.

        >>> ra, dec, distance = astrometric.apparent().radec(epoch='date')
        >>> print(ra, dec, sep='\n')
        03h 22m 54.73s
        +18deg 33' 04.5"

        To get J2000.0 coordinates, simply pass ``ts.J2000``.

        Nttdatepthe epoch= must be a Time object, a floating point Terrestrial Time (TT), or the string "date" for epoch-of-datehoursradians
preferenceTr   signed)rG   rI   
isinstancer#   floatr0   
ValueErrorr   Mr   r$   r&   )rN   r>   r.   r_audecras         r4   radecz
ICRF.radec   s    8 mm&&%&E5)Te,&  "K L L egg{3K$[1c2bW5c$/  	 r6   c                    t         j                  j                  | j                        }t	        || j
                  j                        }t        |      \  }}}t        | j                  dd      }|t        t              |j                  |z
  }|t        z  }|t        z  }|t        z  }t        |dd      t        |d      t!        |      fS )uz  Compute hour angle, declination, and distance.

        Returns a tuple of two :class:`~skyfield.units.Angle` objects
        plus the :class:`~skyfield.units.Distance` to the target.  The
        angles are the hour angle (±12 hours) east or west of your
        meridian along the ITRS celestial equator, and the declination
        (±90 degees) above or below it.  This only works for positions
        whose center is a geographic location; otherwise, there is no
        local meridian from which to measure the hour angle.

        Because this declination is measured from the plane of the
        Earth’s physical geographic equator, it will be slightly
        different than the declination returned by ``radec()`` if you
        have loaded a :ref:`polar motion` file.

        The coordinates are not adjusted for atmospheric refraction near
        the horizon.

        	longitudeNr   T)r   r   r   r   )r   itrsrV   r0   r   rG   rI   r   rU   r1   r   _hadec_messager   r   r   r$   r&   )rN   RrX   rI   r   sublongtiudelonhas           r4   hadecz
ICRF.hadec  s    ( MM%%dff-4==##$ ,QCdkk;5;^,,[[<'
b
c	
bbWTBc$/ 	r6   c                     t        | ||      S )u  Compute (alt, az, distance) relative to the observer's horizon

        The altitude returned is an :class:`~skyfield.units.Angle`
        measured in degrees above the horizon, while the azimuth
        :class:`~skyfield.units.Angle` measures east along the horizon
        from geographic north (so 0 degrees means north, 90 is east, 180
        is south, and 270 is west).

        By default, Skyfield does not adjust the altitude for
        atmospheric refraction.  If you want Skyfield to estimate how
        high the atmosphere might lift the body's image, give the
        argument ``temperature_C`` either the temperature in degrees
        centigrade, or the string ``'standard'`` (in which case 10°C is
        used).

        When calculating refraction, Skyfield uses the observer’s
        elevation above sea level to estimate the atmospheric pressure.
        If you want to override that value, simply provide a number
        through the ``pressure_mbar`` parameter.

        )	_to_altaz)rN   temperature_Cpressure_mbars      r4   altazz
ICRF.altaz7  s    , }m<<r6   c                 ^   | j                   j                  }|j                   j                  }t        |j                        t        |j                        z
  }|r?|dkD  rt	        ||j                  d|z  z         }nt	        ||j                  d| z  z         }t        t        ||            S )a  Return the angle between this position and another.

        >>> from skyfield.api import load
        >>> ts = load.timescale()
        >>> t = ts.utc(2020, 4, 18)
        >>> eph = load('de421.bsp')
        >>> sun, venus, earth = eph['sun'], eph['venus'], eph['earth']
        >>> e = earth.at(t)
        >>> s = e.observe(sun)
        >>> v = e.observe(venus)
        >>> print(s.separation_from(v))
        43deg 23' 23.1"

        You can also compute separations across an array of positions.

        >>> t = ts.utc(2020, 4, [18, 19, 20])
        >>> e = earth.at(t)
        >>> print(e.observe(sun).separation_from(e.observe(venus)))
        3 values from 43deg 23' 23.1" to 42deg 49' 46.6"

        r   r
   r   )rG   rI   lenrJ   r   r$   r   )rN   another_icrfurY   
differences        r4   separation_fromzICRF.separation_fromO  s    , MM!!$$ \CL0
A~Aqww
)::;Aqww);;<]1a011r6   c                    t        |t              rn;t        |t              rt        d|      }n|dk(  r| j                  }nt	        d      t        |j                  | j                  j                        }t        |      S )aO  Compute cartesian CIRS coordinates at a given epoch |xyz|.

        Calculate coordinates in the Celestial Intermediate Reference System
        (CIRS), a dynamical coordinate system referenced to the Celestial
        Intermediate Origin (CIO). As this is a dynamical system it must be
        calculated at a specific epoch.
        Nr}   r   r   )
r   r#   r   r0   r   r   r   rG   rI   r&   )rN   r>   vectors      r4   cirs_xyzzICRF.cirs_xyzu  ss     eT"u%%(Ef_FFE G H H UWWdmm../r6   c                     t        | j                  |      j                        \  }}}t        |d      t        |d      t	        |      fS )aY  Get spherical CIRS coordinates at a given epoch (ra, dec, distance).

        Calculate coordinates in the Celestial Intermediate Reference System
        (CIRS), a dynamical coordinate system referenced to the Celestial
        Intermediate Origin (CIO). As this is a dynamical system it must be
        calculated at a specific epoch.
        r   r   Tr   )r   r   rI   r$   r&   )rN   r>   r   r   r   s        r4   
cirs_radeczICRF.cirs_radec  sH     %T]]5%9%<%<=c2bW5c$/  	 r6   c                     || j                  t        j                        S t        | |      j                  t        j                        S ro   )	frame_xyzr   ecliptic_J2000_frame_Fakeecliptic_framerN   r>   s     r4   ecliptic_xyzzICRF.ecliptic_xyz  s:    =>>("?"?@@T5!++H,C,CDDr6   c                 F    | j                  t        j                        d   S )Nr
   )frame_xyz_and_velocityr   r   rt   s    r4   ecliptic_velocityzICRF.ecliptic_velocity  s    **8+H+HI!LLr6   c                     || j                  t        j                        S t        | |      j                  t        j                        S ro   )frame_latlonr   r   r   r   r   s     r4   ecliptic_latlonzICRF.ecliptic_latlon  s<    =$$X%B%BCCT5!..x/F/FGGr6   c                 @    | j                  t        j                        S ro   )r   r   galactic_framert   s    r4   galactic_xyzzICRF.galactic_xyz  s    4>>(2I2I#JJr6   c                 @    | j                  t        j                        S ro   )r   r   r   rt   s    r4   galactic_latlonzICRF.galactic_latlon  s    d&7&78O8O&PPr6   c                     t        t        |j                  | j                        | j                  j
                              S )zReturn this position as an |xyz| vector in a reference frame.

        Returns a :class:`~skyfield.units.Distance` object giving the
        |xyz| of this position in the given ``frame``.  See
        `reference_frames`.

        )r&   r   rV   r0   rG   rI   )rN   rW   s     r4   r   zICRF.frame_xyz  s/     E--dff5t}}7G7GHIIr6   c                 L   |j                  | j                        }| j                  j                  | j                  j
                  }}t        ||      }t        ||      }t        |dd      }|! || j                        }|t        ||      z  }t        |      t        |      fS )aE  Return |xyz| position and velocity vectors in a reference frame.

        Returns two vectors in the given coordinate ``frame``: a
        :class:`~skyfield.units.Distance` providing an |xyz| position
        and a :class:`~skyfield.units.Velocity` giving (xdot,ydot,zdot)
        velocity.  See `reference_frames`.

        rS   N)
rV   r0   rG   rI   rK   rT   r   rU   r&   r'   )rN   rW   r   rX   rY   rZ   r[   s          r4   r   zICRF.frame_xyz_and_velocity  s     dff%}}!7!711I1IU/6>466
AQNA{HQK''r6   c                     t        |j                  | j                        | j                  j                        }t        |      \  }}}t        |d      t        |      t        |      fS )a*  Return longitude, latitude, and distance in the given frame.

        Returns a 3-element tuple giving the latitude and longitude as
        :class:`~skyfield.units.Angle` objects and the range to the
        target as a :class:`~skyfield.units.Distance`.  See
        `reference_frames`.

        Tr   r   )r   rV   r0   rG   rI   r   r$   r&   )rN   rW   r   dlatr   s         r4   r   zICRF.frame_latlon  s\     U&&tvv.0@0@A"6*3c$/c" 	r6   c                 *   | j                  |      \  }}|j                  }|j                  }t        ||      \  }}}}}}	t	        |d      t	        |      t        |      t        j                  |      t        j                  |	      t        |      fS )u  Return a reference frame longitude, latitude, range, and rates.

        Return a 6-element tuple of 3 coordinates and 3 rates-of-change
        for this position in the given reference ``frame``:

        * Latitude :class:`~skyfield.units.Angle` from +90° north to −90° south
        * Longitude :class:`~skyfield.units.Angle` 0°–360° east
        * Radial :class:`~skyfield.units.Distance`
        * Latitude :class:`~skyfield.units.AngleRate`
        * Longitude :class:`~skyfield.units.AngleRate`
        * Radial :class:`~skyfield.units.Velocity`

        If the reference frame is the ICRS, or is J2000, or otherwise
        involves the celestial equator and pole, then the latitude and
        longitude returned will measure what are more commonly called
        “declination” and “right ascension”.  Note that right ascension
        is usually expressed as hours (24 in a circle), rather than in
        the degrees that this routine will return.

        Tr   r   )	r   rI   rT   r   r$   r&   r%   _from_radians_per_dayr'   )
rN   rW   rX   rY   r   r   r   d_ratelat_ratelon_rates
             r4   frame_latlon_and_rateszICRF.frame_latlon_and_rates  s    * **511DDJJ2I!Q2O/3VXxc$/c"//9//9 " 	"r6   c                 D   ddl m} ddlm} | j                  dk(  rd}n[| j                  dk(  r(ddl m}  || j                  j                               }n$t        dj                  | j                              | j                  j                  \  }}} ||d	||||
      S )zConvert this distance to an AstroPy ``SkyCoord`` object.

        Currently, this will only work with Skyfield positions whose
        center is the Solar System barycenter or else the geocenter.

        r   )SkyCoordrI   icrsr*   )GCRS)obstimezSkyfield can only return AstroPy positions for barycentric and geocentric coordinates; if you are interested in adding support for positions whose center={}, please open an issue	cartesian)rW   representation_typeunitxyz)astropy.coordinatesr   astropy.unitsrI   r1   r   r0   
to_astropyNotImplementedErrorre   rG   )	rN   r   r   rI   rW   r   r   r   r   s	            r4   to_skycoordzICRF.to_skycoord  s     	1$;;!E[[C0!2!2!45E%O $	  --""1ae1Q0 	0r6   c                    |j                  | j                        }| j                  j                  }||j                  j                  z
  | j                  j                  j                  z   }t        t        ||            S )uB  Return this position’s phase angle: the angle Sun-target-observer.

        Given a Sun object (which you can build by loading an ephemeris
        and looking up ``eph['Sun']``), return the `Angle` from the
        body's point of view between light arriving from the Sun and the
        light departing toward the observer.  This angle is 0° if the
        observer is in the same direction as the Sun and sees the body
        as fully illuminated, and 180° if the observer is behind the
        body and sees only its dark side.

        .. versionadded:: 1.42

        r   )rZ   r0   rG   rI   rM   r$   r   )rN   sunsr   rY   s        r4   phase_anglezICRF.phase_angle  s_      FF466NMM

 7 7 @ @ C CC]1a011r6   c                 Z    | j                  |      j                  }ddt        |      z   z  S )uj  Return the fraction of the target’s disc that is illuminated.

        Given a Sun object (which you can build by loading an ephemeris
        and looking up ``eph['Sun']``), compute what fraction from 0.0
        to 1.0 of this target’s disc is illuminated, under the
        assumption that the target is a sphere.

        .. versionadded:: 1.42

        g      ?      ?)r   r   r   )rN   r   as      r4   fraction_illuminatedzICRF.fraction_illuminated)  s-     S!))cCFl##r6   c                 ~   | j                   dk(  r| j                  j                   }n:| j                  }|t	        d      | j                  j                   |t
        z  z
  }|d   |d   z
  j                  | j                        j                  j                  }t        ||z   |t              \  }}t        |      dk  S )u  Return whether a position in Earth orbit is in sunlight.

        Returns ``True`` or ``False``, or an array of such values, to
        indicate whether this position is in sunlight or is blocked by
        the Earth’s shadow.  It should work with positions produced
        either by calling ``at()`` on a satellite object, or by calling
        ``at()`` on the relative position ``sat - topos`` of a satellite
        with respect to an Earth observer’s position.  See
        :ref:`satellite-is-sunlit`.

        r*   z+cannot tell whether this position is sunlitr   earthr   )r1   rG   rz   _observer_gcrs_aur   r   rZ   r0   r    r   r	   )rN   	ephemerisearth_mgcrs_positionsun_mnearfars          r4   	is_sunlitzICRF.is_sunlit7  s     ;;#'G 22M$ !NOO'-$*>>G5!Ig$66::466BKKMM-egowM	c#!##r6   c                     | j                   }|t        d      | t        z  }| j                  j                  }t        ||t              \  }}t        |      }t        |      dkD  t        |      |k  z  S )zReturn whether the Earth blocks the view of this object.

        For a position centered on an Earth-orbiting satellite, return
        whether the target is in eclipse behind the disc of the Earth.
        See :ref:`is-behind-earth`.

        zQcan only compute Earth occultation for positions observed from an Earth satelliter   )	r   r   r   rG   rz   r    r   r   r	   )rN   observer_gcrs_aur   vector_mr   r   length_ms          r4   is_behind_earthzICRF.is_behind_earthO  s      11# K L L$$t+==??-hF	cX&3!#
4(88(CDDr6   c                 v    t        | j                  dd       }|t        t               || j                        S )NrV   )rU   r2   r   _altaz_messager0   )rN   rV   s     r4   _altaz_rotationzICRF._altaz_rotationa  s6    
 dkk=$?^,,466""r6   g?r   c                    t        | j                  dd      }|t        t               || j                        }t        d||      }t        d||      }|j                  }t        |||      }	t        d||	      }	t        |	      S )a:  Generate an Apparent position from an altitude and azimuth.

        The altitude and azimuth can each be provided as an `Angle`
        object, or else as a number of degrees provided as either a
        float or a tuple of degrees, arcminutes, and arcseconds::

            alt=Angle(...), az=Angle(...)
            alt_degrees=23.2289, az_degrees=142.1161
            alt_degrees=(23, 13, 44.1), az_degrees=(142, 6, 58.1)

        The distance should be a :class:`~skyfield.units.Distance`
        object, if provided; otherwise a default of 0.1 au is used.

        rV   Naltazzji...,j...->i...)
rU   r2   r   r   r0   r(   rI   r   r   r_   )
rN   r   r   alt_degrees
az_degreesrC   rV   r   rX   rl   s
             r4   
from_altazzICRF.from_altazk  s    $ dkk=$?^,,uc;7dB
3KK1c2&%q!,{r6   NNNNro   )Nstandard).rc   
__module____qualname____doc__rM   r   rL   
_ephemerisrO   classmethod_GIGAPARSEC_AUrQ   r]   ri   rm   rr   ru   rC   rx   r   r{   r   r   r   r   r   r   r   r   r   r   r   ecliptic_positiongalactic_positionr   r   r   r   r   r   r   r   r   r   r&   r    r6   r4   r-   r-   L   s/    OJ>B%)
+ -T     &
@F

5; - -, \ D=0"2L , "EMH
 KP$$J(&"@042*$$0E$ # # "d$,r6   r-   c                       e Zd ZdZy)	Geometrica  An |xyz| vector between two instantaneous position.

    A geometric position is the difference between the Solar System
    positions of two bodies at exactly the same instant.  It is *not*
    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 |xyz| vectors
    oriented along the axes of the International Celestial Reference
    System (ICRS), the modern replacement for J2000 coordinates.

    Nrc   r   r   r   r  r6   r4   r  r    s    r6   r  c                       e Zd ZdZdZd Zy)r+   uT  An |xyz| position measured from the Solar System barycenter.

    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 BCRS position and velocity at date t center=0 target=499>

    This class’s ``.position`` and ``.velocity`` are |xyz| vectors in
    the Barycentric Celestial Reference System (BCRS), the modern
    replacement for J2000 coordinates measured from the Solar System
    Barycenter.

    r   c                     |j                  |       \  }}}}t        |||| j                  |j                        }| j                  |_        | |_        ||_        |S )a  Compute the `Astrometric` position of a body from this location.

        To compute the body's astrometric position, it is first asked
        for its position at the time `t` of this position itself.  The
        distance to the body is then divided by the speed of light to
        find how long it takes its light to arrive.  Finally, the light
        travel time is subtracted from `t` and the body is asked for a
        series of increasingly exact positions to learn where it was
        when it emitted the light that is now reaching this position.

        >>> earth.at(t).observe(mars)
        <Astrometric ICRS position and velocity at date t center=399 target=499>

        )_observe_from_bcrsAstrometricr2   r   rM   r{   )rN   rk   rl   rY   r0   r{   astrometrics          r4   observezBarycentric.observe  sY     #55d;1a!!Q4;;D!%)-&!+r6   N)rc   r   r   r   rL   r  r  r6   r4   r+   r+     s      Or6   r+   c                       e Zd ZdZd Zd Zy)r	  a  An astrometric |xyz| position relative to a particular observer.

    The astrometric position of a body is its position relative to an
    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 eye or telescope.  Astrometric positions are
    usually generated in Skyfield by calling the `Barycentric` method
    `observe()`, which performs the light-time correction.

    Both the ``.position`` and ``.velocity`` are |xyz| vectors
    oriented along the axes of the ICRF, the modern replacement for the
    J2000 reference frame.

    It is common to either call ``.radec()`` (with no argument) on an
    astrometric position to generate an *astrometric place* right
    ascension and declination with respect to the ICRF axes, or else to
    call ``.apparent()`` to generate an :class:`Apparent` position.

    c                     t        d      )Nzwit is not useful to call .altaz() on an astrometric position; try calling .apparent() first to get an apparent position)r   rt   s    r4   r   zAstrometric.altaz  s    I
 	
r6   c                    | j                   }| j                  j                  j                         }| j                  }|j                  j                  }|j
                  j                  }|j                  }t        |j                        t        |j                        k  rD|j                  dz   }|j                  |      }|j                  |      }||j                  |      }|t        d      }nt        ||      \  }	}
|
dk\  }t        ||| j                  ||       t        ||| j                          | j
                  j                  }|	 t#        |||| j$                  | j&                        }| j                  |_        ||_        |S )a  Compute an :class:`Apparent` position for this body.

        This applies two effects to the position that arise from
        relativity and shift slightly where the other body will appear
        in the sky: the deflection that the image will experience if its
        light passes close to large masses in the Solar System, and the
        aberration of light caused by the observer's own velocity.

        >>> earth.at(t).observe(mars).apparent()
        <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
        of the observer.  In the specific case of an Earth observer, the
        output reference frame is the GCRS.

        r   Fg?)r0   rG   rI   copyrM   rK   rT   r   r   rJ   r   r   r   r"   r   r!   r{   r_   r1   r2   )rN   r0   	target_aucbbcrs_positionbcrs_velocityr   rJ   include_earth_deflection
limb_anglenadir_anglerY   apparents                r4   r  zAstrometric.apparent  sd   $ FFMM$$))+	$$,,// }""#c)//&::!''$.E)11%8M)11%8M+#3#;#;E#B #',X$&8+'-#J'2c'9$y-+C	E 	y-AMM""=Iq!T[[$++F&*&=&=#%5"r6   N)rc   r   r   r   r   r  r  r6   r4   r	  r	    s    &
8r6   r	  c                       e Zd ZdZy)r_   u  An apparent |xyz| position relative to a particular observer.

    This class’s vectors provide the position and velocity of a body
    relative to an observer, adjusted to predict where the body’s image
    will really appear (hence "apparent") in the sky:

    * Light-time delay, as already present in an `Astrometric` position.

    * Deflection: gravity bends light, and thus the image of a distant
      object, as the light passes massive objects like Jupiter, Saturn,
      and the Sun.  For an observer on the Earth’s surface or in Earth
      orbit, the slight deflection by the gravity of the Earth itself is
      also included.

    * Aberration: incoming light arrives slanted because of the
      observer's motion through space.

    These positions are usually produced in Skyfield by calling the
    `apparent()` method of an `Astrometric` object.

    Both the ``.position`` and ``.velocity`` are |xyz| vectors
    oriented along the axes of the ICRF, the modern replacement for the
    J2000 reference frame.  If the observer is at the geocenter, they
    are more specifically GCRS coordinates.  Two common coordinates that
    this vector can generate are:

    * *Proper place:* call ``.radec()`` without arguments to compute
      right ascension and declination with respect to the fixed axes of
      the ICRF.

    * *Apparent place,* the most popular option: call ``.radec('date')``
      to generate right ascension and declination with respect to the
      equator and equinox of date.

    Nr  r  r6   r4   r_   r_     s    "r6   r_   c                        e Zd ZdZdZd Zd Zy)r,   a,  An |xyz| 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 |xyz| axes that
    are those of the Geocentric Celestial Reference System (GCRS), an
    inertial system that is an update to J2000 and that does not rotate
    with the Earth itself.

    r*   c                 @    | j                  t        j                        S )zODeprecated; instead, call ``.frame_xyz(itrs)``.         See `reference_frames`.)r   r   r   rt   s    r4   itrf_xyzzGeocentric.itrf_xyzP  s     ~~hmm,,r6   c                 0    ddl m} |j                  |       S )z_Deprecated; instead, call either ``iers2010.subpoint(pos)`` or         ``wgs84.subpoint(pos)``.r
   )iers2010)toposlibr  subpoint)rN   r  s     r4   r   zGeocentric.subpointU  s     	'  &&r6   N)rc   r   r   r   rL   r  r   r  r6   r4   r,   r,   @  s     O-
'r6   r,   c                    | j                   }||j                  }n:t        | j                  d      }| || j                        }nt        t              t        || j                  j                        }t        |      \  }}}	|t        |      }nLt        | j                  dd      }
|
t        t              | j                  j                  |t        z  ||      }|t        |	      t        |      fS )z?Compute (alt, az, distance) relative to the observer's horizon.NrV   r   refract)rM   r   rU   r1   r0   r   r   r   rG   rI   r   r$   r"  r   r&   )rG   r   r   r  r   rV   r.   r   r   r   r"  s              r4   r   r   [  s    		$	$B	~hoo}="HJJ'A^,,a**--.K -MD#rC (//9d;?^,,oo%%'M=-
 b!8D>11r6   ue   to compute a body’s hour angle, you must observe it from a specific latitude and longitude on Earthzto compute altitude and azimuth, you must observe it from a specific latitude and longitude on Earth, or else from a location on another Solar System body that you have loaded from a set of planetary constantsc                       e Zd Zd Zy)r   c                     |j                   | _         t        |t              r|| _        y t        |t              rt        d |      | _        y |dk(  r|j                  | _        y t        d      )Nr}   r   r   )rG   r   r#   r0   r   r   )rN   originalr>   s      r4   rO   z_Fake.__init__  s_     ))eT"DFu%$5)DFf_ZZDF G H Hr6   N)rc   r   r   rO   r  r6   r4   r   r     s    Hr6   r   c                 f    t        t        t        j                  j	                  |             |      S ro   )r   r   r   r   rV   )r0   rITRFs     r4   ITRF_to_GCRSr(    s#    r(--++A./77r6   c                    t        |      }t        |      }|r`dt        z  }| j                  j                  | j                  | j
                  |z         }|j                  | j                  z
  dz  t        z  }nt        }t        | j                  dz  t        z        }	t        | j                  |	      }
d|z  }t        |t         |z  |ft        |z  ||f|||ff      }|t        ||      z   }t        |
|      }t        |
|      }||fS )Nr   r9   g        )r   r   tstt_jdwholett_fractiongastr   r   r   r   r:   r   )r0   r'  vITRF_high_accuracyrG   rK   _one_secondt_laterangvelspinr   r   r[   s                r4   ITRF_to_GCRS2r5    s    U|HU|H Ek$$**QWWammk&AB,,'4/#5$$%DADD$AfA	
E6F?1	!	
1Q 	A #a**H1hH1hHXr6   r   )r   NNNNr  )Br   numpyr   r   r   r   r   r   r	   r`   r   	constantsr   r   r   r   r   r   r   r   descriptorlibr   earthlibr   	functionsr   r   r   r   r   r   r   r   r   r   geometryr    
relativityr!   r"   timelibr#   unitsr$   r%   r&   r'   r(   r   r5   rA   rD   objectr-   ICRSr  r+   r	  r_   r,   r   r   r   r   r(  r5  r  r6   r4   <module>rA     s   D D D D  E E E   (   0 6  I I#:>'+B :H Dd@4 DH480({6 {~  '$ 'XR$ Rh#t #J' '6287 
P HD H8!r6   