U
    f»{j7/  ã                   @   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mZ dd	lmZmZ eG d
d„ deeƒƒZdS )é    Né   )Úfilter_data)Ú_regularized_covarianceé   )ÚTransformerMixinÚBaseEstimator)Úpsd_array_welch)Ú
_time_maskÚfill_docÚ_validate_typeÚ_check_option)Ú_get_channel_typesÚ_picks_to_idxc                   @   sL   e Zd ZdZddd„Zdd„ Zdd	d
„Zdd„ Zdd„ Zdd„ Z	dd„ Z
dS )ÚSSDu,  
    M/EEG signal decomposition using the Spatio-Spectral Decomposition (SSD).

    SSD seeks to maximize the power at a frequency band of interest while
    simultaneously minimizing it at the flanking (surrounding) frequency bins
    (considered noise). It extremizes the covariance matrices associated with
    signal and noise :footcite:`NikulinEtAl2011`.

    SSD can either be used as a dimensionality reduction method or a
    â€˜denoisedâ€™ low rank factorization method :footcite:`HaufeEtAl2014b`.

    Parameters
    ----------
    %(info_not_none)s Must match the input data.
    filt_params_signal : dict
        Filtering for the frequencies of interest.
    filt_params_noise : dict
        Filtering for the frequencies of non-interest.
    reg : float | str | None (default)
        Which covariance estimator to use.
        If not None (same as 'empirical'), allow regularization for
        covariance estimation. If float, shrinkage is used
        (0 <= shrinkage <= 1). For str options, reg will be passed to
        method to :func:`mne.compute_covariance`.
    n_components : int | None (default None)
        The number of components to extract from the signal.
        If n_components is None, no dimensionality reduction is applied.
    picks : array of int | None (default None)
        The indices of good channels.
    sort_by_spectral_ratio : bool (default False)
       If set to True, the components are sorted accordingly
       to the spectral ratio.
       See Eq. (24) in :footcite:`NikulinEtAl2011`.
    return_filtered : bool (default True)
        If return_filtered is True, data is bandpassed and projected onto
        the SSD components.
    n_fft : int (default None)
       If sort_by_spectral_ratio is set to True, then the SSD sources will be
       sorted accordingly to their spectral ratio which is calculated based on
       :func:`mne.time_frequency.psd_array_welch` function. The n_fft parameter
       set the length of FFT used.
       See :func:`mne.time_frequency.psd_array_welch` for more information.
    cov_method_params : dict | None (default None)
        As in :class:`mne.decoding.SPoC`
        The default is None.
    rank : None | dict | â€˜infoâ€™ | â€˜fullâ€™
        As in :class:`mne.decoding.SPoC`
        This controls the rank computation that can be read from the
        measurement info or estimated from the data.
        See Notes of :func:`mne.compute_rank` for details.
        We recommend to use 'full' when working with epoched data.

    Attributes
    ----------
    filters_ : array, shape (n_channels, n_components)
        The spatial filters to be multiplied with the signal.
    patterns_ : array, shape (n_components, n_channels)
        The patterns for reconstructing the signal from the filtered data.

    References
    ----------
    .. footbibliography::
    NTFc                 C   sŽ  ||dœ}dD ]j\}}d| }|d || krBt d|d |f ƒ‚|| |d  }t|ttfƒst|d|› d|› d�ƒ q|d |d ksš|d |d kr¢t d	ƒ‚t||d
dd�| _~t|| jdd�}t|ƒdkrât dt|ƒ ƒ‚|| _	|d |d f| _
|d |d f| _|| _|| _t|tƒ�s,t dƒ‚|| _|	dk�rNt| j	d ƒ| _n
t|	ƒ| _t|tƒ�slt dƒ‚|| _|| _|| _|| _|
| _dS )zInitialize instance.)ÚsignalÚnoise))Úlr   )Úhr   )r   r   )r   r   Z_freqz.%s must be defined in filter parameters for %s)Únumericú Zl_freqZh_freqz[Wrongly specified frequency bands!
The signal band-pass must be within the noise band-pass!ÚdataZbads)ÚnoneÚexcludeT)ÚpicksÚuniquer   zTAt this point SSD only supports fitting single channel types. Your info has %i typesz&sort_by_spectral_ratio must be booleanNÚsfreqzreturn_filtered must be boolean)Ú
ValueErrorÚ
isinstanceÚintÚfloatr   r   Úpicks_r   ÚlenÚinfoÚfreqs_signalÚfreqs_noiseÚfilt_params_signalÚfilt_params_noiseÚboolÚsort_by_spectral_ratioÚn_fftÚreturn_filteredÚregÚn_componentsÚrankÚcov_method_params)Úselfr"   r%   r&   r+   r,   r   r(   r*   r)   r.   r-   ZdictsÚparamÚddÚkeyÚvalZch_types© r4   úO/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/decoding/ssd.pyÚ__init__Q   sZ    

ÿÿÿþÿÿ

