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
| Type | Description | Use Case |
|---|---|---|
| Continuous | Analog-style, time-based | Audio, sensor data |
| Discrete | Event-based, irregular timestamps | Packet data, transactions |
| Frame-based | Batches of samples | Video, 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
- Always specify units — Prevents calculation errors
- Check sample rates — Mismatched rates cause issues
- Use appropriate dtypes — float32 vs float64 tradeoffs
- Chunk large signals — Memory-efficient processing
See Also
Help us improve
Found an issue or have a suggestion?