a
    ߙfb5                     @   s   d Z ddlZddlmZ ddlZddlZddlmZ	 ddl
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 ddlmZmZ ddlmZ g dZdd Zdd Zdd Zi ZdddZ dd Z!dd Z"dd Z#dS )z
This module contains convenience functions for coordinate-related functionality.

This is generally just wrapping around the object-oriented coordinates
framework, but it is useful for some users who are used to more functional
interfaces.
    N)Sequence)units)c)ascii)
isiterabledata   SkyCoord)GCRSPrecessedGeocentric)SphericalRepresentationCartesianRepresentation)get_jd12)cartesian_to_sphericalspherical_to_cartesianget_sunget_constellationconcatenate_representationsconcatenatec                 C   sb   t | ds| tj } t |ds(|tj }t |ds<|tj }t| ||}|t}|j|j|jfS )a  
    Converts 3D rectangular cartesian coordinates to spherical polar
    coordinates.

    Note that the resulting angles are latitude/longitude or
    elevation/azimuthal form.  I.e., the origin is along the equator
    rather than at the north pole.

    .. note::
        This function simply wraps functionality provided by the
        `~astropy.coordinates.CartesianRepresentation` and
        `~astropy.coordinates.SphericalRepresentation` classes.  In general,
        for both performance and readability, we suggest using these classes
        directly.  But for situations where a quick one-off conversion makes
        sense, this function is provided.

    Parameters
    ----------
    x : scalar, array-like, or `~astropy.units.Quantity`
        The first Cartesian coordinate.
    y : scalar, array-like, or `~astropy.units.Quantity`
        The second Cartesian coordinate.
    z : scalar, array-like, or `~astropy.units.Quantity`
        The third Cartesian coordinate.

    Returns
    -------
    r : `~astropy.units.Quantity`
        The radial coordinate (in the same units as the inputs).
    lat : `~astropy.units.Quantity` ['angle']
        The latitude in radians
    lon : `~astropy.units.Quantity` ['angle']
        The longitude in radians
    unit)	hasattrudimensionless_unscaledr   represent_asr   distancelatlon)xyzcartsph r#   8lib/python3.9/site-packages/astropy/coordinates/funcs.pyr      s    #






r   c                 C   sd   t | ds| tj } t |ds(|tj }t |ds<|tj }t| ||d}|t}|j|j|j	fS )ai  
    Converts spherical polar coordinates to rectangular cartesian
    coordinates.

    Note that the input angles should be in latitude/longitude or
    elevation/azimuthal form.  I.e., the origin is along the equator
    rather than at the north pole.

    .. note::
        This is a low-level function used internally in
        `astropy.coordinates`.  It is provided for users if they really
        want to use it, but it is recommended that you use the
        `astropy.coordinates` coordinate systems.

    Parameters
    ----------
    r : scalar, array-like, or `~astropy.units.Quantity`
        The radial coordinate (in the same units as the inputs).
    lat : scalar, array-like, or `~astropy.units.Quantity` ['angle']
        The latitude (in radians if array or scalar)
    lon : scalar, array-like, or `~astropy.units.Quantity` ['angle']
        The longitude (in radians if array or scalar)

    Returns
    -------
    x : float or array
        The first cartesian coordinate.
    y : float or array
        The second cartesian coordinate.
    z : float or array
        The third cartesian coordinate.

    r   )r   r   r   )
r   r   r   Zradianr   r   r   r   r   r    )rr   r   r"   r!   r#   r#   r$   r   N   s    "






