U
    f»{j¡Y  ã                   @   s¾   d dl ZddlmZ ddlmZmZmZmZ ddl	m
Z
mZmZmZmZ ddlmZ ddlmZ ddlmZmZmZmZmZ eddd„ƒZddd„Zdd„ Zddd„Zedddœdd„ƒZdS )é    Né   )ÚBaseRaw)ÚAnnotationsÚ_annotations_starts_stopsÚannotations_from_eventsÚ_adjust_onset_meas_date)Úquat_to_rotÚ_average_quatsÚ_angle_between_quatsÚapply_transÚ_quat_to_affine)Úfilter_data)Ú	Transform)Ú_mask_to_onsets_offsetsÚloggerÚverboseÚ_validate_typeÚ_plé   çš™™™™™¹?©én   éŒ   c                 C   sð  ddl m} ddlm} |  ¡ }	|dkrp|	 ¡ }
d|
kr>d}n$d|
krLd}nd|
krZd}ntdƒ‚t d	| ¡ |d
krˆ|	j	|dd� ndd|di}|	j	f |Ž |	j
|d |d dd|d� |	jd|d� |	jdd�}t |d ¡ }|	jd }||dd…|f dd�}|jdd�t |jd ¡ }t||ddƒ}t |jd ¡}|||< ||k}tj|| < |dk�rldn|}|| }||dkƒ\}}td|d ƒD ].}t ||k¡d }t|ƒ|k �r–d||< �q–t|	j|d| jd d�}t|| ƒ ||fS )a   Create annotations for segments that likely contain muscle artifacts.

    Detects data segments containing activity in the frequency range given by
    ``filter_freq`` whose envelope magnitude exceeds the specified z-score
    threshold, when summed across channels and divided by ``sqrt(n_channels)``.
    False-positive transient peaks are prevented by low-pass filtering the
    resulting z-score time series at 4 Hz. Only operates on a single channel
    type, if ``ch_type`` is ``None`` it will select the first type in the list
    ``mag``, ``grad``, ``eeg``.
    See :footcite:`Muthukumaraswamy2013` for background on choosing
    ``filter_freq`` and ``threshold``.

    Parameters
    ----------
    raw : instance of Raw
        Data to estimate segments with muscle artifacts.
    threshold : float
        The threshold in z-scores for marking segments as containing muscle
        activity artifacts.
    ch_type : 'mag' | 'grad' | 'eeg' | None
        The type of sensors to use. If ``None`` it will take the first type in
        ``mag``, ``grad``, ``eeg``.
    min_length_good : float | None
        The shortest allowed duration of "good data" (in seconds) between
        adjacent annotations; shorter segments will be incorporated into the
        surrounding annotations.``None`` is equivalent to ``0``.
        Default is ``0.1``.
    filter_freq : array-like, shape (2,)
        The lower and upper frequencies of the band-pass filter.
        Default is ``(110, 140)``.
    %(n_jobs)s
    %(verbose)s

    Returns
    -------
    annot : mne.Annotations
        Periods with muscle artifacts annotated as BAD_muscle.
    scores_muscle : array
        Z-score values averaged across channels for each sample.

    References
    ----------
    .. footbibliography::
    r   )Úzscore)ÚlabelNÚmagÚgradZeegzSNo M/EEG channel types found, please specify a ch_type or provide M/EEG sensor dataz.Using %s sensors for muscle artifact detection)r   r   F)ÚmegZref_megr   Té   ZfirwinZreflect_limited)Z
