U
    f»{j´M  ã                   @   sR  d Z ddlmZ ddlmZ ddlmZ ddlZ	ddl
mZmZmZ ddl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 d	dlmZ ddlmZ ejej ej!ej"ej#ej$iZ%dd„ Z&dd„ Z'dd„ Z(dd„ Z)d0dd„Z*dd„ Z+dd„ Z,dd„ Z-d d!„ Z.d"d#„ Z/d$d%„ Z0d&d'„ Z1ej2d(ej3d)iZ4d*d+„ Z5d,d-„ Z6d.d/„ Z7dS )1zPopulate measurement info.é    )Ústrptime)ÚtimegmNé   )ÚloggerÚwarnÚ_clean_names)Úapply_transÚ_coord_frame_nameÚinvert_transformÚcombine_transforms)ÚAnnotationsé   )Ú_empty_info)Úget_new_file_id)Ú	_add_kindÚ_calibrate_comp)ÚFIFFé   )ÚCTFc                 C   sx  |dkrt ƒ t ƒ fS t ƒ }tt ƒ d�}d}d}|D �]}|d r2|d tjtjtjfkrltj}t|d  }	ntj	}|d }	|d tj
krÜ|dksœ|d dkr¤tdƒ‚t||	t|d |d	 ƒtjd
�}
|d  |
¡ |d7 }q2|d tjkr2|dk�s|d dk�r
tdƒ‚t||	t|d |d	 ƒtjd
�}
| |
¡ |d7 }q2|dk�rVt d| ¡ |dk�rnt d| ¡ ||gfS )z8Pick the HPI coil locations given in device coordinates.N)Ú
dig_pointsr   ZvalidÚkindÚcoord_frameÚt_ctf_dev_devz=No coordinate transformation available for HPI coil locationsÚr)r   Úidentr   r   r   r   Út_ctf_head_headzBNo coordinate transformation available for (virtual) Polhemus dataz(    Polhemus data for %d HPI coils addedz6    Device coordinate locations for %d HPI coils added)ÚlistÚdictr   ÚCTFV_COIL_LPAÚCTFV_COIL_RPAÚCTFV_COIL_NASr   ÚFIFFV_POINT_CARDINALÚ_ctf_to_fiffZFIFFV_POINT_HPIZFIFFV_MNE_COORD_CTF_DEVICEÚRuntimeErrorr   ÚFIFFV_COORD_UNKNOWNÚappendÚFIFFV_MNE_COORD_CTF_HEADÚFIFFV_COORD_HEADr   Úinfo)Úres4ÚcoilsÚtÚdigZ
hpi_resultZ
n_coil_devZn_coil_headÚpr   r   Úd© r/   úN/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/io/ctf/info.pyÚ_pick_isotrak_and_hpi_coils   sP    
ÿþ
þ



ÿr1   c              
   C   sÚ   | |  krdkr*n nd} d}t  d¡ dD ]0}zt|  ¡ |ƒ}W n tk
