U
    f»{j¼¶ ã                   @   sœ  d dl mZmZ d dlmZ 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 d dlZd dlZddl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 m!Z!m"Z"m#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/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z< ddl=m>Z>m?Z? ddl@mAZAmBZBmCZCmDZDmEZE ddlFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZPmQZQmRZRmSZSmTZT ddlUmVZVmWZWmXZXmYZYmZZZm[Z[ ddlUm\Z\m]Z] ddl^m_Z_ ddl`maZa ebZcdZdeeedd ƒZfeedƒZgdd„ ZheHdƒdd„ƒZiG dd „ d ejƒZkG d!d"„ d"ejƒZld#d$„ Zmd„d'd(„Znd)d*„ Zod+d,„ Zpd-d.„ Zqd/d0„ Zrd1d2„ Zsd3d4„ Ztd5d6„ Zud7d8„ ZvG d9d:„ d:ewekelƒZxd;d<„ ZyeHd…d=d>„ƒZzeHd†d@ddAœdBdC„ƒZ{eHd‡dDdE„ƒZ|dFdG„ Z}dHdI„ Z~eHdˆdJdK„ƒZdLdM„ Z€dNdO„ Z�dPdQ„ Z‚d‰dSdT„ZƒeSdŠdUdV„ƒZ„eSd‹dWdX„ƒZ…eHdŒdYdZ„ƒZ†eHd�d[d\„ƒZ‡eHdŽd^d_„ƒZˆd`Z‰dadb„ ZŠdcdd„ Z‹dedf„ ZŒeHd�dgdh„ƒZ�eSdidj„ ƒZŽewe�e�dkdl„ e�dm�Z�eej‘e�e5fej’e�e5fej“e�e5fej”e•e4fej–e•e4fej—e�e5fej˜dndl„ e4fej™e�e5fejše�e5fej›eœe2fej�e�e5fdo�Zžedpdq„ ež Ÿ¡ D ƒƒZ edrdq„ ež Ÿ¡ D ƒƒZ¡ej¢dsdt„ ƒZ£dudv„ Z¤dwdx„ Z¥dydz„ Z¦d{d|„ Z§d}d~œdd€„Z¨d�d‚„ Z©dS )�é    )ÚCounterÚOrderedDict)ÚMappingN©Údeepcopy)ÚBytesIO)Úshortené   )Úchannel_typeÚ_get_channel_typesÚget_channel_type_constantsÚ
pick_typesÚ_contains_ch_type)ÚFIFFÚ_coord_frame_named)Ú	fiff_open)Údir_tree_find)Úread_tagÚfind_tagÚ_ch_coord_dictÚ_update_ch_info_namedÚ_rename_list)Ú
_read_projÚ_write_projÚ_uniquify_projsÚ_normalize_projÚ_proj_equalÚ
Projection)Ú_read_ctf_compÚwrite_ctf_comp)Ústart_and_end_fileÚstart_blockÚ	end_blockÚwrite_stringÚwrite_dig_pointsÚwrite_floatÚ	write_intÚwrite_coord_transÚwrite_ch_infoÚwrite_name_listÚwrite_julianÚwrite_float_matrixÚwrite_idÚ	DATE_NONE)Ú_read_proc_historyÚ_write_proc_historyé   )Úinvert_transformÚ	TransformÚ_coord_frame_nameÚ_ensure_transÚ_frame_to_str)ÚloggerÚverboseÚwarnÚobject_diffÚ_validate_typeÚ_stamp_to_dtÚ_dt_to_stampÚ_plÚ_is_numericÚ_check_optionÚ_on_missingÚ_check_on_missingÚfill_docÚ_check_fname)Ú_format_dig_pointsÚ_dig_kind_properÚDigPointÚ_dig_kind_revÚ_dig_kind_intsÚ_read_dig_fif)Ú	write_digÚ_get_data_as_dict_from_dig)Úget_current_comp)Ú_handle_default)	ÚscannoÚlognoÚkindÚrangeÚcalÚ	coil_typeÚunitÚunit_mulÚcoord_frame)ÚlocÚch_name)rP   rR   rT   rW   rX   c                     sR  ddddddddd	d
ddddddddddg} dddddddddddd d!d"d#d$d%d&d'd(g}d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEg‰ ddFdGdHdIdJdKdLdMdNdOdPdQdRdSdTdUdVdWdXd$dYdZd[d\d]d^d_d`g‰g }|‡ fdadb„| D ƒ7 }|‡fdcdb„| D ƒ7 }|‡ fdddb„|D ƒ7 }|‡fdedb„|D ƒ7 }|ˆ 7 }|ˆ7 }|dfg7 }t |ƒS )ga’  Get valid units according to the International System of Units (SI).

    The International System of Units (SI, :footcite:`WikipediaSI`) is the
    default system for describing units in the Brain Imaging Data Structure
    (BIDS). For more information, see the BIDS specification
    :footcite:`BIDSdocs` and the appendix "Units" therein.

    References
    ----------
    .. footbibliography::
    ZyoctoZzeptoZattoZfemtoZpicoZnanoÚmicroZmilliZcentiZdeciZdecaZhectoZkiloÚmegaZgigaZteraZpetaZexaZzettaZyottaÚyÚzÚaÚfÚpÚnõ   ÂµÚmÚcÚdÚdaÚhÚkÚMÚGÚTÚPÚEÚZÚYZmetreZkilogramÚsecondZampereZkelvinZmoleZcandelaZradianZ	steradianZhertzZnewtonÚpascalZjouleZwattZcoulombZvoltZfaradZohmZsiemensZweberZteslaZhenryzdegree CelsiusZlumenZluxZ	becquerelÚgrayZsievertZkatalZkgÚsÚAÚKZmolÚcdZradÚsrZHzÚNZPaÚJÚWÚCÚVÚFu   â„¦ÚSZWbÚHu   Â°CZlmÚlxZBqZGyZSvZkatc                    s$   g | ]}ˆ D ]}d   ||g¡‘qqS ©Ú ©Újoin©Ú.0ÚprefixrT   ©Úvalid_unit_names© úO/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/io/meas_info.pyÚ
<listcomp>[   s     ÿz$_get_valid_units.<locals>.<listcomp>c                    s$   g | ]}ˆ D ]}d   ||g¡‘qqS r€   r‚   r„   ©Úvalid_unit_symbolsr‰   rŠ   r‹   ]   s     ÿc                    s$   g | ]}ˆ D ]}d   ||g¡‘qqS r€   r‚   r„   r‡   r‰   rŠ   r‹   _   s     ÿc                    s$   g | ]}ˆ D ]}d   ||g¡‘qqS r€   r‚   r„   rŒ   r‰   rŠ   r‹   a   s     ÿzn/a)Útuple)Zvalid_prefix_namesZvalid_prefix_symbolsZvalid_unitsr‰   )rˆ   r�   rŠ   Ú_get_valid_units:   sª               ý         ÿ
                   û                 ý
r�   c              	      sN  t tjƒ}ˆdk	r,‡fdd„ˆ D ƒˆ dd…< tjˆ dd�d }t|ƒtˆ ƒk�rJ‡ fdd„t ttˆ ƒƒ|¡D ƒ}td	| ƒ |D ]Æ}t 	t 
ˆ ¡|k¡d
 }ˆdk	rÈˆd tt t t|ƒ¡¡ƒ }ntj}tt|ƒ|ƒ}|d|… }t|ƒD ]V\}	}
