a
    ߙfb                    @   s  d Z ddlZddlZddlZddlZddlZddlmZmZmZ ddl	m
Z
 ddlmZ ddlZddlZddlmZm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! ddl"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z( ddl"m)Z) ddl*m+Z+ g dZ,dZ-dZ.e/dd e-e.fD Z0e-e. Z1ddddddddddddddd d!Z2d"Z3d#Z4d$Z5e/d%d e3e4e5e.fD Z6e3e4 e5 e. Z7ddej8 ej8d&ej8  ej8 ej8d&ej8  ej9 ej9d&ej9  d'Z:ej;d(d)ej<d(d)ej=d$d*d+d,ej>d(d)ej?d(d)ej@d$d)ejAd$d*d+d-d.ZBG d/d0 d0ejCZDeDjEaFeG ZHG d1d2 d2eZIG d3d4 d4eIZJG d5d6 d6eZKG d7d8 d8eKZLG d9d: d:eKZMG d;d< d<eNZOdGd=d>ZPd?d@ ZQG dAdB dBeRZSdCdD ZTdHdEdFZUdS )Iz
The astropy.time package provides functionality for manipulating times and
dates. Specific emphasis is placed on supporting time scales (e.g. UTC, TAI,
UT1) and time representations (e.g. JD, MJD, ISO 8601) that are used in
astronomy.
    N)datetimedate	timedelta)strftime)warn)units	constants)UnitConversionError)ShapedLikeNDArray)override__dir__)	MixinInfodata_info_factory)AstropyWarning   )day_frac)TIME_FORMATSTIME_DELTA_FORMATSTimeJD
TimeUniqueTimeAstropyTimeTimeDatetime)TimeFromEpoch)	_strptime)
TimeBaseTime	TimeDeltaTimeInfoupdate_leap_secondsTIME_SCALESSTANDARD_TIME_SCALESTIME_DELTA_SCALESScaleValueErrorOperandTypeError)taitcbtcgtdbttut1utc)localc                 c   s    | ]}|D ]}||fV  q
qd S N .0scalesscaler,   r,   0lib/python3.9/site-packages/astropy/time/core.py	<genexpr>,   s   r2   r'   r&   r'   )r)   )r&   r'   )r&   )r&   r'   r#   r)   )r&   r'   r#   )r'   r#   r)   r'   r#   )r#   r)   )r#   ))r#   r$   r#   r%   )r#   r(   )r#   r&   )r$   r%   )r$   r'   )r$   r(   )r$   r)   )r%   r&   )r%   r(   )r%   r)   )r&   r(   )r&   r)   )r'   r(   )r'   r)   )r#   r'   r%   r$   r&   r(   c                 c   s    | ]}|D ]}||fV  q
qd S r+   r,   r-   r,   r,   r1   r2   B   s   g      ?)r5   )r#   r'   )r%   r'   )r'   r%   )r%   r#   r6   r7   )r&   r$   )r(   r'   )functionr/   F)r9   r/   include_tio)ZIAU2006ZIAU2000ZIAU1982)ZIAU2006AZIAU2000AZIAU2000BZIAU1994)meanapparentc                   @   s   e Zd ZdZdZdZdS )_LeapSecondsCheckr   r      N)__name__
__module____qualname__NOT_STARTEDRUNNINGDONEr,   r,   r,   r1   r=   g   s   r=   c                       s   e Zd ZdZejdhB ZdZdZdZe	j
jZedd Zd fd	d
	Zdd Zedd Zeeejdd ejD dZdd Zdd ZdddZ  ZS )r   z
    Container for meta information like name, description, format.  This is
    required when the object is used as a mixin column within a table, but can
    be used as a general way to store meta information.
    serialize_methodT)formatr0   	precision	in_subfmt
out_subfmtlocation_delta_ut1_utc_delta_tdb_ttvaluec                 C   s:   | j | j }|dkrd}n|dkr(d}ntd|| j S )Nformatted_value)rM   jd1_jd2)jd1jd2z7serialize method must be 'formatted_value' or 'jd1_jd2')rE   Z_serialize_context
ValueError_represent_as_dict_extra_attrs)selfmethodoutr,   r,   r1   _represent_as_dict_attrs   s    z!TimeInfo._represent_as_dict_attrsFc                    s(   t  | |r$ddddddd| _d S )NrO   rN   )ZfitsZecsvZhdf5ZyamlZparquetN)super__init__rE   )rT   bound	__class__r,   r1   rY      s    zTimeInfo.__init__c                 C   s(   | j }|j}||j|dd j}||gS )z
        Return a list of arrays which can be lexically sorted to represent
        the order of the parent column.

        Returns
        -------
        arrays : list of ndarray
        jdrF   )Z_parentr]   r\   )rT   parentZ	jd_approxZjd_remainderr,   r,   r1   get_sortable_arrays   s    	zTimeInfo.get_sortable_arraysc                 C   s   d S r+   r,   rT   r,   r,   r1   unit   s    zTimeInfo.unitc                 C   s   g | ]}t t|qS r,   )getattrnp)r.   statr,   r,   r1   
<listcomp>       zTimeInfo.<listcomp>)namesZfuncsc                 C   s   d|v rpd|v rp| d}| dd }d|d< | d|d< | d|d< | jf i |}||_|d ur||_n| d|d< | jf i |}|S )	NrP   rQ   rF   rI   r]   valval2rM   )pop_parent_clsrF   rI   )rT   maprF   rI   rV   r,   r,   r1   _construct_from_dict_base   s    
z"TimeInfo._construct_from_dict_basec                 C   sB   | dd }| dd }| |}|d ur0||_|d ur>||_|S )NrK   rL   )rk   rn   rK   rL   )rT   rm   delta_ut1_utcdelta_tdb_ttrV   r,   r,   r1   _construct_from_dict   s    
zTimeInfo._construct_from_dictr   Nc              	      s   |  |||d}|d |d  |dd D ]4}z td| W q. ty`   tdY q.0 q.|f|d }d}tj||d	d
}	tj|d	d
}
 fdddD }| j|	|
fddi|} j	|_	|
 D ]\}}t|j|| q|S )a  
        Return a new Time instance which is consistent with the input Time objects
        ``cols`` and has ``length`` rows.

        This is intended for creating an empty Time instance whose elements can
        be set in-place for table operations like join or vstack.  It checks
        that the input locations and attributes are consistent.  This is used
        when a Time object is used as a mixin column in an astropy Table.

        Parameters
        ----------
        cols : list
            List of input columns (Time objects)
        length : int
            Length of the output column object
        metadata_conflicts : str ('warn'|'error'|'silent')
            How to handle metadata conflicts
        name : str
            Output column name

        Returns
        -------
        col : Time (or subclass)
            Empty instance of this class consistent with ``cols``

        metaZdescriptiondtyper   r   Nz)input columns have inconsistent locationsshape   @,BAf8rt   c                    s   i | ]}|t  |qS r,   )rc   )r.   attrcol0r,   r1   
<dictcomp>
  s   z%TimeInfo.new_like.<locals>.<dictcomp>)r0   rJ   rG   rH   rI   rF   r]   )merge_cols_attributesrk   _make_value_equivalentslicerR   rd   Zfullzerosrl   rF   itemssetattrinfo)rT   colslengthmetadata_conflictsnameattrscolru   Zjd2000rP   rQ   Ztm_attrsrV   ry   rM   r,   rz   r1   new_like   s,    


zTimeInfo.new_like)F)r   N)r?   r@   rA   __doc__r   Z
attr_namesZ_supports_indexingrS   Z_represent_as_dict_primary_datard   mamaskedZmask_valpropertyrW   rY   r`   rb   staticmethodr   Z_statsZinfo_summary_statsrn   rq   r   __classcell__r,   r,   r[   r1   r   q   s(   

r   c                   @   s"   e Zd ZdZdd ZdddZdS )	TimeDeltaInforF   r0   c                 C   s
   |  |S r+   )rn   )rT   rm   r,   r,   r1   rq     s    z"TimeDeltaInfo._construct_from_dictr   Nc                 C   s   |  |||d}|d |d }|f|d }tj|dd}tj|dd}	| j||	d|jd}
|j|
_| D ]\}}t|
j	|| qr|
S )	a  
        Return a new TimeDelta instance which is consistent with the input Time objects
        ``cols`` and has ``length`` rows.

        This is intended for creating an empty Time instance whose elements can
        be set in-place for table operations like join or vstack.  It checks
        that the input locations and attributes are consistent.  This is used
        when a Time object is used as a mixin column in an astropy Table.

        Parameters
        ----------
        cols : list
            List of input columns (Time objects)
        length : int
            Length of the output column object
        metadata_conflicts : str ('warn'|'error'|'silent')
            How to handle metadata conflicts
        name : str
            Output column name

        Returns
        -------
        col : Time (or subclass)
            Empty instance of this class consistent with ``cols``

        rr   rt   r   ru   rw   rx   r]   r   )
r}   rk   rd   r   rl   r0   rF   r   r   r   )rT   r   r   r   r   r   r{   ru   rP   rQ   rV   ry   rM   r,   r,   r1   r     s    

zTimeDeltaInfo.new_like)r   N)r?   r@   rA   rS   rq   r   r,   r,   r,   r1   r     s   r   c                       s^  e Zd ZdZdZdZdd ZdpddZdd	 Ze	d
d Z
e
jdd Z
e	dd Zejdd Zdd Zdd Zdd Ze	dd Zdd Ze	dd Zejdd Ze	dd Zejdd Ze	d d! Zejd"d! Ze	d#d$ Zejd%d$ Zd&d' Ze	d(d) Ze	d*d+ Zdqd-d.Ze	d/d0 Ze	d1d2 Ze	d3d4 Zdrd6d7Zd8d9 Zdsd:d;Zdtd<d=Z dud?d@Z!dddA fdBdC
Z"dDdE Z#dFdG Z$dvdHdIZ%dwdJdKZ&dxdLdMZ'dydOdPZ(dzdQdRZ)d{dSdTZ*d|dUdVZ+d}dWdXZ,e	dYdZ Z-e-j.d[dZ Z-d\d] Z/e0d^d_ Z1d`da Z2dbdc Z3ddde Z4dfdg Z5dhdi Z6djdk Z7dldm Z8dndo Z9  Z:S )~r   z6Base time class from which Time and TimeDelta inherit.i N  Nc                 C   s   | j fS r+   )_timera   r,   r,   r1   __getnewargs__W  s    zTimeBase.__getnewargs__c	           
   	   C   s*  |du rd}|du rd}|du r$d}t ||}|durlt ||}zt|| W n tyj   tdY n0 |durt|tr| | jv std	|t
