
    HR-e<_                     ~   d dl Z d dlZd dlmZmZ d dlZd dlmZ	 d dl
mZ d dlmZmZ d dlmZ d dlmZmZ d dlmZ d d	lmZ d d
lmZ ddlmZmZ  e j        d          Z e j        d          Zg dZ dZ!dZ"de"z   e!z   Z#dZ$dd%                    e$           dZ&d Z'ddddZ(d Z)d Z*d Z+d Z,d  Z-d! Z.d" Z/d# Z0dS )$    N)OrderedDictdefaultdict)units)EarthLocation)ColumnMaskedColumn)col_copy)Time	TimeDelta)BARYCENTRIC_SCALES)FITS_DEPRECATED_SCALES)AstropyUserWarning   )CardHeaderz(?P<type>[A-Z]+)[-]+z(?P<algo>[A-Z]+)\s*)	sdacyminhyrtaBa)zOBSGEO-XzOBSGEO-YzOBSGEO-Z)zOBSGEO-LzOBSGEO-BzOBSGEO-H)DATEzDATE-AVGzDATE-BEGzDATE-ENDzDATE-OBSDATEREFJDREFzMJD-AVGzMJD-BEGzMJD-ENDzMJD-OBSMJDREFTIMEOFFSTIMESYSTIMEUNITTREFDIRTREFPOS)TCTYPTCUNITRPOS(|z)[0-9]+c                 :    t          j        t          |           duS )z
    Check if the FITS header keyword is a time column-specific keyword.

    Parameters
    ----------
    keyword : str
        FITS keyword.
    N)rematchCOLUMN_TIME_KEYWORD_REGEXP)keywords    8lib/python3.11/site-packages/astropy/io/fits/fitstime.pyis_time_column_keywordr/   F   s     8.88DD    )UTCzDefault time scale)g        zTime columns are jd = jd1 + jd2)
TOPOCENTERzTime reference position)r    r   r#   c                     t          j         d          d                                                    d<    d         t          j        vr d         dk    r$t          j        dt                     d d<   d d<    d         dk    r%t          j        dt                     d	 d<   d
 d<   n-t          d	                     d                             d
 d<    fdt          D             }t          |          dk    rt          j        |dt          j        i d<   n|r-t          j        d	                    |          t                      fdt           D             }t          |          dk    rt          j        |  d<   n4|r-t          j        d	                    |          t                     d
 d<   dD ]\  }}| v r |         |d d<    d
S ddd d<   d
S )z
    Given the global time reference frame information, verify that
    each global time coordinate attribute will be given a valid value.

    Parameters
    ----------
    global_info : dict
        Global time reference frame information.
    r    scalegpszGlobal time scale (TIMESYS) has a FITS recognized time scale value "GPS". In Astropy, "GPS" is a time from epoch format which runs synchronously with TAI; GPS is approximately 19 s ahead of TAI. Hence, this format will be used.taiformatlocala+  Global time scale (TIMESYS) has a FITS recognized time scale value "LOCAL". However, the standard states that "LOCAL" should be tied to one of the existing scales because it is intrinsically unreliable and/or ill-defined. Astropy will thus use the default global time scale "UTC" instead of "LOCAL".utcNzGlobal time scale (TIMESYS) should have a FITS recognized time scale value (got {!r}). The FITS standard states that the use of local time scales should be restricted to alternate coordinates.c                 (    g | ]}|v |         S  r;   .0attrglobal_infos     r.   
<listcomp>z'_verify_global_info.<locals>.<listcomp>   s(    OOOT4;;N;N{4 ;N;N;Nr0      unitlocationzaThe geocentric observatory location {} is not completely specified (X, Y, Z) and will be ignored.c                 (    g | ]}|v |         S r;   r;   r<   s     r.   r@   z'_verify_global_info.<locals>.<listcomp>   s(    SSSt{?R?R;t$?R?R?Rr0   zeThe geodetic observatory location {} is not completely specified (lon, lat, alt) and will be ignored.))r   mjd)r   jd)r   fits)valr7   ref_timer   rE   )r   getlowerr
   SCALESwarningswarnr   AssertionErrorr7   
