U
    f»{jcE  ã                   @   s¼   d dl mZ d dlmZ 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mZmZmZ dd	lmZmZmZ dd
d„Zdd„ Zeddd„ƒZddd„Zddd„Zdd„ Zdd„ ZdS ) é    )Úisgenerator)Ú
namedtupleNé   )ÚSourceEstimate)Ú
BaseEpochs)ÚEvokedÚEvokedArray)ÚloggerÚ_reject_data_segmentsÚwarnÚfill_doc)Ú
pick_typesÚ	pick_infoÚ_picks_to_idxc                    sÔ  |dkr dd„ t |jd ƒD ƒ}tˆ tƒr–tˆ jddddddddgd�	}‡ fd	d„|D ƒˆ jkrhtd
ƒ d}ˆ  ¡ }t	t
 |jdd… ¡ˆ jˆ jƒ}nxtˆ ƒrÈd}tˆ ƒ}t
 |jgdd„ ˆ D ƒ ¡}nFtˆ tƒ�rtˆ d tƒ�rd}ˆ d }t
 dd„ ˆ D ƒ¡}ntdƒ‚t |dt
 |jdd… ¡t|ƒf  ¡ t|||ƒ}tddƒ}i }	|D ]n‰‡fdd„|D ƒ}
t|
ƒD ]@\}}| ¡ }t|ttfƒ�sœtdƒ‚||jdd…< ||
|< �qt||
Ž |	ˆ< �qVt d¡ |	S )u  Fit Ordinary Least Squares (OLS) regression.

    Parameters
    ----------
    inst : instance of Epochs | iterable of SourceEstimate
        The data to be regressed. Contains all the trials, sensors, and time
        points for the regression. For Source Estimates, accepts either a list
        or a generator object.
    design_matrix : ndarray, shape (n_observations, n_regressors)
        The regressors to be used. Must be a 2d array with as many rows as
        the first dimension of the data. The first column of this matrix will
        typically consist of ones (intercept column).
    names : array-like | None
        Optional parameter to name the regressors (i.e., the columns in the
        design matrix). If provided, the length must correspond to the number
        of columns present in design matrix (including the intercept, if
        present). Otherwise, the default names are ``'x0'``, ``'x1'``,
        ``'x2', â€¦, 'x(n-1)'`` for ``n`` regressors.

    Returns
    -------
    results : dict of namedtuple
        For each regressor (key), a namedtuple is provided with the
        following attributes:

            - ``beta`` : regression coefficients
            - ``stderr`` : standard error of regression coefficients
            - ``t_val`` : t statistics (``beta`` / ``stderr``)
            - ``p_val`` : two-sided p-value of t statistic under the t
              distribution
            - ``mlog10_p_val`` : -logâ‚�â‚€-transformed p-value.

        The tuple members are numpy arrays. The shape of each numpy array is
        the shape of the data minus the first dimension; e.g., if the shape of
        the original data was ``(n_observations, n_channels, n_timepoints)``,
        then the shape of each of the arrays will be
        ``(n_channels, n_timepoints)``.
    Nc                 S   s   g | ]}d | ‘qS )zx%i© ©Ú.0Úir   r   úS/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/stats/regression.pyÚ
<listcomp>=   s     z%linear_regression.<locals>.<listcomp>é   TFZbads)ZmegZeegZref_megZstimZeogZecgZemgÚexcludec                    s   g | ]}ˆ j | ‘qS r   )Úch_names©r   Úp)Úinstr   r   r   C   s     z?Fitting linear model to non-data or bad channels. Check pickingzFitting linear model to epochsz:Fitting linear model to source estimates (generator input)c                 S   s   g | ]
}|j ‘qS r   ©Údatar   r   r   r   r   L   s     r   z5Fitting linear model to source estimates (list input)c                 S   s   g | ]
}|j ‘qS r   r   r   r   r   r   r   P   s     z4Input must be epochs or iterable of source estimatesz, (%s targets, %s regressors)Úlmz$beta stderr t_val p_val mlog10_p_valc                    s   g | ]}|ˆ  ‘qS r   r   r   )Únamer   r   r   Z   s     zInvalid container.ÚDone)ÚrangeÚshapeÚ
isinstancer   r   Úinfor   r   Úget_datar   ÚnpZzerosÚtminr   ÚnextÚarrayr   Úlistr   Ú
ValueErrorr	   ÚproductÚlenÚ_fit_lmr   Ú	enumerateÚcopyr   ÚRuntimeErrorÚ_data)r   Údesign_matrixÚnamesÚpicksÚmsgr   ÚoutZ	lm_paramsr   Zlm_fitsÚ
parametersÚiiÚvalueZout_r   )r   r   r   Úlinear_regression   sR    '
   þ"ÿ

