
    R1i-                         d Z ddlmZmZmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ dZd	Zd
 Z G d de      Zd Z G d de      Z G d de      Z G d de      Zd ZeeedZy)zCompute positions from a NASA SPICE SPK ephemeris kernel file.

http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/FORTRAN/req/spk.html

    )arrayinterprollaxis   )DAF)reify)OutOfRangeError)target_namesg   ,BAg     @c                 "    t         | t        z  z   S )z9Convert a number of seconds since J2000 to a Julian Date.)T0	S_PER_DAY)secondss    P/home/cursorai/projects/iching/venv/lib/python3.12/site-packages/jplephem/spk.pyjdr      s    )###    c                   J    e Zd ZdZd Zed        Zd Zd Zd Z	d Z
d Zd	 Zy
)SPKa  A JPL SPK ephemeris kernel for computing positions and velocities.

    You can load an SPK by specifying its filename::

        kernel = SPK.open('de431.bsp')

    Run ``print(kernel)`` see which segments are inside.  You can also
    loop across all of the segments in the list ``kernel.segments`` or,
    as a convenience, you can select a particular segment by providing a
    center and target integer in square brackets.  So ``kernel[3,399]``
    will select the segment that computes the distance between the
    Earth-Moon barycenter (3) and the Earth itself (399).

    To extract the text comments from the SPK use ``kernel.comments()``.

    c           	          || _         | j                   j                         D cg c]  \  }}t        | j                   ||       c}}| _        t	        d | j                  D              | _        y c c}}w )Nc              3   P   K   | ]  }|j                   |j                  f|f   y wN)centertarget).0ss     r   	<genexpr>zSPK.__init__.<locals>.<genexpr>*   s#     K]AHHahh/3]s   $&)daf	summariesbuild_segmentsegmentsdictpairsselfr   source
descriptors       r   __init__zSPK.__init__$   sf     '+hh&8&8&:
&:"
 $((FJ7&:
 KT]]KK
	
s   !A1c                 8     | t        t        |d                  S )z3Open the file at `path` and return an SPK instance.rb)r   open)clspaths     r   r)   zSPK.open,   s     3tD$'())r   c                     | j                   j                  j                          | j                  D ]  }d|j                  v s|` d| j                   _        d| j                   _        y)zClose this SPK file._dataN)r   filecloser   __dict__r-   _array_map)r#   segments     r   r/   z	SPK.close1   sO    }}G'***M % r   c                    | j                   }d }dj                   ||j                         ||j                        t	        | j
                              g}|j                  d | j
                  D               dj                  |      S )Nc                 $    | j                  d      S )Nzlatin-1)decode)bs    r   <lambda>zSPK.__str__.<locals>.<lambda><   s    ahhy)r   z/File type {0} and format {1} with {2} segments:c              3   2   K   | ]  }t        |        y wr   )str)r   r3   s     r   r   zSPK.__str__.<locals>.<genexpr>A   s     ?gS\s   
)r   formatlocidwlocfmtlenr   extendjoin)r#   r   dliness       r   __str__zSPK.__str__:   sh    hh)=VAcjjM1SZZ=#dmm2DE
 	???yyr   c                      | j                   |   S )zBGiven (center, target) integers, return the last matching segment.)r!   )r#   keys     r   __getitem__zSPK.__getitem__D   s    zz#r   c                 6    | j                   j                         S )z&Return the file comments, as a string.)r   commentsr#   s    r   rI   zSPK.commentsH   s    xx  ""r   c                     | S r    rJ   s    r   	__enter__zSPK.__enter__L   s    r   c                 $    | j                          y r   )r/   )r#   exc_typeexc_valexc_tbs       r   __exit__zSPK.__exit__O   s    

r   N)__name__
__module____qualname____doc__r&   classmethodr)   r/   rD   rG   rI   rM   rR   rL   r   r   r   r      s?     L * * #r   r   c                 T    |d   }t         j                  |t              } || ||      S )N   )_segment_classesgetBaseSegment)r   r$   r%   	data_typer*   s        r   r   r   R   s,    1I


