B
    d=                 @   s   d dl mZ d dl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 ddlmZmZmZ d d	lmZ d
ZG dd deZdddZdddZdd ZG dd deZdd Zdd ZdS )    )import_moduleN)deepcopy)OrderedDict)	MixinInfo   )ColumnMaskedColumn)TableQTablehas_info_class)QuantityInfo)zastropy.time.core.Timezastropy.time.core.TimeDeltazastropy.units.quantity.Quantityz,astropy.units.function.logarithmic.Magnitudez*astropy.units.function.logarithmic.Decibelz&astropy.units.function.logarithmic.Dexz#astropy.coordinates.angles.Latitudez$astropy.coordinates.angles.Longitudez astropy.coordinates.angles.Anglez&astropy.coordinates.distances.Distancez'astropy.coordinates.earth.EarthLocationz+astropy.coordinates.sky_coordinate.SkyCoordz(astropy.table.ndarray_mixin.NdarrayMixinz(astropy.table.table_helpers.ArrayWrapperz!astropy.table.column.MaskedColumnz:astropy.coordinates.representation.CartesianRepresentationz>astropy.coordinates.representation.UnitSphericalRepresentationz7astropy.coordinates.representation.RadialRepresentationz:astropy.coordinates.representation.SphericalRepresentationzAastropy.coordinates.representation.PhysicsSphericalRepresentationz<astropy.coordinates.representation.CylindricalRepresentationz8astropy.coordinates.representation.CartesianDifferentialz<astropy.coordinates.representation.UnitSphericalDifferentialz8astropy.coordinates.representation.SphericalDifferentialzBastropy.coordinates.representation.UnitSphericalCosLatDifferentialz>astropy.coordinates.representation.SphericalCosLatDifferentialz5astropy.coordinates.representation.RadialDifferentialz?astropy.coordinates.representation.PhysicsSphericalDifferentialz:astropy.coordinates.representation.CylindricalDifferentialz'astropy.utils.masked.core.MaskedNDArrayc               @   s   e Zd ZdZdS )SerializedColumnaF  
    Subclass of dict that is a used in the representation to contain the name
    (and possible other info) for a mixin attribute (either primary data or an
    array-like attribute) that is serialized as a column in the table.

    Normally contains the single key ``name`` with the name of the column in the
    table.
    N)__name__
__module____qualname____doc__ r   r   d/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/astropy/table/serialize.pyr   <   s   r   r   c                s   j  }|r j|kr&|  dS i }xTddd fddd fddd fd	d
d ffD ]$\}}t j |}	||	rX|	||< qXW  fdd| D }
x|
D ]}|| }| j jkr|}|}n|d | }i }t|ts$t	|drt
|jrtnt}|||fd|i| td|i||< qt|||| t||||< qW x" j jD ]}||krR||= qRW |rz||d< |d jd  jj  |||< dS )a  Carry out processing needed to serialize ``col`` in an output table
    consisting purely of plain ``Column`` or ``MaskedColumn`` columns.  This
    relies on the object determine if any transformation is required and may
    depend on the ``serialize_method`` and ``serialize_context`` context
    variables.  For instance a ``MaskedColumn`` may be stored directly to
    FITS, but can also be serialized as separate data and mask columns.

    This function builds up a list of plain columns in the ``new_cols`` arg (which
    is passed as a persistent list).  This includes both plain columns from the
    original table and plain columns that represent data from serialized columns
    (e.g. ``jd1`` and ``jd2`` arrays from a ``Time`` column).

    For serialized columns the ``mixin_cols`` dict is updated with required
    attributes and information to subsequently reconstruct the table.

    Table mixin columns are always serialized and get represented by one
    or more data columns.  In earlier versions of the code *only* mixin
    columns were serialized, hence the use within this code of "mixin"
    to imply serialization.  Starting with version 3.1, the non-mixin
    ``MaskedColumn`` can also be serialized.
    Nunitc             S   s   | d k	o| dkS )N r   )xr   r   r   <lambda>p       z,_represent_mixin_as_column.<locals>.<lambda>formatc             S   s   | d k	S )Nr   )r   r   r   r   r   q   r   descriptionc             S   s   | d k	S )Nr   )r   r   r   r   r   r   r   metac             S   s   | S )Nr   )r   r   r   r   r   s   r   c                s6   g | ].\}}t |d ddd  jdd kr|qS )shaper   Nr   )getattrr   ).0keyvalue)colr   r   