r;   c                 C   sX  ddl m}m} t| ƒ}t | jdd… ¡}|jdkr>tdƒ‚|j\}}||krXtdƒ‚|t|ƒkrltdƒ‚t 	| ||f¡}	|j
||	d	�\}
}}}|| }t || ¡ 	| jdd… ¡}| t |j|¡¡}t t |¡¡}t tj¡j}d
d„ tdƒD ƒ\}}}}}t|
||ƒD �]4\}}}| 	| jdd… ¡||< || ||< t || ¡||< t || ¡||< || dk}|| dk}|| | || |  || |< |j t || | ¡|¡}t d| d |d¡|| |< | |@ }tjt || | ¡ || |< ||| |< | | @ }d|| |< d|| |< t || ¡ ||< �q|||||fS )zAux function.r   )ÚstatsÚlinalgr   Nr   z Design matrix must be a 2d arrayzGNumber of rows in design matrix must be equal to number of observationszLNumber of regressor names must be equal to number of column in design matrix)ÚaÚbc                 s   s   | ]}t ƒ V  qd S )N)Údict)r   Ú_r   r   r   Ú	<genexpr>~   s     z_fit_lm.<locals>.<genexpr>é   ç      ð?g       @)Úscipyr<   r=   r-   r&   r,   r"   Úndimr+   ZreshapeZlstsqÚsqrtÚinvÚdotÚTZdiagZfinfoZfloat64Útinyr!   ÚzipZ
empty_likeÚtÚcdfÚabsZclipÚinfÚsignÚlog10)r   r3   r4   r<   r=   Ú	n_samplesZ
n_featuresZn_rowsZn_predictorsÚyZbetasZresid_sum_squaresrA   ZdfZsqrt_noise_varZdesign_invcovZunscaled_stderrsrK   ÚbetaÚstderrZt_valZp_valZmlog10_p_valÚxZunscaled_stderrZ	predictorZ
stderr_posZbeta_posrN   Úmaskr   r   r   r.   f   sL    



ÿ
 r.   çš™™™™™¹¿r   rD   Úcholeskyc              	      s  ddl m‰  t|tƒrB|dkr,td |¡ƒ‚|dkrT‡ fdd„}nt|ƒrLntdƒ‚t| ||