| jt||\}	}}| |||||||| _| jj| _t| jdr| jj| _| j`|	dur&t|	| jjj}	d| jj|	< tj| jj|	< dS )	z
        Set the internal _format, scale, and _time attrs from user
        inputs.  This handles coercion into the correct shapes and
        some basic input validation.
        N   *zNInput val and val2 have inconsistent shape; they cannot be broadcast together.*Scale {!r} is not in the allowed scales {}	_locationFrv   )_make_arrayrd   Z	broadcastrR   
isinstancestrlowerSCALESr!   rF   sorted_check_for_masked_and_fill_get_time_fmtr   r   _formathasattrr   rJ   broadcast_torQ   ru   rP   nan)
rT   ri   rj   rF   r0   copyrG   rH   rI   maskr,   r,   r1   _init_from_valsZ  sB    





zTimeBase._init_from_valsc                 C   sd  |du r@|j jdv s|j jr@dd | j D }|dtf nRt|trX|	 | jv s|du rjt
dqt
d|t| jn|| j| fg}|sJ i }	|D ]\}
}z|||||||W   S  ty    Y q t
tfy@ } zNt|dkr$t
d	| d
tj |jj d|  |n||	|
< W Y d}~qd}~0 0 qt
d|	 |	|d d  dS )aM  
        Given the supplied val, val2, format and scale try to instantiate
        the corresponding TimeFormat class to convert the input values into
        the internal jd1 and jd2.

        If format is `None` and the input is a string-type or object array then
        guess available formats and stop when one matches.
        N)SUOMc                 S   s"   g | ]\}}t |tr||fqS r,   )
issubclassr   )r.   r   clsr,   r,   r1   rf     s   
z*TimeBase._get_time_fmt.<locals>.<listcomp>Zastropy_timez5No time format was given, and the input is not uniquez0Format {!r} is not one of the allowed formats {}r   z,Input values did not match the format class :: zTInput values did not match any of the formats where the format keyword is optional: r   )rt   kindrh   FORMATSr   appendr   r   r   r   rR   rF   r   r	   	TypeErrorlenoslinesepr\   r?   )rT   ri   rj   rF   r0   rG   rH   rI   formatsZproblemsr   r   errr,   r,   r1   r     sR    



 zTimeBase._get_time_fmtc                 C   s   | j jjj| j jjj@ S r+   r   rP   flags	writeablerQ   ra   r,   r,   r1   r     s    zTimeBase.writeablec                 C   s   || j jj_|| j jj_d S r+   r   rT   rM   r,   r,   r1   r     s    c                 C   s   | j S )ao  
        Get or set time format.

        The format defines the way times are represented when accessed via the
        ``.value`` attribute.  By default it is the same as the format used for
        initializing the `Time` instance, but it can be set to any other value
        that could be used for initialization.  These can be listed with::

          >>> list(Time.FORMATS)
          ['jd', 'mjd', 'decimalyear', 'unix', 'unix_tai', 'cxcsec', 'gps', 'plot_date',
           'stardate', 'datetime', 'ymdhms', 'iso', 'isot', 'yday', 'datetime64',
           'fits', 'byear', 'jyear', 'byear_str', 'jyear_str']
        )r   ra   r,   r,   r1   rF     s    zTimeBase.formatc              	   C   sh   || j vrtdt| j  | j | }|| jj| jj| jj| j|| j	|| j
dd| _|| _dS )zSet time formatformat must be one of T)rH   rI   from_jdN)r   rR   listr   rP   rQ   _scalerG   _get_allowed_subfmtrH   rI   r   )rT   rF   Z
format_clsr,   r,   r1   rF     s    




c                 C   s    d | jj| j| j t| | j S )Nz,<{} object: scale='{}' format='{}' value={}>)rF   r\   r?   r0   rc   ra   r,   r,   r1   __repr__  s    
zTimeBase.__repr__c                 C   s   t t| | jS r+   )r   rc   rF   ra   r,   r,   r1   __str__   s    zTimeBase.__str__c                 C   s   zTt | dd }|d ur>|jtj|jtj|jtjf}t| j| j	| j
|fW S  ty   | jdkrrd}n| jr~d}n td| jj d| Y n0 d S )NrJ   r   z(must be scalar)z(value is masked)zunhashable type: 'z' )rc   xto_valueumyzhashrP   rQ   r0   r   ndimr   r\   r?   )rT   Zlocreasonr,   r,   r1   __hash__  s    (
zTimeBase.__hash__c                 C   s   | j jS )z
Time scale)r   r0   ra   r,   r,   r1   r0     s    zTimeBase.scalec              
   C   s  || j krdS || jvr.td|t| j|dks@| j dkrFt  | j |f}tt|}t|d}|dd | |dd  }||krtt	|}| j
j| j
j }}t|dd |dd D ]\}}	||g}
||	f|	|ffD ]H}dj| }zt| |}W n ty   Y q0 |
|||  q.qtt||	 }||
 \}}qt||\}}| jrltj|| j< | j| j |||| j| j| jdd	| _
dS )

        This is the key routine that actually does time scale conversions.
        This is not public and not connected to the read-only scale property.
        Nr   r)   r,   r   z_get_delta_{}_{}Tr   )r0   r   rR   rF   r   _check_leapsectuple
MULTI_HOPSgetreversedr   rP   
jd2_filledziprc   AttributeErrorr   erfar   r   rd   r   r   r   rG   rH   rI   )rT   r0   ZxformZ
xform_sortZmultiZxformsrP   rQ   Zsys1Zsys2argsZsys12Z	dt_methodZget_dtZ	conv_funcr,   r,   r1   
_set_scale  sD    



"
zTimeBase._set_scalec                 C   s   | j jS )z|
        Decimal precision when outputting seconds as floating point (int
        value between 0 and 9 inclusive).
        )r   rG   ra   r,   r,   r1   rG   V  s    zTimeBase.precisionc                 C   s2   | ` t|tr|dk s|dkr&td|| j_d S )Nr   	   z2precision attribute must be an int between 0 and 9)cacher   intrR   r   rG   rT   ri   r,   r,   r1   rG   ^  s    c                 C   s   | j jS )zd
        Unix wildcard pattern to select subformats for parsing string input
        times.
        )r   rH   ra   r,   r,   r1   rH   f  s    zTimeBase.in_subfmtc                 C   s   || j _| `d S r+   )r   rH   r   r   r,   r,   r1   rH   n  s    c                 C   s   | j jS )zR
        Unix wildcard pattern to select subformats for outputting times.
        )r   rI   ra   r,   r,   r1   rI   s  s    zTimeBase.out_subfmtc                 C   s   || j _| `d S r+   )r   rI   r   r   r,   r,   r1   rI   z  s    c                 C   s
   | j jjS )a_  The shape of the time instances.

        Like `~numpy.ndarray.shape`, can be set to a new shape by assigning a
        tuple.  Note that if different instances share some but not all
        underlying data, setting the shape of one instance can make the other
        instance unusable.  Hence, it is strongly recommended to get new,
        reshaped instances with the ``reshape`` method.

        Raises
        ------
        ValueError
            If the new shape has the wrong total number of elements.
        AttributeError
            If the shape of the ``jd1``, ``jd2``, ``location``,
            ``delta_ut1_utc``, or ``delta_tdb_tt`` attributes cannot be changed
            without the arrays being copied.  For these cases, use the
            `Time.reshape` method (which copies any arrays that cannot be
            reshaped in-place).
        )r   rP   ru   ra   r,   r,   r1   ru     s    zTimeBase.shapec              	   C   s   | ` g }| j}| jdf| jdf| df| df| dffD ]`\}}t||d }|d ur4|jdkr4z
||_W n$ ty   |D ]
}||_qv Y q40 || q4d S )NrP   rQ   rK   rL   rJ   r   )r   ru   r   rc   size	Exceptionr   )rT   ru   ZreshapedZoldshapeobjry   ri   rj   r,   r,   r1   ru     s$    
c                 C   s   | j jjr6t|tjr|S td| j jd|dnPt|tjr|jstj|s|j	j
dkrh|d S |j	jrx|d S | S n|S d S )NzJD is an array (z) but value is not ()r   r,   )r   rP   ru   r   rd   Zndarrayr   r   Z	is_maskedrt   r   fieldsitemr   r,   r,   r1   _shaped_like_input  s&    


zTimeBase._shaped_like_inputc                 C   s   | j | j j}| |S )zU
        First of the two doubles that internally store time value(s) in JD.
        )r   mask_if_neededrP   r   )rT   rP   r,   r,   r1   rP     s    zTimeBase.jd1c                 C   s   | j | j j}| |S )zV
        Second of the two doubles that internally store time value(s) in JD.
        )r   r   rQ   r   )rT   rQ   r,   r,   r1   rQ     s    zTimeBase.jd2r   c           	   
   C   s  || j vrtdt| j  | jd }|du r4|n||f}||vr|| jkrT| }n| j|d}i }|dur~||jkr~||d< z|jjf d|i|}W nR t	y } z:|j