|	f| D ]"}|d|  }|ˆ k�r �q&�q|ˆ k�r:|ˆ |
< qðtd| ƒ‚qðq‚ˆ S )zEnsure unique channel names.Nc                    s   g | ]}|d ˆ … ‘qS ©Nr‰   )r…   Úname)Ú
max_lengthr‰   rŠ   r‹   t   s     z)_unique_channel_names.<locals>.<listcomp>T)Zreturn_indexr	   c                    s   h | ]}ˆ | ’qS r‰   r‰   ©r…   Úx©Úch_namesr‰   rŠ   Ú	<setcomp>w   s   ÿz(_unique_channel_names.<locals>.<setcomp>z`Channel names are not unique, found duplicates for: %s. Applying running numbers for duplicates.r   z-%szRAdding a single alphanumeric for a duplicate resulted in another duplicate name %s)rŽ   ÚstringÚascii_lowercaseÚnpÚuniqueÚlenZ	setdiff1drQ   r8   ÚwhereÚarrayÚintÚceilÚlog10ÚinfÚminÚ	enumerateÚ
ValueError)r–   r’   r7   ÚsuffixesZ
unique_idsZdupsZch_stemÚoverlapsZn_keepÚidxZch_idxÚsuffixrX   r‰   )r–   r’   rŠ   Ú_unique_channel_nameso   s<    

ÿÿÿ



þ
rª   c                   @   s*   e Zd ZdZedd„ ƒZed
dd	„ƒZdS )ÚMontageMixinz&Mixin for Montage getting and setting.c           	   
      sæ   ddl m} t| tƒr| n| j}|d dkr0dS t|d ƒ}t |j¡}|d |d  ‰ ‰t	|ddddddg d	�}‡ ‡fd
d„|D ƒ}t	|dg d�}t
|ƒt
|ƒkr®t|ƒ}nt
|ƒdkrÂtdƒ‚||||j|j|j|j|jd�}|S )z]Get a DigMontage from instance.

        Returns
        -------
        %(montage)s
        r0   )Úmake_dig_montageÚdigNr–   ÚchsFT)ÚmegZeegZseegZecogZdbsÚfnirsÚexcludec                    s&   i | ]}ˆ | ˆ| d  dd… “qS )rW   Né   r‰   ©r…   Úii©r–   r®   r‰   rŠ   Ú
<dictcomp>°   s      z,MontageMixin.get_montage.<locals>.<dictcomp>)r°   r±   r   zŠMNE does not support getting the montage for a mix of fNIRS and other data types. Please raise a GitHub issue if you require this feature.)Úch_posrV   ÚnasionÚlpaÚrpaÚhspÚhpi)Úchannels.montager¬   Ú
isinstanceÚInfoÚinforK   r5   ÚgetrV   r   rœ   Ú_get_fnirs_ch_posr¥   r¸   r¹   rº   r»   r¼   )	Úselfr¬   rÀ   Zmontage_bunchrV   Úpicksr·   Zfnirs_picksÚmontager‰   rµ   rŠ   Úget_montage˜   s:    
   ÿ
ù	zMontageMixin.get_montageTFÚraiseNc                 C   s4   ddl m} t| tƒr| n| j}||||||ƒ | S )a,  Set %(montage_types)s channel positions and digitization points.

        Parameters
        ----------
        %(montage)s
        %(match_case)s
        %(match_alias)s
        %(on_missing_montage)s
        %(verbose)s

        Returns
        -------
        inst : instance of Raw | Epochs | Evoked
            The instance, modified in-place.

        See Also
        --------
        mne.channels.make_standard_montage
        mne.channels.make_dig_montage
        mne.channels.read_custom_montage

        Notes
        -----
        .. warning::
            Only %(montage_types)s channels can have their positions set using
            a montage. Other channel types (e.g., MEG channels) should have
            their positions defined properly using their data reading
            functions.
        r0   )Ú_set_montage)r½   rÈ   r¾   r¿   rÀ   )rÃ   rÅ   Z
match_caseZmatch_aliasÚ
on_missingr7   rÈ   rÀ   r‰   r‰   rŠ   Úset_montageÉ   s    #zMontageMixin.set_montage)TFrÇ   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rB   rÆ   r7   rÊ   r‰   r‰   r‰   rŠ   r«   •   s   
0    ÿr«   c                   @   s2   e Zd ZdZdd„ Zedd„ ƒZed
dd	„ƒZdS )ÚContainsMixinz-Mixin class for Raw, Evoked, Epochs and Info.c                 C   s@   t | tƒr| n| j}|dkr2t|dƒp.t|dƒ}n
t||ƒ}|S )a
  Check channel type membership.

        Parameters
        ----------
        ch_type : str
            Channel type to check for. Can be e.g. 'meg', 'eeg', 'stim', etc.

        Returns
        -------
        in : bool
            Whether or not the instance contains the given channel type.

        Examples
        --------
        Channel type membership can be tested as::

            >>> 'meg' in inst  # doctest: +SKIP
            True
            >>> 'seeg' in inst  # doctest: +SKIP
            False

        r¯   ÚmagÚgrad)r¾   r¿   rÀ   r   )rÃ   Úch_typerÀ   Zhas_ch_typer‰   r‰   rŠ   Ú__contains__õ   s    
ÿ
zContainsMixin.__contains__c                 C   s   t | tƒr| n| j}t|ƒS )z(The current gradient compensation grade.)r¾   r¿   rÀ   rL   )rÃ   rÀ   r‰   r‰   rŠ   Úcompensation_grade  s    z ContainsMixin.compensation_gradeNFc                 C   s$   t | tƒr| n| j}t||||d�S )a˜  Get a list of channel type for each channel.

        Parameters
        ----------
        %(picks_all)s
        unique : bool
            Whether to return only unique channel types. Default is ``False``.
        only_data_chs : bool
            Whether to ignore non-data channels. Default is ``False``.

        Returns
        -------
        channel_types : list
            The channel types.
        )rÄ   r›   Úonly_data_chs)r¾   r¿   rÀ   r   )rÃ   rÄ   r›   rÕ   rÀ   r‰   r‰   rŠ   Úget_channel_types  s    ÿzContainsMixin.get_channel_types)NFF)	rË   rÌ   rÍ   rÎ   rÓ   ÚpropertyrÔ   rB   rÖ   r‰   r‰   r‰   rŠ   rÏ   ò   s   
rÏ   c                 C   sJ   z| | }W n t k
r    Y n&X |d k	rFt|d |d |d ƒ| |< d S )NÚfromÚtoÚtrans)ÚKeyErrorr2   )ÚobjÚkeyÚtr‰   r‰   rŠ   Ú_format_trans0  s    rß   úinfo["chs"]Tc              	   C   s|   t | ƒ}t| t¡ƒ}|r>tdt|ƒ› d|› d|› d|› �ƒ‚|rxtt |¡ƒ}|rxtdt|ƒ› d|› d|› d|› �ƒ‚d S )NrÝ   z errantly present for ú[z]: z missing for )ÚsetÚsortedÚ
differenceÚ_ALL_CH_KEYS_SETrÛ   r=   Ú_MIN_CH_KEYS_SET)ÚchÚcir‘   Z	check_minZch_keysÚbadr‰   r‰   rŠ   Ú_check_ch_keys:  s    ÿÿrê   c                 C   s   t | tdƒ | S )NÚbads)r:   Úlist)rë   r‰   r‰   rŠ   Ú_check_badsH  s    rí   c                 C   s   t | d tfdƒ | S )Nzinfo['description']©r:   Ústr)Údescriptionr‰   r‰   rŠ   Ú_check_descriptionM  s    rñ   c                 C   s(   t | td fdƒ | d k	r$t| ddƒ} | S )Nzinfo['dev_head_t']r¯   Úhead)r:   r2   r4   )Ú
dev_head_tr‰   r‰   rŠ   Ú_check_dev_head_tR  s    rô   c                 C   s   t | d tfdƒ | S )NÚexperimenterrî   )rõ   r‰   r‰   rŠ   Ú_check_experimenterY  s    rö   c                 C   s$   t | ddƒ | d k	rt| ƒn| } | S )N)NÚnumericÚ	line_freq)r:   Úfloat)rø   r‰   r‰   rŠ   Ú_check_line_freq^  s    rú   c                 C   s   t | d tfdƒ | S )NÚsubject_info©r:   Údict)rû   r‰   r‰   rŠ   Ú_check_subject_infod  s    rþ   c                 C   s   t | d tfdƒ | S )NÚdevice_inforü   )rÿ   r‰   r‰   rŠ   Ú_check_device_infoi  s    r   c                 C   s   t | d tfdƒ | S )NÚhelium_inforü   )r  r‰   r‰   rŠ   Ú_check_helium_infon  s    r  c                -       s  e Zd ZdZddedddddd	ed
eeddedde	ddddde
ddddddddddddd d!ed"d#„ d$d%d&d'œ,Z‡ fd(d)„Zd*d+„ Zd,d-„ Z‡ fd.d/„ZdJd1d2„Zejd3d3d4œd5d6„ƒZd7d8„ Zd9d:„ Zd;d<„ Zd=d>„ ZdKd@dA„ZdBdC„ ZedDdE„ ƒZdFdG„ ZdLdHdI„Z‡  ZS )Mr¿   aø6  Measurement information.

    This data structure behaves like a dictionary. It contains all metadata
    that is available for a recording. However, its keys are restricted to
    those provided by the
    `FIF format specification <https://github.com/mne-tools/fiff-constants>`__,
    so new entries should not be manually added.

    .. warning:: The only entries that should be manually changed by the user
                 are ``info['bads']``, ``info['description']``,
                 ``info['device_info']``, ``info['dev_head_t']``,
                 ``info['experimenter']``, info['helium_info'],
                 ``info['line_freq']``, ``info['temp']`` and
                 ``info['subject_info']``. All other entries should be
                 considered read-only, though they can be modified by various
                 MNE-Python functions or methods (which have safeguards to
                 ensure all fields remain in sync).

    .. warning:: This class should not be instantiated directly. To create a
                 measurement information structure, use
                 :func:`mne.create_info`.

    Parameters
    ----------
    *args : list
        Arguments.
    **kwargs : dict
        Keyword arguments.

    Attributes
    ----------
    acq_pars : str | None
        MEG system acquisition parameters.
        See :class:`mne.AcqParserFIF` for details.
    acq_stim : str | None
        MEG system stimulus parameters.
    bads : list of str
        List of bad (noisy/broken) channels, by name. These channels will by
        default be ignored by many processing steps.
    ch_names : list of str
        The names of the channels.
    chs : list of dict
        A list of channel information dictionaries, one per channel.
        See Notes for more information.
    command_line : str
        Contains the command and arguments used to create the source space
        (used for source estimation).
    comps : list of dict
        CTF software gradient compensation data.
        See Notes for more information.
    ctf_head_t : dict | None
        The transformation from 4D/CTF head coordinates to Neuromag head
        coordinates. This is only present in 4D/CTF data.
    custom_ref_applied : int
        Whether a custom (=other than average) reference has been applied to
        the EEG data. This flag is checked by some algorithms that require an
        average reference to be set.
    description : str | None
        String description of the recording.
    dev_ctf_t : dict | None
        The transformation from device coordinates to 4D/CTF head coordinates.
        This is only present in 4D/CTF data.
    dev_head_t : dict | None
        The device to head transformation.
    device_info : dict | None
        Information about the acquisition device. See Notes for details.

        .. versionadded:: 0.19
    dig : list of dict | None
        The Polhemus digitization data in head coordinates.
        See Notes for more information.
    events : list of dict
        Event list, sometimes extracted from the stim channels by Neuromag
        systems. In general this should not be used and
        :func:`mne.find_events` should be used for event processing.
        See Notes for more information.
    experimenter : str | None
        Name of the person that ran the experiment.
    file_id : dict | None
        The FIF globally unique ID. See Notes for more information.
    gantry_angle : float | None
        Tilt angle of the gantry in degrees.
    helium_info : dict | None
        Information about the device helium. See Notes for details.

        .. versionadded:: 0.19
    highpass : float
        Highpass corner frequency in Hertz. Zero indicates a DC recording.
    hpi_meas : list of dict
        HPI measurements that were taken at the start of the recording
        (e.g. coil frequencies).
        See Notes for details.
    hpi_results : list of dict
        Head position indicator (HPI) digitization points and fit information
        (e.g., the resulting transform).
        See Notes for details.
    hpi_subsystem : dict | None
        Information about the HPI subsystem that was used (e.g., event
        channel used for cHPI measurements).
        See Notes for details.
    kit_system_id : int
        Identifies the KIT system.
    line_freq : float | None
        Frequency of the power line in Hertz.
    lowpass : float
        Lowpass corner frequency in Hertz.
        It is automatically set to half the sampling rate if there is
        otherwise no low-pass applied to the data.
    maxshield : bool
        True if active shielding (IAS) was active during recording.
    meas_date : datetime
        The time (UTC) of the recording.

        .. versionchanged:: 0.20
           This is stored as a :class:`~python:datetime.datetime` object
           instead of a tuple of seconds/microseconds.
    meas_file : str | None
        Raw measurement file (used for source estimation).
    meas_id : dict | None
        The ID assigned to this measurement by the acquisition system or
        during file conversion. Follows the same format as ``file_id``.
    mri_file : str | None
        File containing the MRI to head transformation (used for source
        estimation).
    mri_head_t : dict | None
        Transformation from MRI to head coordinates (used for source
        estimation).
    mri_id : dict | None
        MRI unique ID (used for source estimation).
    nchan : int
        Number of channels.
    proc_history : list of dict
        The MaxFilter processing history.
        See Notes for details.
    proj_id : int | None
        ID number of the project the experiment belongs to.
    proj_name : str | None
        Name of the project the experiment belongs to.
    projs : list of Projection
        List of SSP operators that operate on the data.
        See :class:`mne.Projection` for details.
    sfreq : float
        Sampling frequency in Hertz.
    subject_info : dict | None
        Information about the subject.
        See Notes for details.
    temp : object | None
        Can be used to store temporary objects in an Info instance. It will not
        survive an I/O roundtrip.

        .. versionadded:: 0.24
    utc_offset : str
        "UTC offset of related meas_date (sHH:MM).

        .. versionadded:: 0.19
    working_dir : str
        Working directory used when the source space was created (used for
        source estimation).
    xplotter_layout : str
        Layout of the Xplotter (Neuromag system only).

    See Also
    --------
    mne.create_info

    Notes
    -----
    The following parameters have a nested structure.

    * ``chs`` list of dict:

        cal : float
            The calibration factor to bring the channels to physical
            units. Used in product with ``range`` to scale the data read
            from disk.
        ch_name : str
            The channel name.
        coil_type : int
            Coil type, e.g. ``FIFFV_COIL_MEG``.
        coord_frame : int
            The coordinate frame used, e.g. ``FIFFV_COORD_HEAD``.
        kind : int
            The kind of channel, e.g. ``FIFFV_EEG_CH``.
        loc : array, shape (12,)
            Channel location. For MEG this is the position plus the
            normal given by a 3x3 rotation matrix. For EEG this is the
            position followed by reference position (with 6 unused).
            The values are specified in device coordinates for MEG and in
            head coordinates for EEG channels, respectively.
        logno : int
            Logical channel number, conventions in the usage of this
            number vary.
        range : float
            The hardware-oriented part of the calibration factor.
            This should be only applied to the continuous raw data.
            Used in product with ``cal`` to scale data read from disk.
        scanno : int
            Scanning order number, starting from 1.
        unit : int
            The unit to use, e.g. ``FIFF_UNIT_T_M``.
        unit_mul : int
            Unit multipliers, most commonly ``FIFF_UNITM_NONE``.

    * ``comps`` list of dict:

        ctfkind : int
            CTF compensation grade.
        colcals : ndarray
            Column calibrations.
        mat : dict
            A named matrix dictionary (with entries "data", "col_names", etc.)
            containing the compensation matrix.
        rowcals : ndarray
            Row calibrations.
        save_calibrated : bool
            Were the compensation data saved in calibrated form.

    * ``device_info`` dict:

        type : str
            Device type.
        model : str
            Device model.
        serial : str
            Device serial.
        site : str
            Device site.

    * ``dig`` list of dict:

        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``.

    * ``events`` list of dict:

        channels : list of int
            Channel indices for the events.
        list : ndarray, shape (n_events * 3,)
            Events in triplets as number of samples, before, after.

    * ``file_id`` dict:

        version : int
            FIF format version, i.e. ``FIFFC_VERSION``.
        machid : ndarray, shape (2,)
            Unique machine ID, usually derived from the MAC address.
        secs : int
            Time in seconds.
        usecs : int
            Time in microseconds.

    * ``helium_info`` dict:

        he_level_raw : float
            Helium level (%) before position correction.
        helium_level : float
            Helium level (%) after position correction.
        orig_file_guid : str
            Original file GUID.
        meas_date : tuple of int
            The helium level meas date.

    * ``hpi_meas`` list of dict:

        creator : str
            Program that did the measurement.
        sfreq : float
            Sample rate.
        nchan : int
            Number of channels used.
        nave : int
            Number of averages used.
        ncoil : int
            Number of coils used.
        first_samp : int
            First sample used.
        last_samp : int
            Last sample used.
        hpi_coils : list of dict
            Coils, containing:

                number: int
                    Coil number
                epoch : ndarray
                    Buffer containing one epoch and channel.
                slopes : ndarray, shape (n_channels,)
                    HPI data.
                corr_coeff : ndarray, shape (n_channels,)
                    HPI curve fit correlations.
                coil_freq : float
                    HPI coil excitation frequency

    * ``hpi_results`` list of dict:

        dig_points : list
            Digitization points (see ``dig`` definition) for the HPI coils.
        order : ndarray, shape (ncoil,)
            The determined digitization order.
        used : ndarray, shape (nused,)
            The indices of the used coils.
        moments : ndarray, shape (ncoil, 3)
            The coil moments.
        goodness : ndarray, shape (ncoil,)
            The goodness of fits.
        good_limit : float
            The goodness of fit limit.
        dist_limit : float
            The distance limit.
        accept : int
            Whether or not the fit was accepted.
        coord_trans : instance of Transformation
            The resulting MEG<->head transformation.

    * ``hpi_subsystem`` dict:

        ncoil : int
            The number of coils.
        event_channel : str
            The event channel used to encode cHPI status (e.g., STI201).
        hpi_coils : list of ndarray
            List of length ``ncoil``, each 4-element ndarray contains the
            event bits used on the event channel to indicate cHPI status
            (using the first element of these arrays is typically
            sufficient).

    * ``mri_id`` dict:

        version : int
            FIF format version, i.e. ``FIFFC_VERSION``.
        machid : ndarray, shape (2,)
            Unique machine ID, usually derived from the MAC address.
        secs : int
            Time in seconds.
        usecs : int
            Time in microseconds.

    * ``proc_history`` list of dict:

        block_id : dict
            See ``id`` above.
        date : ndarray, shape (2,)
            2-element tuple of seconds and microseconds.
        experimenter : str
            Name of the person who ran the program.
        creator : str
            Program that did the processing.
        max_info : dict
            Maxwel filtering info, can contain:

                sss_info : dict
                    SSS processing information.
                max_st
                    tSSS processing information.
                sss_ctc : dict
                    Cross-talk processing information.
                sss_cal : dict
                    Fine-calibration information.
        smartshield : dict
            MaxShield information. This dictionary is (always?) empty,
            but its presence implies that MaxShield was used during
            acquisition.

    * ``subject_info`` dict:

        id : int
            Integer subject identifier.
        his_id : str
            String subject identifier.
        last_name : str
            Last name.
        first_name : str
            First name.
        middle_name : str
            Middle name.
        birthday : tuple of int
            Birthday in (year, month, day) format.
        sex : int
            Subject sex (0=unknown, 1=male, 2=female).
        hand : int
            Handedness (1=right, 2=left, 3=ambidextrous).
    zDacq_pars cannot be set directly. See mne.AcqParserFIF() for details.z acq_stim cannot be set directly.zÊch_names cannot be set directly. Please use methods inst.add_channels(), inst.drop_channels(), inst.pick_channels(), inst.rename_channels(), inst.reorder_channels() and inst.set_channel_types() instead.zÅchs cannot be set directly. Please use methods inst.add_channels(), inst.drop_channels(), inst.pick_channels(), inst.rename_channels(), inst.reorder_channels() and inst.set_channel_types() instead.z$command_line cannot be set directly.zZcomps cannot be set directly. Please use method Raw.apply_gradient_compensation() instead.z"ctf_head_t cannot be set directly.z^custom_ref_applied cannot be set directly. Please use method inst.set_eeg_reference() instead.z!dev_ctf_t cannot be set directly.zIdig cannot be set directly. Please use method inst.set_montage() instead.zevents cannot be set directly.zfile_id cannot be set directly.z$gantry_angle cannot be set directly.zIhighpass cannot be set directly. Please use method inst.filter() instead.z!hpi_meas can not be set directly.z#hpi_results cannot be set directly.z%hpi_subsystem cannot be set directly.z%kit_system_id cannot be set directly.zHlowpass cannot be set directly. Please use method inst.filter() instead.z!maxshield cannot be set directly.zQmeas_date cannot be set directly. Please use method inst.set_meas_date() instead.z!meas_file cannot be set directly.zmeas_id cannot be set directly.z mri_file cannot be set directly.z"mri_head_t cannot be set directly.zmri_id cannot be set directly.z}nchan cannot be set directly. Please use methods inst.add_channels(), inst.drop_channels(), and inst.pick_channels() instead.z$proc_history cannot be set directly.zproj_id cannot be set directly.z!proj_name cannot be set directly.z]projs cannot be set directly. Please use methods inst.add_proj() and inst.del_proj() instead.zHsfreq cannot be set directly. Please use method inst.resample() instead.c                 C   s   | S r�   r‰   ©r”   r‰   r‰   rŠ   Ú<lambda>:  ó    zInfo.<lambda>z"utc_offset cannot be set directly.z#working_dir cannot be set directly.z'xplotter_layout cannot be set directly.),Úacq_parsÚacq_stimrë   r–   r®   Zcommand_lineÚcompsÚ