|	d	�\}}}|d
kr�dd„ t	|d
d
…df ƒD ƒ}t
|jd |d |||||d�\}}}}}t|||||	||ƒ\}}|||jƒ}|jd |jd krútdƒ‚t||||||ƒ}|S )aS  Estimate regression-based evoked potentials/fields by linear modeling.

    This models the full M/EEG time course, including correction for
    overlapping potentials and allowing for continuous/scalar predictors.
    Internally, this constructs a predictor matrix X of size
    n_samples * (n_conds * window length), solving the linear system
    ``Y = bX`` and returning ``b`` as evoked-like time series split by
    condition. See :footcite:`SmithKutas2015`.

    Parameters
    ----------
    raw : instance of Raw
        A raw object. Note: be very careful about data that is not
        downsampled, as the resulting matrices can be enormous and easily
        overload your computer. Typically, 100 Hz sampling rate is
        appropriate - or using the decim keyword (see below).
    events : ndarray of int, shape (n_events, 3)
        An array where the first column corresponds to samples in raw
        and the last to integer codes in event_id.
    event_id : dict | None
        As in Epochs; a dictionary where the values may be integers or
        iterables of integers, corresponding to the 3rd column of
        events, and the keys are condition names.
        If None, uses all events in the events array.
    tmin : float | dict
        If float, gives the lower limit (in seconds) for the time window for
        which all event types' effects are estimated. If a dict, can be used to
        specify time windows for specific event types: keys correspond to keys
        in event_id and/or covariates; for missing values, the default (-.1) is
        used.
    tmax : float | dict
        If float, gives the upper limit (in seconds) for the time window for
        which all event types' effects are estimated. If a dict, can be used to
        specify time windows for specific event types: keys correspond to keys
        in event_id and/or covariates; for missing values, the default (1.) is
        used.
    covariates : dict-like | None
        If dict-like (e.g., a pandas DataFrame), values have to be array-like
        and of the same length as the rows in ``events``. Keys correspond
        to additional event types/conditions to be estimated and are matched
        with the time points given by the first column of ``events``. If
        None, only binary events (from event_id) are used.
    reject : None | dict
        For cleaning raw data before the regression is performed: set up
        rejection parameters based on peak-to-peak amplitude in continuously
        selected subepochs. If None, no rejection is done.
        If dict, keys are types ('grad' | 'mag' | 'eeg' | 'eog' | 'ecg')
        and values are the maximal peak-to-peak values to select rejected
        epochs, e.g.::

            reject = dict(grad=4000e-12, # T / m (gradiometers)
                          mag=4e-11, # T (magnetometers)
                          eeg=40e-5, # V (EEG channels)
                          eog=250e-5 # V (EOG channels))

    flat : None | dict
        For cleaning raw data before the regression is performed: set up
        rejection parameters based on flatness of the signal. If None, no
        rejection is done. If a dict, keys are ('grad' | 'mag' |
        'eeg' | 'eog' | 'ecg') and values are minimal peak-to-peak values to
        select rejected epochs.
    tstep : float
        Length of windows for peak-to-peak detection for raw data cleaning.
    decim : int
        Decimate by choosing only a subsample of data points. Highly
        recommended for data recorded at high sampling frequencies, as
        otherwise huge intermediate matrices have to be created and inverted.
    %(picks_good_data)s
    solver : str | callable
        Either a function which takes as its inputs the sparse predictor
        matrix X and the observation matrix Y, and returns the coefficient
        matrix b; or a string.
        X is of shape (n_times, n_predictors * time_window_length).
        y is of shape (n_channels, n_times).
        If str, must be ``'cholesky'``, in which case the solver used is
        ``linalg.solve(dot(X.T, X), dot(X.T, y))``.

    Returns
    -------
    evokeds : dict
        A dict where the keys correspond to conditions and the values are
        Evoked objects with the ER[F/P]s. These can be used exactly like any
        other Evoked object, including e.g. plotting or statistics.

    References
    ----------
    .. footbibliography::
    r   ©r=   >   rZ   zNo such solver: {}rZ   c                    s*   | j |   ¡ }ˆ j|| j | dddd�j S )NÚposT)Zassume_aZoverwrite_aZoverwrite_b)rJ   ZtoarrayZsolve)ÚXrT   r>   r[   r   r   Úsolverù   s
     ÿz%linear_regression_raw.<locals>.solverz'The solver must be a str or a callable.)r5   ÚdecimNc                 S   s   i | ]}t |ƒ|“qS r   )Ústr)r   Úvr   r   r   Ú
<dictcomp>  s      z)linear_regression_raw.<locals>.<dictcomp>r   r   Úsfreq)rS   rc   ÚeventsÚevent_idr'   ÚtmaxÚ
covariatesz�solver output has unexcepted shape. Supply a function that returns coefficients in the form (n_targets, n_features), where targets == channels.)rE   r=   r#   r`   r+   ÚformatÚcallableÚ	TypeErrorÚ_prepare_rerp_dataÚsetÚ_prepare_rerp_predsr"   Ú_clean_rerp_inputrJ   Ú_make_evokeds)Úrawrd   re   r'   rf   rg   ÚrejectÚflatÚtstepr_   r5   r^   r   r$   r]   ÚcondsÚcond_lengthÚtmin_sÚtmax_sÚcoefsÚevokedsr   r[   r   Úlinear_regression_raw˜   s:    \
ÿ     þrz   c              	   C   s  t | j|ƒ}t| j|ƒ}t|ƒ}| ¡ � |d  |  < W 5 Q R X | dd… \}}||dd|…f }tt|dd…df ƒƒt|dd…df ƒk rštdƒ‚| ¡ }|dd…df  | j	8  < |dd…df  |  < tt|dd…df ƒƒt|dd…df ƒk �r
tdƒ‚|||fS )z?Prepare events and data, primarily for `linear_regression_raw`.rc   Nr   zj`events` contains duplicate time points. Make sure all entries in the first column of `events` are unique.zâAfter decimating, `events` contains duplicate time points. This means some events are too closely spaced for the requested decimation factor. Choose different events, drop close events, or choose a different decimation factor.)
r   r$   r   ÚintZ_unlockr-   rl   r+   r0   Z
first_samp)rp   rd   r5   r_   r$   r   Útimesr   r   r   rk     s    
,.rk   c                    sö  ddl m} t|ƒ}|dk	r(|t|ƒ7 }tˆttfƒrL‡ ‡fdd„|D ƒ}	n‡ ‡fdd„|D ƒ}	tˆttfƒr„‡ ‡fdd„|D ƒ}
n‡ ‡fdd„|D ƒ}
tƒ }g }|D �]8}|	| |
|  }}t|| ƒ}||k�r.t|| tƒrì|| gn|| }|t |dd…d	f |¡df |  }t 	t
|ƒ|f¡}nŠ|| }t
|ƒt
|ƒk�rZd
 |¡}t|ƒ‚|t |dk¡df | d  }t |¡t |¡  t¡}t 	t
