
      io4                         d dl mZmZmZmZmZ d dlZd dlZd dl	Z
d dlZd dlmZmZ d dlmZmZ  G d d      ZdZdZd	Z G d
 de      ZdZdZd	Z G d de      ZddededefdZy)    )ListUnionOptionalSetTupleN)
AnnotationTimeline)DetailsMetricComponentsc            
       L    e Zd ZdZedefd       Zedefd       Z fdZ	d Z
d Zed        Z	 dd	eeef   d
eeef   dedee   fdZddedej*                  fdZd Zd Zdedeeef   fdZd Zd	eeef   d
eeef   defdZdefdZddedeeeeef   f   fdZ  xZ!S )
BaseMetricz
    :class:`BaseMetric` is the base class for most pyannote evaluation metrics.

    Attributes
    ----------
    name : str
        Human-readable name of the metric (eg. 'diarization error rate')
    returnc                 2    t        | j                  dz         )Nz\ is missing a 'metric_name' class method. It should return the name of the metric as string.NotImplementedError__name__clss    j/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/pyannote/metrics/base.pymetric_namezBaseMetric.metric_name1   s"    !LL P P
 	
    c                 2    t        | j                  dz         )Nzh is missing a 'metric_components' class method. It should return the list of names of metric components.r   r   s    r   metric_componentszBaseMetric.metric_components8   s"    !LL V V
 	
r   c                     t         t        |           | j                  j	                         | _        t        | j                  j                               | _        | j                          y N)
superr   __init__	__class__r   metric_name_setr   components_reset)selfkwargsr   s     r   r   zBaseMetric.__init__?   sH    j$(* NN668%()I)I)K%L

r   c                 B    | j                   D ci c]  }|d c}S c c}w )N        )r!   r#   values     r   init_componentszBaseMetric.init_componentsE   s&    (,(8(89(8us
(8999s   
c                     t               | _        t               | _        | j                  D ]  }d| j                  |<    y)z.Reset accumulated components and metric valuesr&   N)dictaccumulated_listresults_r!   r'   s     r   r"   zBaseMetric.resetH   s5    %)V"f%%E'*De$ &r   c                 "    | j                         S )zMetric name.)r   r#   s    r   namezBaseMetric.nameO   s     !!r   	reference
hypothesisdetaileduric                 >    | j                   ||fi |}| j                  |      || j                  <   |xs t        |dd      }| j                  j                  ||f       | j                  D ]  }| j                  |xx   ||   z  cc<    |r|S || j                     S )a  Compute metric value and accumulate components

        Parameters
        ----------
        reference : type depends on the metric
            Manual `reference`
        hypothesis : type depends on the metric
            Evaluated `hypothesis`
        uri : optional
            Override uri.
        detailed : bool, optional
            By default (False), return metric value only.
            Set `detailed` to True to return dictionary where keys are
            components names and values are component values

        Returns
        -------
        value : float (if `detailed` is False)
            Metric value
        components : dict (if `detailed` is True)
            `components` updated with metric value
        r5   NA)compute_componentscompute_metricr   getattrr.   appendr!   r,   )r#   r2   r3   r4   r5   r$   
