o
    9wi'C                     @   s   d dl Z d dlZd dlZd dlmZmZmZ d dlmZ	 d dl
Zd dlZd dlmZmZ d dlmZmZ d dlmZ d dlmZ d dlmZ d dlmZmZmZ d d	lmZmZm Z  d d
l!m"Z" e#ej$Z%e#ej$Z&G dd deZ'dS )    N)DictSequenceUnion)ScopeSubset)MLFlowLoggerTensorBoardLoggerdefault_collate)AudioMetaData)Metric)BinaryAUROCMulticlassAUROCMultilabelAUROC)ProblemTask	get_dtype)create_rng_for_workerc                   @   s   e Zd ZdZdd Zdeeee ee	ef f fddZ
dejfdd	Zd
d ZdejfddZdejfddZdejfddZd"ddZdd ZdefddZdd Zdd Zdefdd Zd!S )#SegmentationTaskz)Methods common to most segmentation tasksc           	      C   sn   t  }| jd | |d< | jd | }| jd | }|d }|d }|d }|d }t|||||d	|d
< |S )Nz
audio-pathaudioz
audio-infozaudio-encodingsample_rate
num_framesnum_channelsbits_per_sample)r   r   r   r   encodingztorchaudio.info)dictprepared_datar   )	selffile_idfile_audio_infor   r   r   r   r    r!   e/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/pyannote/audio/tasks/segmentation/mixins.pyget_file0   s    
zSegmentationTask.get_filereturnc                 C   sp   t | jj}| jjtjkrtddS | jjtjkr t|dddS | jjtj	kr.t
|dddS td| jj d)z5Returns macro-average of the area under the ROC curveT)compute_on_cpumacro)averager%   zThe zB problem type hasn't been given a default segmentation metric yet.)lenspecificationsclassesproblemr   BINARY_CLASSIFICATIONr   MULTI_LABEL_CLASSIFICATIONr   MONO_LABEL_CLASSIFICATIONr   RuntimeError)r   num_classesr!   r!   r"   default_metricF   s   
zSegmentationTask.default_metricrngc                 k   sN   | j d d tdk}| D ]\}}|| j d | | j d | |kM }qt|d }| j d | }t|t| }| j}	t	| dd}
	 ||
|  }t|
D ]M}t| j d
 d |kd }t| j d
 d | t| j d
 d |  }||
|  }| j d
 | \}}}|||| |	 }| |||	V  qXqK)a  Iterate over training samples with optional domain filtering

        Parameters
        ----------
        rng : random.Random
            Random number generator
        filters : dict, optional
            When provided (as {key: value} dict), filter training files so that
            only files such as file[key] == value are used for generating chunks.

        Yields
        ------
        chunk : dict
            Training chunks.
        audio-metadatasubsettrainmetadatar   audio-annotatednum_chunks_per_file   Tannotations-regionsr   duration)r   Subsetsindexitemsnpwherecumsumsumr;   getattrsearchsortedrandomrangeuniformprepare_chunk)r   r2   filterstrainingkeyvaluefile_idsannotated_durationcum_prob_annotated_durationr;   r8   r   _annotated_region_indices#cum_prob_annotated_regions_durationannotated_region_indexregion_durationstart
start_timer!   r!   r"   train__iter__helperW   s^   
z$SegmentationTask.train__iter__helperc                 #   s    t  j}t dd}|du r |}n't }tj fdd|D  D ]}dd t||D } j|fi |||< q%	 |durK||t	| }t
|V  q>)aV  Iterate over training samples

        Yields
        ------
        dict:
            X: (time, channel)
                Audio chunks.
            y: (frame, )
                Frame-level targets. Note that frame < time.
                `frame` is infered automagically from the
                example model output.
            ...
        balanceNc                    s   g | ]	} j d  | qS )r6   )r   ).0rK   r   r!   r"   
