U
    f»{j¶T ã                   @   s<  d dl mZ d dlmZ d dlZd dlZd dlmZ d dl	m
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mZmZ dd	lmZmZmZmZmZmZmZ dd
lm Z  ddl!m"Z" ddl#m$Z$ ddl%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/ ddl0m1Z1m2Z2m3Z3 ddl4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZE G dd„ deFƒZGdd„ ZHdd„ ZIdd„ ZJdd„ ZKdd„ ZLdd„ ZMdd„ ZNd¤d#d$„ZOd%d&„ ZPe5d¥d'd(„ƒZQd)d*„ ZRd+d,„ ZSd-d.„ ZTd¦d/d0„ZUd1d2„ ZVd§d3d4„ZWd5d6„ ZXd7d8„ ZYd¨d:d;„ZZe5d©d>d?„ƒZ[d@dA„ Z\dBdC„ Z]dDdE„ Z^dFdG„ Z_dHdI„ Z`e5dªdNdO„ƒZae5d«dRdS„ƒZbe5d¬dTdU„ƒZce5d­dVdW„ƒZdd®dXdY„Zed¯d[d\„Zfe5d°d_d`„ƒZgdadb„ Zhe5d±dcdd„ƒZidedf„ Zjdgdh„ Zkd²didj„Zle5d³dkdl„ƒZmdmdn„ Zndodp„ ZoedqejpfdrejqfdsejrfdZejsfgƒZtejpejrejsdtœZuejpduejrdvejsdwejvdxiZwejpdqejqdyejrdvejsdwejvdxiZxdzd{„ Zye5d´d|d}„ƒZze5dµdd~œdd€„ƒZ{d�d‚„ Z|e5d¶dƒd„„ƒZ}d…d†„ Z~d‡dˆ„ Zd‰dŠ„ Z€e5d·d‹dŒ„ƒZ�e5d¸dd9dd�œdŽd�„ƒZ‚d�d‘„ Zƒd¹d’d“„Z„dºd–d—„Z…d˜d™„ Z†eFdšd›dœ�Z‡e5d»d�džddŸœd d¡„ƒZˆe5d¼d¢d£„ƒZ‰dS )½é    )ÚOrderedDict)ÚpartialN)ÚPath©Údeepcopyé   )ÚFIFFÚFWD)Ú_dig_kind_dictÚ_dig_kind_revÚ_dig_kind_ints)Ústart_and_end_fileÚstart_blockÚwrite_floatÚ	write_intÚwrite_float_matrixÚwrite_int_matrixÚ	end_block)Úfind_tag)Údir_tree_find)Ú	fiff_open)
Úread_surfaceÚwrite_surfaceÚcomplete_surface_infoÚ_compute_nearestÚ_get_ico_surfaceÚread_triÚ_fast_cross_nd_sumÚ_get_solidsÚ_complete_sphere_surfÚdecimate_surface)Ú_ensure_transÚapply_transÚ	Transform)ÚverboseÚloggerÚrun_subprocessÚget_subjects_dirÚwarnÚ_plÚ_validate_typeÚ_TempDirÚ_check_freesurfer_homeÚ_check_fnameÚhas_nibabelÚ_check_optionÚ	path_likeÚ_on_missingÚ_import_h5io_funcsÚ_ensure_intÚ
_path_likec                   @   s,   e Zd ZdZdd„ Zdd„ Zedd„ ƒZdS )	ÚConductorModelzBEM or sphere model.c                 C   s†   | d rbd  dd„ | d D ƒ¡}| j}|d kr8d| }q~dt| d ƒd	 t| d ƒ||d
 f }ndt| d ƒt| d ƒf }d| S )NÚ	is_sphereú, c                 s   s   | ]}d |d  V  qdS )ú%0.1fç     @�@N© ©Ú.0Úxr:   r:   úF/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/bem.pyÚ	<genexpr>9   s     z*ConductorModel.__repr__.<locals>.<genexpr>Úr0zSphere (no layers): r0=[%s] mmz&Sphere (%s layer%s): r0=[%s] R=%1.f mmÚlayersr   r9   zBEM (%s layer%s)Úsurfsz<ConductorModel | %s>)ÚjoinÚradiusÚlenr)   )ÚselfÚcenterÚradÚextrar:   r:   r>   Ú__repr__7   s    
 ÿÿ
ÿzConductorModel.__repr__c                 C   s   t | ƒS )z'Return copy of ConductorModel instance.r   ©rF   r:   r:   r>   ÚcopyF   s    zConductorModel.copyc                 C   s4   | d st dƒ‚t| d ƒdkr$dS | d d d S )z%Sphere radius if an EEG sphere model.r6   zradius undefined for BEMrA   r   NéÿÿÿÿrH   )ÚRuntimeErrorrE   rK   r:   r:   r>   rD   J   s    zConductorModel.radiusN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rJ   rL   ÚpropertyrD   r:   r:   r:   r>   r5   4   s
   r5   c           	      C   sZ   |d | d  }t j |¡}|| }|t  | |¡ }|t  ||¡ }t  || ¡| }|S )z<Compute coefficients for calculating the magic vector omega.r   )ÚnpÚlinalgÚnormÚdotÚlog)	ZrkZrk_normZrk1Zrk1_normZrkk1ÚsizeÚnumZdenÚresr:   r:   r>   Ú
_calc_betaR   s    r\   c                 C   sn  t  t| ƒdf¡}|t jddd…f |  }|t jddd…f |  }|t jddd…f |  }t|||ƒ}t jj|dd�}	t jj|dd�}
t jj|dd�}|	|
 | }|t  d|||¡7 }|t  d|||
¡7 }|t  d|||	¡7 }t  ||¡}t  	|¡t j
d k }d	|	|< d	|
|< d	||< t||	||
ƒdd…t jf t||
||ƒdd…t jf t||||	ƒdd…t jf g}|d |d  | }||d |d  | 7 }||d |d  | 7 }d
| }d	||  }|||g}dddddg}tdƒD ]€}|||d   |||d    }t|||d   |||d   |ƒ}| || d
 | ||| jdd�   |dd…|f< �qàd||< |S )z9Compute the linear potential matrix element computations.é   r   Nr   é   ©Zaxisz
ij,ij,i->ig    €„.Aç      ð?ç       @rM   ç        )rT   ÚzerosrE   Únewaxisr   rU   rV   ZeinsumZarctan2ÚabsÚpir\   ÚrangeÚsum)ÚfrosÚtri_rrÚtri_nnÚtri_areaÚomegaZv1Zv2Zv3ZtriplesÚl1Úl2Úl3ÚssÚsolidsZbad_maskÚbetaZ	vec_omegaZarea2Zn2ZyysÚidxÚkÚdiffZzdotsr:   r:   r>   Ú_lin_pot_coeff]   sH    þ
 $ÿrw   c                 C   s  dt j }| d  ¡ }||jdd� }t|ƒD ]Ú\}}t| d | ƒ}|dksRt‚|d |||f< |d|  }t  ||k¡d }|d }	t  dd	gd
dgd
dgg¡}
||
|	df  }||
|	df  }t	||ƒD ]8\}}|||| f  |7  < |||| f  |7  < qÎq.dS )z#Improve auto-element approximation.ra   Útrisr   r_   Úneighbor_trir   g      @r]   r^   rM   éþÿÿÿN)
rT   rf   Úravelrh   Ú	enumeraterE   ÚAssertionErrorÚwhereÚarrayÚzip)ÚsurfZmatÚpi2Z	tris_flatÚmissesÚjZmissZn_membÚmembersZmodsÚoffsetsZtri_1Ztri_2Út1Út2r:   r:   r>   Ú_correct_auto_elements’   s"    
r‰   c              
   C   s”  dd„ | D ƒ}t |ƒ}t ||f¡}t t dg|f¡¡}t| ƒD �]J\}}t || ¡}t| ƒD �](\}}	t dt	|d  || t	|	d  || f ¡ |	d |	d  }
|	d }|	d	 }||| ||d
  …|| ||d
  …f }t
|	d ƒD ]†}|	d | }||k�r2||d k||d
 kB ||d kB }ntƒ }t|d |
| || || d�}d||< |dd…|f  |8  < qò||krbt||ƒ qbqB|S )z;Calculate the coefficients for linear collocation approach.c                 S   s   g | ]}|d  ‘qS ©rT   r:   ©r<   r�   r:   r:   r>   Ú
<listcomp>­   s     z*_fwd_bem_lin_pot_coeff.<locals>.<listcomp>r   z        %s (%d) -> %s (%d) ...ÚidÚrrrx   rk   rl   r   Úntrir^   )ri   rj   rk   rl   rb   N)rh   rT   rc   ÚcumsumÚconcatenater|   Úaranger%   ÚinfoÚ_bem_surf_namerg   Úlistrw   r‰   )rB   ÚnpsZnp_totÚcoeffr†   Úsi_1Zsurf1Zrr_ordÚsi_2Zsurf2rj   rk   rl   Zsubmatru   ÚtriZskip_idxÚcoeffsr:   r:   r>   Ú_fwd_bem_lin_pot_coeffª   sL    
 ÿÿ 
ÿ


ÿ
þ ÿrœ   c                 C   sê   ddt j  }t  |¡}| j||fks*t‚t|ƒ}d| }t  t  dg|f¡¡}t|ƒD ]v}t|ƒD ]h}	|dkrt|n||||	f  }
t	|| ||d  ƒ}t	||	 ||	d  ƒ}|| ||f |
  | ||f< qdqX| t  
|¡7 } t j | ¡S )z»Do multi surface solution.

    * Invert I - solids/(2*M_PI)
    * Take deflation into account
    * The matrix is destroyed after inversion
    * This is the general multilayer case
    r`   r^   r   Nr   )rT   rf   rh   Úshaper}   rE   r�   r‘   rg   ÚsliceÚeyerU   Úinv)rr   Úgammar–   r‚   Zn_totZnsurfZdeflr†   r˜   r™   ÚmultZslice_jZslice_kr:   r:   r>   Ú_fwd_bem_multi_solutionÒ   s    
 r£   c                 C   s   t | d|d�S )zMake a homogeneous solution.N)r¡   r–   )r£   )rr   r–   r:   r:   r>   Ú_fwd_bem_homog_solutionë   s    r¤   c           	      C   sÂ   |d }d| | }t  d¡ t t dg|f¡¡}tt|ƒƒD ]F}| || ||d  …t |dd… ¡d…f }|dt ||¡ 8 }q@|| d…| d…f  || 7  < t  d¡ | |9 } dS )	z1Modify the solution according to the IP approach.rM   r`   z        Combining...r   r   Nr^   z        Scaling...)	r%   r“   rT   r�   r‘   rg   rE   rh   rW   )	ÚsolutionÚip_solutionÚip_multÚn_triZn_lastr¢   r†   ÚsiÚsubr:   r:   r>   Ú_fwd_bem_ip_modify_solutionð   s    
