o
    .wiW+                     @   s  d dl m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 es.dd	gZ	dd
edededee deeeeee f f
ddZ				dd
edededee dededed defddZ				dd
edededee dededed defdd	ZdS )    )OptionalN)Tensor)Literal)universal_image_quality_index)reduce)_TORCHVISION_AVAILABLE!_spatial_distortion_index_computespatial_distortion_indexpredsmspanpan_lrreturnc                 C   s  t | jdkrtd| j d| j|jkr#td| j d|j d| j|jkr6td| j d|j d|durM| j|jkrMtd	| j d
|j dt |jdkr]td|j dt |jdkrmtd|j d|durt |jdkrtd|j d| jdd |jdd krtd| j d|j d| jdd |jdd krtd| j d|j d|dur| jdd |jdd krtd| j d
|j d| jdd \}}|jdd \}}|jdd \}}	||krtd| d| ||	krtd| d|	 || dkr td| d| d|| dkr2td| d| d|| dkrDtd| d| d|	| dkrVtd|	 d| d|dur|jdd \}
}|
|krttd| d
|
 d||krtd| d
| d| |||fS )a  Update and returns variables required to compute Spatial Distortion Index.

    Args:
        preds: High resolution multispectral image.
        ms: Low resolution multispectral image.
        pan: High resolution panchromatic image.
        pan_lr: Low resolution panchromatic image.

    Return:
        A tuple of Tensors containing ``preds``, ``ms``, ``pan`` and ``pan_lr``.

    Raises:
        TypeError:
            If ``preds``, ``ms``, ``pan`` and ``pan_lr`` don't have the same data type.
        ValueError:
            If ``preds``, ``ms``, ``pan`` and ``pan_lr`` don't have ``BxCxHxW shape``.
        ValueError:
            If ``preds``, ``ms``, ``pan`` and ``pan_lr`` don't have the same batch and channel sizes.
        ValueError:
            If ``preds`` and ``pan`` don't have the same dimension.
        ValueError:
            If ``ms`` and ``pan_lr`` don't have the same dimension.
        ValueError:
            If ``preds`` and ``pan`` don't have dimension which is multiple of that of ``ms``.

       z3Expected `preds` to have BxCxHxW shape. Got preds: .zAExpected `preds` and `ms` to have the same data type. Got preds: z	 and ms: zBExpected `preds` and `pan` to have the same data type. Got preds: z
 and pan: NzEExpected `preds` and `pan_lr` to have the same data type. Got preds: z and pan_lr: z-Expected `ms` to have BxCxHxW shape. Got ms: z/Expected `pan` to have BxCxHxW shape. Got pan: z5Expected `pan_lr` to have BxCxHxW shape. Got pan_lr:    zOExpected `preds` and `ms` to have the same batch and channel sizes. Got preds: zPExpected `preds` and `pan` to have the same batch and channel sizes. Got preds: zSExpected `preds` and `pan_lr` to have the same batch and channel sizes. Got preds: z?Expected `preds` and `pan` to have the same height. Got preds: z>Expected `preds` and `pan` to have the same width. Got preds: r   zHExpected height of `preds` to be multiple of height of `ms`. Got preds: zFExpected width of `preds` to be multiple of width of `ms`. Got preds: zFExpected height of `pan` to be multiple of height of `ms`. Got preds: zDExpected width of `pan` to be multiple of width of `ms`. Got preds: z<Expected `ms` and `pan_lr` to have the same height. Got ms: z;Expected `ms` and `pan_lr` to have the same width. Got ms: )lenshape
ValueErrordtype	TypeError)r
   r   r   r   preds_hpreds_wms_hms_wpan_hpan_wpan_lr_hpan_lr_w r    ^/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/functional/image/d_s.py _spatial_distortion_index_update   s   $



