U
    f»{jH  ã                	   @   sT  d dl mZ d dlZddl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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lmZm Z m!Z!m"Z" ddl#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z) ddl*m+Z+m,Z, ddl-m.Z.m/Z/ dd„ Z0dd„ Z1dd„ Z2dd„ Z3d*dd„Z4d+dd„Z5e%d,d"d#„ƒZ6e%d-d&dd'œd(d)„ƒZ7dS ).é    )ÚdeepcopyNé   )Ú_check_origin)Úmake_ad_hoc_cov)ÚFIFF)Ú
pick_typesÚ	pick_info)Ú_simplify_info)Ú_has_eeg_average_ref_projÚmake_projector)Úget_head_surfÚget_meg_helmet_surf)Útransform_surface_toÚ
read_transÚ_find_transÚ_ensure_transé   )Ú_create_meg_coilsÚ_create_eeg_elsÚ_read_coil_defs)Ú_do_self_dotsÚ_do_surface_dotsÚ_get_legen_tableÚ_do_cross_dots)ÚloggerÚverboseÚ_check_optionÚ	_reg_pinvÚ_plÚ	path_like)ÚEpochsArrayÚ
BaseEpochs)ÚEvokedÚEvokedArrayc                 C   sx   ddl m} d}t|tdddd�ƒ}| dkr0d	nd
\}}t|d|dd�\}	}
|t dd|	jd ¡|	|dd�}||||
fS )zSet up dot products.r   )Úinterp1dg¸…ëQ¸®?g›+¡†›„=gê-�™—a=g�íµ ÷Æ°>)ÚmagÚgradÚeegÚfast)é2   Znearest)éd   ZlinearF©r   éÿÿÿÿr   ©Zaxis)Zscipy.interpolater$   r   Údictr   ÚnpZlinspaceÚshape)ÚmodeÚinfoÚcoilsÚch_typer$   Úint_radÚnoiseZn_coeffÚinterpZlutÚn_factÚlut_fun© r:   ú_/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/forward/_field_interpolation.pyÚ_setup_dots   s     r<   c                 C   sZ  t  d¡ | d }| dtƒ ¡}t||ƒd }t |jt | d |¡¡}| d }|d s\t‚t 	dt 
|d	  ¡ ¡ ¡}t |jt ||¡¡}|  d
d¡dkr¶t|| d ƒ\}	| d< n.| d
 dksÎt| d
 ƒ‚t|| d ƒ\}	| d< t |jt |	|¡¡}
|j|
 }t | d |¡}| d dk�rVt|ƒ�rVt  d|jd › d�¡ |tj|dd�8 }|S )zDo the hairy computations.z#    Preparing the mapping matrix...Úch_namesÚprojsr   Ú	self_dotsr6   Údiagç      ð?ÚdataÚpinv_methodÚtsvdÚmissÚnestÚtikhonovÚsurface_dotsÚkindr'   z0    The map has an average electrode reference (z
 channels)r-   )r   r2   ÚgetÚlistr   r/   ÚdotÚTÚNotImplementedErrorr@   ÚsqrtZravelÚ_pinv_truncÚAssertionErrorÚ_pinv_tikhonovr
   r0   Zmean)Úfmdr2   r=   r>   Zproj_opZ	proj_dotsZ	noise_covZwhitenerZwhitened_dotsÚinvZinv_whitenedZinv_whitened_projZmapping_matr:   r:   r;   Ú_compute_mapping_matrix)   s.    

ÿrU   c           	   
   C   s¸   ddl m} |j| dd�\}}}t |¡}||d  }t |d| k¡d d d }t d|t|ƒ|d||d   f ¡ d|d	|…  }|d	d	…d	|…f | |d	|…  j	}||fS )
