a
    ߙfbmJ                     @   s*  d Z ddlZddlZddlmZ ddlZddlmZm	Z	m
Z
mZmZmZ ddlmZmZ ddlmZ G dd	 d	Zd
d Zdd Zdd Zdd Zd:ddZdd Zd;ddZd<ddZdd Zdd Zdd  Zd!d" Z d#d$ Z!d%d& Z"d'd( Z#d)d* Z$d+d, Z%d-d. Z&d=d1d2Z'd>d5d6Z(d?d8d9Z)dS )@z
This module contains formatting functions that are for internal use in
astropy.coordinates.angles. Mainly they are conversions from one format
of data to another.
    N)warn   )IllegalHourWarningIllegalHourErrorIllegalMinuteWarningIllegalMinuteErrorIllegalSecondWarningIllegalSecondError)format_exceptionparsing)unitsc                   @   sB   e Zd ZdZe Zdd Zedd Z	edd Z
dd	d
ZdS )_AngleParseru  
    Parses the various angle formats including:

       * 01:02:30.43 degrees
       * 1 2 0 hours
       * 1°2′3″
       * 1d2m3s
       * -1h2m3s
       * 1°2′3″N

    This class should not be used directly.  Use `parse_angle`
    instead.
    c                 C   s$   dt jjvr |  \t j_t j_d S )N_parser)r   _thread_local__dict___make_parserr   _lexer)self r   @lib/python3.9/site-packages/astropy/coordinates/angle_formats.py__init__4   s
    z_AngleParser.__init__c                 C   sJ   t tjjdd}t  }|D ]$}|tjkr|tjkr||j qt|S )NT)Zinclude_prefix_units)	seturadianZfind_equivalent_unitsZdeg	hourangleupdatenamessorted)clsZsimple_unitsZsimple_unit_namesunitr   r   r   _get_simple_unit_names@   s    z#_AngleParser._get_simple_unit_namesc           !      C   s  ddl m}m} d}dd }dd }dd	 }d
d }dd }dd }	ddd |  D |	_d}
d}d}d}d}d}dd }tjddd}dd }d d! }d"d# }d$d% }d&d' }d(d) }d*d+ }d,d- }d.d/ }d0d1 }d2d3 }d4d5 }d6d7 }d8d9 }tjd:dd;} | |fS )<Nr   )lexyacc)ZSIGNZUINTZUFLOATCOLONZDEGREEZHOURZMINUTEZSECONDZSIMPLE_UNITZEASTWESTZ
NORTHSOUTHc                 S   s   t | jdd| _| S )u&   ((\d+\.\d*)|(\.\d+))([eE][+-−]?\d+)?u   −-)floatvaluereplacetr   r   r   t_UFLOATa   s    z+_AngleParser._make_parser.<locals>.t_UFLOATc                 S   s   t | j| _| S )z\d+)intr&   r(   r   r   r   t_UINTi   s    z)_AngleParser._make_parser.<locals>.t_UINTc                 S   s   | j dkrd| _ nd| _ | S )u   [+−-]+      ?      r&   r(   r   r   r   t_SIGNn   s    
z)_AngleParser._make_parser.<locals>.t_SIGNc                 S   s   | j dkrdnd| _ | S )z[EW]$Wr/   r.   r0   r(   r   r   r   
t_EASTWESTy   s    z-_AngleParser._make_parser.<locals>.t_EASTWESTc                 S   s   | j dkrdnd| _ | S )z[NS]$Sr/   r.   r0   r(   r   r   r   t_NORTHSOUTH~   s    z/_AngleParser._make_parser.<locals>.t_NORTHSOUTHc                 S   s   t | j| _| S N)r   ZUnitr&   r(   r   r   r   t_SIMPLE_UNIT   s    z0_AngleParser._make_parser.<locals>.t_SIMPLE_UNIT|c                 s   s   | ]}d | dV  qdS )z(?:)Nr   ).0xr   r   r   	<genexpr>   s   z,_AngleParser._make_parser.<locals>.<genexpr>:u   d(eg(ree(s)?)?)?|°u   hour(s)?|h(r)?|ʰu   m(in(ute(s)?)?)?|′|\'|ᵐu   s(ec(ond(s)?)?)?|″|\"|ˢ c                 S   s   t d| j d S )NzInvalid character at col )
ValueErrorZlexposr(   r   r   r   t_error   s    
z*_AngleParser._make_parser.<locals>.t_errorZangle_lextabzastropy/coordinates)Zlextabpackagec                 S   s^   | d | d  }| d \}}t |trJ||d  f|dd  |f| d< n|| |f| d< dS )z
            angle : sign hms eastwest
                  | sign dms dir
                  | sign arcsecond dir
                  | sign arcminute dir
                  | sign simple dir
            r         r   N)