rX   Y q.X  qlq.td|  ƒ‚dD ],}zt||ƒ}W n tk
r–   Y qpX  qªqptd| ƒ‚t|j|j|j	|j
|j|j|j|j|jf	ƒ}|S )	z,Convert date and time strings to float time.Ú z
01/01/1970z00:00:00zTNo date or time found, setting to the start of the POSIX epoch (1970/01/01 midnight))z%d/%m/%Yz%d-%b-%Yz%a, %b %d, %Yz%Y/%m/%dzÅIllegal date: %s.
If the language of the date does not correspond to your local machine's language try to set the locale to the language of the date string:
locale.setlocale(locale.LC_ALL, "en_US"))z%H:%M:%Sz%H:%MzIllegal time: %s)r   r(   r   ÚstripÚ
ValueErrorr#   r   Útm_yearÚtm_monÚtm_mdayÚtm_hourÚtm_minÚtm_secÚtm_wdayÚtm_ydayÚtm_isdst)Zdate_strZtime_strÚfmtÚdateÚtimeÚresr/   r/   r0   Ú_convert_timeJ   s>    
ýÿ    þrB   c                 C   sü   | j dkst‚t t | |  ¡¡}|dkr2tdƒ‚t |t | d ¡ ¡dk r`t dddg¡}nTt d¡}| d	 | d k r˜d|| d | d	 k r’dnd	< nd|| d | d k r°dnd< | | } |t 	| |¡|  8 }|t t || ¡¡ }t 
| |¡}||fS )
zBGet two orthogonal vectors orthogonal to ez (ez will be modified).)r   r   z#Zero length normal. Cannot proceed.r   gñhãˆµøä>ç      ð?ç        r   r   )ÚshapeÚAssertionErrorÚnpÚsqrtÚsumr#   ÚabsÚarrayZzerosÚdotÚcross)ÚezZez_lenÚexÚeyr/   r/   r0   Ú_get_plane_vectorst   s    
rQ   c                 C   s   t  | |  ¡dk S )z'Determine if a vector is at the origin.g:Œ0âŽyE>)rG   rI   )Úxr/   r/   r0   Ú
_at_origin‰   s    rS   c                 C   s6   |d kr| d }| d |kr2t d|| d |f ƒ‚|S )NÚgrad_order_noz@%s channel with inconsistent compensation grade %s, should be %s)r#   )Úcchr   Zdesiredr/   r/   r0   Ú_check_comp_chŽ   s    þrV   c                 C   s~  d } } } }}t ƒ }d}	t| d ƒD �]L\}
}td|d |d   ƒ}t|
d d|t dtj¡tj|d	 dd
… tj	d�}~
| 
|¡ |d tjtjtjfk�rXt |d d d d ¡dk sät |d d d d ¡dk �r6|d7 }|j|tjtjtjd� d}|d tjk�r |d7 }td||d	 f ƒ q*tj|d< |d d d  ¡ }|d d d  ¡ }|d dk�r~|d9 }d}|d tjk�r$|d d d |d d d  }t t || ¡¡}|dk�rØ|| }t t ||¡¡dk �rd}||| d 8 }|}t ||¡}nt|ƒ\}}nt|ƒ\}}t t|d |ƒt|d |dd�t|d |dd�t|d |dd�g¡|d< ~~~~|d tjk�r¸tj|d < tj|d!< |d7 }||d"< nx|d tjk�r tj|d < |�rätj |d!< n
tj!|d!< |d7 }||d"< n0t"|d#|	ƒ}	tj#|d < tj$|d!< |d7 }||d"< t%|d! |d$ d%> B ƒ|d!< tj&|d&< q*|d tj'k�r&tj(}|�r|d d d |d dd'…< t)|d dd'… ƒ�s|d( dk�rÜtd)|d	  ƒ |d  *tj¡ tj+}n&t|d( |d dd'… ƒ|d dd'…< |d7 }|j|tj,tj|tj-d*� q*|d tj.k�rX|d7 }|j|tjtj/tjd� q*|d7 }|j|tjtjtjd� q*|S )+z.Convert CTF channel information to fif format.r   NÚchsrC   Úproper_gainÚqgainr   é   Úch_nameé   )ÚscannoÚrangeÚcalÚlocZunit_mulr[   Ú	coil_typeZsensor_type_indexZcoilÚposr   g�íµ ÷Æ°>Znorm)Úlognor   r   ÚunitZMEGz refzQ%s channel %s did not have position assigned, so it was changed to a MISC channelrd   rD   éÿÿÿÿFgü©ñÒMbP?Tg       @r   )Úmover`   r   ra   rc   ZGradiometerrT   é   r   r   r   zFEEG electrode (%s) location omitted because of missing HPI information)rc   r   rd   r   ra   )0r   Ú	enumerateÚfloatr   rG   ÚfullÚnanr   ZFIFF_UNITM_NONEZFIFFV_COIL_NONEr%   r   ZCTFV_REF_MAG_CHZCTFV_REF_GRAD_CHZCTFV_MEG_CHrI   Úupdater$   ZFIFFV_MISC_CHZFIFF_UNIT_Vr   ZFIFF_UNIT_TÚcopyrH   rJ   rL   rM   rQ   Zconcatenater   ZFIFFV_REF_MEG_CHZFIFFV_COIL_CTF_REF_MAGZFIFFV_COIL_CTF_OFFDIAG_REF_GRADZFIFFV_COIL_CTF_REF_GRADrV   ZFIFFV_MEG_CHZFIFFV_COIL_CTF_GRADÚintÚFIFFV_COORD_DEVICEZCTFV_EEG_CHr'   rS   Úfillr&   ÚFIFFV_EEG_CHZFIFFV_COIL_EEGZCTFV_STIM_CHZFIFFV_STIM_CH)r)   r+   Zuse_eeg_posZnmegZneegZnstimZnmiscZnrefrW   Z	this_compÚkrU   r_   ÚchÚtextÚr0rN   Zoff_diagÚdiffÚsizerO   rP   r   r/   r/   r0   Ú_convert_channel_info˜   sÜ     þ