ctf_head_tÚcustom_ref_appliedrð   Ú	dev_ctf_tró   rÿ   r­   Úeventsrõ   Úfile_idÚgantry_angler  ÚhighpassÚhpi_measÚhpi_resultsÚhpi_subsystemÚkit_system_idrø   ÚlowpassZ	maxshieldÚ	meas_dateZ	meas_fileÚmeas_idZmri_fileZ
mri_head_tZmri_idÚnchanÚproc_historyÚproj_idÚ	proj_nameÚprojsÚsfreqrû   ÚtempÚ
utc_offsetZworking_dirÚxplotter_layoutc                    sd  d| _ tƒ j||Ž dD ]}t| |ƒ q|  dg ¡D ]}t|dƒ q4|  dd ¡d k	r¢t| d ƒr¢t| d tƒr€t| d t	ƒ| d< t| d d t
ƒs¢t| d ƒ| d< t|  dd ¡tƒrðdd	„ tjj| d d
 dd�D ƒ| d d
< t| d tƒ| d< t|  dg ¡ƒD ](\}}t|tƒ�s tf |Ž| d |< �q z| d }W n tk
�rL   Y nX t|ƒ| d< d| _ d S )NT)ró   r	  r  r  Úcoord_transr­   r   r®   c                 S   s   g | ]}t |ƒ‘qS r‰   )rï   r“   r‰   r‰   rŠ   r‹   N  s     z!Info.__init__.<locals>.<listcomp>rX   Úutf8©Úencodingr  r  F)Ú	_unlockedÚsuperÚ__init__rß   rÁ   rœ   r¾   rý   Ú_dict_unpackÚ	_DIG_CASTrF   rD   rš   ÚcharÚdecodeÚ_CH_CASTr¤   r   rÛ   Ú_ensure_meas_date_none_or_dt)rÃ   ÚargsÚkwargsrÝ   ÚresÚpiÚprojr  ©Ú	__class__r‰   rŠ   r&  @  s4    
 ÿzInfo.__init__c                 C   s
   d| j iS )zGet state (for pickling).r$  ©r$  ©rÃ   r‰   r‰   rŠ   Ú__getstate__]  s    zInfo.__getstate__c                 C   s   |d | _ dS )zSet state (for pickling).r$  Nr4  )rÃ   Ústater‰   r‰   rŠ   Ú__setstate__a  s    zInfo.__setstate__c                    sp   t | ddƒ}|| jkrJt| j| tƒr:|sHt| j| ƒ‚q^| j| |ƒ}ntdt|ƒ› d�ƒ‚tƒ  ||¡ dS )zAttribute setter.r$  Tz/Info does not support directly setting the key zx. You can set info['temp'] to store temporary objects in an Info instance, but these will not survive an I/O round-trip.N)ÚgetattrÚ_attributesr¾   rï   ÚRuntimeErrorÚreprr%  Ú__setitem__)rÃ   rÝ   ÚvalÚunlockedr2  r‰   rŠ   r=  e  s    
ÿzInfo.__setitem__Nc                 K   sR   t |tƒr| ¡ n|}|dk	r4|D ]\}}|| |< q"| ¡ D ]\}}|| |< q<dS )z"Update method using __setitem__().N)r¾   r   Úitems)rÃ   Úotherr.  ÚiterablerÝ   r>  r‰   r‰   rŠ   Úupdatew  s    
zInfo.updateF)Úupdate_redundantÚcheck_afterc                c   sf   t | dƒr| jnd}d| _z>z
dV  W n tk
r<   ‚ Y nX |rJ|  ¡  |rV|  ¡  W 5 || _X dS )z/Context manager unlocking access to attributes.r$  FTN)Úhasattrr$  Ú	ExceptionÚ_update_redundantÚ_check_consistency)rÃ   rD  rE  r7  r‰   r‰   rŠ   Ú_unlock€  s    
zInfo._unlockc                 C   s   t | ƒS )zyCopy the instance.

        Returns
        -------
        info : instance of Info
            The copied info.
        r   r5  r‰   r‰   rŠ   Úcopy“  s    z	Info.copyc                 C   s   t | ƒ dS )a—  (Re-)Normalize projection vectors after subselection.

        Applying projection after sub-selecting a set of channels that
        were originally used to compute the original projection vectors
        can be dangerous (e.g., if few channels remain, most power was
        in channels that are no longer picked, etc.). By default, mne
        will emit a warning when this is done.

        This function will re-normalize projectors to use only the
        remaining channels, thus avoiding that warning. Only use this
        function if you're confident that the projection vectors still
        adequately capture the original signal of interest.
        N)r   r5  r‰   r‰   rŠ   Únormalize_proj�  s    zInfo.normalize_projc              	      s^  d}dg}d}t dƒ‰ˆ ¡ D �]\}}|dkrZ|rJtd |¡|dd�}nd	}|d
