
    R1ir%                        d Z ddlmZmZmZmZ ddlmZmZ ddl	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 ddlmZmZ dd	lmZ d
Z eeeef      Zedz  Zedz  Z  G d de!      Z"deeefZ#de
iZ$dZ% G d de!      Z& G d de      Z'y)z@Open a BPC file, read its angles, and produce rotation matrices.    )arraycosnansin)DAFPCK   )ASEC2RADAU_KMDAY_Stau)text_pck)_Tmxvmxmmxmxmrot_xrot_yrot_z)AngleDistance)VectorFunction)s   KPL/FKs   KPL/PCKg       @g      @c                   P    e Zd ZdZd Zed        Zd Zd Zd Z	d Z
dd	Z	 dd
Zy)PlanetaryConstantsa  Planetary constants manager.

    You can use this class to build working models of Solar System
    bodies by loading text planetary constant files and binary
    orientation kernels.  For a full description of how to use this, see
    :doc:`planetary`.

    c                 .    i | _         g | _        i | _        y N)	variables_binary_files_segment_mapselfs    Y/home/cursorai/projects/iching/venv/lib/python3.12/site-packages/skyfield/planetarylib.py__init__zPlanetaryConstants.__init__   s        c                     | j                   S r   )r   r    s    r"   assignmentszPlanetaryConstants.assignments   s    ~~r$   c                 6   |j                  d       	 |j                  d      j                  t              st	        dj                  t                    t        j                  || j                         |j                          y# |j                          w xY w)a  Read frame variables from a KPL/FK file.

        Appropriate files will typically have the extension ``.tf`` or
        ``.tpc`` and will define a series of names and values that will
        be loaded into this object's ``.variables`` dictionary.

        >>> from skyfield.api import load
        >>> pc = PlanetaryConstants()
        >>> pc.read_text(load('moon_080317.tf'))
        >>> pc.variables['FRAME_31006_NAME']
        'MOON_PA_DE421'

        r      z-file must start with one of the patterns: {0}N)
seekread
startswith_TEXT_MAGIC_NUMBERS
ValueErrorformatr   loadr   close)r!   files     r"   	read_textzPlanetaryConstants.read_text#   so     			!	99Q<**+>?  "((./B(CE EMM$/JJLDJJLs   A"B Bc                    |j                  d       |j                  d      dk7  rt        d      t        t	        |            }| j
                  j                  |       |j                  D ]  }|| j                  |j                  <    y)zRead binary segments descriptions from a DAF/PCK file.

        Binary segments live in ``.bpc`` files and predict how a body
        like a planet or moon will be oriented on a given date.

        r   r(   s   DAF/PCKz(file must start with the bytes "DAF/PCK"N)
r)   r*   r-   r   r   r   appendsegmentsr   body)r!   r1   pcksegments       r"   read_binaryzPlanetaryConstants.read_binary:   sn     			!99Q<:%GHH#d)n!!#&||G.5Dgll+ $r$   c                     	 | j                   |   S # t        $ r( t        t        j	                  |            }d|_        |w xY w)z:Do .variables[key] but with a pretty exception on failure.N)r   KeyErrorr-   _missing_name_messager.   	__cause__)r!   keyes      r"   _get_assignmentz"PlanetaryConstants._get_assignmentI   sG    	>>#&& 	077<=AAKG	s	    1Ac                 d    | j                  dj                  |            }| j                  |      S )z3Given a frame name, return a :class:`Frame` object.	FRAME_{0})r@   r.   build_frame)r!   nameintegers      r"   build_frame_namedz$PlanetaryConstants.build_frame_namedR   s.    &&{'9'9$'?@((r$   Nc                    | j                  dj                  |            }| j                  j                  dj                  |            }|d}n8|dk(  r| j                  dj                  |         }| j                  dj                  |         }| j                  dj                  |         }t        |   }	d}t        |      }d	|_        t        t        ||            D ]#  \  }
}t        |   }t         ||
|	z        |      }% nD|d
k(  r1| j                  dj                  |         }t        |      }d	|_        nt        d|z        | j                  dj                  |         }| j                  dj                  |         }|| j                  j                  |      }n|}|t        dj                  |            |j                  dk(  sJ t        |||      S )z;Given a frame integer code, return a :class:`Frame` object.zFRAME_{0}_CENTERzTKFRAME_{0}_SPECNANGLESzTKFRAME_{0}_ANGLESzTKFRAME_{0}_AXESzTKFRAME_{0}_UNITS)	r	   r   r   r   r	   r   r   r   r	   )   rI   MATRIXzTKFRAME_{0}_MATRIXzspec %r not yet implementedzTKFRAME_{0}_RELATIVErB   zJyou have not yet loaded a binary PCK file that has a segment for frame {0}r	   )r@   r.   r   get_unit_scalesr   shapelistzip
_rotationsr   NotImplementedErrorr   LookupErrorframeFrame)r!   rE   _segmentcenterspecmatrixanglesaxesunitsscaleangleaxisrotrelativer8   s                  r"   rC   zPlanetaryConstants.build_frameW   s   %%&8&?&?&HI~~!!"4";";G"DE<Fx(<(C(CG(LM~~&8&?&?&HI':'A'A''JK$U+,v##'FD(9#:KE4$T*C UU]!3V<F $; !(<(C(CG(LMv#)*G$*NOO~~&<&C&CG&LMHnn[%7%7%ABG''++G4GG? ==CVG_N N}}!!!VWf--r$   c                 \   t        j                  |      }t        j                  |      }| j                  dj                  |j                              }|d   |d   cxk(  r|d   k(  sn t        d|z        |d   |dz  z   t        z  }t        |      }	t        j                  ||||	      S )z<Build an object representing a location on a body's surface.zBODY{0}_RADIIr   r	      zGonly spherical bodies are supported, but the radii of this body are: %sgMbP?)
r   from_degreesr@   r.   rV   r-   r   r   PlanetToposfrom_latlon_distance)
r!   rS   latitude_degreeslongitude_degreeselevation_mlatlonradiiaudistances
             r"   build_latlon_degreesz'PlanetaryConstants.build_latlon_degrees}   s       !12  !23$$_%;%;ELL%IJQx58/uQx/ CEJK L LAht++u4B<//sCJJr$   r   )        )__name__