| dt|v rtd|d	dn W Y d}~n
d}~0 0 ||}|||< || S )
aJ  Get time values expressed in specified output format.

        This method allows representing the ``Time`` object in the desired
        output ``format`` and optional sub-format ``subfmt``.  Available
        built-in formats include ``jd``, ``mjd``, ``iso``, and so forth. Each
        format can have its own sub-formats

        For built-in numerical formats like ``jd`` or ``unix``, ``subfmt`` can
        be one of 'float', 'long', 'decimal', 'str', or 'bytes'.  Here, 'long'
        uses ``numpy.longdouble`` for somewhat enhanced precision (with
        the enhancement depending on platform), and 'decimal'
        :class:`decimal.Decimal` for full precision.  For 'str' and 'bytes', the
        number of digits is also chosen such that time values are represented
        accurately.

        For built-in date-like string formats, one of 'date_hms', 'date_hm', or
        'date' (or 'longdate_hms', etc., for 5-digit years in
        `~astropy.time.TimeFITS`).  For sub-formats including seconds, the
        number of digits used for the fractional seconds is as set by
        `~astropy.time.Time.precision`.

        Parameters
        ----------
        format : str
            The format in which one wants the time values. Default: the current
            format.
        subfmt : str or None, optional
            Value or wildcard pattern to select the sub-format in which the
            values should be given.  The default of '*' picks the first
            available for a given format, i.e., 'float' or 'date_hms'.
            If `None`, use the instance's ``out_subfmt``.

        r   rF   Nr^   rI   r_   z(unexpected keyword argument 'out_subfmt'zto_value() method for format z- does not support passing a 'subfmt' argument)r   rR   r   r   rF   	replicaterI   r   r   r   Z_select_subfmtsr   r   )	rT   rF   subfmtr   keytmkwargsrM   excr,   r,   r1   r     s2    $




zTimeBase.to_valuec                 C   s   |  | jdS )zTime value(s) in current formatN)r   rF   ra   r,   r,   r1   rM   .  s    zTimeBase.valuec                 C   s   | j jS r+   )r   r   ra   r,   r,   r1   r   3  s    zTimeBase.maskedc                 C   s   | j jS r+   )r   r   ra   r,   r,   r1   r   7  s    zTimeBase.maskr   c                 C   s`  zt |}W n ty(   tdY n0 |dkr:td| jsRtd| jjt|t	| krvt
d|t	| |dk rt	| | }t|| jst|}|jrt	|nd}| jjj| gt	| | | jjd}| jjd| |jjd|< | jjd| |jjd|< ||||| < | jj|d |jj|| d< | jj|d |jj|| d< |S )	a  
        Insert values before the given indices in the column and return
        a new `~astropy.time.Time` or  `~astropy.time.TimeDelta` object.

        The values to be inserted must conform to the rules for in-place setting
        of ``Time`` objects (see ``Get and set values`` in the ``Time``
        documentation).

        The API signature matches the ``np.insert`` API, but is more limited.
        The specification of insert index ``obj`` must be a single integer,
        and the ``axis`` must be ``0`` for simple row insertion before the
        index.

        Parameters
        ----------
        obj : int
            Integer index before which ``values`` is inserted.
        values : array-like
            Value(s) to insert.  If the type of ``values`` is different
            from that of quantity, ``values`` is converted to the matching type.
        axis : int, optional
            Axis along which to insert ``values``.  Default is 0, which is the
            only allowed value and will insert a row.

        Returns
        -------
        out : `~astropy.time.Time` subclass
            New time object with inserted value(s)

        zobj arg must be an integerr   zaxis must be 0z#cannot insert into scalar {} objectz1index {} is out of bounds for axis 0 with size {}r   )r   N)operatorindexr   rR   ru   rF   r\   r?   absr   
IndexErrorr   rd   asarrayr   r   r   r   rP   rQ   )rT   r   valuesaxisZidx0Zn_valuesrV   r,   r,   r1   insert;  s4    !
"  zTimeBase.insertc                 C   s   | j s2| jr td| jjntd| jj| `dD ]}t| |r:t| | q:|t	j
ju sj|t	ju r|t	j| jj|< d S | ||}| jd urt|| j}|jj| jj|< |jj| jj|< d S )NzK{} object is read-only. Make a copy() or set "writeable" attribute to True.zscalar {} object is read-only.)rL   rK   )r   ru   rR   rF   r\   r?   r   r   delattrrd   r   r   r   r   rQ   r~   r0   rc   rP   )rT   r   rM   ry   r,   r,   r1   __setitem__  s(    

zTimeBase.__setitem__c              
   C   s   |du rdt tj tj }t|tjtfsBt	d|j
j dz| | }t|}||k}W n< ty } z$t	d|j
j d| W Y d}~n
d}~0 0 |S )aX  Returns a boolean or boolean array where two Time objects are
        element-wise equal within a time tolerance.

        This evaluates the expression below::

          abs(self - other) <= atol

        Parameters
        ----------
        other : `~astropy.time.Time`
            Time object for comparison.
        atol : `~astropy.units.Quantity` or `~astropy.time.TimeDelta`
            Absolute tolerance for equality with units of time (e.g. ``u.s`` or
            ``u.day``). Default is two bits in the 128-bit JD time representation,
            equivalent to about 40 picosecs.
        Nr>   >'atol' argument must be a Quantity or TimeDelta instance, got  insteadze'other' argument must support subtraction with Time and return a value that supports comparison with r   )rd   finfofloatepsr   dayr   Quantityr   r   r\   r?   r   r   )rT   otheratoldtrV   r   r,   r,   r1   isclose  s"    
zTimeBase.isclosec                 C   s   | j d|dS )a  
        Return a fully independent copy the Time object, optionally changing
        the format.

        If ``format`` is supplied then the time format of the returned Time
        object will be set accordingly, otherwise it will be unchanged from the
        original.

        In this method a full copy of the internal time arrays will be made.
        The internal time arrays are normally not changeable by the user so in
        most cases the ``replicate()`` method should be used.

        Parameters
        ----------
        format : str, optional
            Time format of the copy.

        Returns
        -------
        tm : Time object
            Copy of this object
        r   r^   _apply)rT   rF   r,   r,   r1   r     s    zTimeBase.copyFc                 C   s   | j |rdnd||dS )a	  
        Return a replica of the Time object, optionally changing the format.

        If ``format`` is supplied then the time format of the returned Time
        object will be set accordingly, otherwise it will be unchanged from the
        original.

        If ``copy`` is set to `True` then a full copy of the internal time arrays
        will be made.  By default the replica will use a reference to the
        original arrays when possible to save memory.  The internal time arrays
        are normally not changeable by the user so in most cases it should not
        be necessary to set ``copy`` to `True`.

        The convenience method copy() is available in which ``copy`` is `True`
        by default.

        Parameters
        ----------
        format : str, optional
            Time format of the replica.
        copy : bool, optional
            Return a true copy instead of using references where possible.

        Returns
        -------
        tm : Time object
            Replica of this object
        r   r   rF   r   r  )rT   rF   r   r   r,   r,   r1   r     s    zTimeBase.replicater  c             	      s  |du r| j n|}tr, fdd}n&dkr:d}ntjg R i }| jj| jj }}	|rx||}||	}	t |p| j	}
t
||	| jddddd|
_d	D ]p}zt| |}W n ty   Y qY n0 |rt|d
dr||}ndksdkrt|}t|
|| qd| jv r.| j|
_||
jvrNtdt|
j |
j| }||
jj|
jj|
jj| j|| j|| jdd|
_||
_| j|
_|
S )a-  Create a new time object, possibly applying a method to the arrays.

        Parameters
        ----------
        method : str or callable
            If string, can be 'replicate'  or the name of a relevant
            `~numpy.ndarray` method. In the former case, a new time instance
            with unchanged internal data is created, while in the latter the
            method is applied to the internal ``jd1`` and ``jd2`` arrays, as
            well as to possible ``location``, ``_delta_ut1_utc``, and
            ``_delta_tdb_tt`` arrays.
            If a callable, it is directly applied to the above arrays.
            Examples: 'copy', '__getitem__', 'reshape', `~numpy.broadcast_to`.
        args : tuple
            Any positional arguments for ``method``.
        kwargs : dict
            Any keyword arguments for ``method``.  If the ``format`` keyword
            argument is present, this will be used as the Time format of the
            replica.

        Examples
        --------
        Some ways this is used internally::

            copy : ``_apply('copy')``
            replicate : ``_apply('replicate')``
            reshape : ``_apply('reshape', new_shape)``
            index or slice : ``_apply('__getitem__', item)``
            broadcast : ``_apply(np.broadcast, shape=new_shape)``
        Nc                    s   | g R i S r+   r,   )arrayr   r   rU   r,   r1   <lambda>$  rg   z!TimeBase._apply.<locals>.<lambda>r   r   r   T)rG   rH   rI   r   )rK   rL   rJ   ru   r,   r   Zflattenr   r   )rF   callabler   methodcallerr   rP   rQ   rX   __new__r\   r   r0   rc   r   r   r   __dict__r   r   rR   r   r   rG   r   rH   rI   r   r   )rT   rU   rF   r   r   r   Z