8 }�n¾|dkr¦|r–d t|ƒ¡}|d |¡7 }t||dd�d }nd	}|d
8 }�nr|dkræ|rÖd dd„ |D ƒ¡}t||dd�}nd	}|d
8 }�n2|dk�r|dkrþd}n
| d¡}�n|dk�rD|dk	�rDd
dlm} d|| 	|d¡f }�nÔ|dk�r¶|dk	�r¶t
dd„ |D ƒƒ‰ ‡ fdd„tD ƒ‰ tˆ ƒ�r”dd ˆ ¡ nd‰ dt|ƒtt|ƒƒˆ f }�nbt|tƒ�rt |d  t |d  jd ¡¡�s
t|d! ƒ}t|d" ƒ}	d#||	f }nd}�n|d$k�r(d% |¡}nðt|tƒ�rDt||dd�}nÔ|d&k�rŽ‡fd'd„tt|ƒƒD ƒ}
t
|
ƒ}d ‡fd(d„| ¡ D ƒ¡}nŠ|d)k�r´tt|ƒƒ}|�s|d
8 }ndzt|ƒ}W n. tk
�rî   |dk	�ræd* |¡nd}Y n*X |dk�rd+|t|ƒt|ƒjf }nd}|dkr|d
7 }| d,||f ¡ qd- t|ƒ¡}|d.7 }||; }|S )/z'Summarize info instead of printing all.éD   z<Info | %s non-empty valuesr   Útitlesr–   ú, z ...)Úplaceholderz[]r	   rë   z
{} items (ú)r  c                 s   s,   | ]$}|d  ddddœ|d    V  qdS )Údescz: o%sÚffr`   )r   r	   ÚactiveNr‰   ©r…   r_   r‰   r‰   rŠ   Ú	<genexpr>Ä  s   ÿÿz Info.__repr__.<locals>.<genexpr>r  NÚunspecifiedz%Y-%m-%d %H:%M:%S %Zr  )ÚKIT_SYSNAMESz%i (%s)Úunknownr­   c                 s   s   | ]}|d  V  qdS )rP   Nr‰   ©r…   rd   r‰   r‰   rŠ   rV  Ó  s     c                    s,   g | ]$}|ˆ krd ˆ | t t|  f ‘qS )z%d %s)rE   rG   r³   )Úcountsr‰   rŠ   r‹   Ô  s
    þ
ÿz!Info.__repr__.<locals>.<listcomp>z (%s)r�   z%d item%s%srÚ   rØ   rÙ   z%s -> %s transform)r  r  r  z	{:.1f} Hzr®   c                    s   g | ]}t ˆ |ƒ‘qS r‰   ©r
   ©r…   r¨   r5  r‰   rŠ   r‹   è  s     c                 3   s,   | ]$\}}|› d ˆ   || ¡ ¡› �V  qdS )ú N©rÁ   Úupper)r…   rÒ   Úcount©rN  r‰   rŠ   rV  ê  s   ÿr
  z{}z%d item%s (%s)z%s: %sz
 z
>)rM   r@  r   rƒ   Úformatrœ   ÚstrftimeZkit.constantsrX  rÁ   r   rH   r=   r¾   r2   rš   ÚallcloseÚeyeÚshaper3   rï   rQ   ÚboolÚ	TypeErrorÚtyperË   Úappendrã   )rÃ   Z	MAX_WIDTHÚstrsZ	non_emptyrg   ÚvZentrrX  Zframe1Zframe2Úch_typesÚ	ch_countsZthis_lenÚstr‰   )r[  rÃ   rN  rŠ   Ú__repr__­  s–    
ÿ

þ"

þ




ÿzInfo.__repr__c                 C   sÞ   t  t ¡}d|_|  ¡ D ]º\}}|dkrdtƒ ||< |D ]*}| ¡ }|d  ¡ |d< ||  |¡ q6q|dkrz| ¡ ||< q|dkrÄtƒ }|D ],}| ¡ }dd„ |d D ƒ|d< | |¡ qŒ|||< qt||ƒ||< qd	|_|S )
zMake a deepcopy.Tr®   rW   r–   r  c                 S   s   g | ]}|  ¡ ‘qS r‰   )rK  )r…   Úcoilr‰   r‰   rŠ   r‹     s     z%Info.__deepcopy__.<locals>.<listcomp>Ú	hpi_coilsF)r¿   Ú__new__r$  r@  rì   rK  rk  r   )rÃ   ZmemodictÚresultrg   rm  rç   ÚhmsÚhmr‰   r‰   rŠ   Ú__deepcopy__  s*    

	
zInfo.__deepcopy__r�   c              	      s†  ‡ fdd„ˆ d D ƒ}t |ƒdkr6d}t|||f ƒ‚ˆ  d¡}|dk	r�tˆ d tjƒrxˆ d jdksxˆ d jtjjk	r�td|tˆ d ƒf ƒ‚d	d„ ˆ d
 D ƒ}t ˆ d ƒt |ƒksât	dd„ t
ˆ d |ƒD ƒƒsâˆ d t |ƒkrðtd|f ƒ‚ˆ  ¡ �. dD ]"}ˆ  |¡dk	rþtˆ | ƒˆ |< qþW 5 Q R X tˆ  dg ¡ƒD ]B\}}t|td|› d�ƒ dD ]}||k�r\td|› �ƒ‚�q\�q<tˆ d
 ƒD ]¨\}	}
t|
|	ƒ |
d }t|tƒ�sÆtd|	t|ƒf ƒ‚tD ]4}|
 |d¡}t|ƒ�sÊtd|	||t|ƒf ƒ‚�qÊ|
d }t|tjƒ�r"|jdk�sŒtd|	|f ƒ‚�qŒˆ  ¡ �> tˆ d ƒˆ d< tˆ d ƒD ]\}}|ˆ d
 | d< �q\W 5 Q R X dS )z4Do some self-consistency checks and datatype tweaks.c                    s   g | ]}|ˆ d  kr|‘qS r•   r‰   )r…   ré   r5  r‰   rŠ   r‹   +  s      z+Info._check_consistency.<locals>.<listcomp>rë   r   z/%sbad channel(s) %s marked do not exist in infor  NzD%sinfo["meas_date"] must be a datetime object in UTC or None, got %rc                 S   s   g | ]}|d  ‘qS ©rX   r‰   ©r…   rç   r‰   r‰   rŠ   r‹   8  s     r®   r–   c                 s   s   | ]\}}||kV  qd S r�   r‰   )r…   Zch_1Zch_2r‰   r‰   rŠ   rV  9  s    z*Info._check_consistency.<locals>.<genexpr>r  zO%sinfo channel name inconsistency detected, please notify mne-python developers)r  r  r  r  zinfo["projs"][ú])rP   rT  rR  ÚdataZexplained_varzProjection incomplete, missing rX   zABad info: info["chs"][%d]["ch_name"] is not a string, got type %sr	   zCBad info: info["chs"][%d][%r] = %s is type %s, must be float or intrW   )é   zIBad info: info["chs"][%d]["loc"] must be ndarray with 12 elements, got %r)rœ   r;  rÁ   r¾   ÚdatetimeÚtzinfoÚtimezoneÚutcr<  ÚanyÚziprJ  rù   r¤   r:   r   rê   rï   ri  rj  Ú_SCALAR_CH_KEYSr>   rš   Úndarrayrg  rª   )rÃ   Úprepend_errorÚmissingÚmsgr  r®   rÝ   r0  r1  rè   rç   rX   r>  rW   r¨   r‰   r5  rŠ   rI  )  sx    
ÿþþÿþþ



ÿÿ
ÿÿÿÿ
zInfo._check_consistencyc              	   C   s>   |   ¡ �, dd„ | d D ƒ| d< t| d ƒ| d< W 5 Q R X dS )zUpdate the redundant entries.c                 S   s   g | ]}|d  ‘qS ry  r‰   rz  r‰   r‰   rŠ   r‹   i  s     z*Info._update_redundant.<locals>.<listcomp>r®   r–   r  N)rJ  rœ   r5  r‰   r‰   rŠ   rH  f  s    
zInfo._update_redundantc                 C   s   | d S )Nr–   r‰   r5  r‰   r‰   rŠ   r–   l  s    zInfo.ch_namesc                    sJ  t dƒ‰i }‡ fdd„ttˆ d ƒƒD ƒ}t|ƒ}| ¡ D ]œ\}}|dkrtttˆ dd�ƒ|d< ttˆ dd�ƒ|d< nZ|d	kr¢tˆ d
d�}d t ˆ d ¡| ¡}n,|dkrÎtˆ d
d�}d t ˆ d ¡| ¡}	|||< q:d ‡fdd„| ¡ D ƒ¡}
d| 	¡ k�rd}	d	| 	¡ k�rd}tˆ d ƒdk�r:d ˆ d ¡}nd}|
||	|fS )NrN  c                    s   g | ]}t ˆ |ƒ‘qS r‰   r\  r]  r5  r‰   rŠ   r‹   u  s     z*Info._get_chs_for_repr.<locals>.<listcomp>r®   r¯   rÐ   )r¯   rÑ   ÚeogT)r‰  rO  r–   Úecg)rŠ  c              	      s*   g | ]"\}}|› d ˆ   || ¡ ¡› �‘qS )r^  r_  )r…   rg   rm  rb  r‰   rŠ   r‹   †  s     zNot availablerë   r   ÚNone)
rM   rQ   rœ   r   r@  r   rƒ   rš   rž   Úkeys)rÃ   Úchannelsrn  ro  rÒ   ra  Zpick_eogr‰  Zpick_ecgrŠ  Úgood_channelsÚbad_channelsr‰   )rÃ   rN  rŠ   Ú_get_chs_for_reprp  s<    ÿÿ
ÿzInfo._get_chs_for_reprc                 C   sÔ   ddl m} t|tƒr$d|› d�}nd}|  ¡ \}}}}|  d¡}|dk	rX| d¡d	 }|  d
¡}	|	rzdd„ | d
 D ƒ}	nd}	| d¡}
||
j|||	|||||  d¡|  d¡|  d¡|  d¡|  d¡|  d¡d� S )z'Summarize info for HTML representation.r0   )Úrepr_templates_envz<h4>z</h4>r�   r  Nz%B %d, %Y  %H:%M:%Sz GMTr  c                 S   s*   g | ]"}|d  › d|d rdnd› �‘qS )rR  z : rT  ÚonÚoffr‰   rU  r‰   r‰   rŠ   r‹   ¯  s   ÿz$Info._repr_html_.<locals>.<listcomp>zinfo.html.jinjar­   rû   r  r  r  rõ   )Úcaptionr  r  rŠ  r‰  rŽ  r�  r­   rû   r  r  r  rõ   )	Zhtml_templatesr‘  r¾   rï   r�  rÁ   rd  Zget_templateÚrender)rÃ   r”  r‘  ÚhtmlrŽ  r�  rŠ  r‰  r  r  Zinfo_templater‰   r‰   rŠ   Ú_repr_html_•  s<    


þ
ózInfo._repr_html_)N)r�   )N) rË   rÌ   rÍ   rÎ   rí   rñ   rô   r   rö   r  rú   rþ   r:  r&  r6  r8  r=  rC  Ú
contextlibÚcontextmanagerrJ  rK  rL  rq  rx  rI  rH  r×   r–   r�  r—  Ú__classcell__r‰   r‰   r2  rŠ   r¿   s  s„      ¾E
	
W%
=
%r¿   c                 C   s@   dd„ | d D ƒ}t || d | d | d | d d�}| ¡  |S )	z7Return a simplified info structure to speed up picking.c                    s   g | ]‰ ‡ fd d„dD ƒ‘qS )c                    s   i | ]}|ˆ | “qS r‰   r‰   )r…   rÝ   ©rç   r‰   rŠ   r¶   Ê  s   ÿ z-_simplify_info.<locals>.<listcomp>.<dictcomp>)rX   rP   rT   rS   rW   rR   r‰   ©r…   r‰   r›  rŠ   r‹   Ê  s   þ
ÿz"_simplify_info.<locals>.<listcomp>r®   rë   r  r  r
  )r®   rë   r  r  r
  )r¿   rH  )rÀ   r®   Zsub_infor‰   r‰   rŠ   Ú_simplify_infoÈ  s    þþr�  c              	   C   sâ   t | ddd�} t| ƒ\}}}|�¢ t|tjƒ}|d }g }tj}t|d ƒD ]p}|d | j}	|d | j}
|	tj	kr’t
||
ƒ}| t|jƒ¡ qL|	tjkrLt
||
ƒ}|jd }t ||¡}qLW 5 Q R X |D ]}||d< qÌ||fS )an  Read fiducials from a fiff file.

    Parameters
    ----------
    fname : path-like
        The filename to read.
    %(verbose)s

    Returns
    -------
    pts : list of dict
        List of digitizer points (each point in a dict).
    coord_frame : int
        The coordinate frame of the points (one of
        ``mne.io.constants.FIFF.FIFFV_COORD_...``).
    ÚreadT)ÚfnameÚ	overwriteZ
must_existr   ÚnentÚ	directoryrV   )rC   r   r   r   ZFIFFB_ISOTRAKÚFIFFV_COORD_HEADrQ   rP   ÚposÚFIFF_DIG_POINTr   rk  rF   r|  ZFIFF_MNE_COORD_FRAMEr   rÁ   )rŸ  r7   ÚfidÚtreeÚ_ZisotrakÚptsrV   rg   rP   r¤  ÚtagÚptr‰   r‰   rŠ   Úread_fiducialsÔ  s0    ý





r¬  rY  F)r   r7   c                C   s   t | |||d� dS )aÃ  Write fiducials to a fiff 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 : str | int
        The coordinate frame of the points. If a string, must be one of
        ``'meg'``, ``'mri'``, ``'mri_voxel'``, ``'head'``,
        ``'mri_tal'``, ``'ras'``, ``'fs_tal'``, ``'ctf_head'``,
        ``'ctf_meg'``, and ``'unknown'``
        If an integer, must be one of the constants defined as
        ``mne.io.constants.FIFF.FIFFV_COORD_...``.
    %(overwrite)s

        .. versionadded:: 1.0
    %(verbose)s
    )r   N)rJ   )rŸ  r©  rV   r   r7   r‰   r‰   rŠ   Úwrite_fiducials  s    r­  c              	   C   s0   t | ƒ\}}}|�}t||ƒd }W 5 Q R X |S )z¨Read measurement info from a file.

    Parameters
    ----------
    fname : str
        File name.
    %(verbose)s

    Returns
    -------
    %(info_not_none)s
    r   )r   Úread_meas_info)rŸ  r7   r^   r§  r¨  r¦  rÀ   r‰   r‰   rŠ   Ú	read_info  s    r¯  c                 C   s
   t | |ƒS )a  Read bad channels.

    Parameters
    ----------
    fid : file
        The file descriptor.
    node : dict
        The node of the FIF tree that contains info on the bad channels.

    Returns
    -------
    bads : list
        A list of bad channel's names.
    )Ú_read_bad_channels)r¦  Únoder‰   r‰   rŠ   Úread_bad_channels2  s    r²  c                 C   sx   |d kri n|}t |tjƒ}g }t|ƒdkrb|D ]0}t| |tjƒ}|d k	r0|jd k	r0|j d¡}q0t||ƒ|d d …< |S )Nr   ú:)	r   r   ÚFIFFB_MNE_BAD_CHANNELSrœ   r   ÚFIFF_MNE_CH_NAME_LISTr|  Úsplitr   )r¦  r±  Úch_names_mappingZnodesrë   rª  r‰   r‰   rŠ   r°  D  s    r°  c           D   	      s0  t |tjƒ}t|ƒdkr tdƒ‚t|ƒdkr4tdƒ‚|d }t |tjƒ}t|ƒdkr\tdƒ‚t|ƒdkrptdƒ‚|d }d}d}d}d}	d}
d}d}d}d}g }d}d}d}d}d}d}tj}d}d}t|d ƒD �] }|d	 | j}|d	 | j	}|tj
k�rt| |ƒ}t|jƒ}qÒ|tjk�r8t| |ƒ}t|jƒ}qÒ|tjk�r\t| |ƒ}| |j¡ qÒ|tjk�rŒt| |ƒ}t |j¡�sôt|jƒ}qÒ|tjk�r¼t| |ƒ}t |j¡�sôt|jƒ}qÒ|tjk�røt| |ƒ}t|jƒ}	t|	ƒdk�rô|	d df}	qÒ|tjk�rt| |ƒ}t|jƒ}
qÒ|tjk�rÒt| |ƒ}|j}|d
 tjk�r\|d tjk�r\|}nt|d
 tjk�r†|d tjk�r†t|ƒ}nJ|d
 tjk�r¬|d tjk�r¬|}n$|d
 tjk�rô|d tjk�rô|}qÒ|tj k�rðt| |ƒ}|j}qÒ|tj!k�rt| |ƒ}|j}qÒ|tj"k�r,t| |ƒ}|j}qÒ|tj#k�rJt| |ƒ}|j}qÒ|tj$k�rlt| |ƒ}t|jƒ}qÒ|tj%k�rŽt| |ƒ}t|jƒ}qÒ|tj&dfk�r´t| |ƒ}t|jƒ}qÒ|tj'k�rÖt| |ƒ}t|jƒ}qÒ|tj(krÒt| |ƒ}t|jƒ}qÒt)||| ƒ}|dk�rtdƒ‚|dk�r&tdƒ‚t|ƒdk�r<tdƒ‚t|ƒ|k�rRtdƒ‚|dk�sf|dk�r2t |tj*ƒ}t|ƒdk�r2|d }t|d ƒD ]œ}|d	 | j}|d	 | j	}|tjk�r”t| |ƒ}|j}|d
 tjk�r |d tjk�r |dk�r |}n.|d
 tjk�r”|d tjk�r”|dk�r”|}�q”t+| |ƒ} t |tj,ƒ}!d}"d}#t|!ƒdk�rÐ|!d }!t|!d ƒD ]\}|!d	 | j}|!d	 | j	}|tj-k�r°t| |ƒ}|j}"n|tj.k�rrt| |ƒ}|j}#�qrt/| ||d�}$t0| |||d�}%t1| ||d�}&t2|d d�‰ dˆ _3t |tj4ƒ}'t5ƒ }(|'D ]€})t6ƒ }*t|)d ƒD ]\}|)d	 | j}|)d	 | j	}|tj7k�rzt| |ƒj|*d< n|tj8k�r<t| |ƒj|*d< �q<|( |*¡ �q&|(ˆ d< t |tj*ƒ}+t5ƒ },|+D �]n}t6ƒ }-g |-d< t|d ƒD �]@}|d	 | j}|d	 | j	}|tj9k�r,|-d  t| |ƒj¡ nú|tj:k�rJt| |ƒj|-d< nÜ|tj;k�rht| |ƒj|-d< n¾|tj<k�r†t| |ƒj|-d< n |tj=k�r¤t| |ƒj|-d< n‚|tj>k�rÆtt| |ƒjƒ|-d< n`|tj?k�rètt| |ƒjƒ|-d< n>|tj@k�r
