U
    f»{jÏ<  ã                   @   s&  d Z ddlmZ ddlmZ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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 d	dlmZ d	dlmZ dVdd„ZG dd„ deƒZdd„ Z dd„ Z!dWdd„Z"dXdd„Z#dZ$dZ%dZ&ee#dd �Z'ee#d!d �Z(ee#d"d �Z)ee#d#e$d$�Z*d%d&„ Z+ee#d'e&d$�Z,ee#d(d)d$�Z-ee#d*d �Z.ee#d+d �Z/d,d-„ Z0d.d/„ Z1G d0d1„ d1e2ƒZ3G d2d3„ d3e2ƒZ4d4d5„ Z5d6d7„ Z6d8d9„ Z7d:d;„ Z8dYd<d=„Z9d>d?„ Z:d@dA„ Z;dBdC„ Z<dZdEdF„Z=d[dHdI„Z>dJdK„ Z?dLdM„ Z@dNdO„ ZAd\dPdQ„ZBedRdS„ ƒZCd]dTdU„ZDdS )^zTesting functions.é    )Úcontextmanager)ÚpartialÚwrapsN)ÚStringIO)Úrmtree)ÚSkipTest)Úassert_array_equalÚassert_allcloseé   )ÚwarnÚClosingStringIO)Úcheck_version)Úobject_difféÿÿÿÿú> c                 C   s\   t  ¡ \}}}t t |¡| |… ¡}d |¡ d¡t ||¡ }d| d|  |¡ }|S )zExplain an exception.Ú Ú
z:
)ÚsysÚexc_infoÚ	tracebackÚformat_listÚ
extract_tbÚjoinÚsplitÚformat_exception_only)ÚstartÚstopÚprefixÚetypeÚvalueÚtbÚstring© r"   úQ/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/utils/_testing.pyÚ_explain_exception   s    
ÿr$   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	Ú_TempDiraÜ  Create and auto-destroy temp dir.

    This is designed to be used with testing modules. Instances should be
    defined inside test functions. Instances defined at module level can not
    guarantee proper destruction of the temporary directory.

    When used at module level, the current use of the __del__() method for
    cleanup can fail because the rmtree function may be cleaned up before this
    object (an alternative could be using the atexit module instead).
    c                 C   s   t  | tjdd�¡}|S )NZtmp_mne_tempdir_)r   )ÚstrÚ__new__ÚtempfileÚmkdtemp)ÚselfÚnewr"   r"   r#   r'   1   s    z_TempDir.__new__c                 C   s   |   ¡ | _d S ©N)Ú__str__Ú_path©r*   r"   r"   r#   Ú__init__5   s    z_TempDir.__init__c                 C   s   t | jdd� d S )NT)Úignore_errors)r   r.   r/   r"   r"   r#   Ú__del__8   s    z_TempDir.__del__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r'   r0   r2   r"   r"   r"   r#   r%   %   s   r%   c                   C   s   t tdd�S )zEWrap to requires_module with a function call (fewer lines to change).Únibabel©Úname)r   Úrequires_moduler"   r"   r"   r#   Úrequires_nibabel<   s    r;   c               
   C   s˜   ddl } z@ddlm}m}m}m} ddlm} ddlm	} ddl
m} W n. tk
rv } zd}	t|ƒ}
W 5 d}~X Y n
X d}
d	}	| jj|	 d
|
› �d�S )zCheck for dipy.r   N)ÚimaffineÚimwarpÚmetricsÚ
transforms)Úreslice)Ú	AffineMap)ÚDiffeomorphicMapFr   TzRequires dipy >= 0.10.1, got: ©Úreason)ÚpytestZ
dipy.alignr<   r=   r>   r?   Zdipy.align.reslicer@   Zdipy.align.imaffinerA   Zdipy.align.imwarprB   Ú	Exceptionr&   ÚmarkÚskipif)rE   r<   r=   r>   r?   r@   rA   rB   ÚexcZhaveÚwhyr"   r"   r#   Úrequires_dipyA   s     ÿrK   ú0.0c                 C   s@   ddl }d| › �}|dkr(|d|› �7 }|jjt| |ƒ |d�S )zCheck for a library version.r   Nz	Requires rL   z version >= rC   )rE   rG   rH   r   )ZlibraryÚmin_versionrE   rD   r"   r"   r#   Úrequires_versionY   s    
ÿrN   c              
   C   s°   ddl }|dkrd| n|}d| j|f }zt|ƒtƒ ktƒ f W nT tk
