U
    f»{jMÈ  ã                   @   s  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mZ ddlmZmZmZ ddlmZ dd	l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 ddlmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+ dZ,dddej-fZ.dZ/dZ0e1e2e3ddƒƒdƒZ4dd„ e4D ƒZ5dd„ Z6G dd„ dƒZ7dd„ Z8dPdd„Z9dQd"d#„Z:d$d%„ Z;d&d'„ Z<d(d)„ Z=d*d+„ Z>d,d-„ Z?d.d/„ Z@d0d1„ ZAd2d3„ ZBd4d5„ ZCd6d7„ ZDd8d9„ ZEd:d;„ ZFd<d=„ ZGd>d?„ ZHdRdAdB„ZIdSdCdD„ZJG dEdF„ dFeƒZKdGdH„ ZLdTdIdJ„ZMedUdNdO„ƒZNdS )Vé    N)ÚBytesIO©Úcounté   )ÚloggerÚverboseÚ_stamp_to_dtÚ	path_like)Úcombine_transformsÚinvert_transformÚ	Transformé   )Ú_make_bti_dig_points)ÚFIFF)ÚBaseRawÚ_coil_trans_to_locÚ_loc_to_coil_transÚ_empty_info)Ú_mult_cal_oneÚread_stré   )ÚBTI)Ú
read_int32Ú
read_int16Ú
read_floatÚread_doubleÚread_transformÚ	read_charÚ
read_int64Úread_uint16Úread_uint32Úread_double_matrixÚread_float_matrixÚread_int16_matrixÚread_dev_header)ÚkindÚidentÚrÚcoord_frame)ZMxAZMyAZMzAZMxaAZMyaAZMzaA)ÚGxxAÚGyyAÚGyxAZGzaAÚGzyAé   )z>i2z>i4z>f4z>f8c                 C   s   i | ]\}}|t  |¡“qS © )ÚnpÚdtype)Ú.0ÚiÚtr.   r.   úM/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/io/bti/bti.pyÚ
<dictcomp>%   s      r5   c                   C   s>   t tjddddgd dd�dtjtjtjdtjddtjdd�S )	z4Populate entries in info['chs'] with default values.r   r   r   Úf4©r0   Nç      ð?)ÚlocÚch_nameZunit_mulr(   Ú	coil_typeÚrangeÚunitÚcalÚscannor%   Úlogno)	Údictr/   Úarrayr   ZFIFF_UNITM_NONEZFIFFV_COORD_UNKNOWNZFIFFV_COIL_NONEÚFIFF_UNIT_VÚFIFFV_ECG_CHr.   r.   r.   r4   Ú_instantiate_default_info_chs(   s    örE   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	Ú_bytes_io_mock_contextzMake a context for BytesIO.c                 C   s
   || _ d S ©N©Útarget)ÚselfrI   r.   r.   r4   Ú__init__:   s    z_bytes_io_mock_context.__init__c                 C   s   | j S rG   rH   )rJ   r.   r.   r4   Ú	__enter__=   s    z _bytes_io_mock_context.__enter__c                 C   s   d S rG   r.   )rJ   ÚtypeÚvalueÚtbr.   r.   r4   Ú__exit__@   s    z_bytes_io_mock_context.__exit__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rK   rL   rP   r.   r.   r.   r4   rF   7   s   rF   c                 O   s8   t | tƒrt| f|ž|ŽS t | tƒr,t| ƒS tdƒ‚dS )zHandle BytesIO.zCannot mock this.N)Ú
isinstancer	   Úopenr   rF   ÚRuntimeError)ÚfnameÚargsÚkwargsr.   r.   r4   Ú	_bti_openD   s
    

r[   ç        ©r\   g{®Gáz”?g)\�Âõ(¼?c              	   C   s¢   t  dddgdddgdddgg¡}t  | ¡}t  dddgdt  |¡t  |¡ gdt  |¡t  |¡gg¡}t  d¡}t  ||¡|dd…dd…f< ||dd…df< |S )aÎ  Get the general Magnes3600WH to Neuromag coordinate transform.

    Parameters
    ----------
    adjust : float | None
        Degrees to tilt x-axis for sensor frame misalignment.
        If None, no adjustment will be applied.
    translation : array-like
        The translation to place the origin of coordinate system
        to the center of the head.

    Returns
    -------
    m_nm_t : ndarray
        4 x 4 rotation, translation, scaling matrix.
    r\   g      ð¿r8   é   Nr   )r/   rB   Zdeg2radÚcosÚsinÚeyeÚdot)ÚadjustÚtranslationZflip_tZradZadjust_tZm_nm_tr.   r.   r4   Ú_get_bti_dev_tN   s    þ
þ
re   ÚE31©ZE63ZE64c           
         s  t ƒ }dd„ tdƒD ƒ\}}}}}t| dƒD ]â\}	‰ ˆ  d¡rHd|	 ‰ n¼ˆ dkrVd‰ n®ˆ d	krdd
‰ n t‡ fdd„|D ƒƒrˆdt|ƒ ‰ n|ˆ |kr–d‰ nnˆ  d¡r®dt|ƒ ‰ nVˆ dkr¼d‰ nHˆ  d¡rÔdt|ƒ ‰ n0ˆ  d¡rìdt|ƒ ‰ nˆ  d¡�rdt|ƒ ‰ |ˆ g7 }q,|S )a  Rename appropriately ordered list of channel names.

    Parameters
    ----------
    names : list of str
        Lists of 4-D channel names in ascending order

    Returns
    -------
    new : list
        List of names, channel names in Neuromag style
    c                 S   s   g | ]}t d ƒ‘qS )r   r   ©r1   Ú_r.   r.   r4   Ú
