U
    f»{j«0 ã                   @   s  d dl m Z  d dlmZ d dlZd dlZd dlZd dlZd dlmZ	 d dl
Z
ddlmZm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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$m%Z%m&Z& ddl'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/ ddl0m1Z1 ddl2m3Z3m4Z4 ddl5m6Z6 ddl7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z= ddl>m?Z?m@Z@ ddlAmBZB ddlCmDZDmEZEmFZF ddlGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZPmQZQmRZRmSZSmTZTmUZUmVZV ddlWmXZX G dd„ deYƒZZdd„ Z[dd„ Z\dd„ Z]ePd d!„ ƒZ^d"d#„ Z_eOdZd$d%„ƒZ`eOd[d'd(„ƒZaeOd\d+d,„ƒZbeOd]d-d.„ƒZcd/d0„ Zdd^d1d2„ZeePd3d4„ ƒZfd_d5d6„Zgd`d8d9„ZheOdad:d;„ƒZid<d=„ ZjeOdbdAdB„ƒZkdcdEdF„ZldGdH„ ZmeOdddIdJ„ƒZneOdedKdL„ƒZoeOdfdMdN„ƒZpePdgdPdQ„ƒZqdRdS„ ZrdTdU„ ZsdhdVdW„ZteOdidXdY„ƒZudS )jé    )Útime)ÚdeepcopyN)Úpathé   )ÚRawArrayÚInfo)ÚFIFF)Ú	fiff_open)Údir_tree_find)Úfind_tagÚread_tag)Ú_read_named_matrixÚ_transpose_named_matrixÚwrite_named_matrix)Ú_read_bad_channelsÚ
write_infoÚ_write_ch_infosÚ_read_extended_ch_infoÚ_make_ch_names_mappingÚ_rename_list)Úpick_channels_forwardÚ	pick_infoÚpick_channelsÚ
pick_types)Ú	write_intÚstart_blockÚ	end_blockÚwrite_coord_transÚwrite_name_listÚwrite_stringÚstart_and_end_fileÚwrite_id)ÚBaseRaw)ÚEvokedÚEvokedArray)Ú
BaseEpochs)Ú_read_source_spaces_from_treeÚfind_source_space_hemiÚ_set_source_space_verticesÚ_write_source_spaces_to_fidÚ_get_src_nnÚ_src_kind_dict)Ú_BaseVectorSourceEstimateÚ_BaseSourceEstimate)Ú_normal_orth)Útransform_surface_toÚinvert_transformÚwrite_trans)Ú_check_fnameÚget_subjects_dirÚ	has_mne_cÚwarnÚrun_subprocessÚcheck_fnameÚloggerÚverboseÚfill_docÚ_validate_typeÚ_check_compensation_gradeÚ_check_optionÚ_check_stc_unitsÚ_stamp_to_dtÚ_on_missing)ÚLabelc                   @   sF   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zed
d„ ƒZ	ddd„Z
dS )ÚForwardu  Forward class to represent info from forward solution.

    Like :class:`mne.Info`, this data structure behaves like a dictionary.
    It contains all metadata necessary for a forward solution.

    .. warning::
        This class should not be modified or created by users.
        Forward objects should be obtained using
        :func:`mne.make_forward_solution` or :func:`mne.read_forward_solution`.

    Attributes
    ----------
    ch_names : list of str
        A convenience wrapper accessible as ``fwd.ch_names`` which wraps
        ``fwd['info']['ch_names']``.

    See Also
    --------
    mne.make_forward_solution
    mne.read_forward_solution

    Notes
    -----
    Forward data is accessible via string keys using standard
    :class:`python:dict` access (e.g., ``fwd['nsource'] == 4096``):

        source_ori : int
            The source orientation, either ``FIFF.FIFFV_MNE_FIXED_ORI`` or
            ``FIFF.FIFFV_MNE_FREE_ORI``.
        coord_frame : int
            The coordinate frame of the forward solution, usually
            ``FIFF.FIFFV_COORD_HEAD``.
        nsource : int
            The number of source locations.
        nchan : int
            The number of channels.
        sol : dict
            The forward solution, with entries:

            ``'data'`` : ndarray, shape (n_channels, nsource * n_ori)
                The forward solution data. The shape will be
                ``(n_channels, nsource)`` for a fixed-orientation forward and
                ``(n_channels, nsource * 3)`` for a free-orientation forward.
            ``'row_names'`` : list of str
                The channel names.
        mri_head_t : instance of Transform
            The mri â†” head transformation that was used.
        info : instance of :class:`~mne.Info`
            The measurement information (with contents reduced compared to that
            of the original data).
        src : instance of :class:`~mne.SourceSpaces`
            The source space used during forward computation. This can differ
            from the original source space as:

            1. Source points are removed due to proximity to (or existing
               outside)
               the inner skull surface.
            2. The source space will be converted to the ``coord_frame`` of the
               forward solution, which typically means it gets converted from
               MRI to head coordinates.
        source_rr : ndarray, shape (n_sources, 3)
            The source locations.
        source_nn : ndarray, shape (n_sources, 3)
            The source normals. Will be all +Z (``(0, 0, 1.)``) for volume
            source spaces. For surface source spaces, these are normal to the
            cortical surface.
        surf_ori : int
            Whether ``sol`` is surface-oriented with the surface normal in the
            Z component (``FIFF.FIFFV_MNE_FIXED_ORI``) or +Z in the given
            ``coord_frame`` in the Z component (``FIFF.FIFFV_MNE_FREE_ORI``).

    Forward objects also have some attributes that are accessible via ``.``
    access, like ``fwd.ch_names``.
    c                 C   s   t t| ƒƒS )zCopy the Forward instance.)rB   r   ©Úself© rE   úR/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/forward/forward.pyÚcopy‚   s    zForward.copyc                 C   s*  t  dd„ | d D ƒ¡}|dk ¡ r2d| d  }n²|dk ¡ rLd| d  }n˜|d	k ¡ rfd
| d  }n~d}|dk ¡ rŠ|d|dk ¡  7 }|dk ¡ rª|d|dk ¡  7 }|d	k ¡ rÊ|d|d	k ¡  7 }| d¡}d|| d f }| d tjkrød}n*| d tjk�rd}n| d tj	k�r"d}||fS )Nc                 S   s   g | ]}|d  ‘qS )ÚtyperE   ©Ú.0ÚsrcrE   rE   rF   Ú
<listcomp>‡   s     z:Forward._get_src_type_and_ori_for_repr.<locals>.<listcomp>rK   ÚsurfzSurface with %d verticesÚnsourceÚvolzVolume with %d grid pointsÚdiscretezDiscrete with %d dipolesÚ z%d surface, z%d volume, z%d discrete, z, zMixed (%s) with %d verticesÚ
source_oriÚUnknownZFixedZFree)
ÚnpÚarrayÚallÚanyÚsumÚrstripr   ZFIFFV_MNE_UNKNOWN_ORIÚFIFFV_MNE_FIXED_ORIÚFIFFV_MNE_FREE_ORI)rD   Ú	src_typesÚsrc_typeZcount_stringÚsrc_orirE   rE   rF   Ú_get_src_type_and_ori_for_repr†   s6    
ÿ

ÿz&Forward._get_src_type_and_ori_for_reprc                 C   sˆ   d}t t| d ddg d�ƒ}|dd|  7 }t t| d ddg d�ƒ}|dd|  7 }|  ¡ \}}|d	|› �7 }|d
|› �7 }|d7 }|S )z/Summarize forward info instead of printing all.z<ForwardÚinfoTF)ÚmegÚeegÚexcludez | zMEG channels: %dzEEG channels: %dz | Source space: z | Source orientation: ú>)Úlenr   r_   )rD   ZentrÚnchanr]   r^   rE   rE   rF   Ú__repr__¥   s    zForward.__repr__c           	      C   sL   ddl m} | d  ¡ \}}}}|  ¡ \}}| d¡}|j||||d�}|S )Nr   )Úrepr_templates_envr`   zforward.html.jinja)Zgood_channelsZbad_channelsZsource_space_descrZsource_orientation)Zhtml_templatesrh   Z_get_chs_for_reprr_   Zget_templateÚrender)	rD   rh   Zgood_chsZbad_chsÚ_Z	src_descrr^   ÚtÚhtmlrE   rE   rF   Ú_repr_html_µ   s    
üzForward._repr_html_c                 C   s   | d d S )Nr`   Úch_namesrE   rC   rE   rE   rF   rn   Â   s    zForward.ch_namesFc                 C   s   t | |g |ddd�S )aç  Pick channels from this forward operator.

        Parameters
        ----------
        ch_names : list of str
            List of channels to include.
        ordered : bool
            If true (default False), treat ``include`` as an ordered list
            rather than a set.

        Returns
        -------
        fwd : instance of Forward.
            The modified forward model.

        Notes
        -----
        Operates in-place.

        .. versionadded:: 0.20.0
        F)rc   ÚorderedrG   r9   )r   )rD   rn   ro   rE   rE   rF   r   Æ   s
     þzForward.pick_channelsN)F)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rG   r_   rg   rm   Úpropertyrn   r   rE   rE   rE   rF   rB   6   s   K
rB   c           
      C   sê   ddl m} | | ¡rtdƒ‚| j\}}|t|ƒ }|| dkrHtdƒ‚tj|| tj	d� 
||¡}t |d|f¡}| ¡ }tj|tj	d�ddd…f }|tj|tj	d�dd…df  }|j ¡ }| | j ¡ tj||f jf¡ ¡ }	|	S )a  Construct a block diagonal from a packed structure.

    You have to try it on a matrix to see what it's doing.

    If A is not sparse, then returns a sparse block diagonal "bd",
    diagonalized from the
    elements in "A".
    "A" is ma x na, comprising bdn=(na/"n") blocks of submatrices.
    Each submatrix is ma x "n", and these submatrices are
    placed down the diagonal of the matrix.

    If A is already sparse, then the operation is reversed, yielding
    a block
    row matrix, where each set of n columns corresponds to a block element
    from the block diagonal.

    Parameters
    ----------
    A : array
        The matrix
    n : int
        The block size
    Returns
    -------
    bd : scipy.sparse.spmatrix
        The block diagonal matrix
    r   ©Úsparsez#sparse reversal not implemented yetz'Width of matrix must be a multiple of n©Zdtypeé   N)Úscipyrv   ÚissparseÚNotImplementedErrorÚshapeÚintÚ
ValueErrorrT   ÚarangeZint64ÚreshapeÚtileÚravelÚonesÚTZ
coo_matrixZc_Ztocsc)
ÚAÚnrv   ÚmaÚnaZbdnÚtmpÚiiZjjZbdrE   rE   rF   Ú_block_diagá   s    

 
$r‹   c                 C   s2   t | ||ƒ}|dkr(|  ¡  t|d ƒ‚t|jƒS )z!Check we have an appropriate tag.Nz tag not found)r   Úcloser~   r}   Údata)ÚfidÚnodeÚnameZid_ÚtagrE   rE   rF   Ú_get_tag_int  s
    r’   c                 C   sÚ  |dkrdS t ƒ }t| |dtjƒ|d< t| |dtjƒ|d< t| |dtjƒ|d< t| |dtjƒ|d	< z.t| |tjd
d�|d< |d d  	¡ |d< W n  t
k
r°   t d¡ ‚ Y nX z2tj}t| ||d
d�|d< |d d  	¡ |d< W n t
k
�r   d|d< Y nX |d d jd |d	 k�s\|d d jd |d k�rd|d d jd d|d  k�rdtdƒ‚|d dk	�rÖ|d d jd |d	 k�sÎ|d d jd d|d  k�rÖ|d d jd d|d  k�rÖtdƒ‚|S )z4Read all interesting stuff for one forward solution.NzSource orientationrR   zCoordinate frameÚcoord_framezNumber of sourcesrN   zNumber of channelsrf   T)Z	transposeÚsolr�   Ú	_orig_solzForward solution data not foundÚsol_gradÚ_orig_sol_gradr   rx   é   z,Forward solution matrix has wrong dimensionsé	   z5Forward solution gradient matrix has wrong dimensions)rB   r’   r   ÚFIFF_MNE_SOURCE_ORIENTATIONÚFIFF_MNE_COORD_FRAMEÚFIFF_MNE_SOURCE_SPACE_NPOINTSÚ
FIFF_NCHANr   ÚFIFF_MNE_FORWARD_SOLUTIONrG   Ú	Exceptionr8   ÚerrorÚFIFF_MNE_FORWARD_SOLUTION_GRADr|   r~   )rŽ   r�   ÚoneZfwd_typerE   rE   rF   Ú	_read_one  s\    ÿÿÿÿþ

ÿ
ÿþÿþr£   c                    s¼  t ƒ ‰ dˆ _t| tjƒ}t|ƒdkr,tdƒ‚|d }t||tjƒ}|dk	rP|j	ndˆ d< t||tj
ƒ}|dk	rt|j	ndˆ d< t| tjƒ}t|ƒdkrœtdƒ‚|d }t||tjƒ}|dk	rÀ|j	ndˆ d< t||tj
ƒ}|dk	rä|j	ndˆ d< tƒ  ˆ d	< }t|d
 ƒD ]D}|d | j}|d | j}|tjk�rt||ƒ}| |j	¡ �qt|||ƒ}	ˆ  ¡  t||tjƒ}tj}
tj}tj}tj}|dk�r˜tdƒ‚|j	}|d |k�rÄ|d |
k�rÄ|ˆ d< ntdƒ‚t||tjƒ}|dk�rìtdƒ‚|j	}|d |k�r|d |
k�r|ˆ d< n.|d |k�r>|d |
k�r>|ˆ d< ntdƒ‚t|||	d�ˆ d< ‡ fdd„ˆ d D ƒˆ d< t||tjƒ}|dk�r–t||dƒ}|dk	�rªt|j	ƒndˆ d< dˆ _ˆ S )zØRead light measurement info from forward operator.

    Parameters
    ----------
    tree : tree
        FIF tree structure.
    fid : file id
        The file id.

    Returns
    -------
    %(info_not_none)s
    Tr   z+No parent MEG information found in operatorNÚmri_fileÚmri_idÚ	meas_fileÚmeas_idÚchsZnentÚ	directoryú,MRI/head coordinate transformation not foundÚfromÚtoÚ
mri_head_tz,MEG/head coordinate transformation not foundÚ
dev_head_tÚ
ctf_head_t)Úch_names_mappingÚbadsc                    s   g | ]}|ˆ d  kr|‘qS ©rn   rE   )rJ   Úbad©r`   rE   rF   rL   œ  s      z+_read_forward_meas_info.<locals>.<listcomp>éì   FZcustom_ref_applied)r   Z	_unlockedr
   r   ÚFIFFB_MNE_PARENT_MRI_FILEre   r~   r   ÚFIFF_MNE_FILE_NAMEr�   ÚFIFF_PARENT_FILE_IDÚFIFFB_MNE_PARENT_MEAS_FILEÚlistÚrangeÚkindÚposZFIFF_CH_INFOr   Úappendr   Z_update_redundantÚFIFF_COORD_TRANSÚFIFFV_COORD_HEADÚFIFFV_COORD_MRIZFIFFV_COORD_DEVICEZFIFFV_MNE_COORD_CTF_HEADr   ZFIFF_MNE_CUSTOM_REFr}   )ÚtreerŽ   Ú
