Stimulation signals
OSS-DBSv2 separates the stimulation waveform from the geometric and material model. This makes it possible to study how different pulse definitions affect the frequency-domain solve and the reconstructed time-domain results.
Signal concepts
The code distinguishes between:
time-domain signal definitions such as rectangular, trapezoidal, or triangular pulses
a frequency-domain representation used by the volume conductor solver
This separation is useful because the solver can evaluate the field at selected frequencies and then reconstruct the signal in time when needed.
Supported signal types
Time-domain pulse signals
These signals define a periodic waveform that is Fourier-transformed for the frequency-domain FEM solve and optionally reconstructed in the time domain afterwards.
Rectangle (
"Type": "Rectangle") — standard rectangular DBS pulse. The most common and best-tested signal type.Trapezoid (
"Type": "Trapezoid") — trapezoidal pulse with a finite rise time controlled byPulseTopWidth[us].Triangle (
"Type": "Triangle") — triangular pulse (trapezoid with zero top width).
Common parameters for all time-domain signals:
Frequency[Hz]— stimulation repetition rate (e.g. 130 Hz for standard DBS)PulseWidth[us]— duration of the primary pulse phaseCounterPulseWidth[us]— duration of the charge-balancing counter pulse (0 to omit)InterPulseWidth[us]— gap between primary and counter pulseCounterAmplitude— amplitude of the counter pulse relative to the primary pulse (default 1.0)
Multisine
The multisine mode ("Type": "Multisine") bypasses waveform generation
entirely. Instead, a list of discrete frequencies is solved with unit
amplitude at each:
"StimulationSignal": {
"Type": "Multisine",
"ListOfFrequencies": [130.0, 1000.0, 10000.0],
"CurrentControlled": false
}
This is useful for impedance spectroscopy, single-frequency studies, or when the frequency content is known in advance. No time-domain reconstruction is performed.
Frequency-domain settings
SpectrumMode
For time-domain signals, SpectrumMode controls how many frequencies are
actually solved:
"FullSpectrum"(default) — solves at every harmonic up to the cutoff frequency. Accurate but expensive for high cutoff frequencies."OctaveBand"— solves only at octave-band centre frequencies and interpolates. Much faster with minimal loss of accuracy for typical DBS pulses.
CutoffFrequency
CutoffFrequency (default: 1e6 Hz) sets the upper limit of the Fourier
spectrum. Harmonics above this frequency are discarded. For most DBS
applications, 0.5–1 MHz is sufficient. Lower values reduce the number of
FEM solves.
CurrentControlled
CurrentControlled selects between voltage-controlled and current-controlled
stimulation modes. See Stimulation modes in the volume conductor
documentation for a detailed description of all supported cases.
API reference
Signal classes
- class ossdbs.stimulation_signals.rectangle_signal.RectangleSignal(frequency: float, pulse_width: float, inter_pulse_width: float | None = 0.0, counter_pulse_width: float | None = 0.0, counter_pulse_amplitude: float | None = 1.0)[source]
Bases:
TimeDomainSignalRepresents a rectangular signal.
- Parameters:
frequency (float) – Frequency [Hz] of the signal.
pulse_width (float) – Relative pulse width of one period.
counter_pulse_width (float) – Relative width of counter pulse of one period.
inter_pulse_width (float) – Relative width between pulse and counter pulse of one period.
- class ossdbs.stimulation_signals.trapezoid_signal.TrapezoidSignal(frequency: float, pulse_width: float, inter_pulse_width: float, top_width: float, counter_pulse_width: float | None = None, counter_pulse_amplitude: float | None = 1.0)[source]
Bases:
TimeDomainSignalRepresents trapezoid signal.
- Parameters:
frequency (float) – Frequency [Hz] of the signal.
pulse_width (float) – Relative pulse width of one period.
top_width (float) – Relative top width of trapzoid signal.
counter_pulse_width (float) – Relative width of counter pulse of one period.
inter_pulse_width (float) – Relative width between pulse and counter pulse of one period.
- class ossdbs.stimulation_signals.triangle_signal.TriangleSignal(frequency: float, pulse_width: float, inter_pulse_width: float | None = 0.0, counter_pulse_width: float | None = 0.0, counter_pulse_amplitude: float | None = 1.0)[source]
Bases:
TimeDomainSignalRepresents a triangular signal.
- Parameters:
frequency (float) – Frequency [Hz] of the signal.
pulse_width (float) – Relative pulse width of one period.
counter_pulse_width (float) – Relative width of counter pulse of one period.
inter_pulse_width (float) – Relative width between pulse and counter pulse of one period.
Base classes
- class ossdbs.stimulation_signals.signal.FrequencyDomainSignal(frequencies: ndarray, amplitudes: ndarray, current_controlled: bool, base_frequency: float, cutoff_frequency: float, signal_length: int, octave_band_approximation: bool = False)[source]
Bases:
objectStore information for freqency domain signal.
- amplitudes: ndarray
- base_frequency: float
- current_controlled: bool
- cutoff_frequency: float
- frequencies: ndarray
- octave_band_approximation: bool = False
- signal_length: int
- class ossdbs.stimulation_signals.signal.TimeDomainSignal(frequency: float, pulse_width: float, inter_pulse_width: float | None = 0.0, counter_pulse_width: float | None = 0.0, counter_pulse_amplitude: float | None = 1.0)[source]
Bases:
ABCTemplate for Signals.
- Parameters:
frequency (float) – Frequency [Hz] of the signal.
pulse_width (float) – Relative pulse width of one period.
counter_pulse_width (float) – Relative width of counter pulse of one period.
inter_pulse_width (float) – Relative width between pulse and counter pulse of one period.
Notes
Amplitudes are relative: the primary pulse has amplitude 1.0 and the counter pulse amplitude is given as a fraction (e.g. 0.5 means half the primary amplitude). The actual voltage or current scaling is applied externally by the volume conductor model.
- property amplitude: float
Return signal amplitude.
- property counter_amplitude: float
Get amplitude of counterpulse.
- property frequency: float
Return frequency of signal.
- Return type:
float
- get_adjusted_cutoff_frequency(cutoff_frequency: float) float[source]
Adjust cutoff frequency to signal frequency.
Double the cutoff frequency to account for FFT and actually sample until there.
- get_fft_spectrum(cutoff_frequency: float) tuple[numpy.ndarray, numpy.ndarray, int][source]
FFT spectrum of time-domain signal.
- Parameters:
cutoff_frequency (float) – Highest considered frequency.
- abstract get_time_domain_signal(dt: float, timesteps: int) ndarray[source]
Time-domain signal for given timestep.
Helper functions
- ossdbs.stimulation_signals.utilities.adjust_cutoff_frequency(cutoff_frequency, frequency)[source]
Function to make cutoff frequency multiple of stimulation frequency.
- ossdbs.stimulation_signals.utilities.get_indices_in_octave_band(freq_idx: int, frequency_indices: list, cutoff_frequency_index: int) list | ndarray[source]
Get indices of frequencies in octave band.
Notes
We start evaluating from the bottom. I.e., it is checked if there is an overlap with frequencies from the octave band below (already computed). The minimum frequencies are increased until there is no overlap with the previous band.
- ossdbs.stimulation_signals.utilities.get_maximum_octave_band_index(freq_idx: int) int[source]
Get index of highest frequency in octave band.
- ossdbs.stimulation_signals.utilities.get_minimum_octave_band_index(freq_idx: int) int[source]
Get index of lowest frequency in octave band.
- ossdbs.stimulation_signals.utilities.get_octave_band_indices(frequencies: ndarray) ndarray[source]
Return indices of octave band frequencies.
- ossdbs.stimulation_signals.utilities.get_timesteps(cutoff_frequency: float, base_frequency: float, n_frequencies: int) ndarray[source]
Return list with timesteps.
- ossdbs.stimulation_signals.utilities.reconstruct_time_signals(freq_domain_signal: ndarray, signal_length: int) ndarray[source]
Compute time signals from frequency-domain data.
- Parameters:
freq_domain_signal (np.ndarray) – Frequency-domain signal to be transformed
signal_length (int) – Length of initial time-domain signal
- ossdbs.stimulation_signals.utilities.retrieve_time_domain_signal_from_fft(fft_signal: ndarray, cutoff_frequency: float, base_frequency: float, signal_length: int) tuple[numpy.ndarray, numpy.ndarray][source]
Compute time-domain signal via fft.
- Parameters:
fft_signal (np.ndarray) – Frequency-domain signal
signal_length (int) – Length of original time-domain signal
cutoff_frequency (float) – Highest considered frequency
base_frequency (float) – Frequency of time-domain signal (often 130 Hz)