U
    f»{jk÷  ã                   @   s0  d dl mZ d dlmZmZmZ d dlmZ d dlZd dl	m
Z
 d dlmZ d dlZd dl 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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$m%Z%m&Z&m'Z'm(Z(m)Z) d	dl*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1 d	dl2m3Z3 d	dl4m5Z5 d	dl6m7Z7 d	dl8m9Z9 eZ:dd„ Z;dd„ Z<e&G dd„ de=ƒƒZ>G dd„ dƒZ?dd„ Z@dd„ ZAdJdd„ZBdKd d!„ZCdLd#d$„ZDd%d&„ ZEd'd(„ ZFd)d*„ ZGdMd,d-„ZHd.d/„ ZIdNd0d1„ZJd2d3„ ZKd4d5„ ZLd6d7„ ZMd8d9„ ZNd:d;„ ZOd<d=„ ZPd>d?„ ZQd@dA„ ZRedOdDdE„ƒZSedPdFdG„ƒZTdHdI„ ZUdS )Qé    )ÚOrderedDict)ÚdatetimeÚ	timedeltaÚtimezoneN©Údeepcopy)Ú	takewhile)ÚCounter)ÚIterable)Úshortené   )Ú_plÚcheck_fnameÚ_validate_typeÚverboseÚwarnÚloggerÚ_check_pandas_installedÚ_mask_to_onsets_offsetsÚ_DefaultEventParserÚ	_check_dtÚ_stamp_to_dtÚ_dt_to_stampÚ_check_fnameÚint_likeÚ_check_optionÚfill_docÚ_on_missingÚ_is_numericÚ_check_dict_keys)Ústart_blockÚ	end_blockÚwrite_floatÚwrite_name_listÚwrite_doubleÚ
start_fileÚwrite_string)ÚFIFF)Ú	fiff_open)Údir_tree_find)Úread_tagc              
   C   sö  t  t j| td�¡} | jdkr2td| j| jf ƒ‚t j|td�}|jdksT|jdkrdt  |t| ƒ¡}|jdkr~td|jf ƒ‚t j|t	d�}|jdks |jdkr°t  |t| ƒ¡}|jdkrÊtd|jf ƒ‚t
|dd	ƒ t|d ttt jfd
ƒ |d k�rdgt| ƒ }t|ƒ}t|ƒD ]d\}}t|ttt jfd|› d�ƒ t|ƒ||< t|| ƒD ]$\}}t|t	d|› d|› d�ƒ �qP�qt|ƒ}t| ƒt|ƒ  k�r¶t|ƒ  k�r¶t|ƒk�sên tdt| ƒ› dt|ƒ› dt|ƒ› dt|ƒ› d�	ƒ‚| |||fS )N©Údtyper   z9Onset must be a one dimensional array, got %s (shape %s).r   )r   z1Duration must be a one dimensional array, got %d.z4Description must be a one dimensional array, got %d.ÚcheckÚdescriptionÚch_names© z	ch_names[ú]z][zGOnset, duration, description, and ch_names must be equal in sizes, got ú, z, and Ú.)ÚnpÚ
atleast_1dÚarrayÚfloatÚndimÚ
ValueErrorÚshapeÚrepeatÚlenÚstrÚ_prep_name_listr   ÚtupleÚlistZndarrayÚ	enumerateÚ_ndarray_ch_names)ÚonsetÚdurationr.   r/   ZaiÚchÚciÚnamer0   r0   úN/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/annotations.pyÚ_check_o_d_s_c%   sF    

þ
ÿ
ÿ
"6,ÿrI   c                 C   s"   t jt| ƒtd�}| |d d …< |S )Nr+   )r4   Úemptyr<   Úobject)r/   Úoutr0   r0   rH   rB   N   s    rB   c                   @   sÚ   e Zd ZdZd.dd„Zedd„ ƒZdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zed/dd„ƒZdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zed!dd"œd#d$„ƒZd%d&„ Zed0d(d)„ƒZed1d*d+„ƒZed2d,d-„ƒZdS )3ÚAnnotationsaÍ  Annotation object for annotating segments of raw data.

    .. note::
       To convert events to `~mne.Annotations`, use
       `~mne.annotations_from_events`. To convert existing `~mne.Annotations`
       to events, use  `~mne.events_from_annotations`.

    Parameters
    ----------
    onset : array of float, shape (n_annotations,)
        The starting time of annotations in seconds after ``orig_time``.
    duration : array of float, shape (n_annotations,) | float
        Durations of the annotations in seconds. If a float, all the
        annotations are given the same duration.
    description : array of str, shape (n_annotations,) | str
        Array of strings containing description for each annotation. If a
        string, all the annotations are given the same description. To reject
        epochs, use description starting with keyword 'bad'. See example above.
    orig_time : float | str | datetime | tuple of int | None
        A POSIX Timestamp, datetime or a tuple containing the timestamp as the
        first element and microseconds as the second element. Determines the
        starting time of annotation acquisition. If None (default),
        starting time is determined from beginning of raw data acquisition.
        In general, ``raw.info['meas_date']`` (or None) can be used for syncing
        the annotations with raw data if their acquisition is started at the
        same time. If it is a string, it should conform to the ISO8601 format.
        More precisely to this '%%Y-%%m-%%d %%H:%%M:%%S.%%f' particular case of
        the ISO8601 format where the delimiter between date and time is ' '.
    %(ch_names_annot)s

        .. versionadded:: 0.23

    See Also
    --------
    mne.annotations_from_events
    mne.events_from_annotations

    Notes
    -----
    Annotations are added to instance of :class:`mne.io.Raw` as the attribute
    :attr:`raw.annotations <mne.io.Raw.annotations>`.

    To reject bad epochs using annotations, use
    annotation description starting with 'bad' keyword. The epochs with
    overlapping bad segments are then rejected automatically by default.

    To remove epochs with blinks you can do:

    >>> eog_events = mne.preprocessing.find_eog_events(raw)  # doctest: +SKIP
    >>> n_blinks = len(eog_events)  # doctest: +SKIP
    >>> onset = eog_events[:, 0] / raw.info['sfreq'] - 0.25  # doctest: +SKIP
    >>> duration = np.repeat(0.5, n_blinks)  # doctest: +SKIP
    >>> description = ['bad blink'] * n_blinks  # doctest: +SKIP
    >>> annotations = mne.Annotations(onset, duration, description)  # doctest: +SKIP
    >>> raw.set_annotations(annotations)  # doctest: +SKIP
    >>> epochs = mne.Epochs(raw, events, event_id, tmin, tmax)  # doctest: +SKIP

    **ch_names**

    Specifying channel names allows the creation of channel-specific
    annotations. Once the annotations are assigned to a raw instance with
    :meth:`mne.io.Raw.set_annotations`, if channels are renamed by the raw
    instance, the annotation channels also get renamed. If channels are dropped
    from the raw instance, any channel-specific annotation that has no channels
    left in the raw instance will also be removed.

    **orig_time**

    If ``orig_time`` is None, the annotations are synced to the start of the
    data (0 seconds). Otherwise the annotations are synced to sample 0 and
    ``raw.first_samp`` is taken into account the same way as with events.

    When setting annotations, the following alignments
    between ``raw.info['meas_date']`` and ``annotation.orig_time`` take place:

    ::

        ----------- meas_date=XX, orig_time=YY -----------------------------

             |              +------------------+
             |______________|     RAW          |
             |              |                  |
             |              +------------------+
         meas_date      first_samp
             .
             .         |         +------+
             .         |_________| ANOT |
             .         |         |      |
             .         |         +------+
             .     orig_time   onset[0]
             .
             |                   +------+
             |___________________|      |
             |                   |      |
             |                   +------+
         orig_time            onset[0]'

        ----------- meas_date=XX, orig_time=None ---------------------------

             |              +------------------+
             |______________|     RAW          |
             |              |                  |
             |              +------------------+
             .              N         +------+
             .              o_________| ANOT |
             .              n         |      |
             .              e         +------+
             .
             |                        +------+
             |________________________|      |
             |                        |      |
             |                        +------+
         orig_time                 onset[0]'

        ----------- meas_date=None, orig_time=YY ---------------------------

             N              +------------------+
             o______________|     RAW          |
             n              |                  |
             e              +------------------+
                       |         +------+
                       |_________| ANOT |
                       |         |      |
                       |         +------+

                    [[[ CRASH ]]]

        ----------- meas_date=None, orig_time=None -------------------------

             N              +------------------+
             o______________|     RAW          |
             n              |                  |
             e              +------------------+
             .              N         +------+
             .              o_________| ANOT |
             .              n         |      |
             .              e         +------+
             .
             N                        +------+
             o________________________|      |
             n                        |      |
             e                        +------+
         orig_time                 onset[0]'

    .. warning::
       This means that when ``raw.info['meas_date'] is None``, doing
       ``raw.set_annotations(raw.annotations)`` will not alter ``raw`` if and
       only if ``raw.first_samp == 0``. When it's non-zero,
       ``raw.set_annotations`` will assume that the "new" annotations refer to
       the original data (with ``first_samp==0``), and will be re-referenced to
       the new time offset!

    **Specific annotation**

    ``BAD_ACQ_SKIP`` annotation leads to specific reading/writing file
    behaviours. See :meth:`mne.io.read_raw_fif` and
    :meth:`Raw.save() <mne.io.Raw.save>` notes for details.
    Nc                 C   s4   t |ƒ| _t||||ƒ\| _| _| _| _|  ¡  d S ©N)Ú_handle_meas_dateÚ