<listcomp>z   s     z$_rename_channels.<locals>.<listcomp>r-   r   ÚAz	MEG %3.3dÚRESPONSEzSTI 013ÚTRIGGERzSTI 014c                 3   s   | ]}ˆ |kV  qd S rG   r.   ©r1   Úk©Únamer.   r4   Ú	<genexpr>‚   s     z#_rename_channels.<locals>.<genexpr>z	EOG %3.3dzECG 001ÚEz	EEG %3.3dÚ	UACurrentzUTL 001ÚMz	RFM %3.3dÚGz	RFG %3.3dÚXz	EXT %3.3d)Úlistr<   Ú	enumerateÚ
startswithÚanyÚnext)
ÚnamesÚecg_chÚeog_chÚnewZref_magZref_gradZeogZeegÚextr2   r.   rp   r4   Ú_rename_channelsl   s2    




r‚   c              	      s‚   t | dƒ�4}| tj¡ t|ƒ}t|tjdƒ‰ t||dƒ}W 5 Q R X ‡ fdd„dD ƒ\}}}ˆ dtˆ ƒ…dd…f }|||||fS )zRead the head shape.Úrbr   c                    s   g | ]}ˆ |d d …f ‘qS rG   r.   rh   ©Z
idx_pointsr.   r4   rj       s     z$_read_head_shape.<locals>.<listcomp>)r   r   r   N)r[   Úseekr   ZFILE_HS_N_DIGPOINTSr   r!   ZDATA_N_IDX_POINTSÚlen)rX   ÚfidZ_n_dig_pointsÚ
dig_pointsÚnasionÚlpaÚrpaÚhpir.   r„   r4   Ú_read_head_shape—   s    r�   c                 C   s4   t  | d ¡}t  |¡r0t d¡ t  d¡| d< dS )zMake sure we deal with nans.ÚtranszGMissing values BTI dev->head transform. Replacing with identity matrix.r^   N)r/   Úisnanr{   r   ÚinfoÚidentity)Ú	dev_ctf_tZhas_nanr.   r.   r4   Ú_check_nan_dev_head_t¦   s    

r“   c                 C   s&   t t|ƒ|ddƒ}t |d | ¡}|S )zConvert the coil trans.Úctf_headÚmegrŽ   )r
   r   r/   rb   )Z
coil_transr’   Ú	bti_dev_tr3   r.   r.   r4   Ú_convert_coil_trans¯   s    
 ÿr—   c                 C   s6   |   ¡ }|tj dkr2|tj }|  tj| d¡ dS )zAlign fid pointer.r   r   N)Útellr   ÚFILE_CURPOSr…   )r‡   ÚcurrentÚoffsetr.   r.   r4   Ú_correct_offset·   s    
rœ   c                    s  t | dƒ��ø‰ tƒ }tˆ ƒtˆ dƒtˆ dƒtˆ ƒtˆ ƒtˆ ƒtˆ ƒtˆ ƒtˆ ƒtˆ ƒtˆ ƒtˆ ƒdœ|d< ˆ  dd¡ tˆ ƒ|d< tˆ dƒ|d	< ‡ fd
d„t	|d d ƒD ƒ|d< tƒ |d< t	|d d ƒD �	]�}tƒ }tˆ ƒtˆ dƒtˆ ƒtˆ dƒtˆ ƒtˆ ƒtˆ dƒdœ|d< t
ˆ ƒ ˆ  ¡ }|d  d¡}|�s>tdƒ‚tƒ | }|d |< |dd„ t ¡ D ƒk�	rú|tjk�rätˆ ƒ|d< ˆ  dd¡ tƒ |d< t	dƒD ]>}tˆ dƒtˆ ƒtˆ ƒdœ}|d  |g7  < ˆ  dd¡ �q �
q|tjk�rVtˆ ƒ|d< tˆ ƒ|d< g |d< t	dƒD ]8}	tˆ ddƒtˆ ddƒtˆ ƒdœ}|d  |g7  < �q�
q|tjk�r¤tˆ ƒ|d< |d d d k�r„d!nd"‰ˆ  ˆd¡ tˆ ƒ|d#< �
q|tjk�røg |d$< tˆ dƒtˆ ddƒd%œ}|d& �sÞ�	qø|d$  |g7  < �q¸�
q|tjtjfk�r>tˆ ƒ|d< tˆ ƒ|d'< tˆ ƒ|d(< ˆ  d)d¡ �
q|tjk�rød*}
|d  ¡ D ]$\}}|tjk�rZ|d( }
 �q€�qZ|