y+
6CsFJ''r   c                   8    e Zd ZdZdZd Zd ZddZd	dZd	dZ	y)
r\   a  A single segment of an SPK file.

    There are several items of information about each segment that are
    loaded from the underlying SPK file, and made available as object
    attributes:

    segment.source - official ephemeris name, like 'DE-0430LE-0430'
    segment.start_second - initial epoch, as seconds from J2000
    segment.end_second - final epoch, as seconds from J2000
    segment.start_jd - start_second, converted to a Julian Date
    segment.end_jd - end_second, converted to a Julian Date
    segment.center - integer center identifier
    segment.target - integer target identifier
    segment.frame - integer frame identifier
    segment.data_type - integer data type identifier
    segment.start_i - index where segment starts
    segment.end_i - index where segment ends

    Nc           	          || _         || _        |\  | _        | _        | _        | _        | _        | _        | _        | _	        t        | j                        | _        t        | j                        | _        y r   )r   r$   start_second
end_secondr   r   framer]   start_iend_ir   start_jdend_jdr"   s       r   r&   zBaseSegment.__init__m   s\    AK	?	DOT[$+	T^T\4:4,,-)r   c                 &    | j                  d      S )NF)verbose)describerJ   s    r   rD   zBaseSegment.__str__u   s    }}U}++r   c                 0   t        t        j                  | j                  d            }t        t        j                  | j                  d            }dj                  | ||      }|r.|dj                  | | j                  j                  d            z  }|S )z,Return a textual description of the segment.zUnknown centerzUnknown targetzZ{0.start_jd:.2f}..{0.end_jd:.2f}  Type {0.data_type}  {1} ({0.center}) -> {2} ({0.target})z
  frame={0.frame} source={1}ascii)	titlecaser
   r[   r   r   r<   r$   r6   )r#   rh   r   r   texts        r   ri   zBaseSegment.describex   s    <++DKK9IJK<++DKK9IJK9ff- 	 5fT4;;#5#5g#>?ADr   c                 J    t        dj                  | j                              )<Compute the component values for the time `tdb` plus `tdb2`.zbjplephem has not yet learned how to compute positions from an ephemeris segment with data type {0}
ValueErrorr<   r]   r#   tdbtdb2s      r   computezBaseSegment.compute   s"    <VDNN#
 	
r   c                 J    t        dj                  | j                              )@Compute components and differentials for time `tdb` plus `tdb2`.zqjplephem has not yet learned how to compute positions and velocities from an ephemeris segment with data type {0}rp   rr   s      r   compute_and_differentiatez%BaseSegment.compute_and_differentiate   s#    GVDNN#
 	
r   )T        )
rS   rT   rU   rV   r-   r&   rD   ri   ru   rx   rL   r   r   r\   r\   W   s'    & E*,


r   r\   c                   8    e Zd ZddZddZed        Zd Zd Zy)Segmentc                 8    | j                  ||      D ]  }|c S  y)ro   N)generate)r#   rs   rt   positions       r   ru   zSegment.compute   s    c40HO 1r   c                 8    t        | j                  ||            S )rw   )tupler~   rr   s      r   rx   z!Segment.compute_and_differentiate   s    T]]3-..r   c                    | j                   dk(  rd}n| j                   dk(  rd}nt        d      | j                  j                  | j                  dz
  | j                        \  }}}}t        |dz
        |z  }| j                  j                  | j                  | j                  dz
        }t        |      t        |      f|_        |ddddf   }t        |      ||f|_        t        |d      }t        |d      }|ddd   }|||fS )	z?Map the coefficients into memory using a NumPy array.

                 z/this class only supports SPK data types 2 and 3   Nr   )
r]   rq   r   
read_arrayrd   int	map_arrayrc   shaper   )r#   component_countinitintlenrsizencoefficient_countcoefficientss           r   r-   zSegment._data   s    
 >>QO^^q ONOO!%!4!4TZZ!^TZZ!PfeQ	No=xx))$,,

