U
    f»{jOá  ã                
   @   sŒ  d Z ddlmZ ddlZddlmZ ddl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mZ dd
lmZ ddlmZmZ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" ddlm#Z#m$Z$ ddl%m&Z&m'Z'm(Z(m)Z) ddl*m+Z+m,Z, ddl-m.Z.m/Z/m0Z0 ddlm1Z1m2Z2 ddl3m4Z4m5Z5 ddl6m7Z7 ddl8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZG ddlHmIZI e@G dd„ deGƒƒZJdd„ ZKe@G dd„ deGƒƒZLe:dLdd „ƒZMd!d"„ ZNd#d$„ ZOd%ZPd&d'„ ZQd(d)„ ZRdMd*d+„ZSe:dNd,d-„ƒZTdOd.d/„ZUe Vd¡d0d1„ ƒZWd2d3„ ZXdPd4d5„ZYd6d7„ ZZd8d9„ Z[d:d;„ Z\d<d=„ Z]d>d?„ Z^d@dA„ Z_e:dQdEdF„ƒZ`dRdHdI„ZadJdK„ ZbdS )Sz$Single-dipole functions and classes.é    ©ÚdeepcopyN)Úpartialé   )Úcompute_whitenerÚ_ensure_cov)ÚFIFF)Ú
pick_types)Úmake_projectorÚ_needs_eeg_average_ref_proj)Ú_fit_sphere)Ú_read_evokedÚ_aspect_revÚ_write_evokeds)Úpinvh)Úread_freesurfer_lutÚ	_get_aseg)Ú_print_coord_transÚ_coord_frame_nameÚapply_trans©Ú_plot_evoked)Úhead_to_mniÚhead_to_mri)Ú
_get_transÚ
_setup_bemÚ_prep_meg_channelsÚ_prep_eeg_channels)Ú_compute_forwards_meegÚ_prep_field_computation)Útransform_surface_toÚ_compute_nearestÚ_points_outside_surface)Ú_bem_find_surfaceÚ_bem_surf_name)Ú_make_volume_source_spaceÚSourceSpaces)Úparallel_func)ÚloggerÚverboseÚ
_time_maskÚwarnÚ_check_fnameÚcheck_fnameÚ_plÚfill_docÚ_check_optionÚ
_svd_lworkÚ_repeated_svdÚ_get_blas_funcsÚ_validate_typeÚcopy_function_doc_to_method_docÚ	TimeMixin©Úplot_dipole_locationsc                   @   sÂ   e Zd ZdZed(ddœdd„ƒZdd„ Zed)ddœd	d
„ƒZed*dd„ƒZdd„ Z	ee
eƒd+ddddddddœdd„ƒƒZed,dd„ƒZed-dd„ƒZed.dd „ƒZd/d"d#„Zd$d%„ Zd&d'„ ZdS )0ÚDipoleu’  Dipole class for sequential dipole fits.

    .. note:: This class should usually not be instantiated directly,
              instead :func:`mne.read_dipole` should be used.

    Used to store positions, orientations, amplitudes, times, goodness of fit
    of dipoles, typically obtained with Neuromag/xfit, mne_dipole_fit
    or certain inverse solvers. Note that dipole position vectors are given in
    the head coordinate frame.

    Parameters
    ----------
    times : array, shape (n_dipoles,)
        The time instants at which each dipole was fitted (sec).
    pos : array, shape (n_dipoles, 3)
        The dipoles positions (m) in head coordinates.
    amplitude : array, shape (n_dipoles,)
        The amplitude of the dipoles (Am).
    ori : array, shape (n_dipoles, 3)
        The dipole orientations (normalized to unit length).
    gof : array, shape (n_dipoles,)
        The goodness of fit.
    name : str | None
        Name of the dipole.
    conf : dict
        Confidence limits in dipole orientation for "vol" in m^3 (volume),
        "depth" in m (along the depth axis), "long" in m (longitudinal axis),
        "trans" in m (transverse axis), "qlong" in Am, and "qtrans" in Am
        (currents). The current confidence limit in the depth direction is
        assumed to be zero (although it can be non-zero when a BEM is used).

        .. versionadded:: 0.15
    khi2 : array, shape (n_dipoles,)
        The Ï‡^2 values for the fits.

        .. versionadded:: 0.15
    nfree : array, shape (n_dipoles,)
        The number of free parameters for each fit.

        .. versionadded:: 0.15
    %(verbose)s

    See Also
    --------
    fit_dipole
    DipoleFixed
    read_dipole

    Notes
    -----
    This class is for sequential dipole fits, where the position
    changes as a function of time. For fixed dipole fits, where the
    position is fixed as a function of time, use :class:`mne.DipoleFixed`.
    N©r)   c
                C   s¬   |   t |¡¡ t |¡| _t |¡| _t |¡| _t |¡| _|| _tƒ | _	|d k	rx| 
¡ D ]\}}t |¡| j	|< q^|d k	rŠt |¡nd | _|	d k	r¢t |	¡nd | _d S ©N)Ú
_set_timesÚnpÚarrayÚposÚ	amplitudeÚoriÚgofÚnameÚdictÚconfÚitemsÚkhi2Únfree)ÚselfÚtimesr?   r@   rA   rB   rC   rE   rG   rH   r)   ÚkeyÚvalue© rM   úI/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/dipole.pyÚ__init__e   s    zDipole.__init__c                 C   s>   dt | jƒ }|dt | j¡ 7 }|dt | j¡ 7 }d| S )Nún_times : %sz, tmin : %0.3fz, tmax : %0.3fz<Dipole | %s>©ÚlenrJ   r=   ÚminÚmax©rI   ÚsrM   rM   rN   Ú__repr__v   s    zDipole.__repr__Fc                C   s0   t ||d�}| d¡r"t|| ƒ n
t|| ƒ dS )a]  Save dipole in a .dip or .bdip file.

        Parameters
        ----------
        fname : str
            The name of the .dip or .bdip file.
        %(overwrite)s

            .. versionadded:: 0.20
        %(verbose)s

        Notes
        -----
        .. versionchanged:: 0.20
           Support for writing bdip (Xfit binary) files.
        )Ú	overwriteú.bdipN)r,   ÚendswithÚ_write_dipole_bdipÚ_write_dipole_text)rI   ÚfnamerX   r)   rM   rM   rN   Úsave|   s    