_orig_timerI   rC   rD   r.   r/   Ú_sort)ÚselfrC   rD   r.   Ú	orig_timer/   r0   r0   rH   Ú__init__ù   s    
ÿzAnnotations.__init__c                 C   s   | j S )z!The time base of the Annotations.)rP   ©rR   r0   r0   rH   rS      s    zAnnotations.orig_timec                 C   sZ   t |tƒsdS t | j|j¡oXt | j|j¡oXt | j|j¡oXt | j|j¡oX| j|jkS )z(Compare to another Annotations instance.F)	Ú
isinstancerM   r4   Zarray_equalrC   rD   r.   r/   rS   ©rR   Úotherr0   r0   rH   Ú__eq__  s    
ÿþý
üzAnnotations.__eq__c                 C   s„   t | jƒ}d dd„ t| ¡ ƒD ƒ¡}t|ƒdkr6dnd| }|  ¡ rJdnd}dt| jƒtt| jƒƒ||f }d	t	|d
dd� d S )zShow the representation.r2   c                 S   s   g | ]}d | ‘qS )z%s (%s)r0   )Ú.0Úkr0   r0   rH   Ú
<listcomp>  s     z(Annotations.__repr__.<locals>.<listcomp>r   ú: Ú z, channel-specificzAnnotations | %s segment%s%s%sú<éM   z ...)ÚwidthÚplaceholderú>)
r	   r.   ÚjoinÚsortedÚitemsr<   Ú_any_ch_namesrC   r   r   )rR   ÚcounterÚkindsZch_specificÚsr0   r0   rH   Ú__repr__  s    
ÿzAnnotations.__repr__c                 C   s
   t | jƒS )zˆReturn the number of annotations.

        Returns
        -------
        n_annot : int
            The number of annotations.
        )r<   rD   rU   r0   r0   rH   Ú__len__  s    zAnnotations.__len__c                 C   s   |   ¡ }||7 }|S )z*Add (concatencate) two Annotation objects.)Úcopy)rR   rX   rL   r0   r0   rH   Ú__add__#  s    zAnnotations.__add__c                 C   sL   t | ƒdkr|j| _| j|jkr4td| j|jf ƒ‚|  |j|j|j|j¡S )zsAdd (concatencate) two Annotation objects in-place.

        Both annotations must have the same orig_time
        r   zLorig_time should be the same to add/concatenate 2 annotations (got %s != %s))	r<   rS   rP   r9   ÚappendrC   rD   r.   r/   rW   r0   r0   rH   Ú__iadd__)  s    ÿþÿzAnnotations.__iadd__c                 c   s$   t t| jƒƒD ]}|  |¡V  qdS )zIterate over the annotations.N)Úranger<   rC   Ú__getitem__©rR   Úidxr0   r0   rH   Ú__iter__8  s    zAnnotations.__iter__c                 C   s¢   t |tƒr\d}| j| | j| | j| | jf}|  ¡ rN|d7 }|| j| f7 }tt	||ƒƒS t |t
ƒrnt|ƒn|}t| j| | j| | j| | j| j| d�S dS )zAPropagate indexing and slicing to the underlying numpy structure.©rC   rD   r.   rS   ©r/   ©rC   rD   r.   rS   r/   N)rV   r   rC   rD   r.   rS   rg   r/   r   Úzipr?   r@   rM   )rR   ÚkeyZout_keysZout_valsr0   r0   rH   rr   =  s"    
 ÿ
üzAnnotations.__getitem__c                 C   sb   t ||||ƒ\}}}}t | j|¡| _t | j|¡| _t | j|¡| _t | j|¡| _|  ¡  | S )az  Add an annotated segment. Operates inplace.

        Parameters
        ----------
        onset : float | array-like
            Annotation time onset from the beginning of the recording in
            seconds.
        duration : float | array-like
            Duration of the annotation in seconds.
        description : str | array-like
            Description for the annotation. To reject epochs, use description
            starting with keyword 'bad'.
        %(ch_names_annot)s

            .. versionadded:: 0.23

        Returns
        -------
        self : mne.Annotations
            The modified Annotations object.

        Notes
        -----
        The array-like support for arguments allows this to be used similarly
        to not only ``list.append``, but also
        `list.extend <https://docs.python.org/3/library/stdtypes.html#mutable-sequence-types>`__.
        )rI   r4   ro   rC   rD   r.   r/   rQ   )rR   rC   rD   r.   r/   r0   r0   rH   ro   O  s       ÿzAnnotations.appendc                 C   s   t | ƒS )z”Return a copy of the Annotations.

        Returns
        -------
        inst : instance of Annotations
            A copy of the object.
        r   rU   r0   r0   rH   rm   u  s    zAnnotations.copyc                 C   sD   t  | j|¡| _t  | j|¡| _t  | j|¡| _t  | j|¡| _dS )zæRemove an annotation. Operates inplace.

        Parameters
        ----------
        idx : int | array-like of int
            Index of the annotation to remove. Can be array-like to
            remove multiple indices.
        N)r4   ÚdeleterC   rD   r.   r/   rs   r0   r0   rH   r{     s    	zAnnotations.deletec                    sz   t dd�}t| jƒ‰ ˆ dkr$tdƒ‰ ˆ jdd�‰ ‡ fdd„| jD ƒ}t|| j| jd�}|  ¡ rl|j	| j