parent_mrir‘   Z
parent_megr¨   Úkr¼   r½   r°   Z
coord_headZ	coord_mriZcoord_deviceZcoord_ctf_headÚcandrE   r´   rF   Ú_read_forward_meas_infoK  sv    





  ÿ

rÆ   c                 C   s
   | d j S )z%Get subject id from inverse operator.rK   )Z_subject)ÚforwardrE   rE   rF   Ú_subject_from_forward¨  s    rÈ   c                 C   sº  | dk	�r¢|dk	�r¢| d d j d |d d j d ksh| d |d ksh| d |d ksh| d |d krptdƒ‚| }tj|d d |d d f |d d< tj|d	 |d	 f |d	< |d d
 |d d
  |d d
< |d d |d d  |d d< |d dk	�r‚tj|d d |d d f |d d< tj|d |d f |d< |d d
 |d d
  |d d
< |d d |d d  |d d< |d |d  |d< t d¡ n| dk	�r²| }n|}|S )z5Merge loaded MEG and EEG forward dicts into one dict.Nr”   r�   rx   rR   rN   r“   z.The MEG and EEG forward solutions do not matchr•   ÚnrowÚ	row_namesr–   r—   rf   z*    MEG and EEG forward solutions combined)r|   r~   rT   Zr_r8   r`   )ÚmegfwdÚeegfwdr9   ÚfwdrE   rE   rF   Ú_merge_meg_eeg_fwds­  sF    $ÿþý& 

ÿ
ÿ
ÿ


ÿ

ÿ
rÎ   rE   c                 C   sL  t | ddƒ t| ddd�} t d|  ¡ t| ƒ\}}}|��ª}t|tjƒ}t|ƒdkrbt	d|  ƒ‚t|tj
ƒ}	t|	ƒdkr†t	d	|  ƒ‚|	d }	t||d
d�}
|
D ]}t|ƒ|d< q d}d}d}tt|ƒƒD ]R}t||| tjƒ}|dkrðt	dƒ‚|jtjk�r|| }qÊ|jtjkrÊ|| }qÊt||ƒ}|dk	�rbt|ƒ�rBd}nd}t d|d |d |f ¡ t||ƒ}|dk	�r¦t|ƒ�r†d}nd}t d|d |d |f ¡ t||ƒ}t||	tjƒ}|dk�rÐt	dƒ‚|j}|d tjk�sö|d tjk�r.t|ƒ}|d tjk�s|d tjk�r.| ¡  t	dƒ‚||d< t||ƒ|d< t|tjƒ}t|ƒdk�râ|d }t||tjƒ}|dk	�r¤|d  ¡ � |j|d d< W 5 Q R X t||tjƒ}|dk	�râ|d  ¡ � |j|d d< W 5 Q R X W 5 Q R X |d tjtjfk�r
t	dƒ‚d}|
D ]X}zt ||d |ƒ}W n0 t!k
�rZ } zt	d| ƒ‚W 5 d}~X Y nX ||d 7 }�q||d k�r‚t	d ƒ‚t d!¡ |
|d"< t"j#d#d$„ |
D ƒdd%�|d&< |d' |d(< t$|||d
d)� t|dd*��rt"j#d+d$„ |d" D ƒdd%�|d,< tj%|d'< d|d-< n6t" &t" '|d d.f¡t" (d/¡¡|d,< tj)|d'< d
|d-< t*|ƒS )0a^  Read a forward solution a.k.a. lead field.

    Parameters
    ----------
    fname : str
        The file name, which should end with -fwd.fif or -fwd.fif.gz.
    include : list, optional
        List of names of channels to include. If empty all channels
        are included.
    exclude : list, optional
        List of names of channels to exclude. If empty include all
        channels.
    %(verbose)s

    Returns
    -------
    fwd : instance of Forward
        The forward solution.

    See Also
    --------
    write_forward_solution, make_forward_solution

    Notes
    -----
    Forward solutions, which are derived from an original forward solution with
    free orientation, are always stored on disk as forward solution with free
    orientation in X/Y/Z RAS coordinates. To apply any transformation to the
    forward operator (surface orientation, fixed orientation) please apply
    :func:`convert_forward_solution` after reading the forward solution with
    :func:`read_forward_solution`.

    Forward solutions, which are derived from an original forward solution with
    fixed orientation, are stored on disk as forward solution with fixed
    surface-based orientations. Please note that the transformation to
    surface-based, fixed orientation cannot be reverted after loading the
    forward solution with :func:`read_forward_solution`.
    rÇ   ©z-fwd.fifz-fwd.fif.gzz_fwd.fifz_fwd.fif.gzTÚread)ÚfnameZ
must_existÚ	overwritez#Reading forward solution from %s...r   zNo forward solutions in %szNo parent MRI information in %sF)Zpatch_statsÚidNz3Methods not listed for one of the forward solutionsÚfixedÚfreezH    Read MEG forward solution (%d sources, %d channels, %s orientations)rN   rf   zH    Read EEG forward solution (%d sources, %d channels, %s orientations)rª   r«   r¬   r­   r`   Úworking_dirÚcommand_liner“   zIOnly forward solutions computed in MRI or head coordinates are acceptableú%Could not transform source space (%s)Únusez0Source spaces do not match the forward solution.zF    Source spaces transformed to the forward solution coordinate framerK   c                 S   s$   g | ]}|d  |d dd…f ‘qS )ZrrÚvertnoNrE   ©rJ   ÚssrE   rE   rF   rL   t  s   ÿz)read_forward_solution.<locals>.<listcomp>©ÚaxisÚ	source_rrrR   Ú_orig_source_ori)Úincluderc   rG   ©Úorigc                 S   s$   g | ]}|d  |d dd…f ‘qS )ÚnnrÚ   NrE   )rJ   Z_srcrE   rE   rF   rL   ~  s   ÿÚ	source_nnÚsurf_orirx   r˜   )+r7   r2   r8   r`   r	   r
   r   ÚFIFFB_MNE_FORWARD_SOLUTIONre   r~   r¶   r&   r'   r»   r   ÚFIFF_MNE_INCLUDED_METHODSr�   ÚFIFFV_MNE_MEGÚFIFFV_MNE_EEGr£   Úis_fixed_orientrÎ   r¿   rÁ   rÀ   r0   rŒ   rÆ   ÚFIFFB_MNE_ENVÚFIFF_MNE_ENV_WORKING_DIRÚ_unlockÚFIFF_MNE_ENV_COMMAND_LINEr/   rŸ   rT   Úconcatenater   rZ   Úkronrƒ   Úeyer[   rB   )rÑ   rá   rc   r9   ÚfrÂ   rj   rŽ   ÚfwdsrÃ   rK   ÚsrÍ   ZmegnodeZeegnoderÄ   r‘   rË   ZorirÌ   r­   Z
parent_envrÙ   ÚinstrE   rE   rF   Úread_forward_solutionÑ  sÊ    (




þ


þ

ÿÿ

"

ÿÿ

ÿÿ


$
r÷   FTc                    s   ddl m} |r|  ¡ n| } |dkr(d}tdd„ | d D ƒƒrJ|rJtdƒ‚|r‚ˆ r‚tdd	„ | d D ƒƒrtt d
¡ nd‰ t d¡ t| dd�sš|�rlˆ �sltj	‡ fdd„| d D ƒdd�| d< t| dd��sVt d¡ t
| d jdƒ}| d |  d¡| d d< | d | d d< | d dk	�rV| |gd ¡}| d | | d d< d| d  | d d< tj| d< d| d< �n†|�rZt t | d df¡t d¡¡| d< t d¡ d}	| d D ]b}
|
d  d!k�rüt|
ˆ ƒ}|	d|
d"   }t|ƒ d#d¡| d |	|…< |}	~n|	d|
d"  7 }	�q¬|�rÈ| d d$dd…dd…f | d< t
| d jdƒ}| d |  d¡| d d< | d | d d< | d dk	�r´| |gd ¡}| d | | d d< d| d  | d d< tj| d< d| d< n�t
| d jdƒ}| d | | d d< d| d  | d d< | d dk	�rF| |gd ¡}| d | | d d< d%| d  | d d< tj| d< d| d< n˜t d&¡ t t d¡| d df¡| d< | d  ¡ | d d< d| d  | d d< | d dk	�rà| d  ¡ | d d< d%| d  | d d< tj| d< d| d< t d'¡ | S )(a_  Convert forward solution between different source orientations.

    Parameters
    ----------
    fwd : Forward
        The forward solution to modify.
    surf_ori : bool, optional (default False)
        Use surface-based source coordinate system? Note that force_fixed=True
        implies surf_ori=True.
    force_fixed : bool, optional (default False)
        If True, force fixed source orientation mode.
    copy : bool
        Whether to return a new instance or modify in place.
    %(use_cps)s
    %(verbose)s

    Returns
    -------
    fwd : Forward
        The modified forward solution.
    r   ru   Tc                 S   s   g | ]}|d  dk‘qS )rH   rO   rE   rI   rE   rE   rF   rL   §  s     z,convert_forward_solution.<locals>.<listcomp>rK   zËForward operator was generated with sources from a volume source space. Conversion to fixed orientation is not possible. Consider using a discrete source space if you have meaningful normal orientations.c                 s   s   | ]}|  d ¡dk	V  qdS )Z
patch_indsN)Úget©rJ   rõ   rE   rE   rF   Ú	<genexpr>¯  s     z+convert_forward_solution.<locals>.<genexpr>z_    Average patch normals will be employed in the rotation to the local surface coordinates....Fz„    No patch info available. The standard source space normals will be employed in the rotation to the local surface coordinates....râ   c                    s   g | ]}t |ˆ ƒ‘qS rE   )r*   rù   ©Úuse_cpsrE   rF   rL   Ã  s   ÿrÝ   rå   z\    Changing to fixed-orientation forward solution with surface-based source orientations...rx   r•   Zfloat32r”   r�   rN   Úncolr–   Nr˜   r—   rR   ræ   z6    Converting to surface-based source orientations...rH   )rM   rP   rÙ   éÿÿÿÿr   r™   z$    Cartesian source orientations...z
    [done])ry   rv   rG   rW   r~   r8   r`   rë   rT   rð   r‹   r„   ZastypeZ