.$
r«   FÚraiseÚ c                 C   s¬   t | |dd�} t dd„ | d D ƒ¡d }t|ƒdkr¨t|ƒ}t|ƒdkr\|d d… dg n|}d	 d
d„ |D ƒ¡}d t| d  t|ƒt| d ƒ||¡}t||dd� | S )NF)rL   r$   c                 S   s   g | ]}t |ƒd k ‘qS ©r]   )rE   )r<   Útr:   r:   r>   rŒ     s     z+_check_complete_surface.<locals>.<listcomp>ry   r   éP   ú...r7   c                 s   s   | ]}t |ƒV  qd S ©N)Ústr)r<   Úfr:   r:   r>   r?     s     z*_check_complete_surface.<locals>.<genexpr>zoSurface {} has topological defects: {:.0f} / {:.0f} vertices have fewer than three neighboring triangles [{}]{}r�   rŽ   Ú
on_defects)Z
on_missingÚmsgÚname)	r   rT   r~   rE   r•   rC   Úformatr”   r1   )r�   rL   Ú
incompleterI   Zfewerr¶   r:   r:   r>   Ú_check_complete_surface  s    "
  
 ýrº   c                 C   s$  | d D ]}t |ƒ qt d¡ t d¡ t| d ƒ}t|ƒ| d< t d¡ dd„ | d D ƒ}t|| d |ƒ| d	< t| d ƒd
k�r| d d | d d  }|tjk�rt d¡ t d¡ t| d d gƒ}t d¡ t|| d d d gƒ}t d¡ t	| d	 |||ƒ tj
| d< t d¡ dS )z2Compute the linear collocation potential solution.rB   z,Computing the linear collocation solution...z    Matrix coefficients...Únsolz'    Inverting the coefficient matrix...c                 S   s   g | ]}|d  ‘qS rŠ   r:   r‹   r:   r:   r>   rŒ      s     z8_fwd_bem_linear_collocation_solution.<locals>.<listcomp>r¡   r¥   r]   Úsigmar   r^   zIP approach required...z"    Matrix coefficients (homog)...rM   z/    Inverting the coefficient matrix (homog)...rT   z>    Modify the original solution to incorporate IP approach...Ú
bem_methodzSolution ready.N)rº   r%   r“   rœ   rE   r£   r	   ZBEM_IP_APPROACH_LIMITr¤   r«   ÚBEM_LINEAR_COLL)Úbemr�   r—   r–   r§   r¦   r:   r:   r>   Ú$_fwd_bem_linear_collocation_solution  s2    






ÿ
ÿ
rÀ   c                 C   s|   t  d¡ t| ƒ}t|ƒ t|d ƒdkr6t  d¡ n$t|d ƒdkrRt  d¡ ntdƒ‚t|d ƒ t|ƒ t  d¡ |S )	aÞ  Create a BEM solution using the linear collocation approach.

    Parameters
    ----------
    surfs : list of dict
        The BEM surfaces to use (from :func:`mne.make_bem_model`).
    %(verbose)s

    Returns
    -------
    bem : instance of ConductorModel
        The BEM solution.

    See Also
    --------
    make_bem_model
    read_bem_surfaces
    write_bem_surfaces
    read_bem_solution
    write_bem_solution

    Notes
    -----
    .. versionadded:: 0.10.0
    z*Approximation method : Linear collocation
rB   r]   ú"Three-layer model surfaces loaded.r   ú!Homogeneous model surface loaded.z-Only 1- or 3-layer BEM computations supportedz#BEM geometry computations complete.)r%   r“   Ú_ensure_bem_surfacesÚ_add_gamma_multipliersrE   rN   Ú_check_bem_sizerÀ   )rB   r$   r¿   r:   r:   r>   Úmake_bem_solution3  s    

rÆ   c              	   C   s  t | d ƒ}d||f }|d dkr,t|ƒ‚|d }ttt |¡t d¡ ƒƒ}|d| krdt|ƒ‚~||kr~td||f ƒ‚t|ƒ}t|dd�}|d	= |d
= |d= |d= t |d | d ¡sÆtdƒ‚t 	d||t | d ƒt |d ƒf ¡ | d t
||ƒ |d< |S )zADownsample the surface if isomorphic to a subdivided icosahedron.rx   z÷Cannot decimate to requested ico grade %d. The provided BEM surface has %d triangles, which cannot be isomorphic with a subdivided icosahedron. Consider manually decimating the surface to a suitable density and then use ico=None in make_bem_model.é   r   é   z@For this surface, decimation grade should be %d or less, not %s.T)Úpatch_statsZtri_centrk   ry   rl   zKThe source surface has a matching number of triangles but ordering is wrongzGGoing from %dth to %dth subdivision of an icosahedron (n_tri: %d -> %d)rŽ   )rE   rN   ÚintÚroundrT   rX   r   Zarray_equalr%   r“   Ú_get_ico_map)r�   Z
dest_grader¨   Zbad_msgÚfoundÚsourceÚdestr:   r:   r>   Ú_ico_downsample`  s<    üÿ
ÿÿrÐ   c                 C   s>   t | d |d dd�\}}|dk ¡ }|dkr:td| ƒ‚|S )z#Get a mapping between ico surfaces.rŽ   T©Zreturn_distsg{®Gázt?r   z.No matching vertex for %d destination vertices)r   rh   rN   )ÚfroÚtoZnearestÚdistsZn_badsr:   r:   r>   rÌ   …  s    ÿrÌ   c                    sx   t ˆƒdkrˆS tjtjtjg}t dd„ ˆD ƒ¡‰ tˆ ƒt|ƒkrPtdˆ  ƒ‚‡ fdd„|D ƒ}‡fdd„|D ƒ‰ˆS )zReorder the surfaces.r]   c                 S   s   g | ]}|d  ‘qS ©r�   r:   r‹   r:   r:   r>   rŒ   —  s     z#_order_surfaces.<locals>.<listcomp>zbad surface ids: %sc                    s"   g | ]}t  ˆ |k¡d  d  ‘qS )r   )rT   r~   )r<   Úid_)Úidsr:   r>   rŒ   š  s     c                    s   g | ]}ˆ | ‘qS r:   r:   )r<   rt   ©rB   r:   r>   rŒ   ›  s     )	rE   r   ÚFIFFV_BEM_SURF_ID_HEADÚFIFFV_BEM_SURF_ID_SKULLÚFIFFV_BEM_SURF_ID_BRAINrT   r   ÚsetrN   )rB   Z
surf_orderÚorderr:   )r×   rB   r>   Ú_order_surfaces�  s    þrÞ   c              	   C   s¼   | d j dd�}t dt| d  d|d  d|d  d|d  f ¡ t| d | d	  |tjd
d
…f ƒd }|dtj  }t |d ¡dkr¸dt| d  › d|› d�}t	||dt
d� d
S )z2Check the sum of solid angles as seen from inside.rŽ   r   r_   z%s CM is %6.2f %6.2f %6.2f mmr�   éè  r   r^   rx   Nr`   çñhãˆµøä>úSurface z. is not complete (sum of solid angles yielded z, should be 1.)r¹   )r·   Zerror_klass)Úmeanr%   r“   r”   r   rT   rd   rf   re   r1   rN   )r�   r¹   ÚcmÚ	tot_angleÚpropr¶   r:   r:   r>   Ú_assert_complete_surfaceŸ  s$    

 
 
