B
    dQ              l   @   s  d 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 ddlmZ dd	lm	Z	 dd
lm
Z
 ddlmZ dddgZejdfejdfejd dfejd dfejdfejdfejdfejej ddhfejejd  dfejdfejdfejdfejdfejejd  ejd  d fejejd  d!d"hfejejd  ejd  d#d$hfejd%fejd&d'd(hfejejd)  ejd  d*d+hfejd,d-d.hfejd/d0hfejejd1  d2fejd ej d3fejejd  d4fejd ej d5fejej ej d6d7hfejejd  ej d8d9hfejej d:fejejd  d;fejej d<fejejej  d=fejd ej d>d?hfejd d@fejd) dAfejdBfejdCfejdDfejdEdFdGhfejej dHfej dIfej ej dJfej!dKfejej dLfejejd  dMfejej dNfejejd  dOdPdQhfejejd  dRfej!ej dSfej"dTfej#dUfejej dVfejd ej dWfej$ej dXdYhfej$dZfej%d[fej&d\fej'd]d^hfejej d_fej%ejd  d`fejd1 ejd  dafej(dbfejejd  ejd  dcfejejd1  ejd  dddehfej)ej ej*d  ej dffej)ej+ ej*d  ej dgfej,dhfe	j-dife	j-ej djfej.dkfej/dlfej0dmfej1dnfejejd1  dodphfejejdq  drdshfejejdt  dufejejdv  dwdxhfejej dyfejej dzfejejd1  ejd  d{fejejd  d|fejej d}fejejd  ejd  d~fejej dfejej dfejejd  dfejd ej dfejd) dfejd dfej2ejd1  dfej2ejd)  ejd  dfejejd  dfejejd  ej dfejej dfejej dfej$d dfejej dfejej dfejej ej dfejej dfej ejd  ej dfejd ej ej dfej3ej dfejd ej ddhfejejd)  ejd  ddhfejd1 dfejd) ejd  dfgjZ4i Z5i Z6i Z7dd Z8dd Z9dd Z:G dd dZ;dd Z<dd Z=xe4D ]\Z>Z?e<e>e? qbW e dk	rdddddddgZ@xdeAe7B D ]TZCe7eC Z?e@DdeC dde?jEFddd  dddGdd e?D  g qW e ddGe@ 7 Z [>[?dS )z>Defines the physical types that correspond to different units.    N   )core)si)	astrophys)cgs)imperial)misc)quantity)AstropyDeprecationWarningdef_physical_typeget_physical_typePhysicalTypeZdimensionlesslength   Zarea   volumetimeZanglezsolid anglespeedvelocityZaccelerationZ	frequencyZmasszamount of substanceZtemperaturezthermal conductivityzheat capacityZentropyzspecific heat capacityzspecific entropyforceZenergyZworkZtorquezenergy fluxZ
irradianceZpressurezenergy densityZstresspowerzradiant fluxzmass densityzspecific volumezmolar concentrationzmolar volumeZmomentumZimpulsezangular momentumactionzangular speedzangular accelerationzplate scalezdynamic viscosityZdiffusivityzkinematic viscosityZ
wavenumberzcolumn densityzelectrical currentzelectrical chargezelectrical potentialzelectrical resistancezelectrical impedancezelectrical reactancezelectrical resistivityzelectrical conductancezelectrical conductivityzelectrical capacitancezelectrical dipole momentzelectrical current densityzelectrical field strengthzelectrical flux densityzsurface charge densityzpolarization densityzelectrical charge densityZpermittivityzmagnetic fluxzmagnetic flux densityzmagnetic field strengthzmagnetic momentzelectromagnetic field strengthZpermeabilityZ
inductancezluminous intensityzluminous fluxzluminous emittanceZilluminancezradiant intensityZ	luminancezvolumetric ratezspectral flux densityzsurface tensionzspectral flux density wavzpower densityzphoton flux densityzphoton flux density wavzphoton fluxzdata quantity	bandwidthzelectrical charge (ESU)zelectrical current (ESU)zelectrical current (EMU)zelectrical charge (EMU)ZjerkZjoltZsnapZjounceZcrackleipopZpounceztemperature gradientzspecific energyzreaction ratezmoment of inertiazcatalytic activityzmolar heat capacityZmolalityZabsementZabsityzvolumetric flow ratezfrequency driftZcompressibilityzelectron densityzelectron fluxzsurface mass densityZradiancezchemical potentialzlinear densityzmagnetic reluctancezthermal conductancezthermal resistancezthermal resistivityZyankzmolar conductivityzelectrical mobilityzluminous efficacyZopacityzmass attenuation coefficientz	mass fluxzmomentum densityznumber densityzparticle fluxc             C   s2   | dkrt d| tkr t|  S t | ddS )z]
    Return the `PhysicalType` instance associated with the name of a
    physical type.
    unknownz4cannot uniquely identify an 'unknown' physical type.z is not a known physical type.N)