zDipole.saveTc           	      C   s¢   d}t | jƒdkr(dt t | j¡¡ }t| j||||d�}|  | j| ¡ dD ](}t| |ƒdk	rPt| |t| |ƒ| ƒ qP| j	 
¡ D ]}| j	| | | j	|< q„| S )a{  Crop data to a given time interval.

        Parameters
        ----------
        tmin : float | None
            Start time of selection in seconds.
        tmax : float | None
            End time of selection in seconds.
        %(include_tmax)s
        %(verbose)s

        Returns
        -------
        self : instance of Dipole
            The cropped instance.
        Nr   ç      ð?)ÚsfreqÚinclude_tmax)r?   rB   r@   rA   rG   rH   )rR   rJ   r=   ZmedianÚdiffr*   r<   ÚgetattrÚsetattrrE   Úkeys)	rI   ZtminZtmaxra   r)   r`   ÚmaskÚattrrK   rM   rM   rN   Úcrop•   s    ÿzDipole.cropc                 C   s   t | ƒS )z‹Copy the Dipoles object.

        Returns
        -------
        dip : instance of Dipole
            The copied dipole instance.
        r   ©rI   rM   rM   rN   Úcopy´   s    zDipole.copyÚ	orthoviewÚmrirB   ÚrZsegheadZpial)Úhighlight_colorÚfigÚtitleÚhead_sourceÚsurfÚwidthr)   c                C   s.   t | |||||||||	|
||||||||d�S )N)ÚscaleÚcolorrn   ro   rp   rq   rr   rs   r7   )rI   ÚtransÚsubjectÚsubjects_dirÚmodeÚcoord_frameÚidxZshow_allZaxÚblockÚshowrt   ru   rn   ro   rp   rq   rr   rs   r)   rM   rM   rN   Úplot_locations¾   s*                   üzDipole.plot_locationsc                 C   s    t |ƒ\}}t| j||||d�S )a<  Convert dipole location from head to MNI coordinates.

        Parameters
        ----------
        %(subject)s
        %(trans_not_none)s
        %(subjects_dir)s
        %(verbose)s

        Returns
        -------
        pos_mni : array, shape (n_pos, 3)
            The MNI coordinates (in mm) of pos.
        ©rx   r)   )r   r   r?   ©rI   rw   rv   rx   r)   Ú
mri_head_trM   rM   rN   Úto_mniÌ   s
    
 ÿzDipole.to_mnic                 C   s    t |ƒ\}}t| j||||d�S )a[  Convert dipole location from head to MRI surface RAS coordinates.

        Parameters
        ----------
        %(subject)s
        %(trans_not_none)s
        %(subjects_dir)s
        %(verbose)s

        Returns
        -------
        pos_mri : array, shape (n_pos, 3)
            The Freesurfer surface RAS coordinates (in mm) of pos.
        r   )r   r   r?   r€   rM   rM   rN   Úto_mriá   s
    
 ÿzDipole.to_mriÚ	fsaverageú
aparc+asegc                    s‚   t |||ƒ\}‰ tj |j ¡ ¡}tƒ d }dd„ | ¡ D ƒ‰| j||||d�}	t	||	ƒ}	t 
|	¡ t¡}	‡ ‡fdd„|	D ƒ}
|
S )a…  Find an ROI in atlas for the dipole positions.

        Parameters
        ----------
        %(trans)s
        %(subject)s
        %(aseg)s
        %(subjects_dir)s
        %(verbose)s

        Returns
        -------
        labels : list
            List of anatomical region names from anatomical segmentation atlas.

        Notes
        -----
        .. versionadded:: 0.24
        r   c                 S   s   i | ]\}}||“qS rM   rM   )Ú.0ÚkÚvrM   rM   rN   Ú
<dictcomp>  s      z+Dipole.to_volume_labels.<locals>.<dictcomp>r   c                    s    g | ]}ˆ  ˆ t|ƒ d ¡‘qS )ÚUnknown)ÚgetÚtuple)r†   Zcoord©Z	aseg_dataZlutrM   rN   Ú
<listcomp>  s     z+Dipole.to_volume_labels.<locals>.<listcomp>)r   r=   ÚlinalgÚinvÚheaderZget_vox2ras_tkrr   rF   rƒ   r   ZrintÚastypeÚint)rI   rv   rw   Zasegrx   r)   Zaseg_imgZ	mri_vox_tZlut_invr?   ÚlabelsrM   r�   rN   Úto_volume_labelsö   s    

ÿ
zDipole.to_volume_labelsr‡   c                 C   s   ddl m} || g|g|ƒS )aZ  Plot the dipole amplitudes as a function of time.

        Parameters
        ----------
        color : matplotlib color
            Color to use for the trace.
        show : bool
            Show figure if True.

        Returns
        -------
        fig : matplotlib.figure.Figure
            The figure object containing the plot.
        r   )Úplot_dipole_amplitudes)Úvizr–   )rI   ru   r}   r–   rM   rM   rN   Úplot_amplitudes  s    zDipole.plot_amplitudesc              
   C   sÜ   t |tƒr|g}| j|  ¡ }| j|dd…f  ¡ }| j|  ¡ }| j|dd…f  ¡ }| j|  ¡ }| j}t	ƒ }| j
 ¡ D ]}	| j
|	 | ||	< q|| jdk	r¨| j| nd}
| jdk	rÀ| j| nd}t||||||||
|ƒ	S )zòGet a time slice.

        Parameters
        ----------
        item : array-like or slice
            The slice of time points to use.

        Returns
        -------
        dip : instance of Dipole
            The sliced dipole.
        N)Ú
isinstancer“   rJ   rj   r?   r@   rA   rB   rC   rD   rE   re   rG   rH   r9   )rI   ÚitemZselected_timesZselected_posZselected_amplitudeZselected_oriZselected_gofZselected_nameZselected_confrK   Zselected_khi2Zselected_nfreerM   rM   rN   Ú__getitem__/  s0    
      ýzDipole.__getitem__c                 C   s   | j jd S )züReturn the number of dipoles.

        Returns
        -------
        len : int
            The number of dipoles.

        Examples
        --------
        This can be used as::

            >>> len(dipoles)  # doctest: +SKIP
            10
        r   )r?   Úshaperi   rM   rM   rN   Ú__len__O  s    zDipole.__len__)NNNN)F)NNTN)
Nrk   rl   rB   TNFTNN)NN)NN)r„   r…   NN)r‡   T)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r)   rO   rW   r^   rh   rj   r5   r8   r~   r‚   rƒ   r•   r˜   r›   r�   rM   rM   rM   rN   r9   ,   sh   7       ÿþ
                ý    û  ÿ  ÿ    ÿ&
 r9   c                 C   s8   t  d|  ¡ t| ƒ\}}}}}}}t||||||d�S )zRead a fixed dipole FIF file.zReading %s ...©Úcomment)r(   Úinfor   ÚDipoleFixed)r]   r¤   ÚnaveÚaspect_kindr£   rJ   ÚdataÚ_rM   rM   rN   Ú_read_dipole_fixeda  s    rª   c                   @   sX   e Zd ZdZedddœdd„ƒZdd„ Zd	d
„ Zedd„ ƒZ	eddd„ƒZ
ddd„ZdS )r¥   a_  Dipole class for fixed-position dipole fits.

    .. note:: This class should usually not be instantiated directly,
              instead :func:`mne.read_dipole` should be used.

    Parameters
    ----------
    %(info_not_none)s
    data : array, shape (n_channels, n_times)
        The dipole data.
    times : array, shape (n_times,)
        The time points.
    nave : int
        Number of averages.
    aspect_kind : int
        The kind of data.
    comment : str
        The dipole comment.
    %(verbose)s

    See Also
    --------
    read_dipole
    Dipole
    fit_dipole

    Notes
    -----
    This class is for fixed-position dipole fits, where the position
    (and maybe orientation) is static over time. For sequential dipole fits,
    where the position can change a function of time, use :class:`mne.Dipole`.

    .. versionadded:: 0.12
    Ú Nr:   c                C   sN   || _ || _|| _t |d¡| _|| _|  t 	|¡¡ || _
d| _|  ¡  d S )NÚunknownT)r¤   r¦   Ú_aspect_kindr   r‹   Úkindr£   r<   r=   r>   r¨   ZpreloadZ_update_first_last)rI   r¤   r¨   rJ   r¦   r§   r£   r)   rM   rM   rN   rO   �  s    zDipoleFixed.__init__c                 C   s>   dt | jƒ }|dt | j¡ 7 }|dt | j¡ 7 }d| S )NrP   z, tmin : %sz, tmax : %sz<DipoleFixed | %s>rQ   rU   rM   rM   rN   rW   š  s    zDipoleFixed.__repr__c                 C   s   t | ƒS )z¿Copy the DipoleFixed object.

        Returns
        -------
        inst : instance of DipoleFixed
            The copy.

        Notes
        -----
        .. versionadded:: 0.16
        r   ri   rM   rM   rN   rj      s    zDipoleFixed.copyc                 C   s
   | j d S )zChannel names.Úch_names©r¤   ri   rM   rM   rN   r¯   ®  s    zDipoleFixed.ch_namesc                 C   s    t |dddƒ t|| dd� dS )a)  Save dipole in a .fif file.

        Parameters
        ----------
        fname : str
            The name of the .fif file. Must end with ``'.fif'`` or
            ``'.fif.gz'`` to make it explicit that the file contains
            dipole information in FIF format.
        %(verbose)s
        r¥   )z-dip.fifz-dip.fif.gzz_dip.fifz_dip.fif.gz)ú.fifú.fif.gzF)ÚcheckN)r-   r   )rI   r]   r)   rM   rM   rN   r^   ³  s    þzDipoleFixed.saveTrV   c                 C   s.   t | ddd|ddddddddddddd|d�S )a’  Plot dipole data.

        Parameters
        ----------
        show : bool
            Call pyplot.show() at the end or not.
        time_unit : str
            The units for the time axis, can be "ms" or "s" (default).

            .. versionadded:: 0.16

        Returns
        -------
        fig : instance of matplotlib.figure.Figure
            The figure containing the time courses.
        NrM   TZtightFÚ	butterfly)ÚpicksÚexcludeÚunitr}   ZylimZxlimZprojZhlineZunitsZscalingsÚtitlesZaxesZgfpZwindow_titleZspatial_colorsZ	plot_typeZ
selectableÚ	time_unitr   )rI   r}   r¹   rM   rM   rN   ÚplotÄ  s              ûzDipoleFixed.plot)r«   )N)TrV   )rž   rŸ   r    r¡   r)   rO   rW   rj   Úpropertyr¯   r^   rº   rM   rM   rM   rN   r¥   h  s   # ÿÿ
r¥   c                 C   sH   t | ddd�} |  d¡s"|  d¡r*t| ƒS |  d¡r<t| ƒS t| ƒS dS )am  Read .dip file from Neuromag/xfit or MNE.

    Parameters
    ----------
    fname : str
        The name of the .dip or .fif file.
    %(verbose)s

    Returns
    -------
    %(dipole)s

    See Also
    --------
    Dipole
    DipoleFixed
    fit_dipole

    Notes
    -----
    .. versionchanged:: 0.20
       Support for reading bdip (Xfit binary) format.
    ÚreadT)rX   Z
must_existr±   r²   rY   N)r,   rZ   rª   Ú_read_dipole_bdipÚ_read_dipole_text)r]   r)   rM   rM   rN   Úread_dipoleß  s    
r¿   c              
      sÊ  d}d }}t ƒ }t| dƒ�t}|D ]f}| d¡sR| d¡sRd}| | ¡  ¡ ¡ q"|rZ|}| d¡sn| d¡r"t d	|¡}|r"| d
¡}q"~W 5 Q R X t	 
t	 |t¡¡}|dkr¾td| f ƒ‚| d¡ d¡ ¡ }t ddd„ |¡‰ t ddd„ ˆ ¡‰ t ddd„ ˆ ¡‰ ˆ  ¡  ¡ ‰ d}d}	ddddddg}
tt|ƒtˆ ƒ ƒ}t|ƒdk�r\td|f ƒ‚t|ƒt|	ƒB }t|ƒt|ƒt|	ƒ k�sŠt‚ttˆ ƒt|ƒ dh ƒ}t|ƒdk�rÀtd|f ƒ tˆ ƒ|jd
 k�rðtdtˆ ƒ|jd
 ˆ f ƒ‚t dt|ƒ ¡ dˆ k�rDt	 |dd…ˆ  d¡ˆ  d¡gf d
d¡ ¡ �rDtdƒ ‡ fd d!„|D ƒ}t|ƒd"k�sht‚|dd…|d f d# }d|dd…|d
d$… f  }|dd…|d$ f }| ¡ }|d% }d
||dk< |dd…|d&d'… f |dd…t	jf  }|dd…|d' f }dgd( }t|	dd(… ƒD ].\}}|ˆ k�r$|dd…ˆ  |¡f ||< �q$|\}}t ƒ }t!|	d(d… |
ƒD ]<\}}|ˆ k�rt||dd…ˆ  |¡f  || d)¡d < �qtt"|||||||||ƒ	S )*zRead a dipole text file.TNrm   ú%ú#Fz##z%%zName "(.*) dipoles"r   zEDipole text file is missing field definition comment, cannot parse %sz([X|Y|Z] )\(mm\)c                 S   s   |   d¡ ¡ d S )Nr   z/mm)ÚgroupÚstrip©ÚmatchrM   rM   rN   Ú<lambda>  ó    z#_read_dipole_text.<locals>.<lambda>z	\((.*?)\)c                 S   s   d|   d¡ S )Nú/r   ©rÂ   rÄ   rM   rM   rN   rÆ      rÇ   z(begin|end) c                 S   s   |   d¡d S )Nr   z/msrÉ   rÄ   rM   rM   rN   rÆ   "  rÇ   )	úbegin/mszx/mmzy/mmzz/mmzq/namzqx/namzqy/namzqz/namzg/%)zkhi^2Úfreezvol/mm^3zdepth/mmzlong/mmztrans/mmz	qlong/namz
qtrans/namg•Ö&è.>çü©ñÒMbP?r   z-Could not find necessary fields in header: %szend/msz(Ignoring extra fields in dipole file: %sz6More data fields (%s) found than data columns (%s): %sz%d dipole(s) foundrÊ   éÿÿÿÿzObegin and end fields differed, but only begin will be used to store time valuesc                    s   g | ]}ˆ   |¡‘qS rM   )Úindex)r†   Úfield©ÚfieldsrM   rN   rŽ   E  s     z%_read_dipole_text.<locals>.<listcomp>é	   ç     @�@é   ç    eÍÍAé   é   é   rÈ   )#ÚlistÚopenÚ
startswithÚappendrÃ   ÚsplitÚreÚsearchrÂ   r=   Z
atleast_2dr>   ÚfloatÚIOErrorÚlstripÚsubÚlowerÚsortedÚsetrR   ÚRuntimeErrorÚAssertionErrorr+   rœ   r(   r¤   rb   rÎ   Úanyrj   ÚnewaxisÚ	enumeraterD   Úzipr9   )r]   Zneed_headerZdef_linerC   r¨   ÚfidÚlineÚmZrequired_fieldsZoptional_fieldsZconf_scalesZmissing_fieldsZhandled_fieldsZignored_fieldsr{   rJ   r?   r@   ÚnormrA   rB   ÚoptionalÚfirÏ   rG   rH   rE   rt   rM   rÐ   rN   r¾     s¨    ÿ ÿ ÿ ÿÿÿþÿ
ÿ ÿ
*


,r¾   c              
   C   sÀ  d}d}|j d d …tjf d }|jd d …tjf }d|jd d …tjf  }|||jd ||j| |f}tdddd	d
dddd�}dD ]Z}	t||	ƒ}
|
d k	r„|||	 d 7 }|||	 d 7 }||
d d …tjf ||	 d  f7 }q„dD ]\}	|j	 
|	¡}
|
d k	rä|||	 d 7 }|||	 d 7 }||
d d …tjf ||	 d  f7 }qätj|dd�}t| dƒ�\}| d d¡¡ | |d  d¡¡ tj|||d� |jd k	�r²| d|j  d¡¡ W 5 Q R X d S )Nz=  %7.1f %7.1f %8.2f %8.2f %8.2f %8.3f %8.3f %8.3f %8.3f %6.2fzW#   begin     end   X (mm)   Y (mm)   Z (mm)   Q(nAm)  Qx(nAm)  Qy(nAm)  Qz(nAm)    g/%rÓ   rÕ   rÌ   )z	    khi^2z %8.1fr_   )z  freez %5dr   )z
  vol/mm^3ú %9.3frÕ   )z
  depth/mmró   rÓ   )z	  long/mmz %8.3frÓ   )z
  trans/mmró   rÓ   )z  Qlong/nAmz %10.3frÕ   )z  Qtrans/nAmz %11.3frÕ   )rG   rH   ÚvolÚdepthÚlongrv   ÚqlongÚqtrans)rG   rH   r   r   rØ   )rô   rõ   rö   rv   r÷   rø   rÍ   ©ZaxisÚwbz# CoordinateSystem "Head"
zutf-8Ú
)Úfmtz$## Name "%s dipoles" Style "Dipoles")rJ   r=   rê   rB   r@   r?   rA   rD   rc   rE   r‹   ÚconcatenaterÚ   ÚwriteÚencodeZsavetxtrC   )r]   Údiprü   r‘   ÚtrB   ÚampÚoutZfmtsrK   r¨   rí   rM   rM   rN   r\   \  sL    ù	
&&ÿÿr\   )rõ   rö   rv   r÷   rø   c              
   C   s  d }d }t | dƒ��â}tƒ }tƒ }tƒ }tƒ }tƒ }ttƒ d�}	tƒ }
d }t | d¡d¡}t|ƒdkrl�qò| t | d¡d¡d ¡ | d¡ | d¡ | t | d¡d¡¡ t | d¡d¡}| tj 	|¡¡ | ||d  ¡ | d	t | d¡d¡d  ¡ t
t | d¡d¡d ƒ}|d k�rH|}tD ]}tƒ |	|< �q6||k�sVt‚| d¡ t | d
¡d¡}tt|ƒD ]\}}|	|  |¡ �q|| d	¡ |	d  t | d¡d¡d ¡ |
 t | d¡d¡d ¡ | d¡ | d¡ qJW 5 Q R X t|||||||	|
|ƒ	S )NÚrb)rô   rÔ   ú>i4r   ú>f4é   rÍ   éd   é   rô   )rÚ   rÙ   rD   r=   Z
frombufferr¼   rR   rÜ   r�   rð   ÚboolÚ_BDIP_ERROR_KEYSrè   rì   r9   )r]   rC   rH   rí   rJ   r?   r@   rA   rB   rE   rG   Ú
has_errorsÚnumÚQZthis_has_errorsrK   ZlimitsZlimrM   rM   rN   r½   Š  sL    

 


 
r½   c              	   C   s  t | dƒ��ü}t|jƒD �]è\}}| t dd¡ ¡ ¡ | t |dg¡ d¡ ¡ ¡ | t dd¡ ¡ ¡ | |j	|  d¡ ¡ ¡ |j
| |j|  }| | d¡ ¡ ¡ | t |j| d d¡ ¡ ¡ ttt|jƒƒƒ}| t |d¡ ¡ ¡ | t dd¡ ¡ ¡ tD ]J}||jk�r.|j| | nd}|jd	k�sBt‚| t |d¡ ¡ ¡ �q| t d
d¡ ¡ ¡ d|jk�rŒ|jd | nd}	| t |	d¡ ¡ ¡ |jd k	�r¼|j| nd}
| t |
d¡ ¡ ¡ | t dd¡ ¡ ¡ | t dd¡ ¡ ¡ qW 5 Q R X d S )Nzwb+r   r  r   r  é   g      Y@ç        rM   é   rô   )rÚ   rë   rJ   rþ   r=   ÚzerosÚtobytesr>   r’   r?   r@   rA   rB   r“   r
  rR   rE   r  rœ   rè   rG   )r]   r   rí   Útir  r  r  rK   ÚvalrE   rG   rM   rM   rN   r[   µ  s.     r[   c           	      C   sf   t || |dd�}tj|dd�}t |¡ ¡ s0t‚| ¡ }tƒ \}}}|d||jƒ}t 	d¡}|||fS )z5Compute the forward solution and do other nice stuff.T)Zsilentr   rù   r_   r  )
r   r=   rý   ÚisfiniteÚallrè   rj   Ú_get_ddot_dgemv_dgemmÚTZones)	Úfwd_dataÚwhitenerÚrrÚn_jobsÚBÚB_origr©   ZdgemmÚscalesrM   rM   rN   Ú_dipole_forwardsÒ  s    
r!  c              	   C   sÄ   d| kr,t  dt| d  t| d ƒf ¡ nt  dd| d   ¡ t  dd|  ¡ t| ||d| d	|d
�d }d|ks|t‚t|d |d  |d |d  |d |d t |d ¡dd�}t	|gƒS )z2Make a guess space inside a sphere or BEM surface.r  z'Guess surface (%s) is in %s coordinatesÚidrz   z6Making a spherical guess space with radius %7.1f mm...éè  ÚRzFiltering (grid = %6.f mm)...F)Zdo_neighborsr  r   ÚvertnoÚnnÚnuseZdiscrete)r  r&  r'  rz   r%  Útype)
r(   r¤   r$   r   r%   rè   rD   r=   Úaranger&   )rr   Úgridr¶   Zmindistr  r)   ÚsrcrM   rM   rN   Ú_make_guessesæ  s0    

ÿÿ
ÿ ÿÿ  þr,  c                 C   sb   |dkr<t ||| tjdd…f ƒd }t||dd�\}}	}
n
|\}}	}
t||	|
||ƒd }d| S )z&Calculate the residual sum of squares.Nr   T)Zoverwrite_ar_   )r!  r=   rê   r2   Ú_dipole_gof)Úrdr  ÚB2Úfwd_svdr  r  ÚlworkÚfwdÚuuÚsingÚvvrB   rM   rM   rN   Ú	_fit_evalû  s    
r6  c                   C   s   t tjdƒS )N)ÚdotZgemvZgemm)r3   r=   Zfloat64rM   rM   rM   rN   r    s    r  c                 C   sf   t ƒ \}}}|d |d dkr&|d nd dkr4dnd}|d|d|… |ƒ}	||	|	ƒ}
|
| }||	fS )z3Calculate the goodness of fit from the forward SVD.rØ   r   r_   gš™™™™™É?r  N)r  )r3  r4  r5  r  r/  ZddotZdgemvr©   ÚncompÚoneZBm2rB   rM   rM   rN   r-    s    ,
r-  c                 C   sˆ  ddl m} d| krx|dks t‚| d }|jd dks:t‚| d }	|	jd dksTt‚| d }
|
jdksjt‚| d	 d }n$t| ||tjdd…f ƒ\}}	}
d}|dk�r
|dkr¼|j|d
d�}|\}}}t|||||ƒ\}}t	|ƒ}||d|…  }t 
||jd|… ¡}nTt 
|tj |¡}tj |¡}t 
|| |¡}|| d | }|t || ¡ }d}||
d 9 }|t 
|	j|¡ }||||fS )z1Fit the dipole moment once the location is known.r   ©r�   r2  Nr  Úfwd_origr   ©r  r0  F©Zfull_matrices)Úscipyr�   rè   rœ   r!  r=   rê   Úsvdr-  rR   r7  r  rð   Úsum)r  r  r  r/  r  r.  rA   r�   r2  r;  r   r0  r3  r4  r5  rB   r9  r8  r  ZB_residual_noprojrM   rM   rN   Ú_fit_Q  s>    ÿ


rA  c                    s@  ddl m‰ t| |	ƒ\}‰}	|‡‡‡‡‡‡‡‡‡	‡
f
dd„t|j|ƒD ƒƒ}t dd„ |D ƒ¡}t dd„ |D ƒ¡}t dd„ |D ƒ¡‰t d	d„ |D ƒ¡d
 }d‰ |d d dk	rît dd„ |D ƒ¡‰ ddddddg}‡ fdd„t|ƒD ƒ‰ t dd„ |D ƒ¡}t dd„ |D ƒ¡}t dd„ |D ƒ¡j}||ˆ|ˆ |||fS )z:Fit a single dipole to the given whitened, projected data.r   )Úfmin_cobylac                 3   s.   | ]&\}}ˆˆ||ˆˆˆˆ	ˆ ˆˆˆƒV  qd S r;   rM   )r†   r  r  )
rB  r  Ú
guess_dataÚ	guess_rrsÚmin_dist_to_inner_skullrA   Úp_funÚrankÚrhoendr  rM   rN   Ú	<genexpr>C  s   ý
     þz_fit_dipoles.<locals>.<genexpr>c                 S   s   g | ]}|d  ‘qS )r   rM   ©r†   rm   rM   rM   rN   rŽ   G  s     z _fit_dipoles.<locals>.<listcomp>c                 S   s   g | ]}|d  ‘qS )r   rM   rJ  rM   rM   rN   rŽ   H  s     c                 S   s   g | ]}|d  ‘qS )rØ   rM   rJ  rM   rM   rN   rŽ   I  s     c                 S   s   g | ]}|d  ‘qS r<  rM   rJ  rM   rM   rN   rŽ   J  s     r  NrÔ   c                 S   s   g | ]}|d  ‘qS )rÔ   rM   rJ  rM   rM   rN   rŽ   M  s     rô   rõ   rö   rv   r÷   rø   c                    s"   i | ]\}}|ˆ d d …|f “qS r;   rM   )r†   ZkirK   )rE   rM   rN   r‰   O  s      z _fit_dipoles.<locals>.<dictcomp>c                 S   s   g | ]}|d  ‘qS )rÖ   rM   rJ  rM   rM   rN   rŽ   P  s     c                 S   s   g | ]}|d  ‘qS )é   rM   rJ  rM   rM   rN   rŽ   Q  s     c                 S   s   g | ]}|d  ‘qS )é   rM   rJ  rM   rM   rN   rŽ   R  s     )Zscipy.optimizerB  r'   rì   r  r=   r>   rë   )ÚfunrE  r¨   rJ   rD  rC  r  r  rA   r  rG  rH  ÚparallelÚresr?   r  rB   re   rG   rH   Úresidual_noprojrM   )rE   rB  r  rC  rD  rE  rA   rF  rG  rH  r  rN   Ú_fit_dipoles=  s$    
ýrQ  c                 C   sÖ  ddl m} t d¡}||d< | |d d  }||t ||¡  |d< |d  tj |d ¡  < t |d |d ¡|d< t t ||j¡t 	d¡¡sšt
‚d	}t |jd d
f¡}	tdƒD ]r}
g }|D ]8}| tj |||
   }| t |t|||ƒd ¡¡ qÆtj|dd�d t |¡d  |	d d …|
f< qºt ddg¡tj |¡ }t||| tj ƒd }tdƒD ]d}
g }|D ]$}| t ||||
   |¡¡ �qrtj|dd�d t |¡d  |	d d …|
d f< �qftj |	d d …d d…f ¡}tj |	d d …dd…f ¡}t |gd |gd  ¡}|	| }	t |	j|	¡}	t|	dd�}|| }||d d …tjf  }dt t |¡¡ }dtj d t dt |j|d d…d d…f dd�¡ ¡ }t ||gg¡}|d
dddddg }|S )Nr   r:  )r  r  Úinner_skullÚr0rØ   r   r  )g-Cëâ6¿g-Cëâ6?rK  rù   g{®Gáz„¿g{®Gáz„?rÖ   g›+¡†›„=)Zrtolg\�Âõ(\ÿ?rÔ   g      @gÜg•™Æ}@T)Zeigvals_only)r>  r�   r=   Úemptyr7  rð   ÚcrossZallcloser  Úeyerè   rœ   Úrangerê   rÜ   r!  rb   r>   r   ÚsqrtZdiagÚpiÚprodZeighrý   )r.  r  rA   r  r  r�   Ú	directionZrvecZdeltasÚJÚiiZfwdsÚdeltaZthis_rZthis_fwdZdirection_normZQ_normrð   ÚCrE   Zvol_confrM   rM   rN   Ú_fit_confidence´  sP    

 ÿ."4&ÿr`  c                 C   sZ   t |d | tjdd…f dd�d d }t| tjdd…f |dƒd rN|d9 }||8 }|S )zSurface fitting constraint.r  NT©Zreturn_distsr   r   g      ð¿)r!   r=   rê   r"   )r.  rr   rE  ÚdistrM   rM   rN   Ú_surface_constraintó  s    ÿÿÿrc  c                 C   s   |t  t  | | d ¡¡ S )zSphere fitting constraint.rØ   )r=   rX  r@  )r.  rS  ÚR_adjrM   rM   rN   Ú_sphere_constraint  s    re  c              	      sÔ  t  ||¡‰ d|d kr0|d }tt|| d�}n&d}tt|d d |d d |  d�}t  ˆ ˆ ¡‰ˆdkr�td	| ƒ t  d