fir_designÚpadÚn_jobs)Úenveloper    ÚNaN)Zreject_by_annotationÚsfreq©Zaxisr   Z
BAD_muscleÚ	meas_date©Ú	orig_time)Zscipy.statsr   Úscipy.ndimager   ÚcopyZget_channel_typesÚ
ValueErrorr   ÚinfoZ
pick_typesÚfilterZapply_hilbertÚget_dataÚnpÚisnanÚsumÚsqrtÚshaper   ÚzerosÚnanÚrangeZnonzeroÚlenÚ_annotations_from_maskÚtimesr   )ÚrawÚ	thresholdZch_typeZmin_length_goodZfilter_freqr    r   r   r   Zraw_copyZraw_ch_typeÚdataZnan_maskr#   Z
art_scoresZscores_muscleZart_maskZ	min_sampsÚcompsZ	num_compsÚcomZl_idxÚannot© r?   úc/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/preprocessing/artifact_detection.pyÚannotate_muscle_zscore   s`    /ÿ ÿ
 þ
rA   Úaveragec              
      sv  | j d }|dd…df  ¡ | j }t |¡}t ||d d|  gg¡}| j d }	tg g g |	d�}
| jd }|dk	�r.|dks„t‚t	|dd…dd	…f |dd…dd	…f ƒ}|| }|t 
|¡k}t|ƒ\}}|| ||  }}d
||  ¡  | }t  d|t|ƒ|t | ¡ ¡f ¡ |
t||d|	d�7 }
|dk	�rä|dk�sFt‚tjjtj|dd…d	d…f dd�dd�}|| }||k}t|ƒ\}}|| ||  }}d
||  ¡  | }t  d|t|ƒ|| ¡ f ¡ |
t||d|	d�7 }
g }|dk	�rd|dk�s t‚| ¡ }|dk�r$tdd|f  ƒ‚|dk�r:t| |ƒ}n|dk�rN| j d }tdd„ | j d d d D ƒdd„ d�‰ t dd„ ˆ D ƒ¡‰ t ‡ fdd„|dd…dd…f D ƒ¡}t|ˆ ƒ}|t ||jd ddf¡ }t |d  jd d�¡}tj||kdd�}t|ƒ\}}|| ||  }}d
||  ¡  | }t  d!|t|ƒ|| ¡ f ¡ |
t||d"|	d�7 }
t|
| ƒ |
|fS )#a,  Detect segments with movement.

    Detects segments periods further from rotation_velocity_limit,
    translation_velocity_limit and mean_distance_limit. It returns an
    annotation with the bad segments.

    Parameters
    ----------
    raw : instance of Raw
        Data to compute head position.
    pos : array, shape (N, 10)
        The position and quaternion parameters from cHPI fitting. Obtained
        with `mne.chpi` functions.
    rotation_velocity_limit : float
        Head rotation velocity limit in radians per second.
    translation_velocity_limit : float
        Head translation velocity limit in radians per second.
    mean_distance_limit : float
        Head position limit from mean recording in meters.
    use_dev_head_trans : 'average' (default) | 'info'
        Identify the device to head transform used to define the
        fixed HPI locations for computing moving distances.
        If ``average`` the average device to head transform is
        computed using ``compute_average_dev_head_t``.
        If ``info``, ``raw.info['dev_head_t']`` is used.

    Returns
    -------
    annot : mne.Annotations
        Periods with head motion.
    hpi_disp : array
        Head position over time with respect to the mean head pos.

    See Also
    --------
    compute_average_dev_head_t
    r#   Nr   éÿÿÿÿç      ð?r%   r&   r   r   éd   uA   Omitting %5.1f%% (%3d segments): Ï‰ >= %5.1fÂ°/s (max: %0.1fÂ°/s)ZBAD_mov_rotat_velé   r$   z>Omitting %5.1f%% (%3d segments): v >= %5.4fm/s (max: %5.4fm/s)ZBAD_mov_trans_vel)rB   r+   z!use_dev_head_trans must be eitherz 'average' or 'info': got '%s'rB   r+   Ú
dev_head_tc                 S   s   g | ]}|‘qS r?   r?   ©Ú.0Údr?   r?   r@   Ú
<listcomp>á   s     z%annotate_movement.<locals>.<listcomp>Zhpi_resultsZ
dig_pointsc                 S   s   | d S )NÚidentr?   )Úxr?   r?   r@   Ú<lambda>â   ó    z#annotate_movement.<locals>.<lambda>)Úkeyc                 S   s   g | ]}|d  ‘qS )Úrr?   rH   r?   r?   r@   rK   ã   s     c                    s   g | ]}t t|ƒˆ ƒ‘qS r?   )r   r   )rI   Zquat©Zchpi_posr?   r@   rK   æ   s   ÿr   z=Omitting %5.1f%% (%3d segments): disp >= %5.4fm (max: %5.4fm)ZBAD_mov_dist)r+   r)   Ú
first_timer.   ÚdiffÚconcatenater   r8   ÚAssertionErrorr
   Zdeg2radr   r0   r   r6   Zrad2degÚmaxr7   ÚlinalgÚnormÚlowerr*   Úcompute_average_dev_head_tÚsortedÚarrayr   Ztiler2   r1   Úanyr   )r9   ÚposZrotation_velocity_limitZtranslation_velocity_limitZmean_distance_limitZuse_dev_head_transr#   Úhp_tsÚdtr'   r>   Zt_totrQ   Zbad_maskÚonsetsÚoffsetsZbad_pctÚvZdispZfixed_dev_head_tZchpi_pos_movZchpi_pos_fixZhpi_dispr?   rR   r@   Úannotate_movement~   s¬    (




*
ÿþ   ÿ
*
ÿþ   ÿ

ÿÿ


ÿÿÿ
þ   ÿ
re   c                 C   sˆ  | j d }t t| jƒ¡}t d¡}| ¡ }|dd…df | j }|d dk rjd|d< |d d| ksjt‚|| jd k}| 	¡ s¨t
  dt | ¡| jd f ¡ || }~~t |dd…df | jd | gf¡}t |¡dk 	¡ sèt‚|| j| 8 }| j|d	d
�}	~|	d dk�r.d|	d< |	d dk�s.t‚|	dk 	¡ �s@t‚|	d t|ƒk�sVt‚t |	¡dk 	¡ �snt‚t| dƒ\}
}t|
|ƒD ]\}}d|||…< �q†t t t dg|g¡¡|	 ¡}|dk 	¡ �sÐt‚|| }~~	|t ||dd…dd…f ¡7 }|dd…dd…f }t||d�}t d¡}t|ƒ|dd…dd…f< || ¡  |dd…df< tj |dd…df ¡dk �sxt‚tdd|ƒ}|S )aÚ  Get new device to head transform based on good segments.

    Segments starting with "BAD" annotations are not included for calculating
    the mean head position.

    Parameters
    ----------
    raw : instance of Raw
        Data to compute head position.
    pos : array, shape (N, 10)
        The position and quaternion parameters from cHPI fitting.

    Returns
    -------
    dev_head_t : array
        New trans matrix using the averaged good head positions.
    r#   é   Nr   r   rD   rC   z2          Removing %d samples > raw.times[-1] (%s)T)Zuse_roundingÚbadr   rF   )Úweightsr   Úhead)r+   r.   Zonesr6   r8   r3   r)   Z_first_timerV   Úallr   r0   rU   Z	last_samprT   Z
first_sampZtime_as_indexr   ÚzipZcumsumÚdotr	   Úeyer   rX   rY   r   )r9   r_   r#   Zseg_goodZ	trans_posÚhpr`   ÚmaskÚtsÚidxrb   ÚendsÚonsetÚendra   Zrot_qsZbest_qZtransrG   r?   r?   r@   r[   þ   sX    

ÿÿ&  
"r[   c                 C   s   ddl m} ddlm} ||ƒ}t t d¡|t d¡f¡}||ƒd d }t t|ƒd ||ddd… ƒd  ¡d }	|||  	t
¡ d }
|	||	  	t
¡ }d|
|
dk < t| ƒt|ƒkrÖt| ƒd ||t| ƒk< nt|ƒ||t|ƒk< | |
 }| | }|| }|gt|ƒ }t||||d�S )z4Construct annotations from boolean mask of the data.r   )Údistance_transform_edt)Ú
