
    R1iSN                     b   d Z ddlZddlmZmZmZ ddlmZmZm	Z	m
Z
mZ ddlmZ ddlmZmZ dZd	Zd
Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      ZdZ G d de      Z G d de      Z d Z!d%dZ"d  Z#d&d!Z$d" Z%d'd#Z&d$ Z'y)(z<Simple distance, velocity, and angle support for Skyfield.

    N)abscopysignisnan   )AU_KMAU_MCDAY_Stau)reify)	_to_array	length_ofz%{0}{1:02}deg {2:02}' {3:02}.{4:0{5}}"z){0:+>1}{1:02}deg {2:02}' {3:02}.{4:0{5}}"z#{0}{1:02}h {2:02}m {3:02}.{4:0{5}}sc                       e Zd ZdZy)UnpackingErrorz?You cannot iterate directly over a Skyfield measurement object.N)__name__
__module____qualname____doc__     R/home/cursorai/projects/iching/venv/lib/python3.12/site-packages/skyfield/units.pyr   r      s    Ir   r   c                       e Zd ZdZd ZeZy)Unitz?A measurement that can be expressed in several choices of unit.c                 B   | j                   }|j                  }d}t        d |j                  j	                         D              }|D cg c]"  }dj                  |j                         |      $ }}t        |j                  |dj                  |                  c c}w )zATell users to ask for a specific unit before indexing or slicing.z=to use this {0}, ask for its value in a particular unit:

{1}c              3   x   K   | ]2  \  }}|d    j                         rt        |t        t        f      r| 4 yw)r   N)islower
isinstancegetsetr   ).0kvs      r   	<genexpr>z#Unit.__getitem__.<locals>.<genexpr>   s7      M%9TQA$,,.ZFE?-K %9s   8:z    {0}.{1}
)		__class__r   sorted__dict__itemsformatlowerr   join)selfargsclsnamesattrsattrexampless           r   __getitem__zUnit.__getitem__   s    nn||M MS\\%7%7%9 M MINOM((t<OQXXdDIIh,?@AA Ps   	'BN)r   r   r   r   r3   __iter__r   r   r   r   r      s    IB Hr   r   c                        e Zd ZdZddZddZy)r   a`  Unit name that serves as both a class constructor and instance attribute.

    This supports two use cases:

    * When called as a class method like ``Distance.km(5.0)``, we build
      and return an instance of ``Distance`` whose ``km`` has been set
      to 5.0 and whose base unit ``m``, using the appropriate conversion
      factor, has been set to 5000.0.

    * When invoked like ``d.km`` on a particular ``Distance`` that
      doesn't yet have a ``km`` attribute (which otherwise Python itself
      would have returned), we apply the conversion factor to ``d.m``
      and return the result.

    Nc                 <    || _         || _        || _        || _        y N)r.   r   conversion_factor	core_unit)r+   r.   	docstringr8   r9   s        r   __init__zgetset.__init__1   s    	 !2"r   c                      | fd} j                   |_         |S t        | j                         j                  z  }||j                   j
                  <   |S )Nc                     t        |       } j                        }t        |j                  |        j                  }|t        |j
                  | |z         |S r7   )r   __new__setattrr.   r8   r9   )valueobjr8   objtyper+   s      r   constructorz#getset.__get__.<locals>.constructor9   sX    !%(oog.TYY.$($:$:!$0C9J1JK
