o
    ei                  
   @   s   d Z ddlZddlmZ ddlmZmZ ddlZddlm	Z	 ddl
mZ e	eZ	dd	ejd
edeeee  ejf fddZd	ejdee fddZddeeef dedejfddZdejdejfddZdS )zUtilities for k2 integration with SpeechBrain.

This code was adjusted from icefall (https://github.com/k2-fsa/icefall).


Authors:
  * Pierre Champion 2023
  * Zeyu Zhao 2023
  * Georgios Karakasidis 2023
    N)Path)ListUnion)
get_logger   )k2F
best_pathsreturn_raggedreturnc                 C   s   t | jtjr(| jd}| j |j}|d}|d}t||j	}n| j d}t|| j}|d}|j
dksCJ |rG|S | S )aJ  
    Extract the texts (as word IDs) from the best-path FSAs.

    Arguments
    ---------
    best_paths: k2.Fsa
        A k2.Fsa with best_paths.arcs.num_axes() == 3, i.e.
        containing multiple FSAs, which is expected to be the result
        of k2.shortest_path (otherwise the returned values won't
        be meaningful).
    return_ragged: bool
        True to return a ragged tensor with two axes [utt][word_id].
        False to return a list-of-list word IDs.

    Returns
    -------
    Returns a list of lists of int, containing the label sequences we
    decoded.
    r   r      )
isinstance
aux_labelsr   RaggedTensorremove_values_leqarcsshapecomposeremove_axisvaluesnum_axestolist)r   r	   r   	aux_shape r   ^/home/ubuntu/transcripts/venv/lib/python3.10/site-packages/speechbrain/k2_integration/utils.pylattice_path_to_textid   s   


r   c                    s<   t | dd}g }|D ]}|d fdd|D  q
|S )a  
    Convert the best path to a list of strings.

    Arguments
    ---------
    best_paths: k2.Fsa
        It is the path in the lattice with the highest score for a
        given utterance.
    word_table: List[str] or Dict[int,str]
        It is a list or dict that maps word IDs to words.

    Returns
    -------
    texts: List[str]
        A list of strings, each of which is the decoding result of the
        corresponding utterance.
    F)r	    c                    s   g | ]} | qS r   r   ).0wid
word_tabler   r   
<listcomp>^   s    z)lattice_paths_to_text.<locals>.<listcomp>)r   appendjoin)r   r   hypstextswidsr   r   r   lattice_paths_to_textG   s    r&   Tpathcachec                 C   s   t | } tj| ddr*|r*td|  d tj	t
j| dddd}|S td|   tj| s@td|  d	t| d
d!}tjj| dd}t
| | dd d  W d   |S 1 sjw   Y  |S )a  
    load a lm to be used in the decoding graph creation (or lm rescoring).

    Arguments
    ---------
    path: str
        The path to an FST LM (ending with .fst.txt) or a k2-converted
        LM (in pytorch .pt format).
    cache: bool
        Whether or not to load/cache the LM from/to the .pt format (in the same dir).

    Returns
    -------
    G: k2.Fsa
        An FSA representing the LM.
    z.fst.txtz.ptz	Loading 'z\' from its cached .pt format. Set 'caching: False' in the yaml if this is not what you want.cpu)map_locationzLoading G LM: zFile z2 not found. You need to run arpa_to_fst to get it.zutf-8)encodingF)acceptorNi)strosr'   existsreplaceloggerwarningr   Fsa	from_dicttorchloadinfoisfileFileNotFoundErroropenfrom_openfstreadsaveas_dict)r'   r(   Gfr   r   r   load_Gb   s*   


rA   r?   c                 C   sd   d| j v r
d| j d< | `tj| gd} t| } t| } t| } t| ds0| j	
 | _| S )a  
    Prepare a LM with the purpose of using it for LM rescoring.
    For instance, in the librispeech recipe this is a 4-gram LM (while a
    3gram LM is used for HLG construction).

    Arguments
    ---------
    G: k2.Fsa
        An FSA representing the LM.

    Returns
    -------
    G: k2.Fsa
        An FSA representing the LM, with the following modifications:
        - G.aux_labels is removed
        - G.lm_scores is set to G.scores
        - G is arc-sorted
    _propertiesNr)   	lm_scores)__dict__r   r   r3   	from_fsastoarc_sortadd_epsilon_self_loopshasattrscoresclonerC   )r?   r   r   r   prepare_rescoring_G   s   





rL   )F)T)__doc__r.   pathlibr   typingr   r   r5   speechbrain.utils.loggerr    r   __name__r1   r3   boolintr   r   r-   r&   rA   rL   r   r   r   r   <module>   s&    
.")