new_formatZapply_methodrP   rQ   r   ry   ri   Z	NewFormatr[   r  r1   r    sR    





zTimeBase._applyc                 C   s   |   S )z
        Overrides the default behavior of the `copy.copy` function in
        the python stdlib to behave like `Time.copy`. Does *not* make a
        copy of the JD arrays - only copies by reference.
        )r   ra   r,   r,   r1   __copy__f  s    zTimeBase.__copy__c                 C   s   |   S )z
        Overrides the default behavior of the `copy.deepcopy` function
        in the python stdlib to behave like `Time.copy`. Does make a
        copy of the JD arrays.
        r   )rT   memor,   r,   r1   __deepcopy__n  s    zTimeBase.__deepcopy__c                    sn    du rt | jS | j dk r,   rHj| jk rHt   fddt| jD }t|S )a  Turn argmin, argmax output into an advanced index.

        Argmin, argmax output contains indices along a given axis in an array
        shaped like the other dimensions.  To use this to get values at the
        correct location, a list is constructed in which the other axes are
        indexed sequentially.  For ``keepdims`` is ``True``, the net result is
        the same as constructing an index grid with ``np.ogrid`` and then
        replacing the ``axis`` item with ``indices`` with its shaped expanded
        at ``axis``. For ``keepdims`` is ``False``, the result is the same but
        with the ``axis`` dimension removed from all list entries.

        For ``axis`` is ``None``, this calls :func:`~numpy.unravel_index`.

        Parameters
        ----------
        indices : array
            Output of argmin or argmax.
        axis : int or None
            axis along which argmin or argmax was used.
        keepdims : bool
            Whether to construct indices that keep or remove the axis along
            which argmin or argmax was used.  Default: ``False``.

        Returns
        -------
        advanced_index : list of arrays
            Suitable for use as an advanced index.
        Nr   c              	      sj   g | ]b\}}| krnLt |d s0| k r4|n|d  |f d | sV| krZdnd   qS ))r   r   r>   )rd   Zarangereshape)r.   isr   indiceskeepdimsr   r,   r1   rf     s   
z,TimeBase._advanced_index.<locals>.<listcomp>)rd   Zunravel_indexru   r   Zexpand_dims	enumerater   )rT   r  r   r  r   r,   r  r1   _advanced_indexv  s    	zTimeBase._advanced_indexc                 C   s:   | j | j }}tj|| |dd}|| | }|||S )a)  Return indices of the minimum values along the given axis.

        This is similar to :meth:`~numpy.ndarray.argmin`, but adapted to ensure
        that the full precision given by the two doubles ``jd1`` and ``jd2``
        is used.  See :func:`~numpy.argmin` for detailed documentation.
        Tr  )rP   rQ   rd   minargminrT   r   rV   rP   rQ   approxr  r,   r,   r1   r    s    
zTimeBase.argminc                 C   s:   | j | j }}tj|| |dd}|| | }|||S )a)  Return indices of the maximum values along the given axis.

        This is similar to :meth:`~numpy.ndarray.argmax`, but adapted to ensure
        that the full precision given by the two doubles ``jd1`` and ``jd2``
        is used.  See :func:`~numpy.argmax` for detailed documentation.
        Tr  )rP   rQ   rd   maxargmaxr  r,   r,   r1   r    s    zTimeBase.argmaxr   c                 C   sV   | j | j }}|| }|| | }|du r@t| | fS tj||f|dS dS )aw  Returns the indices that would sort the time array.

        This is similar to :meth:`~numpy.ndarray.argsort`, but adapted to ensure
        that the full precision given by the two doubles ``jd1`` and ``jd2``
        is used, and that corresponding attributes are copied.  Internally,
        it uses :func:`~numpy.lexsort`, and hence no sort method can be chosen.
        N)keysr   )rP   rQ   rd   ZlexsortZravel)rT   r   rP   rQ   r  Z	remainderr,   r,   r1   argsort  s    	zTimeBase.argsortc                 C   s(   |durt d| | | ||| S )a  Minimum along a given axis.

        This is similar to :meth:`~numpy.ndarray.min`, but adapted to ensure
        that the full precision given by the two doubles ``jd1`` and ``jd2``
        is used, and that corresponding attributes are copied.

        Note that the ``out`` argument is present only for compatibility with
        ``np.min``; since `Time` instances are immutable, it is not possible
        to have an actual ``out`` to store the result in.
        NUSince `Time` instances are immutable, ``out`` cannot be set to anything but ``None``.)rR   r  r  rT   r   rV   r  r,   r,   r1   r    s    zTimeBase.minc                 C   s(   |durt d| | | ||| S )a  Maximum along a given axis.

        This is similar to :meth:`~numpy.ndarray.max`, but adapted to ensure
        that the full precision given by the two doubles ``jd1`` and ``jd2``
        is used, and that corresponding attributes are copied.

        Note that the ``out`` argument is present only for compatibility with
        ``np.max``; since `Time` instances are immutable, it is not possible
        to have an actual ``out`` to store the result in.
        Nr"  )rR   r  r  r#  r,   r,   r1   r    s    zTimeBase.maxc                 C   s,   |durt d| j||d| j||d S )a  Peak to peak (maximum - minimum) along a given axis.

        This is similar to :meth:`~numpy.ndarray.ptp`, but adapted to ensure
        that the full precision given by the two doubles ``jd1`` and ``jd2``
        is used.

        Note that the ``out`` argument is present only for compatibility with
        `~numpy.ptp`; since `Time` instances are immutable, it is not possible
        to have an actual ``out`` to store the result in.
        Nr"  r  )rR   r  r  r#  r,   r,   r1   ptp   s
    zTimeBase.ptpc                 C   s   | | j | ||dd S )a"  Return a copy sorted along the specified axis.

        This is similar to :meth:`~numpy.ndarray.sort`, but internally uses
        indexing with :func:`~numpy.lexsort` to ensure that the full precision
        given by the two doubles ``jd1`` and ``jd2`` is kept, and that
        corresponding attributes are properly sorted and copied as well.

        Parameters
        ----------
        axis : int or None
            Axis to be sorted.  If ``None``, the flattened array is sorted.
            By default, sort over the last axis.
        Tr  )r  r!  )rT   r   r,   r,   r1   sort  s    zTimeBase.sortc                 C   s   | j jS )zA
        Return the cache associated with this instance.
        r   r   ra   r,   r,   r1   r   "  s    zTimeBase.cachec                 C   s
   | j `d S r+   r&  ra   r,   r,   r1   r   )  s    c                 C   s   || j v rd| jdurd| jd }||vr\|| jkr6| }n|  }|| |jrTd|_|||< || S || jv r|| j|ddS |t	v r| jdu rt
dqt
d| jj| j|n
| |S dS )zU
        Get dynamic attributes to output format or do timescale conversion.
        Nr0   F)r   zCCannot convert TimeDelta with undefined scale to any defined scale.z/Cannot convert {} with scale '{}' to scale '{}')r   r0   r   r   r   ru   r   r   r   r   r!   rF   r\   r?   __getattribute__)rT   ry   r   r   r,   r,   r1   __getattr__-  s*    





zTimeBase.__getattr__c                 C   s   t | j}|| j |S r+   )setr   updater   )rT   resultr,   r,   r1   __dir__P  s    
zTimeBase.__dir__c                 C   sX   t |dd}|jdkrT|j| jkrTztj|| jdd}W n tyR   tdY n0 |S )z
        Ensure that `val` is matched to length of self.  If val has length 1
        then broadcast, otherwise cast to double and make sure shape matches.
        Tr  r   subokzAttribute shape must match or be broadcastable to that of Time object. Typically, give either a single value or one for each time.)r   r   ru   rd   r   r   rR   r   r,   r,   r1   _match_shapeV  s    zTimeBase._match_shapec                 C   s   |j | j ur8z| j || jd}W n ty6   t Y S 0 | jdurN| j|jvsd|jdur~|j| jvr~td| j j| j|j| jdur|jdurt|| j}|| j	|j	 | j
|j
  dS )zvIf other is of same class as self, compare difference in self.scale.
        Otherwise, return NotImplemented
        r0   Nz5Cannot compare {} instances with scales '{}' and '{}'        )r\   r0   r   NotImplementedr   r   rF   r?   rc   rP   rQ   )rT   r   opr,   r,   r1   _time_comparisonh  s"    

zTimeBase._time_comparisonc                 C   s   |  |tjS r+   )r4  r   ltrT   r   r,   r,   r1   __lt__  s    zTimeBase.__lt__c                 C   s   |  |tjS r+   )r4  r   ler6  r,   r,   r1   __le__  s    zTimeBase.__le__c                 C   s   |  |tjS )z
        If other is an incompatible object for comparison, return `False`.
        Otherwise, return `True` if the time difference between self and
        other is zero.
        )r4  r   eqr6  r,   r,   r1   __eq__  s    zTimeBase.__eq__c                 C   s   |  |tjS )z
        If other is an incompatible object for comparison, return `True`.
        Otherwise, return `False` if the time difference between self and
        other is zero.
        )r4  r   ner6  r,   r,   r1   __ne__  s    zTimeBase.__ne__c                 C   s   |  |tjS r+   )r4  r   gtr6  r,   r,   r1   __gt__  s    zTimeBase.__gt__c                 C   s   |  |tjS r+   )r4  r   ger6  r,   r,   r1   __ge__  s    zTimeBase.__ge__)NNN)r   )r   )N)N)NFN)NF)NN)NN)r   )NNF)NNF)NNF)r   );r?   r@   rA   r   Z__array_priority__Z_astropy_column_attrsr   r   r   r   r   setterrF   r   r   r   r0   r   rG   rH   rI   ru   r   rP   rQ   r   rM   r   r   r   r   r  r   r   r  r  r  r  r  r  r!  r  r  r$  r%  r   deleterr(  r   r,  r/  r4  r7  r9  r;  r=  r?  rA  r   r,   r,   r[   r1   r   L  s    
9;




;










P



J
'

d
2








#
r   c                       s8  e Zd ZdZeZeZd0 fdd	Zd1ddZ	dd	 Z
ed
d Ze Zedd Zdd Zd2ddZd3ddZd4ddZeejerejdeed  deed  e_d5ddZdd Zd6ddZd7d d!Zd"d# ZeeeZ d8d$d%Z!d&d' Z"ee!e"Z#d(d) Z$d*d+ Z%d,d- Z&d9d.d/Z'e(j)je'_  Z*S ):r   a  
    Represent and manipulate times and dates for astronomy.

    A `Time` object is initialized with one or more times in the ``val``
    argument.  The input times in ``val`` must conform to the specified
    ``format`` and must correspond to the specified time ``scale``.  The
    optional ``val2`` time input should be supplied only for numeric input
    formats (e.g. JD) where very high precision (better than 64-bit precision)
    is required.

    The allowed values for ``format`` can be listed with::

      >>> list(Time.FORMATS)
      ['jd', 'mjd', 'decimalyear', 'unix', 'unix_tai', 'cxcsec', 'gps', 'plot_date',
       'stardate', 'datetime', 'ymdhms', 'iso', 'isot', 'yday', 'datetime64',
       'fits', 'byear', 'jyear', 'byear_str', 'jyear_str']

    See also: http://docs.astropy.org/en/stable/time/

    Parameters
    ----------
    val : sequence, ndarray, number, str, bytes, or `~astropy.time.Time` object
        Value(s) to initialize the time or times.  Bytes are decoded as ascii.
    val2 : sequence, ndarray, or number; optional
        Value(s) to initialize the time or times.  Only used for numerical
        input, to help preserve precision.
    format : str, optional
        Format of input value(s)
    scale : str, optional
        Time scale of input value(s), must be one of the following:
        ('tai', 'tcb', 'tcg', 'tdb', 'tt', 'ut1', 'utc')
    precision : int, optional
        Digits of precision in string representation of time
    in_subfmt : str, optional
        Unix glob to select subformats for parsing input times
    out_subfmt : str, optional
        Unix glob to select subformat for outputting times
    location : `~astropy.coordinates.EarthLocation` or tuple, optional
        If given as an tuple, it should be able to initialize an
        an EarthLocation instance, i.e., either contain 3 items with units of
        length for geocentric coordinates, or contain a longitude, latitude,
        and an optional height for geodetic coordinates.
        Can be a single location, or one for each input time.
        If not given, assumed to be the center of the Earth for time scale
        transformations to and from the solar-system barycenter.
    copy : bool, optional
        Make a copy of the input values
    NFc
                    s,   t |tr|j||	| d}
nt | }
|
S N)rF   r   r   )r   r   r   rX   r  r   ri   rj   rF   r0   rG   rH   rI   rJ   r   rT   r[   r,   r1   r    s    
zTime.__new__c
              
   C   s`  |d urJddl m}
 t||
r&|| _n
|
| | _| jjdkrZ| j | _nt| dsZd | _t|tr|d urt|| j_	|d ur|| j_
|d ur|| j_t| j | _|d ur| | n$| |||||	||| t| j | _| jd ur\| jjdkr\| jj| jkr\ztj| j| jdd| _W n> tyZ } z$td| jj| j|W Y d }~n
d }~0 0 d S )Nr   )EarthLocationr   rJ   Tr-  zThe location with shape {} cannot be broadcast against time with shape {}. Typically, either give a single location or one for each time.)astropy.coordinatesrF  r   rJ   r   Zsqueezer   r   r   rG   rH   rI   
TIME_TYPESr0   r   r   r   ru   rd   r   r   rR   rF   )rT   ri   rj   rF   r0   rG   rH   rI   rJ   r   rF  r   r,   r,   r1   rY     sH    




zTime.__init__c                 C   s&  | j dur,| j jr,tj| j | jdd| }n| j }t|tr|du rT|j du rTd}n:|du rf|j dusx|dur~|j du r~d}nt||j k}|std||j n|z| j	|| j
|d}W nd ty    z| j	|| j
| j|d}W n4 ty } ztd|W Y d}~n
d}~0 0 Y n0 |S )	z3Coerce setitem value into an equivalent Time objectNTr-  FzTcannot set to Time with different location: expected location={} and got location={})r0   rJ   )r0   rF   rJ   z4cannot convert value to a compatible Time object: {})rJ   ru   rd   r   r   r   allrR   rF   r\   r0   r   )rT   r   rM   Zself_locationmatchr   r,   r,   r1   r~     s:    