<listcomp>}   s    z._represent_mixin_as_column.<locals>.<listcomp>.maskname__info__	__class__)infoZ_represent_as_dictr'   appendr   itemsZ_represent_as_dict_primary_datar   r   hasattrnpanyr$   r   r   r   _represent_mixin_as_columnpopattrs_from_parent
setdefaultr   r   )r!   r%   new_cols
mixin_colsexclude_classes	obj_attrsr(   attr
nontrivialcol_attrZ
data_attrs	data_attrdatanew_nameZnew_infoZcol_clsr   )r!   r   r.   H   sF    







r.   c             C   s   i }g }x&|   D ]}t||jj|||d qW |rVt| j}||d< t||dd}n| }xB|  D ]6}t|tsd|j	|krdt
d|jjd|j	j dqdW |S )a  Represent input Table ``tbl`` using only `~astropy.table.Column`
    or  `~astropy.table.MaskedColumn` objects.

    This function represents any mixin columns like `~astropy.time.Time` in
    ``tbl`` to one or more plain ``~astropy.table.Column`` objects and returns
    a new Table.  A single mixin column may be split into multiple column
    components as needed for fully representing the column.  This includes the
    possibility of recursive splitting, as shown in the example below.  The
    new column names are formed as ``<column_name>.<component>``, e.g.
    ``sc.ra`` for a `~astropy.coordinates.SkyCoord` column named ``sc``.

    In addition to splitting columns, this function updates the table ``meta``
    dictionary to include a dict named ``__serialized_columns__`` which provides
    additional information needed to construct the original mixin columns from
    the split columns.

    This function is used by astropy I/O when writing tables to ECSV, FITS,
    HDF5 formats.

    Note that if the table does not include any mixin columns then the original
    table is returned with no update to ``meta``.

    Parameters
    ----------
    tbl : `~astropy.table.Table` or subclass
        Table to represent mixins as Columns
    exclude_classes : tuple of class
        Exclude any mixin columns which are instannces of any classes in the tuple

    Returns
    -------
    tbl : `~astropy.table.Table`
        New Table with updated columns, or else the original input ``tbl``

    Examples
    --------
    >>> from astropy.table import Table, represent_mixins_as_columns
    >>> from astropy.time import Time
    >>> from astropy.coordinates import SkyCoord

    >>> x = [100.0, 200.0]
    >>> obstime = Time([1999.0, 2000.0], format='jyear')
    >>> sc = SkyCoord([1, 2], [3, 4], unit='deg', obstime=obstime)
    >>> tbl = Table([sc, x], names=['sc', 'x'])
    >>> represent_mixins_as_columns(tbl)
    <Table length=2>
     sc.ra   sc.dec sc.obstime.jd1 sc.obstime.jd2    x
      deg     deg
    float64 float64    float64        float64     float64
    ------- ------- -------------- -------------- -------
        1.0     3.0      2451180.0          -0.25   100.0
        2.0     4.0      2451545.0            0.0   200.0

    )r4   __serialized_columns__F)r   copyzfailed to represent column z (z) as one or more Column subclasses. This looks like a mixin class that does not have the correct _represent_as_dict() method in the class `info` attribute.)itercolsr.   r(   r%   r   r   r	   
isinstancer   r'   	TypeErrorr   )tblr4   r3   r2   r!   r   outr   r   r   represent_mixins_as_columns   s    9
 rC   c       
      C   s   |  d}|tkr td| td| \}}t|}t||}x(| D ]\}}||j	j
