B
    q\1                 @   st   d Z ddlZddlmZ dgZdddZG dd	 d	ZG d
d deZG dd deZ	G dd de	Z
dddZdS )z
Combine 3 images to produce a properly-scaled RGB image following Lupton et al. (2004).

The three images must be aligned and have the same pixel scale and size.

For details, see : http://adsabs.harvard.edu/abs/2004PASP..116..133L
    N   )ZScaleIntervalmake_lupton_rgbc             C   sL   |dks|dkr,|dkr |dks(t d| S | | | d }tj|| jdS )ax  
    Return a naive total intensity from the red, blue, and green intensities.

    Parameters
    ----------
    image_r : `~numpy.ndarray`
        Intensity of image to be mapped to red; or total intensity if ``image_g``
        and ``image_b`` are None.
    image_g : `~numpy.ndarray`, optional
        Intensity of image to be mapped to green.
    image_b : `~numpy.ndarray`, optional
        Intensity of image to be mapped to blue.

    Returns
    -------
    intensity : `~numpy.ndarray`
        Total intensity from the red, blue and green intensities, or ``image_r``
        if green and blue images are not provided.
    NzDplease specify either a single image or red, green, and blue images.g      @)dtype)
ValueErrornpasarrayr   )image_rimage_gimage_b	intensity r   ?lib/python3.7/site-packages/astropy/visualization/lupton_rgb.pycompute_intensity   s    r   c               @   s:   e Zd ZdZdddZdd Zdd Zd	d
 Zdd ZdS )MappingaJ  
    Baseclass to map red, blue, green intensities into uint8 values.

    Parameters
    ----------
    minimum : float or sequence(3)
        Intensity that should be mapped to black (a scalar or array for R, G, B).
    image : `~numpy.ndarray`, optional
        An image used to calculate some parameters of some mappings.
    Nc             C   sj   t ttjj| _yt| W n tk
r>   d|g }Y nX t|dkrTtd|| _	t
|| _d S )N   z)please provide 1 or 3 values for minimum.)floatr   Ziinfouint8max	_uint8Maxlen	TypeErrorr   minimumr   _image)selfr   imager   r   r   __init__=   s    zMapping.__init__c             C   sn   t |}t |}t |}|j|jks6|j|jkrRd}t||j|j|jt | |||t jS )a  
        Convert 3 arrays, image_r, image_g, and image_b into an 8-bit RGB image.

        Parameters
        ----------
        image_r : `~numpy.ndarray`
            Image to map to red.
        image_g : `~numpy.ndarray`
            Image to map to green.
        image_b : `~numpy.ndarray`
            Image to map to blue.

        Returns
        -------
        RGBimage : `~numpy.ndarray`
            RGB (integer, 8-bits per channel) color image as an NxNx3 numpy array.
        z/The image shapes must match. r: {}, g: {} b: {})	r   r   shaper   formatZdstack_convert_images_to_uint8astyper   )r   r	   r
   r   msgr   r   r   make_rgb_imageJ   s    


zMapping.make_rgb_imagec             C   s   t |||S )a  
        Return the total intensity from the red, blue, and green intensities.
        This is a naive computation, and may be overridden by subclasses.

        Parameters
        ----------
        image_r : `~numpy.ndarray`
            Intensity of image to be mapped to red; or total intensity if
            ``image_g`` and ``image_b`` are None.
        image_g : `~numpy.ndarray`, optional
            Intensity of image to be mapped to green.
        image_b : `~numpy.ndarray`, optional
            Intensity of image to be mapped to blue.

        Returns
        -------
        intensity : `~numpy.ndarray`
            Total intensity from the red, blue and green intensities, or
            ``image_r`` if green and blue images are not provided.
        )r   )r   r	   r
   r   r   r   r   r   f   s    zMapping.intensityc          	   C   s*   t jddd t |d| jS Q R X dS )a  
        Return an array which, when multiplied by an image, returns that image
        mapped to the range of a uint8, [0, 255] (but not converted to uint8).

        The intensity is assumed to have had minimum subtracted (as that can be
        done per-band).

        Parameters
        ----------
        I : `~numpy.ndarray`
            Intensity to be mapped.

        Returns
        -------
        mapped_I : `~numpy.ndarray`
            ``I`` mapped to uint8
        ignore)invaliddivider   N)r   errstateZclipr   )r   Ir   r   r   map_intensity_to_uint8}   s    zMapping.map_intensity_to_uint8c             C   sh  || j d  }|| j d  }|| j d  }| | |||}|||g}x8|D ]0}||9 }tjdd d||dk < W dQ R X qNW | j}|\}}	}
tjddd xt|D ]\}}t||	kt||
kt||k|| | |t|
|k|| |
 |t|	|
kt|	|k|| |	 |t|
|k|| |
 |tj	}||||k< |||< qW W dQ R X |S )z\Use the mapping to convert images image_r, image_g, and image_b to a triplet of uint8 imagesr   r      r#   )r$   N)r$   r%   )
r   r(   r   r   r&   r   	enumeratewherer    r   )r   r	   r
   r   ZfacZ	image_rgbcZpixmaxZr0Zg0Zb0ir   r   r   r      s.    





&z Mapping._convert_images_to_uint8)NN)	__name__
__module____qualname____doc__r   r"   r   r(   r   r   r   r   r   r   1   s   