zDCompute pseudoinverse, truncating at most "miss" fraction of varexp.r   )ÚlinalgF)Zfull_matricesr,   rA   r   z?    Truncating at %d/%d components to omit less than %g (%0.2g)N)
ZscipyrV   Zsvdr/   ZcumsumÚwherer   r2   ÚlenrM   )	ÚxrE   rV   ÚuÚsÚvZvarexpÚnrT   r:   r:   r;   rP   U   s    
ÿ&rP   c              	   C   s>   t | |d d�\}}}t d|› dt| ƒ› d|d›�¡ ||fS )N)ÚregZrankz    Truncating at ú/u%    components and regularizing with Î±=z0.1e)r   r   r2   rX   )rY   r^   rT   Ú_r]   r:   r:   r;   rR   e   s    "rR   c                 C   s  t dd„ |d D ƒƒ}|t dd„ | d D ƒƒO }tj|krZ|t tjgƒO }|t tjgƒ8 }t|ƒ}t|ƒdkr‚|d tjtjfks†t‚|d tjkr˜dnd}|dkrätd	d
�}t	| d d| d |ƒ}t	|d d|d |ƒ}	d}
d}nDt
| d ƒ}t
|d ƒ}	d}
d}t| d ƒ�r(t|d ƒ�s(tdƒ‚t|| ƒ}t|| ||ƒ\}}}}t dt|ƒ› d| ¡ › dt|ƒ› d�¡ t|d	|||||dd�}t dt|ƒ› dt|	ƒ› d| ¡ › dt|	ƒ› d�	¡ t|d	||	||||ƒj}dd„ | d D ƒ}t|||||||||
d�	}t|| ƒ}|S )aú  Find mapping from one set of channels to another.

    Parameters
    ----------
    info_from : instance of Info
        The measurement data to interpolate from.
    info_to : instance of Info
        The measurement info to interpolate to.
    mode : str
        Either `'accurate'` or `'fast'`, determines the quality of the
        Legendre polynomial expansion used. `'fast'` should be sufficient
        for most applications.
    origin : array-like, shape (3,) | str
        Origin of the sphere in the head coordinate frame and in meters.
        Can be ``'auto'``, which means a head-digitization-based origin
        fit. Default is ``(0., 0., 0.04)``.

    Returns
    -------
    mapping : array, shape (n_to, n_from)
        A mapping matrix.
    c                 s   s   | ]}|d  V  qdS ©rI   Nr:   ©Ú.0Úchr:   r:   r;   Ú	<genexpr>†   s     z+_map_meg_or_eeg_channels.<locals>.<genexpr>Úchsc                 s   s   | ]}|d  V  qdS ra   r:   rb   r:   r:   r;   re   ‡   s     r   r   r'   ÚmegFr+   ÚnormalÚ
dev_head_trD   ç-Cëâ6?rG   gš™™™™™¹?r>   zIinfo_to must have an average EEG reference projector if info_from has onez    Computing dot products for ú z channelz...N)Ún_jobsz!    Computing cross products for u    â†’ c                 S   s   g | ]}|d  ‘qS )Úch_namer:   )rc   Úcr:   r:   r;   Ú
<listcomp>µ   s     z,_map_meg_or_eeg_channels.<locals>.<listcomp>)	rI   r=   Úoriginr6   r?   rH   r5   rE   rC   )Úsetr   ZFIFFV_REF_MEG_CHZFIFFV_MEG_CHÚsortedrX   ZFIFFV_EEG_CHrQ   r   r   r   r
   ÚRuntimeErrorr   r<   r   r2   Úupperr   r   r   rM   r.   rU   )Ú	info_fromÚinfo_tor1   rp   rE   Z
info_kindsrI   Z	templatesZ
coils_fromZcoils_torC   r5   r6   r9   r8   r?   Z
cross_dotsr=   rS   Úmappingr:   r:   r;   Ú_map_meg_or_eeg_channelsm   s‚    
 ÿ


 ÿ
 ÿ
ÿÿ
   ÿ*  ÿ4
   ÿ    ý