block_diagr   rZ   rñ   rƒ   rò   r*   r.   r€   r[   r�   )rÍ   ræ   Úforce_fixedrG   rü   r9   rv   Zfix_rotÚxÚpprõ   rä   ÚstopZsurf_rotrE   rû   rF   Úconvert_forward_solution‰  s¢    ÿ
ÿÿ

ÿÿ
$

ÿÿ






r  c              	   C   s8   t | ddƒ t| |ƒ} t| ƒ�}t||ƒ W 5 Q R X dS )aŠ  Write forward solution to a file.

    Parameters
    ----------
    fname : str
        File name to save the forward solution to. It should end with
        ``-fwd.fif`` or ``-fwd.fif.gz``.
    fwd : Forward
        Forward solution.
    %(overwrite)s
    %(verbose)s

    See Also
    --------
    read_forward_solution

    Notes
    -----
    Forward solutions, which are derived from an original forward solution with
    free orientation, are always stored on disk as forward solution with free
    orientation in X/Y/Z RAS coordinates. Transformations (surface orientation,
    fixed orientation) will be reverted. To reapply any transformation to the
    forward operator please apply :func:`convert_forward_solution` after
    reading the forward solution with :func:`read_forward_solution`.

    Forward solutions, which are derived from an original forward solution with
    fixed orientation, are stored on disk as forward solution with fixed
    surface-based orientations. Please note that the transformation to
    surface-based, fixed orientation cannot be reverted after loading the
    forward solution with :func:`read_forward_solution`.
    rÇ   rÏ   N)r7   r2   r    Ú_write_forward_solution)rÑ   rÍ   rÒ   r9   rŽ   rE   rE   rF   Úwrite_forward_solution  s    !