ValueError_name_physical_mapping)name r#   c/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/astropy/units/physical.py_physical_type_from_str   s
    r%   c             C   s\   |   }g }d}x.|D ]&\}}|dkr.d}d}|||f qW |rTtjt|S | S dS )u  
    If a unit contains a temperature unit besides kelvin, then replace
    that unit with kelvin.

    Temperatures cannot be converted directly between K, °F, °C, and
    °Ra, in particular since there would be different conversions for
    T and ΔT.  However, each of these temperatures each represents the
    physical type.  Replacing the different temperature units with
    kelvin allows the physical type to be treated consistently.
    F)Zdeg_FZdeg_CZdeg_RKTN)_get_physical_type_idappendr   ZUnitZ_from_physical_type_idtuple)unitphysical_type_idZphysical_type_id_componentsZsubstitution_was_madebaser   r#   r#   r$   !_replace_temperatures_with_kelvin   s    r-   c             C   sd   t | tr| h} t }xH| D ]@}t |ts8td| t|d}dd |D }||O }qW |S )ai  
    Convert a string or `set` of strings into a `set` containing
    string representations of physical types.

    The strings provided in ``physical_type_input`` can each contain
    multiple physical types that are separated by a regular slash.
    Underscores are treated as spaces so that variable names could
    be identical to physical type names.
    zexpecting a string, but got /c             S   s   h | ]}|  d dqS )_ )stripreplace).0sr#   r#   r$   	<setcomp>   s    z3_standardize_physical_type_names.<locals>.<setcomp>)
isinstancestrsetr    split)Zphysical_type_inputZstandardized_physical_typesZptype_inputZ	input_setZprocessed_setr#   r#   r$    _standardize_physical_type_names   s    



r:   c                   s   e Zd ZdZdd Zdd Z fddZdd	 Zd
d Zdd Z	dd Z
dd Zedd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$Z  ZS )%r   a  
    Represents the physical type(s) that are dimensionally compatible
    with a set of units.

    Instances of this class should be accessed through either
    `get_physical_type` or by using the
    `~astropy.units.core.UnitBase.physical_type` attribute of units.
    This class is not intended to be instantiated directly in user code.

    Parameters
    ----------
    unit : `~astropy.units.Unit`
        The unit to be represented by the physical type.

    physical_types : `str` or `set` of `str`
        A `str` representing the name of the physical type of the unit,
        or a `set` containing strings that represent one or more names
        of physical types.

    Notes
    -----
    A physical type will be considered equal to an equivalent
    `PhysicalType` instance (recommended) or a string that contains a
    name of the physical type.  The latter method is not recommended
    in packages, as the names of some physical types may change in the
    future.

    To maintain backwards compatibility, two physical type names may be
    included in one string if they are separated with a slash (e.g.,
    ``"momentum/impulse"``).  String representations of physical types
    may include underscores instead of spaces.

    Examples
    --------
    `PhysicalType` instances may be accessed via the
    `~astropy.units.core.UnitBase.physical_type` attribute of units.

    >>> import astropy.units as u
    >>> u.meter.physical_type
    PhysicalType('length')

    `PhysicalType` instances may also be accessed by calling
    `get_physical_type`. This function will accept a unit, a string
    containing the name of a physical type, or the number one.

    >>> u.get_physical_type(u.m ** -3)
    PhysicalType('number density')
    >>> u.get_physical_type("volume")
    PhysicalType('volume')
    >>> u.get_physical_type(1)
    PhysicalType('dimensionless')

    Some units are dimensionally compatible with multiple physical types.
    A pascal is intended to represent pressure and stress, but the unit
    decomposition is equivalent to that of energy density.

    >>> pressure = u.get_physical_type("pressure")
    >>> pressure
    PhysicalType({'energy density', 'pressure', 'stress'})
    >>> 'energy density' in pressure
    True

    Physical types can be tested for equality against other physical
    type objects or against strings that may contain the name of a
    physical type.

    >>> area = (u.m ** 2).physical_type
    >>> area == u.barn.physical_type
    True
    >>> area == "area"
    True

    Multiplication, division, and exponentiation are enabled so that
    physical types may be used for dimensional analysis.

    >>> length = u.pc.physical_type
    >>> area = (u.cm ** 2).physical_type
    >>> length * area
    PhysicalType('volume')
    >>> area / length
    PhysicalType('length')
    >>> length ** 3
    PhysicalType('volume')

    may also be performed using a string that contains the name of a
    physical type.

    >>> "length" * area
    PhysicalType('volume')
    >>> "area" / length
    PhysicalType('length')

    Unknown physical types are labelled as ``"unknown"``.

    >>> (u.s ** 13).physical_type
    PhysicalType('unknown')

    Dimensional analysis may be performed for unknown physical types too.

    >>> length_to_19th_power = (u.m ** 19).physical_type
    >>> length_to_20th_power = (u.m ** 20).physical_type
    >>> length_to_20th_power / length_to_19th_power
    PhysicalType('length')
    c             C   s0   t || _| j | _t|| _t| j| _d S )N)r-   _unitr'   _physical_type_idr:   _physical_typesorted_physical_type_list)selfr*   Zphysical_typesr#   r#   r$   __init__4  s    