rx   r&   r(   c                 C   s²  t d|ddgƒ t| jdddd�}t| j|ddd�}t|ƒdkrHtdƒ‚t| j|ƒ}t| j|ƒ}t||d	|d
�}t| dƒr„|  ¡ }n| j	}|j
}	|	dkr°|tjdd…dd…f }tj|jd t|ƒ|jd f|jd�}
t||
ƒD ] \}}t ||| ¡|dd…< qàt| j|dd�}|d D ]}|d  d7  < �q| ¡  | ¡  t| tƒ�r‚|	dk�s\t‚|
d }
t|
|| jd | j| jd�}n,t| tƒ�s’t‚t|
|| j| j| j| j d�}|S )al  Compute virtual evoked using interpolated fields in mag/grad channels.

    Parameters
    ----------
    inst : instance of mne.Evoked or mne.Epochs
        The evoked or epochs object.
    ch_type : str
        The destination channel type. It can be 'mag' or 'grad'.
    mode : str
        Either `'accurate'` or `'fast'`, determines the quality of the
        Legendre polynomial expansion used. `'fast'` should be sufficient
        for most applications.

    Returns
    -------
    inst : instance of mne.EvokedArray or mne.EpochsArray
        The transformed evoked object containing only virtual channels.
    r4   r%   r&   TF©rg   r'   Zref_megr   zÛNo channels matching the destination channel type found in info. Please pass an evoked containingboth the original and destination channels. Only the locations of the destination channels will be used for interpolation.©ç        r{   g{®Gáz¤?)rp   r1   Úget_datar   N)Údtype)ÚselÚcopyrf   rm   Ú_v)ÚtminÚcommentÚnave)r�   ÚeventsÚevent_idÚmetadata)!r   r   r2   rX   Ú
ValueErrorr   rx   Úhasattrr|   rB   Úndimr/   ZnewaxisÚemptyr0   r}   ÚziprL   Z_update_redundantZ_check_consistencyÚ
isinstancer"   rQ   r#   Útimesr‚   rƒ   r!   r    r�   r„   r…   r†   )Úinstr4   r1   Z	pick_fromZpick_toru   rv   rw   rB   r‰   Zdata_ÚdZd_r2   rd   Zinst_r:   r:   r;   Ú_as_meg_type_instÂ   s^    
ÿ
ÿ   ÿ

ÿ ÿ
ýr�   rg   rz   c                    sô  t ‡ fdd„dD ƒƒstdƒ‚dˆ kr.tdƒ‚td|dd	gƒ ˆ }ttˆ ƒd
|ƒ‰ t|| ƒ}td|ddgƒ |dkr�t| dddd�}	t d¡ nt| dddd�}	t d¡ t	|	ƒdkr¾t
dƒ‚| d }
tt| ƒ|	ƒ} |
| d< |dk�rt| d d| d ƒ}d}d}nt| d ƒ}d}d}t|| ||ƒ\}}}}t dt	|ƒ|f ¡ t|d||||||ƒ}t t	ˆ d ƒ¡}t dt	|ƒ ¡ t|d|ˆ ||||||ƒ
}t|ˆ | d |||||||d �
}t d!¡ t|| ƒ|d"< ||d#< |d$= |d%= |d&= |d'= |S )(a  Re-map M/EEG data to a surface.

    Parameters
    ----------
    %(info_not_none)s
    surf : dict
        The surface to map the data to. The required fields are `'rr'`,
        `'nn'`, and `'coord_frame'`. Must be in head coordinates.
    ch_type : str
        Must be either `'meg'` or `'eeg'`, determines the type of field.
    trans : None | dict
        If None, no transformation applied. Should be a Head<->MRI
        transformation.
    mode : str
        Either `'accurate'` or `'fast'`, determines the quality of the
        Legendre polynomial expansion used. `'fast'` should be sufficient
        for most applications.
    %(n_jobs)s
    origin : array-like, shape (3,) | str
        Origin of the sphere in the head coordinate frame and in meters.
        The default is ``'auto'``, which means a head-digitization-based
        origin fit.
    %(verbose)s

    Returns
    -------
    mapping : array
        A n_vertices x n_sensors array that remaps the MEG or EEG data,
        as `new_data = np.dot(mapping, data)`.
    c                 3   s   | ]}|ˆ kV  qd S )Nr:   )rc   Úkey©Úsurfr:   r;   re   2  s     z(_make_surface_mapping.<locals>.<genexpr>)ÚrrÚnnz!surf must have both "rr" and "nn"Zcoord_framezEThe surface coordinate frame must be specified in surf["coord_frame"]r1   Zaccurater(   Úheadr4   rg   r'   TFry   zPrepare MEG mapping...zPrepare EEG mapping...r   zcannot map, no channels foundri   rf   rh   r3   rj   Z
electrodesgü©ñÒMbP?z#Computing dot products for %i %s...r”   z2Computing dot products for %i surface locations...r=   )
rI   r“   r=   r3   rp   r6   r?   rH   r5   rE   zField mapping data readyrB   r“   r?   rH   r5   rE   )ÚallÚKeyErrorr   r   r   r   r   r   r2   rX   rs   r   r	   r   r   r<   r   r/   Zaranger   r.   rU   )r2   r“   r4   Útransr1   rl   rp   r   Z	orig_surfZpicksri   r3   Ztype_strrE   r5   r6   r9   r8   r?   r~   rH   rS   r:   r’   r;   Ú_make_surface_mapping  sx    !


  ÿÿ   þ    þ
