U
    f»{jpY  ã                   @   s  d dl ZddlmZ ddlmZ ddlmZmZ ddlm	Z	 ddl
mZmZmZ ddl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mZmZmZmZ d	dlmZ dd„ Z dd„ Z!d&dd„Z"ed'dd„ƒZ#ej$dej%dej&diZ'dd„ Z(ed(d d!„ƒZ)d"d#„ Z*ed)d$d%„ƒZ+dS )*é    Né   )ÚFIFF)Ú_check_ch_keys)Ú_has_eeg_average_ref_projÚmake_eeg_average_ref_proj)Ú
setup_proj)Ú
pick_typesÚpick_channelsÚpick_channels_forward)ÚBaseRawé   )ÚEvoked)Ú
BaseEpochs)Úpinv)ÚloggerÚwarnÚverboseÚ_validate_typeÚ_check_preloadÚ_check_optionÚfill_doc©ÚDEFAULTSc                 C   s2   |   ¡  |g¡}| ||i¡ | j|gdd� | S )a  Add a copy of a channel specified by ch_name.

    Input data can be in the form of Raw, Epochs or Evoked.

    The instance object is modified inplace.

    Parameters
    ----------
    inst : instance of Raw | Epochs | Evoked
        Data containing the EEG channels
    ch_name : str
        Name of the channel to copy.
    new_ch_name : str
        Name given to the copy of the channel.

    Returns
    -------
    inst : instance of Raw | Epochs | Evoked
        The data with a copy of a given channel.
    T©Zforce_update_info)Úcopyr	   Zrename_channelsÚadd_channels)ÚinstÚch_nameZnew_ch_nameZnew_inst© r   úO/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/io/reference.pyÚ_copy_channel   s    r    c              	      sj  t ˆ dƒ tˆ |ƒ}dd„ |D ƒdddœ–}tˆ jf|Ž}|dkrZ‡ fdd„|D ƒ}d	}nd
}t|ƒdkrxtd|f ƒ‚g }tˆ jd ƒD ]f\}‰ˆd dks¬ˆd tjkrÂt	 d¡ | 
|¡ qŠˆd sŠt‡fdd„|| D ƒƒdkrŠtdƒ‚qŠ|D ]}ˆ jd |= qötˆ jddd�\ˆ _}	tˆ j|dd�}
tt |
|¡ƒdk�rfˆ j ¡ � tjˆ jd< W 5 Q R X |S )z!Prepare instance for referencing.zApplying a referencec                 S   s   i | ]
}|d “qS ©Tr   ©Ú.0Útype_r   r   r   Ú
<dictcomp>8   s      z+_check_before_reference.<locals>.<dictcomp>F©ÚmegZref_megNc                    s   g | ]}ˆ j | ‘qS r   ©Úch_names©r#   Úi©r   r   r   Ú
<listcomp>=   s     z+_check_before_reference.<locals>.<listcomp>zEEG channels foundzchannels suppliedr   zNo %s to apply the reference toÚprojsÚdesczAverage EEG referenceÚkindz3Removing existing average EEG reference projection.Zactivec                    s    g | ]}|ˆ d  d kr|‘qS )ÚdataZ	col_namesr   )r#   Úch)Úprojr   r   r-   R   s    ÿzôInactive signal space projection (SSP) operators are present that operate on sensors involved in the desired referencing scheme. These projectors need to be applied using the apply_proj() method function before the desired reference can be set.)Zadd_eeg_refÚactivateT©ÚorderedÚcustom_ref_applied)r   Ú_get_ch_typer   ÚinfoÚlenÚ
ValueErrorÚ	enumerater   ZFIFFV_PROJ_ITEM_EEG_AVREFr   ÚappendÚRuntimeErrorr   Ú
_projectorr	   r)   ÚnpZintersect1dÚ_unlockÚFIFFV_MNE_CUSTOM_REF_ON)r   Úref_fromÚref_toÚch_typeÚch_dictZeeg_idxÚextraZprojs_to_remover+   Ú_Zref_to_channelsr   )r   r3   r   Ú_check_before_reference2   sJ    

 ÿÿ