þÿ
 ÿ
þ
 
ü








ÿÿ ÿ
 þ
 ÿ
 ÿrx   c                 C   s   t | d ƒt | d ƒfS )zSort the compensation data.Ú
coeff_typer]   )rn   )Úcr/   r/   r0   Ú_comp_sort_keys  s    r{   c                 C   sT   d}d}t | ƒD ]>\}}|d |kr:|}|d }|d }q|d |kstdƒ‚qdS )z4Check that conversion to named matrices is possible.Nre   ry   Úsensorsz(Cannot use an uneven compensation matrix)rh   r#   )ÚcompZref_sensr   rr   Zc_kZc_refr/   r/   r0   Ú_check_comp  s    
r~   c                    s  dd„ |D ƒ}ˆ | d }ˆ | d d|… }‡ fdd„t ||d ƒD ƒ}t ||¡}t |¡|  ¡ }t|ƒ}t|ƒ}	tt ˆ | d g¡d	d
�}
t|
ƒ t |	|f¡}t	ˆ ||d … ƒD ] \}}|d | ||dd…f< q¾t|||t|ƒt|ƒd�|
d< d}t
|
||||dd� |
S )z+Add a new converted compensation data item.c                 S   s   g | ]}|d  ‘qS )r[   r/   )Ú.0rz   r/   r/   r0   Ú
<listcomp>%  s     z_conv_comp.<locals>.<listcomp>Zncoeffr|   Nc                    s   g | ]}ˆ | d  ‘qS )Zsensor_namer/   )r   r-   ©r}   r/   r0   r€   (  s     r   ry   F)ZctfkindZsave_calibratedÚcoeffs)Ú	row_namesÚ	col_namesÚdataZnrowZncolr…   )rX   rY   T)Z	mult_keysÚflip)r^   rG   Zin1drK   ÚtolistÚlenr   r   Úemptyrh   r   )r}   ÚfirstÚlastrW   Úch_namesZn_colr„   rƒ   ÚmaskZn_rowZccompr…   Úiir‚   Úmkr/   r�   r0   Ú
_conv_comp#  s.    ÿ  ÿ
r�   c              	   C   sÄ   | d dkrdS t | d td�| d< t| d ƒ d}d}tƒ }tt| d ƒƒD ]T}| d | d |krN|dkrŽ| t| d ||d | d	 ƒ¡ | d | d }|}qN| t| d ||| d	 ƒ¡ |S )
z2Convert the compensation data into named matrices.Zncompr   Nr}   )Úkeyre   ry   r   rW   )Úsortedr{   r~   r   r^   rˆ   r%   r�   )r)   rŠ   r   Úcompsrr   r/   r/   r0   Ú_convert_comp_data<  s"    ÿr”   c              	   C   sÔ   t tjdtƒ tƒ tƒ tƒ dd�}| d D ]„}|d tjkr(t|d dd… ƒs(|d	  |d
 ¡ |d  |d ¡ |d  |d dd… ¡ |d  tj¡ |d  d7  < q(|d dkr¾dS t 	d|d  ¡ |S )zPick EEG positions.Fr   )r   Úassign_to_chsÚlabelsÚidsÚrrÚkindsrG   rW   r   r`   Nr   r–   r[   r—   rc   r˜   r™   rG   r   z5Picked positions of %d EEG channels from channel info)
r   r   r'   r   rq   rS   r%   ÚFIFFV_POINT_EEGr   r(   )rz   Úeegrs   r/   r/   r0   Ú_pick_eeg_posT  s(        ÿ"ÿrœ   c                 C   sH  | dkrdS |dks |d dkr(t dƒ‚d}| d �rt| d ƒD ]Ä}|d D ]¶}|d  ¡ | d	 |  ¡ krN|d
 dd… }| d | |dd…< | d tjkr¸t|d |ƒ|dd…< n"| d tjkrÚt dt| d ƒ ƒ‚|d | d |< tj| d |< |d7 } qBqNqBd } }}	t| d ƒD ]Ò}t	| d |  
¡ | d | | d | tjd�}
|d  |
¡ | d tjk�rˆt|d |
d ƒ|
d< n$| d tjk�r¬t dt| d ƒ ƒ‚| d | tjk�rÊ|d7 }n&| d | tjk�rè|d7 }n|	d7 }	�q |dk�rt d| ¡ t|||	fdƒD ]&\}}|dk�rt d||f ¡ �qdS )z%Pick the (virtual) EEG position data.Nr   z<No coordinate transformation available for EEG position datar   r•   rG   rW   r[   r–   r`   r   r˜   r   z9Illegal coordinate frame for EEG electrode positions : %src   r—   r™   r   )r   r   r   r   r,   r   z8Illegal coordinate frame for EEG electrode positions: %sz8    %d EEG electrode locations assigned to channel info.)Z	fiducialszEEG locationszextra pointsz!    %d %s added to Polhemus data.)r#   r^   Úlowerr   r&   r   r'   r	   rš   r   rm   r%   r!   r   r(   Úzip)r›   r+   rz   Zeeg_assignedrr   rs   ru   Z	fid_countZ	eeg_countZextra_countr.   Úcountr   r/   r/   r0   Ú_add_eeg_posf  sd    

