U
    f»{jƒI  ã                   @   sÊ  d dl 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mZmZmZm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mZmZmZmZm Z m!Z!m"Z" ddl#m$Z$ ej%ej&ej'ej(dœZ)e*e+e) ,¡ ƒƒZ-ddddddœZ.dd„ e) /¡ D ƒZ0dddddœZ1dAdd„Z2dd„ Z3dd „ Z4d!d"d#d$hZ5G d%d&„ d&e6ƒZ7d'd(„ Z8edBddd)œd*d+„ƒZ9ej:d,ej;d-ej<d.iZ=dCd0d1„Z>dDd2d3„Z?d4d5„ Z@d6d7„ ZAdEd9d:„ZBdFd;d<„ZCd=d>„ ZDdGd?d@„ZEdS )Hé    N)ÚCounteré   )ÚloggerÚwarnÚBunchÚ_validate_typeÚ_check_fnameÚverboseé   )ÚFIFFÚ_coord_frame_named)Údir_tree_find)Úread_tag)Ústart_and_end_fileÚwrite_dig_points)Úapply_transÚ	TransformÚget_ras_to_neuromag_transÚcombine_transformsÚinvert_transformÚ	_to_constÚ_str_to_frameÚ_coord_frame_name)Ú__version__)ÚcardinalÚhpiÚeegÚextraZCardinalZHPIZEEGZExtraÚUnknown)r   r   r   r   Úunknownc                 C   s   i | ]\}}||“qS © r    )Ú.0ÚkeyÚvalr    r    úS/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/io/_digitization.pyÚ
<dictcomp>+   s      r%   ZLPAZNasionZRPAZInion)r
   r   é   é   Fc                 C   sX  |�r<| dk	�r<g }g }g }g }g }t | ƒD ]¬\}}|d }	|d }
|
tjkrbt ||	||f¡ q,|
tjkr€t ||	||f¡ q,|
tjkržt ||	||f¡ q,|
tjkr¼t ||	||f¡ q,|
tjkr,t ||	||f¡ q,| 	¡ | 	¡ f | 	¡  | 	¡ | 	¡ f g }t || | | | ƒD ]\}}| 
|d ¡ �q|} | dk	�rTdd„ | D ƒS | S )zFormat the dig points nicely.NÚidentÚkindéÿÿÿÿc                 S   s   g | ]}t |ƒ‘qS r    )ÚDigPoint©r!   Údr    r    r$   Ú
<listcomp>Z   s     z&_format_dig_points.<locals>.<listcomp>)Ú	enumerater   ÚFIFFV_POINT_CARDINALÚheapqÚheappushÚFIFFV_POINT_HPIÚFIFFV_POINT_EEGÚFIFFV_POINT_EXTRAZFIFFV_POINT_HEADÚsortÚappend)ÚdigZenforce_orderZfids_digpointsZhpi_digpointsZeeg_digpointsZextra_digpointsZhead_digpointsÚidxZdigpointr(   r)   Znew_digr-   r    r    r$   Ú_format_dig_points/   sB    




ÿÿþr:   c                 C   s   dd„ | D ƒS )Nc                 S   s   g | ]}|d  t jkr|‘qS ©r)   )r   r4   r,   r    r    r$   r.   ^   s      z _get_dig_eeg.<locals>.<listcomp>r    )r8   r    r    r$   Ú_get_dig_eeg]   s    r<   c                 C   s:   t dd„ | D ƒƒ}t|tj |tj |tj |tj d�S )z&Get the number of points of each type.c                 S   s   g | ]}|d  ‘qS r;   r    r,   r    r    r$   r.   c   s     z)_count_points_by_type.<locals>.<listcomp>)Úfidr   r   r   )r   Údictr   r0   r3   r4   r5   )r8   Zoccurrencesr    r    r$   Ú_count_points_by_typea   s    ür?   r)   r(   ÚrÚcoord_framec                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	r+   ax  Container for a digitization point.

    This is a simple subclass of the standard dict type designed to provide
    a readable string representation.

    Parameters
    ----------
    kind : int
        The kind of channel,
        e.g. ``FIFFV_POINT_EEG``, ``FIFFV_POINT_CARDINAL``.
    r : array, shape (3,)
        3D position in m. and coord_frame.
    ident : int
        Number specifying the identity of the point.
        e.g.  ``FIFFV_POINT_NASION`` if kind is ``FIFFV_POINT_CARDINAL``,
        or 42 if kind is ``FIFFV_POINT_EEG``.
    coord_frame : int
        The coordinate frame used, e.g. ``FIFFV_COORD_HEAD``.
    c                 C   s¢   | d t jkr t | d d¡}n$tt | d d¡ }d|| d f }| d¡}t| d ƒ}d|krzd	t| d
 ƒ  	d¡}ndtd| d
  ƒ  	d¡}d|||f S )Nr)   r(   zUnknown cardinalr   z%s #%sé
   rA   Zvoxelz(%0.1f, %0.1f, %0.1f)r@   é   z(%0.1f, %0.1f, %0.1f) mmiè  z<DigPoint | %s : %s : %s frame>)