r   c           	      C   s   t jt| d \}}|d }|d }|ttjtj  }t	tj
|d dd}dtj
|d dd d }t |||jd	  | ||}t| |d
  tj | |d  tj | |d  tj d}t|t| ddS )a6  
    Determines the location of the sun at a given time (or times, if the input
    is an array `~astropy.time.Time` object), in geocentric coordinates.

    Parameters
    ----------
    time : `~astropy.time.Time`
        The time(s) at which to compute the location of the sun.

    Returns
    -------
    newsc : `~astropy.coordinates.SkyCoord`
        The location of the sun as a `~astropy.coordinates.SkyCoord` in the
        `~astropy.coordinates.GCRS` frame.

    Notes
    -----
    The algorithm for determining the sun/earth relative position is based
    on the simplified version of VSOP2000 that is part of ERFA. Compared to
    JPL's ephemeris, it should be good to about 4 km (in the Sun-Earth
    vector) from 1900-2100 C.E., 8 km for the 1800-2200 span, and perhaps
    250 km over the 1000-3000.

    Ztdbpv   )Zaxisr   g      ?)r   ).r   ).r   ).r(   )r   r   r    )Zobstimeframe)erfaZepv00r   r   to_valuer   ZaudnpZsqrtsumZabZreshapeshaper   ZAUr
   r   )	timeZearth_pv_helioZearth_pv_baryZearth_pZearth_vZdsunZ
invlorentzZ	properdirZcartrepr#   r#   r$   r   }   s    r   Fiauc                    s  |dkrt dtstd}tj|g dd}tjddd}td	d
 |dD  t	 fdd
|d D }|td< |td< ntd }td }| j
}t . tdtj | tdd}W d   n1 s0    Y  |r|j j}	|j j}
n|jj}	|jj}
tjt|	td }|dk}t|D ]X\}}|d |	k |	|d k @ |
|d k@ }||||@ < |dk}t|dkr2 qq2t d||  |r|d | }n|| }|r|d S |S dS )a  
    Determines the constellation(s) a given coordinate object contains.

    Parameters
    ----------
    coord : coordinate-like
        The object to determine the constellation of.
    short_name : bool
        If True, the returned names are the IAU-sanctioned abbreviated
        names.  Otherwise, full names for the constellations are used.
    constellation_list : str
        The set of constellations to use.  Currently only ``'iau'`` is
        supported, meaning the 88 "modern" constellations endorsed by the IAU.

    Returns
    -------
    constellation : str or string array
        If ``coords`` contains a scalar coordinate, returns the name of the
        constellation.  If it is an array coordinate object, it returns an array
        of names.

    Notes
    -----
    To determine which constellation a point on the sky is in, this precesses
    to B1875, and then uses the Delporte boundaries of the 88 modern
    constellations, as tabulated by
    `Roman 1987 <http://cdsarc.u-strasbg.fr/viz-bin/Cat?VI/42>`_.
    r3   z8only 'iau' us currently supported for constellation_listz#data/constellation_data_roman87.dat)ralraudeclname)nameszdata/constellation_names.datZUTF8)encodingc                 S   s.   g | ]&}| d s|dd |dd fqS )#N      )
startswith).0lr#   r#   r$   
<listcomp>   s   
z%get_constellation.<locals>.<listcomp>
c                    s   g | ]} | qS r#   r#   )r>   ZnmZcnames_short_to_longr#   r$   r@          r7   ctablecnames_longignoreZB1875)ZequinoxN)Zdtyper)   r4   r5   r6   r   z-Could not find constellation for coordinates )
ValueError_constellation_datar   Zget_pkg_data_contentsr   readdictsplitr/   Zarrayisscalarwarningscatch_warningssimplefilterr,   ZErfaWarningZtransform_tor   ZraZravelZhourZdecZdegZoneslenint	enumerater0   )coordZ
short_nameZconstellation_listZcdatarD   ZcnamesrE   rL   Zconstel_coordZrahZdecdZconstellidxZnotidedirowZmskr8   r#   rB   r$   r      sL    


.$
r   c                    sX   g }|D ]J t | d  j fdd| D }ttj| }|> }|| q|S )z Helper function for the concatenate function below. Gets and
    concatenates all of the individual components for an iterable of
    representations or differentials.
    r   c                    s   g | ]}t | qS r#   )getattrr-   )r>   r   r7   Zunit0r#   r$   r@     rC   z+_concatenate_components.<locals>.<listcomp>)rV   r   r/   r   Z