componentsr1   s           r   __call__zBaseMetric.__call__W   s    6 -T,,Y
MfM
 )-(;(;J(G
4$$% 4WYt4c:./ $$Dd#z$'77# % $++,,r   displayc                 R   g }g }d| j                         v }| j                  D ]  \  }}i }|r|d   }|j                         D ]^  \  }	}
|	| j                  k(  rd|
z  ||	df<    |	dk(  r|
||	df<   -|
||	df<   |s7dkD  rd|
z  |z  ||	df<   Jt        j
                  ||	df<   ` |j                  |       |j                  |        i }| j                  }|r|d   }|j                         D ]^  \  }	}
|	| j                  k(  rd|
z  ||	df<    |	dk(  r|
||	df<   -|
||	df<   |s7dkD  rd|
z  |z  ||	df<   Jt        j
                  ||	df<   ` dt        |       z  || j                  df<   |j                  |       |j                  d       t        j                  |      }||d<   |j                  d      }t        j                  j                  |j                        |_        || j                  g| j                         z      }|rt        |j!                  dd	d
d              |S )ak  Evaluation report

        Parameters
        ----------
        display : bool, optional
            Set to True to print the report to stdout.

        Returns
        -------
        report : pandas.DataFrame
            Dataframe with one column per metric component, one row per
            evaluated item, and one final row for accumulated results.
        totald   % r   TOTALitemTFrightc                 $    dj                  |       S Nz{0:.2f}formatfs    r   <lambda>z#BaseMetric.report.<locals>.<lambda>   s    9+;+;A+>r   )indexsparsifyjustifyfloat_format)r   r.   itemsr1   npnanr;   r,   abspd	DataFrame	set_index
MultiIndexfrom_tuplescolumnsprint	to_string)r#   r>   reporturispercentr5   r<   rowr@   keyr(   dfs               r   r^   zBaseMetric.report   sJ    T3355#}}OCC"7+(..0
U$))#$'%KCSMG^#(CRL#(CRL 19,/%K%,?CSM,.FFCSM 1 MM#KK%  -( &&
w'E$**,JCdii #eCH$CG$CGqy(+ee(;CH(*CH - "CIoDIIsNcG\\&!6
\\&!]]..rzz:
d44667"#!>	   	r   c                 N    | j                  d      }|j                  dd       S )NF)r>   c                 $    dj                  |       S rH   rI   rK   s    r   rM   z$BaseMetric.__str__.<locals>.<lambda>   s    93C3CA3Fr   )rO   rQ   )r^   r]   )r#   r^   s     r   __str__zBaseMetric.__str__   s0    U+)F   
 	
r   c                 8    | j                  | j                        S )z0Compute metric value from accumulated components)r9   r,   r0   s    r   __abs__zBaseMetric.__abs__   s    ""4#4#455r   	componentc                 j    |t        ddd      k(  rt        | j                        S | j                  |   S )a  Get value of accumulated `component`.

        Parameters
        ----------
        component : str
            Name of `component`

        Returns
        -------
        value : type depends on the metric
            Value of accumulated `component`

        N)slicer+   r,   )r#   ri   s     r   __getitem__zBaseMetric.__getitem__   s7     dD$//))**$$Y//r   c              #   @   K   | j                   D ]  \  }}||f  yw)z*Iterator over the accumulated (uri, value)N)r.   )r#   r5   ri   s      r   __iter__zBaseMetric.__iter__   s"     "mmNCy.  ,s   c                 F    t        | j                  j                  dz         )a  Compute metric components

        Parameters
        ----------
        reference : type depends on the metric
            Manual `reference`
        hypothesis : same as `reference`
            Evaluated `hypothesis`

        Returns
        -------
        components : dict
            Dictionary where keys are component names and values are component
            values

        z is missing a 'compute_components' method.It should return a dictionary where keys are component names and values are component values.r   r   r   )r#   r2   r3   r$   s       r   r8   zBaseMetric.compute_components   s*    ( "NN## 'I I
 	
r   r<   c                 F    t        | j                  j                  dz         )aA  Compute metric value from computed `components`

        Parameters
        ----------
        components : dict
            Dictionary where keys are components names and values are component
            values

        Returns
        -------
        value : type depends on the metric
            Metric value
        z is missing a 'compute_metric' method. It should return the actual value of the metric based on the precomputed component dictionary given as input.rp   )r#   r<   s     r   r9   zBaseMetric.compute_metric  s*     "NN## '` `
 	
r   alphac                 B   | j                   D cg c]  \  }}|| j                      }}}t        |      dk(  rt        d      t        |      dk(  r$t	        j
                  d       |d   x}x}}|||ffS t        j                  j                  ||      d   S c c}}w )aP  Compute confidence interval on accumulated metric values

        Parameters
        ----------
        alpha : float, optional
            Probability that the returned confidence interval contains
            the true metric value.

        Returns
        -------
        (center, (lower, upper))
            with center the mean of the conditional pdf of the metric value
            and (lower, upper) is a confidence interval centered on the median,
            containing the estimate to a probability alpha.

        See Also:
        ---------
        scipy.stats.bayes_mvs

        r   zFPlease evaluate a bunch of files before computing confidence interval.   zCCannot compute a reliable confidence interval out of just one file.)rr   )	r.   r   len
