U
    e»{j~q  ã                   @   s   d Z ddlZddl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ZddlmZ ddlmZmZmZ d	d
lmZmZmZ dZdZdgZddddddgZdddddddgZG dd„ dejƒZG dd„ dej ƒZ!G dd„ dej"ƒZ#G dd„ dej$ƒZ%dS )zíClasses to read AAS MRT table format

Ref: https://journals.aas.org/mrt-standards

:Copyright: Smithsonian Astrophysical Observatory (2021)
:Author: Tom Aldcroft (aldcroft@head.cfa.harvard.edu),          Suyog Garg (suyog7130@gmail.com)
é    N)ÚStringIO)ÚceilÚfloor)ÚTemplate)Úwrap)Úunits)ÚColumnÚMaskedColumnÚTableé   )ÚcdsÚcoreÚ
fixedwidthéP   i † Ú*z'Byte-by-byte Description of file: $filezP--------------------------------------------------------------------------------z+ Bytes Format Units  Label     Explanationsz$bytebybytezTitle:zAuthors:zTable:zP================================================================================zNotes:c                   @   s   e Zd ZdZdd„ ZdS )ÚMrtSplitterz^
    Contains the join function to left align the MRT columns
    when writing to a file.
    c                 C   s    dd„ t ||ƒD ƒ}| j |¡S )Nc                 S   s$   g | ]\}}|d |t |ƒ   ‘qS )ú ©Úlen)Ú.0ÚvalÚwidth© r   úS/var/www/html/bwave/python/venv/lib/python3.8/site-packages/astropy/io/ascii/mrt.pyÚ
<listcomp>;   s     z$MrtSplitter.join.<locals>.<listcomp>)ÚzipÚ	delimiterÚjoin)ÚselfÚvalsÚwidthsr   r   r   r   :   s    zMrtSplitter.joinN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   4   s   r   c                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )Ú	MrtHeaderÚMRTc                 C   sh   t  dt j¡}| |¡}|dkr.t|› d�ƒ‚t|ƒt| d¡ƒt| d¡ƒ| d¡dk| d¡dkfS )	aÅ  
        Splits a Float string into different parts to find number
        of digits after decimal and check if the value is in Scientific
        notation.

        Parameters
        ----------
        value : str
            String containing the float value to split.

        Returns
        -------
        fmt: (int, int, int, bool, bool)
            List of values describing the Float sting.
            (size, dec, ent, sign, exp)
            size, length of the given string.
            ent, number of digits before decimal point.
            dec, number of digits after decimal point.
            sign, whether or not given value signed.
            exp, is value in Scientific notation?
        z¢(?P<sign> [+-]*)
                (?P<ent> [^eE.]+)
                (?P<deciPt> [.]*)
                (?P<decimals> [0-9]*)
                (?P<exp> [eE]*-*)[0-9]*Nz is not a float numberZentZdecimalsÚsignÚ Úexp)ÚreÚcompileÚVERBOSEÚmatchÚ	Exceptionr   Úgroup)r   ÚvalueZregfloatÚmor   r   r   Ú_split_float_formatB   s    ú
ûzMrtHeader._split_float_formatc                 C   sD   t |ƒ|_ t|ƒ|_|j tjjjkr*d|_ |jtjjjkr@d|_dS )z
        Sets the ``col.min`` and ``col.max`` column attributes,
        taking into account columns with Null values.
        N)ÚmaxÚminÚnpÚmar   ZMaskedConstant)r   Úcolr   r   r   Ú_set_column_val_limitsl   s    

z MrtHeader._set_column_val_limitsc                 C   sÊ  d\}}}}d}d}|j D ]º}|dks|dkr0q|  |¡}	|	d dkr^|dkrXd\}}}d	}n
|d	krhq||	d
 k r||	d
 }||	d k r�|	d }||	d k r¤|	d }|	d r°d}||	d |	d  k r|	d |	d  }q|d	k�rFt|ddƒdk�r||_|�r| jd7  _|t|jƒ d t|ƒ |_t|jƒd t|ƒ d |_n€d}