r  c                    s  t | tjƒ t | tjƒ t| tjƒ ˆ d  dd ¡}|d k	rJt| tj|ƒ ˆ d  dd ¡}|d k	rpt| tj	|ƒ t
| tjƒ t | tjƒ t| tjˆ d d ƒ ˆ d d d k	rÄt| tjˆ d d ƒ t| ˆ d d ƒ t
| tjƒ t| ˆ d ƒ tƒ }ˆ d D ]d}t|ƒ}zt|ˆ d d ˆ d ƒ}W n0 tk
�rV } ztd	| ƒ‚W 5 d }~X Y nX | |¡ qþt| |ƒ td
d„ |D ƒƒ}ˆ d tjk�r–|}nd| }ˆ d  ¡ }ˆ d d k	�rÆˆ d  ¡ }	nd }	ˆ d dk�rþˆ d tjk�rôtdtƒ n
tdtƒ tˆ d dddg d�}
tˆ d dddg d�}t|
ƒ}t|ƒ}‡ fdd„|
D ƒ}‡ fdd„|D ƒ}|dk�r6t||
 |||g d�}t|ƒ t | tj ƒ t!| tj"tj#ƒ t!| tj$ˆ d ƒ t!| tj%ˆ d ƒ t!| tj&|ƒ t!| tj'|ƒ t(| tj)|ƒ |	d k	�r*t|	|
 ||d |g d�}t|ƒ t(| tj*|ƒ t
| tj ƒ |dk�rt|| |||g d�}t|ƒ t | tj ƒ t!| tj"tj+ƒ t!| tj$ˆ d ƒ t!| tj%ˆ d ƒ t!| tj'|ƒ t!| tj&|ƒ t(| tj)|ƒ |	d k	�rt|	| ||d |g d�}t|ƒ t(| tj*|ƒ t
| tj ƒ t
| tjƒ d S )Nr`   rÖ   r×   r¤   r¥   r­   rK   r«   rØ   c                 S   s   g | ]}|d  ‘qS )rÙ   rE   rÛ   rE   rE   rF   rL   h  s     z+_write_forward_solution.<locals>.<listcomp>rà   r˜   r•   r–   r—   ræ   Ta  The forward solution, which is stored on disk now, is based on a forward solution with fixed orientation. Please note that the transformation to surface-based, fixed orientation cannot be reverted after loading the forward solution with read_forward_solution.a€  This forward solution is based on a forward solution with free orientation. The original forward solution is stored on disk in X/Y/Z RAS coordinates. Any transformation (surface orientation or fixed orientation) will be reverted. To reapply any transformation to the forward operator please apply convert_forward_solution after reading the forward solution with read_forward_solution.F©ra   rb   Zref_megrc   c                    s   g | ]}ˆ d  d | ‘qS ©r”   rÊ   rE   ©rJ   Úp©rÍ   rE   rF   rL   �  s     c                    s   g | ]}ˆ d  d | ‘qS r  rE   r  r
  rE   rF   rL   �  s     r   )r�   rÉ   rý   rÊ   Z	col_namesr“   ),r   r   Z	FIFFB_MNErì   r!   ZFIFF_BLOCK_IDrø   r   rí   rï   r   r¶   r·   r¸   r   Úwrite_forward_meas_inforº   r   r/   rŸ   r~   r¾   r)   rX   rZ   rG   r5   ÚRuntimeWarningr   re   Údictr   rç   r   rè   ré   r›   rš   rœ   r�   r   rž   r¡   rê   )rŽ   rÍ   r�   rK   rõ   rö   Zn_vertZn_colr”   r–   Z	picks_megZ	picks_eegZn_megZn_eegZrow_names_megZrow_names_eegZmeg_solutionZmeg_solution_gradZeeg_solutionZeeg_solution_gradrE   r
  rF   r  9  sÚ    ÿ
üùÿÿ
 ÿÿ
  þÿ
 ÿÿ
  þÿr  c                 C   s&   |r| d t jk}n| d t jk}|S )a|  Check if the forward operator is fixed orientation.

    Parameters
    ----------
    forward : instance of Forward
        The forward.
    orig : bool
        If True, consider the original source orientation.
        If False (default), consider the current source orientation.

    Returns
    -------
    fixed_ori : bool
        Whether or not it is fixed orientation.
    rà   rR   )r   rZ   )rÇ   rã   Z	fixed_orirE   rE   rF   rë   Â  s    rë   c                 C   s  |  ¡  t| tjƒ t| tj|d ƒ |d dk	rDt| tj|d ƒ | d| d¡¡}|dkrn|  	¡  t
dƒ‚t| |ƒ tƒ }d|krºt|d ƒ}t| tjt|d ƒƒ t| |d d|ƒ d	|k�r
t|d	 ƒd
k�r
t|d	 |ƒ}t| tjƒ t| tj|ƒ t| tjƒ t| tjƒ dS )z’Write measurement info stored in forward solution.

    Parameters
    ----------
    fid : file id
        The file id
    %(info_not_none)s
    r¦   r§   Nr®   r¯   z"Head<-->sensor transform not foundr¨   Fr±   r   )Ú_check_consistencyr   r   r¹   r   r·   r!   ZFIFF_PARENT_BLOCK_IDrø   rŒ   r~   r   r  r   r   r�   re   r   r   ZFIFFB_MNE_BAD_CHANNELSr   ZFIFF_MNE_CH_NAME_LISTr   )rŽ   r`   Z
meg_head_tr°   r±   rE   rE   rF   r  Ù  s*    