tt| |ƒjƒ|-d< n|tjk�ræt| |ƒj|-d < �qæ|, |-¡ �qÆ|,ˆ d!< t |tjAƒ}.t5ƒ }/|.D �]Z}0t6ƒ }1t|0d ƒD �]}|0d	 | j}|0d	 | j	}|tjBk�r²tt| |ƒjƒ|1d"< nÊ|tjk�rÔtt| |ƒjƒ|1d#< n¨|tj
k�rött| |ƒjƒ|1d$< n†|tjCk�	rtt| |ƒjƒ|1d%< nd|tjDk�	r:tt| |ƒjƒ|1d&< nB|tjEk�	r\tt| |ƒjƒ|1d'< n |tjFk�rntt| |ƒjƒ|1d(< �qnt |0tjGƒ}2g }3|2D �]}4t6ƒ }5t|4d ƒD ]â}|4d	 | j}|4d	 | j	}|tjHk�	rîtt| |ƒjƒ|5d)< nž|tjIk�
rt| |ƒj|5d*< d+|5d* jJ_Knt|tjLk�
rBt| |ƒj|5d,< d+|5d, jJ_KnJ|tjMk�
rlt| |ƒj|5d-< d+|5d- jJ_Kn |tjNk�	r¬tt| |ƒjƒ|5d.< �	q¬|3 |5¡ �	q”|3|1d/< |/ |1¡ �qV|/ˆ d0< ~/t |tjOƒ}6d}7t|6ƒdk�r¼|6d }6t6ƒ }7t|6d ƒD �]Â}|6d	 | j}|6d	 | j	}|tjPk�r@t| |ƒ}t|jƒ|7d< �
qö|tjQk�rht| |ƒ}t|jƒ|7d1< �
qö|tjRk�r�t| |ƒ}t|jƒ|7d2< �
qö|tjSk�r¸t| |ƒ}t|jƒ|7d3< �
qö|tjTk�rÞt| |ƒ}t|jƒ|7d4< nÚ|tjUk�r*zt| |ƒ}W n$ tVk
�r   tWd5ƒ Y �
qöY nX |j|7d6< nŽ|tjXk�rPt| |ƒ}t|jƒ|7d7< nh|tjYk�rvt| |ƒ}t|jƒ|7d8< nB|tjZk�r˜t| |ƒ}|j|7d9< n |tj[k�
röt| |ƒ}|j|7d:< �
qö|7ˆ d;< ~7t |tj\ƒ}8d}9t|8ƒdk�r¸|8d }8t6ƒ }9t|8d ƒD ]¸}|8d	 | j}|8d	 | j	}|tj]k�rDt| |ƒ}t|jƒ|9d<< np|tj^k�rjt| |ƒ}t|jƒ|9d=< nJ|tj_k�r�t| |ƒ}t|jƒ|9d>< n$|tj`k�rþt| |ƒ}t|jƒ|9d?< �qþ|9ˆ d@< ~9t |tjaƒ}:d};t|:ƒdk�r¾|:d }:t6ƒ };t|:d ƒD ]Â}|:d	 | j}|:d	 | j	}|tjbk�r@t| |ƒ}t|jƒ|;dA< nz|tjck�rft| |ƒ}t|jƒ|;dB< nT|tjdk�rŒt| |ƒ}t|jƒ|;dC< n.|tjk�rút| |ƒ}tdDdE„ |jD ƒƒ|;dF< �qú|;ˆ dG< ~;t |tjeƒ}<d}=t|<ƒdk�rø|<d }<t6ƒ }=t|<d ƒD ]ö}|<d	 | j}|<d	 | j	}|tjDk�rFt| |ƒ}t|jƒ|=d&< n$|tjfk�rjt| |ƒ}t|jƒ|=dH< t |<tjGƒ}2g }5|2D ]l}>t6ƒ }?t|>d ƒD ]H}@|>d	 |@ j}|>d	 |@ j	}|tjgk�r”t| |ƒ}t h|j¡|?dI< �q”|5 |?¡ �q~|5|=d/< �q |=ˆ dJ< ti| |ƒˆ dK< |dL dk�r~|d dk�rp|d dk�rb|dL dk�rTˆ dM ˆ dN< n|dL ˆ dN< n|d ˆ dN< n|d ˆ dN< n|dL ˆ dN< |ˆ dO< |ˆ dP< |ˆ dQ< |ˆ dR< |	dk�rÌˆ dN dS ˆ dN dT f}	tj|	ƒˆ dF< |
ˆ dU< |ˆ d#< |dk	�rö|ndVˆ dW< |dk	�r|n
ˆ d# dX ˆ dY< |ˆ dZ< |ˆ d[< |ˆ d\< |ˆ d]< |ˆ d^< |ˆ d_< |dk	�rª|dk	�rª|dk�rªd`dalkml}A tjm n|db ¡}Bt o|Bˆ d] db ¡}C|Adcdd|Cƒˆ d_< tp| ƒˆ de< |&ˆ df< ˆ  q¡  |�râ‡ fdgdh„|&D ƒˆ df< |$ˆ di< |%ˆ dj< |"ˆ dk< |#ˆ dl< |ˆ dm< |ˆ dn< |ˆ do< ˆ  r¡  d+ˆ _3ˆ |fS )paÎ  Read the measurement info.

    Parameters
    ----------
    fid : file
        Open file descriptor.
    tree : tree
        FIF tree structure.
    clean_bads : bool
        If True, clean info['bads'] before running consistency check.
        Should only be needed for old files where we did not check bads
        before saving.
    %(verbose)s

    Returns
    -------
    %(info_not_none)s
    meas : dict
        Node in tree that contains the info.
    r   zCould not find measurement datar	   z(Cannot read more that 1 measurement datazCould not find measurement infoz(Cannot read more that 1 measurement infoNr¡  r¢  rØ   rÙ   éì   z!Number of channels is not definedz!Sampling frequency is not definedzChannel information not definedz-Incorrect number of channel definitions found©r·  Úid)r  Tr�  rì   r  Ú
dig_pointsÚorderÚusedÚmomentsÚgoodnessÚ
good_limitÚ
dist_limitÚacceptr   r  Úcreatorr  r  ÚnaveÚncoilÚ
first_sampÚ	last_sampÚnumberÚepochFÚslopesÚ
corr_coeffÚ	coil_freqrs  r  Úhis_idÚ	last_nameÚ
first_nameÚmiddle_namez®Encountered an error while trying to read the birthday from the input data. No birthday will be set. Please check the integrity of the birthday information in the input data.ÚbirthdayÚsexÚhandÚweightÚheightrû   rj  ÚmodelÚserialÚsiterÿ   Úhe_level_rawÚhelium_levelÚorig_file_guidc                 s   s   | ]}t |ƒV  qd S r�   )rŸ   )r…   rÞ   r‰   r‰   rŠ   rV  Ñ  s     z!read_meas_info.<locals>.<genexpr>r  r  Úevent_channelÚ
event_bitsr  r  Z	parent_idr  r  rõ   rð   r  r  ÚsecsÚusecsr  ç        r  ç       @r  rø   r  r®   ró   r	  r  r0   )r2   rÚ   r¯   Zctf_headr­   rë   c                    s   g | ]}|ˆ d  kr|‘qS r•   r‰   )r…   Úb©rÀ   r‰   rŠ   r‹   &  s      z"read_meas_info.<locals>.<listcomp>r  r  r  r  r
  r  r  )sr   r   Ú
FIFFB_MEASrœ   r¥   ÚFIFFB_MEAS_INFOÚFIFFV_MNE_CUSTOM_REF_OFFrQ   rP   r¤  Ú
FIFF_NCHANr   rŸ   r|  Ú
FIFF_SFREQrù   ZFIFF_CH_INFOrk  ÚFIFF_LOWPASSrš   ÚisnanÚFIFF_HIGHPASSÚFIFF_MEAS_DATErŽ   ÚFIFF_UTC_OFFSETrï   ZFIFF_COORD_TRANSZFIFFV_COORD_DEVICEr£  r1   ZFIFFV_MNE_COORD_CTF_HEADZFIFFV_MNE_COORD_CTF_DEVICEÚFIFF_EXPERIMENTERÚFIFF_DESCRIPTIONÚFIFF_PROJ_IDÚFIFF_PROJ_NAMEÚFIFF_LINE_FREQÚFIFF_GANTRY_ANGLEÚFIFF_MNE_CUSTOM_REFÚFIFF_XPLOTTER_LAYOUTÚFIFF_MNE_KIT_SYSTEM_IDÚ_read_extended_ch_infoÚFIFFB_HPI_RESULTrI   ÚFIFFB_DACQ_PARSÚFIFF_DACQ_PARSÚFIFF_DACQ_STIMr   r   r°  r¿   r$  ÚFIFFB_EVENTSrì   rý   ÚFIFF_EVENT_CHANNELSÚFIFF_EVENT_LISTr¥  ÚFIFF_HPI_DIGITIZATION_ORDERÚFIFF_HPI_COILS_USEDÚFIFF_HPI_COIL_MOMENTSÚFIFF_HPI_FIT_GOODNESSÚFIFF_HPI_FIT_GOOD_LIMITÚFIFF_HPI_FIT_DIST_LIMITÚFIFF_HPI_FIT_ACCEPTÚFIFFB_HPI_MEASÚFIFF_CREATORÚ	FIFF_NAVEÚFIFF_HPI_NCOILÚFIFF_FIRST_SAMPLEÚFIFF_LAST_SAMPLEÚFIFFB_HPI_COILÚFIFF_HPI_COIL_NOÚ
FIFF_EPOCHÚflagsZ	writeableÚFIFF_HPI_SLOPESÚFIFF_HPI_CORR_COEFFÚFIFF_HPI_COIL_FREQÚFIFFB_SUBJECTÚFIFF_SUBJ_IDÚFIFF_SUBJ_HIS_IDÚFIFF_SUBJ_LAST_NAMEÚFIFF_SUBJ_FIRST_NAMEÚFIFF_SUBJ_MIDDLE_NAMEÚFIFF_SUBJ_BIRTH_DAYÚOverflowErrorr8   ÚFIFF_SUBJ_SEXÚFIFF_SUBJ_HANDÚFIFF_SUBJ_WEIGHTÚFIFF_SUBJ_HEIGHTÚFIFFB_DEVICEÚFIFF_DEVICE_TYPEZFIFF_DEVICE_MODELZFIFF_DEVICE_SERIALZFIFF_DEVICE_SITEÚFIFFB_HELIUMÚFIFF_HE_LEVEL_RAWÚFIFF_HELIUM_LEVELÚFIFF_ORIG_FILE_GUIDÚFIFFB_HPI_SUBSYSTEMÚFIFF_EVENT_CHANNELÚFIFF_EVENT_BITSrž   r.   r,  Ú
transformsr2   ZlinalgÚinvÚdotrD   rH  rI  )Dr¦  r§  Z
clean_badsr7   ZmeasZ	meas_inforó   r	  r  r  r  r  r  r  r  r®   rõ   rð   r  r  rø   r  r
  r  r  rg   rP   r¤  rª  Úcandr·  Ú