t|ddƒdk�r€|| d |_|�r’| jd7  _n|j d¡�r’d}
|t|jƒ d t|ƒ |_|
|jdd…  d |_dS )a�  
        String formatter function for a column containing Float values.
        Checks if the values in the given column are in Scientific notation,
        by spliting the value string. It is assumed that the column either has
        float values or Scientific notation.

        A ``col.formatted_width`` attribute is added to the column. It is not added
        if such an attribute is already present, say when the ``formats`` argument
        is passed to the writer. A properly formatted format string is also added as
        the ``col.format`` attribute.

        Parameters
        ----------
        col : A ``Table.Column`` object.
        )r   r   r   r   FÚFNr(   é   T)r   r   r   ÚEr   r   é   é   Úformatted_widthÚ.ÚeÚ0Úf)Ústr_valsr2   Úgetattrr>   ÚstrÚfortran_formatÚformatÚ
startswith)r   r7   ÚmaxsizeZmaxprecZmaxentZmaxdecr'   Zfformatr   ÚfmtZleadr   r   r   Úcolumn_float_formatterx   sP    



ÿz MrtHeader.column_float_formatterc                    sh  g }| j  ¡ }t|Ž D ]}| |¡ qt| jƒD ]@\‰‰ t‡fdd„|D ƒƒˆ _| jdk	r0tˆ jt	ˆ j
jƒƒˆ _q0dd„ | jD ƒ}d}t	tt|ƒt	| jƒ d ƒƒ}dt|ƒ d }|d	 | }|d
7 }|d
7 }d\}	}
tdddddgtgd d�}t| jƒD �]ž\‰‰ tˆ tƒˆ _ˆ jdk	�r6tdd„ ˆ jD ƒƒˆ _t ˆ jtj¡�r¶|  ˆ ¡ tˆ ddƒdk�r„tt	tˆ jƒƒt	tˆ jƒƒƒˆ _dtˆ jƒ ˆ _ˆ jdk�r`dˆ jdd…  ˆ _nªt ˆ jt t¡j¡�rä|  ˆ ¡ |  ˆ ¡ n|ˆ jj}ˆ j�rˆ }d|_t | !¡ td�}|jj}tˆ ddƒdk�r@t"t# $d|¡ %d¡ƒˆ _dtˆ jƒ ˆ _tˆ jƒd ˆ _ˆ j| d }ˆ jdk�r€dˆ _ˆ j&dk	�r”ˆ j&}n
dˆ j }d}ˆ j�r®d}ˆ j'dk	�rÈˆ j' (d¡}n ˆ j )¡  *d ¡d!k�räd"}nd#}d}ˆ j�r¸ˆ j�r¸t+‡ fd$d„d%D ƒƒ�s¸ˆ jd& dk�rzt,ˆ jƒt-k �r¸t,ˆ jƒt-k �r¸ˆ jˆ jk�rbd'ˆ j› d(�}nd'ˆ j› d)ˆ j› d(�}n>ˆ jd& d*k�r¸d't.ˆ jd+ ƒd, › d)t/ˆ jd+ ƒd, › d(�}|dk�sÌ|dk�rÞ|› |› d
|› �}t	ˆ jƒ|	k�røt	ˆ jƒ}	t	|ƒ|
k�rt	|ƒ}
ˆ jd-k�rB| 0| |¡d.d#d/d0g¡ d1ˆ _|d7 }| 0||k�rZ| |¡n
| ||¡ˆ jdk�rtdnˆ j|ˆ jdk�rŠdnˆ j|g¡ |d2 }qþt1ƒ }|j2|d3d
d4dd5d5d6t|	ƒ d dt|
ƒ d d7œd8� | 3¡  4¡ }|d2 d d9 |	 d: }d}|D ]F}t	|ƒt5k�rB|d; 6t7|d
| t5d<�¡7 }|d;7 }n||d; 7 }�q
|| _8|dd!… }|S )=aM  
        Writes the Byte-By-Byte description of the table.

        Columns that are `astropy.coordinates.SkyCoord` or `astropy.time.TimeSeries`
        objects or columns with values that are such objects are recognized as such,
        and some predefined labels and description is used for them.
        See the Vizier MRT Standard documentation in the link below for more details
        on these. An example Byte-By-Byte table is shown here.

        See: http://vizier.u-strasbg.fr/doc/catstd-3.1.htx

        Example::

        --------------------------------------------------------------------------------
        Byte-by-byte Description of file: table.dat
        --------------------------------------------------------------------------------
        Bytes Format Units  Label     Explanations
        --------------------------------------------------------------------------------
         1- 8  A8     ---    names   Description of names
        10-14  E5.1   ---    e       [-3160000.0/0.01] Description of e
        16-23  F8.5   ---    d       [22.25/27.25] Description of d
        25-31  E7.1   ---    s       [-9e+34/2.0] Description of s
        33-35  I3     ---    i       [-30/67] Description of i
        37-39  F3.1   ---    sameF   [5.0/5.0] Description of sameF
        41-42  I2     ---    sameI   [20] Description of sameI
        44-45  I2     h      RAh     Right Ascension (hour)
        47-48  I2     min    RAm     Right Ascension (minute)
        50-67  F18.15 s      RAs     Right Ascension (second)
           69  A1     ---    DE-     Sign of Declination
        70-71  I2     deg    DEd     Declination (degree)
        73-74  I2     arcmin DEm     Declination (arcmin)
        76-91  F16.13 arcsec DEs     Declination (arcsec)

        --------------------------------------------------------------------------------
        c                 3   s   | ]}t |ˆ  ƒV  qd S ©Nr   )r   r   )Úir   r   Ú	<genexpr>ø   s     z/MrtHeader.write_byte_by_byte.<locals>.<genexpr>Nc                 S   s   g | ]
}|j ‘qS r   )r   )r   r7   r   r   r   r   û   s     z0MrtHeader.write_byte_by_byte.<locals>.<listcomp>r   z{:zd}ú-r   )é   é   ÚBytesÚFormatÚUnitsÚLabelÚExplanationsé   )ÚnamesÚdtypec                 s   s   | ]}t |ƒV  qd S rL   r   )r   Zsvalr   r   r   rN     s     r>   ÚIú>r(   )rY   z(\d+)$ÚAÚsÚUnknownzDescription of ú?r   Z	magnitudeéÿÿÿÿÚmagz---c                 3   s   | ]}|ˆ j kV  qd S rL   ©Úname©r   Úx)r7   r   r   rN   _  s    )ÚRAÚDEZLONZLATZPLNZPLTr   ú[ú]ú/)r;   r9   éd   g      Y@ÚDEdÚA1zDE-zSign of DeclinationZI2r<   zascii.fixed_width_no_headerFz<6sú<)rS   rT   rU   rV   )rG   r   ZbookendZdelimiter_padÚformatsé   r:   Ú
)Úsubsequent_indentr   )9ÚdatarC   r   ÚappendÚ	enumerateÚcolsr3   r   Ú
start_liner   Úinforc   rE   Úsumr
   Ú
isinstancer	   Zhas_nullrG   r>   r5   Ú
issubdtyperY   Úintegerr8   rD   r4   rF   ÚfloatÚtyperK   Z
fill_valuer   ZfilledÚintr*   Úsearchr/   ÚdescriptionÚunitÚ	to_stringÚlowerÚfindÚanyÚabsÚMAX_COL_INTLIMITr   r   Úadd_rowr   ÚwriteÚgetvalueÚ
splitlinesÚMAX_SIZE_README_LINEr   r   Z	linewidth)r   Z	vals_listZcol_str_itersr   r    ZstartbZbyte_count_widthZ
singlebfmtZfmtbZmax_label_widthZmax_descrip_sizeÚbbbrY   ZmcolZcoltmpZendbr�   ZnullflagZcol_unitZlim_valsZbbblinesZnsplitZbuffÚnewliner   )r7   rM   r   Úwrite_byte_by_byteÍ   s   %

 ÿ
 

ÿþÿýÿþ,ÿ
ûÿ	ÿ
ùÿ
üúýÿ
zMrtHeader.write_byte_by_bytec              
      s´  ddl m} dddddœ}dd	d
dddg}g }tˆ jƒD �]’\}}t||ƒs²t|d |ƒr²z||ƒ}W nJ ttfk
r°   t|tƒsŒt|ƒ}tdd„ |D ƒƒ}|ˆ j|< Y q8Y nX t||ƒ�r†d|j 	¡ k�r6t
t|ƒtˆ jƒ ƒdk�r6|jj|jj }}	|j ¡  d¡|j ¡  d¡|j|	j ¡  d¡|	j ¡  d¡|	jg}
tjtjtjtjtjtjg}ddddddg}t|
|||ƒD ]®\}}}}|dk�r¬ttt  |¡ƒ|||d�}ntt|ƒ|||d�}|d
k�rÒd|_!nH|dk�räd|_!n6|dk�röd|_!n$|dk�rd|_!n| "d¡�rd |_!ˆ j #|¡ �qz| #|¡ nôd!}| $¡ D ]æ\}}||j%k�rBt
t|d"d#… ƒtˆ jƒ ƒd#k�rB||j%k�r”d$|j%› d%�}tt&||d& ƒ|d' | '¡ › d(|› �|j(|d&  d)d*�}tt&||d# ƒ|d | '¡ › d+|› �|j(|d#  d,d*�}ˆ j #|¡ ˆ j #|¡ | #|¡ �qB||k�rÌt) *d-|j%› d.|› d/ˆ j| › d0�t+¡ ˆ j #t| ,¡ ˆ j| d1�¡ | #|¡ q8t|tƒs8t|ƒ}t -|j.t .t/¡j0¡�rÂtd2d„ |D ƒƒ}|ˆ j|< q8|d"d"d3… D ]}ˆ j 1|¡ �qÜt2‡ fd4d5„d6D ƒƒ�rhtˆ jƒD ]T\}}t||ƒ�rt| ,¡ ˆ j| d1�ˆ j|< d7|› d8ˆ j| › d0�}t3 4|¡‚�qt5d9 6t7¡ƒ}| 8d:ˆ  9¡ d;œ¡}t5d9 6t:¡ƒ}| 8d<|i¡}| #|¡ d"S )=zˆ
        Writes the Header of the MRT table, aka ReadMe, which
        also contains the Byte-By-Byte description of the table.
        r   )ÚSkyCoord)ÚGLATZGLONÚbÚl)ZELATÚELONÚlatÚlon)ZHLATZHLONr–   r—   )ZHPLTZHPLNZTyZTx)ZgalacticZeclipticZheliographicZhelioprojectiveÚRAhZRAmZRAsrl   ÚDEmÚDEsc                 S   s   g | ]}t |ƒ‘qS r   ©rE   ©r   r   r   r   r   r   é  s     z#MrtHeader.write.<locals>.<listcomp>Úraé   Úi1zRight Ascension (hour)zRight Ascension (minute)zRight Ascension (second)zDeclination (degree)zDeclination (arcmin)zDeclination (arcsec))r™   rš   )rc   r‚   r�   z013.10fz012.9fZ2dz+03d)rf   rg   Ú02dr(   Nr<   z (ú)r=   r   z
 Longitudez.12f)rc   r�   r‚   rG   z	 Latitudez+.12fzCoordinate system of type 'zU' already stored in table as CDS/MRT-syle columns or of unrecognized type. So column z> is being skipped with designation of a string valued column `z`.rb   c                 S   s   g | ]}t |ƒ‘qS r   r›   rœ   r   r   r   r   `  s     r`   c                 3   s   | ]}|ˆ j kV  qd S rL   )Úcolnamesrd   ©r   r   r   rN   h  s     z"MrtHeader.write.<locals>.<genexpr>)r˜   rl   r•   r’   zGTable already has coordinate system in CDS/MRT-syle columns. So column z@ should have been replaced already with a string valued column `rq   z	table.dat)ÚfileÚ
