o
    .wi$                     @   s   d dl mZ d dlmZmZmZmZ d dlmZ d dl	m
Z
 d dlmZmZ d dlmZ d dlmZ d dlmZ d d	lmZmZ d d
lmZmZ esMdgZesSddgZG dd deZdS )    )Sequence)AnyListOptionalUnion)Tensor)Literal)!_spatial_distortion_index_compute _spatial_distortion_index_update)Metric)rank_zero_warn)dim_zero_cat)_MATPLOTLIB_AVAILABLE_TORCHVISION_AVAILABLE)_AX_TYPE_PLOT_OUT_TYPESpatialDistortionIndex.plotSpatialDistortionIndexc                       s
  e Zd ZU dZdZeed< dZeed< dZeed< dZ	e
ed< d	Ze
ed
< ee ed< ee ed< ee ed< ee ed< 			d$dededed deddf
 fddZdedeeef ddfddZdefddZ	d%d eeeee f  d!ee defd"d#Z  ZS )&r   a
  Compute Spatial Distortion Index (SpatialDistortionIndex_) also now as D_s.

    The metric is used to compare the spatial distortion between two images. A value of 0 indicates no distortion
    (optimal value) and corresponds to the case where the high resolution panchromatic image is equal to the low
    resolution panchromatic image. The metric is defined as:

    .. math::
        D_s = \\sqrt[q]{\frac{1}{L}\\sum_{l=1}^L|Q(\\hat{G_l}, P) - Q(\tilde{G}, \tilde{P})|^q}

    where :math:`Q` is the universal image quality index (see this
    :class:`~torchmetrics.image.UniversalImageQualityIndex` for more info), :math:`\\hat{G_l}` is the l-th band of the
    high resolution multispectral image, :math:`\tilde{G}` is the high resolution panchromatic image, :math:`P` is the
    high resolution panchromatic image, :math:`\tilde{P}` is the low resolution panchromatic image, :math:`L` is the
    number of bands and :math:`q` is the order of the norm applied on the difference.

    As input to ``forward`` and ``update`` the metric accepts the following input

    - ``preds`` (:class:`~torch.Tensor`): High resolution multispectral image of shape ``(N,C,H,W)``.
    - ``target`` (:class:`~Dict`): A dictionary containing the following keys:
        - ``ms`` (:class:`~torch.Tensor`): Low resolution multispectral image of shape ``(N,C,H',W')``.
        - ``pan`` (:class:`~torch.Tensor`): High resolution panchromatic image of shape ``(N,C,H,W)``.
        - ``pan_lr`` (:class:`~torch.Tensor`): Low resolution panchromatic image of shape ``(N,C,H',W')``.

    where H and W must be multiple of H' and W'.

    As output of `forward` and `compute` the metric returns the following output

    - ``sdi`` (:class:`~torch.Tensor`): if ``reduction!='none'`` returns float scalar tensor with average SDI value
      over sample else returns tensor of shape ``(N,)`` with SDI values per sample

    Args:
        norm_order: Order of the norm applied on the difference.
        window_size: Window size of the filter applied to degrade the high resolution panchromatic image.
        reduction: a method to reduce metric score over labels.

            - ``'elementwise_mean'``: takes the mean (default)
            - ``'sum'``: takes the sum
            - ``'none'``: no reduction will be applied

        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Example:
        >>> from torch import rand
        >>> from torchmetrics.image import SpatialDistortionIndex
        >>> preds = rand([16, 3, 32, 32])
        >>> target = {
        ...     'ms': rand([16, 3, 16, 16]),
        ...     'pan': rand([16, 3, 32, 32]),
        ... }
        >>> sdi = SpatialDistortionIndex()
        >>> sdi(preds, target)
        tensor(0.0090)

    Fhigher_is_betterTis_differentiablefull_state_updateg        plot_lower_boundg      ?plot_upper_boundpredsmspanpan_lr      elementwise_mean