r  c           	         s  | d d }t |ƒ‰t ˆd ƒ‰ ˆdk	rJˆt ˆd ƒM ‰ˆ t ˆd ƒO ‰ ntˆd d�‰‡ ‡fdd„ˆd	 D ƒ}tˆd ƒtˆd ƒkr¢t‡fd
d„ˆd D ƒƒs¬t d¡ t| d ˆdƒ t|ƒ}t d| ¡ t| |d|d�} ‡fdd„|D ƒ}tˆ|ƒ}| d  	¡  | 	¡  | |fS )z-Prepare forward solution for inverse solvers.r”   rÊ   r±   NÚnames)r±   c                    s,   g | ]$}|d  ˆ kr|d  ˆkr|d  ‘qS )Úch_namerE   )rJ   Úc)Úall_badsÚall_ch_namesrE   rF   rL     s    þz*_select_orient_forward.<locals>.<listcomp>r¨   c                 3   s   | ]}|ˆ d  kV  qdS )r±   NrE   )rJ   Úb)Ú	noise_covrE   rF   rú     s     z)_select_orient_forward.<locals>.<genexpr>zQinfo["bads"] and noise_cov["bads"] do not match, excluding bad channels from bothr`   rÇ   z,Computing inverse operator with %d channels.T)ro   rG   c                    s   g | ]}ˆ d    |¡‘qS r²   ©Úindex©rJ   r�   r´   rE   rF   rL     s     )
Úsetr  re   rV   r8   r`   r<   r   r   r  )	rÇ   r`   r  rG   Zfwd_sol_ch_namesrn   Zn_chanZinfo_idxZinfo_pickedrE   )r  r  r`   r  rF   Ú_select_orient_forward  s.    ÿ
ÿ
r  Úautoc                    sŠ  t ˆ ttdfdƒ t |ttfdƒ ˆ }tˆ tƒr\tdˆ dƒ |dkrJd‰ n| jdkrXdnd	‰ td
d„ | D ƒƒ}tˆ tƒs’tˆ ƒ‰ ‡ fdd„|D ƒ‰ tˆ  	¡ ƒ}||krÂt
dt|ƒ› dt|ƒ› �ƒ‚|dkrðtdd„ ˆ  ¡ D ƒƒsît
d|› �ƒ‚n*|dk�rtdd„ ˆ  ¡ D ƒƒ�rt
dƒ‚~ˆ  ¡ D ]`\}}|dk�rT|dk�rTt
d|› d|› �ƒ‚d|  k�rldk�s$n t
d|› d|› �ƒ‚�q$ˆ S )NÚnumericÚlooserÔ   )r  Tç        Úsurfacegš™™™™™É?ç      ð?c                 s   s   | ]}t |d   V  qdS )rH   N)r+   rù   rE   rE   rF   rú   .  s     z _triage_loose.<locals>.<genexpr>c                    s   i | ]
}|ˆ “qS rE   rE   ©rJ   Úkey©r  rE   rF   Ú
<dictcomp>1  s      z!_triage_loose.<locals>.<dictcomp>zloose, if dict, must have keys z  to match the source space, got c                 s   s   | ]}|d kV  qdS ©r  NrE   ©rJ   ÚvrE   rE   rF   rú   :  s     z7When using fixed=True, loose must be 0. or "auto", got Fc                 s   s   | ]}|d kV  qdS r%  rE   r&  rE   rE   rF   rú   ?  s     z:If loose==0., then fixed must be True or "auto", got False)r  rP   rx   zYloose parameter has to be 1 or "auto" for non-surface/discrete source spaces, got loose["z"] = r   zloose (z) must be between 0 and 1, got )r;   Ústrr  ÚboolÚ
isinstancer=   r¼   r  ÚfloatÚkeysr~   ÚsortedrV   ÚvaluesrW   Úitems)rK   r  rÔ   Z
orig_looser\   Z
loose_keysr"  Z
this_looserE   r#  rF   Ú_triage_loose$  sL    

ÿÿ
ÿÿÿr0  c              	   C   sj  t | tdƒ | d d jd }t| d |ƒ}tj|tjd�}t| ƒrltdd„ | 	¡ D ƒƒrht
d	|f ƒ‚|S td
d„ | 	¡ D ƒƒr†|S | d sœt
d|f ƒ‚d}tƒ }| d D ]¶}t|d  }|| }	| |¡�s |	dkràd}
n|	dkrìdnd}
t d|
 d¡› d| d¡› d|	› �¡ d||< |d|d   }|||d…  |	9  < ||d |d…  |	9  < |}q®|S )a/  Compute orientation prior.

    Parameters
    ----------
    forward : instance of Forward
        Forward operator.
    %(loose)s
    %(verbose)s

    Returns
    -------
    orient_prior : ndarray, shape (n_sources,)
        Orientation priors.

    See Also
    --------
    compute_depth_prior
    rÇ   r”   r�   rx   rK   rw   c                 s   s   | ]}|d kV  qdS r%  rE   r&  rE   rE   rF   rú   i  s     z'compute_orient_prior.<locals>.<genexpr>zEloose must be 0. with forward operator with fixed orientation, got %sc                 s   s   | ]}|d kV  qdS )r   NrE   r&  rE   rE   rF   rú   m  s     ræ   z]Forward operator is not oriented in surface coordinates. loose parameter should be 1. not %s.r   rH   r   rÕ   r  rÔ   r  z	Applying é   z dipole orientations to é   z source spaces: Tr˜   rÙ   )r;   rB   r|   r0  rT   rƒ   Zfloat64rë   rW   r.  r~   rV   r  r+   rø   r8   r`   Úljust)rÇ   r  r9   Ú	n_sourcesZorient_priorÚstartZloggedrõ   Z	this_typeZ	use_looser�   r  rE   rE   rF   Úcompute_orient_priorO  s@    ÿþ(r6  c                 C   s”   t |d ƒ| jd kr4td| jd t |d ƒf ƒ‚dD ]B\}}}t|||dg d�}t |ƒdkr8t dt |ƒ|f ¡  qŒq8tdƒ td	ƒ}| | S )
z9Restrict gain matrix entries for optimal depth weighting.r¨   r   z;G.shape[0] (%d) and length of info["chs"] (%d) do not match))ÚgradFZplanar)ÚmagFz!magnetometer or axial gradiometer)FTZEEGFr  z    %d %s channelsz:Could not find MEG or EEG channels to limit depth channelsN)re   r|   r~   r   r8   r`   r5   Úslice)ÚGr`   ra   rb   r¼   ÚselrE   rE   rF   Ú_restrict_gain_matrix‰  s    ÿr<  çš™™™™™é?ç      $@Úspectralc	              
   C   sÞ  ddl m}	m}
 t| tdƒ |  dd¡}t| ƒ}| d d }t d¡ t||	dfd	d
ƒ t|t	t
fdƒ t|t	ƒr¤|dkrˆtd|f ƒ‚t||	ƒs¤tdt|ƒf ƒ‚|dk	r¸td|dƒ |dkrÌt||ƒ}n*|dkrö|
||d|dd�\}}t ||¡}|�s|dk�rXtj|d dd�}|�s<|dk�s<| dd¡jdd�}t ||dk ¡||dk< n>|jd ddf|_tjjt d||¡ddd�}|jd df|_|dk	�rÒ|�s¼|dk�r¼t |d¡}||d  }t d¡ d| }|dk	�r¶t |¡}|d }|dk�rd}|d | }nP|d }t|ƒ}|d ||d  k�rbt |||d  k¡d d }|| }|}t d |d t|ƒt ||d  ¡f ¡ d| }t d!||f ¡ t || d¡}|| }|�sÚ|dk�sÚt |d¡}|S )"aW  Compute depth prior for depth weighting.

    Parameters
    ----------
    forward : instance of Forward
        The forward solution.
    %(info_not_none)s
    exp : float
        Exponent for the depth weighting, must be between 0 and 1.
    limit : float | None
        The upper bound on depth weighting.
        Can be None to be bounded by the largest finite prior.
    limit_depth_chs : bool | 'whiten'
        How to deal with multiple channel types in depth weighting.
        The default is True, which whitens based on the source sensitivity
        of the highest-SNR channel type. See Notes for details.

        .. versionchanged:: 0.18
           Added the "whiten" option.
    combine_xyz : 'spectral' | 'fro'
        When a loose (or free) orientation is used, how the depth weighting
        for each triplet should be calculated.
        If 'spectral', use the squared spectral norm of Gk.
        If 'fro', use the squared Frobenius norm of Gk.

        .. versionadded:: 0.18
    noise_cov : instance of Covariance | None
        The noise covariance to use to whiten the gain matrix when
        ``limit_depth_chs='whiten'``.

        .. versionadded:: 0.18
    %(rank_none)s

        .. versionadded:: 0.18
    %(verbose)s

    Returns
    -------
    depth_prior : ndarray, shape (n_vertices,)
        The depth prior.

    See Also
    --------
    compute_orient_prior

    Notes
    -----
    The defaults used by the minimum norm code and sparse solvers differ.
    In particular, the values for MNE are::

        compute_depth_prior(..., limit=10., limit_depth_chs=True,
                            combine_xyz='spectral')

    In sparse solvers and LCMV, the values are::

        compute_depth_prior(..., limit=None, limit_depth_chs='whiten',
                            combine_xyz='fro')

    The ``limit_depth_chs`` argument can take the following values:

    * :data:`python:True` (default)
          Use only grad channels in depth weighting (equivalent to MNE C
          minimum-norm code). If grad channels aren't present, only mag
          channels will be used (if no mag, then eeg). This makes the depth
          prior dependent only on the sensor geometry (and relationship
          to the sources).
    * ``'whiten'``
          Compute a whitener and apply it to the gain matirx before computing
          the depth prior. In this case ``noise_cov`` must not be None.
          Whitening the gain matrix makes the depth prior
          depend on both sensor geometry and the data of interest captured
          by the noise covariance (e.g., projections, SNR).

          .. versionadded:: 0.18
    * :data:`python:False`
          Use all channels. Not recommended since the depth weighting will be
          biased toward whichever channel type has the largest values in
          SI units (such as EEG being orders of magnitude larger than MEG).
    r   )Ú