d	� | |¡}|S )
aB  Export annotations in tabular structure as a pandas DataFrame.

        Returns
        -------
        result : pandas.DataFrame
            Returns a pandas DataFrame with onset, duration, and
            description columns. A column named ch_names is added if any
            annotations are channel-specific.
        T©ÚstrictNr   ©Útzinfoc                    s   g | ]}ˆ t |d � ‘qS )©Úseconds)r   ©rZ   Úo©Údtr0   rH   r\   œ  s     z-Annotations.to_data_frame.<locals>.<listcomp>)rC   rD   r.   rw   )r   rO   rS   ÚreplacerC   ÚdictrD   r.   rg   Úupdater/   Ú	DataFrame)rR   ÚpdZ	onsets_dtÚdfr0   r„   rH   Úto_data_frame�  s    


ÿ
zAnnotations.to_data_framec                 C   s   t dd„ | jD ƒƒS )Nc                 s   s   | ]}t |ƒV  qd S rN   )r<   ©rZ   rE   r0   r0   rH   Ú	<genexpr>¥  s     z,Annotations._any_ch_names.<locals>.<genexpr>)Úanyr/   rU   r0   r0   rH   rg   ¤  s    zAnnotations._any_ch_namesc                 C   sª   t |d ƒ}| j}d}tƒ }t|ƒD ]n\}}t|ƒr$tƒ }	|D ]0}
|
|krd|snt|d|
› �ƒ d}q>|	 |
¡ q>t|	ƒ||< t|| ƒs$| |¡ q$t|ƒr¦|  |¡ | S )Nr/   Fz<At least one channel name in annotations missing from info: T)	Úsetr/   r@   rA   r<   r   ro   r?   r{   )rR   ÚinfoÚ
on_missingZkeepr/   ZwarnedZdrop_idxrF   rE   ÚnamesrG   r0   r0   rH   Ú_prune_ch_names§  s,     ÿ
zAnnotations._prune_ch_namesF)Ú	overwriter   c             	   C   sf   t |ddƒ t||d�}| d¡r.t|| ƒ n4| d¡rDt|| ƒ nt|ƒ�}t|| ƒ W 5 Q R X dS )aT  Save annotations to FIF, CSV or TXT.

        Typically annotations get saved in the FIF file for raw data
        (e.g., as ``raw.annotations``), but this offers the possibility
        to also save them to disk separately in different file formats
        which are easier to share between packages.

        Parameters
        ----------
        fname : str
            The filename to use.
        %(overwrite)s

            .. versionadded:: 0.23
        %(verbose)s

        Notes
        -----
        The format of the information stored in the saved annotation objects
        depends on the chosen file format. :file:`.csv` files store the onset
        as timestamps (e.g., ``2002-12-03 19:01:56.676071``),
        whereas :file:`.txt` files store onset as seconds since start of the
        recording (e.g., ``45.95597082905339``).
        Úannotations)z
-annot.fifz-annot.fif.gzz
_annot.fifz_annot.fif.gzú.txtú.csv)r•   r—   r˜   N)r   r   ÚendswithÚ_write_annotations_txtÚ_write_annotations_csvr%   Ú_write_annotations)rR   Úfnamer•   r   Úfidr0   r0   rH   ÚsaveÁ  s    


zAnnotations.savec                 C   sp   t t| j| jtt| ƒƒƒƒ}t|ƒr8ttt|Ž ƒd ƒng }| j| | _| j| | _| j| | _| j| | _dS )zSort in place.éÿÿÿÿN)	re   ry   rC   rD   rq   r<   r@   r.   r/   )rR   ÚvalsÚorderr0   r0   rH   rQ   ç  s     zAnnotations._sortTc                 C   s,  t | ƒdkr| S |r| jdkr(tdƒ}n| j}|dkrJt| j ¡ d�| }|dkrlt| j| j  ¡ d�| }d|fd|ffD ]\}}t|dt	f|dƒ q|t|ƒ}	t|ƒ}
~~|	|
krÄt
d|	|
f ƒ‚t d	|	|
f ¡ g g g g f\}}}}g g g   }}}tt| j| j| j| jƒƒD �]X\}\}}}}t |¡�r6d
}t|d�| }|t|d� }| ||
k�pf||	k ¡ |d �r®| d¡ | d¡ t d|› d|› d|› d|› d�	¡ n¾| ||	k ¡ |d �rÊ|	}| ||
k¡ |d �ræ|
}|d �sú|d �r| ||  ¡ ¡ n
| |¡ | ||  ¡ ¡ t d|› d|› d|› d|› d|| › d�¡ | |¡ | |¡ �qt dt |ƒ› d�¡ t |t¡| _t |t¡| _| jdk ¡ �s¶t‚tj|td�| _t|ƒ| _|�r(t |¡ ¡ }|dk�rútd| ƒ t |¡t |¡B  ¡ }|dk�r(td| ƒ | S )a¶  Remove all annotation that are outside of [tmin, tmax].

        The method operates inplace.

        Parameters
        ----------
        tmin : float | datetime | None
            Start time of selection in seconds.
        tmax : float | datetime | None
            End time of selection in seconds.
        emit_warning : bool
            Whether to emit warnings when limiting or omitting annotations.
            Defaults to False.
        use_orig_time : bool
            Whether to use orig_time as an offset.
            Defaults to True.
        %(verbose)s

        Returns
        -------
        self : instance of Annotations
            The cropped Annotations object.
        r   Nr€   ÚtminÚtmaxÚnumericznumeric, datetime, or Nonez7tmax should be greater than or equal to tmin (%s < %s).zCropping annotations %s - %sg        r    Fz  [z] Dropping (z - r]   ú)z] Keeping  (z -> zCropping complete (kept r+   z6Omitted %s annotation(s) that were outside data range.zDLimited %s annotation(s) that were expanding outside the data range.)r<   rS   rO   r   rC   ÚminrD   Úmaxr   Ú	_datetimer9   r   ÚdebugrA   ry   r.   r/   r4   Úisnanro   Útotal_secondsr6   r7   ÚallÚAssertionErrorr=   rB   Úsumr   )rR   r£   r¤   Zemit_warningZuse_orig_timer   Úoffsetrz   ÚvalZabsolute_tminZabsolute_tmaxÚonsetsÚ	durationsÚdescriptionsr/   Zout_of_boundsZclip_left_elemZclip_right_elemrt   rC   rD   r.   rE   Zabsolute_onsetZabsolute_offsetZomittedZlimitedr0   r0   rH   Úcropò  s°    
ÿÿÿÿÿ   ÿ
þ


ÿ


ÿ

ÿ&ÿ