hpi_resultr­   Zacqparsr  r  r  r  rë   r  ZevsÚeventZevr  ZhrsÚhrZ	hpi_meassrv  r  rw  rs  ZhcsÚhpi_coilZhcrû   Úsirÿ   Údir  Úhir  Úhsrr  Z	this_coilÚjr2   Zhead_ctf_transZdev_ctf_transr‰   rã  rŠ   r®  R  sD   








ÿÿ
ÿÿ












ÿþÿþ



  ÿ   ÿ  ÿ























r®  c              
   C   s  t |tjƒ}t|ƒdkrd S tdt|ƒt| ƒgƒ t d¡ tƒ }t|| ƒD ]¶\}}t	|d ƒD ]˜}|d | j
}zt| \}	}
W n& tk
r¨   td|› �ƒ Y q`Y nX |	|ks¶t‚t||d | jƒj}|d k	r`|
|ƒ}|	dkrð||||	 < |||	< q`t|ƒ qL|S )Nr   zlength of channel infosz(    Reading extended channel informationr¡  r¢  z*Discarding extra channel information kind rX   )r   r   ÚFIFFB_CH_INFOrœ   r?   r6   rÀ   rý   rƒ  rQ   rP   Ú_CH_READ_MAPrÛ   r8   ÚAssertionErrorr   r¤  r|  r   )r®   Úparentr¦  Zch_infosr·  Únewrç   rg   rP   rÝ   Úcastr|  r‰   r‰   rŠ   r÷  3  s.    



r÷  c                 C   sF   | r|sd S | D ]0}|d }dD ]}t || |ƒ|| d d …< q qd S )Nr|  )Ú	row_namesÚ	col_names)r   )r  r·  Úcompr|  rÝ   r‰   r‰   rŠ   Ú_rename_compsT  s    r>  c                 C   s2   | d kst  | t¡rd } nt| tjƒs.t| ƒ} | S r�   )rš   Úarray_equalr-   r¾   r~  r;   )r  r‰   r‰   rŠ   r,  ]  s
    r,  r�   c                 C   s   dD ]€}|   |¡}|dk	rd|ks&t‚dD ]X}|| t d¡jk sV|| t d¡jkr*td|||t d¡jt d¡j|| f ƒ‚q*q|   d¡}|dkrœdS t|ƒ}|d t d¡jk sÌ|d t d¡jkrütd	|t d¡jdft d¡jdf|d f ƒ‚dS )
z€Check dates before writing as fif files.

    It's needed because of the limited integer precision
    of the fix standard.
    ©r  r  NÚmsecs)rÞ  rß  z>i4z6%sinfo[%s][%s] must be between "%r" and "%r", got "%r"r  r   zC%sinfo["meas_date"] seconds must be between "%r" and "%r", got "%r")rÁ   r7  rš   Ziinfor£   Úmaxr;  r<   )rÀ   r†  rÝ   ÚvalueZkey_2r  Úmeas_date_stampr‰   r‰   rŠ   Ú_check_datese  s<    
ÿ

ýþ

ÿ ÿþÿrE  c                 C   s˜
  |  ¡  t|ƒ t| tjƒ |d dk	r:t| tj|d ƒ |d D ]\}t| tjƒ | d¡dk	rrt	| tj
|d ƒ | d¡dk	r’t	| tj|d ƒ t| tjƒ qB|d D �]}t| tjƒ t| |d ƒ d|krât	| tj|d ƒ d	|krüt	| tj|d	 ƒ d
|k�rt| tj|d
 ƒ d|k�r4t| tj|d ƒ d|k�rPt| tj|d ƒ d|k�rlt| tj|d ƒ d|k�rˆt	| tj|d ƒ d|k�r t| |d ƒ t| tjƒ q¨|d D �]Þ}t| tjƒ | d¡dk	�rêt| tj|d ƒ | d¡dk	�rt| tj|d ƒ | d¡dk	�r.t	| tj|d ƒ | d¡dk	�rPt	| tj|d ƒ | d¡dk	�rrt	| tj|d ƒ | d¡dk	�r”t	| tj |d ƒ | d¡dk	�r¶t	| tj!|d ƒ |d D ]È}t| tj"ƒ | d¡dk	�rðt	| tj#|d ƒ | d¡dk	�rt| tj$|d ƒ | d¡dk	�r4t| tj%|d ƒ | d¡dk	�rVt| tj&|d ƒ | d¡dk	�rxt| tj'|d ƒ t| tj"ƒ �q¾t| tjƒ �q¶t| |d dd � |d! dk	�sÆ|d" dk	�rt| tj(ƒ |d! dk	�ròt| tj)|d! ƒ |d" dk	�rt| tj*|d" ƒ t| tj(ƒ |d# dk	�r:t| |d# ƒ |d$ dk	�rVt| |d$ ƒ |d% dk	�rrt| |d% ƒ t+|d& ƒ}t,| |d' |d(� t-|d) ƒd*k�rÖt.|d) |ƒ}	t| tj/ƒ t0| tj1|	ƒ t| tj/ƒ | d+¡dk	�røt| tj2|d+ ƒ | d,¡dk	�rt| tj3|d, ƒ | d-¡dk	�r<t	| tj4|d- ƒ | d.¡dk	�r^t| tj5|d. ƒ | d/¡dk	�r„t	| tj6t7|d/ ƒƒ | d0¡dk	�r¦t| tj8|d0 ƒ t	| tj|d ƒ t| tj|d ƒ |d1 dk	�rêt| tj9|d1 ƒ |d2 dk	�r
t| tj:|d2 ƒ | d3¡dk	�r,t| tj;|d3 ƒ | d4¡dk	�rNt| tj<|d4 ƒ |dk	�rft	| tj=|ƒ | d5¡�r„t	| tj>|d5 ƒ | d6¡�r¢t| tj?|d6 ƒ t@| |d& ||ƒ | d7¡dk	�r:t| tjAƒ |d7 }
|
 d8¡dk	�rút	| tjB|
d8 ƒ |
 d9¡dk	�rt| tjC|
d9 ƒ |
 d:¡dk	�r>t| tjD|
d: ƒ |
 d;¡dk	�r`t| tjE|
d; ƒ |
 d<¡dk	�r‚t| tjF|
d< ƒ |
 d=¡dk	�r¤tG| tjH|
d= ƒ |
 d>¡dk	�rÆt	| tjI|
d> ƒ |
 d?¡dk	�rèt	| tjJ|
d? ƒ |
 d@¡dk	�r
t| tjK|
d@ ƒ |
 dA¡dk	�r,t| tjL|
dA ƒ t| tjAƒ ~
| dB¡dk	�r¸t| tjMƒ |dB }t| tjN|dC ƒ dDD ]4}| |¡dk	�rtt| tOtdE| P¡  ƒ|| ƒ �qtt| tjMƒ ~| dF¡dk	�	rbt| tjQƒ |dF }| dG¡dk	�rþt| tjR|dG ƒ | dH¡dk	�	r t| tjS|dH ƒ | dI¡dk	�	rBt| tjT|dI ƒ t	| tj6|d/ ƒ t| tjQƒ ~| dJ¡dk	�
r2|dJ }t| tjUƒ | d¡dk	�	r¨t	| tj|d ƒ | dK¡dk	�	rÊt| tjV|dK ƒ | d¡dk	�
r$|d D ]@}t| tj"ƒ | dL¡dk	�
rt	| tjW|dL ƒ t| tj"ƒ �	qât| tjUƒ ~|dM }|�
rRtX|ƒ}tY||ƒ tZ| |ƒ | dN¡dk	�
r~t	| tj[|dN ƒ t| tjƒ t\| |ƒ dS )Oaþ  Write measurement info into a file id (from a fif file).

    Parameters
    ----------
    fid : file
        Open file descriptor.
    %(info_not_none)s
    data_type : int
        The data_type in case it is necessary. Should be 4 (FIFFT_FLOAT),
        5 (FIFFT_DOUBLE), or 16 (FIFFT_DAU_PACK16) for
        raw data.
    reset_range : bool
        If True, info['chs'][k]['range'] will be set to unity.

    Notes
    -----
    Tags are written in a particular order for compatibility with maxfilter.
    r  Nr  r�  rì   r  r»  r¼  r½  r¾  r¿  rÀ  rÁ  rÂ  r   r  rÃ  r  r  rÄ  rÅ  rÆ  rÇ  rs  rÈ  rÉ  rÊ  rË  rÌ  r­   T)Úblockr  r  ró   r	  r  r®   r  r¹  rë   r   rõ   rð   r  r  r  r  r  r  rø   r  r
  r  rû   rº  rÍ  rÎ  rÏ  rÐ  rÑ  rÒ  rÓ  rÔ  rÕ  rÿ   rj  )rÖ  r×  rØ  ZFIFF_DEVICE_r  rÙ  rÚ  rÛ  r  rÜ  rÝ  r  r  )]rI  rE  r!   r   rå  r,   ZFIFF_PARENT_BLOCK_IDrü  rÁ   r&   rý  rþ  r"   rø  r$   rÿ  r   r+   r  r%   r  r  r  r  r'   r  r#   r  rè  rç  r  r	  r
  r  r  r  r  r  r  r  rù  rú  rû  Ú_make_ch_names_mappingr   rœ   r   r´  r)   rµ  rî  rï  rð  rñ  rì  r<   rí  ré  rë  rò  ró  ZFIFF_DATA_PACKrô  rõ  Ú_write_ch_infosr  r  r  r  r  r  r*   r  r  r  r  r  r  r   r9  r`  r!  r"  r#  r$  r%  r&  r'  r   r>  r   rö  r/   )r¦  rÀ   Ú	data_typeÚreset_ranger-  r,  r  r/  r·  rë   r0  r1  rÝ   r2  r3  rr  r  r‰   r‰   rŠ   Úwrite_meas_info‡  s�   ÿ
ÿ
ÿ
ÿ
ÿ

ÿÿ
ÿÿ

rK  c              	   C   s>   t | ƒ�,}t|tjƒ t||||ƒ t|tjƒ W 5 Q R X dS )a¡  Write measurement info in fif file.

    Parameters
    ----------
    fname : str
        The name of the file. Should end by -info.fif.
    %(info_not_none)s
    data_type : int
        The data_type in case it is necessary. Should be 4 (FIFFT_FLOAT),
        5 (FIFFT_DOUBLE), or 16 (FIFFT_DAU_PACK16) for
        raw data.
    reset_range : bool
        If True, info['chs'][k]['range'] will be set to unity.
    N)r    r!   r   rä  rK  r"   )rŸ  rÀ   rI  rJ  r¦  r‰   r‰   rŠ   Ú
write_infoƒ  s    
rL  c                    s´  ‡ fdd„| D ƒ‰dˆ dd„ ˆD ƒf }dd„ }dd„ }d	d
„ }|ˆt tƒr–‡ fdd„| D ƒ}ˆ dkrrt||ƒƒS ˆ dkrŠtt||ƒƒƒS ||ƒS �n|ˆt tƒrî|ˆt ƒ}t|ƒdkrÄˆt|ƒ S t|ƒdkrê‡ fdd„| D ƒ}||ƒS �nÂ|ˆttƒ�r4t‡fdd„ˆdd… D ƒƒ}	|	�r(ˆd S t	|ƒ �n||ˆttƒ�r€|ˆtƒ}t|ƒdk�rfˆt|ƒ S t|ƒdk�r°t	|ƒ‚�n0|ˆt
jtƒ�sž|ˆttƒ�rðt‡fdd„ˆdd… D ƒƒ}	|	�rÊˆd S ˆ dk�ræt dˆ  ¡ dS t	|ƒ‚nÀ|ˆt
jtftƒ�rB|ˆt
jƒ}t|ƒdk�r*ˆt|ƒ S t|ƒdk�r°t	|ƒ‚nntˆƒ}
t|
ƒdk�rdt ˆƒd S tt |
ƒd tƒ�r†t d¡ dS tt |
ƒd tƒ�r¨t d¡ dS t	|ƒ‚dS )zÉMerge things together.

    Fork for {'dict', 'list', 'array', 'other'}
    and consider cases where one or all are of the same type.

    Does special things for "projs", "bads", and "meas_date".
    c                    s   g | ]}|ˆ  ‘qS r‰   r‰   rZ  ©rÝ   r‰   rŠ   r‹   ¢  s     z&_merge_info_values.<locals>.<listcomp>zPDon't know how to merge '%s'. Make sure values are compatible, got types:
    %sc                 S   s   g | ]}t |ƒ‘qS r‰   )rj  ©r…   rm  r‰   r‰   rŠ   r‹   ¥  s     c                 S   s   dd„ | D ƒS )Nc                 S   s   g | ]}|D ]}|‘qqS r‰   r‰   )r…   ZsublistÚitemr‰   r‰   rŠ   r‹   ¨  s       z8_merge_info_values.<locals>._flatten.<locals>.<listcomp>r‰   )Úlistsr‰   r‰   rŠ   Ú_flatten§  s    z$_merge_info_values.<locals>._flattenc                    s   |‡ fdd„| D ƒƒS )Nc                    s   g | ]}t |ˆ ƒ‘qS r‰   )r¾   rN  ©rP   r‰   rŠ   r‹   «  s     zA_merge_info_values.<locals>._check_isinstance.<locals>.<listcomp>r‰   )ÚvaluesrP   Úfuncr‰   rR  rŠ   Ú_check_isinstanceª  s    z-_merge_info_values.<locals>._check_isinstancec                 S   s   t  dd„ | D ƒ¡d S )zGet indices of instances.c                 S   s   g | ]}t |tƒ‘qS r‰   )r¾   rj  rN  r‰   r‰   rŠ   r‹   ¯  s     zA_merge_info_values.<locals>._where_isinstance.<locals>.<listcomp>r   )rš   r�   )rS  rP   r‰   r‰   rŠ   Ú_where_isinstance­  s    z-_merge_info_values.<locals>._where_isinstancec                 3   s   | ]}|ˆ  V  qd S r�   r‰   rZ  rM  r‰   rŠ   rV  ³  s     z%_merge_info_values.<locals>.<genexpr>r  rë   r	   c                 3   s$   | ]}t |ˆ  tƒr|ˆ  V  qd S r�   )r¾   rì   rZ  rM  r‰   rŠ   rV  ¿  s      c                 3   s    | ]}t ˆ d  |ƒdkV  qdS ©r   r�   N©r9   rN  ©rS  r‰   rŠ   rV  Ã  s     Nr   c                 3   s   | ]}t  ˆ d  |¡V  qdS )r   N)rš   r?  r“   rY  r‰   rŠ   rV  Ñ  s     r  z6Found multiple entries for %s. Setting value to `None`z:Found multiple StringIO instances. Setting value to `None`z1Found multiple filenames. Setting value to `None`)rì   Úallr   rã   râ   r‚  rœ   rŸ   rý   r;  rš   r…  rŽ   r6   rÀ   r¾   r   rï   )ÚinfosrÝ   r7   rˆ  rQ  rU  rV  rP  r¨   Zis_qualZunique_valuesr‰   )rÝ   rS  rŠ   Ú_merge_info_values™  sx    	þ


ÿ
ÿ



r\  c           
         sŽ  | D ]‰ ˆ   ¡  q|dkr8t| ƒ} t| d | dd… ƒ tƒ ‰ dˆ _g ˆ d< | D ]}ˆ d  |d ¡ qPˆ  ¡  ‡ fdd„ˆ d D ƒ}t|ƒdkr¦d	t|ƒ }t	|ƒ‚d
ddg}|D ]„‰‡fdd„| D ƒ‰tˆƒdkràdˆ ˆ< q´tˆƒdkrúˆd ˆ ˆ< q´t
‡fdd„ˆdd… D ƒƒ�r(ˆd ˆ ˆ< q´dˆ }t	|ƒ‚q´dd„ | D ƒ}t|ƒdk�r`dˆ d< n(tt|ƒƒdk�r€|d ˆ d< nt	dƒ‚dddg}|D ]Š‰‡fdd„| D ƒ‰tˆƒdk�rÄg ˆ ˆ< nZtˆƒdk�ràˆd ˆ ˆ< n>t
‡fdd„ˆdd… D ƒƒ�rˆd ˆ ˆ< ndˆ }t	|ƒ‚�q–dddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d/d2d3g}	|	D ]‰t| ˆƒˆ ˆ< �q^| d d4 ˆ d4< d5ˆ _ˆ S )6a¿  Merge multiple measurement info dictionaries.

     - Fields that are present in only one info object will be used in the
       merged info.
     - Fields that are present in multiple info objects and are the same
       will be used in the merged info.
     - Fields that are present in multiple info objects and are different
       will result in a None value in the merged info.
     - Channels will be concatenated. If multiple info objects contain
       channels with the same name, an exception is raised.

    Parameters
    ----------
    infos | list of instance of Info
        Info objects to merge into one info object.
    force_update_to_first : bool
        If True, force the fields for objects in `info` will be updated
        to match those in the first item. Use at your own risk, as this
        may overwrite important metadata.
    %(verbose)s

    Returns
    -------
    info : instance of Info
        The merged info object.
    Tr   r	   Nr®   c                    s"   h | ]}ˆ d    |¡dkr|’qS )r–   r	   )ra  rz  rã  r‰   rŠ   r—   	  s    ÿz_merge_info.<locals>.<setcomp>r–   zVThe following channels are present in more than one input measurement info objects: %sr	  ró   r  c                    s   g | ]}|ˆ  r|ˆ  ‘qS r‰   r‰   ©r…   Úi)Ú