r– } z6tt|ƒƒdkr‚t|ƒd| kr‚|d|f 7 }d}W 5 d}~X Y nX d}|jj	||d	�| ƒS )
z4Skip a test if package is not available (decorator).r   Nz	import %szTest %s skipped, requires %s.zNo module named %sz Got exception (%s)TFrC   )
rE   r3   ÚexecÚglobalsÚlocalsrF   Úlenr&   rG   rH   )Úfunctionr9   ÚcallrE   rD   rI   Úskipr"   r"   r#   r:   c   s     r:   z+
if not has_mne_c():
    raise ImportError
z0
if not has_freesurfer():
    raise ImportError
z@
if 'NEUROMAG2FT_ROOT' not in os.environ:
    raise ImportError
Zpandasr8   ZpylslZsklearnzMNE-C©r9   rT   c                 C   s:   t | tƒr(d| f }ttd| f |d�S t| dtd�S dS )zRequire Freesurfer.z@
from . import run_subprocess
run_subprocess([%r, '--version'])
zFreesurfer (%s)rV   Z
FreesurferN)Ú
isinstancer&   r   r:   Ú_fs_call)ÚargrT   r"   r"   r#   Úrequires_freesurferˆ   s    
ý  ÿrZ   Zneuromag2ftzgood network connectionzJif int(os.environ.get("MNE_SKIP_NETWORK_TESTS", 0)):
    raise ImportErrorZnitimeZh5pyc                 C   s   t ddƒ| ƒS )z"Decorate tests that need numpydoc.Znumpydocz1.0)rN   )Úfuncr"   r"   r#   Úrequires_numpydoc¥   s    r\   c                  C   s*   t  ¡ jj} |  dd¡dkr&| d ƒ  dS )z%Run a given command if it's __main__.r3   r   Ú__main__ÚrunN)ÚinspectÚcurrentframeÚf_backÚf_localsÚget)Ú
local_varsr"   r"   r#   Úrun_command_if_mainª   s    re   c                   @   s*   e Zd ZdZddd„Zdd„ Zdd	„ Zd
S )Ú
ArgvSetterzTemporarily set sys.argv.r"   Tc                 C   s6   t d| ƒ| _|rtƒ ntj| _|r*tƒ ntj| _d S )N)Úpython)ÚlistÚargvr   r   ÚstdoutÚstderr)r*   ÚargsZdisable_stdoutZdisable_stderrr"   r"   r#   r0   ´   s    zArgvSetter.__init__c                 C   s4   t j| _| jt _t j| _| jt _t j| _| jt _| S r,   )r   ri   Ú	orig_argvrj   Úorig_stdoutrk   Úorig_stderrr/   r"   r"   r#   Ú	__enter__º   s    zArgvSetter.__enter__c                 G   s   | j t_| jt_| jt_d S r,   )rm   r   ri   rn   rj   ro   rk   ©r*   rl   r"   r"   r#   Ú__exit__Ã   s    zArgvSetter.__exit__N)r"   TT©r3   r4   r5   r6   r0   rp   rr   r"   r"   r"   r#   rf   ±   s     ÿ
	rf   c                   @   s*   e Zd ZdZd