ÿÿ(   ÿræ   c                 C   s‚   t | d  }t |d  }t d|› d|› d�¡ t|d |d  | d ƒ}t |dtj  d ¡d	k ¡ r~td
|› d|› �ƒ‚dS )z,Check one set of points is inside a surface.r�   zChecking that surface z is inside surface z ...rŽ   rx   r^   r`   rà   rá   z" is not completely inside surface N)	r”   r%   r“   r   rT   re   rf   ÚanyrN   )rÒ   rÓ   Zfro_nameZto_namerä   r:   r:   r>   Ú_assert_inside°  s    ÿ ÿrè   c                 C   sH   | D ]}t ||d� qt| dd… | dd… ƒD ]\}}t||ƒ q0dS )z:Check that the surfaces are complete and non-intersecting.©r¹   NrM   r   )ræ   r€   rè   )rB   r¹   r�   Úsurf_1Úsurf_2r:   r:   r>   Ú_check_surfaces½  s    "rì   c                 C   sX   | d j dd�| d jdd� }|dk  ¡ rTtdt| d  › dd| ¡  d	›d
�ƒ‚dS )z0Check that the coordinate limits are reasonable.rŽ   r   r_   gš™™™™™©?zDimensions of the surface r�   z seem too small (rß   z9.5fz4). Maybe the unit of measure is meters instead of mmN)ÚmaxÚminrç   rN   r”   )r�   Úsizesr:   r:   r>   Ú_check_surface_sizeÆ  s
     "ÿrð   c              
   C   sž   t | dd… | dd… ƒD ]~\}}t|d |d dd�d }| ¡ }t|d  }t|d  }t d|› d	|› d
�¡ t d|› d	|› dd| d›d�¡ qdS )zCompute how close we are.NrM   r   rŽ   TrÑ   r�   zChecking distance between z and z surfaces...zMinimum distance between the z surfaces is approximately rß   z6.1fz mm)r€   r   rî   r”   r%   r“   )rB   rê   rë   Zmin_distrÒ   rÓ   r:   r:   r>   Ú_check_thicknessesÐ  s    "ÿÿrñ   Tc                 C   s^  t | ƒdks.t | ƒt |ƒ  kr,t |ƒks6n tdƒ‚t| ƒD ]*\}}t|tƒr>t|dd�d  | |< }q>|dk	r’t| ƒD ]\}}t||ƒ| |< qzt| |ƒD ]d\}}	|	|d< t|d||d� | 	d	t
j¡|d	< |jt |d
 ƒt |d ƒd� |rœ|d
  d  < qœt| |ƒD ]\}}
|
|d< �qt| ƒ} t| |d� | D ]}t|ƒ �q8t| ƒ t d¡ | S )zConvert surfaces to a BEM.©r   r]   zIsurfs, ids, and sigmas must all have the same number of elements (1 or 3)T)Zreturn_dictrM   Nr�   )rL   r¹   rI   Úcoord_framerŽ   rx   )rT   r�   r9   r¼   ré   z*Surfaces passed the basic topology checks.)rE   Ú
ValueErrorr|   Ú
isinstancer³   r   rÐ   r€   rº   Úgetr   ÚFIFFV_COORD_MRIÚupdaterÞ   rì   rð   rñ   r%   r“   )rB   r×   ÚsigmasÚicoÚrescaler¹   rI   r©   r�   rÖ   r¼   r:   r:   r>   Ú_surfaces_to_bemÝ  s8     ÿ
ÿ
rü   rÈ   ©ç333333Ó?gú~j¼t“x?rþ   c                 C   sÜ   t  |t¡}|jdks |jdkr(tdƒ‚t|dd�}t || ¡}t |d¡}t |d¡}t |d¡}t |d	¡}	|||	g}
t	j
t	jt	jg}t d
¡ t|ƒdkr¸|
dd… }
|dd… }t|
|||ƒ}
t|
ƒ t d¡ |
S )a•  Create a BEM model for a subject.

    .. note:: To get a single layer bem corresponding to the --homog flag in
              the command line tool set the ``conductivity`` parameter
              to a list/tuple with a single value (e.g. [0.3]).

    Parameters
    ----------
    subject : str
        The subject.
    ico : int | None
        The surface ico downsampling to use, e.g. 5=20484, 4=5120, 3=1280.
        If None, no subsampling is applied.
    conductivity : array of int, shape (3,) or (1,)
        The conductivities to use for each shell. Should be a single element
        for a one-layer model, or three elements for a three-layer model.
        Defaults to ``[0.3, 0.006, 0.3]``. The MNE-C default for a
        single-layer model would be ``[0.3]``.
    %(subjects_dir)s
    %(verbose)s

    Returns
    -------
    surfaces : list of dict
        The BEM surfaces. Use `make_bem_solution` to turn these into a
        `~mne.bem.ConductorModel` suitable for forward calculation.

    See Also
    --------
    make_bem_solution
    make_sphere_model
    read_bem_surfaces
    write_bem_surfaces

    Notes
    -----
    .. versionadded:: 0.10.0
    r   rò   z7conductivity must be 1D array-like with 1 or 3 elementsT©Zraise_errorr¿   zinner_skull.surfzouter_skull.surfzouter_skin.surfzCreating the BEM geometry...Nz
Complete.
)rT   r   ÚfloatÚndimrY   rô   r'   ÚoprC   r   rÛ   rÚ   rÙ   r%   r“   rE   rü   rÅ   )Úsubjectrú   ZconductivityÚsubjects_dirr$   Úsubject_dirÚbem_dirÚinner_skullÚouter_skullÚ
outer_skinZsurfacesr×   r:   r:   r>   Úmake_bem_model  s,    )
þ

r
  c              
   C   sÌ  t | d ƒ}|dkrdS t |d ¡}t |d ¡}t |d ¡}t |d ¡}t|d ƒD ]p}| d | d | d |d  d  ||< || d ||< | d | d ||< || ||< ||  || 9  < q\t |d ¡}td|ƒD ]à}	t|d ƒD ]}||  || 9  < qöt d¡}
|	d }t|d ddƒD ]V}t |	|||   |||  ||  g|	||  ||  ||	||   gg|
¡}
�q2|	d	|	 d |d   }||	|
d
  ||
d    ||	d < qæ|S )z.Get the model depended weighting factor for n.rA   )r   r   r`   r   r¼   Úrel_radr^   rM   ra   )r   r   )r   r   )rE   rT   rc   rg   rŸ   rW   )ÚmZn_termsZnlayerÚc1Úc2ÚcrZcr_multru   r›   ÚnÚMZn1rZ   r:   r:   r>   Ú&_fwd_eeg_get_multi_sphere_model_coeffsK  s8    (
&"ÿÿ&r  c                 C   sú   ddl m} t d|d ¡}| d | }|d dd… |d dd… ||d d    }|d dd…tjf | dd… |dd…tjf  |dd…tjf   }|j|d	d
�\}}}	|d d }
|dd…d|
…f |d|
… |	d|
…   }}}	||||	fS )zGet the linear fitting data.r   )rU   r   ÚntermsÚwNrM   ÚfnF)Zfull_matricesÚnfit)ZscipyrU   rT   r’   rd   Zsvd)ÚmuÚurU   Zk1Zmu1nsÚyr  ÚuuÚsingÚvvZncompr:   r:   r>   Ú_compose_linear_fitting_datan  s    00ÿ0r  c           
      C   sš   t | |ƒ\}}}}t ||¡}|t ||¡ }|| }t |d ¡}t ||¡|dd…< |d d t |dd… ¡ |d< t ||¡t ||¡ }	|	|fS )z+Compute the best-fitting linear parameters.r  r   Nr  r   )r  rT   rW   rc   rh   )
r  r  r  r  r  r  ZvecÚresiÚlambda_Úrvr:   r:   r>   Ú_compute_linear_parameters~  s    "r!  c                 C   sL   t  | ¡ ¡ dkrdS t| |ƒ\}}}}|t  |t  ||¡¡ }t  ||¡S )zBEvaluate the residual sum of squares fit for one set of mu values.r`   g      Y@)rT   re   rí   r  rW   )r  r  r  r  r  r  r  r:   r:   r>   Ú	_one_stepŽ  s
    r"  c                    s\  ddl m} |dkst‚t||d�}t| |d ƒ|d< tdd„ | d	 D ƒƒtd
