U
    e»{jÓ#  ã                   @   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gZdd	giZG d
d„ dejƒZdS )z`
This module contains the classes and utility functions for distance and
cartesian coordinates.
é    N)Úunits)ÚAstropyWarningé   )ÚAngleÚDistanceÚ*Zscipyc                       s€   e Zd ZdZejZdZddddddej	dddddf‡ fdd„	Z
edd	„ ƒZdd
d„Zedd„ ƒZedd„ ƒZedd„ ƒZ‡  ZS )r   aý
  
    A one-dimensional distance.

    This can be initialized by providing one of the following:

    * Distance ``value`` (array or float) and a ``unit``
    * |Quantity| object with dimensionality of length
    * Redshift and (optionally) a `~astropy.cosmology.Cosmology`
    * Distance modulus
    * Parallax

    Parameters
    ----------
    value : scalar or `~astropy.units.Quantity` ['length']
        The value of this distance.
    unit : `~astropy.units.UnitBase` ['length']
        The unit for this distance.
    z : float
        A redshift for this distance.  It will be converted to a distance
        by computing the luminosity distance for this redshift given the
        cosmology specified by ``cosmology``. Must be given as a keyword
        argument.
    cosmology : `~astropy.cosmology.Cosmology` or None
        A cosmology that will be used to compute the distance from ``z``.
        If `None`, the current cosmology will be used (see
        `astropy.cosmology` for details).
    distmod : float or `~astropy.units.Quantity`
        The distance modulus for this distance. Note that if ``unit`` is not
        provided, a guess will be made at the unit between AU, pc, kpc, and Mpc.
    parallax : `~astropy.units.Quantity` or `~astropy.coordinates.Angle`
        The parallax in angular units.
    dtype : `~numpy.dtype`, optional
        See `~astropy.units.Quantity`.
    copy : bool, optional
        See `~astropy.units.Quantity`.
    order : {'C', 'F', 'A'}, optional
        See `~astropy.units.Quantity`.
    subok : bool, optional
        See `~astropy.units.Quantity`.
    ndmin : int, optional
        See `~astropy.units.Quantity`.
    allow_negative : bool, optional
        Whether to allow negative distances (which are possible in some
        cosmologies).  Default: `False`.

    Raises
    ------
    `~astropy.units.UnitsError`
        If the ``unit`` is not a length unit.
    ValueError
        If value specified is less than 0 and ``allow_negative=False``.

        If ``cosmology`` is provided when ``z`` is *not* given.

        If either none or more than one of ``value``, ``z``, ``distmod``,
        or ``parallax`` were given.


    Examples
    --------
    >>> from astropy import units as u
    >>> from astropy.cosmology import WMAP5
    >>> Distance(10, u.Mpc)
    <Distance 10. Mpc>
    >>> Distance(40*u.pc, unit=u.kpc)
    <Distance 0.04 kpc>
    >>> Distance(z=0.23)                      # doctest: +FLOAT_CMP
    <Distance 1184.01657566 Mpc>
    >>> Distance(z=0.23, cosmology=WMAP5)     # doctest: +FLOAT_CMP
    <Distance 1147.78831918 Mpc>
    >>> Distance(distmod=24.47*u.mag)         # doctest: +FLOAT_CMP
    <Distance 783.42964277 kpc>
    >>> Distance(parallax=21.34*u.mas)        # doctest: +FLOAT_CMP
    <Distance 46.86035614 pc>
    TNFr   c              
      s„  t dd„ ||||fD ƒƒ}|dkr,tdƒ‚n|dkr<tdƒ‚|d krHd}|d k	rx|d krlddlm} | ¡ }| |¡}nÌ|d k	rŠtd	ƒ‚nº|d k	rì|  |¡}|d krêt |j	¡ 
¡ }|d
krÄtj}n&|dkrÔtj}n|dk rätj}ntj}nX|d k	�rD|d k�rtj}|j|t ¡ d�}t |dk ¡�rD|�r<t dt¡ ntdƒ‚tƒ j| |||||	|
|d�}|�s€t |j	dk ¡�r€tdƒ‚|S )Nc                 s   s   | ]}|d k	V  qd S )N© )Ú.0Úxr   r   ú\/var/www/html/bwave/python/venv/lib/python3.8/site-packages/astropy/coordinates/distances.pyÚ	<genexpr>v   s     z#Distance.__new__.<locals>.<genexpr>r   zQnone of `value`, `z`, `distmod`, or `parallax` were given to Distance constructorr   zZmore than one of `value`, `z`, `distmod`, or `parallax` were given to Distance constructorF©Údefault_cosmologyzHa `cosmology` was given but `z` was not provided in Distance constructoré   é   éýÿÿÿ)ZequivalencieszØnegative parallaxes are converted to NaN distances even when `allow_negative=True`, because negative parallaxes cannot be transformed into distances. See the discussion in this paper: https://arxiv.org/abs/1507.02105zòsome parallaxes are negative, which are not interpretable as distances. See the discussion in this paper: https://arxiv.org/abs/1507.02105 . You can convert negative parallaxes to NaN distances by providing the `allow_negative=True` argument.)ÚdtypeÚcopyÚorderÚsubokÚndminzWdistance must be >= 0. Use the argument `allow_negative=True` to allow negative values.)ÚsumÚ
ValueErrorÚastropy.cosmologyr   ÚgetÚluminosity_distanceÚ_distmod_to_pcÚnpÚlog10ÚvalueZmeanÚuZMpcZkpcZAUÚpcÚto_valueÚparallaxÚanyÚwarningsÚwarnr   ÚsuperÚ__new__)Úclsr   ÚunitÚzÚ	cosmologyÚdistmodr#   r   r   r   r   r   Zallow_negativeZ
n_not_noner   Z
meanlogvalZdistance©Ú	__class__r   r   r(   g   sv    ÿÿÿ


ûÿ	øÿzDistance.__new__c                 C   s   |   ¡ S )zShort for ``self.compute_z()``)Ú	compute_z©Úselfr   r   r   r+   Ï   s    z
Distance.zc                 K   sD   ddl m} |dkr(ddl m} | ¡ }| dd¡ ||j| f|ŽS )aº  
        The redshift for this distance assuming its physical distance is
        a luminosity distance.

        Parameters
        ----------
        cosmology : `~astropy.cosmology.Cosmology` or None
            The cosmology to assume for this calculation, or `None` to use the
            current cosmology (see `astropy.cosmology` for details).
        **atzkw
            keyword arguments for :func:`~astropy.cosmology.z_at_value`

        Returns
        -------
        z : `~astropy.units.Quantity`
            The redshift of this distance given the provided ``cosmology``.

        Warnings
        --------
        This method can be slow for large arrays.
        The redshift is determined using :func:`astropy.cosmology.z_at_value`,
        which handles vector inputs (e.g. an array of distances) by
        element-wise calling of :func:`scipy.optimize.minimize_scalar`.
        For faster results consider using an interpolation table;
        :func:`astropy.cosmology.z_at_value` provides details.

        See Also
        --------
        :func:`astropy.cosmology.z_at_value` : Find the redshift corresponding to a
            :meth:`astropy.cosmology.FLRW.luminosity_distance`.
        r   )Ú
z_at_valueNr   Zztolg»½×Ùß|Û=)r   r3   r   r   Ú
setdefaultr   )r2   r,   Zatzkwr3   r   r   r   r   r0   Ô   s     zDistance.compute_zc                 C   s,   dt  |  tj¡¡ d }tj|tjdd�S )z3The distance modulus as a `~astropy.units.Quantity`ç      @F©r   )r   r   r"   r    r!   ÚQuantityÚmag)r2   Úvalr   r   r   r-   þ   s    zDistance.distmodc                 C   s,   t  |t j¡}| d|jd d  t jdd�S )Né
   é   r5   Fr6   )r    r7   r8   r   r!   )r)   Údmr   r   r   r     s    zDistance._distmod_to_pcc                 C   s   t |  tjt ¡ ¡ƒS )z<The parallax angle as an `~astropy.coordinates.Angle` object)r   Útor    Zmilliarcsecondr#   r1   r   r   r   r#   	  s    zDistance.parallax)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r    ÚmZ_equivalent_unitZ _include_easy_conversion_membersr   Zinexactr(   Úpropertyr+   r0   r-   Úclassmethodr   r#   Ú__classcell__r   r   r.   r   r      s2   Lóh

*

)rA   r%   Únumpyr   Zastropyr   r    Zastropy.utils.exceptionsr   Zanglesr   Ú__all__Z__doctest_requires__ZSpecificTypeQuantityr   r   r   r   r   Ú<module>   s   