dd„Zdd„ Zdd„ Zd	S )ÚSilenceStdoutzSilence stdout.Tc                 C   s
   || _ d S r,   )Úclose)r*   ru   r"   r"   r#   r0   Ì   s    zSilenceStdout.__init__c                 C   s   t j| _tƒ t _t jS r,   )r   rj   r   r/   r"   r"   r#   rp   Ï   s    zSilenceStdout.__enter__c                 G   s   | j rtj  ¡  | jt_d S r,   )ru   r   rj   rq   r"   r"   r#   rr   Ô   s    
zSilenceStdout.__exit__N)Trs   r"   r"   r"   r#   rt   É   s   
rt   c                  C   s,   zddl } W n tk
r"   Y dS X dS dS )zuDetermine if nibabel is installed.

    Returns
    -------
    has : bool
        True if the user has nibabel.
    r   NFT)r7   ÚImportError)r7   r"   r"   r#   Úhas_nibabelÚ   s
    rw   c                   C   s
   dt jkS )zCheck for MNE-C.ZMNE_ROOT©ÚosÚenvironr"   r"   r"   r#   Ú	has_mne_cê   s    r{   c                   C   s
   dt jkS )zCheck for Freesurfer.ZFREESURFER_HOMErx   r"   r"   r"   r#   Úhas_freesurferï   s    r|   c                    s   t ˆ ƒ‡ fdd„ƒ}|S )z>Decorate tests that make calls to SVD and intermittently fail.c               
      sZ   zˆ | |ŽW S  t jjk
rT } z&dt|ƒkrBd}t|ƒ t|ƒ‚‚ W 5 d }~X Y nX d S )NzSVD did not convergez7Intel MKL SVD convergence error detected, skipping test)ÚnpÚlinalgZLinAlgErrorr&   r   r   )rl   ÚkwargsÚexpÚmsg©rS   r"   r#   Údecö   s    zbuggy_mkl_svd.<locals>.dec)r   )rS   rƒ   r"   r‚   r#   Úbuggy_mkl_svdô   s    	r„   c                 C   s\   ddl m} t| |ƒr| j} dD ]6}t | jd| k¡d }t|ƒ|ksLt‚|  	|¡ q dS )z;Assert that there are boundary annotations and remove them.é   ©ÚBaseRaw)ZEDGEÚBADz%s boundaryr   N)
Zio.baser‡   rW   Úannotationsr}   ÚwhereÚdescriptionrR   ÚAssertionErrorÚdelete)r‰   Únr‡   ÚkeyÚidxr"   r"   r#   Ú assert_and_remove_boundary_annot  s    
r‘   c                 C   s   t | |ƒ}|dkst|ƒ‚dS )zAssert two objects are equal.r   N)r   rŒ   )ÚaÚbÚdr"   r"   r#   Úassert_object_equal  s    
r•   c           	   	   C   s    ddl m}m} ddlm} ddlm} |ddd�}|t d¡|dd	�}| d k	rX|| ƒ} |j	j
d
d�� | |j	d< W 5 Q R X |dgdgdg|ƒ}|j|d� |S )Nr…   )ÚAnnotationsÚcreate_info)Ú_handle_meas_date)ÚRawArrayé
   g      $@)Úch_namesZsfreq)rš   rš   )ÚdataÚinfoZ
first_sampT)Zcheck_afterÚ	meas_dateg      à?gš™™™™™É?Údummy)r‰   )r   r–   r—   r‰   r˜   Úior™   r}   Úemptyr�   Z_unlockZset_annotations)	rž   Z	orig_timer–   r—   r˜   r™   r�   ÚrawZannotr"   r"   r#   Ú
_raw_annot  s    r£   c                 C   sF   ddl m} ddlm} t| |ƒr.| | d S t| |ƒrB| j| S dS )z#Get the (n_ch, n_times) data array.r…   )ÚEvokedr†   r   N)Zevokedr¤   r    r‡   rW   rœ   )ÚxZch_idxr¤   r‡   r"   r"   r#   Ú	_get_data#  s    

