
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "examples\stimuli\plot_sinusoidal.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_examples_stimuli_plot_sinusoidal.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_examples_stimuli_plot_sinusoidal.py:


===============================================================================
Generating a sinusoidal pulse train
===============================================================================

*This example shows how to build a sinusoidal pulse train from scratch.*

In addition to built-in stimuli such as
:py:class:`~pulse2percept.stimuli.BiphasicPulse` and
:py:class:`~pulse2percept.stimuli.BiphasicPulseTrain`, you can also create your
own :py:class:`~pulse2percept.stimuli.Stimulus` by manually specifying the
values for the ``data`` container and ``time`` axis.

Consider a sine wave:

.. GENERATED FROM PYTHON SOURCE LINES 17-31

.. code-block:: Python


    from pulse2percept.utils.constants import DT
    from pulse2percept.stimuli import Stimulus
    import numpy as np
    import matplotlib.pyplot as plt
    plt.style.use('ggplot')


    t = np.linspace(0, 2 * np.pi, 100)
    x = np.sin(t)
    plt.plot(t, x)
    plt.xlabel('Time (ms)')
    plt.ylabel('Amplitude')




.. image-sg:: /examples/stimuli/images/sphx_glr_plot_sinusoidal_001.png
   :alt: plot sinusoidal
   :srcset: /examples/stimuli/images/sphx_glr_plot_sinusoidal_001.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    Text(22.347222222222214, 0.5, 'Amplitude')



.. GENERATED FROM PYTHON SOURCE LINES 33-37

To turn this sine wave into a stimulus feasible for a retinal implant, it
will have to be discretized to a number of different amplitude levels.

The following code turns the sine wave into 5 different amplitude levels:

.. GENERATED FROM PYTHON SOURCE LINES 37-47

.. code-block:: Python


    levels = np.linspace(-1, 1, num=5)
    data = levels[np.argmin(np.abs(x[:, np.newaxis] - levels), axis=1)]

    plt.plot(t, data, label='discretized')
    plt.plot(t, x, label='original')
    plt.xlabel('Time (ms)')
    plt.ylabel('Amplitude')
    plt.legend()




.. image-sg:: /examples/stimuli/images/sphx_glr_plot_sinusoidal_002.png
   :alt: plot sinusoidal
   :srcset: /examples/stimuli/images/sphx_glr_plot_sinusoidal_002.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    <matplotlib.legend.Legend object at 0x00000251C62FB310>



.. GENERATED FROM PYTHON SOURCE LINES 48-50

We can turn this signal into a :py:class:`~pulse2percept.stimuli.Stimulus`
object as follows:

.. GENERATED FROM PYTHON SOURCE LINES 50-55

.. code-block:: Python



    stim = Stimulus(10 * data.reshape((1, -1)), time=t)
    stim.plot()




.. image-sg:: /examples/stimuli/images/sphx_glr_plot_sinusoidal_003.png
   :alt: plot sinusoidal
   :srcset: /examples/stimuli/images/sphx_glr_plot_sinusoidal_003.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    <Axes: ylabel='0'>



.. GENERATED FROM PYTHON SOURCE LINES 56-58

Alternatively, we can automate this process by creating a new class
``SinusoidalPulse`` that inherits from ``Stimulus``:

.. GENERATED FROM PYTHON SOURCE LINES 58-92

.. code-block:: Python



    class SinusoidalPulse(Stimulus):

        def __init__(self, amp, freq, phase, stim_dur, n_levels=5, dt=DT):
            """Sinusoidal pulse

            Parameters
            ----------
            amp : float
                Maximum stimulus amplitude (uA)
            freq : float
                Ordinary frequency of the sine wave (Hz)
            phase : float
                Phase of the sine wave (rad)
            stim_dur : float
                Stimulus duration (ms)
            n_levels : int, optional, default: 5
                Number of discretization levels
            dt : float, optional, default: 0.001
                Smallest time step (ms)
            """
            # Create the sine wave:
            t = np.arange(0, stim_dur + dt / 2, dt)
            x = np.sin(2 * np.pi * freq * t + phase)
            # Discretize it:
            levels = np.linspace(-1, 1, num=n_levels)
            data = levels[np.argmin(np.abs(x[:, np.newaxis] - levels), axis=1)]
            # Reshape data to 1xM so it is interpreted as M data points for a
            # single electrode:
            data = amp * data.reshape((1, -1))
            # Call the Stimulus constructor:
            super(SinusoidalPulse, self).__init__(data, time=t, compress=True)








.. GENERATED FROM PYTHON SOURCE LINES 93-94

Then we can create a new pulse as follows:

.. GENERATED FROM PYTHON SOURCE LINES 94-98

.. code-block:: Python



    sine = SinusoidalPulse(26, 0.25, -np.pi / 4, 20)
    sine.plot()



.. image-sg:: /examples/stimuli/images/sphx_glr_plot_sinusoidal_004.png
   :alt: plot sinusoidal
   :srcset: /examples/stimuli/images/sphx_glr_plot_sinusoidal_004.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    <Axes: ylabel='0'>




.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 0.707 seconds)


.. _sphx_glr_download_examples_stimuli_plot_sinusoidal.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: plot_sinusoidal.ipynb <plot_sinusoidal.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: plot_sinusoidal.py <plot_sinusoidal.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: plot_sinusoidal.zip <plot_sinusoidal.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