ÿÿÿÿrI   Úautoc                 C   sJ  t | |||ƒ}t|ƒdk�r>t|ƒdks,t‚|}t| j|dd�}t| j|dd�}| j}|d|dd…f jddd�}|d|dd…f  |8  < |dddd…f }|dk	�rBt||dd�}|d d	 }|jd t|ƒksØt‚|t	j|ddd
� }	t
|	dd�}
||
 }t	j||d|dd…f  ddd
�}|d|dd…f  |7  < nd}| |fS )z&Apply a custom EEG referencing scheme.r   Tr5   .Néþÿÿÿ)ÚkeepdimsZsolr1   )ZaxisrL   g�íµ ÷Æ°>)Zrtol)rI   r:   ÚAssertionErrorr	   r)   Ú_dataZmeanr
   Úshaper@   r   )r   rC   rD   ÚforwardrE   Z	ref_namesr1   Úref_dataÚGZGaZGa_invZRaZVpar   r   r   Ú_apply_referencen   s*    
"rS   Tc                 C   s6  t | dƒ t|tttfdƒ t|tƒr,|g}|D ]}|| jd kr0td| ƒ‚q0t| jd dd�rjt	dƒ‚|rv|  
¡ } t| ttfƒr¸| j}t t|ƒ|jd	 f¡}t ||f¡}|| _n†t| tƒ�r.| j}|j\}}}t |t|ƒ |f¡}t |j|| |fd
d�|f¡}|j||t|ƒ |d
d�}|| _ntdt| ƒ ƒ‚t| jd ƒ}	| j dd¡dk	�rdd„ | jd D ƒ}
t|ƒd	k�s”t|
ƒt|ƒk�r¬t dtj¡}tdƒ nbt |
d d |
d d t d¡f¡}t| jddg d�D ](}|
d d | jd | d dd…< �qänt dtj¡}t d¡ |D ]L}|tjtj |	d	 |	d	 d	ddtj!tj"|dœ}| jd  #|¡ | j $¡  �q,t %d	t|ƒd	 ¡}t| tƒ�rìt &| j'd	gt|ƒ f¡| _'t(| j)ƒD ](\}}t |t *|¡| g¡| j)|< �qÀn,t| tƒ�r| j+}t |t *|¡| g¡| _+| j ,¡  t-| |ddd� | S ) a¹  Add reference channels to data that consists of all zeros.

    Adds reference channels to data that were not included during recording.
    This is useful when you need to re-reference your data to different
    channels. These added channels will consist of all zeros.

    Parameters
    ----------
    inst : instance of Raw | Epochs | Evoked
        Instance of Raw or Epochs with EEG channels and reference channel(s).
    %(ref_channels)s
    copy : bool
        Specifies whether the data will be copied (True) or modified in-place
        (False). Defaults to True.

    Returns
    -------
    inst : instance of Raw | Epochs | Evoked
        Data with added EEG reference channels.
    Úadd_reference_channelsÚref_channelsr)   z%Channel %s already specified in inst.r.   T)Zcheck_activez*Average reference already applied to data.r   ÚF)Úorderz4inst should be Raw, Epochs, or Evoked instead of %s.ÚdigNc                 S   s*   g | ]"}|d  t jkr|d dkr|‘qS )r0   Úidentr   )r   ZFIFFV_POINT_EEG)r#   Údlr   r   r   r-   Ò   s    þz*add_reference_channels.<locals>.<listcomp>é   z9The locations of multiple reference channels are ignored.r   Úré   F)r'   ÚeegÚexcludeÚchsÚlocé   zULocation for this channel is unknown; consider calling set_montage() again if needed.g      ð?g        )r   Ú	coil_typer0   ZlognoZscannoÚcalÚrangeZunit_mulÚunitZcoord_framera   )rU   r   r   ).r   r   ÚlistÚtupleÚstrÚ