CovarianceÚcompute_whitenerrÇ   Úpatch_areasNr”   r�   z&Creating the depth weighting matrix...r  zCovariance or NoneÚlimit_depth_chsZwhitenz1limit_depth_chs, if str, must be "whiten", got %szEWith limit_depth_chs="whiten", noise_cov must be a Covariance, got %sFÚcombine_xyz)Úfror?  T)ZpcaÚrankr9   )rE  Fr   rÝ   rþ   r˜   rx   r  zsvj,svk->vjk)rx   r   )ÚordrÞ   z9    Patch areas taken into account in the depth weightingr   z    limit = %d/%d = %fz    scale = %g exp = %g)Zcovr@  rA  r;   rB   rø   rë   r8   r`   r(  r)  r*  r~   rH   r=   r<  rT   ÚdotrX   r€   Úminr|   ZlinalgZnormZeinsumÚrepeatÚsortre   ÚwhereÚsqrtÚminimum)rÇ   r`   ÚexpÚlimitrC  rD  r  rF  r9   r@  rA  rB  Zis_fixed_orir:  Zwhitenerrj   ÚdÚwÚwsZweight_limitZn_limitÚindÚscaleZdepth_priorrE   rE   rF   Úcompute_depth_prior�  sŠ    S
ÿ
ÿ
ÿ
ÿ
	 ÿ




ÿÿrV  Úraiseú$, likely due to forward calculationsc                 C   sŒ  t |tƒr|}nt |tƒst‚|j}~t| ƒt|ƒksNtdt| ƒt|ƒf ƒ‚g g g   }}}d }}	t| |ƒD ]|\}
}t 	|
d |¡}| 
t |
d |¡| ¡ |t|
d ƒ7 }t ||¡}| 
||	 ¡ |	t|ƒ7 }	| 
t |¡| ¡ qpt |¡}t |¡}t|ƒt|ƒ  k�r0tdd„ |D ƒƒk�s6n t‚tdd„ |D ƒƒ}t|ƒ}||k�r‚d|||dk�rnd	nd
|f }t||ƒ |||fS )zDSelect the vertex indices of a source space using a source estimate.zCMismatch between number of source spaces (%s) and STC vertices (%s)r   rÚ   c                 s   s   | ]}t |ƒV  qd S ©N©re   r&  rE   rE   rF   rú   _  s     z_stc_src_sel.<locals>.<genexpr>c                 s   s   | ]}t |ƒV  qd S rY  rZ  r&  rE   rE   rF   rú   a  s     z7Only %i of %i SourceEstimate %s found in source space%srx   ZvertexÚvertices)r*  rº   r-   ÚAssertionErrorr[  re   ÚRuntimeErrorÚziprT   Úintersect1dr¾   ÚsearchsortedrU   rð   rX   r@   )rK   ÚstcÚ
on_missingÚextrar[  Zsrc_selsZstc_selsZout_verticesZ
src_offsetZ
stc_offsetrõ   r'  Z	joint_selÚidxÚsrc_selÚstc_selZn_stcZn_jointÚmsgrE   rE   rF   Ú_stc_src_selG  s@    
ÿ

4
ÿþ
rh  c           	   
      sº   t | d ˆ d d ƒ}t| |ƒ} g | d< tƒ }t |¡}d||  }| jdd��> | jˆ d d	 | d	 tt|ƒt|ƒfƒd
|d |g d� W 5 Q R X ‡ fdd„| d D ƒ}|| }| |fS )z4Fill the measurement info of a Raw or Evoked object.rn   r”   rÊ   r±   g    €„.AT)Zcheck_afterr`   r§   r  g       @)r§   Zfile_idZ	meas_dateZhighpassZlowpassÚsfreqÚprojsc                    s   g | ]}ˆ d  d   |¡‘qS r  r  r  r
  rE   rF   rL   }  s     z*_fill_measurement_info.<locals>.<listcomp>)	r   r   r   rT   Úfloorrî   Úupdater?   r}   )	r`   rÍ   ri  r�   r;  ÚnowÚsecZusecÚorderrE   r
  rF   Ú_fill_measurement_infol  s"    

   þrp  c                 C   sN  t |tddƒ t | tdƒ t|tƒr8d}t| ddd�} nd}t| ƒsRt| d|d�} t |j	dk¡rjt
d	ƒ t|ƒ t| d
 ||d�\}}	}
| d d }t|	ƒt|j	ƒkr°tdƒn|	}	|j||…  ¡ }|j	|	d||…f  dt|ƒ¡}~|�r
| t|ƒ|jd d d¡}|dd…|f  t|ƒd¡}t d¡ t ||¡}t d¡ ||fS )z5Apply forward model and return data, times, ch_names.ra  ZSourceEstimaterÍ   TF)rÿ   ræ   )rÿ   rü   r   z™Source estimate only contains currents with positive values. Use pick_ori="normal" when computing the inverse to compute currents not current magnitudes.rK   ©rb  r”   r�   N.rþ   rx   r˜   z-Projecting source estimate to sensor space...z[done])r;   r-   rB   r*  r,   r  rë   rT   rV   r�   r5   r>   rh  re   r9  ÚtimesrG   r€   r|   r8   r`   rH  )rÍ   ra  r5  r  rb  rü   r9   Zvectorre  rf  rj   Zgainrr  Zstc_datar�   rE   rE   rF   Ú_apply_forwardƒ  s4    
ÿ 

rs  c                 C   s¬   t |tdƒ t | tdƒ | ¡  | d d D ]}||d kr,td| ƒ‚q,t| |||||d�\}	}
td|j ƒ}t|| ||	ƒ\}}	t	|	||
d	 d
d�}| 
|
¡ | ¡  |S )a  Project source space currents to sensor space using a forward operator.

    The sensor space data is computed for all channels present in fwd. Use
    pick_channels_forward or pick_types_forward to restrict the solution to a
    subset of channels.

    The function returns an Evoked object, which is constructed from
    evoked_template. The evoked_template should be from the same MEG system on
    which the original data was acquired. An exception will be raised if the
    forward operator contains channels that are not present in the template.

    Parameters
    ----------
    fwd : Forward
        Forward operator to use.
    stc : SourceEstimate
        The source estimate from which the sensor space data is computed.
    %(info_not_none)s
    start : int, optional
        Index of first time sample (index not time is seconds).
    stop : int, optional
        Index of first time sample not to include (index not time is seconds).
    %(use_cps)s

        .. versionadded:: 0.15
    %(on_missing_fwd)s
        Default is "raise".

        .. versionadded:: 0.18
    %(verbose)s

    Returns
    -------
    evoked : Evoked
        Evoked object with computed sensor space data.

    See Also
    --------
    apply_forward_raw: Compute sensor space data and return a Raw object.
    r`   rÇ   r”   rÊ   rn   z>Channel %s of forward operator not present in evoked_template.©rb  rü   r   r   rx   )Znave)r;   r   rB   r  r~   rs  r+  Útsteprp  r$   Z