d„ | d	 D ƒƒ }t d|d ¡}t 	d| d d| d  | ¡t 
||d ¡ |d< d|d d< t d¡}tt|d�}d}	dd|	  ‰ ‡ fdd„}
||||
gdd|	d�}t||ƒ\}}t |¡ddd… }|| ||  }}|| d< || d	 d d  | d< || d< |S )zAFit the Berg-Scherg equivalent spherical model dipole parameters.r   ©Úfmin_cobylar^   )r  r  r   r  c                 S   s   g | ]}|d  ‘qS ©rH   r:   ©r<   Úlayerr:   r:   r>   rŒ   £  s     z,_fwd_eeg_fit_berg_scherg.<locals>.<listcomp>rA   c                 S   s   g | ]}|d  ‘qS r%  r:   r&  r:   r:   r>   rŒ   ¤  s     ra   g      @r`   r  rM   r]   )r  ç�íµ ÷Æ°>c                    s   ˆ t  | ¡ S r²   )rT   re   )r=   ©Zmax_r:   r>   Úcons²  s    z&_fwd_eeg_fit_berg_scherg.<locals>.consg      à?rà   )ÚrhobegÚrhoendÚcatolNr  r¼   Úlambdar  )Úscipy.optimizer$  r}   Údictr  rî   rí   rT   r’   ÚsqrtÚpowerrc   r   r"  r!  Úargsort)r  r  r  r$  r  r´   ru   Zmu_0Zfunr-  r*  r  r   r  rÝ   r:   r)  r>   Ú_fwd_eeg_fit_berg_scherg™  s6    ÿÿÿ
r4  ©rb   rb   g{®Gáz¤?ç
×£p=
·?©gÍÌÌÌÌÌì?gq=
×£pí?g
×£p=
ï?r`   ©ç…ëQ¸Õ?r`   gü©ñÒMbp?r9  c              
   C   s¸  dD ]0}t ƒ | }t|tƒr|dkrtd||f ƒ‚qt |t¡ ¡ }t |t¡ ¡ }t|ƒt|ƒkr~tdt|ƒt|ƒf ƒ‚t|ƒdkr¤|dk	r¤tdt|ƒf ƒ‚t| tƒr¶| dksÌt|tƒ�r|dk�r|dkrÜtdƒ‚t	|d	d
�dd… \}}	t| tƒ�r|	} t|tƒ�r|}t
dt | ¡tjd�}
tƒ |
d< |dk	�r´t |t¡}t |t¡}t |¡}|| }|| }t||ƒD ]4\}}t||d�}| |d< |d< |
d  |¡ �qz|
d d d }|
d d d }|
d D ]&}|d  |  < |d  |  < �qØtt|ƒƒD ]&}||
d | d  |
d | d< �qt|
ddƒ}t dd|  ¡ tdƒD ]D}t d|d |
d | |d |
d d d |
d |  f ¡ �qZt dd| f ¡ |
S )uò  Create a spherical model for forward solution calculation.

    Parameters
    ----------
    r0 : array-like | str
        Head center to use (in head coordinates). If 'auto', the head
        center will be calculated from the digitization points in info.
    head_radius : float | str | None
        If float, compute spherical shells for EEG using the given radius.
        If 'auto', estimate an appropriate radius from the dig points in Info,
        If None, exclude shells (single layer sphere model).
    %(info)s Only needed if ``r0`` or ``head_radius`` are ``'auto'``.
    relative_radii : array-like
        Relative radii for the spherical shells.
    sigmas : array-like
        Sigma values for the spherical shells.
    %(verbose)s

    Returns
    -------
    sphere : instance of ConductorModel
        The resulting spherical conductor model.

    See Also
    --------
    make_bem_model
    make_bem_solution

    Notes
    -----
    The default model has::

        relative_radii = (0.90, 0.92, 0.97, 1.0)
        sigmas = (0.33, 1.0, 0.004, 0.33)

    These correspond to compartments (with relative radii in ``m`` and
    conductivities Ïƒ in ``S/m``) for the brain, CSF, skull, and scalp,
    respectively.

    .. versionadded:: 0.9.0
    )r@   Úhead_radiusÚautoz#%s, if str, must be "auto" not "%s"z9relative_radii length (%s) must match that of sigmas (%s)r   NzEat least 2 sigmas must be supplied if head_radius is not None, got %sz#Info must not be None for auto moder  )Úunitsr^   T)r6   r@   ró   rA   )rH   r¼   r  rH   rM   éÈ   r]   z#
Equiv. model fitting -> RV = %g %%éd   zmu%d = %g    lambda%d = %gr  r¼   r.  z3Set up EEG sphere model with scalp radius %7.1f mm
rß   )Úlocalsrõ   r³   rô   rT   r   r   r{   rE   Úfit_sphere_to_headshaper5   r   ÚFIFFV_COORD_HEADr•   r3  r€   r0  Úappendrg   r4  r%   r“   )r@   r:  r“   Zrelative_radiirù   r$   r·   ÚparamZhead_radius_fitZr0_fitZsphererÝ   r  Úsigr'  ÚRZrRru   r   r:   r:   r>   Úmake_sphere_modelÃ  sˆ    -

ÿÿÿÿÿÿÿ


ÿ
ÿÿÿ
ÿrF  r;  r  c                 C   sT   t |tƒr|dkrtdƒ‚t| |ƒ\}}}|dkrJ|d9 }|d9 }|d9 }|||fS )aU  Fit a sphere to the headshape points to determine head center.

    Parameters
    ----------
    %(info_not_none)s
    %(dig_kinds)s
    units : str
        Can be "m" (default) or "mm".

        .. versionadded:: 0.12
    %(verbose)s

    Returns
    -------
    radius : float
        Sphere radius.
    origin_head: ndarray, shape (3,)
        Head center in head coordinates.
    origin_device: ndarray, shape (3,)
        Head center in device coordinates.

    Notes
    -----
    This function excludes any points that are low and frontal
    (``z < 0 and y > 0``) to improve the fit.
    )r  Úmmzunits must be a "m" or "mm"rG  r9   )rõ   r³   rô   Ú_fit_sphere_to_headshape)r“   Ú	dig_kindsr<  r$   rD   Úorigin_headÚorigin_devicer:   r:   r>   r@  6  s     ÿ
r@  c           	   	      sp  t | dƒ | d dkrtdƒ‚tˆ tƒrbˆ dkr\zt| dƒW S  tk
rP   Y nX t| dƒS ˆ f‰ tˆ ƒ‰ tˆ ƒD ]B\}}t 	||¡ˆ |< ˆ | t
krrtd||ttt ¡ ƒƒf ƒ‚qr‡ fd	d
„| d D ƒ}tdd„ | d D ƒƒrêtdƒ‚|� rþdd
„ |D ƒ}t |¡}t|ƒdk�rld dd
„ tˆ ƒD ƒ¡}dt|ƒtˆ ƒ|f }t|ƒdk �r`t|d ƒ‚nt|d ƒ |S )a  Get digitization points suitable for sphere fitting.

    Parameters
    ----------
    %(info_not_none)s
    %(dig_kinds)s
    %(exclude_frontal)s
        Default is True.

        .. versionadded:: 0.19
    %(verbose)s

    Returns
    -------
    dig : array, shape (n_pts, 3)
        The digitization points (in head coordinates) to use for fitting.

    Notes
    -----
    This will exclude digitization locations that have ``z < 0 and y > 0``,
    i.e. points on the nose and below the nose on the face.

    .. versionadded:: 0.14
    r“   ÚdigNz?Cannot fit headshape without digitization , info["dig"] is Noner;  rI   )rI   Zeegz%dig_kinds[#%d] (%s) must be one of %sc                    s    g | ]}|d  ˆ kr|d ‘qS )ÚkindÚrr:   ©r<   Úp©rI  r:   r>   rŒ   �  s      z#get_fitting_dig.<locals>.<listcomp>c                 s   s   | ]}|d  t jkV  qdS )ró   N)r   rA  rO  r:   r:   r>   r?   �  s     z"get_fitting_dig.<locals>.<genexpr>zJDigitization points not in head coordinates, contact mne-python developersc                 S   s(   g | ] }|d  dk r |d dks|‘qS )r^   g�íµ ÷Æ°¾r   r(  r:   rO  r:   r:   r>   rŒ   –  s       é
   r7   c                 S   s   g | ]}d t |  ‘qS )z"%s")r   )r<   Údr:   r:   r>   rŒ   š  s   ÿz>Only %s head digitization points of the specified kind%s (%s,)rÈ   z, at least 4 requiredz, fitting may be inaccurate)r*   rN   rõ   r³   Úget_fitting_digrô   r•   r|   r
   rö   r   ÚsortedÚkeysrç   rT   r   rE   rC   r)   r(   )	r“   rI  Zexclude_frontalr$   ZdirS  ÚhspZ	kinds_strr¶   r:   rQ  r>   rT  ]  sF    


ÿ

ÿÿrT  c           	      C   s  t | |ƒ}tt |¡dd�\}}| d }|dkr:tddƒ}t|ddƒ}t||ƒ}t d 	d¡d	|d
 f  ¡ |dkrˆt
