def test_PulseTrain(): # All zeros: npt.assert_almost_equal(PulseTrain(10, Stimulus(np.zeros((1, 5)))).data, 0) # Simple fake pulse: pulse = Stimulus([[0, -1, 0]], time=[0, 0.1, 0.2]) for n_pulses in [2, 3, 10]: pt = PulseTrain(10, pulse, n_pulses=n_pulses) npt.assert_equal(np.sum(np.isclose(pt.data, -1)), n_pulses) # stim_dur too short: npt.assert_almost_equal(PulseTrain(2, pulse, stim_dur=10).data, 0) # Invalid calls: with pytest.raises(TypeError): # Wrong stimulus type: PulseTrain(10, {'a': 1}) with pytest.raises(ValueError): # Pulse does not fit: PulseTrain(100000, pulse) with pytest.raises(ValueError): # n_pulses does not fit: PulseTrain(10, pulse, n_pulses=100000) with pytest.raises(ValueError): # No time component: PulseTrain(10, Stimulus(1)) with pytest.raises(ValueError): # Empty stim: pulse = Stimulus([[0, 0, 0]], time=[0, 0.1, 0.2], compress=True) PulseTrain(10, pulse)
def test_PulseTrain(): # All zeros: npt.assert_almost_equal(PulseTrain(10, Stimulus(np.zeros((1, 5)))).data, 0) # Simple fake pulse: pulse = Stimulus([[0, -1, 0]], time=[0, 0.1, 0.2]) for n_pulses in [2, 3, 10]: pt = PulseTrain(10, pulse, n_pulses=n_pulses, electrode='A4') npt.assert_equal(np.sum(np.isclose(pt.data, -1)), n_pulses) npt.assert_equal(pt.electrodes, 'A4') # PulseTrains can cut off/trim individual pulses if necessary: pt = PulseTrain(3, pulse, stim_dur=11) npt.assert_almost_equal(pt.time[-1], 11) npt.assert_almost_equal(pt[0, 11], 0) # Invalid calls: with pytest.raises(TypeError): # Wrong stimulus type: PulseTrain(10, {'a': 1}) with pytest.raises(ValueError): # Pulse does not fit: PulseTrain(100000, pulse) with pytest.raises(ValueError): # n_pulses does not fit: PulseTrain(10, pulse, n_pulses=100000) with pytest.raises(ValueError): # No time component: PulseTrain(10, Stimulus(1)) with pytest.raises(ValueError): # Empty stim: pulse = Stimulus([[0, 0, 0]], time=[0, 0.1, 0.2], compress=True) PulseTrain(10, pulse)
pt.plot() ############################################################################### # Generic pulse trains # -------------------- # # Finally, you can concatenate any :py:class:`~pulse2percept.stimuli.Stimulus` # object into a pulse train. # # For example, let's define a single ramp stimulus: import numpy as np from pulse2percept.stimuli import Stimulus, PulseTrain # Single ramp: dt = 1e-3 ramp = Stimulus([[0, 0, 1, 1, 2, 2, 0, 0]], time=[0, 1, 1 + dt, 2, 2 + dt, 3, 3 + dt, 5 - dt]) ramp.plot() # Ramp train: PulseTrain(20, ramp, stim_dur=200).plot() # Biphasic ramp: biphasic_ramp = Stimulus(np.concatenate((ramp.data, -ramp.data), axis=1), time=np.concatenate((ramp.time, ramp.time + 5))) biphasic_ramp.plot() # Biphasic ramp train: PulseTrain(20, biphasic_ramp, stim_dur=200).plot()
# ---------------------------------- # The easiest way to generate a pulse train is to use the # :py:class:`~pulse2percept.stimuli.PulseTrain` object, which allows for # various stimulus attributes to be specified: time_step = 0.1 / 1000 # temporal sampling in seconds freq = 20 # frequency in Hz amp = 100 # maximum amplitude of the pulse train in microAmps dur = 0.2 # total duration of the pulse train in seconds pulse_type = 'cathodicfirst' # whether the first phase is positive or negative pulse_order = 'gapfirst' # whether the train starts with gap or a pulse. # Define the pulse train with given parameters ptrain = PulseTrain(tsample=time_step, freq=freq, dur=dur, amp=amp, pulsetype=pulse_type, pulseorder=pulse_order) # Create a new stimulus where the pulse train is the source ptrain_stim = Stimulus(ptrain) # Visualize: fig, ax = plt.subplots(figsize=(8, 5)) ax.plot(ptrain_stim.time, ptrain_stim.data[0, :]) ax.set_xlabel('Time (s)') ax.set_ylabel('Amplitude ($\mu$A)') ############################################################################### # Alternatively, we are free to specify a discrete set of points in time and # the current amplitude we would like to apply at those times.