_set_timesZ_update_first_last)rÍ   ra  r`   r5  r  rü   rb  r9   r  r�   rr  ri  ÚevokedrE   rE   rF   Úapply_forwardª  s"    +ÿÿ

rw  c              	   C   s¤   | d d D ]}||d krt d| ƒ‚qt| |||||d�\}	}
d|j }t|| ||	ƒ\}}	| ¡ � g |d< W 5 Q R X t|	|tt |
d | ¡ƒd	�}d
|_	|S )a  Project source space currents to sensor space using a forward operator.

    The sensor space data is computed for all channels present in fwd. Use
    pick_channels_forward or pick_types_forward to restrict the solution to a
    subset of channels.

    The function returns a Raw object, which is constructed using provided
    info. The info object should be from the same MEG system on which the
    original data was acquired. An exception will be raised if the forward
    operator contains channels that are not present in the info.

    Parameters
    ----------
    fwd : Forward
        Forward operator to use.
    stc : SourceEstimate
        The source estimate from which the sensor space data is computed.
    %(info_not_none)s
    start : int, optional
        Index of first time sample (index not time is seconds).
    stop : int, optional
        Index of first time sample not to include (index not time is seconds).
    %(on_missing_fwd)s
        Default is "raise".

        .. versionadded:: 0.18
    %(use_cps)s

        .. versionadded:: 0.21
    %(verbose)s

    Returns
    -------
    raw : Raw object
        Raw object with computed sensor space data.

    See Also
    --------
    apply_forward: Compute sensor space data and return an Evoked object.
    r”   rÊ   rn   z3Channel %s of forward operator not present in info.rt  r   rj  r   )Z
first_sampN)
r~   rs  ru  rp  rî   r   r}   rT   ÚroundZ
_projector)rÍ   ra  r`   r5  r  rb  rü   r9   r  r�   rr  ri  ÚrawrE   rE   rF   Úapply_forward_rawï  s    ,ÿÿ


 rz  Úignorec                 C   s<   t |tdƒ td|dƒ t| d ||d�\}}}~t| |ƒS )aÈ  Restrict forward operator to active sources in a source estimate.

    Parameters
    ----------
    fwd : instance of Forward
        Forward operator.
    stc : instance of SourceEstimate
        Source estimate.
    %(on_missing_fwd)s
        Default is "ignore".

        .. versionadded:: 0.18

    Returns
    -------
    fwd_out : instance of Forward
        Restricted forward operator.

    See Also
    --------
    restrict_forward_to_label
    rb  )r{  r5   rW  rK   rq  )r;   r(  r=   rh  Ú_restrict_forward_to_src_sel)rÍ   ra  rb  re  rj   r[  rE   rE   rF   Úrestrict_forward_to_stc.  s
    r}  c                    s†  t | ƒ}tjdd„ t| d ƒD ƒdd�‰ ˆ jdkr@ˆ jd dksDt‚ˆ jd | d	 ksZt‚ˆ d d …|f ‰ | d
 | |d
< t|ƒ|d	< t| ƒrÂ|}| d d k	rÀd|d d …d f  t 	d¡  
¡ }nRd|d d …d f  t 	d¡  
¡ }| d d k	�rd|d d …d f  t 	d¡  
¡ }| d | |d< | d d d d …|f |d d< | d d k	�rr| d d d d …|f |d d< t|ƒ|d d< t| dd��rÆ|}| d d k	�rd|d d …d f  t 	d¡  
¡ }nRd|d d …d f  t 	d¡  
¡ }| d d k	�rd|d d …d f  t 	d¡  
¡ }| d d d …|f |d< | d d k	�rV| d d d …|f |d< ‡ fdd„tt|d ƒƒD ƒ}t|d |ƒ |S )Nc                 S   s*   g | ]"\}}|gt |d  ƒ |d  g‘qS )rÚ   rZ  )rJ   Úsirõ   rE   rE   rF   rL   P  s   ÿz0_restrict_forward_to_src_sel.<locals>.<listcomp>rK   rþ   rÝ   r   r   rx   rN   rß   r–   r˜   r™   rå   r”   r�   rý   Trâ   r•   r—   c                    s    g | ]}ˆ d  ˆ d |k ‘qS )rx   r   rE   )rJ   r~  ©Zidx_selrE   rF   rL   u  s   ÿ)r   rT   rð   Ú	enumerateÚndimr|   r\  re   rë   r   r‚   r»   r(   )rÍ   re  Úfwd_outrd  Úidx_gradr[  rE   r  rF   r|  M  sL    

ÿÿ$""  $""
ÿr|  c                 C   sø  t  g t¡t  g t¡g}t|tƒs(|g}|D ]:}t|tddƒ |jdkrLdnd}t  || |j	¡||< q,dd„ |D ƒ}t
| ƒ}t  d¡|d	< d|d
< t  d¡|d< t  | d d jd df¡|d d< t  | d jd df¡|d< | d dk	�r0t  | d d jd df¡|d d< t  | d jd df¡|d< d|d d< | d d d }tdƒD �]œ}t  g t¡|d | d< d|d | d< | d | d  ¡ |d | d< |d | d  d¡ t  g gt¡|d | d< t  dg¡|d | d< t  | d | d || ¡}t  | d | d |¡}| d | d | }d|d | d |< |d | d  t|ƒ7  < t  |d | d ¡d |d | d< ||| 7 }t  |d	 | d	 | g¡|d	< |d
  t|ƒ7  < t| ƒ�r|}	| d dk	�rXd|dd…df  t  d¡  ¡ }