r¦   ÚMEGc                 C   sÜ   t | |ƒ}t ||ƒ}t tj|| dd�¡}	|| }
t tj|
|
 dd�¡}tj|dtj|d� |	| }| ¡ }||k  ¡ }|dkrŒd| n|}|dks²td|||t	|ƒ|f ƒ‚t 
|¡}||ksØtd	||||f ƒ‚d
S )z#Check the SNR of a set of channels.r
   )Zaxisg&¦¬ª¶y3)Úoutr   z (%s)r   z.SNR (worst %0.2f) < %0.2f for %s/%s channels%sz%s SNR median %0.2f < %0.2f%sN)r¦   r}   ÚsqrtÚmeanZclipÚinfÚminÚsumrŒ   rR   Zmedian)ÚactualÚdesiredÚpicksÚmin_tolÚmed_tolr�   ÚkindZactual_dataZdesired_dataZ	bench_rmsÚerrorZ	error_rmsZsnrsÚsnrZ	bad_countr"   r"   r#   Ú
_check_snr-  s(    

 ÿÿ

ÿr¶   ç     @@c              	   C   s8  ddl m} ||jdg d�}||jdg d�}t||dd� || jddg d�}	||jddg d�}
|d	k	rtt|	|
d
d� t t t| jƒ¡t 	||	g¡¡}t t t|jƒ¡t 	||
g¡¡}t||dd� t|ƒdkrðt
t| |ƒt||ƒdddd� t| |||||dd� |d	k	�r4t|	ƒdk�r4t| ||	d||dd� d	S )z¦Assert channel SNR of a certain level.

    Mostly useful for operations like Maxwell filtering that modify
    MEG channels while leaving EEG and others intact.
    r…   )Ú
pick_typesT)ÚmegÚexcludezMEG pick mismatch)Úerr_msgF)r¹   Zchpirº   NzcHPI pick mismatchzOther pick mismatchr   g•dyáý¥=çñhãˆµøä>znon-MEG channel mismatch)ÚatolÚrtolr»   r§   )r³   g        ZcHPI)Zio.pickr¸   r�   r   r}   Z	setdiff1dZarangerR   r›   Zconcatenater	   r¦   r¶   )r®   r¯   r±   r²   Zchpi_med_tolr�   r¸   r°   Zpicks_desiredZchpisZchpis_desiredZothersZothers_desiredr"   r"   r#   Úassert_meg_snrC  s6    ÿÿÿ
  þr¿   c              	   C   s`   ddl m} tjdd��& |j|dd�|j||  dd� }W 5 Q R X ||ks\td||f ƒ‚dS )	z?Assert actual and desired arrays are within some SNR tolerance.r   )r~   Úignore)ÚdivideZfro)Úordz%f < %fN)Zscipyr~   r}   ZerrstateZnormrŒ   )r®   r¯   Ztolr~   rµ   r"   r"   r#   Ú
assert_snra  s    ÿrÃ   c                 C   sh   t | j|jƒ t | j|jƒ t| jd |jd ƒ t| jd |jd ƒ t | j|jƒ t | j|jƒ dS )zCheck that two STC are equal.r   r
   N)r	   Útimesrœ   r   ZverticesZtminZtstep)Zstc1Zstc2r"   r"   r#   Úassert_stcs_equalj  s    rÅ   c                 C   s   | d | d fS )zSort dig keys.r³   Úidentr"   )Údigr"   r"   r#   Ú_dig_sort_keyt  s    rÈ   c                    sÜ  ddl m} ddlm‰  ddlm} ddlm} | | }}t||ƒrft||ƒsRt	‚|d |d  }}n2t||ƒstt	‚t||ƒs‚t	‚|j
|j
 }}d } }t|tƒs¦t	‚t|tƒs´t	‚t|td�}t|td�}t|ƒt|ƒksàt	‚tt|d|… |d|… ƒƒD ]`\}\}	}
d	D ] }|	| |
| k�st	|ƒ‚�qt|	d
 |
d
 ddd||	d
 |