OBSGEO_XYZlenr   from_geocentricum
OBSGEO_LBHfrom_geodetic)r?   obs_geokeyformat_s   `   r.   _verify_global_inforZ   Z   so    25II 6 < < > > K
 74;.. w5((MA #   $)K $)K!w7**M>
 #   $)K $(K!! !  &vk)&<==	   !%H POOOZOOOG 7||q"/"?"Sqs"S"SJ
  	M;;A6'??"   TSSSSSSw<<1&3&A7&KK
##  EEKVG__&  
 '+K
# R > >W+.9#.>'&R&RK
#EE 
 +,u"="=Jr0   c                    |                      dd          }|                      dd          }|                      dd          }|Ut                              |dd                   r$t                              |dd                   rdS |                                t
          j        v r|                                | d<   d| d<   n|t          j                    v rt          |         | d<   d| d<   n|d	k    r|d         | d<   |d         | d<   n|d
k    r8t          j
        d                    |           t                     d| d<   d| d<   nr|dk    rDt          j
        d                    |           t                     |d         | d<   |d         | d<   n(dS |	|t          v s||d         | d<   |d         | d<   ndS |:|dk    r.|d         | d<   | d         t          j
        dt                     n?d| d<   n9|d         dk    r(|d         t          j
        dt                     d| d<   nd| d<   |d         | d<   dS )a  
    Given the column-specific time reference frame information, verify that
    each column-specific time coordinate attribute has a valid value.
    Return True if the coordinate column is time, or else return False.

    Parameters
    ----------
    global_info : dict
        Global time reference frame information.
    column_info : dict
        Column-specific time reference frame override information.
    r$   Nr%   r&      Fr4   r7   TIMEGPSzTable column "{}" has a FITS recognized time scale value "GPS". In Astropy, "GPS" is a time from epoch format which runs synchronously with TAI; GPS runs ahead of TAI approximately by 19 s. Hence, this format will be used.r6   r5   LOCALa  Table column "{}" has a FITS recognized time scale value "LOCAL". However, the standard states that "LOCAL" should be tied to one of the existing scales because it is intrinsically unreliable and/or ill-defined. Astropy will thus use the global time scale (TIMESYS) as the default.r2   rC   zTime column reference position "TRPOSn" value is "TOPOCENTER". However, the observatory position is not properly specified. The FITS standard does not support this and hence reference position will be ignored.r#   zTime column reference position "TRPOSn" is not specified. The default value for it is "TOPOCENTER", and the observatory position has been specified. However, for supporting column-specific location, reference position will be ignored for this column.rI   T)rJ   TCTYP_RE_TYPEr+   TCTYP_RE_ALGOrK   r
   rL   r   keysrM   rN   r7   r   FITS_TIME_UNIT)column_infor?   r4   rB   rC   s        r.   _verify_column_infore      s    OOGT**E??7D))Dw--HuRaRy)) +	m.A.A%).L.L +	5[[]]dk))#(;;==K $(K!!,13333#9%#@K $(K!! f__#.w#7K $/$9K!!e^^M< =CF;<O<O"   $)K $)K!!gM, -3F;,?,?"   $/w#7K $/$9K!!
 5 
t~55(:N*73G +H 5H u  |##&1*&=K
#:&.0 '   '+K
## 
Y	<	/	/z".MF #   #'J"&J **5K
4r0   c                 R   | j         j                                        dk    r| j         j        t          v rq|d         |d         |d         dd}|d         dk    rJ|d	         |d	<   |d	         7t          j        d
                    | j         j                  t                     |S dS )a/  
    Check if a column without corresponding time column keywords in the
    FITS header represents time or not. If yes, return the time column
    information needed for its conversion to Time.
    This is only applicable to the special-case where a column has the
    name 'TIME' and a time unit.
    r]   r4   r7   rI   N)r4   r7   rI   rC   r#   r2   rC   z\Time column "{}" reference position will be ignored due to unspecified observatory position.)	infonameupperrB   rc   rM   rN   r7   r   )colr?   rd   s      r.   _get_info_if_time_columnrk   1  s     x}&&38=N+J+J )!(+#J/	
 
 y!\11&1*&=K
#:&.??Evchm?T?T&   4r0   c                     |                                 D ]8\  }}|| j        vr*	 t          ||          | j        |<   (# t          $ r Y 4w xY w9dS )a  
    Convert the table metadata for time informational keywords
    to astropy Time.

    Parameters
    ----------
    table : `~astropy.table.Table`
        The table whose time metadata is to be converted.
    global_info : dict
        Global time reference frame information.
    N)itemsmeta_convert_time_key
ValueError)tabler?   rX   values       r.   _convert_global_timers   Q  s{     "''))  
Uej  "3K"E"E
3    ! s   =
A
	A
c                 V   | |         }|                     d          rQ|dk    rdn| d         }d|v r(t          |                    d          d                   nd}t          |d||          S |                     d	          rt          |d
| d                   S t	          d          )aF  
    Convert a time metadata key to a Time object.

    Parameters
    ----------
    global_info : dict
        Global time reference frame information.
    key : str
        Time key.

    Returns
    -------
    astropy.time.Time

    Raises
    ------
    ValueError
        If key is not a valid global time keyword.
    r   r9   r4   .r   rG   )r7   r4   	precisionzMJD-rE   )r7   r4   z&Key is not a valid global time keyword)
startswithrQ   splitr
   rp   )r?   rX   rr   r4   rw   s        r.   ro   ro   g  s    ( E
~~f CK,@14CC((,---1	E&KKKK			 CE%{7/CDDDDABBBr0   c                    	 | j         j        j        dv rWt          t	          | j         j        j        dd                   dz
  d          }t          | d|d         ||d         	          S |d
         dk    rt          | d|d                   S |d         d         dk    r|d         d
         dv r| j        d         dk    rC| j        dk    r8t          | d         | d         |d         |d         d
         |d                   S t          | |d         |d         d
         |d                   S t          |d         d         |d         |d         d
         |d                   }| j        d         dk    r(| j        dk    rt          | d         | d                   }nt          |           }||z   S # t          $ rD}t          j        d                    || j         j                  t                     | cY d}~S d}~ww xY w)a  
    Convert time columns to astropy Time columns.

    Parameters
    ----------
    col : `~astropy.table.Column`
        The time coordinate column to be converted to Time.
    column_info : dict
        Column-specific time reference frame override information.
    )SU   N   r   rG   r4   rC   )r7   r4   rw   rC   r7   r5   )r7   rC   rI   rH   )rF   rE   rv   r   ).r   ).r   )r4   r7   rC   z`The exception "{}" was encountered while trying to convert the time column "{}" to Astropy Time.)rg   dtypekindmaxintstrr
   shapendimr   	ExceptionrM   rN   r7   rh   r   )rj   rd   rw   rI   