dd
| f ƒ tj |dd… ¡dkr¼t
dtd
|dd…  ƒ ƒ t d 	d¡dtd
| ƒ  ¡ t d 	d¡dtd
| ƒ  ¡ |||fS )z%Fit a sphere to the given head shape.F)ÚdispÚ
dev_head_tNÚmegÚheadzFitted sphere radius:é   z%0.1f mmr9   g)\�Âõ(¼?zKEstimated head size (%0.1f mm) exceeded 99th percentile for adult head sizer^   g{®Gáz”?z@(X, Y) fit (%0.1f, %0.1f) more than 20 mm from head frame originzOrigin head coordinates:z%0.1f %0.1f %0.1f mmzOrigin device coordinates:)rT  Ú_fit_sphererT   r   r#   r!   r"   r%   r“   Úljustr(   rU   rV   Útuple)	r“   rI  r$   rW  rD   rJ  rY  Zhead_to_devrK  r:   r:   r>   rH  ¥  s2    


ÿÿÿÿÿrH  c                    sÀ   ddl m} t|tƒr0|dkr0tjdkr,dnd}tjˆ dd�tjˆ dd� d	 }| 	¡ }tj
ˆ dd�}t ||gg¡}‡ fd
d„}dd„ }||||||d |d�}	|	dd… |	d  }
}||
fS )z+Fit a sphere to an arbitrary set of points.r   r#  r;  rÇ   TFr   r_   ra   c                    s4   t jjˆ | d d…  dd�| d  }||9 }| ¡ S )Nr]   r   r_   )rT   rU   rV   rh   )Ú
center_radrS  ©Úpointsr:   r>   Úcost_funÐ  s    $z_fit_sphere.<locals>.cost_func                 S   s   | d S )Nr]   r:   )r`  r:   r:   r>   Ú
constraintÕ  s    z_fit_sphere.<locals>.constraintr(  )r+  r,  rX  Nr]   )r/  r$  rõ   r³   r%   ÚlevelrT   rí   rî   râ   Zmedianr‘   )rb  rX  r$  ZradiiZradius_initZcenter_initZx0rc  rd  Zx_optÚoriginrD   r:   ra  r>   r]  Ã  s     
 ÿr]  r[  c                 C   sò   t | tƒr^| dkr td| f ƒ‚|dkrZt|ddd�dd… \}} t d	|d
 f ¡ ~nd} t | t¡} | j	dkr|tdƒ‚|rîd 
dd„ | D ƒ¡}d||f }|dkrä|d dk	rät|d | ƒ}d 
dd„ |D ƒ¡}|d|f 7 }t |¡ | S )z#Check or auto-determine the origin.r;  z3origin must be a numerical array, or "auto", not %sr[  Fr  )r$   r<  Nr^   z1    Automatic origin fit: head of radius %0.1f mmr9   )rb   rb   rb   r®   z origin must be a 3-element arrayr7   c                 S   s   g | ]}d |d  ‘qS )r8   rß   r:   ©r<   Úor:   r:   r>   rŒ   ñ  s     z!_check_origin.<locals>.<listcomp>z&    Using origin %s mm in the %s framerZ  rY  c                 s   s   | ]}d |d f V  qdS )r8   rß   Nr:   rg  r:   r:   r>   r?   ö  s     z _check_origin.<locals>.<genexpr>z (%s mm in the head frame))rõ   r³   rô   r@  r%   r“   rT   r   r   r�   rC   r"   )rf  r“   ró   rX  rE  Z
origin_strr¶   Zo_devr:   r:   r>   Ú_check_originß  s<    
ÿÿÿ
ÿ
ÿ
ri  ÚT1úws.mgzc           $   	   C   sr  ddl m} t| |ƒ\}}}tƒ }tt||d�}|d }t || ¡}t |d¡}t ||¡}|}| d¡sr|d7 }t 	|¡s†t
 |¡ t|ddd	d
� t 	|¡r¼|s²td| ƒ‚n
t |¡ dg}|rÚ|ddt|ƒ g7 }|	dkræ|}	|	rô|dg7 }|�rNt |d dd¡}tt |¡ƒddd… d }t d|f ¡ |dd||d g7 }n|�r^|dg7 }t |¡�rŽ|ddt || ¡|t ||
¡g7 }n"|ddt || ¡|t ||
¡g7 }t d|d |¡f ¡ t
 t |¡¡ ||ƒ ~t |¡�rætƒ �rþt|ƒntƒ }|�stdƒ dd d!d"g}|D ]–}t |d#| |f ¡}t|dd$�\}}}| |¡ t||||dd%� t |d&| ¡}|�s�t |¡�r�d} n&t |¡�r¦t
 |¡ t|||ƒ d'} �q"| �rØt d(¡ t |d¡}!nt d)¡ |}!t d*|! ¡ t || d+ ¡}"t |"¡�rt
 |"¡ t t || d, ¡gt!j"gdgd-�}#t#|"|#ƒ |�r^|| |d.ddd/� t d0|"f ¡ dS )1a  Create BEM surfaces using the FreeSurfer watershed algorithm.

    Parameters
    ----------
    subject : str
        Subject name.
    %(subjects_dir)s
    %(overwrite)s
    volume : str
        Defaults to T1.
    atlas : bool
        Specify the --atlas option for mri_watershed.
    gcaatlas : bool
        Specify the --brain_atlas option for mri_watershed.
    preflood : int
        Change the preflood height.
    show : bool
        Show surfaces to visually inspect all three BEM surfaces (recommended).

        .. versionadded:: 0.12

    copy : bool
        If True (default), use copies instead of symlinks for surfaces
        (if they do not already exist).

        .. versionadded:: 0.18
        .. versionchanged:: 1.1 Use copies instead of symlinks.
    T1 : bool | None
        If True, pass the ``-T1`` flag.
        By default (None), this takes the same value as ``gcaatlas``.

        .. versionadded:: 0.19
    brainmask : str
        The filename for the brainmask output file relative to the
        ``$SUBJECTS_DIR/$SUBJECT/bem/watershed/`` directory.
        Can be for example ``"../../mri/brainmask.mgz"`` to overwrite
        the brainmask obtained via ``recon-all -autorecon1``.

        .. versionadded:: 0.19
    %(verbose)s

    See Also
    --------
    mne.viz.plot_bem

    Notes
    -----
    If your BEM meshes do not look correct when viewed in
    :func:`mne.viz.plot_alignment` or :func:`mne.viz.plot_bem`, consider
    potential solutions from the :ref:`FAQ <faq_watershed_bem_meshes>`.

    .. versionadded:: 0.10
    r   ©Úplot_bem©ÚenvÚcwdÚSUBJECTS_DIRZ	watershedú.mgzÚreadTzMRI data)Ú	overwriteZ
must_existr·   z=%s already exists. Use the --overwrite option to recreate it.Zmri_watershedz-hz%sNz-T1ÚFREESURFER_HOMEZaveragezRB_all_withskull_*.gcarM   r   zUsing GCA atlas: %sz-atlasz-brain_atlasz(/mri/transforms/talairach_with_skull.ltaz-useSRASz-surfzj
Running mri_watershed for BEM segmentation with the following parameters:

Results dir = %s
Command = %s
ú zfnibabel is not available or the volumn info is invalid.Volume info not updated in the written surface.Úbrainr  r  r	  z%s_%s_surface)Zread_metadata)Úvolume_infort  z%s.surfFújUnable to create all symbolic links to .surf files in bem folder. Use --overwrite option to recreate them.ú3Symbolic links to .surf files created in bem folderzY
Thank you for waiting.
The BEM triangulations for this subject are now available at:
%s.z	-head.fifZ_outer_skin_surface)rù   Úcoronal©r  r  ZorientationZslicesÚshowzCreated %s

Complete.)$Úviz.miscrm  Ú_prepare_envr+   r   r&   r  rC   ÚendswithÚisdirÚosÚmakedirsr-   rN   ÚshutilÚrmtreerÊ   rU  Úglobr%   r“   ÚexistsÚisfiler.   Ú_extract_volume_infor0  r(   r   rø   r   ÚremoveÚ_symlinkrü   r   rÙ   Úwrite_bem_surfaces)$r  r  rt  ÚvolumeZatlasZgcaatlasZprefloodr}  rL   rj  Z	brainmaskr$   rm  ro  Úmri_dirr  ÚtempdirÚrun_subprocess_envr  Zws_dirÚT1_dirZT1_mgzÚcmdÚfnameZnew_inforB   ÚsZsurf_ws_outrŽ   rx   rx  Zsurf_outÚskip_symlinkrÏ   Z
fname_headr�   r:   r:   r>   Úmake_watershed_bemÿ  sÂ    :ÿ



ÿ

ÿÿ

ÿ
ÿþÿ

ÿ


ÿ
 ÿ
  ÿr–  c                 C   sŒ   ddl }| | ¡j}|d }tƒ }|dkrˆd| }||d< | |d< |d dd	… |d
< |d |d< |d \|d< |d< |d< |d |d< |S )z$Extract volume info from a mgz file.r   NÚversionr   z%s  # volume info validZvalidÚfilenameÚdimsr]   r�  ÚdeltaZ	voxelsizeZMdcZxrasZyrasZzrasZPxyz_cZcras)ÚnibabelÚloadÚheaderr0  )Zmgzr›  r�  r—  Zvol_infor:   r:   r>   r‰  §  s    r‰  c                 C   s”   t |ddƒ t| dddƒ} |  d¡r0t| |ƒ}n
t| |ƒ}|dk	rZt|ƒdkrZtd	| ƒ‚|D ] }|sr|d
 dkr^t||d� q^|dk	r�|d S |S )a  Read the BEM surfaces from a FIF file.

    Parameters
    ----------
    fname : str
        The name of the file containing the surfaces.
    patch_stats : bool, optional (default False)
        Calculate and add cortical patch statistics to the surfaces.
    s_id : int | None
        If int, only read and return the surface with the given s_id.
        An error will be raised if it doesn't exist. If None, all
        surfaces are read and returned.
    %(on_defects)s

        .. versionadded:: 0.23
    %(verbose)s

    Returns
    -------
    surf: list | dict
        A list of dictionaries that each contain a surface. If s_id
        is not None, only the requested surface will be returned.

    See Also
    --------
    write_bem_surfaces, write_bem_solution, make_bem_model
    )zint-likeNÚs_idrs  Tr“  ú.h5Nr   zsurface with id %d not foundÚnnré   r   )r*   r-   r€  Ú_read_bem_surfaces_h5Ú_read_bem_surfaces_fifrE   rô   rº   )r“  rÉ   rž  rµ   r$   r�   Úthisr:   r:   r>   Úread_bem_surfaces¼  s    

r¤  c                    sl   t ƒ \}}|| ƒ}zdd„ |d D ƒ W n tk
rD   tdƒ‚Y nX |d }ˆ d k	rh‡ fdd„|D ƒ}|S )Nc                 S   s   g | ]}|d  ‘qS rÕ   r:   ©r<   r”  r:   r:   r>   rŒ   í  s     z)_read_bem_surfaces_h5.<locals>.<listcomp>rB   úBEM data not foundc                    s   g | ]}|d  ˆ kr|‘qS rÕ   r:   r¥  ©rž  r:   r>   rŒ   ò  s      )r2   Ú	Exceptionrô   )r“  rž  Ú	read_hdf5Ú_r¿   r�   r:   r§  r>   r¡  é  s    
r¡  c              	      s  t j‰ t| ƒ\}}}|�ú‰t|t jƒ}|d ks:t|ƒdkrBtdƒ‚|d }t|t jƒ}|d krftdƒ‚t 	dt|ƒ ¡ t
ˆ|t jƒ}|d k	r”|j‰ ˆd k	rÂ‡ ‡‡fdd„|D ƒ}dd„ |D ƒ}nLtƒ }|D ].}	t 	d¡ tˆ|	ˆ ƒ}
| |
¡ t 	d	¡ qÌt 	d
t|ƒ ¡ W 5 Q R X |S )Nr   r¦  zBEM surface data not foundz    %d BEM surfaces foundc                    s   g | ]}t ˆ|ˆ ˆƒ‘qS r:   )Ú_read_bem_surface)r<   Úbsurf©ró   Úfidrž  r:   r>   rŒ     s   ÿz*_read_bem_surfaces_fif.<locals>.<listcomp>c                 S   s   g | ]}|d k	r|‘qS r²   r:   r¥  r:   r:   r>   rŒ     s      z    Reading a surface...ú[done]z    %d BEM surfaces read)r   r÷   r   r   Ú	FIFFB_BEMrE   rô   ÚFIFFB_BEM_SURFr%   r“   r   ÚFIFF_BEM_COORD_FRAMEÚdatar•   r«  rB  )r“  rž  r´   Útreerª  r¿   ZbemsurfÚtagr�   r¬  r£  r:   r­  r>   r¢  ö  s6    ÿ

r¢  c                 C   s.  t ƒ }t| |tjƒ}|dkr(tj|d< nt|jƒ|d< |dk	rN|d |krNdS t| |tjƒ}|dkrhdnt|jƒ|d< t| |tj	ƒ}|dkr”t
dƒ‚t|jƒ|d< t| |tjƒ}|dkrÀt
dƒ‚t|jƒ|d< t| |tjƒ}|dk�rt| |tjƒ}|dk�r||d	< n
|j|d	< n
|j|d	< t| |tjƒ}|dk�r>t
d
ƒ‚|j tj¡|d< |d jd |d k�rpt
dƒ‚t| |tjƒ}|dk�r–t| |tjƒ}|dk�rªd|d< n2|j tj¡|d< |d jd |d k�rÜt
dƒ‚t| |tjƒ}|dk�rüt
dƒ‚|jd |d< |d jd |d k�r*t
dƒ‚|S )zRead one bem surface.Nr�   r`   r¼   zNumber of vertices not foundrT   zNumber of triangles not foundr�   ró   zVertex data not foundrŽ   r   zVertex information is incorrectr   z&Vertex normal information is incorrectzTriangulation not foundr   rx   z&Triangulation information is incorrect)r0  r   r   ÚFIFF_BEM_SURF_IDÚFIFFV_BEM_SURF_ID_UNKNOWNrÊ   r³  ÚFIFF_BEM_SIGMAr   ÚFIFF_BEM_SURF_NNODErô   ÚFIFF_BEM_SURF_NTRIÚFIFF_MNE_COORD_FRAMEr²  ÚFIFF_BEM_SURF_NODESZastyperT   Zfloat64r�   ZFIFF_MNE_SOURCE_SPACE_NORMALSÚFIFF_BEM_SURF_NORMALSÚFIFF_BEM_SURF_TRIANGLES)r®  r£  Zdef_coord_framerž  r[   rµ  r:   r:   r>   r«    sZ    








r«  c                    s0  t | dddƒ} |  d¡r6tƒ \}}t d¡ || ƒ}nt| ƒ}t|d ƒdkrÐt d¡ t t	j
t	jt	jg¡‰ t‡ fd	d
„|d D ƒƒs�tdƒ‚dgd }|d D ]"}||t |d ˆ k¡d d < q¢||d< n<t|d ƒdk�r|d d d t	jk�stdƒ‚t d¡ t| ¡ ƒtdƒk�s&t‚t|ƒ}d|d< td|d t	jt	jfƒ d}|d D ]0}|d t	jk�r|||d 7 }n||d 7 }�qZ|d j}	t|	ƒdk�r´td|	d  ƒ‚|	d |k�sÐ|	d |k�rìtd|||	d |	d f ƒ‚|d jd |d< t|ƒ t	jdt	jdi|d  }
t d |
| ¡ |S )!aa  Read the BEM solution from a file.

    Parameters
    ----------
    fname : str
        The file containing the BEM solution.
    %(verbose)s

    Returns
    -------
    bem : instance of ConductorModel
        The BEM solution.

    See Also
    --------
    read_bem_surfaces
    write_bem_surfaces
    make_bem_solution
    write_bem_solution
    rs  Tr“  rŸ  z Loading surfaces and solution...rB   r]   rÁ   c                 3   s   | ]}|d  ˆ kV  qdS )r�   Nr:   r;   ©Úneededr:   r>   r?   „  s     z$read_bem_solution.<locals>.<genexpr>z%Could not find necessary BEM surfacesNr�   r   r   zBEM Surfaces not foundrÂ   ©rB   r¥   r½   Fr6   zBEM approximation methodr½   rT   r�   r¥   r^   zJExpected a two-dimensional solution matrix instead of a %d dimensional onez;Expected a %d x %d solution matrix instead of a %d x %d oner»   zconstant collocationZlinear_collocationzLoaded %s BEM solution from %s)r-   r€  r2   r%   r“   Ú_read_bem_solution_fifrE   rT   r   r   rÙ   rÚ   rÛ   ÚallrN   r~   rÜ   rV  r}   r5   r/   ÚFIFFV_BEM_APPROX_LINEARZFIFFV_BEM_APPROX_CONSTr�   rÄ   )r“  r$   r©  rª  r¿   Zreorderr=   Údimr�   r™  rM  r:   r¿  r>   Úread_bem_solution`  sj    




þ
 



ÿ
ÿÿ  þýrÆ  c              	   C   sº   t  d¡ t| ddd�}t  d¡ t| ƒ\}}}|�r}t|tjƒ}t|ƒdkrZtd|  ƒ‚|d }t	||tj
ƒ}|d kr„td|  ƒ‚|jd }	t	||tjƒ}|j}
W 5 Q R X t|
|	|d	�S )
NzLoading surfaces...TF)rÉ   r$   z 
Loading the solution matrix...
r   zNo BEM data in %szNo BEM solution found in %s)r¥   r½   rB   )r%   r“   r¤  r   r   r   r°  rE   rN   r   ÚFIFF_BEM_APPROXr³  ÚFIFF_BEM_POT_SOLUTIONr0  )r“  rB   r´   r´  rª  r®  ÚnodesZbem_noderµ  ÚmethodZsolr:   r:   r>   rÂ  ®  s     


rÂ  c                 C   sÚ   t  dd„ | d D ƒ¡| d< t jd| d f }d|dd… |dd	…   | d
< |dd… |dd	…  | d< t| d ƒt| d ƒks†t‚|dd… |dd	…  t jdd…f |dd… |dd	…  dd…t jf  | d< dS )z#Add gamma and multipliers in-place.c                 S   s   g | ]}|d  ‘qS )r¼   r:   r‹   r:   r:   r>   rŒ   É  s     z*_add_gamma_multipliers.<locals>.<listcomp>rB   r¼   rb   ra   r   NrM   Zsource_multZ
field_multr¡   )rT   r   Zr_rE   r}   rd   )r¿   r¼   r:   r:   r>   rÄ   Ç  s     $$ÿrÄ   rw  r  r  )r  r  r[  zinner skullzouter skullzouter skin zunknown    Zcsfc                 C   s´   | d rt }t}d}d}nt}t}d}d}t|tƒrB|}|| }n|| }| d rVdnd}t t dd„ | d D ƒ¡|k¡d	 }t	|ƒd
kr¤t
|› d|› d|› �ƒ‚| d |d	  S )z1Find surface from already-loaded conductor model.r6   zSphere modelÚboundaryZBEMZtriangulationc                 S   s   g | ]}|d  ‘qS rÕ   r:   r¥  r:   r:   r>   rŒ     s     z%_bem_find_surface.<locals>.<listcomp>rB   r   r   z does not have the rv  )Ú_sm_surf_dictÚ_sm_surf_nameÚ_bem_surf_dictr”   rõ   r³   rT   r~   r   rE   rN   )r¿   rÖ   Z
_surf_dictZ
_name_dictrM  rš   r·   rt   r:   r:   r>   Ú_bem_find_surfaceñ  s$    

&rÏ  c              	   C   s˜   t |tƒr|g}t| |dd�} |  d¡rHtƒ \}}|| t|d�dd� nLt| ƒ�>}t|tjƒ t	|tj
|d d ƒ t||ƒ t|tjƒ W 5 Q R X d	S )
a  Write BEM surfaces to a fiff file.

    Parameters
    ----------
    fname : str
        Filename to write. Can end with ``.h5`` to write using HDF5.
    surfs : dict | list of dict
        The surfaces, or a single surface.
    %(overwrite)s
    %(verbose)s
    r“  ©rt  r·   rŸ  rØ   T©rt  r   ró   N)rõ   r0  r-   r€  r2   r   r   r   r°  r   r²  Ú_write_bem_surfaces_blockr   )r“  rB   rt  r$   rª  Ú
write_hdf5r®  r:   r:   r>   rŒ    s    




rŒ  )r$   c                C   s4   t t||d�gtjgdgd|d�}t| ||d� dS )a›  Write a head surface to a fiff file.

    Parameters
    ----------
    fname : str
        Filename to write.
    rr : array, shape (n_vertices, 3)
        Coordinate points in the MRI coordinate system.
    tris : ndarray of int, shape (n_tris, 3)
        Triangulation (each line contains indices for three points which
        together form a face).
    %(on_defects)s
    %(overwrite)s
    %(verbose)s
    ©rŽ   rx   r   F)rû   r¹   rÑ  N)rü   r0  r   rÙ   rŒ  )r“  rŽ   rx   rµ   rt  r$   r�   r:   r:   r>   Úwrite_head_bem)  s      þrÕ  c                 C   sÞ   |D ]Ô}t | tjƒ t| tj|d ƒ t| tj|d ƒ t| tj|d ƒ t| tj|d ƒ t| tj	|d ƒ t
| tj|d ƒ t| tj|d d ƒ d	|krÌ|d	 d
k	rÌt|d	 ƒdkrÌt
| tj|d	 ƒ t| tjƒ qd
S )z'Write bem surfaces to open file handle.r¼   r�   ró   rT   r�   rŽ   rx   r   r   Nr   )r   r   r±  r   r¸  r   r¶  r»  r¹  rº  r   r¼  r   r¾  rE   r½  r   )r®  rB   r�   r:   r:   r>   rÒ  A  s    
ÿ$rÒ  c                    sR   t | |dd�} |  d¡rDtƒ \}}‡ fdd„dD ƒ‰ || ˆ dd� n
t| ˆ ƒ d	S )
a@  Write a BEM model with solution.

    Parameters
    ----------
    fname : str
        The filename to use. Can end with ``.h5`` to write using HDF5.
    bem : instance of ConductorModel
        The BEM model with solution to save.
    %(overwrite)s
    %(verbose)s

    See Also
    --------
    read_bem_solution
    r“  rÐ  rŸ  c                    s   i | ]}|ˆ | “qS r:   r:   )r<   ru   ©r¿   r:   r>   Ú
<dictcomp>g  s      z&write_bem_solution.<locals>.<dictcomp>rÁ  TrÑ  N)r-   r€  r2   Ú_write_bem_solution_fif)r“  r¿   rt  r$   rª  rÓ  r:   rÖ  r>   Úwrite_bem_solutionS  s    

rÙ  c              	   C   s¤   t |d ƒ t| ƒ�†}t|tjƒ t|tj|d d d ƒ t||d ƒ d|krŠ|d tj	krht
dƒ‚t|tjtjƒ t|tj|d ƒ t|tjƒ W 5 Q R X d S )NrB   r   ró   r¥   r½   z!Only linear collocation supported)rÅ   r   r   r   r°  r   r²  rÒ  r	   r¾   rN   rÇ  rÄ  r   rÈ  r   )r“  r¿   r®  r:   r:   r>   rØ  m  s    
ÿÿrØ  c                 C   s¦   t j ¡ }tƒ }t| dƒ t|dd�}t |¡}t |¡}t 	|¡sPt
d| ƒ‚t || ¡}t 	|¡stt
d|f ƒ‚|j| ||d� t |d¡}t |d¡}|||fS )	z+Prepare an env object for subprocess calls.r³   Trÿ   z*Could not find the MRI data directory "%s"z.Could not find the subject data directory "%s")ÚSUBJECTrq  ru  Úmrir¿   )r‚  ÚenvironrL   r,   r*   r'   r  ÚabspathÚ
expanduserr�  rN   rC   rø   )r  r  ro  Zfs_homer  rŽ  r  r:   r:   r>   r  ƒ  s*    




ÿ
ÿÿr  c                 C   sð   dd l }ddlm} t|ƒr&| |¡}t||ƒr g }t |j¡}|j	}|j
dkr^|dtjf }t|jd ƒD ],}|j|d|f |t|jƒd�}	| |	¡ ql|}~t|dƒD ]@\}
}t|ƒrÄ| |¡}| |t | dd|› d	|
d
›d�¡¡ qªd S )Nr   )ÚSpatialImager]   .)Úaffiner�  r   ÚflashÚmefrª  Z03drr  )r›  Znibabel.spatialimagesrß  r4   rœ  rõ   rT   Z
asanyarrayZdataobjrà  r  rd   rg   r�   Ú	__class__r   r�  rB  r|   Úsaver  rC   )rŽ  Zflash_echosÚangleÚnibrß  Zflash_echo_imgsr³  rà  Zecho_idxZthis_echo_imgrt   Z
flash_echor:   r:   r>   Ú_write_echosœ  s2    



 þ
ÿrç  c                 C   s>  t | |ƒdd… \}}tƒ }	tt||	d�}
t|ƒ}|d }|d }|jddd� d}|rjt|tƒsjtd	ƒ‚|r€t|tƒs€td
ƒ‚|�r
t	dt
ƒ t d¡ ddddddddg}|r¼ddg}ndg}d}|D ](}|D ]}t t d| |¡¡sÒd}qÒqÊ|�rVddddddddg}|D ]B}|D ]6}t t d| |¡¡�stdt d| |¡ ƒ‚�q�q|D ]¬}|D ] }t t d| |¡¡�s–tdt d| |¡ ƒ‚t t d| |d¡¡d }t |dd|› d|› d�¡}t |¡�ræt d¡ nd||g}|
|ƒ |d 7 }�qb�qZn4t|tƒ�s$t||dd!� t|tƒ�s>t||dd!� t |d"¡}tt |¡ƒ}t|ƒdk�rrtd#| ƒ‚|�r´t d$¡ |D ],}| dd%¡}d&d'|d(|d)d*g}|
|ƒ �q†|dk�rÜ| ¡ �rÜt |¡ t d+¡ | ¡ �sô|jddd� |�r´t d,¡ |�r tt t |d-¡¡ƒ}tt |¡ƒdk�rRd.g| t|ƒg }|
|ƒ n
t d/¡ t d0¡ |d1  ¡ �s¨d2d3d4d4|d5 |d6 |d1 g}|
|ƒ |d7  ¡  n
t d8¡ nnt d9¡ |�rÈd-nd:}t| |¡ƒ}t|ƒdk�rôtd#| ƒ‚d;d<g| |d1 g }|
|ƒ |d7 jdd=� ~	|d1  ¡ �s6t‚|d1 S )>am	  Synthetize the flash 5 files for use with make_flash_bem.

    This function aims to produce a synthesized flash 5 MRI from
    multiecho flash (MEF) MRI data. This function can use MEF data
    with 5 or 30 flip angles. If flash5 (and flash30) images are not
    explicitly provided, it will assume that the different echos are available
    in the mri/flash folder of the subject with the following naming
    convention "mef<angle>_<echo>.mgz", e.g. "mef05_001.mgz"
    or "mef30_001.mgz".

    Parameters
    ----------
    subject : str
        Subject name.
    flash30 : bool | list of SpatialImage or path-like | SpatialImage | path-like
        If False do not use 30-degree flip angle data.
        The list of flash 5 echos to use. If True it will look for files
        named mef30_*.mgz in the subject's mri/flash directory and if not False
        the list of flash 5 echos images will be written to the mri/flash
        folder with convention mef05_<echo>.mgz. If a SpatialImage object
        each frame of the image will be interpreted as an echo.
    convert : bool
        Assume that the Flash MRI images have already been converted
        to mgz files.

        DEPRECATED: This option is deprecated and will be removed in 1.2.
        Set it explicitly to False to silence the deprecation warning
        and use the flash5_echos and flash30_echos parameters to specify
        the images to use.
    unwarp : bool
        Run grad_unwarp with -unwarp option on each of the converted
        data sets. It requires FreeSurfer's MATLAB toolbox to be properly
        installed.
    %(subjects_dir)s
    flash5 : list of SpatialImage or path-like | SpatialImage | path-like | True
        The list of flash 5 echos to use. If True it will look for files
        named mef05_*.mgz in the subject's mri/flash directory and if not None
        the list of flash 5 echos images will be written to the mri/flash
        folder with convention mef05_<echo>.mgz. If a SpatialImage object
        each frame of the image will be interpreted as an echo.
    %(verbose)s

    Returns
    -------
    flash5_img : path-like
        The path the synthesized flash 5 MRI.

    Notes
    -----
    This function assumes that the Freesurfer segmentation of the subject
    has been completed. In particular, the T1.mgz and brain.mgz MRI volumes
    should be, as usual, in the subject's mri directory.
    Nr^   rn  rá  Úparameter_mapsT)ÚparentsÚexist_okr   z2When passing flash5 images, convert must be False.z3When passing flash30 images, convert must be False.z½The convert parameter is deprecated and will be removed in 1.2. You can now pass the Flash 5 and 30 echos as nibabel images to the function via the flash5_echos and flash30_echosparameters.z"
---- Converting Flash images ----Z001Z002Z003Z004Z005Z006Z007Z008Z05Z30FZ009zDirectory %s is missing.Ú*râ  rª  rr  zThe file %s is already thereÚmri_convertr   )rå  z
mef*_*.mgzz#No suitable source files found (%s)z
---- Unwarp mgz data sets ----zu.mgzZgrad_unwarpú-iú-oz-unwarpÚtruez!
Parameter maps directory clearedz&
---- Creating the parameter maps ----zmef05_*u.mgzZmri_ms_fitparmsz$Parameter maps were already computedz&
---- Synthesizing flash 5 images ----ú
flash5.mgzZmri_synthesizeZ20Ú5úT1.mgzzPD.mgzúflash5_reg.mgzz+Synthesized flash 5 volume is already therez"
---- Averaging flash5 echoes ----zmef05_*.mgzZmri_averagez
-noconform)Ú
missing_ok)r  r+   r   r&   r   Úmkdirrõ   Úboolrô   r(   ÚDeprecationWarningr%   r“   r  r�  rC   rN   r†  rˆ  rç  rU  rE   Úreplacer‡  r„  r…  r‚  Úlistdirr³   Úunlinkr}   )r  Zflash30ÚconvertZunwarpr  Úflash5r$   ro  rŽ  r�  r�  Z	flash_dirZpm_dirZ
echos_doneZechosZflashesÚmissingrá  ZechoZsample_fileÚ	dest_filer’  ÚtemplateÚfilesÚinfileÚoutfiler:   r:   r>   Úconvert_flash_mris¶  sÆ    8ÿü

ÿÿ

ÿ






ý
r  )Ú
flash5_imgÚregisterr$   c          #      C   s’  ddl m}	 t| |ƒ\}
}}tƒ }tt|
|d�}t|ƒ}t|ƒ}|dkrV|d d }ntdƒ t|ƒ ¡ }|
d }|j	d	d	d
� t
 d|| |d f ¡ |d }t|ƒrÚt
 d|› d|› �¡ dt|ƒ ¡ |g}||ƒ nF|dkrü| ¡ sútd|› d�ƒ‚n$t
 d|› �¡ ddl}| ||¡ |�r–t
 d¡ |d }| ¡ �sŠ|d  ¡ �rZ|d }n|d }ddt|ƒdt|ƒdt|ƒg}||ƒ n
t
 d¡ n|}t
 d¡ |d }tj|d	d� |j	d	d	d
� d||g}||ƒ d }|d }| ¡ �rt| d!¡ƒdk�rd	}d }|d" }| ¡ �r2t| d!¡ƒdk�r6d	}t
 d#¡ |�r‚|d }| ¡ �s`td$ƒ‚|j	d	d	d