r   r0   Ú_cardinal_kind_revÚgetÚ_dig_kind_properÚ_dig_kind_revÚrjustr   ÚtupleÚljust)ÚselfZid_ÚcfÚposr    r    r$   Ú__repr__„   s     ÿ
ÿÿzDigPoint.__repr__c                 C   s$   t | d | d  ¡ | d | d d�S )zMake a deepcopy.r)   r@   r(   rA   )r)   r@   r(   rA   )r+   Úcopy)rK   Zmemodictr    r    r$   Ú__deepcopy__•   s     
 þzDigPoint.__deepcopy__c                    sZ   dddg}t ˆ ¡ ƒt ˆ  ¡ ƒkr&dS t‡ ‡fdd„|D ƒƒrBdS t ˆd ˆ d ¡S dS )	z‘Compare two DigPoints.

        Two digpoints are equal if they are the same kind, share the same
        coordinate frame and position.
        r)   r(   rA   Fc                 3   s   | ]}ˆ| ˆ | kV  qd S ©Nr    )r!   Ú_©ÚotherrK   r    r$   Ú	<genexpr>¤   s     z"DigPoint.__eq__.<locals>.<genexpr>r@   N)ÚsetÚkeysÚanyÚnpZallclose)rK   rT   Zmy_keysr    rS   r$   Ú__eq__›   s    
zDigPoint.__eq__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rN   rP   rZ   r    r    r    r$   r+   o   s   r+   c           
      C   sÞ   t |tjƒ}d}t|ƒdkr(t d¡ n®t|ƒdkr>tdƒ n˜|d }tj}g }t|d ƒD ]f}|d | j	}|d | j
}|tjkržt| |ƒ}| |j¡ q\|tjkr\t| |ƒ}t t|jƒ¡}q\|D ]}	||	d< qÈt|ƒS )	z%Read digitizer data from a FIFF file.Nr   zIsotrak not foundr
   zMultiple Isotrak foundZnentÚ	directoryrA   )r   r   ZFIFFB_ISOTRAKÚlenr   Úinfor   ZFIFFV_COORD_HEADÚranger)   rM   ZFIFF_DIG_POINTr   r7   ÚdataZFIFF_MNE_COORD_FRAMEr   rE   Úintr:   )
r=   Z	meas_infoZisotrakr8   rA   Úkr)   rM   Útagr-   r    r    r$   Ú_read_dig_fifª   s*    





rg   )Ú	overwriter	   c             	      s„   t | |d�} ˆ dk	r\tˆ ƒ‰ ‡ fdd„|D ƒ}|ˆ h }t|ƒdkr\tdˆ tt|ƒƒf ƒ‚t| ƒ�}t||dˆ d� W 5 Q R X dS )	a=  Write digitization data to a FIF file.

    Parameters
    ----------
    fname : path-like
        Destination file name.
    pts : iterator of dict
        Iterator through digitizer points. Each point is a dictionary with
        the keys 'kind', 'ident' and 'r'.
    coord_frame : int | str | None
        If all the points have the same coordinate frame, specify the type
        here. Can be None (default) if the points could have varying
        coordinate frames.
    %(overwrite)s

        .. versionadded:: 1.0
    %(verbose)s

        .. versionadded:: 1.0
    )rh   Nc                    s   h | ]}|  d ˆ ¡’qS ©rA   )rE   )r!   Úptri   r    r$   Ú	<setcomp>Ý   s     zwrite_dig.<locals>.<setcomp>r   zNPoints have coord_frame entries that are incompatible with coord_frame=%i: %s.T)ÚblockrA   )r   r   r`   Ú
ValueErrorÚstrrI   r   r   )ÚfnameZptsrA   rh   r	   Z
pts_framesZ
bad_framesr=   r    ri   r$   Ú	write_digÄ   s    
ÿÿ
rp   ÚnasionÚlpaÚrpaTc           	   
   C   st  t ƒ t ƒ t ƒ   }}}tƒ t ƒ  }}| D ]ž}|d tjkrP|d |t|d  < q(|d tjkr|| |d ¡ | |d ¡ q(|d tjkrš| |d ¡ q(|d tjkr(|d dks¸|s(| |d ¡ q(t	dd„ | D ƒƒ}t
|ƒdkrôtd|› �ƒ‚t |¡}d	|_t| d
d¡| dd¡| dd¡t
|ƒ�r8t |¡ndt
|ƒ�rNt |¡ndt
|ƒ�rdt |¡nd|| ¡ d�S )a  Obtain coordinate data from a Dig.

    Parameters
    ----------
    dig : list of dicts
        A container of DigPoints to be added to the info['dig'].

    Returns
    -------
    ch_pos : dict
        The container of all relevant channel positions inside dig.
    r)   r@   r(   r   c                 S   s   g | ]}|d  ‘qS ri   r    r,   r    r    r$   r.     s     z._get_data_as_dict_from_dig.<locals>.<listcomp>r
   z6Only single coordinate frame in dig is supported, got )r*   r&   rq   Nrr   rs   )rq   rr   rs   Úhspr   ÚelpÚdig_ch_pos_locationrA   )Úlistr>   r   r0   Ú_cardinal_ident_mappingr3   r7   r5   r4   rV   r`   ÚRuntimeErrorrY   ÚarrayÚshaper   rE   Úpop)	r8   Zexclude_ref_channelrt   r   ru   Zfidsrv   r-   Zdig_coord_framesr    r    r$   Ú_get_data_as_dict_from_digó   s8    



