--- source_files: - DataPRO/FftSharp.Test/PowerSpectralDensityShould.cs generated_at: "2026-04-16T03:50:52.298896+00:00" model: "Qwen/Qwen3-Coder-Next-FP8" schema_version: 1 sha256: "bdc792ce4fb3e148" --- # FftSharp.Test ## Documentation Page: `FftSharp.Test.PowerSpectralDensityShould` --- ### 1. **Purpose** This test class (`PowerSpectralDensityShould`) validates the correctness of the `FftSharp.Transform.PSD_Welch` method — specifically its implementation of the Welch method for power spectral density (PSD) estimation — by comparing its output against a precomputed reference dataset (`PSD.csv`). It ensures that the computed PSD matches expected frequency bins (`FFTfreq`) and power values within a defined numerical tolerance, using real-world test data (`Raw.csv` and `PSD.csv`). The class serves as a regression guard to prevent unintended changes to the PSD computation behavior. --- ### 2. **Public Interface** This is a **test fixture** (NUnit `[TestFixture]`) and does **not expose production APIs**. It contains only private helper methods and test methods. The *actual* production APIs under test are referenced but not defined here: - **`FftSharp.Transform.FFTfreq(int sampleRate, int n)`** *Inferred usage*: Generates the array of frequency bins (in Hz) for an FFT of length `n` at given `sampleRate`. Returns `double[]`. - **`FftSharp.Transform.PSD_Welch(double[] data, int sampleRate, WindowType windowType, int windowWidth, double overlappingPct, WindowAveragingType averagingType)`** *Inferred usage*: Computes the power spectral density of `data` using Welch’s method. Returns `double[]` of PSD values (in units of `g²/Hz`, per test assertions). - `data`: Input time-domain signal. - `sampleRate`: Sampling rate in Hz. - `windowType`: Window function type (e.g., `WindowType.Rectangular`). - `windowWidth`: Length of each segment (in samples). - `overlappingPct`: Overlap percentage between segments (0–100). - `averagingType`: Averaging strategy (e.g., `WindowAveragingType.Averaging`). > **Note**: The types `WindowType` and `WindowAveragingType` are referenced but not defined in this file; their definitions must be found in the `FftSharp` source. --- ### 3. **Invariants** - **Data lengths**: - `Raw.csv` must contain exactly **304,478** samples per column (`RawValueLength = 304478`). - `PSD.csv` must contain exactly **2,049** samples per column (`PSDValueLength = 2049`). - **Frequency bin count**: For a signal of length `N`, the PSD output length is `N/2 + 1` (i.e., `2049` for `windowWidth = 4096`), consistent with real-input FFT symmetry. - **Numerical tolerance**: Comparison uses a dynamic epsilon based on the magnitude of the expected value: `delta = 10^(floor(log10(val1[i])))`, adjusted by ±1 in exponent. Values < `1e-10` (both expected and actual) are ignored (noise floor). - **Test data format**: CSV files use comma separators, with two columns per file (no header), parsed as `double`. --- ### 4. **Dependencies** - **External libraries**: - `NUnit.Framework` (for `[TestFixture]`, `[Test]`, `Assert.Multiple`, etc.) - `System`, `System.IO`, `System.Linq`, `System.Collections.Generic` (standard .NET) - **Internal dependencies** (inferred from usage): - `FftSharp.Transform` namespace (contains `FFTfreq`, `PSD_Welch`) - `FftSharp.WindowType` enum (e.g., `Rectangular`) - `FftSharp.WindowAveragingType` enum (e.g., `Averaging`) - **Test data files**: - `Raw.csv`: Raw time-domain input (304,478 samples per channel). - `PSD.csv`: Reference PSD output (2,049 Hz and `g²/Hz` values). - Files are loaded relative to `TestContext.CurrentContext.TestDirectory`. --- ### 5. **Gotchas** - **Relative tolerance logic**: The `CloseEnough` method uses a *relative* tolerance scaled by the order of magnitude of the expected value, not a fixed epsilon. This may fail for values near zero or extremely small magnitudes (though those are skipped if both values < `1e-10`). - **Hardcoded lengths**: `RawValueLength` and `PSDValueLength` are constants. If test data files change size, tests will break silently unless updated. - **No validation of `PSD_Welch` parameters**: Tests assume valid inputs (e.g., `windowWidth ≤ data.Length`, `overlappingPct ∈ [0,100]`). No tests cover edge cases (e.g., zero overlap vs. 50% overlap, different window types). - **Assumed units**: The test compares against `g²/Hz`, implying the input data is in `g` (acceleration), but this is not enforced programmatically. - **File path separator**: Uses hardcoded `"\\"` — may fail on non-Windows systems unless `TestContext` resolves paths correctly. > **None identified from source alone** beyond the above — but the reliance on external test data and hardcoded constants is a maintenance concern.