ÿÿ
ÿzAnnotations.cropc                    s�   t |tttfƒ t|tƒrZt|| jddd� |D ]&‰ ‡ fdd„| jD ƒ}|ˆ  | j|< q0n2t|ƒrxt	 
| jj¡| | _ntdt|ƒ› d�ƒ‚| S )aV  Set annotation duration(s). Operates inplace.

        Parameters
        ----------
        mapping : dict | float
            A dictionary mapping the annotation description to a duration in
            seconds e.g. ``{'ShortStimulus' : 3, 'LongStimulus' : 12}``.
            Alternatively, if a number is provided, then all annotations
            durations are set to the single provided value.
        %(verbose)s

        Returns
        -------
        self : mne.Annotations
            The modified Annotations object.

        Notes
        -----
        .. versionadded:: 0.24.0
        ÚdataúAnnotation description(s)©Zvalid_key_sourceZkey_descriptionc                    s   g | ]}|ˆ k‘qS r0   r0   )rZ   Údesc©Zstimr0   rH   r\   |  s     z-Annotations.set_durations.<locals>.<listcomp>zbSetting durations requires the mapping of descriptions to times to be provided as a dict. Instead z was provided.)r   Úintr7   r‡   rV   r   r.   rD   r   r4   Zonesr:   r9   Útype)rR   Úmappingr   Zmap_idxr0   rº   rH   Úset_durations_  s    
þzAnnotations.set_durationsc                    sX   t |tƒ t|| jddd� | ¡ D ] \‰‰ ‡ ‡fdd„| jD ƒ| _q$t | j¡| _| S )a¾  Rename annotation description(s). Operates inplace.

        Parameters
        ----------
        mapping : dict
            A dictionary mapping the old description to a new description,
            e.g. {'1.0' : 'Control', '2.0' : 'Stimulus'}.
        %(verbose)s

        Returns
        -------
        self : mne.Annotations
            The modified Annotations object.

        Notes
        -----
        .. versionadded:: 0.24.0
        r¶   r·   r¸   c                    s   g | ]}|  ˆˆ ¡‘qS r0   ©r†   ©rZ   Úd©ÚnewÚoldr0   rH   r\   ¢  s     z&Annotations.rename.<locals>.<listcomp>)r   r‡   r   r.   rf   r4   r6   )rR   r½   r   r0   rÂ   rH   Úrename‰  s    

ÿzAnnotations.rename)NN)N)NNFTN)N)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rT   ÚpropertyrS   rY   rk   rl   rn   rp   ru   rr   r   ro   rm   r{   rŒ   rg   r”   r   rŸ   rQ   rµ   r¾   rÅ   r0   r0   r0   rH   rM   X   sB    !   ÿ




%
%    ÿl)rM   c                   @   sB   e Zd ZdZedd„ ƒZedddœdd„ƒZd	d
„ Zddd„Z	dS )ÚEpochAnnotationsMixinz&Mixin class for Annotations in Epochs.c                 C   s   | j S rN   )Ú_annotationsrU   r0   r0   rH   r–   «  s    z!EpochAnnotationsMixin.annotationsÚraiseN)r   c                C   sT   t |tdfdƒ |dkr d| _n0t| ddƒr4tdƒ | ¡ }| | j|¡ || _| S )a8  Setter for Epoch annotations from Raw.

        This method does not handle offsetting the times based
        on first_samp or measurement dates, since that is expected
        to occur in Raw.set_annotations().

        Parameters
        ----------
        annotations : instance of mne.Annotations | None
            Annotations to set.
        %(on_missing_ch_names)s
        %(verbose)s

        Returns
        -------
        self : instance of Epochs
            The epochs object with annotations.

        Notes
        -----
        Annotation onsets and offsets are stored as time in seconds (not as
        sample numbers).

        If you have an ``-epo.fif`` file saved to disk created before 1.0,
        annotations can be added correctly only if no decimation or
        resampling was performed. We thus suggest to regenerate your
        :class:`mne.Epochs` from raw and re-save to disk with 1.0+ if you
        want to safely work with :class:`~mne.Annotations` in epochs.

        Since this method does not handle offsetting the times based
        on first_samp or measurement dates, the recommended way to add
        Annotations is::

            raw.set_annotations(annotations)
            annotations = raw.annotations
            epochs.set_annotations(annotations)

        .. versionadded:: 1.0
        Nr–   Z_unsafe_annot_addFzÛAdding annotations to Epochs created (and saved to disk) before 1.0 will yield incorrect results if decimation or resampling was performed on the instance, we recommend regenerating the Epochs and re-saving them to disk)r   rM   rÌ   Úgetattrr   rm   r”   r‘   )rR   r–   r’   r   Znew_annotationsr0   r0   rH   Úset_annotations¯  s    *z%EpochAnnotationsMixin.set_annotationsc                 C   sj  dd„ t t| jƒƒD ƒ}| jdkr&|S | jdd…df | j }t |¡t | jddg ¡j \}}| j	j
}|| j	j }t t |¡t |¡jkt |¡t |¡jk ¡}t t |¡t |¡jkt |¡t |¡jk¡}t t |¡t |¡jkt |¡t |¡jk¡}	|| |	 }
tt |
¡Ž D ]D\}}| j	| }|| }|d | |d |d f}||  |¡ �q |S )	a<  Get a list of annotations that occur during each epoch.

        Returns
        -------
        epoch_annots : list
            A list of lists (with length equal to number of epochs) where each
            inner list contains any annotations that overlap the corresponding
            epoch. Annotations are stored as a :class:`tuple` of onset,
            duration, description (not as a :class:`~mne.Annotations` object),
            where the onset is now relative to time=0 of the epoch, rather than
            time=0 of the original continuous (raw) data.
        c                 S   s   g | ]}g ‘qS r0   r0   )rZ   Ú_r0   r0   rH   r\   ö  s     zCEpochAnnotationsMixin.get_annotations_per_epoch.<locals>.<listcomp>Nr   r    rC   rD   r.   )rq   r<   Úeventsr–   Z
_raw_sfreqr4   Z
atleast_2dÚtimesÚTrÌ   rC   rD   Úlogical_andry   Znonzeroro   )rR   Úepoch_annot_listZepoch_tzerosZepoch_startsZepoch_stopsZannot_startsZannot_stopsZannot_straddles_epoch_startZannot_straddles_epoch_endZannot_fully_within_epochZ	all_casesZannot_ixZepo_ixZ
this_annotZ
this_tzeroÚannotr0   r0   rH   Úget_annotations_per_epochè  sJ    
ÿÿþþþÿþ

þz/EpochAnnotationsMixin.get_annotations_per_epochFc                    s  t ƒ }| jdkr$td| › d�ƒ | S | jdk	r6| j‰n t t| jƒdf¡}|j|d�‰t	‡fdd„dD ƒƒrx|sxt
d	ƒ‚|  ¡ }g g g   }}}|D ]R}t|||fƒD ]>\‰ }	‡ fd
d„|D ƒ}
ˆ dk rÚtj|
dd� ¡ }
|	 |
¡ q¦q”| |¡ˆd< | |¡ˆd< | |¡ˆd< ˆ| _| S )aJ  Add raw annotations into the Epochs metadata data frame.

        Adds three columns to the ``metadata`` consisting of a list
        in each row:
        - ``annot_onset``: the onset of each Annotation within
        the Epoch relative to the start time of the Epoch (in seconds).
        - ``annot_duration``: the duration of each Annotation
        within the Epoch in seconds.
        - ``annot_description``: the free-form text description of each
        Annotation.

        Parameters
        ----------
        overwrite : bool
            Whether to overwrite existing columns in metadata or not.
            Default is False.

        Returns
        -------
        self : instance of Epochs
            The modified instance (instance is also modified inplace).

        Notes
        -----
        .. versionadded:: 1.0
        Nz$There were no Annotations stored in z, so metadata was not modified.r   )r¶   c                 3   s   | ]}|ˆ j kV  qd S rN   )Úcolumns)rZ   rG   )Úmetadatar0   rH   rŽ   U  s     zDEpochAnnotationsMixin.add_annotations_to_metadata.<locals>.<genexpr>)Úannot_onsetÚannot_durationÚannot_descriptionzeMetadata for Epochs already contains columns "annot_onset", "annot_duration", or "annot_description".c                    s   g | ]}|ˆ  ‘qS r0   r0   )rZ   rÖ   )Úixr0   rH   r\   b  s     zEEpochAnnotationsMixin.add_annotations_to_metadata.<locals>.<listcomp>é   é   )ZdecimalsrÚ   rÛ   rÜ   )r   r–   r   Ú	_metadatar4   rJ   r<   rÑ   r‰   r�   ÚRuntimeErrorr×   rA   ÚroundÚtolistro   ZSeriesrÙ   )rR   r•   rŠ   r¶   rÕ   rC   rD   r.   Zepoch_annotZ
