o
    si$Q                     @   s^   d dl Z d dlZd dlmZ d dlZdddZG dd deZG d	d
 d
Z	G dd dZ
dS )    N)	rearrangemetricsOutputMetricsc                 C   sv   |  } | d7 } | d|j j d7 } | d|jj d7 } |jd ur*| d|jj d7 } |jd ur9| d|jj d7 } | S )	Nz$
Shapes: (is shape) (symbolic shape)z
	speech_prediction: z (K_target, N)z
	speech_source: z (K_source, N)z
	speech_contribution: z (K_source, K_target, N)z
	noise_contribution: )speech_predictionshapespeech_sourcespeech_contributionnoise_contribution)msgr    r   R/home/ubuntu/.local/lib/python3.10/site-packages/pb_bss_eval/evaluation/wrapper.py_get_err_msg   s   



r   c                       s   e Zd Z fddZ  ZS )VerboseKeyErrorc                    s   t | jdkr | j\}}dd l}|j||ddd}|d|S t | jdkrD| j\}}}dd l}|j||ddd}|d|d| S t  S )N   r   d   )cutoffnz.
Close matches:    
)lenargsdifflibget_close_matchessuper__str__)selfitemkeysr   suggestionsr
   	__class__r   r   r      s*   

zVerboseKeyError.__str__)__name__
__module____qualname__r   __classcell__r   r   r   r   r      s    r   c                   @   s&  e Zd Z				d6ddddddd	dd
edefddZdd Zdd Zejdd Z	ejdd Z
ejdd Zejdd Zejdd Zejdd Zejdd Zejd d! Zejd"d# Zejd$d% Zejd&d' Zd(d) Zd*d+ Zd,d- Zed.d/ Zed0d1 Zed2d3 Zd4d5 ZdS )7InputMetricsNFobservationzShape(D, N)r   Shape(K_source, N)speech_imagezShape(K_source, D, N)noise_imagesample_rateenable_si_sdrc                 C   st   || _ || _|| _|| _|| _|   |duo|du| _| j jd | _| j jd | _	| jjd | _
|| _|   dS )a  

        Args:
            observation: When you pass D channels, you get D metrics per
                speaker. If you want to select a reference channel, you need
                to slice the input to just have a singleton channel dimension.
            speech_source:
            speech_image:
            noise_image:
            sample_rate:
            enable_si_sdr: Since SI-SDR is only well defined for non-reverb
                single-channel data, it is disabled by default.
        Nr   )r&   r   r(   r)   r*   enable_1d_inputs_has_image_signalsr   sampleschannelsK_sourcer+   check_inputs)r   r&   r   r(   r)   r*   r+   r   r   r   __init__7   s   zInputMetrics.__init__c                 C   8   | j jdkr| j d  | _ | jjdkr| jd  | _d S d S N   )r&   ndimr   r   r   r   r   r.   _   
   zInputMetrics.enable_1d_inputsc                 C   s4   | j jdksJ | j j| jjdksJ | jjd S )Nr   )r&   r8   r   r   r9   r   r   r   r3   e   s   zInputMetrics.check_inputsc                 C   s4   t jjt| jg| j dt| jg| j ddddS )N4channels sources samples -> sources channels samples4sources channels samples -> sources channels samplesTF)	reference
estimationreturn_dictcompute_permutation)pb_bss_eval
evaluationmir_eval_sourcesr   r   r1   r&   r2   r9   r   r   r   mir_evali   s   zInputMetrics.mir_evalc                 C   
   | j d S NsdrrD   r9   r   r   r   mir_eval_sdrx      
zInputMetrics.mir_eval_sdrc                 C   rE   NsirrH   r9   r   r   r   mir_eval_sir|   rJ   zInputMetrics.mir_eval_sirc                 C   rE   NsarrH   r9   r   r   r   mir_eval_sar   rJ   zInputMetrics.mir_eval_sarc                 C   s.   t jjt| jg| j d| jg| j | jdS )Nr;   )r*   )	rA   rB   pesqr   r   r1   r&   r2   r*   r9   r   r   r   rQ      s   zInputMetrics.pesqc                 C   s2   ddl m} |t| jdt| jddddd}|S )Nr   )	input_sxrz2sources sensors samples -> sources sensors samplesz"sensors samples -> sensors samplesFT)average_sourcesaverage_channelsr?   )!pb_bss_eval.evaluation.sxr_modulerR   r   r(   r)   )r   rR   invasive_sxrr   r   r   rV      s   