krP|| |< qPW |j	| }	x*| D ]\}}|| krt|	j	|| qW |	S )Nr'   z unsupported class for construct z(.+)\.(\w+))r/   __construct_mixin_classes
ValueErrorrematchgroupsr   r   r*   r(   r0   Z_construct_from_dictsetattr)
r5   r(   Zcls_full_namemod_namecls_namemoduleclsr6   r    Zmixinr   r   r   (_construct_mixin_from_obj_attrs_and_info  s    

rN   c               @   s.   e Zd ZdZd
ddZedd Zdd Zd	S )
_TableLitea  
    Minimal table-like object for _construct_mixin_from_columns.  This allows
    manipulating the object like a Table but without the actual overhead
    for a full Table.

    More pressing, there is an issue with constructing MaskedColumn, where the
    encoded Column components (data, mask) are turned into a MaskedColumn.
    When this happens in a real table then all other columns are immediately
    Masked and a warning is issued. This is not desirable.
    r   c             C   s>   | j }|| |jj< x&t|D ]\}}||kr| | qW d S )N)colnamesr(   r%   	enumeratemove_to_end)selfr!   indexrP   iir%   r   r   r   
add_column'  s
    z_TableLite.add_columnc             C   s   t |  S )N)listkeys)rS   r   r   r   rP   .  s    z_TableLite.colnamesc             C   s   |   S )N)values)rS   r   r   r   r>   2  s    z_TableLite.itercolsN)r   )r   r   r   r   rV   propertyrP   r>   r   r   r   r   rO     s   

rO   c                sJ  i }xV|  D ]J\}}t|trd|kr6|||d < q|  d| }t||  |||< qW x| D ]
}||= qfW t fdd|D }x*|  D ]\}} | }	|	||<  |= qW |di }
t|dkr&xTddd	 fd
dd	 fddd	 fddd	 ffD ]$\}}t|	j	|}||r||
|< qW | |
d< t
||
}	 j|	|d d S )Nr%   r#   c             3   s   | ]} j |V  qd S )N)rP   rT   )r   r%   )rB   r   r   	<genexpr>E  s    z0_construct_mixin_from_columns.<locals>.<genexpr>r&   r   r   c             S   s   | dkS )N)Nr   r   )r   r   r   r   r   T  r   z/_construct_mixin_from_columns.<locals>.<lambda>r   c             S   s   | d k	S )Nr   )r   r   r   r   r   U  r   r   c             S   s   | d k	S )Nr   )r   r   r   r   r   V  r   r   c             S   s   | S )Nr   )r   r   r   r   r   W  r   )rT   )r*   r?   r   _construct_mixin_from_columnsrY   minr/   lenr   r(   rN   rV   )r;   r5   rB   Zdata_attrs_mapr%   valZout_nameidxr9   r!   r(   r6   r7   r8   r   )rB   r   r\   6  s6    





r\   c             C   s   d| j kr| S | j  }|d}t| j}x | D ]\}}t||| q6W tdd | D }|rlt	nt
}|t| |jd|dS )Nr<   c             s   s   | ]}t |jtV  qd S )N)r?   r(   r   )r   r!   r   r   r   r[   q  s   z1_construct_mixins_from_columns.<locals>.<genexpr>F)namesr=   r   )r   r=   r/   rO   columnsr*   r\   r-   r>   r
   r	   rW   rY   rP   )rA   r   r3   rB   r;   r5   Zhas_quantitiesZout_clsr   r   r   _construct_mixins_from_columnsa  s    



rc   )r   )r   )	importlibr   rF   r=   r   collectionsr   numpyr,   Zastropy.utils.data_infor   columnr   r   tabler	   r
   r   Zastropy.units.quantityr   rD   dictr   r.   rC   rN   rO   r\   rc   r   r   r   r   <module>   s    !
`
\+