annot_propÚentryr0   )rÝ   rÙ   rH   Úadd_annotations_to_metadata+  s:    

ÿþÿz1EpochAnnotationsMixin.add_annotations_to_metadata)rÍ   )F)
rÆ   rÇ   rÈ   rÉ   rÊ   r–   r   rÏ   r×   rå   r0   r0   r0   rH   rË   ¨  s   
ÿ8CrË   c                 C   s–   | dk	st ‚|dk	st ‚|| }||| 7 }||| 8 }t | j|j| g¡}t | j|jg¡}t | j|jg¡}	t | j|jg¡}
t|||	| j|
ƒS )zCombine a tuple of annotations.N)	r®   r4   ÚconcatenaterC   rD   r.   r/   rM   rS   )ÚoneÚtwoZone_n_samplesZone_first_sampZtwo_first_sampÚsfreqÚshiftrC   rD   r.   r/   r0   r0   rH   Ú_combine_annotationsu  s    rë   c                 C   s¬   t | tƒrHd}zt | |¡} W n tk
r6   d} Y qZX | jtjd�} nt | tƒrZt	| ƒ} | dk	r¨t
 | ¡r t
 t
 | ¡ddd… ¡} | ddg9 } t	t
 | ¡ƒ} t| ƒ | S )aX  Convert meas_date to datetime or None.

    If `meas_date` is a string, it should conform to the ISO8601 format.
    More precisely to this '%Y-%m-%d %H:%M:%S.%f' particular case of the
    ISO8601 format where the delimiter between date and time is ' '.
    Note that ISO8601 allows for ' ' or 'T' as delimiters between date and
    time.
    z%Y-%m-%d %H:%M:%S.%fNr~   r    r   g    €„.A)rV   r=   r   Ústrptimer9   r†   r   Úutcr?   r   r4   Zisscalarr6   Úmodfrâ   r   )Ú	meas_dateZACCEPTED_ISO8601r0   r0   rH   rO   „  s     	



rO   Fc                 C   s4   |rdnd| j  }| jd | jjks(t‚|| }|S )z&Adjust onsets in relation to raw data.r    r   rï   )Z_first_timer‘   r–   rS   r®   )ÚrawrC   Zinverser°   Zannot_startr0   r0   rH   Ú_sync_onset§  s    rñ   Úskip_by_annotationc                    sx  t ˆ tttf|ƒ tˆ tƒr$ˆ g‰ nˆ D ]}t |ddƒ q(t| jƒdkrdt g t	¡t g t	¡ }}n\‡ fdd„t
| jjƒD ƒ}| jj| }t| |ƒ}|| jj|  }| j|dd�}| j|dd�}||k ¡ sÐt‚|�rpt t| jƒt¡}t||ƒD ]\}	}
d||	|
…< qò| }||k}|| ||  }}t|ƒ\}}~t t ||g¡¡}t t ||g¡¡}||k ¡ �spt‚||fS )zOGet starts and stops from given kinds.

    onsets and ends are inclusive.
    r=   zAll entriesr   c                    s*   g | ]"\}‰ t ‡ fd d„ˆD ƒƒr|‘qS )c                 3   s    | ]}ˆ   ¡  |  ¡ ¡V  qd S rN   )ÚupperÚ
startswith)rZ   Úkind©r¹   r0   rH   rŽ   À  s   ÿz7_annotations_starts_stops.<locals>.<listcomp>.<genexpr>)r�   )rZ   rt   ©ri   rö   rH   r\   ¿  s
    ÿÿz-_annotations_starts_stops.<locals>.<listcomp>T)Úuse_rounding)r   r=   r@   r?   rV   r<   r–   r4   r6   r»   rA   r.   rC   rñ   rD   Útime_as_indexr­   r®   ÚzerosrÒ   Úboolry   r   Úsortræ   )rð   ri   rG   Úinvertrõ   r²   ZendsZidxsÚmaskrC   ÚendÚextrasZextra_onsetsZ
extra_endsr0   r÷   rH   Ú_annotations_starts_stops¯  s6    

r  r.   c                 C   s†   |dkr,t dd„ | D ƒƒr‚td|› d�ƒ‚nV|dkrHd dd	„ | D ƒ¡S |d
ksTt‚t| tƒsbt‚t| ƒsng S dd„ |  d¡D ƒS d S )Nr-   c                 S   s   g | ]}d |k‘qS )ú{COLON}r0   ©rZ   r±   r0   r0   rH   r\   ß  s     z#_prep_name_list.<locals>.<listcomp>zThe substring "{COLON}" in z not supported.Úwriteú:c                 s   s   | ]}|  d d¡V  qdS )r  r  Nr¿   r  r0   r0   rH   rŽ   ä  s     z"_prep_name_list.<locals>.<genexpr>Úreadc                 S   s   g | ]}|  d d¡‘qS )r  r  r¿   r  r0   r0   rH   r\   ë  s     )r�   r9   rd   r®   rV   r=   r<   Úsplit)ÚlstZ	operationrG   r0   r0   rH   r>   Ý  s    
ÿr>   c                 C   sž   t | tjƒ t| tj|jƒ t| tj|j|j ƒ t| tj	t
|jdƒ d¡ƒ |jdk	rlt| tjt|jƒƒ | ¡ rŽt| tjt t|jƒ¡ƒ t| tjƒ dS )zWrite annotations.r  r  N)r    r'   ÚFIFFB_MNE_ANNOTATIONSr"   ÚFIFF_MNE_BASELINE_MINrC   ÚFIFF_MNE_BASELINE_MAXrD   r#   ÚFIFF_COMMENTr>   r.   r  rS   r$   ÚFIFF_MEAS_DATEr   rg   r&   ÚFIFF_MNE_EPOCHS_DROP_LOGÚjsonÚdumpsr?   r/   r!   )rž   r–   r0   r0   rH   rœ   î  s(    
ÿ
 ÿÿ
