| """ |
| domain/value_objects/signal_metadata.py |
| ββββββββββββββββββββββββββββββββββββββββ |
| SignalMetadata β immutable value object summarising the technical |
| characteristics of a PPG recording. |
| """ |
| from __future__ import annotations |
|
|
| from dataclasses import dataclass |
|
|
|
|
| @dataclass(frozen=True) |
| class SignalMetadata: |
| """ |
| Technical metadata for a PPG signal recording. |
| |
| Attributes: |
| sampling_rate: Number of samples per second (Hz). |
| duration_seconds: Length of the recording in seconds. |
| num_samples: Actual number of data points captured. |
| """ |
|
|
| sampling_rate: float |
| duration_seconds: float |
| num_samples: int |
|
|
| def __post_init__(self) -> None: |
| if self.sampling_rate <= 0: |
| raise ValueError("SignalMetadata.sampling_rate must be positive") |
| if self.duration_seconds <= 0: |
| raise ValueError("SignalMetadata.duration_seconds must be positive") |
| if self.num_samples <= 0: |
| raise ValueError("SignalMetadata.num_samples must be positive") |
|
|
| @property |
| def expected_samples(self) -> int: |
| """Expected sample count derived from duration Γ sampling_rate.""" |
| return int(self.duration_seconds * self.sampling_rate) |
|
|
| @property |
| def nyquist_frequency(self) -> float: |
| """Nyquist frequency = sampling_rate / 2 (Hz).""" |
| return self.sampling_rate / 2.0 |
|
|
| def __str__(self) -> str: |
| return ( |
| f"SignalMetadata(" |
| f"fs={self.sampling_rate} Hz, " |
| f"duration={self.duration_seconds}s, " |
| f"samples={self.num_samples})" |
| ) |
|
|