U
    f»{j°,  ã                   @   s¶   d dl Zddl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 ddlmZ dd	lmZ dd
lmZmZ dd„ Zdd„ Zedddœdd„ƒZeddd„ƒZdS )é    Né   )Ú
pick_types)Ú_validate_typeÚ_ensure_intÚ_check_preloadÚverboseÚlogger)ÚBaseRaw)ÚFIFF)Ú
BaseEpochsÚmake_fixed_length_epochs)ÚEvoked)Úfit_sphere_to_headshape)Ú_calc_gÚ_calc_hc                 C   sJ   | j d d t| ƒd …  |7  < tj | ¡}| d¡}t |¡}|||fS )Né   r   )ÚflatÚlenÚnpÚlinalgÚinvÚsum)ÚGÚlambda2ÚGiÚTCÚsgi© r   úU/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/preprocessing/_csd.pyÚ
_prepare_G   s
     

r   c                 C   s–   |j d }t |¡}| d¡}|| }| \}}}	t ||¡}
tj|
dd�|	 }|
t |dd…tjf |tjdd…f ¡ }t |j|¡j|d  }|S )zCompute the CSD.r   ©ÚaxisNr   )Úshaper   ÚeyeZmeanÚdotr   ÚnewaxisÚT)ÚG_precomputedÚHÚradiusZ
n_channelsÚdataÚmuÚZr   r   r   ZCp2Zc02ZC2ÚXr   r   r   Ú_compute_csd'   s    



,r.   Úautoçñhãˆµøä>é   é2   T)r   c             	      sX  t ˆ tttfdƒ tˆ dƒ ˆ jd tjkr4tdƒ‚t |t	dƒ |rLˆ  
¡ nˆ ‰ tˆ jddg d�‰t‡ ‡fd	d
„ˆ jd D ƒƒrˆtdƒ‚tˆƒdkrœtdƒ‚t |ddƒ d|  kr¼dk sÊn td| ƒ‚t |ddƒ |dk rêtd| ƒ‚t|dƒ}|dk �r
td| ƒ‚t|tƒ�rJ|dk�rJtˆ jƒ\}}}	||	 \}
}}|
|||f}zt |t¡}|\}
}}}W n$ tk
�rŠ   td|› �ƒ‚Y nX t |
ddƒ t |ddƒ t |ddƒ t |ddƒ |dk�rÒtd| ƒ‚t ‡ fdd
„ˆD ƒ¡}t |¡ ¡ �rt |d¡ d¡ ¡ �rtd ƒ‚||
||f8 }|tjj|ddd!� }t t ||j¡d"d¡}~t|||d#�}t|||d#�}t ||ƒ}t!|||d$�}tˆ tƒ�s ˆ j"gnˆ j"}|D ]}t ||ˆ ¡|ˆ< �qªˆ j #¡ � tjˆ jd< W 5 Q R X ˆD ]"}ˆ jd% | j$tj%tj&d&� �qìtˆ tƒ�rTˆ j'�r8d'ˆ j'k�r8ˆ j'd'= ˆ j(�rTd'ˆ j(k�rTˆ j(d'= ˆ S )(aÆ  Get the current source density (CSD) transformation.

    Transformation based on spherical spline surface Laplacian
    :footcite:`PerrinEtAl1987,PerrinEtAl1989,Cohen2014,KayserTenke2015`.

    This function can be used to re-reference the signal using a Laplacian
    (LAP) "reference-free" transformation.

    Parameters
    ----------
    inst : instance of Raw, Epochs or Evoked
        The data to be transformed.
    sphere : array-like, shape (4,) | str
        The sphere, head-model of the form (x, y, z, r) where x, y, z
        is the center of the sphere and r is the radius in meters.
        Can also be "auto" to use a digitization-based fit.
    lambda2 : float
        Regularization parameter, produces smoothness. Defaults to 1e-5.
    stiffness : float
        Stiffness of the spline.
    n_legendre_terms : int
        Number of Legendre terms to evaluate.
    copy : bool
        Whether to overwrite instance data or create a copy.
    %(verbose)s

    Returns
    -------
    inst_csd : instance of Raw, Epochs or Evoked
        The transformed data. Output type will match input type.

    Notes
    -----
    .. versionadded:: 0.20

    References
    ----------
    .. footbibliography::
    ÚinstzComputing CSDZcustom_ref_appliedz,CSD already applied, should not be reappliedÚcopyFT)ZmegÚeegÚexcludec                    s    g | ]}|t  ˆ j¡ˆ k‘qS r   )r   ÚarrayÚch_names)Ú.0Úch©r3   Úpicksr   r   Ú
<listcomp>m   s     z2compute_current_source_density.<locals>.<listcomp>Zbadsz�CSD cannot be computed with bad EEG channels. Either drop (inst.drop_channels(inst.info['bads']) or interpolate (`inst.interpolate_bads()`) bad EEG channels.r   zNo EEG channels found.Únumericr   r   z'lambda2 must be between 0 and 1, got %sÚ	stiffnessz%stiffness must be non-negative got %sÚn_legendre_termsz/n_legendre_terms must be greater than 0, got %sr/   z9sphere must be "auto" or array-like with shape (4,), got ÚxÚyÚzr)   z,sphere radius must be greater than 0, got %sc                    s&   g | ]}ˆ j d  | d dd… ‘qS )ÚchsÚlocNé   )Úinfo)r9   Úpick)r3   r   r   r=   –   s     g        z&Zero or infinite position found in chs)r!   Zkeepdimséÿÿÿÿ)r?   r@   )r'   r(   r)   rD   )Z	coil_typeÚunitr5   ))r   r   r	   r   r   rG   r
   ZFIFFV_MNE_CUSTOM_REF_CSDÚ