r"         elementwise_mean
norm_orderwindow_size	reduction)r%   sumnonec                 C   sN  | j d }|j dd \}}	||ks||	krtd| d|du rGts(tdddlm}
 dd	lm} |||d
}|
||j dd dd}n|}tj|| j	d}tj|| j	d}t
|D ]8}t|dd||d f |dd||d f ||< t| dd||d f |dd||d f ||< q]||  | }t||d|  S )a  Compute Spatial Distortion Index (SpatialDistortionIndex_).

    Args:
        preds: High resolution multispectral image.
        ms: Low resolution multispectral image.
        pan: High resolution panchromatic image.
        pan_lr: Low resolution panchromatic image.
        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

    Return:
        Tensor with SpatialDistortionIndex score

    Raises:
        ValueError
            If ``window_size`` is smaller than dimension of ``ms``.

    Example:
        >>> from torch import rand
        >>> preds = rand([16, 3, 32, 32])
        >>> ms = rand([16, 3, 16, 16])
        >>> pan = rand([16, 3, 32, 32])
        >>> preds, ms, pan, pan_lr = _spatial_distortion_index_update(preds, ms, pan)
        >>> _spatial_distortion_index_compute(preds, ms, pan, pan_lr)
        tensor(0.0090)

    r#   r   NzNExpected `window_size` to be smaller than dimension of `ms`. Got window_size: r   zWhen `pan_lr` is not provided as input to metric Spatial distortion index, torchvision should be installed. Please install with `pip install torchvision` or `pip install torchmetrics[image]`.r   )resize)_uniform_filter)r'   F)size	antialias)device)r   r   r   !torchvision.transforms.functionalr+   #torchmetrics.functional.image.utilsr,   torchzerosr/   ranger   absr   )r
   r   r   r   r&   r'   r(   lengthr   r   r+   r,   pan_degradedm1m2idiffr    r    r!   r      s.   
)
68c                 C   sn   t |tr	|dkrtd| dt |tr|dkr"td| dt| |||\} }}}t| ||||||S )a  Calculate `Spatial Distortion Index`_ (SpatialDistortionIndex_) also known as D_s.

    Metric is used to compare the spatial distortion between two images.

    Args:
        preds: High resolution multispectral image.
        ms: Low resolution multispectral image.
        pan: High resolution panchromatic image.
        pan_lr: Low resolution panchromatic image.
        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

    Return:
        Tensor with SpatialDistortionIndex score

    Raises:
        TypeError:
            If ``preds``, ``ms``, ``pan`` and ``pan_lr`` don't have the same data type.
        ValueError:
            If ``preds``, ``ms``, ``pan`` and ``pan_lr`` don't have ``BxCxHxW shape``.
        ValueError:
            If ``preds``, ``ms``, ``pan`` and ``pan_lr`` don't have the same batch and channel sizes.
        ValueError:
            If ``preds`` and ``pan`` don't have the same dimension.
        ValueError:
            If ``ms`` and ``pan_lr`` don't have the same dimension.
        ValueError:
            If ``preds`` and ``pan`` don't have dimension which is multiple of that of ``ms``.
        ValueError:
            If ``norm_order`` is not a positive integer.
        ValueError:
            If ``window_size`` is not a positive integer.

    Example:
        >>> from torch import rand
        >>> from torchmetrics.functional.image import spatial_distortion_index
        >>> preds = rand([16, 3, 32, 32])
        >>> ms = rand([16, 3, 16, 16])
        >>> pan = rand([16, 3, 32, 32])
        >>> spatial_distortion_index(preds, ms, pan)
        tensor(0.0090)

    r   z@Expected `norm_order` to be a positive integer. Got norm_order: r   zBExpected `window_size` to be a positive integer. Got window_size: )
isinstanceintr   r"   r   )r
   r   r   r   r&   r'   r(   r    r    r!   r	      s   9)N)Nr#   r$   r%   )typingr   r2   r   typing_extensionsr   !torchmetrics.functional.image.uqir   "torchmetrics.utilities.distributedr   torchmetrics.utilities.importsr   __doctest_skip__tupler"   r=   r   r	   r    r    r    r!   <module>   s~   
j
N