isinstancetuple)psignr&   r   r   r   r   p_angle   s
    
$z*_AngleParser._make_parser.<locals>.p_anglec                 S   s&   t | dkr| d | d< nd| d< dS )z8
            sign : SIGN
                 |
            rC   r   r   r.   NlenrF   r   r   r   p_sign   s    z)_AngleParser._make_parser.<locals>.p_signc                 S   s&   t | dkr| d | d< nd| d< dS )zD
            eastwest : EASTWEST
                     |
            rC   r   r   r.   NrI   rK   r   r   r   
p_eastwest   s    z-_AngleParser._make_parser.<locals>.p_eastwestc                 S   s&   t | dkr| d | d< nd| d< dS )zW
            dir : EASTWEST
                | NORTHSOUTH
                |
            rC   r   r   r.   NrI   rK   r   r   r   p_dir   s    z(_AngleParser._make_parser.<locals>.p_dirc                 S   s   | d | d< dS )zC
            ufloat : UFLOAT
                   | UINT
            r   r   Nr   rK   r   r   r   p_ufloat   s    z+_AngleParser._make_parser.<locals>.p_ufloatc                 S   sL   t | dkr"| d | d f| d< n&t | dkrH| d | d | d f| d< dS )zd
            colon : UINT COLON ufloat
                  | UINT COLON UINT COLON ufloat
               r   rB   r         NrI   rK   r   r   r   p_colon   s    z*_AngleParser._make_parser.<locals>.p_colonc                 S   sL   t | dkr"| d | d f| d< n&t | dkrH| d | d | d f| d< dS )zT
            spaced : UINT ufloat
                   | UINT UINT ufloat
            rB   r   rC   r   rP   NrI   rK   r   r   r   p_spaced   s    z+_AngleParser._make_parser.<locals>.p_spacedc                 S   s   | d | d< dS )zc
            generic : colon
                    | spaced
                    | ufloat
            r   r   Nr   rK   r   r   r   	p_generic   s    z,_AngleParser._make_parser.<locals>.p_genericc                 S   sx   t | dkr | d tjf| d< nTt | dv rH| d | d ftjf| d< n,t | dv rt| d | d | d ftjf| d< dS )a"  
            hms : UINT HOUR
                | UINT HOUR ufloat
                | UINT HOUR UINT MINUTE
                | UINT HOUR UFLOAT MINUTE
                | UINT HOUR UINT MINUTE ufloat
                | UINT HOUR UINT MINUTE ufloat SECOND
                | generic HOUR
            rB   r   r   rP   rR   rQ      rR   N)rJ   r   r   rK   r   r   r   p_hms   s    
z(_AngleParser._make_parser.<locals>.p_hmsc                 S   sx   t | dkr | d tjf| d< nTt | dv rH| d | d ftjf| d< n,t | dv rt| d | d | d ftjf| d< dS )a0  
            dms : UINT DEGREE
                | UINT DEGREE ufloat
                | UINT DEGREE UINT MINUTE
                | UINT DEGREE UFLOAT MINUTE
                | UINT DEGREE UINT MINUTE ufloat
                | UINT DEGREE UINT MINUTE ufloat SECOND
                | generic DEGREE
            rB   r   r   rV   rW   rR   N)rJ   r   degreerK   r   r   r   p_dms   s    
z(_AngleParser._make_parser.<locals>.p_dmsc                 S   s6   t | dkr| d df| d< n| d | d f| d< dS )zS
            simple : generic
                   | generic SIMPLE_UNIT
            rC   r   Nr   rI   rK   r   r   r   p_simple  s    z+_AngleParser._make_parser.<locals>.p_simplec                 S   s   | d t jf| d< dS )z4
            arcsecond : generic SECOND
            r   r   N)r   Z	arcsecondrK   r   r   r   p_arcsecond  s    z._AngleParser._make_parser.<locals>.p_arcsecondc                 S   s   | d t jf| d< dS )z4
            arcminute : generic MINUTE
            r   r   N)r   Z	arcminuterK   r   r   r   p_arcminute  s    z._AngleParser._make_parser.<locals>.p_arcminutec                 S   s   t d S r6   )r?   rK   r   r   r   p_error%  s    z*_AngleParser._make_parser.<locals>.p_errorZangle_parsetab)Z	tabmodulerA   )Zastropy.extern.plyr!   r"   joinr    __doc__r   )!r   r!   r"   tokensr*   r,   r1   r3   r5   r7   Zt_COLONZt_DEGREEZt_HOURZt_MINUTEZt_SECONDZt_ignorer@   lexerrH   rL   rM   rN   rO   rS   rT   rU   rY   r[   r\   r]   r^   r_   parserr   r   r   r   L   sF    