þÿ
 ÿ
þ


ÿ
ÿ
r    ZlowpassZhighpassc                 C   sš  t | d ƒ}tƒ |d< d|d d< t| d | d ƒ|d d< |d d |d d f|d< | d	 |d
< t| d d�|d< | d D ]$}|d tkr~|d |t|d  < q~t| ||ƒ\|d< |d< |dk	�r@t|d ƒdkrê|d |d d d< |d dk	�r&|d |d< t|d t|d ƒt	j
t	jƒ|d< |d dk	�r@|d |d< t| ||dkƒ|d< t| ƒ|d< |dk�rrt|ƒ}t|||ƒ t d¡ d|_| ¡  |S )zCreate meas info from CTF data.ZsfreqZmeas_idr   ZusecsZ	data_dateZ	data_timeZsecsÚ	meas_dateZnf_operatorZexperimenterZnf_subject_id)Zhis_idZsubject_infoÚfiltersÚtypeÚfreqr,   Zhpi_resultsNr   Zcoord_transZ
t_dev_headZ
dev_head_tZ	dev_ctf_tZ
ctf_head_trW   r“   z    Measurement info composed.F)r   r   rB   r   Ú	_filt_mapr1   rˆ   r   r
   r   ro   r&   rx   r”   rœ   r    r   r(   Z	_unlockedZ_update_redundant)r)   r*   Ztransr›   r(   Zfiltr/   r/   r0   Ú_compose_meas_info¡  sN    
ÿ  ÿ

 ý

r¦   c              	      sd   t  | d¡}t  |¡sg S ttt|d ƒ|d ƒƒ‰ t|dƒ�}‡ fdd„| ¡ D ƒ}W 5 Q R X |S )z2Read Bad channel list and match to internal names.ZBadChannelsrŒ   r   c                    s   g | ]}ˆ |  ¡  ‘qS r/   )r3   )r   Úf©Úmappingr/   r0   r€   Ð  s     z#_read_bad_chans.<locals>.<listcomp>)ÚopÚjoinÚexistsr   rž   r   ÚopenÚ	readlines)Ú	directoryr(   ÚfnameÚfidZ	bad_chansr/   r¨   r0   Ú_read_bad_chansÉ  s    
 r²   c           
   	   C   sÀ   t  | d¡}t  |¡sd S g }g }g }t|dƒ�l}| ¡ D ]\}| ¡  ¡ }	| d|	d  ¡ | t 	|	d ¡| ¡ | t 	|	d ¡t 	|	d ¡ ¡ q:W 5 Q R X t
|ƒdkr²d S t||||ƒS )Nzbad.segmentsr   zbad_%sr   r   r   )rª   r«   r¬   r­   r®   r3   Úsplitr%   rG   Zfloat64rˆ   r   )
r¯   Ú
start_timer¡   r°   ZonsetsZ	durationsÚdescr±   r§   Útmpr/   r/   r0   Ú_annotate_bad_segmentsÔ  s    
.r·   )N)8Ú__doc__r@   r   Úcalendarr   Úos.pathÚpathrª   ÚnumpyrG   Úutilsr   r   r   Z
transformsr   r	   r
   r   Úannotationsr   Z	meas_infor   Úwriter   Zctf_compr   r   Ú	constantsr   r   r   ZFIFFV_POINT_LPAr   ZFIFFV_POINT_RPAr    ZFIFFV_POINT_NASIONr"   r1   rB   rQ   rS   rV   rx   r{   r~   r�   r”   rœ   r    ZCTFV_FILTER_LOWPASSZCTFV_FILTER_HIGHPASSr¥   r¦   r²   r·   r/   r/   r/   r0   Ú<module>   sJ     þ+*

y7 ÿ(