trans_namer‰   rŠ   r‹   !	  s      z_merge_info.<locals>.<listcomp>c                 3   sP   | ]H}t  ˆ d  d |d k¡oFˆ d  d |d koFˆ d  d |d kV  qdS )r   rÚ   rØ   rÙ   N)rš   rZ  r“   )rÚ   r‰   rŠ   rV  &	  s
   ýÿz_merge_info.<locals>.<genexpr>z2Measurement infos provide mutually inconsistent %sc                 S   s   g | ]}|d  r|d  ‘qS )r  r‰   r]  r‰   r‰   rŠ   r‹   1	  s      r  z3Trying to merge channels from different KIT systemsr  r  r­   c                    s   g | ]}|ˆ  r|ˆ  ‘qS r‰   r‰   r]  )rg   r‰   rŠ   r‹   <	  s      c                 3   s    | ]}t ˆ d  |ƒdkV  qdS rW  rX  rN  rY  r‰   rŠ   rV  A	  s     z)Measurement infos are inconsistent for %sr  r  rë   r  r
  rð   rõ   r  r  r  r  r  rÿ   r  rø   r  r  r  r  r  r  r  rû   r  r  r  F)rI  r   Ú_force_update_infor¿   r$  ÚextendrH  rœ   rì   r¥   rZ  râ   r\  )
r[  Zforce_update_to_firstr7   Z	this_infoÚ
duplicatesrˆ  r(  Zkit_sys_idsÚfieldsZother_fieldsr‰   )rÀ   rg   rÚ   r_  rS  rŠ   Ú_merge_infoñ  sž    
ÿ


ý
ÿ



                  úrd  Úmiscc                 C   sÚ  zt  | ¡} W n tk
r"   Y nX tt | ¡ t¡ƒ} t| tt	fddƒ t
|ƒ}|dkrbtdƒ‚t| ƒ}t|tƒr~|g| }t t |tj¡¡}|jdks¨t|ƒ|kr¾tdt|ƒ||f ƒ‚t|ƒ}tdd�}tt| |ƒƒD ]à\}\}}	t|d	d
ƒ t|	d	dƒ |	|k�r$tdt|ƒ› d|	› �ƒ‚||	 }
|
d }t|tt	fƒ�rL|d n|}t |tj¡}|
 dtj¡}|
 dtj¡}tt dtj¡tj dd||||t|ƒ|d |d d�}|d  !|¡ qÞ| "¡  | #¡  d|_$|S )a  Create a basic Info instance suitable for use with create_raw.

    Parameters
    ----------
    ch_names : list of str | int
        Channel names. If an int, a list of channel names will be created
        from ``range(ch_names)``.
    sfreq : float
        Sample rate of the data.
    ch_types : list of str | str
        Channel types, default is ``'misc'`` which is not a
        :term:`data channel <data channels>`.
        Currently supported fields are 'ecg', 'bio', 'stim', 'eog', 'misc',
        'seeg', 'dbs', 'ecog', 'mag', 'eeg', 'ref_meg', 'grad', 'emg', 'hbr'
        or 'hbo'. If str, then all channels are assumed to be of the same type.
    %(verbose)s

    Returns
    -------
    %(info_not_none)s

    Notes
    -----
    The info dictionary will be sparsely populated to enable functionality
    within the rest of the package. Advanced functionality such as source
    localization can only be obtained through substantial, proper
    modifications of the info structure (not recommended).

    Note that the MEG device-to-head transform ``info['dev_head_t']`` will
    be initialized to the identity transform.

    Proper units of measure:
    * V: eeg, eog, seeg, dbs, emg, ecg, bio, ecog
    * T: mag
    * T/m: grad
    * M: hbo, hbr
    * Am: dipole
    * AU: misc
    r–   zlist, tuple, or intr   zsfreq must be positiver	   zHch_types and ch_names must be the same length (%s != %s) for ch_types=%sT)Zinclude_defaultsrï   zeach entry in ch_nameszeach entry in ch_typeszkind must be one of z, not rP   rS   rT   r}  ç      ð?)rW   rU   rQ   rR   rP   rS   rT   rV   rX   rN   rO   r®   F)%ÚoperatorÚindexri  rì   rš   ZarangeZastyperï   r:   rŽ   rù   r¥   rœ   r¾   Ú
atleast_1drž   Zstr_ÚndimÚ_empty_infor   r¤   rƒ  rÛ   r   rÁ   r   ZFIFFV_COORD_UNKNOWNZFIFFV_COIL_NONEZFIFF_UNIT_NONErý   ÚfullÚnanZFIFF_UNITM_NONErk  rH  rI  r$  )r–   r  rn  r7   r  rÀ   Zch_types_dictrè   rX   rÒ   Zthis_ch_dictrP   rV   rS   rT   Z	chan_infor‰   r‰   rŠ   Úcreate_infoY	  sb    )ÿ

þ

      ürn  )$r  r  rë   r–   r®   r  r	  r
  rð   r  ró   r­   rõ   r  r  rÿ   r  r  r  r  r  r  r  rø   r  r  r  r  r  r  r  r  rû   r  r  r  c                 C   sŠ   d}d}t ƒ }d|_|D ]}d||< q|D ]}tƒ ||< q*tj|d< d|d< t| ƒ|d< |d d	 |d
< tddƒ|d< | ¡  | ¡  |S )z Create an empty info dictionary.)r  r  r	  rð   r  r­   rõ   r  rÿ   r  r  r  r  r  rø   r  r  r  r  r  rû   r  r  )rë   r®   r  r  r  r  r  r  TNr
  rà  r  r  rá  r  r¯   rò   ró   )	r¿   r$  rì   r   ræ  rù   r2   rH  rI  )r  Z
_none_keysZ
_list_keysrÀ   rg   r‰   r‰   rŠ   rk  ½	  s     

rk  c                 C   s�   dddg}t  |¡ ¡ }t  | |g¡}|D ]}t|tƒs*tdt|ƒ ƒ‚q*|  ¡ D ]8\}}||krdqR|D ] }| 	¡ � |||< W 5 Q R X qhqRdS )a  Update target info objects with values from info base.

    Note that values in info_target will be overwritten by those in info_base.
    This will overwrite all fields except for: 'chs', 'ch_names', 'nchan'.

    Parameters
    ----------
    info_base : mne.Info
        The Info object you want to use for overwriting values
        in target Info objects.
    info_target : mne.Info | list of mne.Info
        The Info object(s) you wish to overwrite using info_base. These objects
        will be modified in-place.
    r®   r–   r  z*Inputs must be of type Info. Found type %sN)
rš   ri  ZravelZhstackr¾   r¿   r¥   rj  r@  rJ  )Z	info_baseZinfo_targetZexclude_keysZ	all_infosr´   rÝ   r>  Zi_targr‰   r‰   rŠ   r`  Ø	  s    

ÿ
r`  c                 C   s   | dk	rt t| ƒ| ƒ} | S )z%Add a timedelta to a meas_date tuple.N)r<   r;   )rD  Údelta_tr‰   r‰   rŠ   Ú_add_timedelta_to_stampö	  s    rp  c              	   C   sl  t | ddƒ tjddddddtjjd�}d}d}d}d}| d	 d
k}	|	rZ|d
k	r tdƒ nF|d
krp| d	 | }
ntj|d�}
|  ¡ � | d	 |
 | d	< W 5 Q R X dD ]�}|  |¡}|d
k	r¤d|ksÆt‚|	sÞ|d |d ft	krät	}nt
|d |d f|
 ƒ}|d |d< |d |d< |d  ¡ }d|d