find_peaksr   NrC   r&   )r(   ru   Zscipy.signalrv   r.   rU   r3   Úflipr6   ZastypeÚintr   )r8   ro   Z
annot_namer'   ru   rv   Zmask_tfZins_mask_tfZleft_midpt_indexZright_midpt_indexZonsets_indexZ
ends_indexrb   rr   Z	durationsÚdescr?   r?   r@   r7   H  s.    ÿÿÿr7   ç      .@ç      @©rg   Úedge)r   c                   sà  t | dtdd� t |ddtjfd� || | dkrN|| | }td|› �ƒ‚|dk	rh|jdkrhtd	ƒ‚|dk	st|s|tƒ }nt|ƒ}|D ]}t |d
dd� qˆ|dkrÊ| j ¡ }	|rät	 
dd |¡› �¡ nt|| j
d | j
d d�}	|	sðtdƒ‚tdd„ |D ƒƒ}dgt|	ƒ }
t|	jƒD ]2\}‰ ˆ  ¡ ‰ t‡ fdd„|D ƒƒ�rd|
|< �qdd„ t|	j|
 |	j|
 ƒD ƒ}|d g}|D ]V}|d d }|\}}||k �r¤�q|n,||k�rÆ||k�rÆ||d d< n
| |¡ �q|t |¡}|| j8 }g }g }d|d d k �rD|d d |k�rDd}|d d | }|| }| |¡ | |¡ t|dd…dd…f dd�D ]d\}}||df }||d df }|| |k �r–�q`|| }|| }|| }| |¡ | |¡ �q`| jd |d d k�r0| jd |d d  |k�r0|d d | }| jd }|| }| |¡ | |¡ t||dg| j
d d�}t|ƒ}dd„ t|j|jƒD ƒ}d  |¡}t|jƒ}|| jd  }t	 
d!|› d"t|ƒ› d#|› d$|› d%td&| dƒd'›d(t|dƒd'›d)�¡ t|| ƒ |S )*a§  Create `~mne.Annotations` for breaks in an ongoing recording.

    This function first searches for segments in the data that are not
    annotated or do not contain any events and are at least
    ``min_break_duration`` seconds long, and then proceeds to creating
    annotations for those break periods.

    Parameters
    ----------
    raw : instance of Raw
        The continuous data to analyze.
    events : None | array, shape (n_events, 3)
        If ``None`` (default), operate based solely on the annotations present
        in ``raw``. If an events array, ignore any annotations in the raw data,
        and operate based on these events only.
    min_break_duration : float
        The minimum time span in seconds between the offset of one and the
        onset of the subsequent annotation (if ``events`` is ``None``) or
        between two consecutive events (if ``events`` is an array) to consider
        this period a "break". Defaults to 15 seconds.

        .. note:: This value defines the minimum duration of a break period in
                  the data, **not** the minimum duration of the generated
                  annotations! See also ``t_start_after_previous`` and
                  ``t_stop_before_next`` for details.

    t_start_after_previous, t_stop_before_next : float
        Specifies how far the to-be-created "break" annotation extends towards
        the two annotations or events spanning the break. This can be used to
        ensure e.g. that the break annotation doesn't start and end immediately
        with a stimulation event. If, for example, your data contains a break
        of 30 seconds between two stimuli, and ``t_start_after_previous`` is
        set to ``5`` and ``t_stop_before_next`` is set to ``3``, the break
        annotation will start 5 seconds after the first stimulus, and end 3
        seconds before the second stimulus, yielding an annotated break of
        ``30 - 5 - 3 = 22`` seconds. Both default to 5 seconds.

        .. note:: The beginning and the end of the recording will be annotated
                  as breaks, too, if the period from recording start until the
                  first annotation or event (or from last annotation or event
                  until recording end) is at least ``min_break_duration``
                  seconds long.

    ignore : iterable of str
        Annotation descriptions starting with these strings will be ignored by
        the break-finding algorithm. The string comparison is case-insensitive,
        i.e., ``('bad',)`` and ``('BAD',)`` are equivalent. By default, all
        annotation descriptions starting with "bad" and annotations
        indicating "edges" (produced by data concatenation) will be
        ignored. Pass an empty list or tuple to take all existing annotations
        into account. If ``events`` is passed, this parameter has no effect.
    %(verbose)s

    Returns
    -------
    break_annotations : instance of Annotations
        The break annotations, each with the description ``'BAD_break'``. If
        no breaks could be found given the provided function parameters, an
        empty `~mne.Annotations` object will be returned.

    Notes
    -----
    .. versionadded:: 0.24
    r9   ZRaw)ÚitemÚ	item_nameÚtypesÚ	type_nameÚeventsN)r~   r   r€   r   zrThe result of min_break_duration - t_start_after_previous - t_stop_before_next must be greater than 0, but it is: z#The events array must not be empty.ÚstrzAll elements of "ignore")r~   r€   r   z6Ignoring annotations with descriptions starting with: z, r#   r%   )r‚   r#   r'   z:Could not find (or generate) any annotations in your data.c                 s   s   | ]}|  ¡ V  qd S ©N)rZ   ©rI   Úir?   r?   r@   Ú	<genexpr>Ü  s     z!annotate_break.<locals>.<genexpr>Tc                 3   s   | ]}ˆ   |¡V  qd S r„   )Ú