r   )r   getattrr9   r8   r&   r.   )r+   instancerB   rC   r@   s   ` `  r   __get__zgetset.__get__7   sV     #',,K$..1D4J4JJ',$))$r   NNr7   )r   r   r   r   r;   rF   r   r   r   r   r   !   s    #r   r   c                       e Zd ZdZdZddZed        Z edd      Z	 edd	e
d      Z ed
ded      Zd Zd Zd Zd Zd Zy)Distanceat  A distance, stored internally as au and available in other units.

    You can initialize a ``Distance`` by providing a single float or a
    float array as either an ``au=``, ``km=``, or ``m=`` parameter.

    You can access the magnitude of the distance with its three
    attributes ``.au``, ``.km``, and ``.m``.  By default a distance
    prints itself in astronomical units (au), but you can take control
    of the formatting and choice of units yourself using standard Python
    numeric formatting:

    >>> d = Distance(au=1)
    >>> print(d)
    1.0 au
    >>> print('{:.2f} km'.format(d.km))
    149597870.70 km

    FNc                     |t        |      | _        y |!t        |      x| _        }|t        z  | _        y |!t        |      x| _        }|t
        z  | _        y t        d      )Nz,to construct a Distance provide au, km, or m)r   aukmr   mr   
ValueError)r+   rK   rL   rM   s       r   r;   zDistance.__init__\   sa    >mDG%^$R=(DGb5jDG]"1%DFQ$hDGKLLr   c                 $    | j                  |      S r7   rK   )r-   rK   s     r   from_auzDistance.from_aui   s    vvbzr   rK   uB   Astronomical units (the Earth-Sun distance of 149,597,870,700 m).rL   u   Kilometers (1,000 meters).rM   zMeters.c                 x    | j                   }t        |dd      rdj                  |      S dj                  |      S )Nshaper   z{0} auz	{0:.6} au)rK   rD   r(   )r+   ns     r   __str__zDistance.__str__r   s7    GG#Aw2KKANNKKANNr   c                 L    dj                  t        |       j                  |       S N	<{0} {1}>r(   typer   r+   s    r   __repr__zDistance.__repr__v       !!$t*"5"5t<<r   c                 @    t        t        | j                              S )a@  Compute the length when this is an |xyz| vector.

        The Euclidean vector length of this vector is returned as a new
        :class:`~skyfield.units.Distance` object.

        >>> from skyfield.api import Distance
        >>> d = Distance(au=[1, 1, 0])
        >>> d.length()
        <Distance 1.41421 au>

        rP   )rI   r   rK   r[   s    r   lengthzDistance.lengthy   s     9TWW-..r   c                 (    | j                   t        z  S )z2Return the length of this vector in light seconds.)rM   r	   r[   s    r   light_secondszDistance.light_seconds   s    vvzr   c                 J    ddl m} | j                  |z  j                  |      S )z0Convert this distance to the given AstroPy unit.r   rP   )astropy.unitsrK   to)r+   unitrK   s      r   rd   zDistance.to   s    $"  &&r   )NNN)r   r   r   r   _warnedr;   classmethodrQ   r   rK   r   rL   r   rM   rU   r\   r_   ra   rd   r   r   r   rI   rI   G   sx    $ GM   
 C 
DB	3UD	ABsItT*AO=/'r   rI   c                   x    e Zd ZdZdZddZ edd      Z eddee	z  d      Z
 ed	d
ee	z  d      Zd Zd Zd Zy)VelocityzA velocity, stored internally as au/day and available in other units.

    You can initialize a ``Velocity`` by providing a float or float
    array to its ``au_per_d=`` parameter.

    FNc                     |(t        |      x| _        }|t        z  t        z  | _        y |t        |      | _        y t        d      )Nz4to construct a Velocity provide au_per_d or km_per_s)r   km_per_sr
   r   au_per_drN   )r+   rl   rk   s      r   r;   zVelocity.__init__   sN    '0'::DMH$u,u4DM!%h/DM 5 6 6r   rl   zAstronomical units per day.rk   zKilometers per second.m_per_szMeters per second.c                 ^    | j                   }t        |dd      rdnd}|j                  |      S )NrS   r   z
{0} au/dayz{0:.6} au/day)rl   rD   r(   )r+   rT   fmts      r   rU   zVelocity.__str__   s+    MM%a!4l/zz!}r   c                 L    dj                  t        |       j                  |       S rW   rY   r[   s    r   r\   zVelocity.__repr__   r]   r   c                 T    ddl m}m} | j                  |z  |z  j	                  |      S )z0Convert this velocity to the given AstroPy unit.r   )rK   d)rc   rK   rr   rl   rd   )r+   re   rK   rr   s       r   rd   zVelocity.to   s$    '"Q&**400r   rG   )r   r   r   r   rf   r;   r   rl   r   r
   rk   r   rm   rU   r\   rd   r   r   r   ri   ri      sa     G6 j"?@Hj":emZ1HY 4E\:/G