ør}   c                 C   sÊ   t d d d d�}tƒ }| D ]6}|d tjkrt|d  }|d ||< |d ||< qt|ƒdkr®|r®t| ¡ ƒtddd	gƒkrŠtd
| ¡  ƒ‚tt| 	¡ ƒƒdkr®tdt|ƒ ƒ‚|r¾| 
¡ d nd }||fS )N)rq   rr   rs   r)   r(   r@   rA   r   rq   rr   rs   z*Some fiducial points are missing (got %s).r
   zBAll fiducial points must be in the same coordinate system (got %s))r   r>   r   r0   rx   r`   rV   rW   rm   ÚvaluesÚpopitem)r8   Zraise_errorZ
fid_coordsZfid_coord_framesr-   r"   rA   r    r    r$   Ú_get_fid_coords"  s(    ÿÿÿr€   c           	   	   C   sÊ   t  | ¡\}}t |¡}|jdks0|jd dkrDd|jf }t|ƒ‚|dkr¶t| dƒ�X}t}t	j	 
¡  d¡}| d| ¡ | ¡ f ¡ | d	t|ƒ ¡ tj||d
dd� W 5 Q R X nd| }t|ƒ‚dS )a!  Write points to text file.

    Parameters
    ----------
    fname : str
        Path to the file to write. The kind of file to write is determined
        based on the extension: '.txt' for tab separated text file.
    dig_points : numpy.ndarray, shape (n_points, 3)
        Points.
    r   r
   r&   z-Points must be of shape (n_points, 3), not %sz.txtÚwbz%I:%M%p on %B %d, %Ys?   %% Ascii 3D points file created by mne-python version %s at %s
s    %% %d 3D points, x y z per line
ú	Ú
)Ú	delimiterÚnewlinez(Unrecognized extension: %r. Need '.txt'.N)ÚopÚsplitextrY   ÚasarrayÚndimr{   rm   Úopenr   ÚdatetimeÚnowÚstrftimeÚwriteÚencoder`   Zsavetxt)	ro   Ú
dig_pointsrR   ÚextÚerrr=   ÚversionrŒ   Úmsgr    r    r$   Ú_write_dig_points<  s$    
ÿÿr•   c                 C   s2   t | tƒr| tkr*tdtt ¡ ƒ| f ƒ‚t|  S )Nz%coord_frame must be one of %s, got %s)Ú
isinstancern   r   rm   ÚsortedrW   ri   r    r    r$   Ú_coord_frame_const[  s
    ÿr˜   Úheadc              	   C   s¸  t |ƒ}g }|dk	rPt |¡}|jdkr8td|jf ƒ‚| |tjtj|dœ¡ | dk	r”t | ¡} | jdkr|td| jf ƒ‚| | tj	tj|dœ¡ |dk	rØt |¡}|jdkrÀtd|jf ƒ‚| |tj
tj|dœ¡ |dk	�rFt |¡}|jdk�s|jd d	k�rtd
|jf ƒ‚t|ƒD ]$\}}	| |	|d tj|dœ¡ �q |dk	�r²t |¡}t|ƒ�r„|jd d	k�r„td|jf ƒ‚t|ƒD ]$\}}	| |	|d tj|dœ¡ �qŒ|dk	�r°g }
d}| ¡ D ]”\}}t|tdƒ z|
 t|dd… ƒ¡ W n tk