r   c               @   s"   e Zd ZdZdddZdd ZdS )LinearMappinga  
    A linear map map of red, blue, green intensities into uint8 values.

    A linear stretch from [minimum, maximum].
    If one or both are omitted use image min and/or max to set them.

    Parameters
    ----------
    minimum : float
        Intensity that should be mapped to black (a scalar or array for R, G, B).
    maximum : float
        Intensity that should be mapped to white (a scalar).
    Nc             C   s   |d ks|d kr@|d kr t d|d kr0| }|d kr@| }tj| ||d || _|d krfd | _n||krvt dt|| | _d S )NzCyou must provide an image if you don't set both minimum and maximum)r   r   z,minimum and maximum values must not be equal)r   minr   r   r   maximum_ranger   )r   r   r4   r   r   r   r   r      s    zLinearMapping.__init__c             C   sJ   t jddd2 t |dkdt || jk| j| | j| j S Q R X d S )Nr#   )r$   r%   r   )r   r&   r+   r5   r   )r   r'   r   r   r   r(      s    z$LinearMapping.map_intensity_to_uint8)NNN)r.   r/   r0   r1   r   r(   r   r   r   r   r2      s   
r2   c               @   s"   e Zd ZdZdddZdd ZdS )	AsinhMappinga  
    A mapping for an asinh stretch (preserving colours independent of brightness)

    x = asinh(Q (I - minimum)/stretch)/Q

    This reduces to a linear stretch if Q == 0

    See http://adsabs.harvard.edu/abs/2004PASP..116..133L

    Parameters
    ----------

    minimum : float
        Intensity that should be mapped to black (a scalar or array for R, G, B).
    stretch : float
        The linear stretch of the image.
    Q : float
        The asinh softening parameter.
       c             C   sb   t | | d}t||k r"d}nd}||kr2|}d}|| j t||  | _|t| | _d S )Ng      >g?g    _B)	r   r   absr   r   arcsinh_sloper   _soften)r   r   stretchQepsilonZQmaxZfracr   r   r   r      s    zAsinhMapping.__init__c          	   C   sB   t jddd* t |dkdt || j | j | S Q R X d S )Nr#   )r$   r%   r   )r   r&   r+   r9   r;   r:   )r   r'   r   r   r   r(     s    z#AsinhMapping.map_intensity_to_uint8N)r7   )r.   r/   r0   r1   r   r(   r   r   r   r   r6      s   
r6   c               @   s   e Zd ZdZdddZdS )AsinhZScaleMappingaj  
    A mapping for an asinh stretch, estimating the linear stretch by zscale.

    x = asinh(Q (I - z1)/(z2 - z1))/Q

    Parameters
    ----------
    image1 : `~numpy.ndarray` or a list of arrays
        The image to analyse, or a list of 3 images to be converted to
        an intensity image.
    image2 : `~numpy.ndarray`, optional
        the second image to analyse (must be specified with image3).
    image3 : `~numpy.ndarray`, optional
        the third image to analyse (must be specified with image2).
    Q : float, optional
        The asinh softening parameter. Default is 8.
    pedestal : float or sequence(3), optional
        The value, or array of 3 values, to subtract from the images; or None.

    Notes
    -----
    pedestal, if not None, is removed from the images when calculating the
    zscale stretch, and added back into Mapping.minimum[]
    Nr7   c             C   sF  |dks|dkr0|dkr |dks(t d|g}n
|||g}|dk	ryt| W n tk
rl   d|g }Y nX t|dkrt dt|}x@t|D ]$\}}|| dkr|||  ||< qW nt|dg }t| }t |}	t|	d|i}
|
j	|
j
d  }|
j
}x&t|D ]\}}||  |7  < qW t| ||| || _dS )z	
        Nz5please specify either a single image or three images.r   z please provide 1 or 3 pedestals.g        r   r   )r   r   r   listr*   r   r   Z
get_limitsr2   r4   r   r6   r   r   )r   Zimage1Zimage2Zimage3r=   Zpedestalr   r-   ZimZzscale_limitsZzscaler<   r   levelr   r   r   r      s4    
zAsinhZScaleMapping.__init__)NNr7   N)r.   r/   r0   r1   r   r   r   r   r   r?     s   r?      r7   c       
      C   s<   t |||}|| ||}|r8ddl}	|	jj||dd |S )a  
    Return a Red/Green/Blue color image from up to 3 images using an asinh stretch.
    The input images can be int or float, and in any range or bit-depth.

    For a more detailed look at the use of this method, see the document
    :ref:`astropy-visualization-rgb`.

    Parameters
    ----------

    image_r : `~numpy.ndarray`
        Image to map to red.
    image_g : `~numpy.ndarray`
        Image to map to green.
    image_b : `~numpy.ndarray`
        Image to map to blue.
    minimum : float
        Intensity that should be mapped to black (a scalar or array for R, G, B).
    stretch : float
        The linear stretch of the image.
    Q : float
        The asinh softening parameter.
    filename: str
        Write the resulting RGB image to a file (file type determined
        from extension).

    Returns
    -------
    rgb : `~numpy.ndarray`
        RGB (integer, 8-bits per channel) color image as an NxNx3 numpy array.
    r   Nlower)origin)r6   r"   Zmatplotlib.imager   Zimsave)
r	   r
   r   r   r<   r=   filenameZasinhMapZrgbZ
matplotlibr   r   r   r   J  s    !)NN)r   rB   r7   N)r1   Znumpyr    r   __all__r   r   r2   r6   r?   r   r   r   r   r   <module>   s   
  )*D 