o
    F,h&                     @   sl   d dl Zd dlZd dlmZ d dlmZ d dlmZ d dl	m  m
Z G dd deZG dd dejZdS )    N)Metric)cKDTreec                       sF   e Zd ZdZddef fddZdejdejfd	d
Zdd Z	  Z
S )Sensitivityz
    Computes Sensitivity (Recall) = TP / (TP + FN)

    Args:
        threshold (float, optional): Threshold for binarizing predictions. Default is 0.5.
          ?F	thresholdc                    sP   t  j|d || _| jdtjdtjddd | jdtjdtjddd d S )N)dist_sync_on_steptrue_positivesr   )dtypesum)defaultdist_reduce_fxfalse_negatives)super__init__r   	add_statetorchtensorfloat32)selfr   r   	__class__ ,/home/xmoravc/AI_project/utils/my_metrics.pyr      s    zSensitivity.__init__predstargetc                 C   sb   || j k }| }t|dk|dk@ }t|dk|dk@ }|  j|7  _|  j|7  _dS )z
        Update metric states with new batch of predictions and targets.

        Args:
            preds (torch.Tensor): Model predictions (logits or probabilities).
            target (torch.Tensor): Ground truth labels (binary).
           r   N)r   floatr   r
   r   r   )r   r   r   tpfnr   r   r   update   s   	zSensitivity.updatec                 C   s   | j | j | j d  S )zN
        Computes final sensitivity score across accumulated batches.
        g|=)r   r   )r   r   r   r   compute.   s   zSensitivity.compute)r   F)__name__
__module____qualname____doc__r   r   r   Tensorr   r    __classcell__r   r   r   r   r   	   s
    	r   c                       s:   e Zd ZdZd fdd	Zdd Zdd	 Zd
d Z  ZS )HausdorffDistancez
    Computes the Hausdorff Distance (HD) and the 95th percentile Hausdorff Distance (HD95)
    for 3D binary segmentation masks in PyTorch.
    _   r   c                    s&   t    || _|| _td| _dS )z
        Initializes the HausdorffDistance class.

        :param percentile: Percentile for the HD computation (default is 95).
        :param threshold: Binarization threshold for segmentation masks.
        cpuN)r   r   
percentiler   r   device)r   r*   r   r   r   r   r   ;   s   
zHausdorffDistance.__init__c                 C   s
   || _ | S )zD
        Ensures the metric is moved to the correct device.
        r+   )r   r+   r   r   r   toG   s   zHausdorffDistance.toc           
      C   s   | | j}| | j}|| jk }|| jk }tj|dd}tj|dd}| dks4| dkrHtjtd| jdtjtd| jdfS | ||}| ||}t	||g}t
|}t|| jd }	||	fS )aE  
        Computes the Hausdorff Distance (HD) and the 95th percentile Hausdorff Distance (HD95).

        :param seg1: Binary 3D PyTorch tensor (segmentation mask 1)
        :param seg2: Binary 3D PyTorch tensor (segmentation mask 2)
        :return: (HD, HD95) as a tuple of torch.Tensors (floats or NaN if invalid)
        F)as_tupler   nanr,   g      Y@)r-   r+   r   r   r   nonzeronumelr   _min_distancecatmaxquantiler*   )
r   seg1seg2Zseg1_pointsZseg2_pointsZdists_1_to_2Zdists_2_to_1Z	all_distshdhd95r   r   r   forwardp   s   (
zHausdorffDistance.forwardc                 C   s`   |j d dks|j d dkrtjtdg| jdS tj| | dd}tj|dd\}}|S )a!  
        Computes the minimum distance from each point in points1 to the closest point in points2.

        :param points1: Tensor of shape (N, 3) - voxel positions
        :param points2: Tensor of shape (M, 3) - voxel positions
        :return: Tensor of distances of shape (N,)
        r   infr,      )pr   )dim)shaper   r   r   r+   cdistmin)r   Zpoints1Zpoints2distsZ	min_dists_r   r   r   r2      s
   zHausdorffDistance._min_distance)r(   r   )	r!   r"   r#   r$   r   r-   r:   r2   r&   r   r   r   r   r'   5   s    )&r'   )numpynpr   torchmetricsr   scipy.spatialr   torch.nnnnZtorch.nn.functional
functionalFr   Moduler'   r   r   r   r   <module>   s    ,