zPhysicalType.__init__c             c   s   | j E d H  d S )N)r?   )r@   r#   r#   r$   __iter__:  s    zPhysicalType.__iter__c                s^   |dkrt  | tt| |d }tt| |rNd|d}t|t |S t  | d S )Nr?   z-support for accessing str attributes such as za from PhysicalType instances is deprecated since 4.3 and will be removed in a subsequent release.)super__getattribute__getattrr7   hasattrwarningswarnr
   )r@   attrZself_str_attrZwarning_message)	__class__r#   r$   __getattr__=  s    zPhysicalType.__getattr__c             C   s<   t |tr| j|jkS t |tr4t|}|| jS tS dS )z
        Return `True` if ``other`` represents a physical type that is
        consistent with the physical type of the `PhysicalType` instance.
        N)r6   r   r<   r7   r:   issubsetr=   NotImplemented)r@   otherr#   r#   r$   __eq__P  s    

zPhysicalType.__eq__c             C   s   |  |}t|tr| S tS )N)rO   r6   boolrM   )r@   rN   Zequalityr#   r#   r$   __ne__]  s    
zPhysicalType.__ne__c             C   s   dt | jdd  d S )N{r   r   })r7   r?   )r@   r#   r#   r$   _name_string_as_ordered_seta  s    z(PhysicalType._name_string_as_ordered_setc             C   s6   t | jdkr"d| jd  d }n|  }d| dS )Nr   'r   zPhysicalType())lenr=   r?   rT   )r@   namesr#   r#   r$   __repr__d  s    zPhysicalType.__repr__c             C   s   d | jS )Nr.   )joinr?   )r@   r#   r#   r$   __str__k  s    zPhysicalType.__str__c             C   sZ   t | tjrt| S t | tr$| jS t | tjr>| dkr>tjS t | t	rRt
| jS tS dS )a  
        Return a unit that corresponds to the provided argument.

        If a unit is passed in, return that unit.  If a physical type
        (or a `str` with the name of a physical type) is passed in,
        return a unit that corresponds to that physical type.  If the
        number equal to ``1`` is passed in, return a dimensionless unit.
        Otherwise, return `NotImplemented`.
        r   N)r6   r   UnitBaser-   r   r;   numbersRealdimensionless_unscaledr7   r%   rM   )objr#   r#   r$   _dimensionally_compatible_unitn  s    


z+PhysicalType._dimensionally_compatible_unitc             C   s4   |  |}|tkrtS t|}t| j||}|jS )N)ra   rM   r-   rE   r;   physical_type)r@   rN   Z	operationZ
other_unitZnew_unitr#   r#   r$   _dimensional_analysis  s    
z"PhysicalType._dimensional_analysisc             C   s   |  |dS )N__mul__)rc   )r@   rN   r#   r#   r$   rd     s    zPhysicalType.__mul__c             C   s
   |  |S )N)rd   )r@   rN   r#   r#   r$   __rmul__  s    zPhysicalType.__rmul__c             C   s   |  |dS )N__truediv__)rc   )r@   rN   r#   r#   r$   rf     s    zPhysicalType.__truediv__c             C   s$   |  |}|tkrtS |j| dS )Nrf   )ra   rM   rb   rc   )r@   rN   r#   r#   r$   __rtruediv__  s    
