Understanding Signals
Conceptsstable

Understanding Signals

Deep dive into signal types, sampling, and data representation in SimFusion

Understanding Signals

Signals are the fundamental data carriers in SimFusion. This guide covers signal types, properties, and best practices.

Signal Basics

A signal in SimFusion consists of:

  • Data: The actual values (NDArray)
  • Sample Rate: Samples per second (Hz)
  • Metadata: Units, timestamps, channel names

Creating a Signal

from simfusion import Signal
import numpy as np

# Create a 1kHz sine wave
t = np.linspace(0, 1, 1000)
data = np.sin(2 * np.pi * 10 * t)  # 10 Hz sine

signal = Signal(
    data=data,
    sample_rate=1000,
    unit="V",
    name="Voltage Signal"
)

Signal Types

Continuous vs Discrete

TypeDescriptionUse Case
ContinuousAnalog-style, time-basedAudio, sensor data
DiscreteEvent-based, irregular timestampsPacket data, transactions
Frame-basedBatches of samplesVideo, image sequences

Common Signal Patterns

Audio

Shape: (channels, samples)
Example: (2, 48000)  # Stereo, 1 second at 48kHz

Video

Shape: (frames, height, width, channels)
Example: (30, 1080, 1920, 3)  # 1 second at 30fps

Sensor Array

Shape: (sensors, timepoints)
Example: (64, 1000)  # 64 EEG channels, 1 second at 1kHz

Sampling Theory

Nyquist Rate

To avoid aliasing, sample at >2x the highest frequency:

Signal bandwidth: 0-20 kHz
Minimum sample rate: 40 kHz
Recommended: 44.1 kHz or 48 kHz

Resampling

Change sample rate while preserving information:

# Downsample from 48kHz to 16kHz
downsampled = signal.resample(target_rate=16000)

# Upsample with interpolation
upsampled = signal.resample(target_rate=96000, method='cubic')

Signal Operations

Arithmetic

Signals support vectorized operations:

# Element-wise operations
result = signal1 + signal2
result = signal1 * 2.5
result = Signal.concat([sig1, sig2], axis=0)

Windowing

Apply time windows for spectral analysis:

# Hanning window
windowed = signal.window('hanning', size=1024)

# Custom window
window = np.hamming(512)
windowed = signal.apply_window(window)

Metadata and Annotations

Adding Metadata

signal.set_metadata({
    "sensor_id": "TEMP_01",
    "location": "Room A",
    "calibration_date": "2024-01-15"
})

Time Stamps

For irregular sampling or event data:

timestamps = np.array([0.0, 0.1, 0.25, 0.3, 0.5])
event_signal = Signal(data=values, timestamps=timestamps)

Best Practices

  1. Always specify units — Prevents calculation errors
  2. Check sample rates — Mismatched rates cause issues
  3. Use appropriate dtypes — float32 vs float64 tradeoffs
  4. Chunk large signals — Memory-efficient processing

See Also

Help us improve

Found an issue or have a suggestion?