isinstancer9   r;   r   r>   r   r   r   rN   r@   Úzerosr:   rO   Zvstackr   ZreshapeÚ	TypeErrorÚtypeÚgetÚfullÚnanr   Zconcatenater   r   r   ZFIFFV_COIL_EEGZFIFFV_EEG_CHZFIFF_UNIT_VZFIFFV_COORD_HEADr=   Z_update_redundantZarangeZhstackZ_calsr<   Z_read_picksÚmaxÚpicksZ_check_consistencyÚset_eeg_reference)r   rU   r   r2   r1   ÚrefsÚxÚyÚzÚnchanZref_dig_locZref_dig_arrayÚidxZ	chan_infoZrange_Úpirr   r   r   r   rT   ˜   s�    

 ÿ 

 ÿ(
öÿÿ
ÿrT   ÚonÚoffZCSDc                 C   sB   t | tttfdƒ | jd }|tjtjfkr>tdt	| f ƒ‚d S )NÚInstancer7   z>Cannot set new reference on data with custom reference type %r)
r   r   r   r   r9   r   rB   ÚFIFFV_MNE_CUSTOM_REF_OFFr>   Ú	_ref_dict)r   Zcurrent_customr   r   r   Ú_check_can_reref  s    
ÿÿr€   ÚaverageFc                    s®  ddl m} tˆ ƒ |rÚ|dkr.td|f ƒ‚tˆ jd ƒrFtdƒ nŒˆ jd }z:ˆ j ¡ � tj	ˆ jd< W 5 Q R X ˆ  
tˆ jdd	�¡ W n6 tk
rÀ   ˆ j ¡ � |ˆ jd< W 5 Q R X ‚ Y nX ˆ jrÒt d
¡ ˆ dfS ~|rèˆ  ¡ nˆ ‰ tˆ |ƒ}dd„ |D ƒdddœ–}	‡ fdd„tˆ jf|	ŽD ƒ}
|dk�rBt||dƒ nd}|dk�rft d|› d�¡ |
}|g k�r|t d¡ n t dtdd„ |D ƒƒ› d�¡ tˆ ||
||d�S )a]  Specify which reference to use for EEG data.

    Use this function to explicitly specify the desired reference for EEG.
    This can be either an existing electrode or a new virtual channel.
    This function will re-reference the data according to the desired
    reference.

    Note that it is also possible to re-reference the signal using a
    Laplacian (LAP) "reference-free" transformation using the
    :func:`.compute_current_source_density` function.

    Parameters
    ----------
    inst : instance of Raw | Epochs | Evoked
        Instance of Raw or Epochs with EEG channels and reference channel(s).
    %(ref_channels_set_eeg_reference)s
    copy : bool
        Specifies whether the data will be copied (True) or modified in-place
        (False). Defaults to True.
    %(projection_set_eeg_reference)s
    %(ch_type_set_eeg_reference)s
    %(forward_set_eeg_reference)s
    %(verbose)s

    Returns
    -------
    inst : instance of Raw | Epochs | Evoked
        Data with EEG channels re-referenced. If ``ref_channels='average'`` and
        ``projection=True`` a projection will be added instead of directly
        re-referencing the data.
    ref_data : array
        Array of reference data subtracted from EEG channels. This will be
        ``None`` if ``projection=True`` or ``ref_channels='REST'``.
    %(set_eeg_reference_see_also_notes)s
    r   )ÚForwardr�   zMSetting projection=True is only supported for ref_channels="average", got %r.r.   zTAn average reference projection was already added. The data has been left untouched.r7   F)r4   zlAverage reference projection was added, but has not been applied yet. Use the apply_proj method to apply it.Nc                 S   s   i | ]
}|d “qS r!   r   r"   r   r   r   r%   _  s      z%set_eeg_reference.<locals>.<dictcomp>r&   c                    s   g | ]}ˆ j | ‘qS r   r(   r*   r,   r   r   r-   a  s     z%set_eeg_reference.<locals>.<listcomp>ÚRESTz forward when ref_channels="REST")r�   rƒ   z	Applying z reference.z8EEG data marked as already having the desired reference.zApplying a custom c                 s   s   | ]}t d  | V  qdS )ÚtitlesNr   r"   r   r   r   Ú	<genexpr>p  s     z$set_eeg_reference.<locals>.<genexpr>)rE   )rP   r‚   r€   r;   r   r9   r   rA   r   r~   Zadd_projr   Ú	ExceptionZpreloadr   r   r8   r   r   rh   rS   )r   rU   r   Z
projectionrE   rP   r   r‚   r7   rF   Zch_selr   r,   r   rs     s\    'þ