rš   ÚautoÚhelmet)Úbemr–   )Úhead_sourcer   c	             
      s<  ˆ j }|dkr"‡ fdd„dD ƒ}ntd|ddgƒ |g}|dkrJt||ƒ}d|krn|dkrnt  d	¡ | d¡ t|ƒd
kr‚tdƒ‚|dk	r¨t|tƒrœt	|ƒ}t
|ddƒ}td|ddgƒ g }|D ]8}|dkrà|dkràt||ƒ}nt||	|d�}| |¡ qÀtƒ }t||ƒD ],\}}tˆ j ||||||d�}| |¡ �q
|S )a7  Compute surface maps used for field display in 3D.

    Parameters
    ----------
    evoked : Evoked | Epochs | Raw
        The measurement file. Need to have info attribute.
    trans : str | 'auto' | None
        The full path to the ``*-trans.fif`` file produced during
        coregistration. If present or found using 'auto'
        the maps will be in MRI coordinates.
        If None, map for EEG data will not be available.
    subject : str | None
        The subject name corresponding to FreeSurfer environment
        variable SUBJECT. If None, map for EEG data will not be available.
    subjects_dir : str
        The path to the freesurfer subjects reconstructions.
        It corresponds to Freesurfer environment variable SUBJECTS_DIR.
    ch_type : None | 'eeg' | 'meg'
        If None, a map for each available channel type will be returned.
        Else only the specified type will be used.
    mode : 'accurate' | 'fast'
        Either ``'accurate'`` or ``'fast'``, determines the quality of the
        Legendre polynomial expansion used. ``'fast'`` should be sufficient
        for most applications.
    meg_surf : 'helmet' | 'head'
        Should be ``'helmet'`` or ``'head'`` to specify in which surface
        to compute the MEG field map. The default value is ``'helmet'``.
    origin : array-like, shape (3,) | 'auto'
        Origin of the sphere in the head coordinate frame and in meters.
        Can be ``'auto'``, which means a head-digitization-based origin
        fit. Default is ``(0., 0., 0.04)``.

        .. versionadded:: 0.11
    %(n_jobs)s
    %(head_source)s

        .. versionadded:: 1.1
    %(verbose)s

    Returns
    -------
    surf_maps : list
        The surface maps to be used for field plots. The list contains
        separate ones for MEG and EEG (if both MEG and EEG are present).
    Nc                    s   g | ]}|ˆ kr|‘qS r:   r:   )rc   Út©Úevokedr:   r;   ro   ´  s      z"make_field_map.<locals>.<listcomp>)r'   rg   r4   r'   rg   r›   z*No trans file available. EEG data ignored.r   zNo data available for mapping.r–   ZmriÚmeg_surfrœ   )ÚsourceÚsubjects_dir)rl   rp   r1   )r2   r   r   r   ÚremoverX   rs   rŒ   r   r   r   r   r   ÚappendrK   r‹   rš   )r¡   r™   Úsubjectr¤   r4   r1   r¢   rp   rl   rž   r   r2   ÚtypesZsurfsZ	this_typer“   Z	surf_mapsZ	this_surfZthis_mapr:   r    r;   Úmake_field_map  sJ    2



  ÿ
  þr©   )N)r&   r(   )rg   Nr(   Nrz   N)r›   NNNr(   rœ   rz   N)8r   r   Únumpyr/   r�   r   Zcovr   Zio.constantsr   Zio.pickr   r   Zio.meas_infor	   Zio.projr
   r   Zsurfacer   r   Z
transformsr   r   r   r   Z_make_forwardr   r   r   Z
_lead_dotsr   r   r   r   Úutilsr   r   r   r   r   r   Zepochsr    r!   r¡   r"   r#   r<   rU   rP   rR   rx   r�   rš   r©   r:   r:   r:   r;   Ú<module>	   sJ    ,
U
O      ÿm         þ ý