"zTime._make_value_equivalentc                 C   s   t  }| |dddS )aF  
        Creates a new object corresponding to the instant in time this
        method is called.

        .. note::
            "Now" is determined using the `~datetime.datetime.utcnow`
            function, so its accuracy and precision is determined by that
            function.  Generally that means it is set by the accuracy of
            your system clock.

        Returns
        -------
        nowtime : :class:`~astropy.time.Time`
            A new `Time` object (or a subclass of `Time` if this is called from
            such a subclass) at the current time.
        r   r)   )ri   rF   r0   )r   Zutcnow)r   Zdtnowr,   r,   r1   now1  s    zTime.nowc                 K   s   t |}|jjdvr,d|jj}t||jjdkr<tndd }t j|dg|jdgd}|D ]<\}}	t|||\}
}|
dd	 |f }d
j| |	d< q`|	dd}| |j
dd ddi|}|dur||_|S )ab  
        Parse a string to a Time according to a format specification.
        See `time.strptime` documentation for format specification.

        >>> Time.strptime('2012-Jun-30 23:59:60', '%Y-%b-%d %H:%M:%S')
        <Time object: scale='utc' format='isot' value=2012-06-30T23:59:60.000>

        Parameters
        ----------
        time_string : str, sequence, or ndarray
            Objects containing time data of type string
        format_string : str
            String specifying format of time_string.
        kwargs : dict
            Any keyword arguments for ``Time``.  If the ``format`` keyword
            argument is present, this will be used as the Time format.

        Returns
        -------
        time_obj : `~astropy.time.Time`
            A new `~astropy.time.Time` object corresponding to the input
            ``time_string``.

        )r   r   zSExpected type is string, a bytes-like object or a sequence of these. Got dtype '{}'r   c                 S   s   t |  ddS )Nascii)encoding)r   r   )r   r,   r,   r1   r  k  rg   zTime.strptime.<locals>.<lambda>NZU30)Z	op_dtypes   z){:04}-{:02}-{:02}T{:02}:{:02}:{:02}.{:06}.rF   r   Zisot)rd   r   rt   r   rF   r   r   Znditerr   rk   Zoperands)r   Ztime_stringformat_stringr   Z
time_arrayr   Z	to_stringiteratortimeZ	formattedr'   ZfractionZ
time_tuplerF   rV   r,   r,   r1   strptimeI  s.    


zTime.strptimec              
   C   s   g }|  dj D ]}t|d |d |d  }|d |d |d |d |d |d |d |d	 d
f	}|}d|v r|ddj|d | jd}t||}|	| q| j
r|d S t|| jS dS )a  
        Convert Time to a string or a numpy.array of strings according to a
        format specification.
        See `time.strftime` documentation for format specification.

        Parameters
        ----------
        format_spec : str
            Format definition of return string.

        Returns
        -------
        formatted : str or numpy.array
            String or numpy.array of strings formatted according to the given
            format string.

        ZisoZyearZmonr   Zhourr  ZsecrN     r   z%fz{frac:0{precision}}Zfracsec)ZfracrG   r   N)r   r   Z
str_kwargsr   Z	timetuplereplacerF   rG   r   r   Zisscalarrd   r  r  ru   )rT   format_specZformatted_stringsZskZ
date_tupleZdatetime_tupleZfmtd_strr,   r,   r1   r   |  s"    


zTime.strftimebarycentricc                 C   sV  |  dvrtd|du r4| jdu r.td| j}ddlm}m}m}m}m}	m	}
 |
| shtdz|j| d}W n ty   td	Y n0 |
|R |  d
kr||| djj}n ||	| d}|| jj}W d   n1 s0    Y  |j||j}t|d|j}t|d|j}|| jddtj }t|ddS )a  Light travel time correction to the barycentre or heliocentre.

        The frame transformations used to calculate the location of the solar
        system barycentre and the heliocentre rely on the erfa routine epv00,
        which is consistent with the JPL DE405 ephemeris to an accuracy of
        11.2 km, corresponding to a light travel time of 4 microseconds.

        The routine assumes the source(s) are at large distance, i.e., neglects
        finite-distance effects.

        Parameters
        ----------
        skycoord : `~astropy.coordinates.SkyCoord`
            The sky location to calculate the correction for.
        kind : str, optional
            ``'barycentric'`` (default) or ``'heliocentric'``
        location : `~astropy.coordinates.EarthLocation`, optional
            The location of the observatory to calculate the correction for.
            If no location is given, the ``location`` attribute of the Time
            object is used
        ephemeris : str, optional
            Solar system ephemeris to use (e.g., 'builtin', 'jpl'). By default,
            use the one set with ``astropy.coordinates.solar_system_ephemeris.set``.
            For more information, see `~astropy.coordinates.solar_system_ephemeris`.

        Returns
        -------
        time_offset : `~astropy.time.TimeDelta`
            The time offset between the barycentre or Heliocentre and Earth,
            in TDB seconds.  Should be added to the original time to get the
            time in the Solar system barycentre or the Heliocentre.
            Also, the time conversion to BJD will then include the relativistic correction as well.
        )rV  heliocentricz?'kind' parameter must be one of 'heliocentric' or 'barycentric'Nz\An EarthLocation needs to be set or passed in to calculate bary- or heliocentric correctionsr   )UnitSphericalRepresentationCartesianRepresentationHCRSICRSGCRSsolar_system_ephemerisz/Given skycoord is not transformable to the ICRS)Zobstimez9Supplied location does not have a valid `get_itrs` methodrW  r   )r   r&   r0  )r   rR   rJ   rG  rX  rY  rZ  r[  r\  r]  Zis_transformable_toZget_itrsr   r)  Ztransform_toZ	cartesianZxyzZicrsZrepresent_asrd   Zrollaxisr   sumconstcr   )rT   Zskycoordr   rJ   Z	ephemerisrX  rY  rZ  r[  r\  r]  ZitrsZcposZgcrs_coosposZtcor_valr,   r,   r1   light_travel_time  s2    #
 .zTime.light_travel_timec                 C   s4   t |tr|dkrd}d}nd}| j|tjd|dS )a  Calculate local Earth rotation angle.

        Parameters
        ----------
        longitude : `~astropy.units.Quantity`, `~astropy.coordinates.EarthLocation`, str, or None; optional
            The longitude on the Earth at which to compute the Earth rotation
            angle (taken from a location as needed).  If `None` (default), taken
            from the ``location`` attribute of the Time instance. If the special
            string 'tio', the result will be relative to the Terrestrial
            Intermediate Origin (TIO) (i.e., the output of `~erfa.era00`).

        Returns
        -------
        `~astropy.coordinates.Longitude`
            Local Earth rotation angle with units of hourangle.

        See Also
        --------
        astropy.time.Time.sidereal_time

        References
        ----------
        IAU 2006 NFA Glossary
        (currently located at: https://syrte.obspm.fr/iauWGnfa/NFA_Glossary.html)

        Notes
        -----
        The difference between apparent sidereal time and Earth rotation angle
        is the equation of the origins, which is the angle between the Celestial
        Intermediate Origin (CIO) and the equinox. Applying apparent sidereal
        time to the hour angle yields the true apparent Right Ascension with
        respect to the equinox, while applying the Earth rotation angle yields
        the intermediate (CIRS) Right Ascension with respect to the CIO.

        The result includes the TIO locator (s'), which positions the Terrestrial
        Intermediate Origin on the equator of the Celestial Intermediate Pole (CIP)
        and is rigorously corrected for polar motion.
        (except when ``longitude='tio'``).

        tior   FTr8   )	longituder9   r/   r:   )r   r   _sid_time_or_earth_rot_angr   Zera00)rT   rd  r:   r,   r,   r1   earth_rotation_angle  s    )zTime.earth_rotation_anglec                 C   s   |  t vr,tddtt t|   }|du rRt| d }n&| |vrxtd||t| ||  }t|t	r|dv rd}|
 }d|d	< | jf d
|i|S )a	  Calculate sidereal time.

        Parameters
        ----------
        kind : str
            ``'mean'`` or ``'apparent'``, i.e., accounting for precession
            only, or also for nutation.
        longitude : `~astropy.units.Quantity`, `~astropy.coordinates.EarthLocation`, str, or None; optional
            The longitude on the Earth at which to compute the Earth rotation
            angle (taken from a location as needed).  If `None` (default), taken
            from the ``location`` attribute of the Time instance. If the special
            string  'greenwich' or 'tio', the result will be relative to longitude
            0 for models before 2000, and relative to the Terrestrial Intermediate
            Origin (TIO) for later ones (i.e., the output of the relevant ERFA
            function that calculates greenwich sidereal time).
        model : str or None; optional
            Precession (and nutation) model to use.  The available ones are:
            - {0}: {1}
            - {2}: {3}
            If `None` (default), the last (most recent) one from the appropriate
            list above is used.

        Returns
        -------
        `~astropy.coordinates.Longitude`
            Local sidereal time, with units of hourangle.

        See Also
        --------
        astropy.time.Time.earth_rotation_angle

        References
        ----------
        IAU 2006 NFA Glossary
        (currently located at: https://syrte.obspm.fr/iauWGnfa/NFA_Glossary.html)

        Notes
        -----
        The difference between apparent sidereal time and Earth rotation angle
        is the equation of the origins, which is the angle between the Celestial
        Intermediate Origin (CIO) and the equinox. Applying apparent sidereal
        time to the hour angle yields the true apparent Right Ascension with
        respect to the equinox, while applying the Earth rotation angle yields
        the intermediate (CIRS) Right Ascension with respect to the CIO.

        For the IAU precession models from 2000 onwards, the result includes the
        TIO locator (s'), which positions the Terrestrial Intermediate Origin on
        the equator of the Celestial Intermediate Pole (CIP) and is rigorously
        corrected for polar motion (except when ``longitude='tio'`` or ``'greenwich'``).

        z&The kind of sidereal time has to be {}z or Nr   zFModel {} not implemented for {} sidereal time; available models are {})rc  Z	greenwichr   Fr:   rd  )r   SIDEREAL_TIME_MODELSr   rR   rF   joinr   upperr   r   r   re  )rT   r   rd  ZmodelZavailable_modelsZmodel_kwargsr,   r,   r1   sidereal_time%  s&    5zTime.sidereal_timer<   r;   Tc                 C   s  ddl m}m} ddlm} ddlm} |du rL| jdu rBtd| jj	}n"t
||r^|j	}n||tjdd}| ||}	|r| tjd	}
|| \}}||d
|| dtjd || dtjd ||	|
 d
tjd }t|d |d tj> }n||	tj>  }||tjS )a  Calculate a local sidereal time or Earth rotation angle.

        Parameters
        ----------
        longitude : `~astropy.units.Quantity`, `~astropy.coordinates.EarthLocation`, str, or None; optional
            The longitude on the Earth at which to compute the Earth rotation
            angle (taken from a location as needed).  If `None` (default), taken
            from the ``location`` attribute of the Time instance.
        function : callable
            The ERFA function to use.
        scales : tuple of str
            The time scales that the function requires on input.
        include_tio : bool, optional
            Whether to includes the TIO locator corrected for polar motion.
            Should be `False` for pre-2000 IAU models.  Default: `True`.

        Returns
        -------
        `~astropy.coordinates.Longitude`
            Local sidereal time or Earth rotation angle, with units of hourangle.

        r   )	LongituderF  )get_polar_motion)rotation_matrixNzFNo longitude is given but the location for the Time object is not set.Fr  r4   r   r   )rb   r   ).r   r   ).r   r   )rG  rk  rF  Z(astropy.coordinates.builtin_frames.utilsrl  Z$astropy.coordinates.matrix_utilitiesrm  rJ   rR   lonr   r   Zdegree
_call_erfar   Zsp00radianrd   Zarctan2Z	hourangle)rT   rd  r9   r/   r:   rk  rF  rl  rm  ZthetaZspZxpZyprZangler,   r,   r1   re  v  s0    


zTime._sid_time_or_earth_rot_angc                    s0    fdd|D }|| } j r,tj| j< |S )Nc                    s(   g | ] }d D ]}t t  |j|qqS ))rP   r   )rc   r   )r.   r0   Zjd_partra   r,   r1   rf     s   z#Time._call_erfa.<locals>.<listcomp>)r   rd   r   r   )rT   r9   r/   Zerfa_parametersr+  r,   ra   r1   ro    s    
zTime._call_erfac                 C   s,   |du rddl m} | }|j| j|dS )a  Find UT1 - UTC differences by interpolating in IERS Table.

        Parameters
        ----------
        iers_table : `~astropy.utils.iers.IERS`, optional
            Table containing UT1-UTC differences from IERS Bulletins A
            and/or B.  Default: `~astropy.utils.iers.earth_orientation_table`
            (which in turn defaults to the combined version provided by
            `~astropy.utils.iers.IERS_Auto`).
        return_status : bool
            Whether to return status values.  If `False` (default), iers
            raises `IndexError` if any time is out of the range
            covered by the IERS table.

        Returns
        -------
        ut1_utc : float or float array
            UT1-UTC, interpolated in IERS Table
        status : int or int array
            Status values (if ``return_status=`True```)::
            ``astropy.utils.iers.FROM_IERS_B``
            ``astropy.utils.iers.FROM_IERS_A``
            ``astropy.utils.iers.FROM_IERS_A_PREDICTION``
            ``astropy.utils.iers.TIME_BEFORE_IERS_RANGE``
            ``astropy.utils.iers.TIME_BEYOND_IERS_RANGE``

        Notes
        -----
        In normal usage, UT1-UTC differences are calculated automatically
        on the first instance ut1 is needed.

        Examples
        --------
        To check in code whether any times are before the IERS table range::

            >>> from astropy.utils.iers import TIME_BEFORE_IERS_RANGE
            >>> t = Time(['1961-01-01', '2000-01-01'], scale='utc')
            >>> delta, status = t.get_delta_ut1_utc(return_status=True)  # doctest: +REMOTE_DATA
            >>> status == TIME_BEFORE_IERS_RANGE  # doctest: +REMOTE_DATA
            array([ True, False]...)
        Nr   earth_orientation_table)return_status)astropy.utils.iersrs  r   ut1_utcr)   )rT   
iers_tablert  rs  r,   r,   r1   get_delta_ut1_utc  s    *zTime.get_delta_ut1_utcc           
      C   s   t | dsddlm} | }|du rD| j}|jj|jj }}d}n| j}|	||}|dkrt
|||tj\}}	|	||	}| | | jS )a  
        Get ERFA DUT arg = UT1 - UTC.  This getter takes optional jd1 and
        jd2 args because it gets called that way when converting time scales.
        If delta_ut1_utc is not yet set, this will interpolate them from the
        the IERS table.
        rK   r   rr  Nr)   r(   )r   ru  rs  r   r)   r   rP   r   r0   rv  r   Zut1utcr   r   r  _set_delta_ut1_utcrK   )
rT   rP   rQ   rs  rw  Zself_utcr0   ZdeltaZjd1_utcZjd2_utcr,   r,   r1   _get_delta_ut1_utc  s    	

zTime._get_delta_ut1_utcc                 C   s0   | ` t|dr|tjj}| |}|| _d S Nto)r   r   r|  r   secondrM   r/  rK   r   r,   r,   r1   ry    s
    

zTime._set_delta_ut1_utcc           
   
   C   s   t | ds|d u s|d u r>| jdvr.tdn| jj}| jj}t||\}}t||\}}t	|d |d }| j