nRd|dd…df  t  d¡  ¡ }	| d dk	�rXd|dd…df  t  d¡  ¡ }
t  |d | d |	 g¡|d< t  |d d | d d dd…|	f g¡|d d< | d dk	�rèt  |d d | d d dd…|
f g¡|d d< |d d  t|	ƒ7  < t| dd��rD|}	| d dk	�r–d|dd…df  t  d¡  ¡ }
nRd|dd…df  t  d¡  ¡ }	| d dk	�r–d|dd…df  t  d¡  ¡ }
t  |d | d dd…|	f g¡|d< | d dk	�rTt  |d | d dd…|
f g¡|d< �qT|S )aQ  Restrict forward operator to labels.

    Parameters
    ----------
    fwd : Forward
        Forward operator.
    labels : instance of Label | list
        Label object or list of label objects.

    Returns
    -------
    fwd_out : dict
        Restricted forward operator.

    See Also
    --------
    restrict_forward_to_stc
    ÚlabelzLabel or listZlhr   rx   c                 S   s   g | ]}t  |¡‘qS rE   )rT   Úunique)rJ   Z	vert_hemirE   rE   rF   rL   š  s     z-restrict_forward_to_label.<locals>.<listcomp>)r   r˜   rß   rN   rå   r”   r�   r•   r–   Nr—   rý   rK   rÙ   r   rÚ   ZinuseZuse_trisZnuse_trir˜   r™   Zsol_radTrâ   )rT   rU   r}   r*  rº   r;   rA   Zhemir¾   r[  r   Zzerosr|   r»   rG   Úfillr_  r`  re   rL  Zvstackrë   r   r‚   Zhstack)rÍ   Úlabelsr[  r„  Úir‚  Znuse_lhre  rÚ   rd  rƒ  rE   rE   rF   Úrestrict_forward_to_label|  sœ    
$ÿÿ &

ÿ

$""ÿ"ÿ
ÿÿ$""ÿÿÿr‰  c              
   C   sú  t ƒ stdƒ‚t ¡ }|dkr*t |d¡}t||ƒ t| ddƒ t|t	ƒrbt 
|¡s˜td| ƒ‚n6t|tttfƒr�t |d¡}t||jƒ |}ntdƒ‚|dk	r°|dk	r°td	ƒ‚|dkrÈ|dkrÈtd
ƒ‚|dk	ròt|ddƒ t 
|¡sòtd| ƒ‚|dk	�rxt|t	ƒ�s`t|tƒ�rXt|ƒ}t |d¡}zt||ƒ W n tk
�rT   tdƒ‚Y nX ntdƒ‚t 
|¡�sxtd| ƒ‚|
�sŒ|	�sŒtdƒ‚t |¡\}}t |¡d dk�s¶tdƒ‚t |¡}|dk	�r t|t	ƒ�rô| ¡ dk�sìtdƒ‚dg}ndd| g}t|||fddƒD ](\}}}|dk	�rt|||d| ƒ �qdd| d|d |d!|g	}|dk	�rh|d"|g7 }|dk	�rº| ¡ �r~n0t d#|¡}|dk�r td$| ƒ‚d% | ¡ ¡}|d&|g7 }|dk	�rÌ||7 }|dk	�râ|d'|g7 }|dk	�rü|d(d)| g7 }|dk	�r|d*d)| g7 }|
�s&| d+¡ |	�s6| d,¡ |�rF| d-¡ |�rV| d.¡ |�rf| d/¡ |�rv| d0¡ t j! "¡ }t#|d1d2�}||d3< zPzt& d5| ¡ t'||d6� W n tk
�rÌ   ‚ Y nX t(t ||¡d7d8�}W 5 t$j%|d1d4� X |S )9a¥	  Calculate a forward solution for a subject using MNE-C routines.

    This is kept around for testing purposes.

    This function wraps to mne_do_forward_solution, so the mne
    command-line tools must be installed and accessible from Python.

    Parameters
    ----------
    subject : str
        Name of the subject.
    meas : Raw | Epochs | Evoked | str
        If Raw or Epochs, a temporary evoked file will be created and
        saved to a temporary directory. If str, then it should be a
        filename to a file with measurement information the mne
        command-line tools can understand (i.e., raw or evoked).
    fname : str | None
        Destination forward solution filename. If None, the solution
        will be created in a temporary directory, loaded, and deleted.
    src : str | None
        Source space name. If None, the MNE default is used.
    spacing : str
        The spacing to use. Can be ``'#'`` for spacing in mm, ``'ico#'`` for a
        recursively subdivided icosahedron, or ``'oct#'`` for a recursively
        subdivided octahedron (e.g., ``spacing='ico4'``). Default is 7 mm.
    mindist : float | str | None
        Minimum distance of sources from inner skull surface (in mm).
        If None, the MNE default value is used. If string, 'all'
        indicates to include all points.
    bem : str | None
        Name of the BEM to use (e.g., "sample-5120-5120-5120"). If None
        (Default), the MNE default will be used.
    mri : str | None
        The name of the trans file in FIF format.
        If None, trans must not be None.
    trans : dict | str | None
        File name of the trans file in text format.
        If None, mri must not be None.
    eeg : bool
        If True (Default), include EEG computations.
    meg : bool
        If True (Default), include MEG computations.
    fixed : bool
        If True, make a fixed-orientation forward solution (Default:
        False). Note that fixed-orientation inverses can still be
        created from free-orientation forward solutions.
    grad : bool
        If True, compute the gradient of the field with respect to the
        dipole coordinates as well (Default: False).
    mricoord : bool
        If True, calculate in MRI coordinates (Default: False)
    %(overwrite)s
    %(subjects_dir)s
    %(verbose)s

    See Also
    --------
    make_forward_solution

    Returns
    -------
    fwd : Forward
        The generated forward solution.
    z)mne command line tools could not be foundNztemp-fwd.fifr(  Úsubjectz(measurement file "%s" could not be foundzinfo.fifz+meas must be string, Raw, Epochs, or Evokedz&trans and mri cannot both be specifiedz%Either trans or mri must be specifiedÚtransztrans file "%s" not foundzmri-trans.fifzDmri was a dict, but could not be written to disk as a transform filez&trans must be a string or dict (trans)z"trans file "%s" could not be foundz!meg or eeg (or both) must be Truerx   z.fifz#Forward name does not end with .fifrV   z!mindist, if string, must be "all"z--allz	--mindistz%g)rK   ÚspacingÚbem)ú	path-liker(  rŽ  z
%s or NoneZmne_do_forward_solutionz	--subjectz--measz--fwdz	--destdirz--srcz(oct|ico)-?(\d+)$zInvalid spacing parameter: %rú-z	--spacingz--bemz--mriz%sz--transz	--eegonlyz	--megonlyz--fixedz--gradz
--mricoordz--overwriteT)Zraise_errorZSUBJECTS_DIR)Úignore_errorsz@Running forward solution generation command with subjects_dir %s)ÚenvF)r9   ))r4   r]  ÚtempfileÚmkdtempÚopÚjoinr2   r;   r*  r(  ÚisfileÚIOErrorr"   r%   r#   r   r`   r~   r  r   r1   rŸ   ÚsplitÚsplitextÚabspathÚlowerr^  ÚisdigitÚreÚmatchÚgroupsr¾   ÚosÚenvironrG   r3   ÚshutilÚrmtreer8   r6   r÷   )rŠ  ZmeasrÑ   rK   rŒ  Zmindistr�  Zmrir‹  rb   ra   rÔ   r7  ZmricoordrÒ   Zsubjects_dirr9   Útemp_dirr¦   Zmri_datar   Úelementr�   r¼   Úcmdrž  r‘  rÍ   rE   rE   rF   Ú_do_forward_solutionè  sÔ    E







þ
    ü














ÿr§  c                    sd  t ˆtdƒ tˆƒdks tdƒ‚|dkr6t tˆƒ¡}t |¡}t |dk¡sVtdƒ‚t|ƒtˆƒksntdƒ‚t |¡}|dksˆtdƒ‚|| }ˆD ]L‰ t ˆ t	dd	ƒ d
dddddddddddg}t‡ fdd„|D ƒƒs”t
dƒ‚q”t‡fdd„ˆdd… D ƒƒ�r
tdƒ‚t‡fdd„ˆdd… D ƒƒ�r2tdƒ‚tˆd ƒ}|d d  |d 9  < |d  |d 9  < tˆdd… |dd… ƒD ]B\‰ }|d d  |ˆ d d  7  < |d  |ˆ d  7  < �q„|d dk	�r`|d d  |d 9  < |d   |d 9  < tˆdd… |dd… ƒD ]B\‰ }|d d  |ˆ d d  7  < |d   |ˆ d   7  < �q|S )!aû  Average forward solutions.

    Parameters
    ----------
    fwds : list of Forward
        Forward solutions to average. Each entry (dict) should be a
        forward solution.
    weights : array | None
        Weights to apply to each forward solution in averaging. If None,
        forward solutions will be equally weighted. Weights must be
        non-negative, and will be adjusted to sum to one.
    %(verbose)s

    Returns
    -------
    fwd : Forward
        The averaged forward solution.
    rô   r   zfwds must not be emptyNzweights must be non-negativez/weights must be None or the same length as fwdszweights cannot all be zerozeach entry in fwdsr  r`   r–   rf   rK   rå   r”   rß   rR   ræ   r“   r­   rN   c                 3   s   | ]}|ˆ kV  qd S rY  rE   r!  r
  rE   rF   rú   Ý  s     z,average_forward_solutions.<locals>.<genexpr>zQforward solution dict does not have all standard entries, cannot compute average.c                 3   s4   | ],}d D ]"}|d | ˆ d d | kV  q
qdS ))rÉ   rý   r”   r   NrE   ©rJ   rÍ   rÄ   ©rô   rE   rF   rú   â  s     ÿrx   z.Forward solutions have incompatible dimensionsc                 3   s,   | ]$}d D ]}|| ˆ d | kV  q
qdS ))rR   ræ   r“   r   NrE   r¨  r©  rE   rF   rú   å  s     ÿz0Forward solutions have incompatible orientationsr�   r•   r—   )r;   rº   re   r~   rT   rƒ   Z
asanyarrayrV   rX   r  ÚKeyErrorrW   r   r^  )rô   Úweightsr9   Zw_sumZ
check_keysZfwd_averR  rE   )rÍ   rô   rF   Úaverage_forward_solutions¯  sZ    

    þ

ÿ
 " " r¬  )N)rE   rE   N)FFTTN)FN)F)NT)r  )r  N)r=  r>  Fr?  NNN)rW  rX  )NNrW  TN)NNTrW  N)NNrW  TN)r{  )NNNNNNNTTFFFFNN)NN)vr   rG   r   r�  ÚnumpyrT   r¢  r   r   r”  r’  Úior   r   Zio.constantsr   Zio.openr	   Zio.treer
   Zio.tagr   r   Z	io.matrixr   r   r   Zio.meas_infor   r   r   r   r   r   Zio.pickr   r   r   r   Zio.writer   r   r   r   r   r   r    r!   Zio.baser"   rv  r#   r$   Zepochsr%   Zsource_spacer&   r'   r(   r)   r*   r+   Zsource_estimater,   r-   r  r.   Z
transformsr/   r0   r1   Úutilsr2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   r„  rA   r  rB   r‹   r’   r£   rÆ   rÈ   rÎ   r÷   r  r  r  rë   r  r  r0  r6  r<  rV  rh  rp  rs  rw  rz  r}  r|  r‰  r§  r¬  rE   rE   rE   rF   Ú<module>
   sÖ    ( D ,2	/
\# 8      ÿ ) 


(
"
+9         þ *  ÿ
%    ÿ&    ÿD      ÿ>/l                     ü
 H