__module____qualname____doc__r#   propertyr&   r2   r9   r@   rF   rC   rn    r$   r"   r   r      sE    
  .6)
$.N *-Kr$   r   N
ARCSECONDSa  unknown planetary constant {0!r}

You should either use this object's `.read_text()` method to load an
additional "*.tf" PCK text file that defines the missing name, or
manually provide a value by adding the name and value to the this
object's `.variables` dictionary.c                   "    e Zd ZdZd Zd Zd Zy)rT   z:Planetary constants frame, for building rotation matrices.c                 .    || _         || _        || _        y r   )rV   rU   _matrix)r!   rV   r8   rX   s       r"   r#   zFrame.__init__   s    r$   c           	         | j                   j                  |j                  dd      \  }}}t        t	        |       t        t        |       t	        |                   }| j                  t        | j                  |      }|S )z8Return the rotation matrix for this frame at time ``t``.ro   F)rU   computetdbr   r   r   ry   )r!   tradecwRs         r"   rotation_atzFrame.rotation_at   sh    ]]**155#u=
Cqb	3ucT{E2#J78<<#DLL!$Ar$   c           	      h   | j                   j                  |j                  |j                  d      \  }}|\  }}}|\  }}}	t	        t        |       t	        t        |       t        |                   }
|dz  }t        |      }t        |      }t        |      }t        |       }|	||z  z   }||z  ||z  |z  z
  }||z  ||z  |z  z   }t        |||f| ||f| | |ff      }t	        ||
      }| j                  ,t	        | j                  |
      }
t	        | j                  |      }|
|t        z  fS )zReturn rotation and rate matrices for this frame at time ``t``.

        The rate matrix returned is in units of angular motion per day.

        Tro   )rU   r{   wholetdb_fractionr   r   r   r   r   r   ry   r   )r!   r}   
componentsratesr~   r   r   radotdecdotwdotr   zerocasauvdomega0domega1domega2drdtrtdRdts                        r"   rotation_and_rate_atzFrame.rotation_and_rate_at   sF    !MM11!''1>>4P
E
C#vtqb	3ucT{E2#J783wVVHXIU"v+Q.v+Q.7G$XtW%Xx&
  61~<<#DLL!$At||T*D$,r$   N)rp   rq   rr   rs   r#   r   r   ru   r$   r"   rT   rT      s    D
"r$   rT   c                   B    e Zd ZdZd Zed        Zed        Zd Z	d Z
y)rd   zLocation that rotates with the surface of another Solar System body.

    The location can either be on the surface of the body, or in some
    other fixed position that rotates with the body's surface.

    c                 B    |j                   | _         || _        || _        y r   )rV   _frame_position_au)r!   rS   position_aus      r"   r#   zPlanetTopos.__init__   s    ll'r$   c                     t        |j                  ddf      }t        t        |j                        t        t        |j                         |            } | ||      }||_        ||_        |S )Nro   )r   rl   r   r   radiansr   latitude	longitude)clsrS   r   r   rm   rr!   s          r"   re   z PlanetTopos.from_latlon_distance   sa    8;;S)*i''(#eX5E5E4E.F*JK5!} "r$   c                     | S r   ru   r    s    r"   targetzPlanetTopos.target   s	     r$   c                     | j                   j                  |      \  }}t        t        |      | j                        }t        t        |      | j                        }||d d fS r   )r   r   r   r   r   )r!   r}   r   r   r   r   s         r"   _atzPlanetTopos._at   sW     ++221541t(()4$++,!T4r$   c                     t        t        t        | j                  j                  z
        t        t        | j                  j                  z
        | j                  j                  |            }|dxx   dz  cc<   |S )uA   Compute the altazimuth rotation matrix for this location’s sky.r	   )
r   r   _quartertaur   r   r   _halftaur   r   r   )r!   r}   r   s      r"   r   zPlanetTopos.rotation_at   sb    
 + 5 556(T^^3334KK##A&
 	
!
r$   N)rp   rq   rr   rs   r#   classmethodre   rt   r   r   r   ru   r$   r"   rd   rd      s>    (
     r$   rd   )(rs   numpyr   r   r   r   jplephem.pckr   r   	constantsr
   r   r   r   datar   	functionsr   r   r   r   r   r   r   r[   r   r   	vectorlibr   r,   _NAN3r   r   objectr   rP   rL   r<   rT   rd   ru   r$   r"   <module>r      s    F & & ! 2 2  ? ? ? " %+ sCo9CiwK wKr 5%&
h'% 2F 2h6. 6r$   