U
    f»{j¡,  ã                   @   s�   d dl Zd dlZd dlmZ ddlmZ ddlm	Z	 dd„ Z
ddd	„Zd
d„ Zdd„ Zdd„ Zddd„Zddd„Zdd„ Zdd„ Zddd„ZdS )é    Né   )ÚFIFF)Ú_get_valid_unitsc                 C   s�   | dkrdS t ƒ }dd„ |D ƒ}t| ƒ}|  ¡ D ]Z\}}| ¡ |krFq0tƒ }d|d< d|d< d|d< | ¡ |kr‚|| ¡  ||< q0d||< q0|S )	ay  Check original units from a raw file.

    Units that are close to a valid_unit but not equal can be remapped to fit
    into the valid_units. All other units that are not valid will be replaced
    with "n/a".

    Parameters
    ----------
    orig_units : dict
        Dictionary mapping channel names to their units as specified in
        the header file. Example: {'FC1': 'nV'}

    Returns
    -------
    orig_units_remapped : dict
        Dictionary mapping channel names to their VALID units as specified in
        the header file. Invalid units are now labeled "n/a".
        Example: {'FC1': 'nV', 'Hfp3erz': 'n/a'}
    Nc                 S   s   g | ]}|  ¡ ‘qS © )Úlower)Ú.0Úunitr   r   úK/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/io/utils.pyÚ
<listcomp>,   s     z%_check_orig_units.<locals>.<listcomp>u   ÂµVZuvu   Î¼vu   ÂƒÃªvzn/a)r   ÚdictÚitemsr   )Z
orig_unitsZvalid_unitsZvalid_units_loweredZorig_units_remappedÚch_namer   Z
remap_dictr   r   r	   Ú_check_orig_units   s"    
r   ÚEOGc                    s:   |f‰ dd„ ˆ D ƒ‰ |dkr d‰ ‡ fdd„t | ƒD ƒ}|S )zFind EOG channel.c                 S   s   g | ]}|  ¡ ‘qS r   ©Úupper)r   Úsr   r   r	   r
   F   s     z"_find_channels.<locals>.<listcomp>r   )r   ZEYEc                    s*   g | ]"\}‰ t ‡ fd d„ˆD ƒƒr|‘qS )c                 3   s   | ]}|ˆ   ¡ kV  qd S ©Nr   )r   Z	substring©Úchr   r	   Ú	<genexpr>J   s     z,_find_channels.<locals>.<listcomp>.<genexpr>)Úany)r   Úidx©Z
substringsr   r	   r
   I   s    ÿ)Ú	enumerate)Úch_namesZch_typeZeog_idxr   r   r	   Ú_find_channelsC   s    r   c                 C   s¼   t j|| jd�}| jd |jd ks<t| jd |jd fƒ‚|dk	rv|j|j  koZdkn   |||  | dd…< nB|dk	s‚t‚t|tƒrž|| | dd…< nt j||d| d� | |9 } dS )z>Take a chunk of raw data, multiply by mult or cals, and store.©Údtyper   Né   r   )ZaxisÚout)	ÚnpZasarrayr   ÚshapeÚAssertionErrorÚndimÚ
isinstanceÚsliceZtake)Ú	data_viewÚoner   ÚcalsÚmultr   r   r	   Ú_mult_cal_oneN   s    ,
r+   c                 C   s  t dd„ | ||fD ƒƒst‚| | }|| }|d }|||  | }|| }|| || dk }| | }	|| }
t |dft¡}t |dft¡}t|ƒD ]p}|dkr®d}|	}n|| |	 }d}||d krÜ||  }||
 }n|d | |	 }|}||g||< ||g||< q˜|||fS )a&  Deal with indexing in the middle of a data block.

    Parameters
    ----------
    start : int
        Starting index.
    stop : int
        Ending index (exclusive).
    buf_len : int
        Buffer size in samples.

    Returns
    -------
    block_start_idx : int
        The first block to start reading from.
    r_lims : list
        The read limits.
    d_lims : list
        The write limits.

    Notes
    -----
    Consider this example::

        >>> start, stop, buf_len = 2, 27, 10

                    +---------+---------+---------
    File structure: |  buf0   |   buf1  |   buf2  |
                    +---------+---------+---------
    File time:      0        10        20        30
                    +---------+---------+---------
    Requested time:   2                       27

                    |                             |
                blockstart                    blockstop
                      |                        |
                    start                    stop

    We need 27 - 2 = 25 samples (per channel) to store our data, and
    we need to read from 3 buffers (30 samples) to get all of our data.

    On all reads but the first, the data we read starts at
    the first sample of the buffer. On all reads but the last,
    the data we read ends on the last sample of the buffer.

    We call ``this_data`` the variable that stores the current buffer's data,
    and ``data`` the variable that stores the total output.

    On the first read, we need to do this::

        >>> data[0:buf_len-2] = this_data[2:buf_len]  # doctest: +SKIP

    On the second read, we need to do::

        >>> data[1*buf_len-2:2*buf_len-2] = this_data[0:buf_len]  # doctest: +SKIP

    On the final read, we need to do::

        >>> data[2*buf_len-2:3*buf_len-2-3] = this_data[0:buf_len-3]  # doctest: +SKIP

    This function encapsulates this logic to allow a loop over blocks, where
    data is stored using the following limits::

        >>> data[d_lims[ii, 0]:d_lims[ii, 1]] = this_data[r_lims[ii, 0]:r_lims[ii, 1]]  # doctest: +SKIP

    c                 s   s   | ]}t |tƒV  qd S r   )r%   Úint)r   Úxr   r   r	   r   £   s     z!_blk_read_lims.<locals>.<genexpr>r   r   r   )Úallr#   r!   Úemptyr,   Úrange)ÚstartÚstopZbuf_lenZblock_start_idxZblock_startZlast_used_sampZ