ÿ
ÿ

 ÿ


ÿ
ÿrs   c                 C   sÂ   t |tttfdƒ d}t|tƒr<td||ƒ |dkr||g}n@t|ttfƒr||D ]$}t |tdƒ td||dd … ƒ qNt|ƒ}|dkr¾dD ],}|| krˆ|g}t dtd |  ¡  q¾qˆt	dƒ‚|S )	NrE   )rJ   r^   ÚecogÚseegÚdbsrJ   r   )r^   r‡   rˆ   r‰   z+%s channel type selected for re-referencingr„   z8No EEG, ECoG, sEEG or DBS channels found to rereference.)
r   ri   rg   rh   rj   r   r   r9   r   r;   )r   rE   Zvalid_ch_typesr$   r   r   r   r8   x  s*    

ÿr8   c              	   C   s�  ddl m} ddlm}	 ddlm}
 ddlm} t| ƒ t	|t
ƒsH|g}t	|t
ƒsX|g}t|ƒt|ƒkr€tdt|ƒt|ƒf ƒ‚|dkržd	d
„ t||ƒD ƒ}nt	|t
ƒs®|g}t|ƒt|ƒkrÎtdt|ƒ ƒ‚t|||ƒD ],\}}}|||fkrÚ|| jkrÚtd| ƒ‚qÚ|dk�r"dd
„ |D ƒ}nt	|t
ƒ�s4|g}t|ƒt|ƒk�rNtdƒ‚|�r\|  ¡ } t| ||dd�}t t|ƒt| jƒf¡}tt||ƒƒD ]6\}\}}d||| j |¡f< d||| j |¡f< �q’||| jd | j|d�d�}tt||ƒƒD ]|\}\}}t||ddd� | j |¡}dd„ | jd |  ¡ D ƒ}|d |  |¡ tj|d | d< |d |  |¡ �qôdd„ | j ¡ D ƒ}| ¡ � | |¡ W 5 Q R X || j }t	| tƒ�rÎ|	||| jdd�}nDt	| t ƒ�rø|
||| j!| j"| j#| j$d�}n|||| j"| j%| j&dd �}| j'|gd!d"� d# (d$d
„ |D ƒ¡}t) d%|› �¡ d&D ]}t*| |dƒ �qJ|�rŒt
t+|ƒt+|ƒB t+| jƒ@ ƒ}|  ,|¡ | S )'aß  Re-reference selected channels using a bipolar referencing scheme.

    A bipolar reference takes the difference between two channels (the anode
    minus the cathode) and adds it as a new virtual channel. The original
    channels will be dropped by default.

    Multiple anodes and cathodes can be specified, in which case multiple
    virtual channels will be created. The 1st cathode will be subtracted
    from the 1st anode, the 2nd cathode from the 2nd anode, etc.

    By default, the virtual channels will be annotated with channel-info and
    -location of the anodes and coil types will be set to EEG_BIPOLAR.

    Parameters
    ----------
    inst : instance of Raw | Epochs | Evoked
        Data containing the unreferenced channels.
    anode : str | list of str
        The name(s) of the channel(s) to use as anode in the bipolar reference.
    cathode : str | list of str
        The name(s) of the channel(s) to use as cathode in the bipolar
        reference.
    ch_name : str | list of str | None
        The channel name(s) for the virtual channel(s) containing the resulting
        signal. By default, bipolar channels are named after the anode and
        cathode, but it is recommended to supply a more meaningful name.
    ch_info : dict | list of dict | None
        This parameter can be used to supply a dictionary (or a dictionary for
        each bipolar channel) containing channel information to merge in,
        overwriting the default values. Defaults to None.
    drop_refs : bool
        Whether to drop the anode/cathode channels from the instance.
    copy : bool
        Whether to operate on a copy of the data (True) or modify it in-place
        (False). Defaults to True.
    %(verbose)s

    Returns
    -------
    inst : instance of Raw | Epochs | Evoked
        Data with the specified channels re-referenced.

    See Also
    --------
    set_eeg_reference : Convenience function for creating an EEG reference.

    Notes
    -----
    1. If the anodes contain any EEG channels, this function removes
       any pre-existing average reference projections.

    2. During source localization, the EEG signal should have an average
       reference.

    3. The data must be preloaded.

    .. versionadded:: 0.9.0
    r   )Úcreate_infor   )ÚRawArray)ÚEpochsArray)ÚEvokedArrayzENumber of anodes (got %d) must equal the number of cathodes (got %d).Nc                 S   s   g | ]\}}|› d |› �‘qS )ú-r   )r#   ÚaÚcr   r   r   r-   ã  s     z)set_bipolar_reference.<locals>.<listcomp>zJNumber of channel names must equal the number of anodes/cathodes (got %d).z{There is already a channel named "%s", please specify a different name for the bipolar channel using the ch_name parameter.c                 S   s   g | ]}i ‘qS r   r   )r#   rH   r   r   r   r-   ó  s     zMNumber of channel info dictionaries must equal the number of anodes/cathodes.rJ   )rC   rD   rE   éÿÿÿÿÚsfreq)rr   )r)   r’   Zch_typesÚch_infoF)ÚnameZ	check_minc                 S   s   i | ]\}}|d kr||“qS )r   r   ©r#   ÚkÚvr   r   r   r%     s    ÿ z)set_bipolar_reference.<locals>.<dictcomp>r`   rc   c                 S   s   i | ]\}}|d kr||“qS ))r`   r)   Zbadsrx   r’   r   r•   r   r   r   r%     s     ÿ  )Ú