d u rt|||ddd| _nP| j
}|j}t|j|j}|j}	t||||tj|tj|	tj| _| jS )NrL   r3   zOAccessing the delta_tdb_tt attribute is only possible for TT or TDB time scalesg      ?r   r1  )r   r0   rR   r   rP   r   r   ZtttaiZtaiutcr   rJ   ZdtdbrL   rn  rd   Zhypotr   r   r   r   r   rp  Zkm)
rT   rP   rQ   Znjd1Znjd2utrJ   rn  Zrxyr   r,   r,   r1   _get_delta_tdb_tt  s(    



zTime._get_delta_tdb_ttc                 C   s0   | ` t|dr|tjj}| |}|| _d S r{  )r   r   r|  r   r}  rM   r/  rL   r   r,   r,   r1   _set_delta_tdb_ttD  s
    

zTime._set_delta_tdb_ttc                 C   s  t |t }|rt |ts>zt|}W n ty<   t Y S 0 |  }| j|jv rp|j|jd fvrt||j}nF|jd u r|	d n0| jt
|j vrtd| j|j|	|j dD ]}t||rt|| qnj|j| jvrtd| j|j| jtv r| jn| jj}t|j|jd|jd}|j|jkr@t||j}|jj|jj }|jj|jj }t||\|j_|j_|r|	| j |S )Nr#   zFCannot subtract Time and TimeDelta instances with scales '{}' and '{}'rK   rL   z8Cannot subtract Time instances with scales '{}' and '{}'r]   r   )r   r   r   r   r2  r   r0   r   rc   r   rH  r   rF   r   r   r    r   r#   rP   rQ   r   )rT   r   Zother_is_deltarV   ry   Z	self_timerP   rQ   r,   r,   r1   __sub__P  sN    



zTime.__sub__c                 C   s   t |trt| |dt |tsDzt|}W n tyB   t Y S 0 |  }| j|jv rv|j|jd fvrt	||j}nF|jd u r|
d n0| jt|j vrtd| j|j|
|j dD ]}t||rt|| q|jj|jj }|jj|jj }t||\|j_|j_|
| j |S )N+r#   zACannot add Time and TimeDelta instances with scales '{}' and '{}'r  )r   r   r"   r   r   r2  r   r0   r   rc   r   rH  r   rF   r   r   r   rP   rQ   r   )rT   r   rV   ry   rP   rQ   r,   r,   r1   __add__  s4    




zTime.__add__c                 C   s
   |  |S r+   r  r6  r,   r,   r1   __radd__  s    zTime.__radd__c                 C   s   | j dd}||j|S )Nr   r^   )r   r   r   r   )rT   timezoner   r,   r,   r1   to_datetime  s    zTime.to_datetime)NNNNNNNF)NNNNNNNF)rV  NN)N)NN)T)NF)NN)NN)N)+r?   r@   rA   r   r   r   r   r   r  rY   r~   classmethodrK  r   r   rR  r   rb  rf  rj  r   r   rF   r   rg  r   re  ro  rx  rz  ry  r   ro   r  r  rp   r  r  r  r  r   r   r   r,   r,   r[   r1   r     sP   0      
-%

2$
R
3
L
:
1
#	

&	
:.
r   c                       s   e Zd ZdZeZeZe Z	d- fdd	Z
d.ddZ f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d Zd d! Zd"d# Zg fd$d%Z fd&d'Zd(d) Zd/d+d,Z  ZS )0r   aH  
    Represent the time difference between two times.

    A TimeDelta object is initialized with one or more times in the ``val``
    argument.  The input times in ``val`` must conform to the specified
    ``format``.  The optional ``val2`` time input should be supplied only for
    numeric input formats (e.g. JD) where very high precision (better than
    64-bit precision) is required.

    The allowed values for ``format`` can be listed with::

      >>> list(TimeDelta.FORMATS)
      ['sec', 'jd', 'datetime']

    Note that for time differences, the scale can be among three groups:
    geocentric ('tai', 'tt', 'tcg'), barycentric ('tcb', 'tdb'), and rotational
    ('ut1'). Within each of these, the scales for time differences are the
    same. Conversion between geocentric and barycentric is possible, as there
    is only a scale factor change, but one cannot convert to or from 'ut1', as
    this requires knowledge of the actual times, not just their difference. For
    a similar reason, 'utc' is not a valid scale for a time difference: a UTC
    day is not always 86400 seconds.

    See also:

    - https://docs.astropy.org/en/stable/time/
    - https://docs.astropy.org/en/stable/time/index.html#time-deltas

    Parameters
    ----------
    val : sequence, ndarray, number, `~astropy.units.Quantity` or `~astropy.time.TimeDelta` object
        Value(s) to initialize the time difference(s). Any quantities will
        be converted appropriately (with care taken to avoid rounding
        errors for regular time units).
    val2 : sequence, ndarray, number, or `~astropy.units.Quantity`; optional
        Additional values, as needed to preserve precision.
    format : str, optional
        Format of input value(s)
    scale : str, optional
        Time scale of input value(s), must be one of the following values:
        ('tdb', 'tt', 'ut1', 'tcg', 'tcb', 'tai'). If not given (or
        ``None``), the scale is arbitrary; when added or subtracted from a
        ``Time`` instance, it will be used without conversion.
    copy : bool, optional
        Make a copy of the input values
    NFc
                    s,   t |tr|j||	| d}
nt | }
|
S rD  )r   r   r   rX   r  rE  r[   r,   r1   r    s    
zTimeDelta.__new__c                 C   s`   t |tr|d ur\| | n>|d u r8t |tr4dnd}| ||||| |d ur\t| | _d S )Nr   r]   )r   r   r   r   r   TIME_DELTA_TYPESr   )rT   ri   rj   rF   r0   r   r,   r,   r1   rY   	  s    
zTimeDelta.__init__c                    s   t  j|i |}| j|_|S r+   )rX   r   r   )rT   r   r   rV   r[   r,   r1   r   	  s    zTimeDelta.replicatec                 C   s   | j dd}||jjS )z;
        Convert to ``datetime.timedelta`` object.
        r   r^   )r   r   r   rM   )rT   r   r,   r,   r1   r  	  s    zTimeDelta.to_datetimec              	   C   s   || j krdS || jvr.td|t| jt| j |f }|du rN|| j_ nR| jj| jj }}t	|||d\}}| j
| j || || || j| j| jdd| _dS )r   Nr   ZfactorTr   )r0   r   rR   rF   r   SCALE_OFFSETSr   rP   rQ   r   r   rG   rH   rI   )rT   r0   Zscale_offsetrP   rQ   Zoffset1Zoffset2r,   r,   r1   r   	  s     




zTimeDelta._set_scalec                 C   s   t |ts.zt|}W n ty,   t Y S 0 | jdurD| j|jvsZ|jdurn|j| jvrntd| j|j| jdus|jdu r|  }|jdurt	|| j}n| }|| j
j|j
j}|| j
j|j
j}t||\|j
_|j
_|S )zEPerform common elements of addition / subtraction for two delta timesNz8Cannot add TimeDelta instances with scales '{}' and '{}')r   r   r   r2  r0   r   r   rF   r   rc   r   rP   rQ   r   )rT   r   r3  rV   rP   rQ   r,   r,   r1   _add_sub8	  s,    



zTimeDelta._add_subc                 C   s"   t |tr|| S | |tjS r+   )r   r   r  r  r   addr6  r,   r,   r1   r  V	  s    

zTimeDelta.__add__c                 C   s$   t |trt| |d| |tjS )N-)r   r   r"   r  r   subr6  r,   r,   r1   r  ]	  s    
zTimeDelta.__sub__c                 C   s
   |  |S r+   r  r6  r,   r,   r1   r  d	  s    zTimeDelta.__radd__c                 C   s   |  |}| S r+   )r  )rT   r   rV   r,   r,   r1   __rsub__g	  s    
zTimeDelta.__rsub__c                 C   s(   |   }| jj |j_| jj |j_|S )z!Negation of a `TimeDelta` object.)r   r   rP   rQ   )rT   newr,   r,   r1   __neg__k	  s    zTimeDelta.__neg__c                 C   sR   | j j| j j }}|| dk }|  }t|| ||j _t|| ||j _|S )z'Absolute value of a `TimeDelta` object.r   )r   rP   rQ   r   rd   where)rT   rP   rQ   negativer  r,   r,   r1   __abs__r	  s    zTimeDelta.__abs__c                 C   s   t |trt| |dn0t |tjr.|tjks@t |trH|dkrH|  S ztj|tjdd}W nD t	y   z| 
tj| W  Y S  t	y   t Y  Y S 0 Y n0 t| j| j|jd\}}t||d| jd}| jdkr|j| jd}|S )	z8Multiplication of `TimeDelta` objects by numbers/arrays.r    Fr  r  r]   r   r^   )r   r   r"   r   UnitBasedimensionless_unscaledr   r   r   r   r|  r   r2  r   rP   rQ   rM   r   r0   rF   r   rT   r   rP   rQ   rV   r,   r,   r1   __mul__{	  s,    

zTimeDelta.__mul__c                 C   s
   |  |S )z:Multiplication of numbers/arrays with `TimeDelta` objects.)r  r6  r,   r,   r1   __rmul__	  s    zTimeDelta.__rmul__c                 C   s   t |tjr|tjks(t |tr0|dkr0|  S ztj|tjdd}W nD ty   z| tj	| W  Y S  ty   t
 Y  Y S 0 Y n0 t| j| j|jd\}}t||d| jd}| jdkr|j| jd}|S )z2Division of `TimeDelta` objects by numbers/arrays.r  Fr  )Zdivisorr]   r   r^   )r   r   r  r  r   r   r   r   r|  r   r2  r   rP   rQ   rM   r   r0   rF   r   r  r,   r,   r1   __truediv__	  s(    
zTimeDelta.__truediv__c                 C   s   ||  tj S )z2Division by `TimeDelta` objects of numbers/arrays.)r|  r   r   r6  r,   r,   r1   __rtruediv__	  s    zTimeDelta.__rtruediv__c                 C   s$   t | jj| jj t jj||dS )a  
        Convert to a quantity in the specified unit.

        Parameters
        ----------
        unit : unit-like
            The unit to convert to.
        equivalencies : list of tuple
            A list of equivalence pairs to try if the units are not directly
            convertible (see :ref:`astropy:unit_equivalencies`). If `None`, no
            equivalencies will be applied at all, not even any set globallyq
            or within a context.

        Returns
        -------
        quantity : `~astropy.units.Quantity`
            The quantity in the units specified.

        See also
        --------
        to_value : get the numerical value in a given unit.
        )equivalencies)r   r   r   rP   rQ   r   r|  )rT   rb   r  r,   r,   r1   r|  	  s
    zTimeDelta.toc              
      s   |s|st dd|v s:|dkrL|d du s:|d | jv rLt j|i |S |rzt|d }W n: ty } z"tdt| j|W Y d}~n