z_AngleParser._make_parserFc              
   C   s   z | j jj|| j j|d\}}W nV tyv } z>t|rRtt| d||ntd||W Y d }~n
d }~0 0 |d u r|d u rtd||fS )N)rc   debugz
 in angle zSyntax error parsing angle zNo unit specified)r   r   parser   r?   strr   Z
UnitsError)r   angler   re   Zfound_angleZ
found_uniter   r   r   rf   ,  s    

z_AngleParser.parseN)F)__name__
__module____qualname__ra   	threadinglocalr   r   classmethodr    r   rf   r   r   r   r   r   !   s   

 `r   c                 C   sL   t t | dkr$tt| d n$t | dk s@t | dkrHt| dS )z@
    Checks that the given value is in the range (-24, 24).
    g      8@zTreating as 24 hrg      8N)npanyabsr   r   r   )Zhrsr   r   r   _check_hour_range=  s    rs   c                 C   sF   t | dkrtt| d n$t | dk s:t | dkrBt| dS )y
    Checks that the given value is in the range [0,60].  If the value
    is equal to 60, then a warning is raised.
          N@zTreating as 0 min, +1 hr/deg      NN)rp   rq   r   r   r   )mr   r   r   _check_minute_rangeG  s    rx   c                 C   sP   t | dkrtt| d n.| du r(n$t | dk sDt | dkrLt| dS )rt   ru   zTreating as 0 sec, +1 minNrv   )rp   rq   r   r   r	   )Zsecr   r   r   _check_second_rangeS  s    ry   c                 C   s   t |  t| t| dS )z\
    Checks that the given hour, minute and second are all within
    reasonable range.
    N)rs   rx   ry   hrw   sr   r   r   check_hms_rangesa  s    r}   Fc                 C   s   t  j| ||dS )u  
    Parses an input string value into an angle value.

    Parameters
    ----------
    angle : str
        A string representing the angle.  May be in one of the following forms:

            * 01:02:30.43 degrees
            * 1 2 0 hours
            * 1°2′3″
            * 1d2m3s
            * -1h2m3s

    unit : `~astropy.units.UnitBase` instance, optional
        The unit used to interpret the string.  If ``unit`` is not
        provided, the unit must be explicitly represented in the
        string, either at the end or as number separators.

    debug : bool, optional
        If `True`, print debugging information from the parser.

    Returns
    -------
    value, unit : tuple
        ``value`` is the value as a floating point number or three-part
        tuple, and ``unit`` is a `Unit` instance which is either the
        unit passed in or the one explicitly mentioned in the input
        string.
    )re   )r   rf   )rh   r   re   r   r   r   parse_anglel  s    r~   c                 C   s\   t d| }t t | \}} t |d \}}|d }t ||  |t | || fS )zd
    Convert a floating-point degree value into a ``(degree, arcminute,
    arcsecond)`` tuple.
    r.   ru   rp   copysignZmodfrr   floor)drG   Zdfmfrw   r|   r   r   r   degrees_to_dms  s
    r   c              
   C   s   t | t| td| }zFtt| } |du rFt|}d}ntt|}t|}W n8 ty } z ttd| |||W Y d}~n
d}~0 0 || |d  |d   S )zI
    Convert degrees, arcminute, arcsecond to a float degrees value.
    r.   Nr   zL{func}: dms values ({1[0]},{2[1]},{3[2]}) could not be converted to numbers.ru         @)rx   ry   rp   r   r   rr   r?   r
   )r   rw   r|   rG   errr   r   r   dms_to_degrees  s$    
r   c              
   C   s   t | || td| }zFtt| } |du rBt|}d}ntt|}t|}W n8 ty } z ttd| |||W Y d}~n
d}~0 0 || |d  |d   S )z=
    Convert hour, minute, second to a float hour value.
    r.   Nr   zL{func}: HMS values ({1[0]},{2[1]},{3[2]}) could not be converted to numbers.ru   r   )r}   rp   r   r   rr   r?   r
   )r{   rw   r|   rG   r   r   r   r   hms_to_hours  s"    
r   c                 C   s   t | ||d S )z@
    Convert hour, minute, second to a float degrees value.
    g      .@)r   rz   r   r   r   hms_to_degrees  s    r   c                 C   s   t jt jt| ||S )z@
    Convert hour, minute, second to a float radians value.
    )r   rZ   tor   r   rz   r   r   r   hms_to_radians  s    r   c                 C   s   t t| ||S )z]
    Convert degrees, arcminutes, arcseconds to an ``(hour, minute, second)``
    tuple.
    )r   r   rz   r   r   r   
hms_to_dms  s    r   c                 C   s   ddl m} |j| tjdjS )z>
    Convert any parseable hour value into a float value.
    r   )angles)r   ) r   ZAngler   r   Zhour)r{   r   r   r   r   hours_to_decimal  s    r   c                 C   s   t jt j| S )z/
    Convert an angle in Hours to Radians.
    )r   r   r   r   )r{   r   r   r   hours_to_radians  s    r   c                 C   s\   t d| }t t | \}} t |d \}}|d }t ||  |t | || fS )z\
    Convert an floating-point hour value into an ``(hour, minute,
    second)`` tuple.
    r.   ru   r   )r{   rG   Zhfr   rw   r|   r   r   r   hours_to_hms  s
    r   c                 C   s   t jt j| S )z1
    Convert an angle in Radians to Degrees.
    )r   r   r   rZ   rr   r   r   radians_to_degrees	  s    r   c                 C   s   t jt j| S )z/
    Convert an angle in Radians to Hours.
    )r   r   r   r   r   r   r   r   radians_to_hours  s    r   c                 C   s   t | }t|S )zM
    Convert an angle in Radians to an ``(hour, minute, second)`` tuple.
    )r   r   )r   Zhoursr   r   r   radians_to_hms  s    r   c                 C   s   t jt j| }t|S )zY
    Convert an angle in Radians to an ``(degree, arcminute,
    arcsecond)`` tuple.
    )r   r   r   rZ   r   )r   Zdegreesr   r   r   radians_to_dms   s    r   r=   rB   c           	      C   s~  t d| d }dd | D } |r6|dkr0d}q:d}nd}t|tsLt|}|dk s\|dkrdtd	|snd
}nht|dkr|dkr||d df }q|dkr|d }qd
}n*t|dkr|d }nt|dkrtd|du rd}ndd|   }|dkr$| d |kr$d| d< | d  d7  < n(|dk rL| d dkrL| d  d7  < |dkr~| d dkr~d| d< | d  d7  < n(|dk r| d dkr| d  d7  < g }d}|d |dkr|d |dkrF|du rt| d d}|dd}ndj	t| d |d}t|dks4|d dkr<d| }|d d
|}|j	t | d |t| d | d |||dS )z
    Given an already separated tuple of sexagesimal values, returns
    a string.

    See `hours_to_string` and `degrees_to_string` for a higher-level
    interface to this functionality.
    r.   r   c                 S   s   g | ]}t |qS r   )rp   rr   )r:   r&   r   r   r   
<listcomp>9      z)sexagesimal_to_string.<locals>.<listcomp>rB   rC   r   zfields must be 1, 2, or 3)r   r   r   r   )r   r   )r   z?Invalid separator specification for converting angle to string.NgqM@ru   g      $@g        g      >@z{0:0{pad}.0f}{sep[0]}z{1:02d}{sep[1]}z.8f0.z{0:.{precision}f})	precisionz{last_value}{sep[2]})seppad
last_value)rp   r   rD   rE   r?   rJ   appendrr   rstripformatr`   r+   )	valuesr   r   r   fieldsrG   Zrounding_threshliteralr   r   r   r   sexagesimal_to_string*  sz    









r   rR   rz   c                 C   s&   t | \} }}t| ||f||||dS )z
    Takes a decimal hour value and returns a string formatted as hms with
    separator specified by the 'sep' parameter.

    ``h`` must be a scalar.
    r   r   r   r   )r   r   )r{   r   r   r   r   rw   r|   r   r   r   hours_to_string  s    r   r=   c                 C   s&   t | \} }}t| ||f||||dS )z
    Takes a decimal hour value and returns a string formatted as dms with
    separator specified by the 'sep' parameter.

    ``d`` must be a scalar.
    r   )r   r   )r   r   r   r   r   rw   r|   r   r   r   degrees_to_string  s    r   )NF)N)N)NFr   rB   )rR   Frz   rB   )rR   Fr=   rB   )*ra   osrm   warningsr   Znumpyrp   errorsr   r   r   r   r   r	   Zastropy.utilsr
   r   Zastropyr   r   r   rs   rx   ry   r}   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sF      

"

		
  
Z  