delta_timeerrs         r.   _convert_time_columnr     sY   =8>*,, C 2122 677"<a@@I!'*#$Z0    x E))EK
4KLLLL
 z"5)Q..;z3J4
4 4 y}!!chllKK%g.&z28<(4    %g.&z28<(4	    
#E*g&z*84 ,	
 
 
 9R=A#(Q,,"3v;F<<JJ"3J*$$   ++16#sx}+E+E	
 	
 	

 





s8   A)F5 ,#F5 A5F5 *F5 1BF5 5
H?9G>8H>Hc                 t   ddd}t          t                    }|                     d          }| j        D ]\  }}}|t          v r|||<   |                    |           *t          |          rXt          j        d|          	                                \  }}	||t          |	                   |<   |                    |           |t          v r t          j        d|          r||         ||<   t          |           t          ||           |rS|                                D ]>\  }	}
t          |
|          r)|j        |	dz
           }t#          ||         |
          ||<   ?t%          |j                  D ]=\  }	}|	dz   |vr1t'          ||         |          }
|
rt#          ||         |
          ||<   >|S )	as  
    Read FITS binary table time columns as `~astropy.time.Time`.

    This method reads the metadata associated with time coordinates, as
    stored in a FITS binary table header, converts time columns into
    `~astropy.time.Time` columns and reads global reference times as
    `~astropy.time.Time` instances.

    Parameters
    ----------
    hdr : `~astropy.io.fits.header.Header`
        FITS Header
    table : `~astropy.table.Table`
        The table whose time columns are to be read as Time

    Returns
    -------
    hdr : `~astropy.io.fits.header.Header`
        Modified FITS Header (time metadata removed)
    r1   r2   )r    r#   T)stripz([A-Z]+)([0-9]+)zTTYPE[0-9]+r   )r   r   copycardsTIME_KEYWORDSremover/   r*   r+   groupsr   rP   rZ   rs   rm   re   colnamesr   	enumeraterk   )hdrrq   r?   time_columnshcopyrX   rr   commentbaseidxrd   colnames               r.   fits_to_timer     s   , $==K {++L HH4H  E  #y . .UG-$KLL#C(( 	.!4c::AACCID#+0LS"4(LLj  RXmS%A%A !&uK $$$,,,  S , 2 2 4 4 	S 	SC";<< S.q1!5eGnk!R!Rg "%.11 S SW!GL((25>;OOK S!5eGnk!R!RgLr0   c           
      v   g }|                                  D ]b}t          |t                    r|                    d          }n|j        j        rt          |d          n|}|                    |           c|                     |d          }| j	        |_	        t          d t                                          D                       }t          t                    |j	        d<   |j	        d         }| j                            t                     }d|D ]}|j        rt$          nt          }|j        j        d         d	k    r/|                    |j        j         ||j                             ]t/          j        |j        |j        gd
          }	|                    |j        j         ||	d                     |j                                        ||j        j                 d<   d||j        j                 d<   |j        Pd||j        j                 d<   7t=          j        d                     |j        j                  tB                     Bd||j        j                 d<   |j        tD          v rOt=          j        d                     |j        j        |j                                                  tB                     |j        j#        dk    rkdD ]f}