d}~0 0 |f|dd  }t	| j
j| j
j tjj|i |S )a  Get time delta values expressed in specified output format or unit.

        This method is flexible and handles both conversion to a specified
        ``TimeDelta`` format / sub-format AND conversion to a specified unit.
        If positional argument(s) are provided then the first one is checked
        to see if it is a valid ``TimeDelta`` format, and next it is checked
        to see if it is a valid unit or unit string.

        To convert to a ``TimeDelta`` format and optional sub-format the options
        are::

          tm = TimeDelta(1.0 * u.s)
          tm.to_value('jd')  # equivalent of tm.jd
          tm.to_value('jd', 'decimal')  # convert to 'jd' as a Decimal object
          tm.to_value('jd', subfmt='decimal')
          tm.to_value(format='jd', subfmt='decimal')

        To convert to a unit with optional equivalencies, the options are::

          tm.to_value('hr')  # convert to u.hr (hours)
          tm.to_value('hr', [])  # specify equivalencies as a positional arg
          tm.to_value('hr', equivalencies=[])
          tm.to_value(unit='hr', equivalencies=[])

        The built-in `~astropy.time.TimeDelta` options for ``format`` are:
        {'jd', 'sec', 'datetime'}.

        For the two numerical formats 'jd' and 'sec', the available ``subfmt``
        options are: {'float', 'long', 'decimal', 'str', 'bytes'}. Here, 'long'
        uses ``numpy.longdouble`` for somewhat enhanced precision (with the
        enhancement depending on platform), and 'decimal' instances of
        :class:`decimal.Decimal` for full precision.  For the 'str' and 'bytes'
        sub-formats, the number of digits is also chosen such that time values
        are represented accurately.  Default: as set by ``out_subfmt`` (which by
        default picks the first available for a given format, i.e., 'float').

        Parameters
        ----------
        format : str, optional
            The format in which one wants the `~astropy.time.TimeDelta` values.
            Default: the current format.
        subfmt : str, optional
            Possible sub-format in which the values should be given. Default: as
            set by ``out_subfmt`` (which by default picks the first available
            for a given format, i.e., 'float' or 'date_hms').
        unit : `~astropy.units.UnitBase` instance or str, optional
            The unit in which the value should be given.
        equivalencies : list of tuple
            A list of equivalence pairs to try if the units are not directly
            convertible (see :ref:`astropy:unit_equivalencies`). If `None`, no
            equivalencies will be applied at all, not even any set globally or
            within a context.

        Returns
        -------
        value : ndarray or scalar
            The value in the format or units specified.

        See also
        --------
        to : Convert to a `~astropy.units.Quantity` instance in a given unit.
        value : The time value in the current format.

        z3to_value() missing required format or unit argumentrF   r,   r   NzRfirst argument is not one of the known formats ({}) and failed to parse as a unit.r   )r   r   rX   r   r   ZUnitrR   rF   r   r   r   rP   rQ   r   )rT   r   r   rb   r   r[   r,   r1   r   	  s6    A
zTimeDelta.to_valuec              
   C   sZ   t |tsVz| j|| j| jd}W n2 tyT } ztd|W Y d}~n
d}~0 0 |S )z8Coerce setitem value into an equivalent TimeDelta object)r0   rF   z9cannot convert value to a compatible TimeDelta object: {}N)r   r   r\   r0   rF   r   rR   )rT   r   rM   r   r,   r,   r1   r~   6
  s    
z TimeDelta._make_value_equivalentr1  c              
   C   s   z| tj}W n2 tyB } ztd| W Y d}~n
d}~0 0 |du r^ttjtj }t	|tj
tfstd|jj dtj|  tj||| tjdS )a  Returns a boolean or boolean array where two TimeDelta objects are
        element-wise equal within a time tolerance.

        This effectively evaluates the expression below::

          abs(self - other) <= atol + rtol * abs(other)

        Parameters
        ----------
        other : `~astropy.units.Quantity` or `~astropy.time.TimeDelta`
            Quantity or TimeDelta object for comparison.
        atol : `~astropy.units.Quantity` or `~astropy.time.TimeDelta`
            Absolute tolerance for equality with units of time (e.g. ``u.s`` or
            ``u.day``). Default is one bit in the 128-bit JD time representation,
            equivalent to about 20 picosecs.
        rtol : float
            Relative tolerance for equality
        z2'other' argument must support conversion to days: Nr   r   )rtolr   )r   r   r   r   r   rd   r   r   r   r   r   r   r\   r?   r  )rT   r   r   r  Z	other_dayr   r,   r,   r1   r  @
  s    $
zTimeDelta.isclose)NNNNNNNF)NNNF)Nr1  )r?   r@   rA   r   r    r   r   r   r   r   r  rY   r   r  r   r  r  r  r  r  r  r  r  r  r  r  r|  r   r~   r  r   r,   r,   r[   r1   r     s6   .   
	 Z
r   c                   @   s   e Zd ZdS )r!   N)r?   r@   rA   r,   r,   r,   r1   r!   c
  s   r!   c                 C   s   t | ttfr.t| dkr.t | d tr.t}nd}tj| |d|d} | jj	dkrh| jj
ttjj
krhn| jj	dv rvntj| tjd} | S )z
    Take ``val`` and convert/reshape to an array.  If ``copy`` is `True`
    then copy input values.

    Returns
    -------
    val : ndarray
        Array version of ``val``.
    r   NT)r   r.  rt   fZOSUMaVrx   )r   r   r   r   r   objectrd   r  rt   r   itemsizeZfloat64Z
asanyarray)ri   r   rt   r,   r,   r1   r   g
  s    
("r   c                 C   sN   dd }d}t | tjjr(||| \}} t |tjjrD|||\}}|| |fS )ai  
    If ``val`` or ``val2`` are masked arrays then fill them and cast
    to ndarray.

    Returns a mask corresponding to the logical-or of masked elements
    in ``val`` and ``val2``.  If neither is masked then the return ``mask``
    is ``None``.

    If either ``val`` or ``val2`` are masked then they are replaced
    with filled versions of themselves.

    Parameters
    ----------
    val : ndarray or MaskedArray
        Input val
    val2 : ndarray or MaskedArray
        Input val2

    Returns
    -------
    mask, val, val2: ndarray or None
        Mask: (None or bool ndarray), val, val2: ndarray
    c                 S   sH   d}t |jr6| |jB } | }t|dkr6|d }||}| |fS )z
        Fill the given MaskedArray ``val`` from the first non-masked
        element in the array.  This ensures that upstream Time initialization
        will succeed.

        Note that nothing happens if there are no masked elements.
        Nr   )rd   anyr   Z
compressedr   Zfilled)r   ri   Z
fill_valueZval_unmaskedr,   r,   r1   get_as_filled_ndarray
  s    

z9_check_for_masked_and_fill.<locals>.get_as_filled_ndarrayF)r   rd   r   ZMaskedArray)ri   rj   r  r   r,   r,   r1   r   
  s    r   c                       s   e Zd Zd fdd	Z  ZS )r"   Nc                    s8   |d u rdnd| }t  d||jj|jj d S )Nr  z for z,Unsupported operand type(s){}: '{}' and '{}')rX   rY   rF   r\   r?   )rT   leftrightr3  Z	op_stringr[   r,   r1   rY   
  s    zOperandTypeError.__init__)N)r?   r@   rA   rY   r   r,   r,   r[   r1   r"   
  s   r"   c                  C   sZ   t tjkrVddlm}  t, t tjkr8tja t  tja W d    n1 sL0    Y  d S )Nr   iers)	_LEAP_SECONDS_CHECKr=   rD   astropy.utilsr  _LEAP_SECONDS_LOCKrB   rC   r   r  r,   r,   r1   r   
  s    

r   c              
   C   sb   z&ddl m} |j| }tj|W S  ty\ } ztd|t	 W Y d}~dS d}~0 0 dS )a  If the current ERFA leap second table is out of date, try to update it.

    Uses `astropy.utils.iers.LeapSeconds.auto_open` to try to find an
    up-to-date table.  See that routine for the definition of "out of date".

    In order to make it safe to call this any time, all exceptions are turned
    into warnings,

    Parameters
    ----------
    files : list of path-like, optional
        List of files/URLs to attempt to open.  By default, uses defined by
        `astropy.utils.iers.LeapSeconds.auto_open`, which includes the table
        used by ERFA itself, so if that is up to date, nothing will happen.

    Returns
    -------
    n_update : int
        Number of items updated.

    r   r  z?leap-second auto-update failed due to the following exception: N)
r  r  ZLeapSecondsZ	auto_openr   Zleap_secondsr*  r   r   r   )filesr  tabler   r,   r,   r1   r   
  s    r   )F)N)Vr   r   r   enumr   Z	threadingr   r   r   rQ  r   warningsr   Znumpyrd   r   Zastropyr   r   r   r_  Zastropy.unitsr	   r  r
   Zastropy.utils.compat.miscr   Zastropy.utils.data_infor   r   Zastropy.utils.exceptionsr   Zutilsr   r   r   r   r   r   r   r   r   Zastropy.externr   __all__r   ZLOCAL_SCALESdictrH  r   r   ZGEOCENTRIC_SCALESZBARYCENTRIC_SCALESZROTATIONAL_SCALESr  r    ZELGZELBr  Zgmst06Zgmst00Zgmst82Zgst06aZgst00aZgst00bZgst94rg  Enumr=   rB   r  RLockr  r   r   r   r   r   r   r!   r   r   r   r"   r   r   r,   r,   r,   r1   <module>   s    





 '5        Y      -   "
=