d*k�r˜td+tj ƒ‚tƒ |d,< t	|
ƒD ]H}tˆ ƒtˆ ƒtˆ ƒtˆ ƒtˆ ƒd-œ}|d,  |g7  < ˆ  d)d¡ �qª�
q|tjk�rÜd*}|d  ¡ D ]$\}}|tjk�r|d( } �q:�q|d*k�rRtd.tj ƒ‚tƒ |d/< t	|ƒD ]r}tˆ ƒtˆ ƒtˆ ƒtˆ ƒtˆ ƒd0œ}ˆ  dd¡ | tˆ ƒtˆ ƒtˆ ƒtˆ ƒtˆ ƒd1œ¡ |d/  |g7  < �qd�
q|tjk�rFtˆ ƒ|d< tˆ ƒ|d(< ˆ  dd¡ tƒ |d2< t	|d( ƒD ]}|d2  tˆ dƒg7  < �q"�
q|tjk�rˆtˆ ƒ|d3< ˆ  dd¡ tˆ ƒ|d4< tˆ d5ƒ|d6< �
q|tj k�rÌ|d d d7k�rªd5nd8‰tˆ ˆƒ|d9< tˆ ƒ|d4< �
q|tj!k�rètˆ ƒ|d:< �
q|tj"tj#fk�r
tˆ ƒtˆ ƒtˆ ƒtˆ dƒtˆ ƒtˆ d;ƒd<œ|d< |d d dk�r´d‰‡ ‡fd=d„t	|d d> ƒD ƒ|d?< ‡ ‡fd@d„t	|d dA ƒD ƒ|dB< |d d> }|d dA }t$ˆ ||ƒ|dC< nRdDg|d dA  |d?< d|d dA< t%|dB< |d d> }|d dA }t$ˆ ||ƒ|dC< �
qt&|tj'k|d*d"… tj(kgƒ�	rnttˆ ƒtˆ ƒtˆ ƒtˆ dƒdE�|d< |d d dk�r8|d jtˆ dFƒtˆ ƒtˆ ƒtˆ dGƒdH� ‡ fdId„t	|d d> ƒD ƒ|d?< ‡ fdJd„t	|d dK ƒD ƒ|dL< ‡ fdMd„t	|d dN ƒD ƒ|dO< t$ˆ |d d> |d dN ƒ|dP< t)ˆ |d d> |d dK ƒ|dQ< �	qøˆ  ||d d  |d dR |d d>   d!¡ |d dR d" d |d dN< |d dN t*t%ƒt*t+ƒ k�s¦t,‚dDg|d d>  |d?< d|d dK< t-j.|d d> |d dK fdSdT�|dQ< t-j.|d d> |d dN fdUdT�|dP< t	|d d> ƒD ]F}t)ˆ d|d dK ƒ|dQ |< tˆ ƒ t$ˆ d|d dN ƒ|dP |< �	q$nŠ|tj/k�
rtˆ ƒ|d< tˆ ƒ|d(< ˆ  dd¡ g |dV< t	|d( ƒD ]D}tˆ dƒt0ˆ ƒt0ˆ ƒtˆ ƒdWœ}|dV  |g7  < ˆ  d)d¡ �	q²ndtˆ |d d ƒi|dX< ˆ  ¡ | }||d d k�
rLtdY||d d |f ƒ‚| |¡ t
ˆ ƒ qÌtƒ |dZ< t	|d d[ ƒD �]‚}tˆ dƒtˆ ƒt0ˆ ƒtˆ ƒtƒ d\œ}ˆ  dd¡ | tˆ ƒtˆ ƒtˆ dƒtˆ ƒtˆ ƒtˆ dƒd]œ¡ |dZ  |g7  < t
ˆ ƒ tƒ }|d^ tj1tj2fk�rðt3ˆ ƒtˆ ƒtˆ d"ƒt4tˆ ƒd_ƒtˆ ƒtˆ ƒd`œ}ˆ  d"d¡ tˆ dƒ|d	< | |g daœ¡ t	|db ƒD ]j}tˆ ddƒtˆ ddƒtˆ ƒtˆ ƒtˆ ƒdcœ}ˆ  dd¡ tˆ ƒ|d< tˆ dƒ|d	< |dd  |g7  < �q‚nú|d^ tj5k�r*t3ˆ ƒtˆ ƒtˆ d"ƒtˆ ƒtˆ dƒdeœ}nÀ|d^ tj6k�rVt3ˆ ƒtˆ ƒtˆ dƒdfœ}n”|d^ tj7k�r”t3ˆ ƒtˆ ƒdgœ}ˆ  dd¡ tˆ dƒ|d	< nV|d^ tj8tj9fk�rÆt3ˆ ƒtˆ ƒtˆ dƒdfœ}n$|d^ tj:k�rêt3ˆ ƒtˆ dƒdhœ}| |¡ t
ˆ ƒ �
qzW 5 Q R X |S )izÆRead BTi system config file.

    Parameters
    ----------
    fname : str
        The absolute path to the config file

    Returns
    -------
    cfg : dict
        The config blocks found.
    rƒ   é    é   )ÚversionZ	site_nameZdap_hostnameZsys_typeZsys_optionsZsupply_freqÚtotal_chansZsystem_fixed_gainÚvolts_per_bitÚtotal_sensorsÚtotal_user_blocksZnext_der_chan_noÚhdrr   r   ÚchecksumÚreservedc                    s   g | ]}t ˆ ƒ‘qS r.   )r   )r1   r3   ©r‡   r.   r4   rj   ß   s     z _read_config.<locals>.<listcomp>r¢   Ú