norm_orderwindow_size	reductionr   sumnonekwargsreturnNc                    s   t  jdi | td t|tr|dkrtd| d|| _t|tr*|dkr2td| d|| _d}||vrEtd| d| || _| j	d	g d
d | j	dg d
d | j	dg d
d | j	dg d
d d S )NzMetric `SpatialDistortionIndex` will save all targets and predictions in buffer. For large datasets this may lead to large memory footprint.r   z@Expected `norm_order` to be a positive integer. Got norm_order: .zBExpected `window_size` to be a positive integer. Got window_size: r#   z(Expected argument `reduction` be one of z	 but got r   cat)defaultdist_reduce_fxr   r   r    )
super__init__r   
isinstanceint
ValueErrorr    r!   r"   	add_state)selfr    r!   r"   r&   allowed_reductions	__class__r,   S/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/image/d_s.pyr.   f   s$   zSpatialDistortionIndex.__init__targetc                 C   s   d|vrt d|  dd|vrt d|  d|d }|d }|d}t||||\}}}}| j| | j|d  | j|d  d|v rX| j|d  dS dS )a  Update state with preds and target.

        Args:
            preds: High resolution multispectral image.
            target: A dictionary containing the following keys:

                - ``'ms'``: low resolution multispectral image.
                - ``'pan'``: high resolution panchromatic image.
                - ``'pan_lr'``: (optional) low resolution panchromatic image.

        Raises:
            ValueError:
                If ``target`` doesn't have ``ms`` and ``pan``.

        r   z0Expected `target` to have key `ms`. Got target: r(   r   z1Expected `target` to have key `pan`. Got target: r   N)	r1   keysgetr
   r   appendr   r   r   )r3   r   r8   r   r   r   r,   r,   r7   update   s   
zSpatialDistortionIndex.updatec                 C   sx   t | j}t | j}t | j}t| jdkrt | jnd}||d}||dur,d|ini  t||||| j| j	| j
S )z-Compute and returns spatial distortion index.r   N)r   r   r   )r   r   r   r   lenr   r<   r	   r    r!   r"   )r3   r   r   r   r   r8   r,   r,   r7   compute   s   



zSpatialDistortionIndex.computevalaxc                 C   s   |  ||S )a  Plot a single or multiple values from the metric.

        Args:
            val: Either a single result from calling `metric.forward` or `metric.compute` or a list of these results.
                If no value is provided, will automatically call `metric.compute` and plot that result.
            ax: An matplotlib axis object. If provided will add plot to that axis

        Returns:
            Figure and Axes object

        Raises:
            ModuleNotFoundError:
                If `matplotlib` is not installed

        .. plot::
            :scale: 75

            >>> # Example plotting a single value
            >>> from torch import rand
            >>> from torchmetrics.image import SpatialDistortionIndex
            >>> preds = rand([16, 3, 32, 32])
            >>> target = {
            ...     'ms': rand([16, 3, 16, 16]),
            ...     'pan': rand([16, 3, 32, 32]),
            ... }
            >>> metric = SpatialDistortionIndex()
            >>> metric.update(preds, target)
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> # Example plotting multiple values
            >>> from torch import rand
            >>> from torchmetrics.image import SpatialDistortionIndex
            >>> preds = rand([16, 3, 32, 32])
            >>> target = {
            ...     'ms': rand([16, 3, 16, 16]),
            ...     'pan': rand([16, 3, 32, 32]),
            ... }
            >>> metric = SpatialDistortionIndex()
            >>> values = [ ]
            >>> for _ in range(10):
            ...     values.append(metric(preds, target))
            >>> fig_, ax_ = metric.plot(values)

        )_plot)r3   r?   r@   r,   r,   r7   plot   s   2r   )r   r   r   )NN)__name__
__module____qualname____doc__r   bool__annotations__r   r   r   floatr   r   r   r0   r   r   r.   dictstrr<   r>   r   r   r   r   r   rB   __classcell__r,   r,   r5   r7   r   #   sF   
 7N)collections.abcr   typingr   r   r   r   torchr   typing_extensionsr   !torchmetrics.functional.image.d_sr	   r
   torchmetrics.metricr   torchmetrics.utilitiesr   torchmetrics.utilities.datar   torchmetrics.utilities.importsr   r   torchmetrics.utilities.plotr   r   __doctest_skip__r   r,   r,   r,   r7   <module>   s   