bytebybyter¥   );Zastropy.coordinatesr‘   ru   rv   rz   Ú
ValueErrorÚ	TypeErrorr   Zrepresentation_component_namesÚkeysr   Úsetr¢   r�   ZhmsÚdecZdmsÚhÚroundZastypeÚmr]   ÚdÚur4   ÚsecondÚdegZarcminZarcsecr   Úlistr5   r‡   rG   rH   rt   Úitemsrc   rD   Ú
capitalizeZrepresentation_component_unitsÚwarningsÚwarnÚUserWarningrƒ   r{   rY   Úobjectr~   Úpopr†   r   ZInconsistentTableErrorr   r   ÚBYTE_BY_BYTE_TEMPLATEÚ
substituter�   ÚMRT_TEMPLATE)r   Úlinesr‘   Zcoord_systemsZeqtnamesZto_poprM   r7   Zra_cZdec_cZcoordsZcoord_unitsZcoord_descripZcoordrc   Z
coord_unitZdescripZ	coord_colZfrminfoÚframeZlatlonZlon_colZlat_colÚmessageZbbb_templateZbyte_by_byteZrm_templateZreadme_filledr   r£   r   rŠ   Æ  sö    ü


ÿþúú   ÿ
üü



ÿ þûû

û
ÿÿzMrtHeader.writeN)	r!   r"   r#   Ú_subfmtr2   r8   rK   r�   rŠ   r   r   r   r   r%   ?   s   *U zr%   c                   @   s    e Zd ZdZdZeZdd„ ZdS )ÚMrtDatazMRT table data readerr&   c                 C   s   d| j _tj | |¡ d S )Nr   )Zsplitterr   r   ZFixedWidthDatarŠ   )r   r½   r   r   r   rŠ   ˆ  s    zMrtData.writeN)r!   r"   r#   r$   rÀ   r   Zsplitter_classrŠ   r   r   r   r   rÁ   ‚  s   rÁ   c                       s<   e Zd ZdZdZdgZdZdZeZ	e
Zd‡ fdd„	Z‡  ZS )	ÚMrtaÔ  AAS MRT (Machine-Readable Table) format table.

    **Reading**
    ::

      >>> from astropy.io import ascii
      >>> table = ascii.read('data.mrt', format='mrt')

    **Writing**

    Use ``ascii.write(table, 'data.mrt', format='mrt')`` to  write tables to
    Machine Readable Table (MRT) format.

    Note that the metadata of the table, apart from units, column names and
    description, will not be written. These have to be filled in by hand later.

    See also: :ref:`cds_mrt_format`.

    Caveats:

    * The Units and Explanations are available in the column ``unit`` and
      ``description`` attributes, respectively.
    * The other metadata defined by this format is not available in the output table.
    ZmrtTzMRT format tableNc                    s>   t |ƒdkrt‚| j| j_d | j_d | j_| ¡ }tƒ  |¡S )Nr   )	r   ÚNotImplementedErrorÚheaderrs   Zposition_linerw   ÚcopyÚsuperrŠ   )r   Útable©Ú	__class__r   r   rŠ   ¯  s    
z	Mrt.write)N)r!   r"   r#   r$   Z_format_nameZ_io_registry_format_aliasesZ_io_registry_can_writeZ_descriptionrÁ   Z
data_classr%   Zheader_classrŠ   Ú__classcell__r   r   rÈ   r   rÂ   �  s   rÂ   )&r$   r*   rµ   Úior   Úmathr   r   Ústringr   Útextwrapr   Únumpyr5   Zastropyr   r¯   Zastropy.tabler   r	   r
   r(   r   r   r   r�   rˆ   Z__doctest_skip__rº   r¼   ZFixedWidthSplitterr   Z	CdsHeaderr%   ZCdsDatarÁ   Z
BaseReaderrÂ   r   r   r   r   Ú<module>   sH   	ú
ù    G