ValueErrorÚboolr4   r   Úanyr   r   Ú
isinstanceÚstrr   r   r7   ÚfloatÚ	ExceptionÚisfiniteÚallÚiscloser   ZnormZclipr$   r&   r   r   r   r.   Ú_dataZ_unlockÚupdateZFIFFV_COIL_EEG_CSDZFIFF_UNIT_V_M2Zrejectr   )r3   Zspherer   r?   r@   r4   r   r)   Zorigin_headZorigin_devicerA   rB   rC   ÚposZcos_distr   r(   r'   Z	trans_csdÚepochsZeporH   r   r;   r   Úcompute_current_source_density7   s”    +


ÿÿ

ÿ(ÿÿ
 ÿÿ
rY   é   ç      à?é   c              
      sJ  ddl m} ddlm}	 t| dƒ |  ¡ } t| jdd�}
t|
ƒdkrLt	dƒ‚| j
|||
dd	� t| tƒrxt| |ddd
�} | j|
d�}t| tƒrœ|tjdf }|jd }t ||
j|
jf¡tj }t|
jƒD ]R}t|d |
jƒD ]<}tj|dd…|f |dd…|f  dd�|dd…||f< qÞqÊ|d9 }tƒ }|t |¡  }||ˆk  j| |k �r\||fS |||ˆk  ƒ‰ tjdd�� t|	‡ ‡fdd„ƒjƒ}W 5 Q R X t d|› d�¡ t|
jƒD ]ˆ}t|d |
jƒD ]p}t |dd…||f |k ¡}|| |k�rÌt d| j|
|  › d| j|
|  › �¡ |  |
| |
| f¡ �qÌ�q¸||fS )a|  Compute bridged EEG electrodes using the intrinsic Hjorth algorithm.

    First an electrical distance matrix is computed by taking the pairwise
    variance. Then, a local maximum near 0 :math:`{\mu}V^2` and a
    a local minimum below 5 :math:`{\mu}V^2` are found, the presence
    of which is indicative of bridging. Finally, electrode distances below
    the local minimum are marked as bridged as long as they happen on more
    than the ``epoch_threshold`` proportion of epochs.

    Based on :footcite:`TenkeKayser2001,GreischarEtAl2004,DelormeMakeig2004`
    and the `EEGLAB implementation
    <https://psychophysiology.cpmc.columbia.edu/software/eBridge/index.html>`_.

    Parameters
    ----------
    inst : instance of Raw, Epochs or Evoked
        The data to compute electrode bridging on.
    lm_cutoff : float
        The distance in :math:`{\mu}V^2` cutoff below which to
        search for a local minimum (lm) indicative of bridging.
        Defaults to 16 :math:`{\mu}V^2` to be conservative based
        on the distributions in :footcite:`GreischarEtAl2004`.
    epoch_threshold : float
        The proportion of epochs with electrical distance less than
        ``ed_threshold`` in order to consider the channel bridged.
        The default is 0.5.
    l_freq : float
        The low cutoff frequency to use. Default is 0.5 Hz.
    h_freq : float
        The high cutoff frequency to use. Default is 30 Hz.
    epoch_duration : float
        The time in seconds to divide the raw into fixed-length epochs
        to check for consistent bridging. Only used if ``inst`` is
        :class:`mne.io.BaseRaw`. The default is 2 seconds.
    bw_method : None
        ``bw_method`` to pass to :class:`scipy.stats.gaussian_kde`.
    %(verbose)s

    Returns
    -------
    bridged_idx : list of tuple
        The indices of channels marked as bridged with each bridged
        pair stored as a tuple.
    ed_matrix : ndarray of float, shape (n_epochs, n_channels, n_channels)
        The electrical distance matrix for each pair of EEG electrodes.

    Notes
    -----
    .. versionadded:: 1.1

    References
    ----------
    .. footbibliography::
    r   )Úgaussian_kde)Úminimize_scalarzComputing bridged electrodesT)r5   z8No EEG channels found, cannot compute electrode bridgingF)Úl_freqÚh_freqr<   r   )ÚdurationZpreloadr   )r<   .r   Nr    g   ¢”mBÚignore)Úinvalidc                    s   | ˆk r| dkrˆ | ƒS t jS )Nr   )r   Úinf)rA   ©ZkdeÚ	lm_cutoffr   r   Ú<lambda>$  ó    z,compute_bridged_electrodes.<locals>.<lambda>zLocal minimum z foundzBridge detected between z and )!Zscipy.statsr]   Zscipy.optimizer^   r   r4   r   rG   r   ÚRuntimeErrorÚfilterrN   r	   r   Úget_datar   r   r%   r"   ZzerosÚsizeÚnanÚrangeÚvarÚlistÚisnanZerrstaterP   rA   r   r   r8   Úappend)r3   rf   Zepoch_thresholdr_   r`   Zepoch_durationZ	bw_methodr   r]   r^   r<   r*   Zn_epochsZ	ed_matrixÚiÚjZbridged_idxZed_flatZlocal_minimumZbridged_countr   re   r   Úcompute_bridged_electrodesÀ   sN    :

 ÿ

<ÿ*ru   )r/   r0   r1   r2   T)rZ   r[   r[   r\   r   NN)Únumpyr   Ú r   Úutilsr   r   r   r   r   Úior	   Zio.constantsr
   rX   r   r   Zevokedr   Zbemr   Zchannels.interpolationr   r   r   r.   rY   ru   r   r   r   r   Ú<module>   s6        þþ 	         þ