�r   d}Y nX t|tjttfdƒ tj|td�}|||< |jdk�rÌtd|j› d�ƒ‚�qÌ|�r|t dt|ƒd ¡}
t||
ƒD ](\}}| || t|ƒtj|dœ¡ �q†t|ƒS )aÇ  Construct digitizer info for the info.

    Parameters
    ----------
    nasion : array-like | numpy.ndarray, shape (3,) | None
        Point designated as the nasion point.
    lpa : array-like |  numpy.ndarray, shape (3,) | None
        Point designated as the left auricular point.
    rpa : array-like |  numpy.ndarray, shape (3,) | None
        Point designated as the right auricular point.
    hpi : array-like | numpy.ndarray, shape (n_points, 3) | None
        Points designated as head position indicator points.
    extra_points : array-like | numpy.ndarray, shape (n_points, 3)
        Points designed as the headshape points.
    dig_ch_pos : dict
        Dict of EEG channel positions.
    coord_frame : str
        The coordinate frame of the points. Usually this is "unknown"
        for native digitizer space. Defaults to "head".

    Returns
    -------
    dig : list of dicts
        A container of DigPoints to be added to the info['dig'].
    N)r&   z,LPA should have the shape (3,) instead of %s)r@   r(   r)   rA   z/Nasion should have the shape (3,) instead of %sz,RPA should have the shape (3,) instead of %sr   r
   r&   z5HPI should have the shape (n_points, 3) instead of %sz8Points should have the shape (n_points, 3) instead of %sFÚ
dig_ch_poséýÿÿÿT)Zdtypez>The position should be a 1D array of 3 floats. Provided shape Ú.)r˜   rY   rˆ   r{   rm   r7   r   ÚFIFFV_POINT_LPAr0   ÚFIFFV_POINT_NASIONÚFIFFV_POINT_RPAr‰   r/   r3   r`   r5   Úitemsr   rn   rd   Zndarrayrw   rI   rz   Úfloatry   ZarangeÚzipr4   r:   )rq   rr   rs   r   Úextra_pointsrš   rA   r8   r9   ÚpointZidentsZ
use_aranger"   Úvaluer(   r    r    r$   Ú_make_dig_pointsb  sœ    

ÿ
þ

ÿ
þ

ÿ
þ

ÿþ

ÿþ

ÿþr¦   c           	      C   s€   |rTt | ||ƒ}t|| ƒ} t||ƒ}t||ƒ}|d k	r@t||ƒ}t||ƒ tj¡}nd }tdd|d�}t| ||||d�}||fS )NÚctf_headr™   )ZfroÚtoÚtrans)rq   rr   rs   r   r£   )r   r   ZastyperY   Zfloat32r   r¦   )	rq   rr   rs   r   r   ÚconvertZneuromag_transÚ
ctf_head_tÚinfo_digr    r    r$   Ú_call_make_dig_pointsÅ  s"    



ür­   c                 C   s   t | ||||ƒ\}}|S rQ   )r­   )Znasrr   rs   r   r   r�   rR   r    r    r$   Ú_artemis123_read_posà  s    r®   c	                 C   s`   |r|nd }	t | |||	||ƒ\}
}|rHtt|ƒ|ddƒ}t||ddƒ}ntddd d�}|
||fS )NZmegr§   r™   )r©   )r­   r   r   r   )rq   rr   rs   r   r   rª   Zuse_hpiZ	bti_dev_tZ	dev_ctf_tZ_hpir¬   r«   ÚtZ
dev_head_tr    r    r$   Ú_make_bti_dig_pointsè  s    ÿ
 ÿr°   )F)N)T)T)NNNNNNr™   )T)FFFF)Fr1   Úcollectionsr   r‹   Úos.pathÚpathr†   ÚnumpyrY   Úutilsr   r   r   r   r   r	   Ú	constantsr   r   Útreer   rf   r   rŽ   r   r   Z
transformsr   r   r   r   r   r   r   r   Ú r   r0   r3   r4   r5   Z_dig_kind_dictrI   r—   r~   Z_dig_kind_intsrF   r    rG   rD   r:   r<   r?   Z	_dig_keysr>   r+   rg   rp   rž   r�   rŸ   rx   r}   r€   r•   r˜   r¦   r­   r®   r°   r    r    r    r$   Ú<module>
   sp    (üü
.;$   ý
/
     þ
c
	      þ