|$                    t          tK          |
          &                    tN          j(                            d|
                                            g3|)                    fddD                        Vt/          j*        |j        k              r(tW          d                     |j                            ||fS )as  
    Replace Time columns in a Table with non-mixin columns containing
    each element as a vector of two doubles (jd1, jd2) and return a FITS
    header with appropriate time coordinate keywords.
    jd = jd1 + jd2 represents time in the Julian Date format with
    high-precision.

    Parameters
    ----------
    table : `~astropy.table.Table`
        The table whose Time columns are to be replaced.

    Returns
    -------
    table : `~astropy.table.Table`
        The table with replaced Time columns
    hdr : `~astropy.io.fits.header.Header`
        Header containing global time reference frame FITS keywords
    F)	copy_data)copy_indices)r   c                 P    g | ]#\  }}t          ||d          |d                   $S )r   r   )r-   rr   r   )r   )r=   rX   rH   s      r.   r@   z time_to_fits.<locals>.<listcomp><  sC     	
 	
 	
S CFCF;;;	
 	
 	
r0   __coordinate_columns__NrG   formatted_valuerv   )axisr   )rB   
coord_type
coord_unittime_ref_poszTime Column "{}" has no specified location, but global Time Position is present, which will be the default for this column in FITS specification.r2   zQEarth Location "TOPOCENTER" for Time Column "{}" is incompatible with scale "{}".r   )xyzOBSGEO-)rh   c           	          g | ]S}t          d |                                 t          |                              t          j                            TS )r   )r-   rr   )r   ri   getattrto_valuerS   rT   )r=   dimrC   s     r.   r@   z time_to_fits.<locals>.<listcomp>~  sj       
 !$	 !(?#))++(?(?&-h&<&<&E&Eac&J&J    r0   zMultiple Time Columns with different geocentric observatory locations ({}, {}) encountered.This is not supported by the FITS standard.),itercols
isinstancer   r   rg   indicesr	   append	__class__rn   r   GLOBAL_TIME_INFOrm   r   r   columnsr
   maskedr   serialize_methodreplace_columnrh   rr   npstackjd1jd2r4   ri   rC   rM   rN   r7   r   r   size
add_columnr   r   rS   rT   extendanyrp   )rq   new_colsrj   new_colnewtabler   
coord_meta	time_colscol_clsjd12r   rC   s              @r.   time_to_fitsr     s   2 H~~ ! !c6"" 	Uhhh//GG;>8;KThs7777QTG    xe44HJHM 	
 	
,2244	
 	
 	
 C /:+.F.FHM*+78J((..I H B B #&*8,,&8$V,0AAA##CHM77393E3EFFF x#'*444 	wwt#/F/F/FGGG 36)//2C2C
38=!,/25
38=!,/ <8<Jsx}%n5#--3VCHM-B-B&	   9EJsx}%n5y...''-vchmSY__=N=N'O'O&   <=1$$.   ++"78S#9#9#B#B13#G#GHH!8399;;!8!8 ,     JJ   
 (7      CL011  BBH& #,C C   S=r0   )1r*   rM   collectionsr   r   numpyr   astropyr   rS   astropy.coordinatesr   astropy.tabler   r   astropy.table.columnr	   astropy.timer
   r   astropy.time.corer   astropy.time.formatsr   astropy.utils.exceptionsr    r   r   compiler`   ra   rc   rP   rU   r   COLUMN_TIME_KEYWORDSjoinr,   r/   r   rZ   re   rk   rs   ro   r   r   r   r;   r0   r.   <module>r      s>   
			  0 0 0 0 0 0 0 0           - - - - - - . . . . . . . . ) ) ) ) ) ) ( ( ( ( ( ( ( ( 0 0 0 0 0 0 7 7 7 7 7 7 7 7 7 7 7 7         
233
122 EDD 2
1
& '( ) 4 3  I*>!?!?HHH 	E 	E 	E -58  d> d> d>Nm m m`  @  ,C C C@I I IXA A AHx x x x xr0   