a
    ߙfb0                     @   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 : https://ui.adsabs.harvard.edu/abs/2004PASP..116..133L
    N   )ZScaleIntervalmake_lupton_rgbc                 C   sL   |du s|du r,|du r |du s(t d| S | | | d }tj|| jdS )aT  
    Return a naive total intensity from the red, blue, and green intensities.

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

    Returns
    -------
    intensity : 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.9/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 )MappingaA  
    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 : ndarray, optional
        An image used to calculate some parameters of some mappings.
    Nc                 C   sh   t ttjj| _zt| W n ty<   d|g }Y n0 t|dkrRt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 : ndarray
            Image to map to red.
        image_g : ndarray
            Image to map to green.
        image_b : ndarray
            Image to map to blue.

        Returns
        -------
        RGBimage : 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 : ndarray
            Intensity of image to be mapped to red; or total intensity if
            ``image_g`` and ``image_b`` are None.
        image_g : ndarray, optional
            Intensity of image to be mapped to green.
        image_b : ndarray, optional
            Intensity of image to be mapped to blue.

        Returns
        -------
        intensity : 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   sB   t jddd  t |d| jW  d   S 1 s40    Y  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 : ndarray
            Intensity to be mapped.

        Returns
        -------
        mapped_I : ndarray
            ``I`` mapped to uint8
        ignoreinvalidZdivider   N)r   errstateZclipr   r   Ir   r   r   map_intensity_to_uint8}   s    zMapping.map_intensity_to_uint8c                 C   s  || j d  }|| j d  }|| j d  }| | |||}|||g}|D ]D}||9 }tjdd d||dk < W d   qL1 s0    Y  qL| j}|\}}	}
tjddd t|D ]\}}t||	kt||
kt||k|| | |t|
|k|| |
 |t|	|
kt|	|k|| |	 |t|
|k|| |
 |tj	}||||k< |||< qW d   n1 s|0    Y  |S )z\Use the mapping to convert images image_r, image_g, and image_b to a triplet of uint8 imagesr   r      r#   )r%   Nr$   )
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      s8    
,



*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 u s|d u r@|d u r t d|d u r0| }|d u r@| }tj| ||d || _|d u 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   r5   r   r   r   r   r      s    zLinearMapping.__init__c                 C   sb   t jddd@ t |dkdt || jk| j| | j| j W  d    S 1 sT0    Y  d S Nr#   r$   r   )r   r&   r,   r6   r   r'   r   r   r   r)      s     z$LinearMapping.map_intensity_to_uint8)NNNr/   r0   r1   r2   r   r)   r   r   r   r   r3      s   
r3   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 https://ui.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   sZ   t jddd8 t |dkdt || j | j | W  d    S 1 sL0    Y  d S r7   )r   r&   r,   r<   r>   r=   r'   r   r   r   r)     s    z#AsinhMapping.map_intensity_to_uint8N)r:   r8   r   r   r   r   r9      s   
r9   c                   @   s   e Zd ZdZdddZdS )AsinhZScaleMappingaO  
    A mapping for an asinh stretch, estimating the linear stretch by zscale.

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

    Parameters
    ----------
    image1 : ndarray or a list of arrays
        The image to analyse, or a list of 3 images to be converted to
        an intensity image.
    image2 : ndarray, optional
        the second image to analyse (must be specified with image3).
    image3 : 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[]
    Nr:   c                 C   s<  |du s|du r0|du r |du s(t d|g}n
|||g}|durzt| W n tyj   d|g }Y n0 t|dkrt dt|}t|D ]$\}}|| dkr|||  ||< qnt|dg }t| }t |}	t|	d|i}
|
j	|
j
d  }|
j
}t|D ]\}}||  |7  < q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_limitsr3   r5   r   r9   r   r   )r   Zimage1Zimage2Zimage3r@   Zpedestalr   r.   ZimZzscale_limitsZzscaler?   r   levelr   r   r   r      s4    
zAsinhZScaleMapping.__init__)NNr:   N)r/   r0   r1   r2   r   r   r   r   r   rB     s   rB      r:   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:astropy-visualization-rgb`.

    Parameters
    ----------
    image_r : ndarray
        Image to map to red.
    image_g : ndarray
        Image to map to green.
    image_b : 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 : ndarray
        RGB (integer, 8-bits per channel) color image as an NxNx3 numpy array.
    r   Nlower)origin)r9   r"   Zmatplotlib.imager   Zimsave)
r	   r
   r   r   r?   r@   filenameZasinhMapZrgbZ
matplotlibr   r   r   r   J  s     )NN)r   rE   r:   N)r2   Znumpyr    r   __all__r   r   r3   r9   rB   r   r   r   r   r   <module>   s   
  )*D  