ÿÿrœ   c                 C   s8   |  ¡ }d|kr&dd„ |d D ƒ|d< |j| dd� d S )Nr/   c                 S   s   g | ]}t |d ƒ‘qS ©r  ©r>   r�   r0   r0   rH   r\     s    z*_write_annotations_csv.<locals>.<listcomp>F)Úindex)rŒ   Zto_csv)r�   rÖ   r0   r0   rH   r›   ÿ  s    ÿ
r›   c              	   C   sð   d}|j d k	r(|d|j jd d�› d�7 }|d7 }|j|j|jg}| ¡ rf|d7 }| dd„ |jD ƒ¡ |d7 }tj	|t
d	�j}|jd
ksŒt‚|jd t|jƒks¤t‚|jd dks¶t‚t| dƒ�&}| | ¡ ¡ tj||ddd� W 5 Q R X d S )Nz# MNE-Annotations
z# orig_time : r~   Ú
z# onset, duration, descriptionz
, ch_namesc                 S   s   g | ]}t |d ƒ‘qS r  r  r�   r0   r0   rH   r\     s     z*_write_annotations_txt.<locals>.<listcomp>r+   rÞ   r   r   ©é   é   Úwbú,z%s)Ú	delimiterÚfmt)rS   r†   rC   rD   r.   rg   ro   r/   r4   r6   r=   rÓ   r8   r®   r:   r<   Úopenr  ÚencodeZsavetxt)r�   rÖ   Úcontentr¶   rž   r0   r0   rH   rš     s     
rš   Úautoc              	   C   s  ddl m} ddlm} ddlm} ddlm} ddlm	} ddl
m} t| dd	ƒ t| d
dt| ƒ d¡d	d�} t | ¡}	|	 d¡r´t| dd�\}
}}|
�}t||ƒ}W 5 Q R X �n>|	 d¡rìt| ƒ}t| ƒ\}}}}t|||||d�}�n|	 d¡�r|| |d�}nì|	 d¡�rt| ƒ}nÖ|	 d¡�r2|| ƒ}nÀ|	 d¡�rH|| ƒ}nª|	 d¡�rb|| |d�}n�|	 d¡�r||| |d�}nv|	 d¡�rÄ|| ƒ\}}}tj|td�}tj|td�}t|||dd�}n.|	 d¡�ræ|  d ¡�ræt| ƒ}ntd!|  ƒ‚|dk�rtd"|  ƒ‚|S )#a€  Read annotations from a file.

    This function reads a .fif, .fif.gz, .vmrk, .amrk, .edf, .txt, .csv, .cnt,
     .cef, or .set file and makes an :class:`mne.Annotations` object.

    Parameters
    ----------
    fname : str
        The filename.
    sfreq : float | 'auto'
        The sampling frequency in the file. This parameter is necessary for
        \*.vmrk, \*.amrk, and \*.cef files as Annotations are expressed in
        seconds and \*.vmrk/\*.amrk/\*.cef files are in samples. For any other
        file format, ``sfreq`` is omitted. If set to 'auto' then the ``sfreq``
        is taken from the respective info file of the same name with according
        file extension (\*.vhdr/\*.ahdr for brainvision; \*.dap for Curry 7;
        \*.cdt.dpa for Curry 8). So data.vmrk/amrk looks for sfreq in
        data.vhdr/ahdr, data.cef looks in data.dap and data.cdt.cef looks in
        data.cdt.dpa.
    uint16_codec : str | None
        This parameter is only used in EEGLAB (\*.set) and omitted otherwise.
        If your \*.set file contains non-ascii characters, sometimes reading
        it may fail and give rise to error message stating that "buffer is
        too small". ``uint16_codec`` allows to specify what codec (for example:
        'latin1' or 'utf-8') should be used when reading character arrays and
        can therefore help you solve this problem.

    Returns
    -------
    annot : instance of Annotations | None
        The annotations.

    Notes
    -----
    The annotations stored in a .csv require the onset columns to be
    timestamps. If you have onsets as floats (in seconds), you should use the
    .txt extension.
    r   )Ú_read_annotations_brainvision)Ú_read_annotations_eeglab)Ú_read_annotations_edf)Ú_read_annotations_cnt)Ú_read_annotations_curry)Ú_read_annotations_ctfz	path-liker�   r  Tz.ds)r•   Z
must_existÚneed_dirrG   )Úfifzfif.gzF)ZpreloadÚtxtrx   )ZvmrkZamrk)ré   ÚcsvZcntZdsZcefr�   )Úuint16_codec)ZedfZbdfZgdfr+   Nrv   Zevents_Zmatz#Unknown annotation file format "%s"z%No annotation data found in file "%s")Úio.brainvision.brainvisionr   Zio.eeglab.eeglabr!  Z
io.edf.edfr"  Z
io.cnt.cntr#  Zio.curry.curryr$  Zio.ctf.markersr%  r   r   r=   r™   ÚopÚbasenamer(   Ú_read_annotations_fifÚ"_read_annotations_txt_parse_headerÚ_read_annotations_txtrM   Ú_read_annotations_csvr4   r6   r7   rô   Ú_read_brainstorm_annotationsÚIOError)r�   ré   r*  r   r!  r"  r#  r$  r%  rG   ÚffÚtreerÐ   rž   r–   rS   rC   rD   r.   r/   r0   r0   rH   Úread_annotations  sn    '  ý


 þ



ÿþ

r6  c           	      C   s¼   t dd�}|j| dd�}|d jd }zt|ƒ tdƒ W n tk
rN   Y nX | |d ¡}||d  j ¡ }|d j 	t¡}|d	 j}d
}d|j
kr¬dd„ |d jD ƒ}t|||||ƒS )zºRead annotations from csv.

    Parameters
    ----------
    fname : str
        The filename.

    Returns
    -------
    annot : instance of Annotations
        The annotations.
    Tr|   F)Zkeep_default_narC   r   zÌIt looks like you have provided annotation onsets as floats. These will be interpreted as MILLISECONDS. If that is not what you want, save your CSV as a TXT file; the TXT reader accepts onsets in seconds.rD   r.   Nr/   c                 S   s   g | ]}t |d ƒ‘qS ©r  r  r  r0   r0   rH   r\   �  s   ÿz)_read_annotations_csv.<locals>.<listcomp>)r   Zread_csvÚvaluesr7   r   r9   Úto_datetimer…   r¬   ÚastyperØ   rM   )	r�   rŠ   r‹   rS   Zonset_dtrC   rD   r.   r/   r0   r0   rH   r1    s$    


ÿr1  c                 C   s®   ddl m} dd„ }| | ¡}tƒ tƒ tƒ   }}}|d d D ]P\}}	}	}	}
}	}	| |
d ¡ | ||
ƒ¡ t|
d ƒ}|t|d ƒg| 7 }q@tt 	|¡t 	|¡||d�S )aü  Read annotations from a Brainstorm events_ file.

    Parameters
    ----------
    fname : str
        The filename
    orig_time : float | int | instance of datetime | array of int | None
        A POSIX Timestamp, datetime or an array containing the timestamp as the
        first element and microseconds as the second element. Determines the
        starting time of annotation acquisition. If None (default),
        starting time is determined from beginning of raw data acquisition.
        In general, ``raw.info['meas_date']`` (or None) can be used for syncing
        the annotations with raw data if their acquisition is started at the
        same time.

    Returns
    -------
    annot : instance of Annotations | None
        The annotations.
    r   )Úioc                 S   s0   | j d dkr| d | d  S t t| d ƒ¡S )Nr   rÞ   r   )r:   r4   rú   r<   )Útr0   r0   rH   Úget_duration_from_times¹  s    z=_read_brainstorm_annotations.<locals>.get_duration_from_timesrÑ   rv   )
Zscipyr;  Zloadmatr@   ro   r<   r=   rM   r4   ræ   )r�   rS   r;  r=  Ú
annot_datar²   r³   r´   ÚlabelrÐ   rÒ   Zn_annotr0   r0   rH   r2  ¢  s    

