U
    f»{jS  ã                   @   s´   d dl 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mZ ddlmZ ddlmZ eddd„ƒZedd„ ddd	ddd
fdd„ƒZddd„ZG dd„ deƒZdS )é    Né   )ÚSourceEstimateÚVolSourceEstimate)Ú_ensure_src)Úrng_uniform)Úcheck_random_stateÚwarnÚ_check_optionÚfill_docÚ_ensure_intÚ_ensure_events)ÚLabel)Ú_compute_nearestÚrandomÚspherec                 C   s    t ƒ }t ƒ }td|ddgƒ t|ƒ}	|jdkr8|}
d}n|}
d}t | | d |j¡}|dkr||t|	ƒdt|ƒdƒd  }n|j	||||d�}|
 
|¡ ||fS )	a   Select source positions using a label.

    Parameters
    ----------
    src : list of dict
        The source space.
    label : Label
        The label.
    %(random_state)s
    location : str
        The label location to choose. Can be 'random' (default) or 'center'
        to use :func:`mne.Label.center_of_mass` (restricting to vertices
        both in the label and in the source space). Note that for 'center'
        mode the label values are used as weights.

        .. versionadded:: 0.13
    subject : str | None
        The subject the label is defined for.
        Only used with ``location='center'``.

        .. versionadded:: 0.13
    %(subjects_dir)s

        .. versionadded:: 0.13
    surf : str
        The surface to use for Euclidean distance center of mass
        finding. The default here is "sphere", which finds the center
        of mass on the spherical surface to help avoid potential issues
        with cortical folding.

        .. versionadded:: 0.13

    Returns
    -------
    lh_vertno : list
        Selected source coefficients on the left hemisphere.
    rh_vertno : list
        Selected source coefficients on the right hemisphere.
    Úlocationr   ÚcenterÚlhr   é   Úvertno)Zrestrict_verticesÚsubjects_dirÚsurf)Úlistr	   r   ÚhemiÚnpÚintersect1dÚverticesr   ÚlenZcenter_of_massÚappend)ÚsrcÚlabelÚrandom_stater   Úsubjectr   r   Ú	lh_vertnoÚ	rh_vertnoÚrngr   Zhemi_idxÚsrc_selÚidx© r(   úT/var/www/html/bwave/python/venv/lib/python3.8/site-packages/mne/simulation/source.pyÚselect_source_in_label   s(    *
  þ
r*   c                 C   s   dt  dt j |  ¡ S )NgH¯¼šò×z>é   )r   ÚsinÚpi)Útr(   r(   r)   Ú<lambda>X   ó    r/   c
              	      sÔ  t |ƒ‰ t| dd�} | j}
|dkr(|
}n |
dk	rH||
krHtd||
f ƒ‚t |t|ƒf¡}t|ƒD ]}||ƒ||dd…f< qb|dkrÊt d|t| ƒd ¡ 	t
¡}t |¡}‡ fdd„t|| ƒD ƒ}|}�n¬|t|ƒkrîtd	t|ƒ|f ƒ‚�nˆ|t|ƒk�rtd
t|t|ƒƒ ƒ |t|ƒk �r,|d|… n|}g g g}t d|jd f¡g}t d|jd f¡g}t|ƒD ]’\}}t| |ˆ ||||	ƒ\}}|d  |7  < |d  |7  < t|ƒdk�rÐ| || tj ¡ n,t|ƒdk�rô| || tj ¡ ntdƒ‚�qldd„ |D ƒ}dd„ ||fD ƒ}tdƒD ]B}t || ¡}|| | ||< t|ƒdk�r(|| | ||< �q(t |¡}|d t |dd… ¡d  }}|j|jk�s¨t‚t|ƒdk�rºtnt}||||||d�}|S )ao  Generate sparse (n_dipoles) sources time courses from data_fun.

    This function randomly selects ``n_dipoles`` vertices in the whole
    cortex or one single vertex (randomly in or in the center of) each
    label if ``labels is not None``. It uses ``data_fun`` to generate
    waveforms for each vertex.

    Parameters
    ----------
    src : instance of SourceSpaces
        The source space.
    n_dipoles : int
        Number of dipoles to simulate.
    times : array
        Time array.
    data_fun : callable
        Function to generate the waveforms. The default is a 100 nAm, 10 Hz
        sinusoid as ``1e-7 * np.sin(20 * pi * t)``. The function should take
        as input the array of time samples in seconds and return an array of
        the same length containing the time courses.
    labels : None | list of Label
        The labels. The default is None, otherwise its size must be n_dipoles.
    %(random_state)s
    location : str
        The label location to choose. Can be 'random' (default) or 'center'
        to use :func:`mne.Label.center_of_mass`. Note that for 'center'
        mode the label values are used as weights.

        .. versionadded:: 0.13
    subject : str | None
        The subject the label is defined for.
        Only used with ``location='center'``.

        .. versionadded:: 0.13
    %(subjects_dir)s

        .. versionadded:: 0.13
    surf : str
        The surface to use for Euclidean distance center of mass
        finding. The default here is "sphere", which finds the center
        of mass on the spherical surface to help avoid potential issues
        with cortical folding.

        .. versionadded:: 0.13

    Returns
    -------
    stc : SourceEstimate
        The generated source time courses.

    See Also
    --------
    simulate_raw
    simulate_evoked
    simulate_stc

    Notes
    -----
    .. versionadded:: 0.10.0
    F)ÚverboseNzHsubject argument (%s) did not match the source space subject_his_id (%s)r   r   c                    s:   g | ]2\}}|d  t  ˆ  t  |d ¡¡d|… ¡ ‘qS )r   ZnuseN)r   ÚsortZpermutationÚarange)Ú.0ÚnÚs©r%   r(   r)   Ú