zInputMetrics.invasive_sxrc                 C   rE   rF   rV   r9   r   r   r   invasive_sdr   rJ   zInputMetrics.invasive_sdrc                 C   rE   rK   rW   r9   r   r   r   invasive_sir   rJ   zInputMetrics.invasive_sirc                 C   rE   NsnrrW   r9   r   r   r   invasive_snr   rJ   zInputMetrics.invasive_snrc                 C   s8   t jjt| jg| j dt| jg| j d| jd}|S )Nr;   r<   r=   r>   r*   )	rA   rB   stoir   r   r1   r&   r2   r*   )r   scoresr   r   r   r^      s   zInputMetrics.stoic                 C   sF   | j rtjj| jd d d d d f | jd d d d d f dS tdN)r=   r>   zSI-SDR is disabled by default since it is only well-defined for non-reverberant single-channel data. Enable it with `enable_si_sdr=True`.)r+   rA   rB   si_sdrr   r&   
ValueErrorr9   r   r   r   ra      s   zInputMetrics.si_sdrc                 C   sD   g d}| j r|d | jr|d |d |d t|S )NrQ   r^   rI   rM   rP   ra   rX   r\   rY   )r+   appendr/   tupler   metric_namesr   r   r   _available_metric_names   s   



z$InputMetrics._available_metric_namesc                 C   s<   g }| j s
|d | js|d |d |d |S )Nra   rX   r\   rY   )r+   rd   r/   r   disabledr   r   r   _disabled_metric_names   s   