first_sampr   )ÚeventsÚtminÚevent_idÚmetadatar�   )rš   ÚcommentÚnaver0   Tr   z, c                 S   s   g | ]}|‘qS r   r   )r#   r”   r   r   r   r-   0  s     z&Added the following bipolar channels:
)rr   r?   )-Ú	meas_inforŠ   Úior‹   ÚepochsrŒ   Úevokedr�   r€   rj   rg   r:   r;   Úzipr)   r   rI   r@   rk   r<   Úindexr9   Zget_channel_typesr   ÚitemsÚupdater   ZFIFFV_COIL_EEG_BIPOLARrA   rN   r   r˜   r   r™   rš   r›   rœ   r�   rž   r   Újoinr   ÚsetattrÚsetÚdrop_channels)r   ZanodeZcathoder   r“   Z	drop_refsr   r   rŠ   r‹   rŒ   r�   r2   r�   r�   Z
multiplierry   Zref_infoZch_idxZanr9   Zan_idxZan_chsZ	pick_inforQ   Zref_instZadded_channelsÚ	attr_namerª   r   r   r   Úset_bipolar_reference•  s     =

ÿ
ÿþ
 ÿ
ÿ


ÿ
 þ
 þ
r¬   )NNrJ   )T)r�   TFrJ   NN)NNTTN),Únumpyr@   Ú	constantsr   rŸ   r   r3   r   r   r   Úpickr   r	   r
   Úbaser   r¢   r   r¡   r   Úfixesr   Úutilsr   r   r   r   r   r   r   Údefaultsr   r    rI   rS   rT   rB   r~   ZFIFFV_MNE_CUSTOM_REF_CSDr   r€   rs   r8   r¬   r   r   r   r   Ú<module>   sP   $<  ÿ
*l   ý	       þc      ÿ