<listcomp>¨   s   ÿz'simulate_sparse_stc.<locals>.<listcomp>zANumber of labels (%d) smaller than n_dipoles (%d) is not allowed.z]The number of labels is different from the number of dipoles. %s dipole(s) will be generated.zNo vertno found.c                 S   s   g | ]}t  |¡‘qS r(   ©r   Úarray©r4   Úvr(   r(   r)   r8   Ã   s     c                 S   s   g | ]}t  |¡‘qS r(   )r   Úconcatenate)r4   Údr(   r(   r)   r8   Ä   s     r   ©r   ÚtminÚtstepr"   )r   r   Ú_subjectÚ
ValueErrorr   Úzerosr   ÚrangeZlinspaceÚastypeÚintÚdiffÚzipr   ÚminÚemptyÚshapeÚ	enumerater*   r   ZnewaxisÚargsortr=   ÚAssertionErrorr   r   )r   Z	n_dipolesÚtimesZdata_funÚlabelsr!   r   r"   r   r   Zsubject_srcÚdataZi_dipÚoffsetsZn_dipoles_ssÚvsZdatasr   Zlh_dataZrh_dataÚir    r#   r$   ÚiiÚorderr@   rA   ÚclsÚstcr(   r7   r)   Úsimulate_sparse_stcV   sz    Aÿ

ÿ
ÿ
þ      ÿ
 rZ   Fc                    sÊ  t |ƒt |ƒkrtdƒ‚g g g}g g g}dddœ}	t|ƒD �]ª\}
}|	|j }t | | d |j¡}t |ƒdkrÄ| | d  d¡}| | d | }| | d |j }t||ƒ}| | d t 	|¡ }ˆ d	k	�rt 
|j|¡}t ‡ fd
d„|j| D ƒ¡}t |||
 ¡}nt ||
 t |ƒdf¡}|�rÄg }t|ƒD ]f\}}t ||| k¡d }t |ƒdk�r6t |ƒdk�stt‚|| |d   || 7  < | |¡ �q6tj||dd�}tt t |¡|¡ƒ}||  |¡ ||  t |¡¡ q:dd„ |D ƒ}|�sBt|dƒD ]:\}}t |ƒt t 	|¡ƒ }|dk�rtd||f ƒ‚�qtƒ }tdƒD ]Z}
t ||
 ƒdk�rPt ||
 ¡||
< t ||
 ¡}| ||
 | ¡ ||
 | ||