=1r   ri   c                   p    e Zd ZdZed        Zed        Zed        Zed        Z	ed        Z
ed        Zy)		AngleRatez'The rate at which an angle is changing.c                 "     |        }||_         |S r7   )_radians_per_day)r-   radians_per_dayars      r   _from_radians_per_dayzAngleRate._from_radians_per_day   s    U-	r   c                 @    t         j                  | j                        S )z#:class:`Rate` of change in radians.)Rate_from_per_dayrv   r[   s    r   radianszAngleRate.radians   s     !!$"7"788r   c                 T    t         j                  | j                  t        z  dz        S )z#:class:`Rate` of change in degrees.     v@r{   r|   rv   r   r[   s    r   degreeszAngleRate.degrees   s%     !!$"7"7#"="EFFr   c                 T    t         j                  | j                  t        z  dz        S )z&:class:`Rate` of change in arcminutes.g     @r   r[   s    r   
arcminuteszAngleRate.arcminutes   %     !!$"7"7#"="GHHr   c                 T    t         j                  | j                  t        z  dz        S )z&:class:`Rate` of change in arcseconds.g    3Ar   r[   s    r   
arcsecondszAngleRate.arcseconds   s%     !!$"7"7#"=	"IJJr   c                 T    t         j                  | j                  t        z  dz        S )z+:class:`Rate` of change in milliarcseconds.g    OAr   r[   s    r   maszAngleRate.mas   r   r   N)r   r   r   r   rg   ry   r   r}   r   r   r   r   r   r   r   rt   rt      s    1  
 9 9 G G I I K K I Ir   rt   c                   `    e Zd ZdZed        Zed        Zed        Zed        Z	ed        Z
y)r{   z&Measurement whose denominator is time.c                 "     |        }||_         |S r7   _per_day)r-   per_dayrs      r   r|   zRate._from_per_day   s    E
r   c                     | j                   S )z"Units per day of Terrestrial Time.r   r[   s    r   r   zRate.per_day   s     }}r   c                      | j                   dz  S )z#Units per hour of Terrestrial Time.      8@r   r[   s    r   per_hourzRate.per_hour   s     }}t##r   c                      | j                   dz  S )z%Units per minute of Terrestrial Time.g     @r   r[   s    r   
per_minutezRate.per_minute   s     }}v%%r   c                      | j                   dz  S )z%Units per second of Terrestrial Time.g     @r   r[   s    r   
per_secondzRate.per_second   s     }}w&&r   N)r   r   r   r   rg   r|   r   r   r   r   r   r   r   r   r{   r{      si    0  
   $ $ & & ' 'r   r{   zto instantiate an Angle, try one of:

Angle(angle=another_angle)
Angle(radians=value)
Angle(degrees=value)
Angle(hours=value)

where `value` can be either a Python float, a list of Python floats,
or a NumPy array of floatsc                       e Zd Z	 	 ddZedd       Z edd      Zed        Z	ed        Z
ed        Zed	        Zd
 Zd Zd Zd Zd ZddZddZddefdZddZddZddZd Zy)AngleNc                 v   |1t        |t              st        t              |j                  | _        np|t        |      | _        n]|-t        t        |            x| _        }|dz  t        z  | _        n.|,t        t        |            x| _	        }|dz  t        z  | _        ||n|dnd| _
        || _        y )Nr   r   hoursr   )r   r   rN   _instantiation_instructionsr}   r   _unsexagesimalize_degreesr   _hours
preferencesigned)r+   angler}   r   r   r   r   s          r   r;   zAngle.__init__  s     eU+ !<== ==DL $W-DL &/0A'0J&KKDMG"U?S0DL"+,=e,D"EEDK% 4<#-DL)3)?:+0+< ) 	 r   c                     t        t        |            }| j                  |       }||_        |dz  t        z  |_        d|_        ||_        |S )Nr   r   )r   r   r>   r   r   r}   r   r   )r-   r   r   r+   s       r   from_degreeszAngle.from_degrees   sJ    -g67{{3,#r   r}   u%   Radians (𝜏 = 2𝜋 in a circle).c                 .    | j                   dz  t        z  S )Nr   r}   r   r[   s    r   r   zAngle._hours,  s    ||d"S((r   c                 .    | j                   dz  t        z  S )Nr   r   r[   s    r   r   zAngle._degrees0  s    ||e#c))r   c                 N    | j                   dk7  rt        d      | j                  S )zHours (24\ |h| in a circle).r   )r   WrongUnitErrorr   r[   s    r   r   zAngle.hours4  s%     ??g% )){{r   c                 N    | j                   dk7  rt        d      | j                  S )u   Degrees (360° in a circle).r   )r   r   r   r[   s    r   r   zAngle.degrees;  s%     ??i' ++}}r   c                      | j                   dz  S )zReturn the angle in arcminutes.      N@r   r[   s    r   r   zAngle.arcminutesB  s    }}t##r   c                      | j                   dz  S )zReturn the angle in arcseconds.      @r   r[   s    r   r   zAngle.arcsecondsF  s    }}v%%r   c                      | j                   dz  S )z$Return the angle in milliarcseconds.g    @wKAr   r[   s    r   r   z	Angle.masJ  s    }}y((r   c           	         | j                   j                  }|dk(  ry| j                  dk(  r;| j                  }| j                  rt
        j                  nt        j                  }d}n| j                  }t        j                  }d}|dk\  r8dj                  t        |      t        ||d   |      t        ||d   |            S t        |||      S )Nr   zAngle []r   r      z{0} values from {1} to {2})r}   sizer   r   r   _dsgnr(   _dfmtr   _hfmtlen_sfmt)r+   r   r!   ro   placess        r   rU   zAngle.__str__N  s    ||  19??i'A"&++%,,5<<CFA,,CF19/66Ac1Q40%QrUF2KM MS!V$$r   c                     | j                   j                  dk(  r$dj                  t        |       j                        S dj                  t        |       j                  |       S )Nr   z<{0} []>rX   )r}   r   r(   rZ   r   r[   s    r   r\   zAngle.__repr___  sL    <<!$$T$Z%8%899%%d4j&9&94@@r   Tc                     |r| j                   dk7  rt        d      t        | j                        \  }}}}||z  ||z  ||z  fS )zConvert to a tuple (hours, minutes, seconds).

        All three quantities will have the same sign as the angle itself.

        r   hmsr   r   _sexagesimalize_to_floatr   r+   warnsignunitsminutessecondss         r   r   z	Angle.hmse  sM     DOOw. ''(@(M%eWge|TG^TG^;;r   c                 d    |r| j                   dk7  rt        d      t        | j                        S )zConvert to a tuple (sign, hours, minutes, seconds).

        The ``sign`` will be either +1 or -1, and the other quantities
        will all be positive.

        r   
signed_hmsr   r+   r   s     r   r   zAngle.signed_hmsp  s,     DOOw. ..'44r   r   c                     |r| j                   dk7  rt        d      | j                  }t        |dd      }|j                  }|r|D cg c]  }t        |||       c}S t        |||      S c c}w )zReturn a string like ``12h 07m 30.00s``; see `Formatting angles`.

        .. versionadded:: 1.39

           Added the ``format=`` parameter.

        r   hstrrS   r   )r   r   r   rD   r(   r   )r+   r   r   r(   r   rS   ro   hs           r   r   z
Angle.hstr{  sr     DOOw. ((w+mm3895aE#q&)599S%(( :s   A,c                     |r| j                   dk7  rt        d      t        | j                        \  }}}}||z  ||z  ||z  fS )zConvert to a tuple (degrees, minutes, seconds).

        All three quantities will have the same sign as the angle itself.

        r   dmsr   r   r   r   r   s         r   r   z	Angle.dms  sM     DOOy0 ''(@(O%eWge|TG^TG^;;r   c                 d    |r| j                   dk7  rt        d      t        | j                        S )zConvert to a tuple (sign, degrees, minutes, seconds).

        The ``sign`` will be either +1 or -1, and the other quantities
        will all be positive.

        r   
signed_dmsr   r   s     r   r   zAngle.signed_dms  s,     DOOy0 ..'66r   c                    |r| j                   dk7  rt        d      | j                  }| j                  }||rt        nt
        }|j                  }t        |dd      }|r|D cg c]  }t        |||       c}S t        |||      S c c}w )zReturn a string like ``181deg 52' 30.0"``; see `Formatting angles`.

        .. versionadded:: 1.39

           Added the ``format=`` parameter.

        r   dstrrS   r   )	r   r   r   r   r   r   r(   rD   r   )	r+   r   r   r(   r   r   ro   rS   rr   s	            r   r   z
Angle.dstr  s     DOOy0 ((-->$U%Fmm"-3:;7aE#q&)7;;S'6** <s   $Bc                 J    ddl m} | j                  |z  j                  |      S )z-Convert this angle to the given AstroPy unit.r   )rad)rc   r   r}   rd   astropy.coordinatesr   )r+   re   r   r   s       r   rd   zAngle.to  s    %s"&&t,,r   )NNNNNF)F)T)r   TN)r   r   r   r;   rg   r   r   r}   r   r   r   r   r   r   r   r   rU   r\   r   r   r   r   r   r   r   rd   r   r   r   r   r   	  s    EI).*   Y GHG
) ) * *    $&)%"A	<	5 $u )"	<	7+(1r   r   c                       e Zd Zd Zy)r   c                     |j                  d      sd|v rdnd}|dk(  rdnd}dj                  ||      }||k(  r|dj                  |      z  }n|dj                  |      z  }|f| _        y )Nr   _hr   r   zOthis angle is usually expressed in {0}, not {1}; if you want to use {1} anyway,z# then please use the attribute _{0}z  then call {0}() with warn=False)
startswithr(   r,   )r+   r.   re   usualmessages        r   r;   zWrongUnitError.__init__  sz    ??3/44<wi I-I55;VE45H 	4<<CCDIIG9@@FFGJ	r   N)r   r   r   r;   r   r   r   r   r     s    	r   r   c                     t        j                  |       }t        |       }t        |dz  d      \  }}t        |d      \  }}||||fS )ap  Decompose `value` into units, minutes, and seconds.

    Note that this routine is not appropriate for displaying a value,
    because rounding to the smallest digit of display is necessary
    before showing a value to the user.  Use `_sexagesimalize_to_int()`
    for data being displayed to the user.

    This routine simply decomposes the floating point `value` into a
    sign (+1.0 or -1.0), units, minutes, and seconds, returning the
    result in a four-element tuple.

    >>> _sexagesimalize_to_float(12.05125)
    (1.0, 12.0, 3.0, 4.5)
    >>> _sexagesimalize_to_float(-12.05125)
    (-1.0, 12.0, 3.0, 4.5)

    r   r   )npr   r   divmod)r@   r   rT   r   r   r   s         r   r   r     sN    $ 775>DE
Aa&j$/GWGT*NE7((r   c                     d|z  }t        |dz  | z  dz   dz        }t        j                  |      }t        t	        |      |      \  }}t        |d      \  }}t        |d      \  }}|||||fS )aR  Decompose `value` into units, minutes, seconds, and second fractions.

    This routine prepares a value for sexagesimal display, with its
    seconds fraction expressed as an integer with `places` digits.  The
    result is a tuple of five integers:

    ``(sign [either +1 or -1], units, minutes, seconds, second_fractions)``

    The integers are properly rounded per astronomical convention so
    that, for example, given ``places=3`` the result tuple ``(1, 11, 22,
    33, 444)`` means that the input was closer to 11u 22' 33.444" than
    to either 33.443" or 33.445" in its value.

    
   i  g      ?      ?<   )intr   r   r   r   )r@   r   powerrT   r   fractionr   r   s           r   _sexagesimalize_to_intr     sz     &LEUT\E!C'C/0A771:DQ'KAx2JAw2JAwGWh..r   c                 j    t        |      ryt        ||      \  }}}}}|dk  rdnd} | ||||||      S )z>Decompose floating point `value` into sexagesimal, and format.nan        - )r   r   )	ro   r@   r   sgnr   rM   r/   r   r   s	            r   r   r     sE    U|3E6BCAq()3DtQ1h//r   c                 F    | t        ||       dz  z   t        ||       dz  z   S )zAReturn a quantity expressed with 1/60 minutes and 1/3600 seconds.r   r   )r   )wholer   r   s      r   wmsr     s2    w&-.w&/0 1r   c                     t        | t              r6t        |       }t        |      } d}|D ]  }|dz  }| t	        ||       |z  z  }  | S )a,  Return `value` after interpreting a (units, minutes, seconds) tuple.

    When `value` is not a tuple, it is simply returned.

    >>> _unsexagesimalize(3.25)
    3.25

    An input tuple is interpreted as units, minutes, and seconds.  Note
    that only the sign of `units` is significant!  So all of the
    following tuples convert into exactly the same value:

    >>> '%f' % _unsexagesimalize((-1, 2, 3))
    '-1.034167'
    >>> '%f' % _unsexagesimalize((-1, -2, 3))
    '-1.034167'
    >>> '%f' % _unsexagesimalize((-1, -2, -3))
    '-1.034167'

    r   r   )r   tupleiternextr   )r@   
componentsfactor	components       r   r   r   
  sV    ( %%[
Z #IdNFXi/&88E $ Lr   c                     |t        |t              r#|j                  S |t        |      dz  t        z  S t        dj                  | |            )aO  Return an angle in radians from one of two arguments.

    It is common for Skyfield routines to accept both an argument like
    `alt` that takes an Angle object as well as an `alt_degrees` that
    can be given a bare float or a sexagesimal tuple.  A pair of such
    arguments can be passed to this routine for interpretation.

    r   zzyou must either provide the {0}= parameter with an Angle argument or supply the {0}_{1}= parameter with a numeric argument)r   r   r}   r   r   rN   r(   )r.   angle_objectangle_floatre   s       r   _interpret_angler   '  s[     lE*'''		  -5;;
 006tT0BD Dr   c                 v   t        | t              st        |       S | j                         j	                         } | j                  |      rd}n1| j                  |      rd}nt        dj                  || ||            	 t        | d d       } || z  S # t        $ r t        dj                  ||             w xY w)Nr   g      z=your {0} string {1!r} does not end with either {2!r} or {3!r}r   zAyour {0} string {1!r} cannot be parsed as a floating point number)	r   strr   stripupperendswithrN   r(   float)r@   r.   psuffixnsuffixr   s        r   _ltuder  9  s    eS! ''KKM!E~~g		  %%+VD%'%JL 	L>eCRj! %<  > ))/e)<> 	>>s    B %B8)r   )r   r   )r   )(r   numpyr   r   r   r   	constantsr   r   r	   r
   r   descriptorlibr   	functionsr   r   r   r   r   	Exceptionr   objectr   r   rI   ri   rt   r{   r   r   rN   r   r   r   r   r   r   r   r  r   r   r   <module>r	     s     & & 1 1   +04-JY J6 $V $LG't G'R&1t &1P"I "IL'6 'B u1D u1nZ )0/.01:D$r   