zPhysicalType.__rtruediv__c             C   s   | j | jS )N)r;   rb   )r@   r   r#   r#   r$   __pow__  s    zPhysicalType.__pow__c             C   s
   t | jS )N)hashr<   )r@   r#   r#   r$   __hash__  s    zPhysicalType.__hash__c             C   s
   t | jS )N)rW   r=   )r@   r#   r#   r$   __len__  s    zPhysicalType.__len__N)__name__
__module____qualname____doc__rA   rB   rK   rO   rQ   rT   rY   r[   staticmethodra   rc   rd   re   rf   rg   rh   rj   rk   Z	__array____classcell__r#   r#   )rJ   r$   r      s&   hc       
      C   s   |   }t|}d|kr tdtt t|i }||@ }|rVtd| d|tk}|rt| }|t|O }|	| | nt
| |}|t|< x|D ]}|t|< qW x|D ]}	|t|	< qW dS )a  
    Add a mapping between a unit and the corresponding physical type(s).

    If a physical type already exists for a unit, add new physical type
    names so long as those names are not already in use for other
    physical types.

    Parameters
    ----------
    unit : `~astropy.units.Unit`
        The unit to be represented by the physical type.

    name : `str` or `set` of `str`
        A `str` representing the name of the physical type of the unit,
        or a `set` containing strings that represent one or more names
        of physical types.

    Raises
    ------
    ValueError
        If a physical type name is already in use for another unit, or
        if attempting to name a unit as ``"unknown"``.
    r   z/cannot uniquely define an unknown physical typez6the following physical type names are already in use: .N)r'   r:   r    r8   _unit_physical_mappingkeys
difference_physical_unit_mappinggetrA   r   r!   )
r*   r"   r+   Zphysical_type_namesZnames_for_other_unitsZnames_already_in_useZunit_already_in_userb   ptypeZ
ptype_namer#   r#   r$   r     s*    


c          
   C   s   t | tr| S t | tr t| S y$t | tjr2| ntj| ddj}W n2 t	k
rv } zt	|  d|W dd}~X Y nX t
|}| }|tk}|rt| S t|dS dS )a@  
    Return the physical type that corresponds to a unit (or another
    physical type representation).

    Parameters
    ----------
    obj : quantity-like or `~astropy.units.PhysicalType`-like
        An object that (implicitly or explicitly) has a corresponding
        physical type. This object may be a unit, a
        `~astropy.units.Quantity`, an object that can be converted to a
        `~astropy.units.Quantity` (such as a number or array), a string
        that contains a name of a physical type, or a
        `~astropy.units.PhysicalType` instance.

    Returns
    -------
    `~astropy.units.PhysicalType`
        A representation of the physical type(s) of the unit.

    Examples
    --------
    The physical type may be retrieved from a unit or a
    `~astropy.units.Quantity`.

    >>> import astropy.units as u
    >>> u.get_physical_type(u.meter ** -2)
    PhysicalType('column density')
    >>> u.get_physical_type(0.62 * u.barn * u.Mpc)
    PhysicalType('volume')

    The physical type may also be retrieved by providing a `str` that
    contains the name of a physical type.

    >>> u.get_physical_type("energy")
    PhysicalType({'energy', 'torque', 'work'})

    Numbers and arrays of numbers correspond to a dimensionless physical
    type.

    >>> u.get_physical_type(1)
    PhysicalType('dimensionless')
    F)copyz( does not correspond to a physical type.Nr   )r6   r   r7   r%   r   r\   r	   ZQuantityr*   	TypeErrorr-   r'   rv   )r`   r*   excr+   Zunit_has_known_physical_typer#   r#   r$   r     s    +

$"z&.. list-table:: Defined Physical Typesz    :header-rows: 1z    :widths: 30 10 50 z    * - Physical typez      - Unitz-      - Other physical type(s) with same unitz
    * - _``z      - :math:`latexz      - z, c             C   s   g | ]}|t kr|qS r#   )r"   )r3   nr#   r#   r$   
<listcomp>7  s    r   z


)Hro   r]   rG   r|   r   r   r   r   r   r   r	   Zastropy.utils.exceptionsr
   __all__r_   mr4   ZradsrZHzgZmolr&   WJZkgNZPaACVZOhmSFZWbTHcdZlmlxZJyZphotoncmZAARbitZFranklinZ
statampereZBiotZ	abcoulombZelectronZlumenZ_units_and_physical_typesrv   rs   r!   r%   r-   r:   r   r   r   r*   rb   Zdoclinesr>   rt   r"   extendr;   Z	to_stringrZ   r#   r#   r#   r$   <module>   s$  
  
   c6@

$