¡dt  d
¡dˆ fS t  ‡ ‡‡fdd„t|d ƒD ƒ¡}ˆ| }t	d
ˆ j
d fƒ}ttˆ ˆ|||d�}||||fdd|
dd�}t||ˆ ˆ|||d�\}}}}d| ˆ }|	| }t  t  ||¡¡}|dk�rLdn|}|| }t|||||ƒ}dd|  }|dk	�r¶t|d |t jdd…f dd�d d }|d|d  7 }t |¡ ||||||||fS )zFit a single bit of data.r  rR  )rr   rE  NrS  r$  )rS  rd  r   úZero field found for time %sr  c                    s,   g | ]$\}}t ˆ|gd d …f ˆ ˆ|ƒ‘qS r;   )r6  )r†   rò   r0  ©r  r/  rD  rM   rN   rŽ     s   ÿz_fit_dipole.<locals>.<listcomp>r0  )r  r/  r  r  r1  rM   gš™™™™™©?F)ZconsargsZrhobegrH  Údisp)rA   r   r  r_   z---- Fitted : %7.1f msrÓ   Tra  z$, distance to inner skull : %2.4f mm)r=   r7  r   rc  re  r+   r  Zargminrë   r1   rœ   r6  rA  rX  r`  r!   rê   r(   r¤   )rE  r  r  rD  rC  r  r  rB  rA   rG  rH  rr   Ú
constraintr{   Zx0r1  rM  Úrd_finalr  rB   rP  Zn_comprG   rH   r  rð   rE   ÚmsgZdist_to_inner_skullrM   rg  rN   Ú_fit_dipole  sx    ÿ 
þ
ÿÿ  ÿ      ÿ
  ÿÿÿÿ
rl  c              	   C   sØ   t  ||¡}t  ||¡}|dkrLtd| ƒ t  d¡dt  d¡dt  d¡fS t|||||d|d�dd… \}}}|dkr¤t  t  ||¡¡}|dkr–dn|}|| }nt  ||¡}|d }d } }}||||||||fS )	z"Fit a data using a fixed position.r   rf  r  rK  N)r.  rA   r  r_   )r=   r7  r+   r  rA  rX  )rE  r  r  rD  rC  r  r  rB  rA   rG  rH  r  r/  r  rB   rP  r  rð   rj  rE   rG   rH   rM   rM   rN   Ú_fit_dipole_fixedF  s&      ÿÿ
rm  ç      @Únormalç-Cëâ6
?c           8         s>  ddl m‰ |  ¡ } t|	tdƒ td|	dƒ t| jƒr>tdƒ‚|dk rRtd| ƒ‚|dk	rj|dkrjtdƒ‚| j	}t
 |¡ ¡ s†td	ƒ‚| j‰ | j ¡ }| j}|d
 }~ttˆ dddg d�ƒ}t|tƒrÌ|}nt|ƒ}t d| ¡ t|ƒ\}}t d| ¡ t||||dd�}|d �sžt|dƒ}| ¡ }t|d dd�\}}t|d |t
jdd…f ƒd }||d< t dd|d  d|d  d|d  d| f ¡ ~~nü|d }t| dg ¡ƒdk�rÒ|d d d }d}nˆt
 t
j ˆ d d ¡t
 |dgg¡¡dd… }|‡ fd d!„tˆ dg d"�D ƒ }t|ƒdk�r8td#ƒ‚t
 t
  t
j!|| dd$�¡¡}d%}t d&d|d  d|d  d|d  ||f ¡ t"||d'�}~~|dk	�rhd}t
 #|t$¡}|j%d(k�rÎtd)|f ƒ‚t d*t&d| ƒ ¡ |dk	�rXt
 #|t$¡}|j%d(k�rtd+|f ƒ‚t
  t
 !|| ¡¡}t
 '|d¡�sDtd,|f ƒ‚t d-t&|ƒ ¡ n
t d.¡ d}n|d}d/}t(d0|ƒ}d/}t d1d| f ¡ |d2k�r°t d3d| f ¡ |dk�rÎt d4d| f ¡ t d5|	› d6�¡ |}t)|ƒ}t d7¡ t*|ƒ t*ˆ d ƒ t d8tˆ d9 ƒ ¡ |  +¡ }g g g df\}}} }!g g  }"}#d:|k�sZd;|k�rrt,ˆ d9|	|d<�\}}} }!d=|k�rŽt-ˆ d9|d>�\}"}#t||" ƒdk�r¨td?ƒ‚t d@¡ tˆ ddddA�}$t.|ˆ |$|ddB�\}%}&}|�rt"d|t
j t
 #dg¡dC�}'t dD¡ n6t dE¡ t/|||||dF�d }'t0|'dG|ƒ t dH¡ d|k�rTt0|dG|ƒ |�r¨d|k�rrt1|||ƒ}(nt2||d |dI | dJ�}(|(dk�r¨tdKdL|( f ƒ‚t"||"g|!dg|dgdMd=g|dN�})t3|'d ||)|dd� t4|)|%|'d |dF�\}*}+},‡fdOd!„t
 5|*t|'d ƒ¡D ƒ}-t"|*|-|+|,dP�}.~*~-~+~,t dQ|'dR t6|'dR ƒf ¡ ||$ }‡ fdSd!„|$D ƒ}/t7ˆ dT |/ˆ d9 ƒd }0|�rŽt8nt9}1t:|1||||'d |.|)|%||||
ƒ}2t|2ƒdUk�sÆt;‚|�rÌ|dk	�rÌt
 #|2d |2d g¡}t<ˆ ƒ}3t
 =||t
 >dV¡g¡}4d|3_?t"dW|4t@jAt@jBt@jCt@jDddddddX�t"dYt
 EdZt
jF¡t@jGt@jCt@jBt@jHddddd[d\�g|3d]< d^D ]}5tIƒ |3|5< �qnd_D ]}5d|3|5< �q„d|3_?g |3d9< |3 J¡  |3 K¡  tL|3||| jM| jN|d`�}6n4tO||2d |2d |2d |2d ||2da |2db |2dV ƒ	}6|  ¡  P¡ }7t
 |0|2dc ¡|7j	|$< t ddt|6jƒ ¡ |6|7fS )ea¯	  Fit a dipole.

    Parameters
    ----------
    evoked : instance of Evoked
        The dataset to fit.
    cov : str | instance of Covariance
        The noise covariance.
    bem : str | instance of ConductorModel
        The BEM filename (str) or conductor model.
    trans : str | None
        The head<->MRI transform filename. Must be provided unless BEM
        is a sphere model.
    min_dist : float
        Minimum distance (in millimeters) from the dipole to the inner skull.
        Must be positive. Note that because this is a constraint passed to
        a solver it is not strict but close, i.e. for a ``min_dist=5.`` the
        fits could be 4.9 mm from the inner skull.
    %(n_jobs)s
        It is used in field computation and fitting.
    pos : ndarray, shape (3,) | None
        Position of the dipole to use. If None (default), sequential
        fitting (different position and orientation for each time instance)
        is performed. If a position (in head coords) is given as an array,
        the position is fixed during fitting.

        .. versionadded:: 0.12
    ori : ndarray, shape (3,) | None
        Orientation of the dipole to use. If None (default), the
        orientation is free to change as a function of time. If an
        orientation (in head coordinates) is given as an array, ``pos``
        must also be provided, and the routine computes the amplitude and
        goodness of fit of the dipole at the given position and orientation
        for each time instant.

        .. versionadded:: 0.12
    %(rank_none)s

        .. versionadded:: 0.20
    accuracy : str
        Can be "normal" (default) or "accurate", which gives the most accurate
        coil definition but is typically not necessary for real-world data.

        .. versionadded:: 0.24
    tol : float
        Final accuracy of the optimization (see ``rhoend`` argument of
        :func:`scipy.optimize.fmin_cobyla`).

        .. versionadded:: 0.24
    %(verbose)s

    Returns
    -------
    dip : instance of Dipole or DipoleFixed
        The dipole fits. A :class:`mne.DipoleFixed` is returned if
        ``pos`` and ``ori`` are both not None, otherwise a
        :class:`mne.Dipole` is returned.
    residual : instance of Evoked
        The M-EEG data channels with the fitted dipolar activity removed.

    See Also
    --------
    mne.beamformer.rap_music
    Dipole
    DipoleFixed
    read_dipole

    Notes
    -----
    .. versionadded:: 0.9.0
    r   r:  Úaccuracy)Zaccuratero  z6EEG average reference is mandatory for dipole fitting.z#min_dist should be positive. Got %sNz'pos must be provided if ori is not NonezEvoked data must be finiterÓ   FT)ÚmegÚeegÚref_megr¶   zBEM               : %szMRI transform     : %sr:   Z	is_sphererR  r  )rh  rv   rS  z8Head origin       : %6.1f %6.1f %6.1f mm rad = %6.1f mm.r#  r   rØ   ZlayersZradZ