ValueErrorwarningswarnscipystats	bayes_mvs)r#   rr   _rvaluescenterloweruppers           r   confidence_intervalzBaseMetric.confidence_interval(  s    . 48==A=41a!D%%&=Av;!eff[AMM_`%+AY.F.UUE5>)) ;;((u(=a@@ Bs   B)FN)F)g?)"r   
__module____qualname____doc__classmethodstrr   r   r   r   r)   r"   propertyr1   r   r	   r   boolr   r=   rV   rW   r^   rf   rh   floatr
   rl   rn   r8   r9   r   r   __classcell__)r   s   @r   r   r   '   sT    
C 
 
 
"2 
 
:+ " " ?C+-%*(<"= +-"8Z#78+-+-.6sm+-ZRd Rr|| Rh
60S 0U5'>-B 0&!

&+Hj,@&A
',Xz-A'B
 )0
4
 
("A "AUE%,//0"Ar   r   	precisionz# retrievedz# relevant retrievedc                   F    e Zd ZdZed        Zedefd       Zdede	fdZ
y)	PrecisionaU  
    :class:`Precision` is a base class for precision-like evaluation metrics.

    It defines two components '# retrieved' and '# relevant retrieved' and the
    compute_metric() method to compute the actual precision:

        Precision = # retrieved / # relevant retrieved

    Inheriting classes must implement compute_components().
    c                     t         S r   )PRECISION_NAMEr   s    r   r   zPrecision.metric_name^  s    r   r   c                     t         t        gS r   )PRECISION_RETRIEVEDPRECISION_RELEVANT_RETRIEVEDr   s    r   r   zPrecision.metric_componentsb  s    #%ABBr   r<   c                 \    |t            }|t           }|dk(  r|dk(  ryt        d      ||z  S )z#Compute precision from `components`r&   r         ?rC   )r   r   rv   r#   r<   	numeratordenominators       r   r9   zPrecision.compute_metricf  s?    ;<	 !45#A~ n${**r   Nr   r   r   r   r   r   r   r   r
   r   r9    r   r   r   r   R  sM    	   C"2 C C
+ 
+U 
+r   r   recallz
# relevantc                   F    e Zd ZdZed        Zedefd       Zdede	fdZ
y)RecallaG  
    :class:`Recall` is a base class for recall-like evaluation metrics.

    It defines two components '# relevant' and '# relevant retrieved' and the
    compute_metric() method to compute the actual recall:

        Recall = # relevant retrieved / # relevant

    Inheriting classes must implement compute_components().
    c                     t         S r   )RECALL_NAMEr   s    r   r   zRecall.metric_name  s    r   r   c                     t         t        gS r   )RECALL_RELEVANTRECALL_RELEVANT_RETRIEVEDr   s    r   r   zRecall.metric_components  s    !:;;r   r<   c                 \    |t            }|t           }|dk(  r|dk(  ryt        d      ||z  S )z Compute recall from `components`r&   r   r   rC   )r   r   rv   r   s       r   r9   zRecall.compute_metric  s>    89	 1#A~ n${**r   Nr   r   r   r   r   r   x  sJ    	   <"2 < <
+ 
+U 
+r   r   r   c                 H    | |z   dk(  ryd||z  z   | z  |z  ||z  | z  |z   z  S )u   Compute f-measure

    f-measure is defined as follows:
        F(P, R, b) = (1+b²).P.R / (b².P + R)

    where P is `precision`, R is `recall` and b is `beta`
    r&   r   rt   r   )r   r   betas      r   	f_measurer     s?     6S tOy(61TD[95Lv5UVVr   )r   )typingr   r   r   r   r   rw   numpyrS   pandasrV   scipy.statsry   pyannote.corer   r	   pyannote.metrics.typesr
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>r      s   8 5 4     . <cA cAL	 # 5 +
 +B 2 +Z +B
W 
W 
WE 
Wr   