d
…< ||d< q¤|  d¡}|d
k	�rl| d¡d
k	�rb||d< |�rtt d¡ nJ| d¡d
k	�r�t|ƒ|d< | d¡d
k	�r¨||d< | d¡d
k	�r¾|d= dD ]}| |¡d
k	�rÂ|||< �qÂ|	�rö| dd
¡ nR| d¡d
k	�rHt |d d |d d |d d ¡}||
8 }|j|j|jf|d< dD ]}| |¡d
k	�rLd||< �qL|| d< || d< |  ¡ �R | d d
k	�r¦t | d ¡| d< | d d
k	�r¼|| d< | d  d
k	�rÒd
| d < W 5 Q R X |  d!¡}|d
k	�r |D ]ª}d|d" d d
d
…< ||d< |	�rDt	d |d" d< t	d |d" d< t	|d#< nX|d" d |d" d f}t
||
 ƒ}|d |d" d< |d |d" d< t
|d# |
 ƒ|d#< �qô|  d$¡}|d
k	�r| d%¡d
k	�rÌ||d%< |	�rì| d	¡d
k	�rìt	|d	< n$| d	¡d
k	�rt
|d	 |
 ƒ|d	< |  d&¡}|d
k	�rHd'D ]}| |¡d
k	�r(|||< �q(d(}| j|d)� d*}t| |d)� | S )+aÉ  Anonymize measurement information in place.

    .. warning:: If ``info`` is part of an object like
                 :class:`raw.info <mne.io.Raw>`, you should directly use
                 the method :meth:`raw.anonymize() <mne.io.Raw.anonymize>`
                 to ensure that all parts of the data are anonymized and
                 stay synchronized (e.g.,
                 :class:`raw.annotations <mne.Annotations>`).

    Parameters
    ----------
    %(info_not_none)s
    %(daysback_anonymize_info)s
    %(keep_his_anonymize_info)s
    %(verbose)s

    Returns
    -------
    info : instance of Info
        The anonymized measurement information.

    Notes
    -----
    %(anonymize_info_notes)s
    rÀ   rÃ   iÐ  r	   r   )r  Zmne_anonymizez<Anonymized using a time shift to preserve age at acquisitionr  Nz}Input info has "meas_date" set to None. Removing all information from time/date structures, *NOT* performing any time shifts!)Údaysr@  rA  rÞ  rß  Zmachidrû   rº  z?Not fully anonymizing info - keeping his_id, sex, and hand inforÍ  rÒ  rÓ  )rÎ  rÏ  rÐ  rÑ  r0   )rÔ  rÕ  rõ   rð   r  r  r  r  Zblock_idÚdater  rÛ  rÿ   )r×  rØ  zHanonymize_info generated an inconsistent info object. Underlying Error:
)r†  zjanonymize_info generated an inconsistent info object. daysback parameter was too large. Underlying Error:
)r:   r~  r€  r�  r8   Ú	timedeltarJ  rÁ   r7  r-   rp  rK  r6   rÀ   rï   ÚpopÚyearÚmonthÚdayrš   Z
zeros_likerI  rE  )rÀ   ZdaysbackZkeep_hisr7   Zdefault_anon_dosZdefault_strZdefault_subject_idZdefault_sexZdefault_descZnone_meas_datero  rÝ   rC  ÚtmpZ_tmprû   ZdobZ	proc_histÚrecordZthis_t0Zthis_t1r2  r1  rg   Zerr_mesgr‰   r‰   rŠ   Úanonymize_infoý	  sâ    ÿ


ÿ ÿ




þ





ÿ ÿ ÿ


 ÿ

rz  c                 C   sœ   d| krdg fS t |ƒ}g }| d D ]0}t| |d d ¡ƒdkr$| |d d ¡ q$tt |ƒƒ}tt |ƒ |¡ƒ}t| ƒdkr”t|ƒdkr”d|fS d|fS )aÆ  Check if channel names are consistent with current compensation status.

    Parameters
    ----------
    %(info_not_none)s

    ch_names : list of str
        The channel names to check.

    Returns
    -------
    status : bool
        True if compensation is *currently* in use but some compensation
            channels are not included in picks

        False if compensation is *currently* not being used
            or if compensation is being used and all compensation channels
            in info and included in picks.

    missing_ch_names: array-like of str, shape (n_missing,)
        The names of compensation channels not included in picks.
        Returns [] if no channels are missing.

    r  Fr|  r;  r   r<  T)râ   rœ   Úintersectionra  rã   rä   rL   )rÀ   r–   Z
ch_names_sZ
comp_namesr=  Zmissing_ch_namesr‰   r‰   rŠ   Ú_bad_chans_comp¡
  s    r|  c                 C   s   | S r�   r‰   r  r‰   r‰   rŠ   r  Ð
  r  r  )rP   ÚidentÚrrV   c                 C   s   | S r�   r‰   r  r‰   r‰   rŠ   r  Ù
  r  )rN   rO   rP   rQ   rR   rS   rW   rT   rU   rX   rV   c                 c   s   | ]\}}||d  fV  qdS )r	   Nr‰   ©r…   rÝ   r>  r‰   r‰   rŠ   rV  à
  s     rV  c                 c   s&   | ]\}}|d  ||d ffV  qdS )r   r	   Nr‰   r  r‰   r‰   rŠ   rV  â
  s   ÿc              
   c   sª   |   dd ¡}| d }|  ¡ �„ zb|d k	rFt|ƒdkrFt| d tƒ| d< t| d tƒ| d< tjj| d d dd�| d d< d V  W 5 |d k	r’|| d< || d< X W 5 Q R X d S )Nr­   r®   r   rX   r!  r"  )	rÁ   rJ  rœ   Ú
_dict_packr(  r+  rš   r)  Úencode)rÀ   Zorig_digZorig_chsr‰   r‰   rŠ   Ú_writing_info_hdf5æ
  s    

 ÿ
r‚  c                    s   ‡ fdd„|D ƒS )Nc                    s&   i | ]‰ ˆ t  ‡ fd d„ˆD ƒ¡“qS )c                    s   g | ]}|ˆ  ‘qS r‰   r‰   )r…   ÚorM  r‰   rŠ   r‹   û
  s     z)_dict_pack.<locals>.<dictcomp>.<listcomp>)rš   rž   rœ  ©rÜ   rM  rŠ   r¶   û
  s      z_dict_pack.<locals>.<dictcomp>r‰   )rÜ   Úcastsr‰   r„  rŠ   r€  ù
  s    r€  c                    s,   t ˆtˆ ƒd  ƒ}‡ ‡fdd„t|ƒD ƒS )Nr   c                    s$   g | ]‰ ‡ ‡fd d„ˆ  ¡ D ƒ‘qS )c                    s"   i | ]\}}||ˆ| ˆ  ƒ“qS r‰   r‰   )r…   rÝ   r:  )r´   rÜ   r‰   rŠ   r¶     s      z+_dict_unpack.<locals>.<listcomp>.<dictcomp>)r@  rœ  ©r…  rÜ   )r´   rŠ   r‹     s   ÿz _dict_unpack.<locals>.<listcomp>)rœ   rì   rQ   )rÜ   r…  r`   r‰   r†  rŠ   r'  þ
  s    ÿr'  c                 C   sF   dd„ | D ƒ}|  ¡ }t|ddd� tƒ }||krB| t||ƒ¡ |S )Nc                 S   s   g | ]}|d  ‘qS ry  r‰   )r…   rc   r‰   r‰   rŠ   r‹     s     z*_make_ch_names_mapping.<locals>.<listcomp>é   Úerror)r’   r7   )rK  rª   rý   rC  rƒ  )r®   Zorig_ch_namesr–   r·  r‰   r‰   rŠ   rG    s    rG  c                 C   sî   |d krt ƒ n|}t|ƒD ]^\}}| ¡ }| |d |d ¡|d< t|d ƒdksVt‚|d |d< |rnd|d< t| |ƒ qt|ƒrêt d¡ |D ]X}t	| t
jƒ t|ƒttƒks´t‚t ¡ D ]\}\}}	}
|
| ||| ƒ q¼t| t
jƒ q�d S )NrX   r‡  r	   rN   rf  rQ   zJ    Writing channel names to FIF truncated to 15 characters with remapping)rý   r¤   rK  rÁ   rœ   r7  r(   r6   rÀ   r!   r   r5  râ   Ú_CH_INFO_MAPr@  r"   )r¦  r®   rJ  r·  rg   rc   rç   rÝ   Úconstr¨  Úwriter‰   r‰   rŠ   rH    s&    ÿrH  rÇ   )Úon_mismatchc                C   sb  t |dd� |  ¡  | ¡  | d |d kr:t|› d�ƒ‚t| d ƒt|d ƒkr`t|› d�ƒ‚| d |d kr~t|› d�ƒ‚t| d	 ƒt|d	 ƒkr¤t|› d
�ƒ‚t|d ƒt| d ƒkrÌtd|› d�ƒ‚tdd„ t|d | d ƒD ƒƒrütd|› d�ƒ‚| d dk|d dkk�sF| d dk	�r^tj| d d |d d dd��s^|› d�}t	||dd� dS )a{  Check if infos match.

    Parameters
    ----------
    info1, info2 : instance of Info
        The infos to compare.
    name : str
        The name of the object appearing in the error message of the comparison
        fails.
    on_mismatch : 'raise' | 'warn' | 'ignore'
        What to do in case of a mismatch of ``dev_head_t`` between ``info1``
        and ``info2``.
    rŒ  )rÉ   r‘   r  z.info['nchan'] must matchrë   z.info['bads'] must matchr  z.info['sfreq'] must matchr–   z.info['ch_names'] must matchr  zSSP projectors in z must be the samec                 s   s   | ]\}}t ||ƒ V  qd S r�   )r   )r…   Úp1Zp2r‰   r‰   rŠ   rV  E  s     z&_ensure_infos_match.<locals>.<genexpr>ró   NrÚ   g�íµ ÷Æ°>)Zrtolai  .info['dev_head_t'] differs. The instances probably come from different runs, and are therefore associated with different head positions. Manually change info['dev_head_t'] to avoid this message but beware that this means the MEG sensors will not be properly spatially aligned. See mne.preprocessing.maxwell_filter to realign the runs to a common head position.)rÉ   rˆ  r‘   )
rA   rI  r¥   râ   rœ   r‚  rƒ  rš   re  r@   )Zinfo1Zinfo2r‘   rŒ  rˆ  r‰   r‰   rŠ   Ú_ensure_infos_match(  s:    ÿ
ÿ
 ÿþ
ÿrŽ  c                 C   s@   ddl m}m} || ƒ\}}i }||•D ]}|| |ƒ||< q(|S )a  Return positions of each fNIRS optode.

    fNIRS uses two types of optodes, sources and detectors.
    There can be multiple connections between each source
    and detector at different wavelengths. This function
    returns the location of each source and detector.
    r0   )Ú_fnirs_optode_namesÚ_optode_position)Zpreprocessing.nirsr�  r�  )rÀ   r�  r�  ZsrcsZdetsr·   Zoptoder‰   r‰   rŠ   rÂ   X  s    rÂ   )NN)rà   T)N)rY  )N)FN)r�   )NT)NT)N)FN)re  N)NFN)ªÚcollectionsr   r   Úcollections.abcr   r˜  rK  r   r~  Úior   rg  Útextwrapr   r˜   Únumpyrš   Úpickr
   r   r   r   r   Ú	constantsr   r   Úopenr   r§  r   rª  r   r   r   r   r   r1  r   r   r   r   r   r   Zctf_compr   r   r‹  r    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r  r.   r/   r(  r1   r2   r3   r4   r5   Úutilsr6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   Z_digitizationrD   rE   rF   rG   rH   rI   rJ   rK   ZcompensatorrL   ÚdefaultsrM   Úbytesrâ  r„  râ   rå   ræ   r�   rª   Úobjectr«   rÏ   rß   rê   rí   rñ   rô   rö   rú   rþ   r   r  rý   r¿   r�  r¬  r­  r¯  r²  r°  r®  r÷  r>  r,  rE  rK  rL  r\  rd  rn  ZRAW_INFO_FIELDSrk  r`  rp  rz  r|  rŸ   r(  ZFIFF_CH_SCAN_NOZFIFF_CH_LOGICAL_NOZFIFF_CH_KINDZFIFF_CH_RANGErù   ZFIFF_CH_CALZFIFF_CH_COIL_TYPEZFIFF_CH_LOCZFIFF_CH_UNITZFIFF_CH_UNIT_MULZFIFF_CH_DACQ_NAMErï   ZFIFF_CH_COORD_FRAMEr‰  r@  r+  r6  r™  r‚  r€  r'  rG  rH  rŽ  rÂ   r‰   r‰   r‰   rŠ   Ú<module>	   sò    @@ 5%]>

      [.ÿ   c!	
" |WgX $
-   ÿ









õÿ

0