d
 f d� � qþt‡ fdd„|D ƒƒ�rØ| dk	�rØ||ddd�\}}}|| ddd�\}}}t||dd� t||ddd� t||ddd� dS )zAssert dig allclose.r…   )Úfit_sphere_to_headshape©ÚFIFF)ÚInfo)Ú
DigMontagerÇ   N)r�   )rÆ   r³   Zcoord_frameÚrr¼   zFailure on %s:
%s
%s)r¾   r½   r»   c                 3   s   | ]}|d  ˆ j kV  qdS )r³   N)ZFIFFV_POINT_EXTRA)Ú.0r”   rÊ   r"   r#   Ú	<genexpr>”  s     z&assert_dig_allclose.<locals>.<genexpr>Úmr´   )ZunitsÚverboseg�íµ ÷Æ°>)r½   )r¾   r½   )ZbemrÉ   Zio.constantsrË   Zio.meas_inforÌ   Zchannels.montagerÍ   rW   rŒ   rÇ   rh   ÚsortedrÈ   rR   Ú	enumerateÚzipr	   Úany)Zinfo_pyZinfo_binÚlimitrÉ   rÌ   rÍ   Zdig_pyZdig_binÚiiZd_pyZd_binr�   Zr_binZ
o_head_binZ	o_dev_binZr_pyZ	o_head_pyZo_dev_pyr"   rÊ   r#   Úassert_dig_allclosey  sR    

*ÿÿ
ÿ  ÿ  ÿrÙ   c               
   k   s®   t dtƒ tƒ }|  ¡ D ]J\}}t |¡||< |dk	rPt|tƒsDt‚|tj	|< q|tj	krtj	|= qz
dV  W 5 | ¡ D ].\}}|dk	r”|tj	|< qx|tj	krxtj	|= qxX dS )z½Use a modified os.environ with temporarily replaced key/value pairs.

    Parameters
    ----------
    **kwargs : dict
        The key/value pairs of environment variables to replace.
    zŸmodified_env is deprecated and will be removed in 1.1. In tests, use monkeypatch from pytest instead. In subprocess calls, pass modified environments directly.N)
r   ÚDeprecationWarningÚdictÚitemsry   ÚgetenvrW   r&   rŒ   rz   )r”   Zorig_envr�   Úvalr"   r"   r#   Úmodified_envŸ  s$    	þ



rß   c                 C   s`   ddl m} | j ¡  | jj ¡ | }| ¡ }|j 	¡ }|j
 	¡ }|| | jj||fd|d� dS )z>Click on a channel name in a raw/epochs/ICA browse-style plot.r…   )Ú_fake_clickZpix)ZxformÚbuttonN)Z	viz.utilsrà   ZcanvasZdrawZmneZax_mainZget_yticklabelsZget_window_extentZ	intervalxrª   Z	intervaly)ZfigZch_indexrá   rà   ÚtextZbboxr¥   Úyr"   r"   r#   Ú_click_ch_name½  s    


ÿrä   )r   Nr   )rL   )N)r
   )r§   )r·   r·   N)N)r   r
   )Er6   Ú
contextlibr   Ú	functoolsr   r   ry   r_   r    r   Úshutilr   r   r(   r   Zunittestr   Únumpyr}   Znumpy.testingr   r	   Z_loggingr   r   Úcheckr   Znumericsr   r$   r&   r%   r;   rK   rN   r:   Z	_mne_callrX   Z
_n2ft_callZrequires_pandasZrequires_pylslZrequires_sklearnZrequires_mnerZ   Zrequires_neuromag2ftZrequires_good_networkZrequires_nitimeZrequires_h5pyr\   re   Úobjectrf   rt   rw   r{   r|   r„   r‘   r•   r£   r¦   r¶   r¿   rÃ   rÅ   rÈ   rÙ   rß   rä   r"   r"   r"   r#   Ú<module>   s|   



ÿ þ


  ÿ
	

&