z#InputMetrics._disabled_metric_namesc                        fdd   D S )Nc                       i | ]}| | qS r   r   .0namer9   r   r   
<dictcomp>       z(InputMetrics.as_dict.<locals>.<dictcomp>rh   r9   r   r9   r   as_dict      zInputMetrics.as_dictc                 C      | j S NrI   r9   r   r   r   rG         zInputMetrics.sdrc                 C   rv   rw   rM   r9   r   r   r   rL      ry   zInputMetrics.sirc                 C   rv   rw   rP   r9   r   r   r   rO      ry   zInputMetrics.sarc                    p   t |tr fdd|D S t |tsJ t||fzt |W S  ty*   Y nw t|  d   )Nc                    rm   r   r   rn   r9   r   r   rq      rr   z,InputMetrics.__getitem__.<locals>.<dictcomp>
Disabled: 	
isinstanceliststrtypegetattrAttributeErrorr   rh   rk   r   r   r   r9   r   __getitem__      
zInputMetrics.__getitem__)NNNF)r!   r"   r#   intboolr4   r.   r3   cached_propertyrD   rI   rM   rP   rQ   rV   rX   rY   r\   r^   ra   rh   rk   rt   propertyrG   rL   rO   r   r   r   r   r   r%   6   sh    
(















r%   c                   @   sH  e Zd Z					d<dddddd	d
ddededefddZdd Zdd Zejdd Z	ejdd Z
ejdd Zejdd Zejdd Zejdd Zejd d! Zejd"d# Zejd$d% Zejd&d' Zejd(d) Zejd*d+ Zejd,d- Zd.d/ Zd0d1 Zd2d3 Zed4d5 Zed6d7 Zed8d9 Zd:d; ZdS )=r   NFTr   zShape(K_target, N)r   r'   r   zShape(K_source, K_target, N)r	   r*   r+   r@   c                 C   sz   || _ || _|| _|| _|| _|| _|   |duo|du| _| j jd | _	| jjd | _
| j jd | _|| _|   dS )a
  

        Args:
            speech_prediction: Shape(K_target, N)
                The prediction of the source signal.
            speech_source: Shape(K_source, N)
                The true source signal, before the reverberation.
            speech_contribution: Shape(K_source, K_target, N)
                Optional for linear enhancements. See below.
            noise_contribution: Shape(K_target, N)
                Optional for linear enhancements. See below.
            sample_rate: int
                pesq and stoi need the sample rate.
                In pesq the sample rate defines the mode:
                    8000: narrow band (nb)
                    8000: wide band (wb)
            enable_si_sdr: Since SI-SDR is only well defined for non-reverb
                single-channel data, it is disabled by default.
            compute_permutation: whether to realign sources and estimates
                according to SDR values.

        speech_contribution and noise_contribution can only be calculated for
        linear system and are used for the calculation of invasive_sxr.
        Use speech image (reverberated speech source) and apply for each source
        the enhancement for each target speaker enhancement. The same for the
        noise and each target speaker.

        Example:

            >>> from IPython.lib.pretty import pprint
            >>> metrics = OutputMetrics(
            ...     speech_prediction=np.array([[1., 2., 3., 4.] * 1000,
            ...                                 [4., 3., 2., 1.] * 1000]),
            ...     speech_source=np.array([[1., 2., 2., 3., 2.] * 800,
            ...                             [4., 3., 3., 2., 3.] * 800]),
            ...     sample_rate=8000,
            ... )

            # Obtain all metrics (recommended)
            >>> with np.printoptions(precision=4):
            ...     pprint(metrics.as_dict())
            {'pesq': array([1.2235, 1.225 ]),
             'stoi': array([0.0503, 0.0638]),
             'mir_eval_sdr': array([7.2565, 7.3303]),
             'mir_eval_sir': array([25.6896, 46.638 ]),
             'mir_eval_sar': array([7.3309, 7.3309]),
             'mir_eval_selection': array([0, 1])}

            # Obtain particular metric (e.g. pesq)
            >>> metrics.pesq
            array([1.22345543, 1.2250005 ])

            # Obtain multiple metrics (e.g. pesq and stoi)
            >>> pprint({m: metrics[m] for m in ['pesq', 'stoi']})
            {'pesq': array([1.22345543, 1.2250005 ]),
             'stoi': array([0.05026565, 0.06377457])}
        Nr,   r   )r   r   r   r	   r*   r@   r.   _has_contribution_signalsr   r0   r2   K_targetr+   r3   )r   r   r   r   r	   r*   r+   r@   r   r   r   r4     s   CzOutputMetrics.__init__c                 C   r5   r6   )r   r8   r   r9   r   r   r   r.   ]  r:   zOutputMetrics.enable_1d_inputsc              	   C   s  | j jdksJ | j j| jjdksJ | jj| jdks)J td| j d| | jdks:J td| j d| | j| j| jd fv sLJ td| | jjd | jks\J td| | jd ur| j	d ur| j	d uspJ | j	| jj\}}}| j|ksJ td	| | j|ksJ td
| | jdk sJ td| | j	j\}}| j|ksJ td| | j|ksJ td| t
t
| j t
j| jdd | j	 }|dk sJ d| d S | jd u r| j	d u sJ d| j d| j	 d S )Nr      z9Number of source speakers (K_source) of speech_source is z). Expect a reasonable value of 5 or less.z=Number of target speakers (K_target) of speech_prediction is r7   zlNumber of target speakers (K_target) should be equal to number of source speakers (K_source) or K_target + 1zPNum samples (N) of speech_source does not fit to theshape from speech_predictionzVNum samples (N) of speech_contribution does not fit to theshape from speech_predictionzfNum target speakers (K_target) of speech_contribution does not fit to the shape from speech_predictionzbNum source speakers (K_source) of speech_contribution does not fit to the shape from speech_sourcezVNum samples (N) of noise_contribution does not fit to the shape from speech_predictionzeNum target speakers (K_target) of noise_contribution does not fit to the shape from speech_predictionr   )axisgMbP?zbThe deviation of speech prediction and the sum of individual contributions is expected to be low: ziExpect that speech_contribution and noise_contribution are both None or given.
Got:
speech_contribution: z
noise_contribution: )r   r8   r   r   r2   r   r   r0   r   r	   npstdabssum)r   	K_source_	K_target_samples_	deviationr   r   r   r3   c  s   