transformsÚuser_blocksr£   é   )Únbytesr%   r¥   ÚusernameÚ	timestampÚuser_space_sizer¦   r%   zŒCould not read user block. Probably you acquired data using a BTi version currently not supported. Please contact the mne-python developers.c                 S   s$   g | ]\}}|d d… dkr|‘qS )Nr-   ZUB_B_r.   )r1   ro   Úvr.   r.   r4   rj   ÷   s      rŸ   Úheadersé   )rq   Ú	transformÚunits_per_bitZn_pointsÚstatusZpointsr   )ÚposÚ	directionÚerrorÚmethodr®   é„   r   r^   r²   Z
electrodes)ÚlabelÚlocationrº   Zstruct_sizeÚentriesé   Nz4Cannot find block %s to determine number of channelsZchannels)Úsubsys_typeÚ
subsys_numZcard_numZchan_numZ	recdspnumz6Cannot find block %s to determine number of subsystemsZsubsys)r¾   r¿   Zcards_per_sysZchannels_per_cardZcard_version)ZoffsetdacgainZ
squid_typeZtimesliceoffsetÚpaddingr¡   ÚlabelsÚ	sensor_nor­   é   Zlogdiri  i   Zsysconfig_nameZdelta_enabledé   )rŸ   Z
entry_sizeÚ	n_entriesÚ
filternameÚ
n_e_valuesr¦   c                    s   g | ]}t ˆ ˆƒ‘qS r.   ©r   ©r1   Úch©r‡   Úsizer.   r4   rj   {  s     rÅ   Zch_namesc                    s   g | ]}t ˆ ˆƒ‘qS r.   rÈ   rÉ   rË   r.   r4   rj   }  s     rÇ   Z
e_ch_namesZetableZWH2500)rŸ   Ún_bytesrÅ   rq   éP   éH   )ÚdescriptionÚn_anlgÚn_dspr¦   c                    s   g | ]}t ˆ d ƒ‘qS ©rž   rÈ   rÉ   r§   r.   r4   rj   ˜  s     c                    s   g | ]}t ˆ d ƒ‘qS rÓ   rÈ   rÉ   r§   r.   r4   rj   š  s     rÑ   Zanlg_ch_namesc                    s   g | ]}t ˆ d ƒ‘qS rÓ   rÈ   rÉ   r§   r.   r4   rj   �  s     rÒ   Zdsp_ch_namesZdsp_wtsZanlg_wtsrÍ   Úi2r7   r6   Zmasks)rq   ÚnbitsÚshiftÚmaskÚunknownzHInternal MNE reading error, read size %d != %d expected size for kind %sÚchsr    )rq   Úchan_noÚch_typerÂ   Údata©Úgainr³   Úyaxis_labelZaar_valr¥   r¦   rÛ   F)Údevice_infoZ
inductancerÀ   r²   Z
xform_flagÚtotal_loops)ÚdevÚloopsrá   ©ÚpositionZorientationZradiusZwire_radiusZturnsrã   )rà   Ú	impedancerÀ   r²   r¦   )rà   r®   r¦   )rà   r®   )rà   r¦   );r[   rA   r   r   r   r   r…   r    r   r<   rœ   r˜   ÚpoprW   r   ÚitemsZUB_B_MAG_INFOrx   r   ZUB_B_COH_POINTSr!   r   ZUB_B_CCP_XFM_BLOCKZUB_B_EEG_LOCSZUB_B_WHC_CHAN_MAP_VERZUB_B_WHS_SUBSYS_VERZUB_B_WHC_CHAN_MAPÚ
ValueErrorZUB_B_WHS_SUBSYSÚupdateZUB_B_CH_LABELSZUB_B_CALIBRATIONZUB_B_SYS_CONFIG_TIMEZUB_B_DELTA_ENABLEDÚUB_B_E_TABLE_USEDZUB_B_E_TABLEr"   ÚBTI_WH2500_REF_MAGr{   ÚUB_B_WEIGHTS_USEDZUB_B_WEIGHT_TABLEr#   r†   ÚBTI_WH2500_REF_GRADÚAssertionErrorr/   ZzerosZUB_B_TRIG_MASKr   Ú
CHTYPE_MEGZCHTYPE_REFERENCEr$   Ú_correct_transÚ
CHTYPE_EEGÚCHTYPE_EXTERNALÚCHTYPE_TRIGGERÚCHTYPE_UTILITYÚCHTYPE_DERIVEDÚCHTYPE_SHORTED)rX   ÚcfgÚblockZubZstart_bytesr%   Zdtar¤   ÚdZpntZnum_channelsrq   rÜ   r2   Z
num_subsysZsub_keyrº   ÚrowsÚcolsÚnÚentryZn_readZchannelrÊ   râ   Úloopr.   rË   r4   Ú_read_config¿   sž   õ

ÿ

ú

þ

þ
ÿ
ÿ

þ
ü

þ
ü
ü
 û
ÿ
ÿ

ÿü
ü
ÿ

ÿ

ÿ
 
 
ÿ 
 
ÿ

ÿÿþ
ÿÿ
þ
þ
  
ÿ  
ÿý
ÿ
ÿþ


ü
ûû

üüþÿþÿ
r   c                 C   s@   t | ƒt| ƒt| ƒt| ƒt | ƒt | ƒt | ƒdœ}|  dd¡ |S )zRead BTi PDF epoch.)Úpts_in_epochZepoch_durationZexpected_itiZ
actual_itiZtotal_var_eventsr¥   Zepoch_timestamprÄ   r   )r   r   r…   ©r‡   Úoutr.   r.   r4   Ú_read_epoch'  s    úr  c              	   C   s|   t | dƒt| ƒt| ƒt| ƒt | dƒt| ƒdœ}|  dd¡ | t| ƒt| ƒt| ƒt| ƒt | dƒt| ƒdœ¡ |  dd¡ |S )zRead BTi PDF channel.rž   )Ú
chan_labelrÚ   Ú
attributesÚscalerß   Zvalid_min_maxr±   r   r^   )ZyminZymaxÚindexr¥   Zoff_flagr›   é   )r   r   r   r…   rê   r   r   r  r.   r.   r4   Ú_read_channel6  s"    û
ûr
  c                 C   sD   t | dƒt| ƒt| ƒt| ƒt| ƒt| ƒdœ}|  dd¡ t| ƒ |S )zRead BTi PDF event.rž   )Z