dev_head_tr_   r  c                    s$   g | ]}ˆ d  | d dd… ‘qS )ÚchsÚlocNr  rM   )r†   Úpickr°   rM   rN   rŽ   ç  s   ÿzfit_dipole.<locals>.<listcomp>)rr  r¶   z5No MEG channels found, but MEG-only sphere model usedrù   Zmax_radzFSphere model      : origin at (% 7.2f % 7.2f % 7.2f) mm, %s = %6.1f mm)r$  rS  r<  z2pos must be None or a 3-element array-like, got %sz(Fixed position    : %6.1f %6.1f %6.1f mmz3oris must be None or a 3-element array-like, got %sz(ori must be a unit vector, got length %sz)Fixed orientation  : %6.4f %6.4f %6.4f mmz#Free orientation   : <time-varying>g{®Gáz”?g{®Gázt?zGuess grid        : %6.1f mmr  zGuess mindist     : %6.1f mmzGuess exclude     : %6.1f mmzUsing z MEG coil definitions.r«   z%d bad channels totalZbadsZgradÚmag)r¶   rq  r)   rs  )r¶   r)   zNo MEG or EEG channels found.z1Decomposing the sensor noise covariance matrix...)rr  rs  rt  )rµ   rG  Zreturn_rank)r'  r  Zinusez&Compute forward for dipole location...z7
---- Computing the forward solution for the guesses...)r  Úheadz(Go through all guess source locations...r$  )rd  z:fixed position is %0.1fmm outside the inner skull boundaryiüÿÿrr  )Z
coils_listÚinfosZccoils_listZ
coil_typesrR  c                    s   g | ]}ˆ j |d d�‘qS )Fr=  )r?  )r†   r2  r:  rM   rN   rŽ   k  s   ÿ)r2  r0  r;  r   z[done %d source%s]r'  c                    s   g | ]}ˆ d  | ‘qS )r¯   rM   )r†   Úpr°   rM   rN   rŽ   v  s     Úprojsr×   rK  zdip 01)Úch_namerv  r®   rz   r·   Ú	coil_typeÚunit_mulrW  ÚcalÚscannoÚlognoZgoodnessr  r  )r}  rv  r®   r·   rz   r~  r  rW  r€  r�  r‚  ru  )Zhpi_measZhpi_resultsr|  )	Zacq_parsZacq_stimÚdescriptionÚdigZexperimenterZhpi_subsystemZproj_idZ	proj_nameZsubject_infor¢   rÔ   rÖ   rÍ   z%d time points fitted)Qr>  r�   rj   r4   Ústrr0   r   r¤   Ú
ValueErrorr¨   r=   r  r  rJ   r£   rR   r	   r™   Úreprr(   r   r   r#   r   r   rê   r‹   r7  r�   Zhstackrç   rS   rX  r@  rD   r>   rà   rœ   rŒ   ÚiscloserT   r   r   Zget_channel_typesr   r   r   r,  r    rc  re  r   r!  Zarray_splitr.   r
   rm  rl  rQ  rè   r   rý   r  Z	_unlockedr   ZFIFFV_DIPOLE_WAVEZFIFFV_COORD_UNKNOWNZFIFF_UNIT_AMZFIFFV_COIL_DIPOLEÚfullÚnanZFIFFV_GOODNESS_FITZFIFFV_COIL_NONErÙ   Z_update_redundantZ_check_consistencyr¥   r¦   r­   r9   Z
apply_proj)8ÚevokedÚcovÚbemrv   Zmin_distr  r?   rA   rG  rq  Ztolr)   r¨   rJ   r£   rE  ZneegZ	bem_extrar�   rR  r$  rS  r®   Zfixed_positionrð   Z
fit_n_jobsZ
guess_gridZguess_mindistZguess_excludeZch_typesZmegcoilsZ	compcoilsZmegnamesZmeg_infoZeegelsZeegnamesrµ   r  r©   Z	guess_srcr³   r  Z	guess_fwdZguess_fwd_origZguess_fwd_scalesZguess_fwd_svdrC  r¯   Zproj_oprM  r  Zout_inforv  rK   ÚdipolesZresidualrM   )r¤   r�   rN   Ú
fit_dipole`  sð   K

ÿ


 &þÿÿÿ$þ
ÿ
ÿ
ÿÿÿ


ÿ
ÿ

 ÿÿ

ÿ

 ÿ
 ÿÿ


ÿ 
þ
ÿ þÿ   ÿ

ÿÿ ÿ
ÿ          þ
     ý     üû
 ÿ  ÿr�  Ú
vectorviewc              
   C   sH  t d| ddgƒ | dkrät dddddd	d
dg¡}t ddddddddg¡}t |dgd | dgd f¡}t dgd | dgd |f¡}ddddddddg}ddd d!d"d#d$d%g}t ||||f¡}d&d'gd( d'd&gd(  d) }n¬| dk�r�t d*d+d,d-g¡}t d.d	d/d0g¡}t d(¡}t ||||| | ||f¡}t ||| | ||||f¡}t ||||||||f¡}d'gd d&gd1  d'gd  }t |||f¡jd2 }	tƒ }
t|	ƒD ]€\}}t d3¡}t 	|dk¡d }t 
t d3¡|d ¡}|| d4d4d'… tj || ¡ d&d'g ||< ||| 9 }|
 |¡ �q´t |
¡}
|	|
fS )5aÐ  Get standard phantom dipole locations and orientations.

    Parameters
    ----------
    kind : str
        Get the information for the given system:

            ``vectorview`` (default)
              The Neuromag VectorView phantom.
            ``otaniemi``
              The older Neuromag phantom used at Otaniemi.

    Returns
    -------
    pos : ndarray, shape (n_dipoles, 3)
        The dipole positions.
    ori : ndarray, shape (n_dipoles, 3)
        The dipole orientations.

    See Also
    --------
    mne.datasets.fetch_phantom

    Notes
    -----
    The Elekta phantoms have a radius of 79.5mm, and HPI coil locations
    in the XY-plane at the axis extrema (e.g., (79.5, 0), (0, -79.5), ...).
    r®   r�  Zotaniemigš™™™™ÙM@gÍÌÌÌÌLH@gfffffæA@gÍÌÌÌÌÌ8@gš™™™™™B@g     €;@gš™™™™™/@gš™™™™™@gÍÌÌÌÌG@g33333óD@gfffff&C@g     €?@gÍÌÌÌÌÌ+@g3333330@g      4@gÍÌÌÌÌL3@r   r×   gfffffæ6@g     €7@g     €9@gš™™™™7@g      J@g333333G@g     €D@g     €@@g333333F@g      A@gš™™™™™5@gffffff)@g333333O@g     ÀI@gÍÌÌÌÌŒC@gfffffæ;@r   rÍ   rÔ   rØ   gfffff&L@gÍÌÌÌÌÌG@g     €C@gÍÌÌÌÌL>@g     @@@g     €6@g     €1@é   rÓ   r  N)r0   r=   r>   rý   r  Zvstackr  rÙ   rë   ÚwhereZ	setdiff1dr)  r�   rð   rÜ   )r®   ÚaÚbÚxÚyÚcÚdÚzZsignsr?   rA   rY  Zthis_posZthis_orir{   rM   rM   rN   Úget_phantom_dipoles¢  sB      


ÿÿ
rš  c                 C   s�   g g g g g f\}}}}}| D ]@}|  |j¡ |  |j¡ |  |j¡ |  |j¡ |  |j¡ qtt |¡t |¡t |¡t |¡t |¡dd�S )zConcatenate a list of dipoles.N)rC   )	rÜ   rJ   r?   r@   rA   rB   r9   r=   rý   )rŽ  rJ   r?   r@   rA   rB   ZdipolerM   rM   rN   Ú_concatenate_dipolesì  s      þr›  )N)N)NN)NNNN)N)	Nrn  NNNNro  rp  N)r�  )cr¡   rj   r   Ú	functoolsr   rÞ   Únumpyr=   rŒ  r   r   Zio.constantsr   Zio.pickr	   Zio.projr
   r   r�  r   r‹  r   r   r   Úfixesr   Z_freesurferr   r   Z
transformsr   r   r   Z
viz.evokedr   r   r   Zforward._make_forwardr   r   r   r   Zforward._compute_forwardr   r   Zsurfacer    r!   r"   r#   r$   Zsource_spacer%   r&   rN  r'   Úutilsr(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r—   r8   r9   rª   r¥   r¿   r¾   r\   r  r½   r[   r!  r,  r6  Ú	lru_cacher  r-  rA  rQ  r`  rc  re  rl  rm  r�  rš  r›  rM   rM   rM   rN   Ú<module>   s†   D  6v![++
  ÿ



&w?@           þ  C
J