zOutputMetrics.check_inputsc                 C   rE   )N	selectionrH   r9   r   r   r   mir_eval_selection  rJ   z OutputMetrics.mir_eval_selectionc                 C   s|   | j jdksJ | j j| j jd dk sJ | j j| js | j S | j jd t| jt| jd fv s8J | j j| j | j S )Nr   r   
   r7   )r   r8   r   r@   r   r   r9   r   r   r   speech_prediction_selection  s   
z)OutputMetrics.speech_prediction_selectionc                 C   s   t jj| j| jddS )NT)r=   r>   r?   )rA   rB   rC   r   r   r9   r   r   r   rD     s
   zOutputMetrics.mir_evalc                 C   rE   rF   rH   r9   r   r   r   rI     rJ   zOutputMetrics.mir_eval_sdrc                 C   rE   rK   rH   r9   r   r   r   rM     rJ   zOutputMetrics.mir_eval_sirc                 C   rE   rN   rH   r9   r   r   r   rP     rJ   zOutputMetrics.mir_eval_sarc                 C      t jj| j| j| jdS Nr]   )rA   rB   rQ   r   r   r*   r9   r   r   r   rQ     
   zOutputMetrics.pesqc                 C   sR   ddl m} |t| jdd d | jd d f t| jd| jd d f ddd}|S )Nr   )
output_sxrz2sources targets samples -> sources targets samplesz"targets samples -> targets samplesFT)rS   r?   )rU   r   r   r   r   r	   )r   r   rV   r   r   r   rV     s"   zOutputMetrics.invasive_sxrc                 C   rE   rF   rW   r9   r   r   r   rX     rJ   zOutputMetrics.invasive_sdrc                 C   rE   rK   rW   r9   r   r   r   rY     rJ   zOutputMetrics.invasive_sirc                 C   rE   rZ   rW   r9   r   r   r   r\     rJ   zOutputMetrics.invasive_snrc                 C   r   r   )rA   rB   r^   r   r   r*   r9   r   r   r   r^     r   zOutputMetrics.stoic                 C   s"   | j rtjj| j| jdS tdr`   )r+   rA   rB   ra   r   r   rb   r9   r   r   r   ra     s   zOutputMetrics.si_sdrc                 C   sT   g d}| j r|d | jr|d | jr&|d |d |d t|S )Nrc   r   ra   rX   r\   rY   )r@   rd   r+   r   re   rf   r   r   r   rh     s   




z%OutputMetrics._available_metric_namesc                 C   sL   g }| j s
|d | js|d | js$|d |d |d |S )Nr   ra   rX   r\   rY   )r@   rd   r+   r   ri   r   r   r   rk   #  s   




z$OutputMetrics._disabled_metric_namesc                    rl   )Nc                    rm   r   r   rn   r9   r   r   rq   0  rr   z)OutputMetrics.as_dict.<locals>.<dictcomp>rs   r9   r   r9   r   rt   /  ru   zOutputMetrics.as_dictc                 C   rv   rw   rx   r9   r   r   r   rG   3  ry   zOutputMetrics.sdrc                 C   rv   rw   rz   r9   r   r   r   rL   7  ry   zOutputMetrics.sirc                 C   rv   rw   r{   r9   r   r   r   rO   ;  ry   zOutputMetrics.sarc                    r|   )Nc                    rm   r   r   rn   r9   r   r   rq   A  rr   z-OutputMetrics.__getitem__.<locals>.<dictcomp>r}   r~   r   r   r9   r   r   ?  r   zOutputMetrics.__getitem__)NNNFT)r!   r"   r#   r   r   r4   r.   r3   r   r   r   rD   rI   rM   rP   rQ   rV   rX   rY   r\   r^   ra   rh   rk   rt   r   rG   rL   rO   r   r   r   r   r   r     sv    
YN















)r   r   )r   numpyr   einopsr   rA   r   KeyErrorr   r%   r   r   r   r   r   <module>   s    
	 N