� d||g}||ƒ n
t
 d%¡ t
 d&¡ |�rØ|d' }| ¡ �s¶td(ƒ‚|j	d	d	d
� d||g}||ƒ n
t
 d)¡ t
 d*¡ d+| g}||ƒ ~t
 d,¡ |d }|j	d	d	d
� d-d.d/g}|D ]T}||d0  }t ||d0  |¡ t|d	d1�\}} tt |¡d d2 || d	d3� �q,t
 d4¡ |d5  ¡  |�r²t |¡ t
 d6¡ |�rÌt |¡ t
 d7¡ t |¡ t
 d8¡ t
 d9¡ |D ]P}||d2  }|�s| ¡ �rd	}!n(| ¡ �r&| ¡  t||j  ||ƒ d }!�qî|!�rZt
 d:¡ |d }"nt
 d;¡ |}"t
 d<|" ¡ |�rŽ|	| |d=dd	d>� dS )?aÈ  Create 3-Layer BEM model from prepared flash MRI images.

    Parameters
    ----------
    subject : str
        Subject name.
    overwrite : bool
        Write over existing .surf files in bem folder.
    show : bool
        Show surfaces to visually inspect all three BEM surfaces (recommended).
    %(subjects_dir)s
    flash_path : str | None
        [DEPRECATED] Use the flash5_img parameter instead.

        Path to the flash images. If None (default), mri/flash/parameter_maps
        within the subject reconstruction is used.

        .. versionadded:: 0.13.0
        .. versionchanged:: 1.1 Deprecated
    copy : bool
        If True (default), use copies instead of symlinks for surfaces
        (if they do not already exist).

        .. versionadded:: 0.18
        .. versionchanged:: 1.1 Use copies instead of symlinks.
    flash5_img : None | path-like | Nifti1Image
        The path to the synthesized flash 5 MRI image or the image itself. If
        None (default), the path defaults to flash5.mgz within the flash_path
        folder. If not present the image is copied or written to the
        flash_path folder as flash5.mgz.

        .. versionadded:: 1.1.0
    register : bool
        Register the flash 5 image with T1.mgz file. If False, we assume
        that the images are already coregistered.

        .. versionadded:: 1.1.0
    %(verbose)s

    See Also
    --------
    convert_flash_mris

    Notes
    -----
    This program assumes that FreeSurfer is installed and sourced properly.

    This function extracts the BEM surfaces (outer skull, inner skull, and
    outer skin) from a FLASH 5 MRI image synthesized from multiecho FLASH
    images acquired with spin angles of 5 and 30 degrees.
    r   rl  rn  Nrá  rè  zpThe flash_path parameter is deprecated and will be removed in version 1.1. Use the flash5_img parameter instead.rq  T)rê  ré  zƒ