block_stopÚ	read_sizeZn_blkZstart_offsetÚ
end_offsetZd_limsZr_limsZbiZd_sidxZr_sidxZd_eidxZr_eidxr   r   r	   Ú_blk_read_lims_   s2    D
r5   c              
   C   s8   t | dƒ�$}| dtj¡ | ¡ W  5 Q R £ S Q R X dS )zGet the file size in bytes.Úrbr   N)ÚopenÚseekÚosÚSEEK_ENDÚtell)ÚfnameÚfr   r   r	   Ú
_file_sizeÂ   s    r>   c              	   C   sP  |	dkr| j | d }	t |¡j}|	| | |
 }|| |	 }tdƒ| |	 |	 }t||ƒ}t| j| ddd��Ö}| |¡ t 	d||¡|	 D ]²}t||||	  ƒ}t 
|||¡}|j|krÎtd|j|f ƒ‚|j|	dd	d
�}|jd }|| }|dk	�r|||… ||… }t ||f¡}|dd…||…f }t|||||ƒ qŽW 5 Q R X dS )zRead a chunk of raw data.NZ
orig_nchang    „×—Ar6   r   )Ú	bufferingzYIncorrect number of samples (%s != %s), please report this error to MNE-Python developerséÿÿÿÿÚF)Úorderr   )Z_raw_extrasr!   r   Úitemsizer,   Úminr7   Z
_filenamesr8   ZarangeÚfromfileÚsizeÚRuntimeErrorZreshaper"   Zvstackr+   )ÚrawÚdatar   Úfir1   r2   r)   r*   r   Z
n_channelsÚoffsetZ
trigger_chZn_bytesZdata_offsetZ	data_leftÚ
block_sizeÚfidZsample_startÚcountÚblockÚ	n_samplesZsample_stopZstim_chr'   r   r   r	   Ú_read_segments_fileÉ   s0    


þ

rQ   c                 C   s`   t  d| ¡}|  |j¡}t j||d�d }d |dd|krF| d¡n|… g¡}t| d¡ƒS )zBRead string from a binary file in a python version compatible way.z>S%ir   r   ó    ó    Úascii)	r!   r   ÚreadrC   Z
frombufferÚjoinÚindexÚstrÚdecode)rM   rN   r   ÚstringrI   Zbytestrr   r   r	   Úread_strì   s    ÿÿ
r[   c                 C   sÚ   t ƒ }t| ƒD ]Æ\}	}
|
|ks&|	|kr4tj}tj}nb|
|ksD|	|krRtj}tj}nD|
|ksb|	|krptj}tj}n&|
|ks€|	|krŽtj}tj}n|}|}||	 |	d |	d dtj|
tj	tj
||t d¡dœ}| |¡ q|S )z(Initialize info['chs'] for eeg channels.r   g      ð?é   )ÚcalZlognoZscannor0   Zunit_mulr   r   Zcoord_frameÚ	coil_typeÚkindÚloc)Úlistr   r   ZFIFFV_COIL_NONEZFIFFV_EOG_CHZFIFFV_ECG_CHZFIFFV_EMG_CHZFIFFV_MISC_CHZFIFF_UNITM_NONEZFIFF_UNIT_VZFIFFV_COORD_HEADr!   ÚzerosÚappend)r   r)   Zch_coilZch_kindZeogZecgZemgÚmiscZchsr   r   r^   r_   Z	chan_infor   r   r	   Ú_create_chs÷   s8        üre   c                 C   sT   |   ¡ } d| | dd…df dk df< t |t¡}| D ]\}}}||||| …< q4|S )al  Synthesize a stim channel from events read from an event file.

    Parameters
    ----------
    events : array, shape (n_events, 3)
        Each row representing an event.
    n_samples : int
        The number of samples.

    Returns
    -------
    stim_channel : array, shape (n_samples,)
        An array containing the whole recording's event marking.
    r   N)Úcopyr!   rb   r,   )ÚeventsrP   Zstim_channelZonsetÚdurationÚtriggerr   r   r	   Ú_synthesize_stim_channel  s    rj   Tc                 C   sz   t  | ¡}t  | ¡} |  d¡}t|ƒdk r<|r<td| › �ƒ‚|d }d |dd… ¡} d | |||¡}|rvt  ||¡}|S )z5Construct a BIDS compatible filename for split files.Ú_r   z]Filename base must end with an underscore followed by the modality (e.g., _eeg or _meg), got r@   Nz{}_split-{:02}_{}{})ÚopÚdirnameÚbasenameÚsplitÚlenÚ
ValueErrorrV   Úformat)ÚbaseÚextZpart_idxÚvalidaterm   Zdeconstructed_baseÚsuffixZ	use_fnamer   r   r	   Ú_construct_bids_filename-  s    


rw   )r   )Nr   N)r   )T)Únumpyr!   r9   Úos.pathÚpathrl   Ú	constantsr   Z	meas_infor   r   r   r+   r5   r>   rQ   r[   re   rj   rw   r   r   r   r	   Ú<module>   s"   .
c     ÿ
#