event_nameZ	start_latZend_latZ	step_sizeZfixed_eventr¥   r�   r   )r   r   r   r   r…   rœ   r  r.   r.   r4   Ú_read_eventL  s    ûr  c                 C   s|  t | ƒt| dƒt | ƒt| dƒt | ƒt| dƒt | ƒdœ}|  dd¡ t| ƒ tƒ |d< t|d ƒD �]}t | ƒt| dƒt | ƒdœ}|d	 }|tjkrèt | ƒ|d
< |  dd¡ t| ƒ|d< t | ƒ|d< t	| ƒ|d< t	| ƒ|d< |  dd¡ nt|tj
k�rt| ƒ|d< |  dd¡ nN|tjk�r4t| ƒ|d< t| ƒ|d< n(t | ƒ }|d< |  dd¡ |  |d¡ |d  |g7  < t| ƒ q`|S )zRead BTi PDF process.rª   r�   rÃ   )r«   Úprocess_typer¥   Úuserr­   ÚfilenameÚtotal_stepsr   Úprocessing_stepsr  )r«   r  r¥   r  Zscale_optionr^   r  r0   ÚselectedZcolor_displayÚfreqÚ	high_freqÚlow_freqr®   )r   r   r…   rœ   rx   r<   r   ZPROC_DEFAULTSr   r   ZPROC_FILTERr   ZPROC_BPFILTER)r‡   r  ÚstepZ	this_stepÚptypeZjumpr.   r.   r4   Ú_read_process[  sJ    ú
þ

r  c                 C   s.   t | ƒt | ƒdœ}|  dd¡ t| ƒ|d< |S )zRead BTi PDF assocfile.)Zfile_idÚlengthr�   r   r¥   )r   r…   r   r  r.   r.   r4   Ú_read_assoc_fileˆ  s    ÿr  c                 C   sr   t | ƒt| dƒdœ}|  dd¡ | t| ƒt | ƒt | ƒt | ƒt | ƒt | ƒt | ƒt| ƒt| ƒdœ	¡ |  dd¡ |S )zRead PDF ed file.é   )Úcomment_sizerq   é	   r   )	Z
pdf_numberÚtotal_eventsr­   ÚflagsZ
de_processr¥   Zed_idZ	win_widthZ
win_offsetr½   )r   r   r…   rê   r   r   r  r.   r.   r4   Ú_read_pfid_ed“  s     ÿ
ø
r  c                 C   sX   t | ddƒt | ddƒt| ƒt| ƒt| ƒdœ}|  | dd¡ t| ƒ|d< t| dƒ|d< dS )	zRead coil definition.r   r   rä   r   r¥   r�   r¦   N)r!   r   r   r…   r   r   )r‡   Zcoildefr.   r.   r4   Ú_read_coil_def¨  s    

ür   c              
      sš  t ˆ tjƒtˆ ƒtˆ ƒtˆ ƒdœ}ˆ  ˆ tjd¡ | tˆ ƒtˆ ƒt ˆ tj	ƒt
ˆ ƒtˆ ƒt ˆ tjƒdœ¡ tˆ ƒ |d tƒ  }}tˆ ƒtˆ ƒt ˆ dƒdœ|d< |tjtjfkrÔ‡ fdd	„t|d d
 ƒD ƒ|d< n²|tjk�rtˆ ƒ|d< t ˆ tjƒ|d< tˆ ƒ|d< tˆ tjƒ|d< nl|tjtjtjtjfk�rjtˆ ƒ|d< |tjk�rXˆ  dd¡ t ˆ tjƒ|d< n|tjk�r†t ˆ tjƒ|d< ||d< tˆ ƒ |S )zRead BTi channel config.)rq   rÚ   rÛ   rÂ   r   rÝ   rÛ   r�   )rÌ   r¥   r¦   râ   c                    s   g | ]}t ˆ ƒ‘qS r.   )r   )r1   rú   r§   r.   r4   rj   Í  s     z#_read_ch_config.<locals>.<listcomp>rá   rã   ræ   rÀ   r²   r¦   r®   r   Úchan)r   r   ZFILE_CONF_CH_NAMEr   r   r…   ZFILE_CONF_CH_NEXTrê   r   ZFILE_CONF_CH_YLABELr   r   ZFILE_CONF_CH_RESERVEDrœ   rA   rð   Z
CHTYPE_REFr<   rò   ZFILE_CONF_CH_PADDINGr   r   rô   ró   rõ   rö   r÷   )r‡   rø   rÛ   r!  r.   r§   r4   Ú_read_ch_configµ  sR    
ý


ûþ

ÿ
 ÿr"  c                    sT  t | dƒ��ú‰ ˆ  dd¡ ˆ  ¡ }tˆ ƒ}|tj@ }|tj | tjkrL|}|d dkrh|d|d  7 }ˆ  |d¡ tˆ ƒtˆ dƒ|| |dœ}ˆ  dd¡ | 	tˆ ƒtˆ ƒt
ˆ ƒt
ˆ ƒt
ˆ ƒt
ˆ ƒtˆ ƒtˆ d	ƒt
ˆ ƒtˆ ƒd
œ
¡ ˆ  dd¡ | 	t
ˆ ƒt
ˆ ƒtˆ ƒtˆ ƒt
ˆ ƒdœ¡ ˆ  dd¡ tˆ ƒ ‡ fdd„t|d ƒD ƒ|d< ‡ fdd„t|d ƒD ƒ|d< ‡ fdd„t|d ƒD ƒ|d< ‡ fdd„t|d ƒD ƒ|d< ‡ fdd„t|d ƒD ƒ|d< ‡ fdd„t|d ƒD ƒ|d< ˆ  |ˆ  ¡  ¡|d < | |d!< W 5 Q R X td"d#„ |d D ƒƒ|d$< t|d%  |d&< |d& j|d  }||d'< |S )(zRead header from pdf file.rƒ   iøÿÿÿr   r½   r   r-   )rŸ   Ú	file_typeZhdr_sizeÚstartr   rž   )
Údata_formatZacq_modeÚtotal_epochsZinput_epochsr  Ztotal_fixed_eventsÚsample_periodZxaxis_labelÚtotal_processesr    )r¥   Útotal_ed_classesÚtotal_associated_filesZlast_file_indexr­   rª   c                    s   g | ]}t ˆ ƒ‘qS r.   )r  )r1   Úepochr§   r.   r4   rj     s     z(_read_bti_header_pdf.<locals>.<listcomp>r&  Zepochsc                    s   g | ]}t ˆ ƒ‘qS r.   )r
  rÉ   r§   r.   r4   rj     s     r    rÙ   c                    s   g | ]}t ˆ ƒ‘qS r.   )r  )r1   Úeventr§   r.   r4   rj     s     r  Úeventsc                    s   g | ]}t ˆ ƒ‘qS r.   )r  )r1   Úprocessr§   r.   r4   rj      s     r(  Ú	processesc                    s   g | ]}t ˆ ƒ‘qS r.   )r  )r1   Úafr§   r.   r4   rj   #  s     r*  Z
assocfilesc                    s   g | ]}t ˆ ƒ‘qS r.   )r  )r1   Zed_classr§   r.   r4   rj   &  s     r)  Z	edclassesÚ
extra_dataÚ	pdf_fnamec                 s   s   | ]}|d  V  qdS )r  Nr.   )r1   Úer.   r.   r4   rr   ,  s     z'_read_bti_header_pdf.<locals>.<genexpr>Útotal_slicesr%  r0   Úbytes_per_slice)r[   r…   r˜   r   r   Z	FILE_MASKr™   r   r   rê   r   r   rœ   r<   ÚreadÚsumÚDTYPESÚitemsize)r2  r$  Úheader_positionÚcheck_valuer�   Zbpsr.   r§   r4   Ú_read_bti_header_pdfç  s~    
ý
÷
ü

ÿ


ÿ


ÿ


ÿ


ÿ


ÿ
ÿr<  Tc                    sŽ  | dk	rt | ƒntƒ }t|ƒ}|d |d< | dd¡‰ ˆ dk	rž‡ fdd„|d D ƒ}tˆ dd„ d	�‰ t|d
d„ d	�}dd„ |D ƒdd„ ˆ D ƒk}|s´tdƒ‚n|d }dd„ |D ƒ‰ tˆ |ƒD ]Ð\}}|d |d< |d |d< |d |d< | dtƒ ¡ dd¡dk	�rt|d d ƒ|d< nt 	dtj
¡|d< | dk	�r~|d dk�rh|d |d  t|d ƒ |d< n|d |d  |d< q¾d |d< |d< q¾|�rLdd„ tˆ ƒD ƒ}	|	jdd„ d	� dd„ |	D ƒ}	‡ fdd„|	D ƒ}
d d„ t|
ƒD ƒ}d!d„ |D ƒ}d"d„ |D ƒ}t|d#d„ d	�t|ƒ }d$d„ |D ƒ}‡ fd%d„|D ƒ|d< ||d&< nˆ |d< t tˆ ƒ¡|d&< |d' tj |d(< |d' tj |d)< |S )*zRead bti PDF header.Nr¨   Úbti_transformrÙ   c                    s&   g | ]}|d  dd„ ˆ D ƒkr|‘qS )rÚ   c                 S   s   g | ]}|d  ‘qS ©rÚ   r.   )r1   Zc_r.   r.   r4   rj   @  s     z/_read_bti_header.<locals>.<listcomp>.<listcomp>r.   ©r1   Úc©Zchansr.   r4   rj   ?  s
     ÿ z$_read_bti_header.<locals>.<listcomp>c                 S   s   | d S ©NrÚ   r.   ©ro   r.   r.   r4   Ú<lambda>C  ó    z"_read_bti_header.<locals>.<lambda>)Úkeyc                 S   s   | d S rB  r.   rC  r.   r.   r4   rD  D  rE  c                 S   s   g | ]}|d  ‘qS r>  r.   r?  r.   r.   r4   rj   G  s     c                 S   s   g | ]}|d  ‘qS r>  r.   r?  r.   r.   r4   rj   H  s     zoCould not match raw data channels with config channels. Some of the channels found are not described in config.c                 S   s   g | ]
}t ƒ ‘qS r.   )rA   rh   r.   r.   r4   rj   P  s     r³   ZupbrÞ   rq   râ   r²   r9   é   r%  r   r  r>   r8   c                 S   s   g | ]\}}||d  f‘qS )r  r.   ©r1   r2   rú   r.   r.   r4   rj   d  s     c                 S   s   | d S ©Nr   r.   ©r@  r.   r.   r4   rD  e  rE  c                 S   s   g | ]}|d  ‘qS ©r   r.   ©r1   Úidxr.   r.   r4   rj   f  s     c                    s   g | ]}ˆ | ‘qS r.   r.   ©r1   rµ   rA  r.   r4   rj   g  s     c                 S   s   g | ]\}}||d  f‘qS rp   r.   rH  r.   r.   r4   rj   i  s     c                 S   s   g | ]}|d    d¡r|‘qS ©r   rk   ©rz   r?  r.   r.   r4   rj   j  s      c                 S   s   g | ]}|d    d¡s|‘qS rO  rP  r?  r.   r.   r4   rj   k  s      c                 S   s   t | d dd … ƒS rI  )ÚintrJ  r.   r.   r4   rD  m  rE  c                 S   s   g | ]}|d  ‘qS rK  r.   rL  r.   r.   r4   rj   o  s     c                    s   g | ]}ˆ | ‘qS r.   r.   rN  rA  r.   r4   rj   q  s     Úorderr©   Ze_tableÚweights)r<  rA   r   ÚgetÚsortedrW   Úzipr   r/   ÚfullÚnanÚfloatry   ÚsortÚaranger†   r   rë   rí   )r2  Úconfig_fnameÚsort_by_ch_namer�   rø   Z	chans_cfgÚmatchrÊ   Zch_cfgZby_indexrÙ   Zsort_by_name_idxZa_chsZ	other_chsr.   rA  r4   Ú_read_bti_header5  sb    ÿ

" ÿÿ
r_  c                 C   sv   t  | t j¡} | dd…dd…f  | ddd…f dd…t jf 9  < d| ddd…f< |rj| d dksrt‚nd| d< | S )z#Convert to a transformation matrix.Nr   r\   )r   r   r8   )r/   rB   Zfloat64Znewaxisrï   )r3   Úcheckr.   r.   r4   rñ   ~  s    6rñ   c                       s.   e Zd ZdZed‡ fdd„	ƒZdd„ Z‡  ZS )ÚRawBTiaó  Raw object from 4D Neuroimaging MagnesWH3600 data.

    Parameters
    ----------
    pdf_fname : str
        Path to the processed data file (PDF).
    config_fname : str
        Path to system config file.
    head_shape_fname : str | None
        Path to the head shape file.
    rotation_x : float
        Degrees to tilt x-axis for sensor frame misalignment. Ignored
        if convert is True.
    translation : array-like, shape (3,)
        The translation to place the origin of coordinate system
        to the center of the head. Ignored if convert is True.
    convert : bool
        Convert to Neuromag coordinates or not.
    rename_channels : bool
        Whether to keep original 4D channel labels or not. Defaults to True.
    sort_by_ch_name : bool
        Reorder channels according to channel label. 4D channels don't have
        monotonically increasing numbers in their labels. Defaults to True.
    ecg_ch : str | None
        The 4D name of the ECG channel. If None, the channel will be treated
        as regular EEG channel.
    eog_ch : tuple of str | None
        The 4D names of the EOG channels. If None, the channels will be treated
        as regular EEG channels.
    %(preload)s

        .. versionadded:: 0.11

    %(verbose)s
    ÚconfigÚhs_filer\   r]   Trf   rg   FNc                    st   t |||||||	|||
d�
\}}dd„ |d D ƒ| _t|tƒrFt|ƒ}tt| ƒj|||g|g|d d g|d� d S )N)
r2  r\  Úhead_shape_fnameÚ
rotation_xrd   Úconvertr~   Úrename_channelsr]  r   c                 S   s   g | ]}|d  ‘qS )r  r.   r?  r.   r.   r4   rj   ¼  s     z#RawBTi.__init__.<locals>.<listcomp>rÙ   r4  r   )Ú	filenamesZ
raw_extrasZ
last_sampsr   )Ú_get_bti_infoZbti_ch_labelsrU   r   ÚreprÚsuperra  rK   )rJ   r2  r\  rd  re  rd   rf  rg  r]  r~   r   Úpreloadr   r�   Úbti_info©Ú	__class__r.   r4   rK   ¯  s.         û


    þzRawBTi.__init__c              	   C   sÀ  | j | }|d }	|d }
t|d ƒ| j | d ks8t‚t|d ƒ}t |
¡j}|| | }t |d f¡}|d D ]}|d ||d < qttdƒ| | | }t||ƒ}t	|	d	ƒ��}| 
|d
 | d¡ t d||¡| D ]Ô}t||||  ƒ}t|tƒ�rt | ¡ |
|¡}nt ||
|¡}|||  }|| |d f}||_|dd…||…f }t |jddd… ¡}t|d ƒD ]&\}}|dd…|f ||  ||< �qxt|||||ƒ qÜW 5 Q R X dS )z#Read a segment of data from a file.r2  r0   rÙ   Z
orig_nchanr    r>   r  g    „×—Arƒ   r5  r   NéÿÿÿÿrR  )Z_raw_extrasr†   rï   r/   r0   r9  ÚemptyrQ  Úminr[   r…   r[  rU   r   Z
frombufferÚgetvalueÚfromfileÚshapery   r   )rJ   rÜ   rM  Úfir$  ÚstopZcalsZmultrm  rX   r0   Z
n_channelsrÍ   Z	data_leftZ	read_calsrÊ   Ú
block_sizer‡   Zsample_startr   rù   Zsample_stopru  Z	data_viewÚoneÚiiZb_i_or.   r.   r4   Ú_read_segment_fileÄ  s>    

ÿÿ zRawBTi._read_segment_file)rb  rc  r\   r]   TTTrf   rg   FN)rQ   rR   rS   rT   r   rK   r{  Ú__classcell__r.   r.   rn  r4   ra  Š  s   $                ûra  c                 C   sž   |   ¡ �| |rRt d| ¡ t|ƒ\}}}}	}
t||||	|
||||ƒ	\| d< }}n.t d¡ d | d< tddd d�}tddd d�}W 5 Q R X | j|||d� | S )	Nz'... Reading digitization points from %sÚdigz.... no headshape file supplied, doing nothing.r•   Úhead)rŽ   r”   )Ú
dev_head_tr’   Ú
ctf_head_t)Z_unlockr   r�   r�   r   r   rê   )r�   rd  rf  Úuse_hpir–   r’   r‰   rŠ   r‹   rŒ   rˆ   r  r€  r.   r.   r4   Ú_make_bti_digitizationè  s6    
ÿÿ       þ
ÿr‚  c
           %         sÀ  | dkrt  d¡ | dk	r8t| tƒs8t | ¡s8t | ¡} t|tƒs t |¡sŠt |¡t t t | ¡|¡¡g}
|
D ]}t 	|¡rr|} qŠqrt 	|¡s t
d| ƒ‚|dk	rèt|tƒsè|}t 	|¡sÒt t | ¡|¡}t 	|¡sèt
d| ƒ‚t  d|  ¡ t| ||	d�}tddt|d	 d
 ƒƒ}t|ƒ |dk�r2dn|}|�rFt||ƒnd}tdd|ƒ}d}t  d¡ d| ¡ k�r€d|d  }nd}| dk	�r¸t|ƒ}|d d
 d }t|d
fƒ|d< n2tdƒ}d|d< d|d< d|d< d|d< tƒ |d< |d |d  }}|d D ]p}d|d k�r|d D ]R}d|k�r@|d |d  }}n.d|d k�rX|d }nd|d k�r|d }�q�q||d< ||d< g }tƒ }|d D ]0}|d  }| d!¡�s¼| d"|¡}| |¡ �q˜t|||d#�}t||ƒ}t  d$¡ t|ƒD �]†\}\‰ }tƒ } |�r|nˆ | d%< |tj | d&< |d' | d(< t|d | d) ƒ| d*< t‡ fd+d,„d-D ƒƒ�rÈ|d | d. }!|!dk	�rÀ|�rÀ|d
k�r˜t  d/¡ t|d | d. ƒ}"t |"||ƒ}"t!|"ƒ}!|!| d.< |�rÔt"j#nt"j$}#|�ræt"j%nt"j$}$ˆ  d!¡�r"t"j&| d0< t"j'| d1< |#| d2< t"j(| d3< �nNˆ  d4¡�rXt"j)| d0< t"j*| d1< |#| d2< t"j(| d3< �nˆ  d5¡�r¬t"j)| d0< |#| d2< t"j+| d3< ˆ d6k�r–t"j,| d1< nˆ d7k�rpt"j-| d1< nÄˆ  d8¡�ràt"j.| d0< t"j/| d1< |$| d2< t"j0| d3< n�ˆ d9k�röt"j1| d0< nzˆ d:k�rt"j1| d0< ndˆ  d;¡�s"ˆ |k�r.t"j2| d0< nBˆ |k�rDt"j3| d0< n,ˆ  d<¡�r\t"j4| d0< nˆ d=k�rpt"j4| d0< | | ¡ �qô||d< t5||||||ƒ}t  d>¡ d|_6| 7¡  | 8¡  ||fS )?aù  Read BTI info.

    Note. This helper supports partial construction of infos when `pdf_fname`
    is None. Some datasets, such as the HCP, are shipped as a large collection
    of zipped files where it can be more efficient to only read the needed
    information. In such a situation, some information can neither be accessed
    directly nor guessed based on the `config`.

    These fields will thus be set to None:
        - 'lowpass'
        - 'highpass'
        - 'sfreq'
        - 'meas_date'

    NzANo pdf_fname passed, trying to construct partial info from configzlCould not find the config file %s. Please check whether you are in the right directory or pass the full namez™Could not find the head_shape file "%s". You should check whether you are in the right directory, pass the full file name, or pass head_shape_fname=None.zReading 4D PDF file %s...)r]  Zctf_megr”   r=  r   r\   r•   Fz$Creating Neuromag info structure ...r'  r8   r/  r­   Z	meas_dateÚsfreqZlowpassZhighpassZfiltr  r  r  r  Úhpr  ÚlprÙ   rq   rk   r  )r~   r   z#... Setting channel info structure.r:   r@   r   r?   r  r>   c                 3   s   | ]}ˆ   |¡V  qd S rG   rP  rn   ©Zchan_4dr.   r4   rr   |  s     z _get_bti_info.<locals>.<genexpr>)rk   ru   rv   r9   z3... putting coil transforms in Neuromag coordinatesr%   r;   r(   r=   ru   rv   )r)   r*   )r+   ZGzxAr,   ZEEGrl   rm   ZEOGrw   rt   zÚCurrently direct inclusion of 4D weight tables is not supported. For critical use cases please take into account the MNE command "mne_create_comp_data" to include weights as printed out by the 4D "print_table" routine.)9r   r�   rU   r   ÚopÚisabsÚabspathÚjoinÚdirnameÚisfileré   r_  r   rñ   r“   re   Úkeysr   r   rx   rz   rT  Úappendr‚   rV  ry   rE   r   Z
FIFF_LOGNOrY  r{   r   r—   r   r   ZFIFFV_COORD_DEVICEZFIFFV_MNE_COORD_4D_HEADÚFIFFV_COORD_HEADZFIFFV_MEG_CHZFIFFV_COIL_MAGNES_MAGZFIFF_UNIT_TZFIFFV_REF_MEG_CHZFIFFV_COIL_MAGNES_REF_MAGZFIFF_UNIT_T_MZFIFFV_COIL_MAGNES_REF_GRADZ"FIFFV_COIL_MAGNES_OFFDIAG_REF_GRADZFIFFV_EEG_CHZFIFFV_COIL_EEGrC   ZFIFFV_STIM_CHZFIFFV_EOG_CHrD   ZFIFFV_MISC_CHr‚  Z	_unlockedZ_update_redundantZ_check_consistency)%r2  r\  rd  re  rd   rf  r~   r   rg  r]  Zconfig_triesZ
config_tryÚ	orig_namerm  r’   r–   r�  rƒ  r�   Údater„  r…  Úprocr  rÙ   Zbti_ch_namesrÊ   r:   Zneuromag_ch_namesZ
ch_mappingrM  Zchan_neuromagZ	chan_infor9   r3   Z	meg_frameZ	eeg_framer.   r†  r4   ri     sD   




ÿÿ

þ
 ÿ
ÿ
ü  ÿÿ




  ÿ




ÿÿ







ÿ






     ÿÿri  rb  rc  Fc                 C   s    t | |||||||||	|
|d�S )aß  Raw object from 4D Neuroimaging MagnesWH3600 data.

    .. note::
        1. Currently direct inclusion of reference channel weights
           is not supported. Please use ``mne_create_comp_data`` to include
           the weights or use the low level functions from this module to
           include them by yourself.
        2. The informed guess for the 4D name is E31 for the ECG channel and
           E63, E63 for the EOG channels. Please check and adjust if those
           channels are present in your dataset but 'ECG 01' and 'EOG 01',
           'EOG 02' don't appear in the channel names of the raw object.

    Parameters
    ----------
    pdf_fname : str
        Path to the processed data file (PDF).
    config_fname : str
        Path to system config file.
    head_shape_fname : str | None
        Path to the head shape file.
    rotation_x : float
        Degrees to tilt x-axis for sensor frame misalignment. Ignored
        if convert is True.
    translation : array-like, shape (3,)
        The translation to place the origin of coordinate system
        to the center of the head. Ignored if convert is True.
    convert : bool
        Convert to Neuromag coordinates or not.
    rename_channels : bool
        Whether to keep original 4D channel labels or not. Defaults to True.
    sort_by_ch_name : bool
        Reorder channels according to channel label. 4D channels don't have
        monotonically increasing numbers in their labels. Defaults to True.
    ecg_ch : str | None
        The 4D name of the ECG channel. If None, the channel will be treated
        as regular EEG channel.
    eog_ch : tuple of str | None
        The 4D names of the EOG channels. If None, the channels will be treated
        as regular EEG channels.
    %(preload)s

        .. versionadded:: 0.11
    %(verbose)s

    Returns
    -------
    raw : instance of RawBTi
        A Raw object containing BTI data.

    See Also
    --------
    mne.io.Raw : Documentation of attribute and methods.
    )r\  rd  re  rd   rf  rg  r]  r~   r   rl  r   )ra  )r2  r\  rd  re  rd   rf  rg  r]  r~   r   rl  r   r.   r.   r4   Úread_raw_btiË  s    <     ûr“  )r\   r]   )rf   rg   )T)T)TT)rb  rc  r\   r]   TTTrf   rg   FN)OÚos.pathÚpathr‡  Úior   Ú	itertoolsr   Únumpyr/   Úutilsr   r   r   r	   r¨   r
   r   r   Z_digitizationr   Ú	constantsr   Ú r   r   r   r   r   r   r   r6  r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   ZFIFF_INFO_DIG_FIELDSr�  ZFIFF_INFO_DIG_DEFAULTSrì   rî   rV  rx   r<   Zdtypesr8  rE   rF   r[   re   r‚   r�   r“   r—   rœ   r   r  r
  r  r  r  r  r   r"  r<  r_  rñ   ra  r‚  ri  r“  r.   r.   r.   r4   Ú<module>   sv   <


+	  j-2N
I
^  þ
 L                û