< �qPtt |¡|||| jd�}|S )a  Simulate sources time courses from waveforms and labels.

    This function generates a source estimate with extended sources by
    filling the labels with the waveforms given in stc_data.

    Parameters
    ----------
    src : instance of SourceSpaces
        The source space.
    labels : list of Label
        The labels.
    stc_data : array, shape (n_labels, n_times)
        The waveforms.
    tmin : float
        The beginning of the timeseries.
    tstep : float
        The time step (1 / sampling frequency).
    value_fun : callable | None
        Function to apply to the label values to obtain the waveform
        scaling for each vertex in the label. If None (default), uniform
        scaling is used.
    allow_overlap : bool
        Allow overlapping labels or not. Default value is False.

        .. versionadded:: 0.18

    Returns
    -------
    stc : SourceEstimate
        The generated source time courses.

    See Also
    --------
    simulate_raw
    simulate_evoked
    simulate_sparse_stc
    z-labels and stc_data must have the same lengthr   r   )r   Zrhr   ZinuseÚboolÚrrNc                    s   g | ]}ˆ |ƒ‘qS r(   r(   r;   ©Ú	value_funr(   r)   r8     s     z simulate_stc.<locals>.<listcomp>)Zaxisc                 S   s   g | ]}t  |¡‘qS r(   r9   r;   r(   r(   r)   r8   (  s     )ÚleftÚrightzILabels had %s overlaps in the %s hemisphere, they must be non-overlappingr   r?   )r   rC   rM   r   r   r   r   rF   r   ÚuniqueZsearchsortedr:   ÚvaluesÚouterZtileÚwhererO   r   Údeleter   ÚextendZ
atleast_2drI   ÚRuntimeErrorrE   ZvstackrN   r   r=   rB   )r   rQ   Ústc_datar@   rA   r^   Úallow_overlapr   Zstc_data_extendedZhemi_to_indrU   r    Zhemi_indr&   r'   Zxhsr\   Zclosest_srcZidx_selZ
values_selrR   Ú
duplicatesZsrc_indZ
vertex_indÚindr<   r   r>   rY   r(   r]   r)   Úsimulate_stcÔ   sn    '

ÿ

ÿ
þ
 ÿrl   c                   @   sb   e Zd ZdZddd„Zedd„ ƒZed	d
„ ƒZedd„ ƒZdd„ Z	ddd„Z
ddd„Zdd„ ZdS )ÚSourceSimulatora  Class to generate simulated Source Estimates.

    Parameters
    ----------
    src : instance of SourceSpaces
        Source space.
    tstep : float
        Time step between successive samples in data. Default is 0.001 sec.
    duration : float | None
        Time interval during which the simulation takes place in seconds.
        If None, it is computed using existing events and waveform lengths.
    first_samp : int
        First sample from which the simulation takes place, as an integer.
        Comparable to the :term:`first_samp` property of `~mne.io.Raw` objects.
        Default is 0.

    Attributes
    ----------
    duration : float
        The duration of the simulation in seconds.
    n_times : int
        The number of time samples of the simulation.
    çü©ñÒMbP?Nr   c                 C   sb   |d k	r||k rt dƒ‚t|dƒ| _|| _|| _g | _g | _tjdt	d�| _
|| _g | _d| _d S )Nz"duration must be None or >= tstep.Ú
first_samp)r   é   ©Údtypeiè  )rC   r   ro   Ú_srcÚ_tstepÚ_labelsÚ
_waveformsr   rK   rG   Ú_eventsÚ	_durationÚ_last_samplesÚ_chk_duration)Úselfr   rA   Údurationro   r(   r(   r)   Ú__init__X  s    zSourceSimulator.__init__c                 C   s   | j dk	r| j S | j| j S )z2Duration of the simulation in same units as tstep.N)rx   Ún_timesrt   ©r{   r(   r(   r)   r|   e  s    
zSourceSimulator.durationc                 C   sH   | j dk	rt| j | j ƒS | j}t| jƒdkr:t | j¡}|| j d S )z)Number of time samples in the simulation.Nr   r   )rx   rG   rt   ro   r   ry   r   Úmax)r{   Zlsr(   r(   r)   r~   l  s    
zSourceSimulator.n_timesc                 C   s   | j | j d S )Nr   )ro   r~   r   r(   r(   r)   Ú	last_sampv  s    zSourceSimulator.last_sampc                    s  t |tƒstdt|ƒ ƒ‚t |tƒs:t |¡dkr:t|ƒ}t |tƒsXt |¡dkrX|g}t|ƒdkrp|t|ƒ }t|ƒt|ƒkr˜tdt|ƒt|ƒf ƒ‚t|ƒ 	tj
¡}ˆ j |gt|ƒ ¡ ˆ j |¡ t ˆ j|g¡ˆ _ˆ jjtj
ksît‚t ‡ fdd„tˆ jƒD ƒ¡ˆ _dS )a  Add data to the simulation.

        Data should be added in the form of a triplet of
        Label (Where) - Waveform(s) (What) - Event(s) (When)

        Parameters
        ----------
        label : instance of Label
            The label (as created for example by mne.read_label). If the label
            does not match any sources in the SourceEstimate, a ValueError is
            raised.
        waveform : array, shape (n_times,) or (n_events, n_times) | list
            The waveform(s) describing the activity on the label vertices.
            If list, it must have the same length as events.
        events : array of int, shape (n_events, 3)
            Events associated to the waveform(s) to specify when the activity
            should occur.
        zlabel must be a Label,not %sr   r   z\Number of waveforms and events should match or there should be a single waveform (%d != %d).c                    s*   g | ]"\}}ˆ j |d f t|ƒ d ‘qS )r   r   )rw   r   )r4   rU   Úwr   r(   r)   r8   ¥  s   ÿz,SourceSimulator.add_data.<locals>.<listcomp>N)Ú
