o
    .wi                     @   sV  d dl mZ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 d dlmZ 			
	d$dededeed  ded deeed f ddfddZ	
d%dededededed deeeef fddZ				d&dededeed  dee deeed f defdd Z	!			
d'dededededeed  ded defd"d#ZdS )(    )OptionalUnionN)Tensor)Literal)_ignore_background)rank_zero_warn)_check_same_shape)_safe_dividemicroone-hot      ?num_classesinclude_backgroundaverager
   macroweightednoneinput_formatr   indexzero_divide)warnnanreturnc                 C   s   t | tr	| dkrtd|  dt |tstd| dg d}|dur5||vr5td| d| d|d	vrAtd
| d|dvrMtd| ddS )z%Validate the arguments of the metric.r   zDExpected argument `num_classes` must be a positive integer, but got .zBExpected argument `include_background` must be a boolean, but got r   Nz)Expected argument `average` to be one of z or None, but got r   zJExpected argument `input_format` to be one of 'one-hot', 'index', but got )r           r   r   zNExpected argument `zero_divide` to be one of 1.0, 0.0, 'warn', 'nan', but got )
isinstanceint
ValueErrorbool)r   r   r   r   r   allowed_average r"   f/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/functional/segmentation/dice.py_dice_score_validate_args   s   

r$   predstargetc                 C   s   t | | |dkr#tjjj| |ddd} tjjj||ddd}| jdk r1td| j d|s:t| |\} }t	t
d|j}tj| | |d	}tj||d	}tj| |d	}d| }	|| }
|}|	|
|fS )
z8Update the state with the current prediction and target.r   )r         zJExpected both `preds` and `target` to have at least 3 dimensions, but got r      dim)r   torchnn
functionalone_hotmovedimndimr   r   listrangesum)r%   r&   r   r   r   reduce_axisintersection
target_sumpred_sum	numeratordenominatorsupportr"   r"   r#   _dice_score_update1   s    


r=   r:   r;   r<   zero_divisionc                 C   s   t | dkrt |dkrt jd| jt jdS |dkr*t j| dd} t j|dd}t| ||d}|dkr>t j|dd}|S |d	kr\|d
ur\t|t j|ddd|d}t j|| dd}|S )z:Compute the Dice score from the numerator and denominator.r   r   )devicedtyper
   r'   r+   )r>   r   r   NT)r,   keepdim)r-   alltensorr?   floatr5   r	   mean)r:   r;   r   r<   r>   diceweightsr"   r"   r#   _dice_score_computeP   s   	rH   Tc           	      C   sF   |dkr	t dt t|||| t| ||||\}}}t||||dS )a	  Compute the Dice score for semantic segmentation.

    Args:
        preds: Predictions from model
        target: Ground truth values
        num_classes: Number of classes
        include_background: Whether to include the background class in the computation
        average: The method to average the dice score. Options are ``"micro"``, ``"macro"``, ``"weighted"``, ``"none"``
          or ``None``. This determines how to average the dice score across different classes.
        input_format: What kind of input the function receives. Choose between ``"one-hot"`` for one-hot encoded tensors
          or ``"index"`` for index tensors

    Returns:
        The Dice score.

    Example (with one-hot encoded tensors):
        >>> from torch import randint
        >>> from torchmetrics.functional.segmentation import dice_score
        >>> preds = randint(0, 2, (4, 5, 16, 16))  # 4 samples, 5 classes, 16x16 prediction
        >>> target = randint(0, 2, (4, 5, 16, 16))  # 4 samples, 5 classes, 16x16 target
        >>> # dice score micro averaged over all classes
        >>> dice_score(preds, target, num_classes=5, average="micro")
        tensor([0.4842, 0.4968, 0.5053, 0.4902])
        >>> # dice score per sample and class
        >>> dice_score(preds, target, num_classes=5, average="none")
        tensor([[0.4724, 0.5185, 0.4710, 0.5062, 0.4500],
                [0.4571, 0.4980, 0.5191, 0.4380, 0.5649],
                [0.5428, 0.4904, 0.5358, 0.4830, 0.4724],
                [0.4715, 0.4925, 0.4797, 0.5267, 0.4788]])

    Example (with index tensors):
        >>> from torch import randint
        >>> from torchmetrics.functional.segmentation import dice_score
        >>> preds = randint(0, 5, (4, 16, 16))  # 4 samples, 5 classes, 16x16 prediction
        >>> target = randint(0, 5, (4, 16, 16))  # 4 samples, 5 classes, 16x16 target
        >>> # dice score micro averaged over all classes
        >>> dice_score(preds, target, num_classes=5, average="micro", input_format="index")
        tensor([0.2031, 0.1914, 0.2500, 0.2266])
        >>> # dice score per sample and class
        >>> dice_score(preds, target, num_classes=5, average="none", input_format="index")
        tensor([[0.1714, 0.2500, 0.1304, 0.2524, 0.2069],
                [0.1837, 0.2162, 0.0962, 0.2692, 0.1895],
                [0.3866, 0.1348, 0.2526, 0.2301, 0.2083],
                [0.1978, 0.2804, 0.1714, 0.1915, 0.2783]])

    r
   zdice_score metric currently defaults to `average=micro`, but will change to`average=macro` in the v1.9 release. If you've explicitly set this parameter, you can ignore this warning.)r<   )r   UserWarningr$   r=   rH   )	r%   r&   r   r   r   r   r:   r;   r<   r"   r"   r#   
dice_scoreh   s   6rJ   )r
   r   r   )r   )r
   Nr   )Tr
   r   )typingr   r   r-   r   typing_extensionsr   *torchmetrics.functional.segmentation.utilsr   torchmetrics.utilitiesr   torchmetrics.utilities.checksr   torchmetrics.utilities.computer	   r   r    rD   r$   tupler=   rH   rJ   r"   r"   r"   r#   <module>   s   


"