Processing the flash MRI data to produce BEM meshes with the following parameters:
SUBJECTS_DIR = %s
SUBJECT = %s
Result dir = %s
rð  zCopying flash 5 image z to rì  z!Flash 5 image cannot be found at Ú.zWriting flash 5 image at r   z-
---- Registering flash 5 with T1 MPRAGE ----ró  rò  rj  Zfsl_rigid_registerz-rrí  rî  z)Registered flash 5 image is already therez3
---- Converting flash5 volume into COR format ----rü  )Úignore_errorsFzCOR*rw  z/
---- Converting T1 volume into COR format ----z'Both T1 mgz and T1 COR volumes missing.z"T1 volume is already in COR formatz2
---- Converting brain volume into COR format ----z	brain.mgzz-Both brain mgz and brain COR volumes missing.z%Brain volume is already in COR formatz$
---- Creating the BEM surfaces ----Zmri_make_bem_surfacesz3
---- Converting the tri files into surf files ----r  r  r	  z.tri)Zswapz.surfrÑ  z
---- Cleaning up ----zinner_skull_tmp.trizDeleted the T1 COR volumezDeleted the brain COR volumezDeleted the flash5 COR volumez"
---- Creating symbolic links ----ry  rz  z¨
Thank you for waiting.
The BEM triangulations for this subject are now available at:
%s.
We hope the BEM meshes created will facilitate your MEG and EEG data analyses.r{  r|  )!r~  rm  r  r+   r   r&   r   r(   Úresolverõ  r%   r“   r4   r‡  rô   r›  rä  r³   r„  r…  Úis_dirÚnextr†  Úis_filerN   Úmover   r   r  Úsplitextrú  r‹  r·   )#r  rt  r}  r  Z
flash_pathrL   r  r  r$   rm  ro  rŽ  r  r�  r�  rü  r’  ræ  Z
flash5_regZ
ref_volumeZ
flash5_dirZ
convert_T1r‘  Zconvert_brainZ	brain_dirZT1_fnameZbrain_fnameZflash_bem_dirrB   r�   Z	out_fnamerÉ  rx   r•  rÏ   r:   r:   r>   Úmake_flash_bemd  sú    7ÿÿü



  ÿ