<listcomp>   s    z2SegmentationTask.train__iter__.<locals>.<listcomp>c                 S   s   i | ]\}}||qS r!   r!   )rY   rK   rL   r!   r!   r"   
<dictcomp>       z2SegmentationTask.train__iter__.<locals>.<dictcomp>)r   modelrC   rW   r   	itertoolsproductzipchoicelistnext)r   r2   rX   chunks	subchunksr`   rI   r!   rZ   r"   train__iter__   s    

zSegmentationTask.train__iter__c                 C      t dd |D S )Nc                 S      g | ]}|d  qS )Xr!   rY   br!   r!   r"   r[          z.SegmentationTask.collate_X.<locals>.<listcomp>r	   r   batchr!   r!   r"   	collate_X      zSegmentationTask.collate_Xc                 C   rh   )Nc                 S   s   g | ]}|d  j qS )y)datark   r!   r!   r"   r[      r]   z.SegmentationTask.collate_y.<locals>.<listcomp>r	   rn   r!   r!   r"   	collate_y   rq   zSegmentationTask.collate_yc                 C   rh   )Nc                 S   ri   )metar!   rk   r!   r!   r"   r[      rm   z1SegmentationTask.collate_meta.<locals>.<listcomp>r	   rn   r!   r!   r"   collate_meta   rq   zSegmentationTask.collate_metar5   c                 C   sb   |  |}| |}| |}| jj|dkd | j|| jjj|dd}|j	|j
d|dS )a  Collate function used for most segmentation tasks

        This function does the following:
        * stack waveforms into a (batch_size, num_channels, num_samples) tensor batch["X"])
        * apply augmentation when in "train" stage
        * convert targets into a (batch_size, num_frames, num_classes) tensor batch["y"]
        * collate any other keys that might be present in the batch using pytorch default_collate function

        Parameters
        ----------
        batch : list of dict
            List of training samples.

        Returns
        -------
        batch : dict
            Collated batch as {"X": torch.Tensor, "y": torch.Tensor} dict.
        r5   )moder9   )samplesr   targets)rj   rr   ru   )rp   rt   rv   augmentationr5   r^   hparamsr   	unsqueezerx   ry   squeeze)r   ro   stage
collated_X
collated_ycollated_meta	augmentedr!   r!   r"   
collate_fn   s   



zSegmentationTask.collate_fnc                 C   sN   t | jd d tdkd }t | jd | }t| jt	|| j
 S )Nr3   r4   r5   r   r7   )r?   r@   r   r<   r=   rB   max
batch_sizemathceilr;   )r   train_file_idsr;   r!   r!   r"   train__len__   s   zSegmentationTask.train__len__r   c                 C   s   t  }t|d d tdkd }|D ]5}|d |d d |k }|D ]$}t|d | j }t|D ]}|d || j  }	|||	| jf q4q%qdt	t
d	d
 |D fddg}
tj||
d|d< |  d S )Nr3   r4   developmentr   r:   r   r;   rU   c                 s   s    | ]}|d  V  qdS )r   Nr!   )rY   vr!   r!   r"   	<genexpr>%  s    z6SegmentationTask.prepare_validation.<locals>.<genexpr>)rU   f)r;   r   )dtype
validation)rc   r?   r@   r<   r=   roundr;   rF   appendr   r   arrayclear)r   r   validation_chunksvalidation_file_idsr   annotated_regionsannotated_region
num_chunkscrV   r   r!   r!   r"   prepare_validation	  s2   	z#SegmentationTask.prepare_validationc                 C   s*   | j d | }| j|d |d |d dS )Nr   r   rU   r;   )r;   )r   rH   )r   idxvalidation_chunkr!   r!   r"   val__getitem__.  s   zSegmentationTask.val__getitem__c                 C   s   t | jd S )Nr   )r(   r   rZ   r!   r!   r"   
val__len__6  s   zSegmentationTask.val__len__	batch_idxc                 C   sn  |d |d }}|  |}|j\}}}t| jd | j | }t| jd | j | }	|dd|||	 df }
|dd|||	 df }| jjtjkr[| j 	|

d|
d n#| jjtjkrt| j 	t|
ddt|dd n
| jjtjkr~t | j j| j j	d	d
d
d
d | j jdkst| j jd dks|dkrdS |  }|   }|  }t| jd}tt|}t|| }tjd| |dd	d\}}tj||dk< t|jdkr|ddddtj f }|t!|jd 9 }t"|D ]{}|| }|| }||d d |f }|| }|#| |$dt| |%d|jd  |& 'd	 |( 'd	 ||d d |f }|| }|j)d|dddd |j)||	 |dddd |#| |%dd |$dt| |& 'd	 q t*  | j j+D ]+}t,|t-r|j./d|| j j qt,|t0r|j.j1|j2|d| j j dd qt3| dS )zCompute validation area under the ROC curve

        Parameters
        ----------
        batch : dict of torch.Tensor
            Current batch.
        batch_idx: int
            Batch index.
        rj   rr   r   r9   N
      FT)on_stepon_epochprog_barlogger	   )      )nrowsncolsfigsizer}   kg      ?)coloralphalwgg?rx   samples_epochz.png)run_idfigureartifact_file)4r^   shaper   warm_upr;   r)   r+   r   r,   validation_metricreshaper-   torch	transposer.   NotImplementedErrorlog_dictcurrent_epochr   log2cpunumpyfloatminr   r   sqrtpltsubplotsr?   nanr(   newaxisarangerF   plotset_xlimset_ylim	get_xaxisset_visible	get_yaxisaxvspantight_layoutloggers
isinstancer   
experiment
add_figurer   
log_figurer   close)r   ro   r   rj   rr   y_predrP   r   warm_up_leftwarm_up_rightpredstargetnum_samplesr   r   figaxes
sample_idxrow_idxcol_idxax_refsample_yax_hypsample_y_predr   r!   r!   r"   validation_step9  s   




z SegmentationTask.validation_stepN)r5   )__name__
__module____qualname____doc__r#   r   r   r   r   strr1   rE   RandomrW   rg   r   Tensorrp   rt   rv   r   r   r   r   r   intr   r!   r!   r!   r"   r   -   s"    
J+
+	%r   )(r_   r   rE   typingr   r   r   matplotlib.pyplotpyplotr   r   r?   r   #pyannote.database.protocol.protocolr   r   pytorch_lightning.loggersr   r   torch.utils.data._utils.collater
   
torchaudior   torchmetricsr   torchmetrics.classificationr   r   r   pyannote.audio.core.taskr   r   r   pyannote.audio.utils.randomr   rc   __args__r<   Scopesr   r!   r!   r!   r"   <module>   s$   

