
    IR-e                         d 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Zddl	Z
ddlmZ ddlmZ ddlmZ dd	lmZmZ dd
lmZmZ ddl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"dZ# ed          Z$ ed          Z%dZ& ed          Z' ed          Z(dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0dZ1g dZ2 G d  d!e          Z3 G d" d#e          Z4 G d$ d%e3          Z5d& Z6d' Z7 G d( d)ej8                  Z9 e9            Z: G d* d+e;          Z< G d, d-e          Z= G d. d/e=          Z> G d0 d1e=          Z? G d2 d3e>          Z@ G d4 d5e          ZA G d6 d7e          ZBdS )8a  
The astropy.utils.iers package provides access to the tables provided by
the International Earth Rotation and Reference Systems Service, in
particular allowing interpolation of published UT1-UTC values for given
times.  These are used in `astropy.time` to provide UT1 values.  The polar
motions are also used for determining earth orientation for
celestial-to-terrestrial coordinate transformations
(in `astropy.coordinates`).
    N)datetimetimezone)urlparse)warn)config)units)utils)MaskedColumnQTable)Time	TimeDelta)clear_download_cacheget_pkg_data_filenameget_readable_fileobjis_url_in_cache)AstropyWarning)ScienceState)Confconfearth_orientation_tableIERSIERS_BIERS_A	IERS_AutoFROM_IERS_BFROM_IERS_AFROM_IERS_A_PREDICTIONTIME_BEFORE_IERS_RANGETIME_BEYOND_IERS_RANGEIERS_A_FILE
IERS_A_URLIERS_A_URL_MIRRORIERS_A_READMEIERS_B_FILE
IERS_B_URLIERS_B_READMEIERSRangeErrorIERSStaleWarningIERSWarningIERSDegradedAccuracyWarningLeapSecondsIERS_LEAP_SECOND_FILEIERS_LEAP_SECOND_URLIETF_LEAP_SECOND_URLzfinals2000A.allz2https://datacenter.iers.org/data/9/finals2000A.allz/https://maia.usno.navy.mil/ser7/finals2000A.allzdata/ReadMe.finals2000Azdata/eopc04.1962-nowz7https://hpiers.obspm.fr/iers/eop/eopc04/eopc04.1962-nowzdata/ReadMe.eopc04zdata/Leap_Second.datz5https://hpiers.obspm.fr/iers/bul/bulc/Leap_Second.datz7https://data.iana.org/time-zones/data/leap-seconds.list      g   @OBAa  interpolating from IERS_Auto using predictive values that are more
than {0} days old.

Normally you should not see this error because this class
automatically downloads the latest IERS-A table.  Perhaps you are
offline?  If you understand what you are doing then this error can be
suppressed by setting the auto_max_age configuration variable to
``None``:

  from astropy.utils.iers import conf
  conf.auto_max_age = None
)JanFebMarAprMayJunJulAugSepOctNovDecc                       e Zd ZdZdS )r)   z)
    Generic warning class for IERS.
    N__name__