ÿ












ý  ÿr  c                 C   s4   t | ƒdkr0| d d dkr0td| d d  ƒ dS )zCheck bem surface sizes.r   r   rT   i'  ztThe bem surfaces have %s data points. 5120 (ico grade=4) should be enough. Dense 3-layer bems may not save properly.N)rE   r(   rØ   r:   r:   r>   rÅ   1  s    
þrÅ   c                 C   s`   |sLt  | t  |¡¡}zt ||¡ W n$ tk
rJ   td| ƒ d}Y nX |r\t | |¡ dS )z)Create a relative symlink (or just copy).zuCould not create symbolic link %s. Check that your partition handles symbolic links. The file will be copied instead.TN)	r  ÚrelpathÚdirnamer‚  ÚsymlinkÚOSErrorr(   r„  rL   )ÚsrcrÏ   rL   Zsrc_linkr:   r:   r>   r‹  9  s    þ
r‹  r:   r¿   c              	   C   s*  t dd„ |D ƒƒst‚dtf| }t| ||ƒ t| tƒrdt dt| ƒ› d�¡ t	| ƒ} t
d| d�} n4t| tƒr˜t| ƒD ] \}}t|t|› d|› d	�ƒ qvt| tƒr®t
d| d�} t| t
ƒ�r&| d
 �r&|  ¡ } g | d< t| d ƒdk�r&tt ¡ ƒD ]2\}}| d  t| |ddd�¡ || d d d< qò| S )Nc                 s   s   | ]}|d t fkV  qd S r²   )r5   )r<   rI   r:   r:   r>   r?   L  s     z'_ensure_bem_surfaces.<locals>.<genexpr>z	path-likezLoading BEM surfaces from r±   F)r6   rB   ú[ú]r6   rB   rA   rÈ   )ZcompleterM   r�   )rÃ  r}   r•   r*   rõ   r0   r%   r“   r³   r¤  r5   r|   r0  rL   rE   rÌ  ÚvaluesrB  r   )r¿   Zextra_allowr·   ÚallowedÚiiÚ	this_surfrt   rÖ   r:   r:   r>   rÃ   H  s2    



   ÿrÃ   c                 C   s"   t  | ¡r|std| › d�ƒ‚dS )zPrevent overwrites.zFile z( exists, use --overwrite to overwrite itN)r  rˆ  ÚIOError)r“  rt  r:   r:   r>   Ú_check_filef  s    r  i0u  iÄ	  )ZmediumÚsparserÇ   rò  )Ú	thresholdrÛ  r$   c                C   s¤  t |dd�}|rdnd}t || ¡}	t |	¡s:td|	 ƒ‚t|tdƒ |dkrjt t |	d|¡¡rf|nd}t d	¡ t |	d
¡fdd„}
|
ƒ }t	|dƒ}|dk�rt
tjƒ}||d< | |d< |d |  |d< d|krÜtdƒ‚tdd| d|dt|ƒdt|ƒg	|d� |
ƒ }|dk�rtdƒ‚t || d¡}t |¡�s>t |¡ t |d|  ¡}| d¡}t d| ¡ t||ƒ d }t|gtjgd!g||d"�d# }t|||d$� t d%d&¡d'k�rÀt|d( ƒg}tt ¡ d)ƒD ]Æ\}\}}|�ræ �q–t |› d*|› d+�¡ t |› d,t|d( ƒ› d-|› d.�¡ t|d/ |d( |d0�\}}| |¡}t d1||f ¡ t||ƒ tt||d2�gtjgd!gd3||d4�}t|||d$� �qÎt d5¡ dS )6aù  Create surfaces of the scalp and neck.

    The scalp surfaces are required for using the MNE coregistration GUI, and
    allow for a visualization of the alignment between anatomy and channel
    locations.

    Parameters
    ----------
    %(subject)s
    %(subjects_dir)s
    force : bool
        Force creation of the surface even if it has some topological defects.
        Defaults to ``True``. See :ref:`tut-fix-meshes` for ideas on how to
        fix problematic meshes.
    %(overwrite)s
    no_decimate : bool
        Disable the "medium" and "sparse" decimations. In this case, only
        a "dense" surface will be generated. Defaults to ``False``, i.e.,
        create surfaces for all three types of decimations.
    threshold : int
        The threshold to use with the MRI in the call to ``mkheadsurf``.
        The default is 20.

        .. versionadded:: 1.1
    mri : str
        The MRI to use. Should exist in ``$SUBJECTS_DIR/$SUBJECT/mri``.

        .. versionadded:: 1.1
    %(verbose)s
    Trÿ   r(   r¬   z<%s does not exist. Please check your subject directory path.rÛ  rò  rj  z91. Creating a dense scalp tessellation with mkheadsurf...r�   c                 S   s0   d }dD ]"}t  | |¡}t  |¡r|} q,q|S )N)z
lh.segheadzlh.smseghead)r  rC   r‡  )Z	surf_pathr�   ru   r  r:   r:   r>   Úcheck_seghead¢  s    
z*make_scalp_surfaces.<locals>.check_segheadr  Nrq  rÚ  ú/Zsubjdirru  ztThe FreeSurfer environment needs to be set up to use make_scalp_surfaces to create the outer skin surface lh.segheadZ
mkheadsurfz-subjidz-srcvolz-thresh1z-thresh2)ro  z4mkheadsurf did not produce the standard output file.r¿   z%s-head-{}.fifZdensez2. Creating %s ...zV

Consider using pymeshfix directly to fix the mesh, or --force to ignore the problem.r   )r¹   rI   r   rÑ  Z_MNE_TESTING_SCALPÚfalserï  rx   r]   z. Creating z tessellation...z&.1 Decimating the dense tessellation (z -> z triangles)...rŽ   )rb  Z	trianglesZn_trianglesz%i.2 Creating %srÔ  F)rû   r¹   rI   r¯  )r'   r  rC   r‡  rN   r*   r³   r%   r“   r3   r   r‚  rÜ  r&   r�  rõ  r¸   r  rü   r   rÙ   rŒ  ÚgetenvrE   r|   Ú_tri_levelsÚitemsr    r0  )r  r  Úforcert  Zno_decimater  rÛ  r$   r¹   Z	subj_pathr  Z
my_segheadZthis_envr�   r  Zfname_templateZdense_fnamer¶   rx   r  re  r¨   rb  Z	dec_fnameZdec_surfr:   r:   r>   Úmake_scalp_surfacesr  s¢    "
ÿ
	


ÿ      ýý



   þþ$þ


   ýr%  c                 C   sî   | j }|dkr | tjdd…f } | jd }t |f¡}t d|› dt|ƒ› d� ¡ |d r¦|d }|rvt||d	d
�}|d d d }t 	|tj
j| | dd� ¡}n4|d d d }	|rÈt||	d	d
�}	t|	| d	d�\}
}|dkrê|d }|S )a7  Calculate the distance of positions to inner skull surface.

    Parameters
    ----------
    pos : array, shape (..., 3)
        Position(s) in m, in head coordinates.
    bem : instance of ConductorModel
        Conductor model.
    %(trans)s If None (default), assumes bem is in head coordinates.
    %(verbose)s

    Returns
    -------
    distances : float | array, shape (...)
        The computed distance(s). A float is returned if pos is
        an array of shape (3,) corresponding to a single position.

    Notes
    -----
    .. versionadded:: 1.1
    r   Nr   z.Computing distance to inner skull surface for z	 positionr±   r6   r@   T)r  rA   rH   r_   rB   rŽ   rÑ   )r  rT   rd   r�   rc   r%   r“   r)   r"   re   rU   rV   r   )Úposr¿   Ztransr$   r  r  ZdistancerG   rD   Zsurface_pointsrª  r:   r:   r>   Údistance_to_bemå  s<    
ÿÿ ÿ  ÿr'  )Fr¬   r­   )N)r¬   )r¬   )NTr¬   r­   )rÈ   rý   NN)r5  r6  Nr7  r8  N)r;  r  N)r;  TN)N)r;  )r[  F)NFrj  FFNFTNrk  N)FNr¬   N)N)N)FN)r¬   F)FN)TTFNTN)FTNNT)F)r:   r¿   )NTFF)NN)ŠÚcollectionsr   Ú	functoolsr   r†  r‚  Úos.pathÚpathr  Úpathlibr   r„  rL   r   ÚnumpyrT   Zio.constantsr   r	   Zio._digitizationr
   r   r   Zio.writer   r   r   r   r   r   r   Zio.tagr   Zio.treer   Zio.openr   Zsurfacer   r   r   r   r   r   r   r   r   r    Z
transformsr!   r"   r#   Úutilsr$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r0  r5   r\   rw   r‰   rœ   r£   r¤   r«   rº   rÀ   rÆ   rÐ   rÌ   rÞ   ræ   rè   rì   rð   rñ   rü   r
  r  r  r!  r"  r4  rF  r@  rT  rH  r]  ri  r–  r‰  r¤  r¡  r¢  r«  rÆ  rÂ  rÄ   rÛ   ZFIFFV_BEM_SURF_ID_CSFrÚ   rÙ   rÌ  rÎ  r·  r”   rÍ  rÏ  rŒ  rÕ  rÒ  rÙ  rØ  r  rç  r  r  rÅ   r‹  rÃ   r  r"  r%  r'  r:   r:   r:   r>   Ú<module>   sV  $0L5(
,%


	
    ÿ
*    ÿC#*     þr&  ÿG

                 ý (  ÿ,%
EMüý    ü     û	ÿ      ÿ .    ÿ þ M

þ    ÿ  þr