o
    piB                     @   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mZ d dl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# e$ej%Z&e$ej%Z'G dd deZ(dS )    N)DictSequenceUnion)MLFlowLoggerTensorBoardLogger)ProblemTask	get_dtype)create_rng_for_worker)ScopeSubset)
functionaldefault_collate)Metric)BinaryAUROCMulticlassAUROCMultilabelAUROCc                   @   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   s   d| j d | iS )Naudioz
audio-pathprepared_data)selffile_id r   \/home/ubuntu/.local/lib/python3.10/site-packages/pyannote/audio/tasks/segmentation/mixins.pyget_file0      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_metric3   s   
zSegmentationTask.default_metricrngc              	   k   sL   | 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 ]L}| j 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   Tzaudio-regions-idsannotations-regionsduration)r   Subsetsindexitemsnpwherecumsumsumr5   getattrsearchsortedrandomrangeuniformprepare_chunk)r   r,   filterstrainingkeyvaluefile_idsannotated_durationcum_prob_annotated_durationr5   r2   r   _start_idend_id#cum_prob_annotated_regions_durationannotated_region_indexregion_durationstart
start_timer   r   r   train__iter__helperD   sX   
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 )r0   r   ).0rE   r   r   r   
<listcomp>   s    z2SegmentationTask.train__iter__.<locals>.<listcomp>c                 S   s   i | ]\}}||qS r   r   )rT   rE   rF   r   r   r   
<dictcomp>       z2SegmentationTask.train__iter__.<locals>.<dictcomp>)r
   modelr=   rR   dict	itertoolsproductzipchoicelistnext)r   r,   rS   chunks	subchunksr\   rC   r   rU   r   train__iter__   s    

zSegmentationTask.train__iter__c                    sN   t dd |D }t|dkrtdd |D S t| t fdd|D S )Nc                 s   s    | ]
}|d  j d V  qdS )XN)shaperT   br   r   r   	<genexpr>   s    z-SegmentationTask.collate_X.<locals>.<genexpr>r3   c                 S      g | ]}|d  qS )rd   r   rg   r   r   r   rV          z.SegmentationTask.collate_X.<locals>.<listcomp>c              	      s.   g | ]}t |d  d |d  jd  fqS )rd   r   re   )Fpadrf   rg   max_lenr   r   rV      s   . )setr"   r   max)r   batchlengthsr   rn   r   	collate_X   s   zSegmentationTask.collate_Xc                 C      t dd |D S )Nc                 S   s   g | ]}|d  j qS )y)datarg   r   r   r   rV      rX   z.SegmentationTask.collate_y.<locals>.<listcomp>r   r   rr   r   r   r   	collate_y   r   zSegmentationTask.collate_yc                 C   ru   )Nc                 S   rj   )metar   rg   r   r   r   rV      rk   z1SegmentationTask.collate_meta.<locals>.<listcomp>r   rx   r   r   r   collate_meta   r   zSegmentationTask.collate_metar/   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.
        r/   )moder3   )samplessample_ratetargets)rd   rv   rz   )rt   ry   r{   augmentationr/   rY   hparamsr~   	unsqueezer}   r   squeeze)r   rr   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 )Nr-   r.   r/   r   r1   )r9   r:   r   r6   r7   r<   rq   
batch_sizemathceilr5   )r   train_file_idsr5   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 )Nr-   r.   developmentr   r4   r   r5   rP   c                 s   s    | ]}|d  V  qdS )r   Nr   )rT   vr   r   r   ri     s    z6SegmentationTask.prepare_validation.<locals>.<genexpr>)rP   f)r5   r   )dtype
validation)r_   r9   r:   r6   r7   roundr5   r@   appendr	   rq   arrayclear)r   r   validation_chunksvalidation_file_idsr   annotated_regionsannotated_region
num_chunkscrQ   r   r   r   r   prepare_validation   s2   	z#SegmentationTask.prepare_validationc                 C   s*   | j d | }| j|d |d |d dS )Nr   r   rP   r5   )r5   )r   rB   )r   idxvalidation_chunkr   r   r   val__getitem__#  s   zSegmentationTask.val__getitem__c                 C   s   t | jd S )Nr   )r"   r   rU   r   r   r   
val__len__+  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.
        rd   rv   r   r3   N
   re      FT)on_stepon_epochprog_barlogger	   )      )nrowsncolsfigsizer   kg      ?)coloralphalwgg?r}   samples_epochz.png)run_idfigureartifact_file)4rY   rf   r   warm_upr5   r#   r%   r   r&   validation_metricreshaper'   torch	transposer(   NotImplementedErrorlog_dictcurrent_epochr   log2cpunumpyfloatminr   r   sqrtpltsubplotsr9   nanr"   newaxisaranger@   plotset_xlimset_ylim	get_xaxisset_visible	get_yaxisaxvspantight_layoutloggers
isinstancer   
experiment
add_figurer   
log_figurer   close)r   rr   r   rd   rv   y_predrJ   
num_frames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_step.  s   




z SegmentationTask.validation_stepN)r/   )__name__
__module____qualname____doc__r   r   r   r   r   strr+   r?   RandomrR   rc   r   Tensorrt   ry   r{   r   r   r   r   r   intr   r   r   r   r   r   -   s"    
H+
+	%r   ))r[   r   r?   typingr   r   r   matplotlib.pyplotpyplotr   r   r9   r   lightning.pytorch.loggersr   r   pyannote.audio.core.taskr   r   r	   pyannote.audio.utils.randomr
   #pyannote.database.protocol.protocolr   r   torch.nnr   rl   torch.utils.data._utils.collater   torchmetricsr   torchmetrics.classificationr   r   r   r_   __args__r6   Scopesr   r   r   r   r   <module>   s$   