__module____qualname____doc__     7lib/python3.11/site-packages/astropy/utils/iers/iers.pyr)   r)   w              rF   r)   c                       e Zd ZdZdS )r*   z
    IERS time conversion has degraded accuracy normally due to setting
    ``conf.auto_download = False`` and ``conf.iers_degraded_accuracy = 'warn'``.
    Nr@   rE   rF   rG   r*   r*   }   s           rF   r*   c                       e Zd ZdZdS )r(   z-
    Downloaded IERS table may be stale.
    Nr@   rE   rF   rG   r(   r(      rH   rF   r(   c                      |                     dddd           t          j        j                            dt          j                  5  t          j        j        | i |cddd           S # 1 swxY w Y   dS )a  
    Overload astropy.utils.data.download_file within iers module to use a
    custom (longer) wait time.  This just passes through ``*args`` and
    ``**kwargs`` after temporarily setting the download_file remote timeout to
    the local ``iers.conf.remote_timeout`` value.
    http_headerszastropy/iersz*/*)z
User-AgentAcceptremote_timeoutN)
setdefaultr	   datar   set_temprN   download_file)argskwargss     rG   rR   rR      s     (	
 	
   
	!	!"2D4G	H	H 9 9z'8889 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9s   	A,,A03A0c                 F    | | nt          j        t                    j        S )z`
    Convert None to a valid floating point value.  Especially
    for auto_max_age = None.
    )npfinfofloatmax)values    rG   _none_to_floatr[      s    
 %5528E??+>>rF   c                   H   e Zd ZdZ ej        dd          Z ej        dd          Z ej        ed          Z	 ej        e
d          Z ej        dd	          Z ej        g d
d          Z ej        dd          Z ej        ed          Z ej        ed          ZdS )r   z<
    Configuration parameters for `astropy.utils.iers`.
    Tag  Enable auto-downloading of the latest IERS data.  If set to False then the local IERS-B file will be used by default (even if the full IERS file with predictions was already downloaded and cached). This parameter also controls whether internet resources will be queried to update the leap second table if the installed version is out of date. Default is True.g      >@zMaximum age (days) of predictive data before auto-downloading. See "Auto refresh behavior" in astropy.utils.iers documentation for details. Default is 30.z(URL for auto-downloading IERS file data.z/Mirror URL for auto-downloading IERS file data.g      $@z4Remote timeout downloading IERS file data (seconds).)errorr   ignorezIERS behavior if the range of available IERS data does not cover the times when converting time scales, potentially leading to degraded accuracy. zSystem file with leap seconds.z&URL for auto-downloading leap seconds.z0Alternate URL for auto-downloading leap seconds.N)rA   rB   rC   rD   _config
ConfigItemauto_downloadauto_max_ager!   iers_auto_urlr"   iers_auto_url_mirrorrN   iers_degraded_accuracysystem_leap_second_filer-   iers_leap_second_auto_urlr.   ietf_leap_second_auto_urlrE   rF   rG   r   r      s          'G&	( M &7%	 L 'G&> M .7-L  (W'D N 0W/###	   1g05UVV 2 2F! ! !3 2P! !rF   r   c                       e Zd ZdZdS )r'   zK
    Any error for when dates are outside of the valid range for IERS.
    Nr@   rE   rF   rG   r'   r'      rH   rF   r'   c                        e Zd ZdZdZ	 edd            Zed             ZddZddZ	dd	Z
dd
Zd ZddZd Zd Zd Zd Zed             Z fdZ xZS )r   zGeneric IERS table class, defining interpolation functions.

    Sub-classed from `astropy.table.QTable`.  The table should hold columns
    'MJD', 'UT1_UTC', 'dX_2000A'/'dY_2000A', and 'PM_x'/'PM_y'.
    NFc                 *   || j         |Pt          |          j        r&|                    t	          ||                     n|                    |           | t
          u rt          j        di || _         n | j        di || _         | j         S )a  Open an IERS table, reading it from a file if not loaded before.

        Parameters
        ----------
        file : str or None
            full local or network path to the ascii file holding IERS data,
            for passing on to the ``read`` class methods (further optional
            arguments that are available for some IERS subclasses can be added).
            If None, use the default location from the ``read`` class method.
        cache : bool
            Whether to use cache. Defaults to False, since IERS files
            are regularly updated.

        Returns
        -------
        IERS
            An IERS table class instance

        Notes
        -----
        On the first call in a session, the table will be memoized (in the
        ``iers_table`` class attribute), and further calls to ``open`` will
        return this stored table if ``file=None`` (the default).

        If a table needs to be re-read from disk, pass on an explicit file
        location or use the (sub-class) close method and re-open.

        If the location is a network location it is first downloaded via
        download_file.

        For the IERS class itself, an IERS_B sub-class instance is opened.

        NcachefilerE   )
iers_tabler   netlocupdaterR   r   r   read)clsrp   rn   rT   s       rG   openz	IERS.open   s    F s~5D>>( -MM}T'G'G'GMHHHHMMtM,,, d{{!'!6!6v!6!6!)!3!3F!3!3~rF   c                     d| _         dS )zRemove the IERS table from the class.

        This allows the table to be re-read from disk during one's session
        (e.g., if one finds it is out of date and has updated the file).
        N)rq   )ru   s    rG   closez
IERS.close  s     rF           c                     	 |j         j        |j         j        }}n# t          $ r Y nw xY wt	          j        |t          z
  |z             }|t          |z   z
  |z   }||fS )a  Turn a time to MJD, returning integer and fractional parts.

        Parameters
        ----------
        jd1 : float, array, or `~astropy.time.Time`
            first part of two-part JD, or Time object
        jd2 : float or array, optional
            second part of two-part JD.
            Default is 0., ignored if jd1 is `~astropy.time.Time`.

        Returns
        -------
        mjd : float or array
            integer part of MJD
        utc : float or array
            fractional part of MJD
        )utcjd1jd2	ExceptionrV   floorMJD_ZERO)selfr|   r}   mjdr{   s        rG   mjd_utczIERS.mjd_utc"  sp    $	w{CGKCC 	 	 	D	 hsX~+,,X^$s*Cxs    
((c                 F    |                      ||dg|r| j        nd          S )a  Interpolate UT1-UTC corrections in IERS Table for given dates.

        Parameters
        ----------
        jd1 : float, array of float, or `~astropy.time.Time` object
            first part of two-part JD, or Time object
        jd2 : float or float array, optional
            second part of two-part JD.
            Default is 0., ignored if jd1 is `~astropy.time.Time`.
        return_status : bool
            Whether to return status values.  If False (default),
            raise ``IERSRangeError`` 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``)::
            ``iers.FROM_IERS_B``
            ``iers.FROM_IERS_A``
            ``iers.FROM_IERS_A_PREDICTION``
            ``iers.TIME_BEFORE_IERS_RANGE``
            ``iers.TIME_BEYOND_IERS_RANGE``
        UT1_UTCN)_interpolateut1_utc_sourcer   r|   r}   return_statuss       rG   ut1_utczIERS.ut1_utc=  s4    6   yk-#Q4#6#6T
 
 	
rF   c                 H    |                      ||ddg|r| j        nd          S )aV  Interpolate CIP corrections in IERS Table for given dates.

        Parameters
        ----------
        jd1 : float, array of float, or `~astropy.time.Time` object
            first part of two-part JD, or Time object
        jd2 : float or float array, optional
            second part of two-part JD (default 0., ignored if jd1 is Time)
        return_status : bool
            Whether to return status values.  If False (default),
            raise ``IERSRangeError`` if any time is out of the range covered
            by the IERS table.

        Returns
        -------
        D_x : `~astropy.units.Quantity` ['angle']
            x component of CIP correction for the requested times.
        D_y : `~astropy.units.Quantity` ['angle']
            y component of CIP correction for the requested times
        status : int or int array
            Status values (if ``return_status``=``True``)::
            ``iers.FROM_IERS_B``
            ``iers.FROM_IERS_A``
            ``iers.FROM_IERS_A_PREDICTION``
            ``iers.TIME_BEFORE_IERS_RANGE``
            ``iers.TIME_BEYOND_IERS_RANGE``
        dX_2000AdY_2000AN)r   dcip_sourcer   s       rG   dcip_xyzIERS.dcip_xy\  s:    8   $ -7D4	
 
 	
rF   c                 H    |                      ||ddg|r| j        nd          S )at  Interpolate polar motions from IERS Table for given dates.

        Parameters
        ----------
        jd1 : float, array of float, or `~astropy.time.Time` object
            first part of two-part JD, or Time object
        jd2 : float or float array, optional
            second part of two-part JD.
            Default is 0., ignored if jd1 is `~astropy.time.Time`.
        return_status : bool
            Whether to return status values.  If False (default),
            raise ``IERSRangeError`` if any time is out of the range covered
            by the IERS table.

        Returns
        -------
        PM_x : `~astropy.units.Quantity` ['angle']
            x component of polar motion for the requested times.
        PM_y : `~astropy.units.Quantity` ['angle']
            y component of polar motion for the requested times.
        status : int or int array
            Status values (if ``return_status``=``True``)::
            ``iers.FROM_IERS_B``
            ``iers.FROM_IERS_A``
            ``iers.FROM_IERS_A_PREDICTION``
            ``iers.TIME_BEFORE_IERS_RANGE``
            ``iers.TIME_BEYOND_IERS_RANGE``
        PM_xPM_yN)r   	pm_sourcer   s       rG   pm_xyz
IERS.pm_xy  s5    :   vv&-(QT
 
 	
rF   c                     t          j        ||k              rJt          j        dk    rd}t	          |          t          j        dk    rd}t          |t                     dS dS dS )z
        Check that the indices from interpolation match those after clipping
        to the valid table range.  This method gets overridden in the IERS_Auto
        class because it has different requirements.
        r]   a  (some) times are outside of range covered by IERS table. Cannot convert with full accuracy. To allow conversion with degraded accuracy set astropy.utils.iers.conf.iers_degraded_accuracy to "warn" or "silent". For more information about setting this configuration parameter or controlling its value globally, see the Astropy configuration system documentation https://docs.astropy.org/en/stable/config/index.html.r   zN(some) times are outside of range covered by IERS table, accuracy is degraded.N)rV   anyr   rf   r'   r   r*   )r   indices_origindices_clippedmax_input_mjdmsgs        rG   _check_interpolate_indiceszIERS._check_interpolate_indices  s     6,/122 	7*g55M  %S))),66,  S566666%	7 	7 76rF   c                    |                      ||          \  }}t          |d           p
|j        dk    }|r+t          j        |g          }t          j        |g          }n|j        dk    rt          j        g           S |                     |           t          j        | d         j        |d          }t          j	        |dt          |           dz
            }	|	dz
  }
| d         |
         j        | d         |	         j        }}g }|D ]}| |         |
         | |         |	         }}||z
  }|dk    r||                                z  }|||z
  |z   ||z
  z  |z  z   }| |         d         ||dk    <   | |         d         ||t          |           k    <   |r|d         }|                    |           |rU ||	          }t          ||dk    <   t          ||t          |           k    <   |r|d         }|                    |           |S |                     |	|t          j        |                     t          |          dk    r|d         n|S )	N	__array__r   MJDrightsider/   r   r1   )r   hasattrndimrV   arraysize_refresh_table_as_neededsearchsortedrZ   cliplenroundappendr   r   r   rY   )r   r|   r}   columnssourcer   r{   	is_scalarii1i0mjd_0mjd_1resultscolumnval_0val_1d_valvalstatuss                       rG   r   zIERS._interpolate  sb   <<S))S[111BSX]	 	 (C5//C(C5//CCX]]8B<<%%c***
 ODK-sAAA WQ3t99q=))!VE{2,d5k"o.Cu 	  	 F<+T&\"-=5EEME"" &
 3;,?%GGC v,q/CQK"&v,r"2CSYY !fNN3 	@VBZZF3F16N%;F1D		>" #NN6"""N++B26#;;???!$W!2!271::?rF   c                     dS )z
        Potentially update the IERS table in place depending on the requested
        time values in ``mdj`` and the time span of the table.  The base behavior
        is not to update the table.  ``IERS_Auto`` overrides this method.
        NrE   )r   r   s     rG   r   zIERS._refresh_table_as_needed  s	     	rF   c                 *    t          j        |          S )z2Source for UT1-UTC.  To be overridden by subclass.rV   
zeros_liker   r   s     rG   r   zIERS.ut1_utc_source      }QrF   c                 *    t          j        |          S )z9Source for CIP correction.  To be overridden by subclass.r   r   s     rG   r   zIERS.dcip_source  r   rF   c                 *    t          j        |          S )z7Source for polar motion.  To be overridden by subclass.r   r   s     rG   r   zIERS.pm_source  r   rF   c                 X    	 | j         S # t          $ r t          j                    cY S w xY w)z
        Property to provide the current time, but also allow for explicitly setting
        the _time_now attribute for testing purposes.
        )	_time_nowr~   r   nowr   s    rG   time_nowzIERS.time_now  s<    	>! 	 	 	8::	s   	 ))c                     t          |dd           4t          |t                    r|                    t          j                  }t                                          |          S )Nunit)getattr
isinstancer
   filledrV   nansuper_convert_col_for_table)r   col	__class__s     rG   r   zIERS._convert_col_for_table  sQ    
 3%%1jl6S6S1**RV$$Cww--c222rF   NF)ry   )ry   FN)rA   rB   rC   rD   rq   classmethodrv   rx   r   r   r   r   r   r   r   r   r   r   propertyr   r   __classcell__r   s   @rG   r   r      sW         JI2 2 2 [2h   [   6
 
 
 
>!
 !
 !
 !
F
 
 
 
B7 7 76:@ :@ :@ :@x                    X3 3 3 3 3 3 3 3 3rF   r   c                   v     e Zd ZdZdZed             Zed             Zed	 fd	            Zd Z	d Z
d Z xZS )
r   av  IERS Table class targeted to IERS A, provided by USNO.

    These include rapid turnaround and predicted times.
    See https://datacenter.iers.org/eop.php

    Notes
    -----
    The IERS A file is not part of astropy.  It can be downloaded from
    ``iers.IERS_A_URL`` or ``iers.IERS_A_URL_MIRROR``. See ``iers.__doc__``
    for instructions on use in ``Time``, etc.
    Nc                    |t          j        |d                   |d         dk    z           }|                     |          }t          j        |d                   }t          j        ||d         |d                   |d<   t          j        ||d         d          |d<   t          j        |d	                   t          j        |d
                   z  }t          j        ||d         |d	                   |d<   t          j        ||d         |d
                   |d<   t          j        ||d         d          |d<   t          j        |d                   t          j        |d                   z  }t          j        ||d         |d                   |d<   t          j        ||d         |d                   |d<   t          j        ||d         d          |d<   t          t          j        |d         d          t          j        |d         d                    }||j        d<   |d         |         j        |j        d<   |S )zZ
        Return a new table with appropriate combination of IERS_A and B columns.
        	UT1_UTC_APolPMFlag_Ar_   	UT1_UTC_Br   	UT1Flag_ABUT1FlagPM_X_BPM_Y_BPM_x_Ar   PM_y_Ar   	PolPMFlag
dX_2000A_B
dY_2000A_B
dX_2000A_Ar   
dY_2000A_Ar   	NutFlag_ANutFlagPpredictive_indexr   predictive_mjd)	rV   isfinite_substitute_iers_bisnanwhereminr   metarZ   )ru   iers_atableb_badp_indexs        rG   _combine_a_b_columnszIERS_A._combine_a_b_columns0  s    r{6+#6776-;PTV;VWX &&u-- {+,,8E5+=u[?QRRi8E5+=sCCix))BHU8_,E,EEhxIIfhxIIfXeU=-A3GGk|,--|9L0M0MMHUE,,?|ATUUjHUE,,?|ATUUj8E5+=sCCi OE+.44OE-0#66
 
 *1
%&',U|G'<'B
#$rF   c                     |S r   rE   )ru   r   s     rG   r   zIERS_A._substitute_iers_b^  s	     rF   c                     |t           }|t          }t                                          |d|          }|                     |          }||j        d<   ||j        d<   |S )a  Read IERS-A table from a finals2000a.* file provided by USNO.

        Parameters
        ----------
        file : str
            full path to ascii file holding IERS-A data.
            Defaults to ``iers.IERS_A_FILE``.
        readme : str
            full path to ascii file holding CDS-style readme.
            Defaults to package version, ``iers.IERS_A_README``.

        Returns
        -------
        ``IERS_A`` class instance
        Ncds)formatreadme	data_pathreadme_path)r    r#   r   rt   r   r   )ru   rp   r   r   r   r   s        rG   rt   zIERS_A.readc  sf    " <D>"Fd5@@ ((00"&
;$*
=!rF   c                     | d         |         }t          j        |          t          z  }t          ||dk    <   t          ||dk    <   |S )2Set UT1-UTC source flag for entries in IERS table.r   Ir   rV   	ones_liker   r   r   )r   r   ut1flagr   s       rG   r   zIERS_A.ut1_utc_source  C    y/!$a;.!,w#~!7w#~rF   c                     | d         |         }t          j        |          t          z  }t          ||dk    <   t          ||dk    <   |S )9Set CIP correction source flag for entries in IERS table.r   r  r   r  )r   r   nutflagr   s       rG   r   zIERS_A.dcip_source  r  rF   c                     | d         |         }t          j        |          t          z  }t          ||dk    <   t          ||dk    <   |S )z7Set polar motion source flag for entries in IERS table.r   r  r   r  )r   r   pmflagr   s       rG   r   zIERS_A.pm_source  sD    k"1%a;. +v} 6v}rF   )NN)rA   rB   rC   rD   rq   r   r   r   rt   r   r   r   r   r   s   @rG   r   r   !  s        
 
 J+ + [+Z   [      [<          rF   r   c                   J     e Zd ZdZdZed fd	            Zd Zd Zd Z	 xZ
S )	r   a  IERS Table class targeted to IERS B, provided by IERS itself.

    These are final values; see https://www.iers.org/IERS/EN/Home/home_node.html

    Notes
    -----
    If the package IERS B file (```iers.IERS_B_FILE``) is out of date, a new
    version can be downloaded from ``iers.IERS_B_URL``.

    See `~astropy.utils.iers.IERS_B.read` for instructions on how to read
    a pre-2023 style IERS B file (usually named ``eopc04_IAU2000.62-now``).
    N   c                     |t           }|t          }t                                          |d||          }||j        d<   ||j        d<   |S )a<  Read IERS-B table from a eopc04.* file provided by IERS.

        Parameters
        ----------
        file : str
            full path to ascii file holding IERS-B data.
            Defaults to package version, ``iers.IERS_B_FILE``.
        readme : str
            full path to ascii file holding CDS-style readme.
            Defaults to package version, ``iers.IERS_B_README``.
        data_start : int
            Starting row. Default is 6, appropriate for standard IERS files.

        Returns
        -------
        ``IERS_B`` class instance

        Notes
        -----
        To read a pre-2023 style IERS B file (usually named something like
        ``eopc04_IAU2000.62-now``), do something like this example with an
        excerpt that is used for testing::

            >>> from astropy.utils.iers import IERS_B
            >>> from astropy.utils.data import get_pkg_data_filename
            >>> old_style_file = get_pkg_data_filename(
            ...     "tests/data/iers_b_old_style_excerpt",
            ...     package="astropy.utils.iers")
            >>> iers_b = IERS_B.read(
            ...     old_style_file,
            ...     readme=get_pkg_data_filename("data/ReadMe.eopc04_IAU2000",
            ...                                  package="astropy.utils.iers"),
            ...     data_start=14)

        Nr   )r   r   
data_startr   r   )r$   r&   r   rt   r   )ru   rp   r   r  r   r   s        rG   rt   zIERS_B.read  sT    J <D>"FT%:VV"&
;$*
=!rF   c                 :    t          j        |          t          z  S )r  rV   r  r   r   s     rG   r   zIERS_B.ut1_utc_source      |A,,rF   c                 :    t          j        |          t          z  S )r  r  r   s     rG   r   zIERS_B.dcip_source  r  rF   c                 :    t          j        |          t          z  S )z-Set PM source flag for entries in IERS table.r  r   s     rG   r   zIERS_B.pm_source  r  rF   )NNr  )rA   rB   rC   rD   rq   r   rt   r   r   r   r   r   s   @rG   r   r     s          J- - - - - [-^- - -- - -- - - - - - -rF   r   c                   N    e Zd ZdZdZed             Zd Zd Zed             Z	dS )r   zp
    Provide most-recent IERS data and automatically handle downloading
    of updated values as necessary.
    Nc                    t           j        s%t                                          | _        | j        S t           j        t           j        f}| j        (| j        j                            d          |v r| j        S |D ]}	 t          |d          }n2# t          $ r%}t          d| d| t                     Y d}~?d}~ww xY w	 |                     |          | _        n2# t          $ r%}t          d| d| t                     Y d}~d}~ww xY w|| j        j        d<    n3t          d	t                     t                                          | _        | j        S )
a  If the configuration setting ``astropy.utils.iers.conf.auto_download``
        is set to True (default), then open a recent version of the IERS-A
        table with predictions for UT1-UTC and polar motion out to
        approximately one year from now.  If the available version of this file
        is older than ``astropy.utils.iers.conf.auto_max_age`` days old
        (or non-existent) then it will be downloaded over the network and cached.

        If the configuration setting ``astropy.utils.iers.conf.auto_download``
        is set to False then ``astropy.utils.iers.IERS()`` is returned.  This
        is normally the IERS-B table that is supplied with astropy.

        On the first call in a session, the table will be memoized (in the
        ``iers_table`` class attribute), and further calls to ``open`` will
        return this stored table.

        Returns
        -------
        `~astropy.table.QTable` instance
            With IERS (Earth rotation) data columns

        Ndata_urlTrm   failed to download : ro   zmalformed IERS table from z6unable to download valid IERS file, using local IERS-B)r   rb   r   rv   rq   rd   re   r   getrR   r~   r   r)   rt   )ru   all_urlsurlfilenameerrs        rG   rv   zIERS_Auto.open  s   . ! 	"#[[]]CN>!&(AB>% ~"&&z22h>>~% 	+ 	+C(D999   7377#77EEE!$x!8!8   >#>>>>LLL /2CN
+E I;WWW#[[]]CN~s0   >B
B?B::B?C
D)D		Dc                     | j         d         }t          t          j                  }||k    r:| j        j        |z
  |k    r)t          t                              |                    dS dS )aF  Check that the indices from interpolation match those after clipping to the
        valid table range.  The IERS_Auto class is exempted as long as it has
        sufficiently recent available data so the clipped interpolation is
        always within the confidence bounds of current Earth rotation
        knowledge.
        r   N)	r   r[   r   rc   r   r   
ValueErrorINTERPOLATE_ERRORr   )r   r   r   r   r   rc   s         rG   r   z$IERS_Auto._check_interpolate_indices,  sn     #34 &d&788N**!N2\AA.55lCCDDD +*AArF   c           
         t          j        |          }| j        j        }| j        d         }| j        d         }t          t          j                  }|dk     rt          d          ||k    r||z
  |k    rt          j	        t          j
        f}	 t          |d         |d          }nN# t          $ rA}	t          t          dd	                    |           d
|	 d                     Y d}	~	dS d}	~	ww xY w| j                            |          }
t%          |d                   |
j        d<   |
d         d         | d         d         k    rt          j        |
d         j        |d          }t+          |           |z
  }|
|||z            | |d<   |
d         ||z            | d         d         z
  dt,          j        z  k    rt          d          |
||z   d         D ]}|                     |           | j                            |
j                   dS t          t5          dt          j         d                     dS dS dS )a  Potentially update the IERS table in place depending on the requested
        time values in ``mjd`` and the time span of the table.

        For IERS_Auto the behavior is that the table is refreshed from the IERS
        server if both the following apply:

        - Any of the requested IERS values are predictive.  The IERS-A table
          contains predictive data out for a year after the available
          definitive values.
        - The first predictive values are at least ``conf.auto_max_age days`` old.
          In other words the IERS-A table was created by IERS long enough
          ago that it can be considered stale for predictions.
        r   r   
   zAIERS auto_max_age configuration value must be larger than 10 daysr   rs   )sourcesrn   r  z and r  z.
A coordinate or time-related calculation might be compromised or fail because the dates are not covered by the available IERS file.  See the "IERS data access" section of the astropy documentation for additional information on working offline.Nro   r  r   r1   r   r   g      ?z0unexpected gap in MJD when refreshing IERS tablez+IERS_Auto predictive values are older than z@ days but downloading the latest table did not find newer values)rV   rY   r   r   r   r[   r   rc   r   rd   re   rR   r~   r   r   joinr   rt   strr   rZ   r   udadd_rowrs   r(   )r   r   r   now_mjdfpir   rc   r  r  r  	new_tablenew_fpi	n_replacerows                 rG   r   z"IERS_Auto._refresh_table_as_needed=  s    s-# i*+#34 &d&788 "S   >))w/G<.W.W*D,EFH(!hhWWW    "$gll8.D.D $ $ $ $ $ 	 	 	   +++::I),Xa[)9)9IN:& #d5k"o55 /e$*N    IIO	&w91D'DESTT
 U#Gi$784;r?JcTUTWiWW$%WXXX %Wy%8%:%:; & &CLL%%%%	  00000$5 -5 5 5     ] *).W.Ws   B, ,
C766C22C7c                 |   t                                           }|d         t          j        |d                            }t          j        |d         |d         d          }t          j        |d         |d         d          }|||         }t          |          }|dk    rt          j        |d         d|         |d                   st          d	          |d
         |d         d|<   |d         |d         d|<   |d         |d         d|<   |d         |d         d|<   |d         |d         d|<   |S )aM  Substitute IERS B values with those from a real IERS B table.

        IERS-A has IERS-B values included, but for reasons unknown these
        do not match the latest IERS-B values (see comments in #4436).
        Here, we use the bundled astropy IERS-B table to overwrite the values
        in the downloaded IERS-A table.
        r   r   r   leftr   r1   r   NzAunexpected mismatch when copying IERS-B values into IERS-A table.r   r   r   r   r   r   r   r   r   )	r   rv   rV   r   r   r   r'  allcloser   )ru   r   iers_bmjd_br   r   n_iers_bs          rG   r   zIERS_Auto._substitute_iers_b  s@    eR[{);<<=_VE]E!H6BBB_VE]E"IGDDD2v;;a<<:eEl9H95ve}EE  W   -39,=E+yy))/E(OIXI&)/E(OIXI&-3J-?E,		*-3J-?E,		*rF   )
rA   rB   rC   rD   rq   r   rv   r   r   r   rE   rF   rG   r   r     s         
 J9 9 [9vE E E"T T Tl   [  rF   r   c                   ,    e Zd ZdZdZed             ZdS )r   a  Default IERS table for Earth rotation and reference systems service.

    These tables are used to calculate the offsets between ``UT1`` and ``UTC``
    and for conversion to Earth-based coordinate systems.

    The state itself is an IERS table, as an instance of one of the
    `~astropy.utils.iers.IERS` classes.  The default, the auto-updating
    `~astropy.utils.iers.IERS_Auto` class, should suffice for most
    purposes.

    Examples
    --------
    To temporarily use the IERS-B file packaged with astropy::

      >>> from astropy.utils import iers
      >>> from astropy.time import Time
      >>> iers_b = iers.IERS_B.open(iers.IERS_B_FILE)
      >>> with iers.earth_orientation_table.set(iers_b):
      ...     print(Time('2000-01-01').ut1.isot)
      2000-01-01T00:00:00.355

    To use the most recent IERS-A file for the whole session::

      >>> iers_a = iers.IERS_A.open(iers.IERS_A_URL)  # doctest: +SKIP
      >>> iers.earth_orientation_table.set(iers_a)  # doctest: +SKIP
      <ScienceState earth_orientation_table: <IERS_A length=17463>...>

    To go back to the default (of `~astropy.utils.iers.IERS_Auto`)::

      >>> iers.earth_orientation_table.set(None)  # doctest: +SKIP
      <ScienceState earth_orientation_table: <IERS_Auto length=17428>...>
    Nc                     |t                                           }t          |t                    st	          d          |S )Nz/earth_orientation_table requires an IERS Table.)r   rv   r   r   r   )ru   rZ   s     rG   validatez earth_orientation_table.validate  s=    =NN$$E%&& 	PNOOOrF   )rA   rB   rC   rD   _valuer   r8  rE   rF   rG   r   r     s?         B F  [  rF   r   c                      e Zd ZdZ ej        d          ZdZdedddgZ		 e
dd	            Zed
             Ze
dd            Zed             Ze
d             Ze
efd            Ze
d             Ze
dd            ZddZdS )r+   a  Leap seconds class, holding TAI-UTC differences.

    The table should hold columns 'year', 'month', 'tai_utc'.

    Methods are provided to initialize the table from IERS ``Leap_Second.dat``,
    IETF/ntp ``leap-seconds.list``, or built-in ERFA/SOFA, and to update the
    list used by ERFA.

    Notes
    -----
    Astropy has a built-in ``iers.IERS_LEAP_SECONDS_FILE``. Up to date versions
    can be downloaded from ``iers.IERS_LEAP_SECONDS_URL`` or
    ``iers.LEAP_SECONDS_LIST_URL``.  Many systems also store a version
    of ``leap-seconds.list`` for use with ``ntp`` (e.g., on Debian/Ubuntu
    systems, ``/usr/share/zoneinfo/leap-seconds.list``).

    To prevent querying internet resources if the available local leap second
    file(s) are out of date, set ``iers.conf.auto_download = False``. This
    must be done prior to performing any ``Time`` scale transformations related
    to UTC (e.g. converting from UTC to TAI).
    z,^#.*File expires on[:\s]+(\d+\s\w+\s\d+)\s*$Nerfarg   rh   ri   Fc                 F   ||                                  S |                                dk    r|                                 S t          |          j        rt          ||          }	 |                     |          S # t          $ r |                     |          cY S w xY w)a  Open a leap-second list.

        Parameters
        ----------
        file : path-like or None
            Full local or network path to the file holding leap-second data,
            for passing on to the various ``from_`` class methods.
            If 'erfa', return the data used by the ERFA library.
            If `None`, use default locations from file and configuration to
            find a table that is not expired.
        cache : bool
            Whether to use cache. Defaults to False, since leap-second files
            are regularly updated.

        Returns
        -------
        leap_seconds : `~astropy.utils.iers.LeapSeconds`
            Table with 'year', 'month', and 'tai_utc' columns, plus possibly
            others.

        Notes
        -----
        Bulletin C is released about 10 days after a possible leap second is
        introduced, i.e., mid-January or mid-July.  Expiration days are thus
        generally at least 150 days after the present.  For the auto-loading,
        a list comprised of the table shipped with astropy, and files and
        URLs in `~astropy.utils.iers.Conf` are tried, returning the first
        that is sufficiently new, or the newest among them all.
        Nr;  rm   )		auto_openlower	from_erfar   rr   rR   from_iers_leap_secondsr~   from_leap_seconds_list)ru   rp   rn   s      rG   rv   zLeapSeconds.open  s    > <==??"::<<6!!==??"D>>  	4 U333D	4--d333 	4 	4 	4--d33333	4s   )A> >B B c                      d                     t          j        t          j                            } t          | ddd          S )N&{0.year:04d}-{0.month:02d}-{0.day:02d})tztaiisodate)scaler   
out_subfmt)r   r   r   r   r{   r   )ss    rG   _todayzLeapSeconds._today4  sD     5;;LHL)))
 
 AU5VDDDDrF   c                    dt           j        dnt           j        z
  }|                                 t          |d          z   }|d | j        D             }d |D             }d |D             }t           j        r|d	 |D             z  }d}g }|D ]\  }}|st          |           	 |                     |d
          }	n,# t          $ r}
|	                    |
           Y d}
~
Sd}
~
ww xY w||	j
        |j
        k    r&|	}t          |          |j        d<   |j
        |k    r n|t          d|           |j
        |                                k     r!t           j        t          dt                     |S )ak  Attempt to get an up-to-date leap-second list.

        The routine will try the files in sequence until it finds one
        whose expiration date is "good enough" (see below).  If none
        are good enough, it returns the one with the most recent expiration
        date, warning if that file is expired.

        For remote files that are cached already, the cached file is tried
        first before attempting to retrieve it again.

        Parameters
        ----------
        files : list of path-like, optional
            List of files/URLs to attempt to open.  By default, uses
            ``cls._auto_open_files``.

        Returns
        -------
        leap_seconds : `~astropy.utils.iers.LeapSeconds`
            Up to date leap-second table

        Notes
        -----
        Bulletin C is released about 10 days after a possible leap second is
        introduced, i.e., mid-January or mid-July.  Expiration days are thus
        generally at least 150 days after the present.  We look for a file
        that expires more than 180 - `~astropy.utils.iers.Conf.auto_max_age`
        after the present.
           N   jd)r   c                 :    g | ]}t          t          ||          S rE   )r   r   .0fs     rG   
<listcomp>z)LeapSeconds.auto_open.<locals>.<listcomp>b  s$    GGGQWT1a((GGGrF   c                     g | ]}||S rE   rE   rQ  s     rG   rT  z)LeapSeconds.auto_open.<locals>.<listcomp>e  s    '''qQ''''rF   c                 \    g | ])}t          |          j        rt          |          %|d f*S )T)r   rr   r   rQ  s     rG   rT  z)LeapSeconds.auto_open.<locals>.<listcomp>j  sK     
 
 
HQKK,>
BQRSBTBT
I
 
 
rF   c                 >    g | ]}t          |          j        |d fS F)r   rr   rQ  s     rG   rT  z)LeapSeconds.auto_open.<locals>.<listcomp>p  s*    GGGaHQKK4FG5zGGGrF   Trm   r  zDnone of the files could be read. The following errors were raised:
 zleap-second file is expired.)r   rc   rK  r   _auto_open_filesrb   r   rv   r~   r   expiresr&  r   r   r   r(   )ru   filesoffsetgood_enoughtrialsr   err_listrS  allow_cachetrialexcs              rG   r=  zLeapSeconds.auto_open=  s   > d/7T=NOjjllYvd%C%C%CC= HG#2FGGGE ('E'''

 
$
 
 

  	HGG5GGGGF % 	 	NA{ ($Q'''$//   $$$ |u}t|;;(+A	*%<+--E<>3;> >  
 <$++--''D,=,I/1ABBBs   'B??
C(	C##C(c                     | j         S )z#The limit of validity of the table.)_expiresr   s    rG   rZ  zLeapSeconds.expires  s     }rF   c           	         d}t          |          5 }|                                }|D ]}| j                            |          }|rr|                                d                                         \  }}	}
t                              |	dd                   dz   }t          |
 d|dd| dd	          } nt          d
|           	 ddd           n# 1 swxY w Y    | j
        |fddi|}||_        |S )z?Read a file, identifying expiration by matching 'File expires'.Nr      r/   -02drE  rG  )rH  rI  z did not find expiration date in r   zascii.no_header)r   	readlines_re_expiresmatchgroupssplit
MONTH_ABBRindexr   r   rt   rd  )ru   rp   rT   rZ  fhlineslinerk  daymonthyearmonth_nbr   s                rG   _read_leap_secondszLeapSeconds._read_leap_seconds  s    !$'' 	L2LLNNE 
L 
L--d33 ',||~~a'8'>'>'@'@$C)//bqb	::Q>H"66(66666ePV  G E !!JD!J!JKKK 	L 	L 	L 	L 	L 	L 	L 	L 	L 	L 	L 	L 	L 	L 	L sxBB&7B6BBs   B:CC Cc                 4    |                      |g d          S )a  Create a table from a file like the IERS ``Leap_Second.dat``.

        Parameters
        ----------
        file : path-like, optional
            Full local or network path to the file holding leap-second data
            in a format consistent with that used by IERS.  By default, uses
            ``iers.IERS_LEAP_SECOND_FILE``.

        Notes
        -----
        The file *must* contain the expiration date in a comment line, like
        '#  File expires on 28 June 2020'
        )r   rs  rt  ru  tai_utc)names)rw  )ru   rp   s     rG   r@  z"LeapSeconds.from_iers_leap_seconds  s-      %%BBB & 
 
 	
rF   c           	      l   ddl m} g d}|                     |||dd         d |t          j                  gi          }|d         dz  d	z                                   |d
<   t          |d
         d
d          j        }t          j        d |D                       }|j	        \  |d<   |d<   |d<   |S )a  Create a table from a file like the IETF ``leap-seconds.list``.

        Parameters
        ----------
        file : path-like, optional
            Full local or network path to the file holding leap-second data
            in a format consistent with that used by IETF.  Up to date versions
            can be retrieved from ``iers.IETF_LEAP_SECOND_URL``.

        Notes
        -----
        The file *must* contain the expiration date in a comment line, like
        '# File expires on:  28 June 2020'
        r   )convert_numpy)ntp_secondsry  commentrs  rt  ru  Nr0   r}  )rz  include_names
convertersiQ i:  r   rE  )r   rH  c                 ~    g | ]:}d  |                     d          d                             d          D             ;S )c                 ,    g | ]}t          |          S rE   )int)rR  parts     rG   rT  zALeapSeconds.from_leap_seconds_list.<locals>.<listcomp>.<listcomp>  s    CCCDc$iiCCCrF   Tr   rg  )	partitionrm  )rR  ts     rG   rT  z6LeapSeconds.from_leap_seconds_list.<locals>.<listcomp>  sF    RRRCCAKK$4$4Q$7$=$=c$B$BCCCRRRrF   ru  rt  rs  )
astropy.io.asciir|  rw  rV   int64r   r   isotr   r  )ru   rp   r|  rz  r   r  ymds          rG   rA  z"LeapSeconds.from_leap_seconds_list  s      	322222MMM %%)%bh(?(?'@A	 & 
 
 M*U2U:AACCUDKU;;;@hRRTRRR
 
 4750Vd7mT%[rF   c                     | t           j                                                  }t          d                    t           j        j                  d          |_        |s|S 	 t           j                            d           |                     d          t           j                            |           S # t           j                            |           w xY w)a)  Create table from the leap-second list in ERFA.

        Parameters
        ----------
        built_in : bool
            If `False` (default), retrieve the list currently used by ERFA,
            which may have been updated.  If `True`, retrieve the list shipped
            with erfa.
        rC  rE  )rH  NF)built_in)	r;  leap_secondsr  r   r   rZ  rd  setr?  )ru   r  currents      rG   r?  zLeapSeconds.from_erfa  s     #d'++--..4;;D<M<UVV
 
 
  	N	+!!$'''==%=00!!'****D!!'****s   %4B9 9!Cc                     |dk    r.t           j                            |            t          |           S |r&t           j                                         |dk    rdS t           j                            |           S )a  Add any leap seconds not already present to the ERFA table.

        This method matches leap seconds with those present in the ERFA table,
        and extends the latter as necessary.

        Parameters
        ----------
        initialize_erfa : bool, or 'only', or 'empty'
            Initialize the ERFA leap second table to its built-in value before
            trying to expand it.  This is generally not needed but can help
            in case it somehow got corrupted.  If equal to 'only', the ERFA
            table is reinitialized and no attempt it made to update it.
            If 'empty', the leap second table is emptied before updating, i.e.,
            it is overwritten altogether (note that this may break things in
            surprising ways, as most leap second tables do not include pre-1970
            pseudo leap-seconds; you were warned).

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

        Raises
        ------
        ValueError
            If the leap seconds in the table are not on 1st of January or July,
            or if the matches are inconsistent.  This would normally suggest
            a corrupted leap second table, but might also indicate that the
            ERFA table was corrupted.  If needed, the ERFA table can be reset
            by calling this method with an appropriate value for
            ``initialize_erfa``.
        emptyonlyr   )r;  r  r  r   rs   )r   initialize_erfas     rG   update_erfa_leap_secondsz$LeapSeconds.update_erfa_leap_seconds  sw    B g%%!!$'''t99 	!!###&((q ''---rF   r   r   rX  )rA   rB   rC   rD   recompilerj  rd  r,   rY  r   rv   staticmethodrK  r=  r   rZ  rw  r@  rA  r?  r  rE   rF   rG   r+   r+     s^        2 "*LMMKH!## 8+4 +4 +4 [+4Z E E \E Q Q Q [Qf   X   [, )> 
 
 
 [
& ! ! [!F + + + [+0+. +. +. +. +. +.rF   r+   )CrD   r  r   r   urllib.parser   warningsr   r;  numpyrV   astropyr   r`   r   r'  r	   astropy.tabler
   r   astropy.timer   r   astropy.utils.datar   r   r   r   astropy.utils.exceptionsr   astropy.utils.stater   __all__r    r!   r"   r#   r$   r%   r&   r,   r-   r.   r   r   r   r   r   r   r!  rn  r)   r*   r(   rR   r[   ConfigNamespacer   r   
IndexErrorr'   r   r   r   r   r   r+   rE   rF   rG   <module>r     s"    
			 ' ' ' ' ' ' ' ' ! ! ! ! ! !            % % % % % %             . . . . . . . . ( ( ( ( ( ( ( (            4 3 3 3 3 3 , , , , , ,  >  A
E %%&?@@ $#$:;;F
%%&:;; .-.DEE N P        
     .       .       {   9 9 9&? ? ?) ) ) ) )7" ) ) )X tvv    Z   D3 D3 D3 D3 D36 D3 D3 D3N
w w w w wT w w wtJ- J- J- J- J-T J- J- J-ZI I I I I I I IX* * * * *l * * *ZH. H. H. H. H.& H. H. H. H. H.rF   