QG!!fc%j1#AabD)!!fo7HIa0a0#DbD)V\))r   c                     | j                   \  }}}t        |      }|t        z  }|d d d   }t        |d      }t        |d      }|||fS )Nr   r   )r-   r   r   r   )r#   r   r   r   initial_epochinterval_lengths         r   
load_arrayzSegment.load_array   sX    %)ZZ"fl4 9,#DbD)a0a0o|;;r   c              #     K   t        |dd       xr t        |dd       }|rt        |f      }| j                  \  }}}|j                  \  }}}	t	        |t
        z
  t        z  |z
  |      \  }
}t	        |t        z  |      \  }}t	        ||z   |      \  }}|
|z   |z   j                  t              }|dk  j                         s||	kD  j                         r/t        d| j                  | j                  fz  |dk  ||	kD  z        ||	k(  }||xx   dz  cc<   ||xx   |z  cc<   |dddd|f   }d|z  |z  dz
  }d|z  }d	x}}g }|dd
 D ]"  }|}|}|||z  |z
  z   }|j                  |       $ |d
   ||z  |z
  z   }|r	|dddf   }| d	x}}t        |dd
 |      D ]  \  }}|}|}d|z  ||z  z   |z
  } |||z  z   |z
  }||z  }|dz  }|t        z  }|r	|dddf   }| yw)a  Generate components and differentials for time `tdb` plus `tdb2`.

        Most uses will simply want to call the `compute()` method or the
        `compute_differentials()` method, for convenience.  But in those
        cases (see Skyfield) where you want to compute a position and
        examine it before deciding whether to proceed with the velocity,
        but without losing all of the work that it took to get to that
        point, this generator lets you get them as two separate steps.

        r   r   z+segment only covers dates %.1f through %.1f)out_of_range_timesr   Ng       @g      ?rz   r   )getattrr   r-   r   divmodr   r   astyper   anyr	   re   rf   appendzip)r#   rs   rt   scalarr   r   r   r   r   r   index1offset1index2offset2index3offsetindexomegasr   s2w0w1wlistcoefficientw2
componentsdw0dw1dw2ratess                                 r   r~   zSegment.generate   sf     S'1--OgdGQ6O2O-C%)ZZ"fl0<0B0B-*A
 !#(i!7$!>G 	!16:' 16:&6)11#6AI?? 1!===$++./$)AI%!)#<  1*fv& #AaI. &L6!C'1WR',KBBR"-BLL	 - ""%R"5
#AaCJ c"<#4e<OKCC(S2X%+C  =
 QWs"!A#JEs   G(G*Nry   )	rS   rT   rU   ru   rx   r   r-   r   r~   rL   r   r   r|   r|      s+    
/ * *.<Mr   r|   c                   6    e Zd ZdZd Zed        ZddZddZy)Type9Segmentz+Lagrange Interpolation - Unequal Time Stepsc                    | j                   }| j                  j                  |dz
  |      \  }}|dk7  rt        dj	                  |            t        |      }| j                  }|d|z  z   dz
  }| j                  j                  ||      }|df|_        |j                  }| j                  j                  |dz   ||z         }||fS )z:Raw coefficients and epochs as memory-mapped NumPy arrays.r   zMjplephem does not yet support Type 9 segments with a polynomial degree of {0}r   )
rd   r   r   rq   r<   r   rc   r   r   T)r#   ipolynomial_degreenumber_of_statesjr   epochss          r   
map_arrayszType9Segment.map_arrays  s    JJ.2hh.A.A!a%.K++! @$f%679 9 /0LL$$$q(xx))!Q/-q0#~~##AE1/?+?@V##r   c                 z    | j                         \  }}t        |dd       }t        |      }t        |      }|||fS )z/Cached arrays that are ready for interpolation.Nr   )r   r   r   )r#   r   r   	positionsand_velocitiess        r   r-   zType9Segment._data%  sH      $0f ,r*+	|,F.&00r   c           
      t    | j                   \  }}}t        |D cg c]  }t        |||       c}      S c c}w )z{Interpolate [x y z] at time `tdb` plus `tdb2`.

        A standard JPL Type 9 ephemerides will return kilometers.

        r-   r   r   r#   rs   rt   r   r   r   cs          r   ru   zType9Segment.compute0  s:     -1JJ)	>6i@ifS&!,i@AA@   5c           
      t    | j                   \  }}}t        |D cg c]  }t        |||       c}      S c c}w )zInterpolate [x y z dx dy dz] at time `tdb` plus `tdb2`.

        A standard JPL Type 9 ephemerides will return kilometers and
        kilometers per second.

        r   r   s          r   rx   z&Type9Segment.compute_and_differentiate9  s:     -1JJ)	>6nEnfS&!,nEFFEr   Nry   )	rS   rT   rU   rV   r   r   r-   ru   rx   rL   r   r   r   r     s*    5$" 1 1BGr   r   c                 H    | j                  d      r| S | j                         S )z3Title-case target `name` if it looks safe to do so.)1zC/zDSS-)
startswithtitle)names    r   rl   rl   C  s    ??#674ITZZ\Ir   )r   r   	   N)rV   numpyr   r   r   r   r   descriptorlibr   
exceptionsr	   namesr
   r   r   r   objectr   r   r\   r|   r   rl   rZ   rL   r   r   <module>r      s   
 * )    ' 	$=& =~(
;
& ;
|zk zx0G; 0GdJ
  r   