atleast_1dappend)Z	reps_difsr8   valuesZ	data_valsZconcat_valsr#   rW   r$   _concatenate_components  s    rZ   c                    s   t | ttjfstdt| d tfdd| D rBtdt| j	 }| }tdd | D }|rtdd | D rt
d|rt| d jd	  t fd
d| D rtdtdd | D  j	 } | }|d	|i}|S )a  
    Combine multiple representation objects into a single instance by
    concatenating the data in each component.

    Currently, all of the input representations have to be the same type. This
    properly handles differential or velocity data, but all input objects must
    have the same differential object type as well.

    Parameters
    ----------
    reps : sequence of `~astropy.coordinates.BaseRepresentation`
        The objects to concatenate

    Returns
    -------
    rep : `~astropy.coordinates.BaseRepresentation` subclass instance
        A single representation object with its data set to the concatenation of
        all the elements of the input sequence of representations.

    z;Input must be a list or iterable of representation objects.r   c                 3   s   | ]}t | kV  qd S )N)typer>   r%   )rep_typer#   r$   	<genexpr>5  rC   z.concatenate_representations.<locals>.<genexpr>z2Input representations must all have the same type.c                 s   s   | ]}d |j v V  qdS sNdifferentialsr>   Zrepr#   r#   r$   r^   >  rC   c                 s   s   | ]}d |j vV  qdS r_   ra   rc   r#   r#   r$   r^   ?  rC   zZInput representations must either all contain differentials, or not contain differentials.r`   c                 3   s*   | ]"}d |j vp t|j d   kV  qdS r_   )rb   r[   r\   )dif_typer#   r$   r^   F  s   
z?All input representations must have the same differential type.c                 S   s   g | ]}|j d  qS )r`   ra   r\   r#   r#   r$   r@   L  rC   z/concatenate_representations.<locals>.<listcomp>)
isinstancer   r/   Zndarray	TypeErrorr[   anyrZ   Zattr_classeskeysrG   rb   Zwith_differentials)ZrepsrY   Znew_repZhas_diffZnew_difr#   )rd   r]   r$   r     s0    r   c                 C   s~   t | ddst| stddd | D }|dd D ]&}||d s6td	||d q6ttd
d | D |d jdS )a|  
    Combine multiple coordinate objects into a single
    `~astropy.coordinates.SkyCoord`.

    "Coordinate objects" here mean frame objects with data,
    `~astropy.coordinates.SkyCoord`, or representation objects.  Currently,
    they must all be in the same frame, but in a future version this may be
    relaxed to allow inhomogeneous sequences of objects.

    Parameters
    ----------
    coords : sequence of coordinate-like
        The objects to concatenate

    Returns
    -------
    cskycoord : SkyCoord
        A single sky coordinate with its data set to the concatenation of all
        the elements in ``coords``
    rL   Fz,The argument to concatenate must be iterablec                 S   s   g | ]}t |d dqS )F)copyr	   )r>   rS   r#   r#   r$   r@   l  rC   zconcatenate.<locals>.<listcomp>r   Nr   z0All inputs must have equivalent frames: {} != {}c                 S   s   g | ]
}|j qS r#   )r   )r>   r   r#   r#   r$   r@   v  rC   r*   )	rV   r   rf   Zis_equivalent_framerG   formatr
   r   r+   )ZcoordsZscsZscr#   r#   r$   r   T  s    r   )Fr3   )$__doc__rM   collections.abcr   Znumpyr/   r,   Zastropyr   r   Zastropy.constantsr   Z
astropy.ior   Zastropy.utilsr   r   Zsky_coordinater
   Zbuiltin_framesr   r   Zrepresentationr   r   Zbuiltin_frames.utilsr   __all__r   r   r   rH   r   rZ   r   r   r#   r#   r#   r$   <module>   s*   0//
Y;