|ƒ|f¡|dd…tjf  }t
|ƒ||< | |j||f| |fd�¡ q¦| |¡|||	|
fS )zBBuild predictor matrix and metadata (e.g. condition time windows).r   )ÚsparseNc                    s   i | ]}|t tˆˆ  ƒƒ“qS r   ©r{   Úround©r   Úcond©rc   r'   r   r   rb   D  s      z'_prepare_rerp_preds.<locals>.<dictcomp>c              	      s&   i | ]}|t tˆ |d ¡ˆ  ƒƒ“qS )rY   ©r{   r   Úgetr€   r‚   r   r   rb   F  s   ÿ c                    s"   i | ]}|t tˆˆ  ƒd  ƒ“qS )r   r~   r€   ©rc   rf   r   r   rb   I  s     c              	      s*   i | ]"}|t tˆ |d ¡ˆ  ƒƒd “qS )rD   r   rƒ   r€   r…   r   r   rb   L  s   ÿ r   zFCondition {0} from ``covariates`` is not the same length as ``events``)r"   )rE   r}   r*   r#   Úfloatr{   r@   r&   Zin1dZonesr-   rh   r+   ÚwhereZasarrayÚnonzeroZastypeZnewaxisÚappendZ
dia_matrixZhstack)rS   rc   rd   re   r'   rf   rg   r}   rt   rv   rw   ru   Zxsr�   Útmin_Útmax_Zn_lagsZidsZonsetsÚvaluesZcovsÚerrorra   r   )rc   rf   r'   r   rm   9  sT    ÿÿÿ


ÿþ&ÿ $ÿ
rm   c                 C   sn   t  |  ¡ d ¡}|dk	rRt|||d||d�\}}	|	D ]\}
}t  |t|
|ƒ¡}q6|  ¡ | |dd…|f fS )zDRemove empty and contaminated points from data & predictor matrices.r   N)r_   r$   rs   )r&   Úuniquerˆ   r
   Z	setdiff1dr!   Ztocsr)r]   r   rq   rr   r_   r$   rs   Zhas_valrA   ZindsÚt0Út1r   r   r   rn   s  s    
 ÿ
rn   c              	   C   sv   t ƒ }d}|D ]b}|| ||  }	}
t| dd…|||
 |	 …f |||	t|d ƒ || dd�||< ||
|	 7 }q|S )zsCreate a dictionary of Evoked objects.

    These will be created from a coefs matrix and condition durations.
    r   Nrc   Zaverage)r$   Úcommentr'   ZnaveÚkind)r@   r   r†   )rx   rt   ru   rv   rw   r$   ry   Zcumulr�   rŠ   r‹   r   r   r   ro   ‚  s       ý
ro   )N)
NrY   r   NNNrD   r   NrZ   )Nr   )NrY   r   N)Úinspectr   Úcollectionsr   Únumpyr&   Zsource_estimater   Zepochsr   Zevokedr   r   Úutilsr	   r
   r   r   Zio.pickr   r   r   r;   r.   rz   rk   rm   rn   ro   r   r   r   r   Ú<module>	   s6   
Q2             þ 
    ÿ
: