
    HR-eHS                     \   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	m
Z
 ddlmZ dd	lmZmZmZ  G d
 de          Z G d de          Z G d dej                  Z G d dej                  Z G d dej                  Z G d dej                  Z G d dej                  ZdS )zAn extensible ASCII table reader and writer.

ipac.py:
  Classes to read IPAC table format

:Copyright: Smithsonian Astrophysical Observatory (2011)
:Author: Tom Aldcroft (aldcroft@head.cfa.harvard.edu)
    N)OrderedDictdefaultdict)wrap)warn)get_auto_format_func)AstropyUserWarning   )basiccore
fixedwidthc                        e Zd Z fdZ xZS )IpacFormatErrorDBMSc                 l    d                     t                                                      d          S )N	{}
See {}zIhttps://irsa.ipac.caltech.edu/applications/DDGEN/Doc/DBMSrestriction.htmlformatsuper__str__self	__class__s    5lib/python3.11/site-packages/astropy/io/ascii/ipac.pyr   zIpacFormatErrorDBMS.__str__   s/    ""GGOOW
 
 	
    __name__
__module____qualname__r   __classcell__r   s   @r   r   r      8        
 
 
 
 
 
 
 
 
r   r   c                        e Zd Z fdZ xZS )IpacFormatErrorc                 l    d                     t                                                      d          S )Nr   zBhttps://irsa.ipac.caltech.edu/applications/DDGEN/Doc/ipac_tbl.htmlr   r   s    r   r   zIpacFormatError.__str__    s/    ""GGOOP
 
 	
r   r   r   s   @r   r"   r"      r    r   r"   c                   <    e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZd ZdS )	IpacHeaderSplitterzSplitter for Ipac Headers.

    This splitter is similar its parent when reading, but supports a
    fixed width format (as required for Ipac table headers) for writing.
    N| Fz\s*\\z\\c                     | j         pd}| j        pd}||z   |z   }||z   }||z   }d t          ||          D             }||                    |          z   |z   S )Nr'   c                 D    g | ]\  }}d |t          |          z
  z  |z   S ) len).0valwidths      r   
<listcomp>z+IpacHeaderSplitter.join.<locals>.<listcomp>?   s1    SSS:3us3xx'(3.SSSr   )delimiter_pad	delimiterzipjoin)r   valswidthspadr2   padded_delimbookend_leftbookend_rights           r   r4   zIpacHeaderSplitter.join8   sv     &BN(b	Y, 3iSST6ARARSSSl//555EEr   )r   r   r   __doc__process_lineprocess_valr2   r1   skipinitialspacecommentwrite_comment
col_startscol_endsr4    r   r   r%   r%   '   sb          LKIMGMJHF F F F Fr   r%   c                       e Zd ZdZeZdej        fdej        fdej        fdej        fdej        fdej	        fdej	        ffZ
d	Zd
Zd Zd Zd Zd Zd Zd Zd
S )
IpacHeaderzIPAC table header.integerlongdoublefloatrealchardateignoreNc              #      K   | j         j        }|D ]W}|                                }|                    |          r,|                    |          r|                    |          V  XdS )zGenerator to yield IPAC header lines, i.e. those starting and ending with
        delimiter character (with trailing whitespace stripped).
        N)splitterr2   rstrip
startswithendswithstrip)r   linesdelimlines       r   process_lineszIpacHeader.process_linesW   sx       ' 	( 	(D;;==Du%% ($--*>*> (jj'''''	( 	(r   c                    d }|d         }g |d<   t                      |d<   |d         }t          j        dt          j                  }|D ]}|                    d          s dS |                    |          }|r||                    d          }	 ||                    d                    }
|	|v r=t          |
t                    r(||	         d         }t          |t                    r||
z   }
d|
i||	<   |                    d	          r9|d
d         	                                }
|
r|d         
                    |
           dS )z
        Extract table-level comments and keywords for IPAC table.  See:
        https://irsa.ipac.caltech.edu/applications/DDGEN/Doc/ipac_tbl.html#kw.
        c                 (   |                                  } 	 t          |           } nl# t          $ r_ 	 t          |           } nK# t          $ r> dD ]8}|                     |          r!|                     |          r| dd         }  n9Y nw xY wY nw xY w| S )zw
            Take a string value and convert to float, int or str, and strip quotes
            as needed.
            )"'r	   )rS   int	ExceptionrI   rQ   rR   )r.   quotes     r   process_keyword_valuez5IpacHeader.update_meta.<locals>.process_keyword_valueg   s    
 ))++C"#hh 	" 	" 	""**CC  " " " ", " ">>%00 "S\\%5H5H ""%ad)C!E"	" Js3   & 
BA BAB	BB		BBtablecommentskeywordsz&\\(?P<name> \w+)\s* = (?P<value> .+) $\namevalue\    N)r   recompileVERBOSErQ   matchgroup
isinstancestrrS   append)r   rT   metar`   
table_metarc   
re_keywordrV   mre   r.   prev_vals               r   update_metazIpacHeader.update_metaa   s~   	 	 	( ']
!#
:!,
:j) Z& J	
 

  	; 	;D ??4((   &&A ;wwv++AGGG,<,<==
 8##
3(<(<#'~g6H!(C00 -&n")3 ??5)) ;qrr(..**C ;":.55c:::3	; 	;r   c                     | j         D ]5\  }}|                    |j                                                  r|c S 6t	          d|j         d|j         d          )NzUnknown data type ""z"" for column "rZ   )col_type_listrQ   raw_typelower
ValueErrorre   )r   colcol_type_keycol_types       r   get_col_typezIpacHeader.get_col_type   sy    &*&8 	 	"L(&&s|'9'9';';<<    Os|OOCHOOO  r   c                    |                      |          }d |                     |          D             }t          |          dk    rt          d          t          |          dk    rt          d          g }d}t	          |d                   D ]\  }}t          j        |                    d                    }||_        |t          |          z   |_	        t          |          dk    r@|d         |                             d          |_
        |                     |          |_        t          |          d	k    r'|d	         |                                         pd
|_        t          |          dk    rj|d         |                                         }	t          |j        t
          j                  rdnd}
| j        j                            |	|
|j        f           |j	        dz   }|                    |           | j        dk    r|xj        dz  c_        | j        dk    r|xj	        dz  c_	        d |D             | _        || _        d
S )a:  
        Initialize the header Column objects from the table ``lines``.

        Based on the previously set Header attributes find or create the column names.
        Sets ``self.cols`` with the list of Columns.

        Parameters
        ----------
        lines : list
            List of table lines

        c                     g | ]}|S rC   rC   )r-   r5   s     r   r0   z'IpacHeader.get_cols.<locals>.<listcomp>   s    DDDtDDDr   r   zEAt least one header line beginning and ending with delimiter required   z&More than four header lines were foundr	   z -re   rh   N   r'   0rightleftc                     g | ]	}|j         
S rC   r   )r-   xs     r   r0   z'IpacHeader.get_cols.<locals>.<listcomp>   s    +++af+++r   )rW   rO   r,   r{   	enumerater   ColumnrS   startendry   r   typeunit
issubclassStrTypedatafill_valuesrp   re   ipac_definitionnamescols)r   rT   header_linesheader_valsr   r   ire   r|   nullfillvals              r   get_colszIpacHeader.get_cols   sG    ))%00DDl(C(CDDD{q  W   !!EFFF  Q00 	 	GAt+4::d#3#3444CCIc$ii'CG;!##*1~a066t<<,,S11;!##&q>!,2244<;!## #1~a(..00 *38T\ B BK""	%,,dGSX-FGGGGaKEKK #w..		Q			%//1++d+++
			r   c                    | j         rt          }nt          }| j        }| j         rbt	          t
                    | j        D ]$}|                                xx         dz  cc<   %fdD             }|g k    r |d|           |D ]}t          j        d|          }|	                                t          |          k    r || d          | j         r4|d                                         s|d         dk    s |d|           | j         r4|d	v r || d
          t          |          dk    r || d          t          |          dk    r || d          g }g }g }| j        D ]}	|	j        j        }
|	j        j        }|	j        j        }|
j        dv r7|
j        dk    r|                    d           nm|                    d           nW|
j        dk    r7|
j        dk    r|                    d           n+|                    d           n|                    d           ||                    d           n,|                    t)          |	j        j                             |	j        t,          j                 }	 t1          |	          }|	j        j                            ||          }|                     |||                                                     |# t8          $ r8 |                    t)          |                                                     Y w xY w||||gS )Nr	   c                 ,    g | ]}|         d k    |S )r	   rC   )r-   r   countnamelists     r   r0   z'IpacHeader.str_vals.<locals>.<listcomp>   s(    LLL}Q7G!7K7K17K7K7Kr   zMIPAC DBMS tables are not case sensitive. This causes duplicate column names: z\w+zB - Only alphanumeric characters and _ are allowed in column names.r   _z'Column name cannot start with numbers: )r   yzXYZzJ - x, y, z, X, Y, Z are reserved names and cannot be used as column names.   z2 - Maximum length for column name is 16 characters(   z3 - Maximum length for column name is 40 characters.)r   urh   r]   rG   fr   rI   rH   rK   r'   )DBMSr   r"   colnamesr   r]   rz   ri   rl   r   r,   isalphar   infodtyper   r   kinditemsizerp   ro   r   r   maskedr   _format_funcsgetrS   r^   )r   IpacFormatEnamelistre   doublenamesrt   	dtypelistunitlistnullistr|   	col_dtypecol_unit
col_formatr   auto_format_funcformat_funcr   s                   @r   str_valszIpacHeader.str_vals   s   9 	*-KK)K=9 		',,M 1 1djjll+++q0++++LLLLmLLLKb  !kI;FI I  
  	 	D&&Auuww#d))##!k 3 3 3   y T$q'//"3"3 TQ3!k"RD"R"RSSSy 999%+ : : :   t99r>>%+SSS   "
 t99r>>%+TTT   "
 	9 !	2 !	2CIx}HJ~++%**$$U++++$$V,,,,3&&%**$$W----$$X....  (((####CHM 2 2333?4;/D	2#7#<#< !h488EUVVJ = =DDFFGGGG 2 2 2
 s4yy00111112 )Xw77s   A K55>L76L7c                     |                                  D ]0}|                    | j                            ||                     1|S )zWrite header.

        The width of each column is determined in Ipac.write. Writing the header
        must be delayed until that time.
        This function is called from there, once the width information is
        available.
        )r   rp   rO   r4   )r   rT   r6   r5   s       r   writezIpacHeader.write9  sG     MMOO 	; 	;DLL++D&99::::r   )r   r   r   r;   r%   splitter_classr   IntType	FloatTyper   rx   
definition
start_linerW   rv   r   r   r   r   rC   r   r   rE   rE   C   s        'N 
DL!		4>"	$.!	 		M JJ( ( (@; @; @;D  8 8 8tQ8 Q8 Q8f
 
 
 
 
r   rE   c                       e Zd ZdZdZdZdS )IpacDataSplitterr*   r'   TN)r   r   r   r2   r1   bookendrC   r   r   r   r   F  s        IMGGGr   r   c                   8    e Zd ZdZdZdZeZej	        dfgZ
d ZdS )IpacDatazIPAC table data reader.z[|\\]r   r   c                 l    |D ]0}|                     | j                            ||                     1|S )z-IPAC writer, modified from FixedWidth writer.)rp   rO   r4   )r   rT   r6   	vals_listr5   s        r   r   zIpacData.writeT  s=     	; 	;DLL++D&99::::r   N)r   r   r   r;   r?   r   r   r   r   r   r   r   rC   r   r   r   r   L  sG        !!GJ%NK()K    r   r   c                   D     e Zd ZdZdZdgZdZdZeZ	e
Zd	 fd	Zd Z xZS )
IpacaE  IPAC format table.

    See: https://irsa.ipac.caltech.edu/applications/DDGEN/Doc/ipac_tbl.html

    Example::

      \\name=value
      \\ Comment
      |  column1 |   column2 | column3 | column4  |    column5    |
      |  double  |   double  |   int   |   double |     char      |
      |  unit    |   unit    |   unit  |    unit  |     unit      |
      |  null    |   null    |   null  |    null  |     null      |
       2.0978     29.09056    73765     2.06000    B8IVpMnHg

    Or::

      |-----ra---|----dec---|---sao---|------v---|----sptype--------|
        2.09708   29.09056     73765   2.06000    B8IVpMnHg

    The comments and keywords defined in the header are available via the output
    table ``meta`` attribute::

      >>> import os
      >>> from astropy.io import ascii
      >>> filename = os.path.join(ascii.__path__[0], 'tests/data/ipac.dat')
      >>> data = ascii.read(filename)
      >>> print(data.meta['comments'])
      ['This is an example of a valid comment']
      >>> for name, keyword in data.meta['keywords'].items():
      ...     print(name, keyword['value'])
      ...
      intval 1
      floatval 2300.0
      date Wed Sp 20 09:48:36 1995
      key_continue IPAC keywords can continue across lines

    Note that there are different conventions for characters occurring below the
    position of the ``|`` symbol in IPAC tables. By default, any character
    below a ``|`` will be ignored (since this is the current standard),
    but if you need to read files that assume characters below the ``|``
    symbols belong to the column before or after the ``|``, you can specify
    ``definition='left'`` or ``definition='right'`` respectively when reading
    the table (the default is ``definition='ignore'``). The following examples
    demonstrate the different conventions:

    * ``definition='ignore'``::

        |   ra  |  dec  |
        | float | float |
          1.2345  6.7890

    * ``definition='left'``::

        |   ra  |  dec  |
        | float | float |
           1.2345  6.7890

    * ``definition='right'``::

        |   ra  |  dec  |
        | float | float |
        1.2345  6.7890

    IPAC tables can specify a null value in the header that is shown in place
    of missing or bad data. On writing, this value defaults to ``null``.
    To specify a different null value, use the ``fill_values`` option to
    replace masked values with a string or number of your choice as
    described in :ref:`astropy:io_ascii_write_parameters`::

        >>> from astropy.io.ascii import masked
        >>> fill = [(masked, 'N/A', 'ra'), (masked, -999, 'sptype')]
        >>> ascii.write(data, format='ipac', fill_values=fill)
        \ This is an example of a valid comment
        ...
        |          ra|         dec|      sai|          v2|            sptype|
        |      double|      double|     long|      double|              char|
        |        unit|        unit|     unit|        unit|              ergs|
        |         N/A|        null|     null|        null|              -999|
                  N/A     29.09056      null         2.06               -999
         2345678901.0 3456789012.0 456789012 4567890123.0 567890123456789012

    When writing a table with a column of integers, the data type is output
    as ``int`` when the column ``dtype.itemsize`` is less than or equal to 2;
    otherwise the data type is ``long``. For a column of floating-point values,
    the data type is ``float`` when ``dtype.itemsize`` is less than or equal
    to 4; otherwise the data type is ``double``.

    Parameters
    ----------
    definition : str, optional
        Specify the convention for characters in the data table that occur
        directly below the pipe (``|``) symbol in the header column definition:

          * 'ignore' - Any character beneath a pipe symbol is ignored (default)
          * 'right' - Character is associated with the column to the right
          * 'left' - Character is associated with the column to the left

    DBMS : bool, optional
        If true, this verifies that written tables adhere (semantically)
        to the `IPAC/DBMS
        <https://irsa.ipac.caltech.edu/applications/DDGEN/Doc/DBMSrestriction.html>`_
        definition of IPAC tables. If 'False' it only checks for the (less strict)
        `IPAC <https://irsa.ipac.caltech.edu/applications/DDGEN/Doc/ipac_tbl.html>`_
        definition.
    ipacTzIPAC format tablerM   Fc                     t                                                       |dv r|| j        _        nt	          d          || j        _        d S )N)rM   r   r   z-definition should be one of ignore/left/right)r   __init__headerr   r{   r   )r   r   r   r   s      r   r   zIpac.__init__  sQ    444*4DK''LMMMr   c                 n   | j         j                            t          j        df           t          |j                                                  | j        _	        | j        
                    | j        | j        | j                   t          j        || j        | j        | j                   |                     |           t          |j                                                  }|| j        _	        || j         _	        g }d|j        v r}|j        d         D ]o}t'          t)          |                    dk    rt+          dt,                     t/          t)          |          ddd          D ]}|                    |           pd|j        v rw|j        d         }|D ]g}	 ||         d	         }|                    d
|                                 d|           ?# t2          $ r t+          d| dt,                     Y dw xY wd |j        D             }	t5          |	          rt+          d|	 dt,                     | j                             | j         j	                   t9          |j                                                  D ]<\  }
t;          fd| j                                        D                       |
_        =g }| j                                         }tA          | D ]}|                    |           t9          |j                                                  D ]/\  }
|r!t;          fd|D                       |
_!        (d|
_!        0d |j                                        D             }| j        "                    ||           | j         "                    |||           |S )a  
        Write ``table`` as list of strings.

        Parameters
        ----------
        table : `~astropy.table.Table`
            Input table data

        Returns
        -------
        lines : list
            List of strings corresponding to ASCII table

        r   rb   N   z9Comment string > 78 characters was automatically wrapped.P   rg   )initial_indentsubsequent_indentrc   rf   rd   =zTable metadata keyword ze has been skipped.  IPAC metadata must be in the form {{'keywords':{{'keyword': {{'value': value}} }}c                     g | ]}|d v|	S ))rc   rb   rC   )r-   keys     r   r0   zIpac.write.<locals>.<listcomp>  s*     
 
 
4L)L)LC)L)L)Lr   zTable metadata keyword(s) ze were not written.  IPAC metadata must be in the form {{'keywords':{{'keyword': {{'value': value}} }}c              3   B   K   | ]}t          |                   V  d S Nr+   r-   r5   r   s     r   	<genexpr>zIpac.write.<locals>.<genexpr>*  s-      PPDGPPPPPPr   c              3   B   K   | ]}t          |                   V  d S r   r+   r   s     r   r   zIpac.write.<locals>.<genexpr>5  s-      GGDGGGGGGGr   r   c                 B    g | ]}t          |j        |j                  S rC   )maxr/   	headwidth)r-   r|   s     r   r0   zIpac.write.<locals>.<listcomp>9  s&    RRRC#ci//RRRr   )#r   r   rp   r   r   listcolumnsvaluesr   r   check_column_namesr   strict_namesguessing_apply_include_exclude_namesinclude_namesexclude_names_check_multidim_tablerq   r,   ro   r   r   r   rS   	TypeErrorany_set_fill_valuesr   r   r   r   r3   r/   r   )r   ra   new_colsrT   r?   rV   keydictkeywordr.   ignored_keysr|   data_str_valscol_str_itersr5   r6   r   s                  @r   r   z
Ipac.write  s   & 		$$dk6%:;;;   4 4 6 677&&tz43DdmTTT)4:t143E	
 	
 	

 	""5))) ,,..//#!	 ## :j1 	' 	's7||$$r))S*   !LL"Ue   ' 'D LL&&&&' ##j,G"  
!'*73CLL!?gmmoo!?!?!?!?@@@@    =' = = = +	    
 
 :
 
 
 | 	5\ 5 5 5 #	   		""49>222   4 4 6 677 	Q 	QFAsPPPP9M9M9O9OPPPPPCMM	**,,' 	' 	'D  &&&& 4 4 6 677 	 	FAs  GGGGGGGGG				RR5=;O;O;Q;QRRR%(((	v}555s   $;G  #HH)rM   F)r   r   r   r;   _format_name_io_registry_format_aliases_io_registry_can_write_descriptionr   
data_classrE   header_classr   r   r   r   s   @r   r   r   [  s        h hT L#)(!&LJL           g g g g g g gr   r   )r;   ri   collectionsr   r   textwrapr   warningsr   astropy.table.pprintr   astropy.utils.exceptionsr   r'   r
   r   r   r^   r   r"   BaseSplitterr%   FixedWidthHeaderrE   FixedWidthSplitterr   FixedWidthDatar   Basicr   rC   r   r   <module>r     s    
			 0 0 0 0 0 0 0 0             5 5 5 5 5 5 7 7 7 7 7 7 % % % % % % % % % %
 
 
 
 
) 
 
 

 
 
 
 
i 
 
 
F F F F F* F F F8@ @ @ @ @, @ @ @F    z4       z(   c c c c c5; c c c c cr   