ýr2  c                 C   s   d}t  |¡ | ¡d k	S )Nz/^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}\.\d{6}$)ÚreÚcompileÚmatch)Zcandidate_strZISO8601r0   r0   rH   Ú_is_iso8601Ê  s    rC  c              	      s^   dd„ ‰ t | ƒ�}ttdd„ |ƒƒ}W 5 Q R X ‡ fdd„|D ƒ}dd„ |D ƒ}|sVd S |d S )	Nc                 S   s
   |   d¡S )Nz# orig_time :©rô   ©Úxr0   r0   rH   Úis_orig_timeÐ  s    z8_read_annotations_txt_parse_header.<locals>.is_orig_timec                 S   s
   |   d¡S )Nú#rD  rE  r0   r0   rH   Ú<lambda>Ô  ó    z4_read_annotations_txt_parse_header.<locals>.<lambda>c                    s$   g | ]}ˆ |ƒr|d d…   ¡ ‘qS )é   N)Ústrip)rZ   Úh©rG  r0   rH   r\   Ö  s      z6_read_annotations_txt_parse_header.<locals>.<listcomp>c                 S   s   g | ]}t |ƒrt|ƒ‘qS r0   )rC  rO   )rZ   Úorigr0   r0   rH   r\   ×  s    ÿr   )r  r@   r   )r�   rž   ÚheaderZorig_valuesr0   rN  rH   r/  Ï  s    
r/  c              	   C   sê   t jdd��$ t  d¡ tj| dtjdd�}W 5 Q R X d }t|ƒdkrXg g g   }}}n4tdt|ƒdƒ t|ƒd	kr€|\}}}n|\}}}}d
d„ t |¡D ƒ}dd„ t |¡D ƒ}dd„ t |¡D ƒ}|d k	rÞdd„ |D ƒ}||||fS )NT)ÚrecordÚignorer  )r  r,   Úunpackr   ztext headerr  r  c                 S   s   g | ]}t | ¡ ƒ‘qS r0   ©r7   Údecoder‚   r0   r0   rH   r\   ì  s     z)_read_annotations_txt.<locals>.<listcomp>c                 S   s   g | ]}t | ¡ ƒ‘qS r0   rT  rÀ   r0   r0   rH   r\   í  s     c                 S   s   g | ]}t | ¡ ƒ ¡ ‘qS r0   )r=   rU  rL  rÀ   r0   r0   rH   r\   î  s     c                 S   s   g | ]}t | ¡  ¡ d ƒ‘qS r7  )r>   rU  rL  r�   r0   r0   rH   r\   ð  s   ÿ)	ÚwarningsÚcatch_warningsÚsimplefilterr4   ZloadtxtÚbytes_r<   r   r5   )r�   rL   r/   rC   rD   r¹   r0   r0   rH   r0  Ý  s*    
 ÿÿr0  c              	   C   sp  t |tjƒ}t|ƒdkr d}�nL|d }d }}tƒ tƒ tƒ   }}}|d D ]â}	|	j}
|	j}t| |ƒ}|
tjkrŒ|j	}|dkr†tƒ n|}qN|
tj
kr´|j	}|dkrªtƒ n|| }qN|
tjkrÌt|j	dƒ}qN|
tjk�r|j	}zt|ƒ}W n tk
�r   t|ƒ}Y nX qN|
tjkrNtdd„ t |j	¡D ƒƒ}qNt|ƒt|ƒ  k�rVt|ƒk�s\n t‚t|||||ƒ}|S )zRead annotations.r   NÚ	directoryr  c                 s   s   | ]}t |ƒV  qd S rN   )r?   )rZ   rF  r0   r0   rH   rŽ     s     z(_read_annotations_fif.<locals>.<genexpr>)r)   r'   r	  r<   r@   rõ   Úposr*   r
  r¶   r  r  r>   r  r7   Ú	TypeErrorr?   r  r  Úloadsr®   rM   )rž   r5  r>  r–   rS   r/   rC   rD   r.   Zentrõ   r[  Útagr0   r0   rH   r.  õ  s@    




* ÿr.  c                    sÊ   t  |dkrdn|¡}tƒ ‰ g }t| ƒD ]f}|ˆ kr6q(| |¡dkrFq(t|tƒrj||kr(|| ˆ |< qŽq(q(||ƒ}|dk	r„|ˆ |< q(| |¡ q(‡ fdd„t| ƒD ƒ}t|ƒdkrÂ|dk	rÂt	dƒ‚|ˆ fS )z?Get a collection of descriptions and returns index of selected.Nz.*c                    s   g | ]\}}|ˆ kr|‘qS r0   r0   )rZ   ÚiiÚkk©Z	event_id_r0   rH   r\   3  s    ÿz<_select_annotations_based_on_description.<locals>.<listcomp>r   ú/Could not find any of the events you specified.)
r@  rA  r‡   re   rB  rV   ro   rA   r<   r9   )r´   Úevent_idÚregexpZregexp_compZdroppedr¹   ÚtriggerÚ	event_selr0   ra  rH   Ú(_select_annotations_based_on_description  s(    

rg  c                    s”   t ƒ ‰ t|t ƒr|jn|}| tj| dd…df dd�d df }|D ]}||ƒ}|dk	rD|ˆ |< qD‡ fdd„t| ƒD ƒ}t|ƒdkrŒtd	ƒ‚|ˆ fS )
z9Get a collection of events and returns index of selected.NrÞ   T)Zreturn_indexr   c                    s    g | ]\}}|d  ˆ kr|‘qS ©rÞ   r0   )rZ   r_  Úe©Zevent_desc_r0   rH   r\   F  s      z._select_events_based_on_id.<locals>.<listcomp>r   rb  )r‡   rV   Úgetr4   ÚuniquerA   r<   r9   )rÑ   Ú
event_descÚfuncZ	event_idsri  re  rf  r0   rj  rH   Ú_select_events_based_on_id<  s    &
ro  c                 C   s¸   ddl m} ddl m} ddl m} ddlm}m} | d krBtƒ S | dkrŒt||ƒrZ|ƒ S t|||fƒr„||j	j
ƒr„t d¡ |ƒ S tƒ S n(t| ƒsžt| tƒr¢| S td t| ƒ¡ƒ‚d S )	Nr   )Ú_BVEventParser)Ú_check_bv_annot)ÚRawBrainVision)ÚRawFIFÚRawArrayr  z/Non-RawBrainVision raw using branvision markerszIInvalid type for event_id (should be None, str, dict or callable). Got {})r+  rp  rq  rr  r;  rs  rt  r   rV   r–   r.   r   r‘   Úcallabler‡   r9   Úformatr¼   )rc  rð   rp  rq  rr  rs  rt  r0   r0   rH   Ú_check_event_idN  s(    

ÿ
ÿrw  c                 C   s°   | dkr"t t |dd…df ¡ƒ} t| tƒrL|  ¡ D ]}t|tdfdƒ q4n`t| tƒr�t 	| ¡} | j
dkrztd | j¡ƒ‚tt| tt| ƒƒƒ} nt| ƒršntd t| ƒ¡ƒ‚| S )z-Check event_id and convert to default format.NrÞ   zEvent namesr   z#event_desc must be 1D, got shape {}zUInvalid type for event_desc (should be None, list, 1darray, dict or callable). Got {})r@   r4   rl  rV   r‡   r8  r   r=   r
   Zasarrayr8   r9   rv  r:   ry   Úmapru  r¼   )rm  rÑ   r±   r0   r0   rH   Ú_check_event_descriptionf  s$    