isinstancer   rC   Útyper   r   Úndimr   r   rF   Úint64ru   rf   rv   r=   rw   rr   rO   r:   rM   ry   )r{   r    ÚwaveformÚeventsr(   r   r)   Úadd_dataz  s,    
ÿþÿzSourceSimulator.add_datac                 C   sÀ   |dkr| j }|dkr&|| j d }n||k r6tdƒ‚|| d }tj|tjd�}t t | jdd…df |k| jdd…df |k ¡¡d }t	|ƒdkr¼| j|df | }| j|df ||< |S )aä  Get the stim channel from the provided data.

        Returns the stim channel data according to the simulation parameters
        which should be added through the add_data method. If both start_sample
        and stop_sample are not specified, the entire duration is used.

        Parameters
        ----------
        start_sample : int
            First sample in chunk. Default is the value of the ``first_samp``
            attribute.
        stop_sample : int | None
            The final sample of the returned stc. If None, then all samples
            from start_sample onward are returned.

        Returns
        -------
        stim_data : ndarray of int, shape (n_samples,)
            The stimulation channel data.
        Nr   z-Argument start_sample must be >= stop_sample.rq   r   r   )
ro   r~   rC   r   rD   r†   rd   Úlogical_andrw   r   )r{   Ústart_sampleÚstop_sampleÚ	n_samplesZ	stim_dataZstim_indZrelative_indr(   r(   r)   Úget_stim_channel¨  s$    þþz SourceSimulator.get_stim_channelc              	      sv  t ˆ jƒdkrtdƒ‚|dkr$ˆ j}|dkr<|ˆ j d }n||k rLtdƒ‚|| d }t t ˆ jƒ|f¡}t t ˆ j	|kˆ j
dd…df |k¡¡d }‡ fdd„|D ƒ}tt|ˆ j
| ƒƒD ]†\}\}}	|	d }
ˆ j	||  }t t |
|d ¡t ||d ¡¡}t t ||d ¡t |
|d ¡¡}|||  |  || 7  < qÀ|ˆ j8 }tˆ jˆ j||ˆ j ˆ jdd	�}|S )
a  Simulate a SourceEstimate from the provided data.

        Returns a SourceEstimate object constructed according to the simulation
        parameters which should be added through function add_data. If both
        start_sample and stop_sample are not specified, the entire duration is
        used.

        Parameters
        ----------
        start_sample : int | None
            First sample in chunk. If ``None`` the value of the ``first_samp``
            attribute is used. Defaults to ``None``.
        stop_sample : int | None
            The final sample of the returned STC. If ``None``, then all samples
            past ``start_sample`` are returned.

        Returns
        -------
        stc : SourceEstimate object
            The generated source time courses.
        r   z_No simulation parameters were found. Please use function add_data to add simulation parameters.Nr   z$start_sample must be >= stop_sample.c                    s   g | ]}ˆ j | ‘qS r(   )rv   )r4   rU   r   r(   r)   r8   ü  s     z+SourceSimulator.get_stc.<locals>.<listcomp>T)ri   )r   ru   rC   ro   r~   r   rD   rd   rŠ   ry   rw   rM   rI   Zin1dr3   rl   rs   rt   )r{   r‹   rŒ   r�   rh   rk   Zsubset_waveformsrU   r‡   ÚeventZwf_startZwf_stopZwaveform_indZstc_indrY   r(   r   r)   Úget_stcÓ  sF    ÿÿÿÿÿ
 þzSourceSimulator.get_stcc                 c   sR   | j }t| j|d | jƒD ]2}t|| j d |ƒ}|  ||¡|  ||¡fV  qdS )zIterate over 1 second STCs.r   N)r�   rE   ro   rz   rJ   r�   rŽ   )r{   Zlast_sampler‹   rŒ   r(   r(   r)   Ú__iter__  s    ÿÿ

ÿzSourceSimulator.__iter__)rn   Nr   )r   N)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r}   Úpropertyr|   r~   r�   r‰   rŽ   r�   r‘   r(   r(   r(   r)   rm   ?  s   


	
.
+
Crm   )Nr   NNr   )NF)Únumpyr   Zsource_estimater   r   Zsource_spacer   Úfixesr   Úutilsr   r   r	   r
   r   r   r    r   Zsurfacer   r*   rZ   rl   Úobjectrm   r(   r(   r(   r)   Ú<module>   s2          ÿ?    ý}  ÿ
k