startswithr…   ©Údescriptionr?   r@   r‡   à  s     Fc                 S   s   g | ]\}}||| g‘qS r?   r?   )rI   rs   Údurationr?   r?   r@   rK   ã  s    z"annotate_break.<locals>.<listcomp>rC   r   )ÚstartZ	BAD_break)rs   r‹   rŠ   r'   c                 S   s0   g | ](\}}|d ›d|| d ›d|d ›d�‘qS )ú.1fu    â€“ z sec [z sec]r?   )rI   ÚorJ   r?   r?   r@   rK   ,  s   ÿz
    z

Detected z break periodz of >= z sec duration:
    z
In total, rE   r�   z% of the data (z# sec) have been marked as a break.
)r   r   r.   Zndarrayr*   ÚsizeÚtupleÚannotationsr)   r   r+   Újoinr   r6   Ú	enumeraterŠ   rZ   r^   rk   rs   r‹   Úappendr]   rS   r8   r   r0   r   Úroundr   )r9   r‚   Zmin_break_durationZt_start_after_previousZt_stop_before_nextÚignorer   Z	annot_durr~   r‘   Z	keep_maskrq   Zannotated_intervalsZmerged_intervalsÚintervalZmerged_interval_stopZinterval_startZinterval_stopZbreak_onsetsZbreak_durationsrs   Úoffsetr‹   Ú_Z
this_startZprevious_stopZbreak_annotationsZn_breaksZbreak_timesZtotal_break_durZfraction_breaksr?   r‰   r@   Úannotate_breaki  sÂ    Hÿÿÿ
ýþ


ÿ

ÿ

$
ÿ


üÿþ

H
rš   )r   Nr   r   NN)NNNrB   )N)Nrz   r{   r{   r|   )Únumpyr.   Zio.baser   r‘   r   r   r   r   Z
transformsr   r	   r
   r   r   r,   r   Ú r   Úutilsr   r   r   r   r   rA   re   r[   r7   rš   r?   r?   r?   r@   Ú<module>   s:         ÿj     þ
 J
!     üú