zSSD.__init__c                 C   sN   t |tjdƒ td|jdƒ |jd }|| jd krJtd|| jd f ƒ‚dS )zCheck input data.ÚXzX.ndim)r   é   éþÿÿÿZnchanzAInfo must match the input data.Found %i channels but expected %i.N)r   ÚnpZndarrayr   ÚndimÚshaper"   r   )r/   r7   Zn_chanr4   r4   r5   Ú_check_X…   s    
þzSSD._check_Xc                 C   s@  ddl m} |  |¡ |d| jdd…f }t|| jd f| jŽ}t|| jd f| jŽ}||8 }|jdkr|t	 
|¡}t	 
|¡}t|| j| j| j| jd�}t|| j| j| j| jd�}|||ƒ\}	}
t	 |	¡ddd… }|	| | _|
dd…|f | _t	j | j¡| _| jj|d| jdd…f  }t}| j�r6| j|d	�\}}|| _| S )
a  Estimate the SSD decomposition on raw or epoched data.

        Parameters
        ----------
        X : array, shape ([n_epochs, ]n_channels, n_times)
            The input data from which to estimate the SSD. Either 2D array
            obtained from continuous data or 3D array obtained from epoched
            data.
        y : None | array, shape (n_samples,)
            Used for scikit-learn compatibility.

        Returns
        -------
        self : instance of SSD
            Returns the modified instance.
        r   )Úeigh.Nr   r8   )r+   Zmethod_paramsr-   r"   éÿÿÿÿ)Ússd_sources)Zscipy.linalgr>   r=   r    r   r"   r%   r&   r;   r:   Zhstackr   r+   r.   r-   ÚargsortÚeigvals_Úfilters_ZlinalgZpinvÚ	patterns_ÚTÚEllipsisr(   Úget_spectral_ratioÚsorter_spec)r/   r7   Úyr>   ÚX_auxZX_signalZX_noiseZ
cov_signalZ	cov_noiserB   Z	eigvects_ZixÚX_ssdrH   Ú_r4   r4   r5   Úfit�   sX    
 ÿÿ ÿÿ


   þ   þ
zSSD.fitc                 C   s¼   |   |¡ | jdkrtdƒ‚| jrL|d| jdd…f }t|| jd f| jŽ}| jj|d| jdd…f  }|j	dkrˆ|| j
 d| j… }n0|dd…| j
dd…f dd…d| j…dd…f }|S )aÄ  Estimate epochs sources given the SSD filters.

        Parameters
        ----------
        X : array, shape ([n_epochs, ]n_channels, n_times)
            The input data from which to estimate the SSD. Either 2D array
            obtained from continuous data or 3D array obtained from epoched
            data.

        Returns
        -------
        X_ssd : array, shape ([n_epochs, ]n_components, n_times)
            The processed data.
        Nz+No filters available. Please first call fit.r   r   )r=   rC   ÚRuntimeErrorr*   r    r   r"   r%   rE   r;   rH   r,   )r/   r7   rJ   rK   r4   r4   r5   Ú	transformÄ   s    

ÿ
0zSSD.transformc           
      C   sì   t || jd | jd�\}}t|f| jžŽ }t|f| jžŽ }|jdkrš|dd…dd…|f jdd�jdd�}|dd…dd…|f jdd�jdd�}|| }n8|dd…|f jdd�}|dd…|f jdd�}|| }| ¡ ddd	… }	||	fS )
ad  Get the spectal signal-to-noise ratio for each spatial filter.

        Spectral ratio measure for best n_components selection
        See :footcite:`NikulinEtAl2011`, Eq. (24).

        Parameters
        ----------
        ssd_sources : array
            Data projected to SSD space.

        Returns
        -------
        spec_ratio : array, shape (n_channels)
            Array with the sprectal ratio value for each component.
        sorter_spec : array, shape (n_channels)
            Array of indices for sorting spec_ratio.

        References
        ----------
        .. footbibliography::
        r   )r   r)   r8   Nr   )Zaxisr   r   r?   )	r   r"   r)   r	   r#   r$   r;   ZmeanrA   )
r/   r@   ZpsdZfreqsZsig_idxZ	noise_idxZmean_sigZ
mean_noiseZ
spec_ratiorH   r4   r4   r5   rG   á   s       ÿ

&&
zSSD.get_spectral_ratioc                 C   s   t dƒ‚dS )zNot implemented yet.z'inverse_transform is not yet available.N)ÚNotImplementedError)r/   r4   r4   r5   Úinverse_transform  s    zSSD.inverse_transformc                 C   s.   |   |¡}| j| j d| j… j}|| }|S )a<  Remove selected components from the signal.

        This procedure will reconstruct M/EEG signals from which the dynamics
        described by the excluded components is subtracted
        (denoised by low-rank factorization).
        See :footcite:`HaufeEtAl2014b` for more information.

        .. note:: Unlike in other classes with an apply method,
           only NumPy arrays are supported (not instances of MNE objects).

        Parameters
        ----------
        X : array, shape ([n_epochs, ]n_channels, n_times)
            The input data from which to estimate the SSD. Either 2D array
            obtained from continuous data or 3D array obtained from epoched
            data.

        Returns
        -------
        X : array, shape ([n_epochs, ]n_channels, n_times)
            The processed data.
        N)rO   rD   rH   r,   rE   )r/   r7   rK   Zpick_patternsr4   r4   r5   Úapply
  s    
z	SSD.apply)NNNTFNNN)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r6   r=   rM   rO   rG   rQ   rR   r4   r4   r4   r5   r      s    A             ý
4

5%r   )Únumpyr:   Úfilterr   Zcovr   Ú r   r   Ztime_frequencyr   Úutilsr	   r
   r   r   Zio.pickr   r   r   r4   r4   r4   r5   Ú<module>   s   