ÿþry  ú%^(?![Bb][Aa][Dd]|[Ee][Dd][Gg][Ee]).*$Tc                    sœ  t | jƒdkr4t|tƒstƒ n|}tjdtd�|fS | j}t|| ƒ}t|j	||d�\}‰ |dkrª| j
|j||jd�}|jdk	rˆ|| j7 }‡ fdd„|j	| D ƒ}	|| }n²t g ¡ t¡ }}	|| D ]”}
|
d	 |
d
  }tj|
d	 ||d�}|| |k}| ¡ rÆ|| }| j
|||jd�}|| j7 }t ||¡}tjt |ƒˆ |
d  td�}t |	|¡}	qÆtj|t t |ƒ¡|	f  t¡}t dtˆ  ¡ ƒf ¡ |ˆ fS )a'
  Get :term:`events` and ``event_id`` from an Annotations object.

    Parameters
    ----------
    raw : instance of Raw
        The raw data for which Annotations are defined.
    event_id : dict | callable | None | 'auto'
        Can be:

        - **dict**: map descriptions (keys) to integer event codes (values).
          Only the descriptions present will be mapped, others will be ignored.
        - **callable**: must take a string input and return an integer event
          code, or return ``None`` to ignore the event.
        - **None**: Map descriptions to unique integer values based on their
          ``sorted`` order.
        - **'auto' (default)**: prefer a raw-format-specific parser:

          - Brainvision: map stimulus events to their integer part; response
            events to integer part + 1000; optic events to integer part + 2000;
            'SyncStatus/Sync On' to 99998; 'New Segment/' to 99999;
            all others like ``None`` with an offset of 10000.
          - Other raw formats: Behaves like None.

          .. versionadded:: 0.18
    regexp : str | None
        Regular expression used to filter the annotations whose
        descriptions is a match. The default ignores descriptions beginning
        ``'bad'`` or ``'edge'`` (case-insensitive).

        .. versionchanged:: 0.18
           Default ignores bad and edge descriptions.
    use_rounding : bool
        If True, use rounding (instead of truncation) when converting
        times to indices. This can help avoid non-unique indices.
    chunk_duration : float | None
        Chunk duration in seconds. If ``chunk_duration`` is set to None
        (default), generated events correspond to the annotation onsets.
        If not, :func:`mne.events_from_annotations` returns as many events as
        they fit within the annotation duration spaced according to
        ``chunk_duration``. As a consequence annotations with duration shorter
        than ``chunk_duration`` will not contribute events.
    %(verbose)s

    Returns
    -------
    %(events)s
    event_id : dict
        The event_id variable that can be passed to :class:`~mne.Epochs`.

    See Also
    --------
    mne.annotations_from_events

    Notes
    -----
    For data formats that store integer events as strings (e.g., NeuroScan
    ``.cnt`` files), passing the Python built-in function :class:`int` as the
    ``event_id`` parameter will do what most users probably want in those
    circumstances: return an ``event_id`` dictionary that maps event ``'1'`` to
    integer event code ``1``, ``'2'`` to ``2``, etc.
    r   )r   r  r+   )rc  rd  N)rø   Úoriginc                    s   g | ]}ˆ | ‘qS r0   r0   )rZ   r`  ra  r0   rH   r\   Ð  s     z+events_from_annotations.<locals>.<listcomp>rC   rD   )ÚstartÚstopÚstepr.   )r:   Z
fill_valuer,   z!Used Annotations descriptions: %s)r<   r–   rV   r‡   r4   rJ   r»   rw  rg  r.   rù   rC   rS   Ú
first_sampr6   r:  Zaranger�   ro   ÚfullZc_rú   r   r‘   r@   Úkeys)rð   rc  rd  rø   Zchunk_durationr   r–   rf  Zindsr8  rÖ   Zannot_offsetZ_onsetsZgood_eventsZ_indsZ_valuesrÑ   r0   ra  rH   Úevents_from_annotations~  sV    B
  ÿ

ÿ


ÿþ


þ ÿr‚  c                    sl   t || ƒ}t| |ƒ\}‰ | | }|dd…df | | }‡ fdd„|D ƒ}	t t|ƒ¡}
t||
|	|d�}|S )uw  Convert an event array to an Annotations object.

    Parameters
    ----------
    events : ndarray, shape (n_events, 3)
        The events.
    sfreq : float
        Sampling frequency.
    event_desc : dict | array-like | callable | None
        Events description. Can be:

        - **dict**: map integer event codes (keys) to descriptions (values).
          Only the descriptions present will be mapped, others will be ignored.
        - **array-like**: list, or 1d array of integers event codes to include.
          Only the event codes present will be mapped, others will be ignored.
          Event codes will be passed as string descriptions.
        - **callable**: must take a integer event code as input and return a
          string description or None to ignore it.
        - **None**: Use integer event codes as descriptions.
    first_samp : int
        The first data sample (default=0). See :attr:`mne.io.Raw.first_samp`
        docstring.
    orig_time : float | str | datetime | tuple of int | None
        Determines the starting time of annotation acquisition. If None
        (default), starting time is determined from beginning of raw data
        acquisition. For details, see :meth:`mne.Annotations` docstring.
    %(verbose)s

    Returns
    -------
    annot : instance of Annotations
        The annotations.

    See Also
    --------
    mne.events_from_annotations

    Notes
    -----
    Annotations returned by this function will all have zero (null) duration.

    Creating events from annotations via the function
    `mne.events_from_annotations` takes in event mappings with
    keyâ†’value pairs as descriptionâ†’ID, whereas `mne.annotations_from_events`
    takes in event mappings with keyâ†’value pairs as IDâ†’description.
    If you need to use these together, you can invert the mapping by doing::

        event_desc = {v: k for k, v in event_id.items()}
    Nr   c                    s   g | ]}ˆ |d   ‘qS rh  r0   )rZ   ri  rj  r0   rH   r\   %  s     z+annotations_from_events.<locals>.<listcomp>rv   )ry  ro  r4   rú   r<   rM   )rÑ   ré   rm  r  rS   r   rf  Z
events_selr²   r´   r³   Zannotsr0   rj  rH   Úannotations_from_eventsí  s    4
ýrƒ  c                 C   s"   |j d dk	r|  j|j7  _dS )z4Adjust the annotation onsets based on raw meas_date.rï   N)r‘   rC   Z
first_time)rÖ   rð   r0   r0   rH   Ú_adjust_onset_meas_date1  s    r„  )F)rò   F)r.   )r  N)N)r  rz  TNN)Nr   NN)VÚcollectionsr   r   r   r   Úos.pathÚpathr,  r@  rm   r   Ú	itertoolsr   r  r	   Úcollections.abcr
   rV  Útextwrapr   Únumpyr4   Úutilsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Zio.writer    r!   r"   r#   r$   r%   r&   Zio.constantsr'   Zio.openr(   Zio.treer)   Zio.tagr*   r©   rI   rB   rK   rM   rË   rë   rO   rñ   r  r>   rœ   r›   rš   r6  r1  r2  rC  r/  r0  r.  rg  ro  rw  ry  r‚  rƒ  r„  r0   r0   r0   rH   Ú<module>   s|   T$)
    S N#
  ÿ
.

d#
(#$      ýn    ÿC