Deferred out of #71 / #73. Nobody has asked for this — filed so it is on record as deliberately deferred rather than forgotten.
What is exposed today
database_options gives the user signal(s), freq_range, db_range, window_s, overlap, and per-PSD-entry label / color / line_dash.
What is fixed and invisible
| Parameter |
Current value |
| window function |
Hann |
| detrending |
per-window mean removal |
| scaling |
one-sided density, 1/(fs·Σw²) |
| averaging |
mean of periodograms |
nfft |
window length |
WINDOW_CYCLES |
5 (derives window_s from freq_min) |
JITTER_TOLERANCE |
0.05 |
GAP_FACTOR |
3.0 |
| gap policy |
mask as NaN |
| interpolation |
linear |
POWER_FLOOR |
1e-20 |
| axes |
dB only (no linear power, no log-frequency PSD x-axis) |
| colorscale |
Viridis |
Plus four hard refusals: decimated signal (period_resampling < 1), freq_max above Nyquist, freq_min <= 0, and a signal shorter than one window.
Why it was deferred
The original framing was "expose every parameter so a wrong default is the user's responsibility". That does not hold up: a parameter left blank is still the maintainer's choice, merely relocated from a constant to a default. In a clinician-facing tool almost everyone leaves advanced fields blank, so the rendered figure would be identical to today's — produced by defaults we picked — while each new knob becomes a new place the implementation can be wrong.
What actually addresses the concern is that the defaults now track scipy.signal.welch. After the scaling fix on new-plot-type-spectrogram, window, noverlap, nfft, average, return_onesided, scaling and detrend all match Welch's defaults, so there are zero unexplained divergences from the implementation any reviewer would compare against. A knob is only worth adding where someone wants to leave that reference point.
Trigger to pick this up
A user asks for a specific parameter. Then add that one, not the set.
detrend='linear' is the likeliest first request (slow drift in long EEG). Note it would re-open a Welch divergence, so it needs to be an opt-in key rather than a new default.
Constraint
spectral.py is pure numpy on purpose — no scipy — because of the PyInstaller bundle in build_info/. Any parameter added here must stay implementable without it, or the bundle-size tradeoff has to be reopened first.
Deferred out of #71 / #73. Nobody has asked for this — filed so it is on record as deliberately deferred rather than forgotten.
What is exposed today
database_optionsgives the usersignal(s),freq_range,db_range,window_s,overlap, and per-PSD-entrylabel/color/line_dash.What is fixed and invisible
1/(fs·Σw²)nfftWINDOW_CYCLESwindow_sfromfreq_min)JITTER_TOLERANCEGAP_FACTORPOWER_FLOORPlus four hard refusals: decimated signal (
period_resampling < 1),freq_maxabove Nyquist,freq_min <= 0, and a signal shorter than one window.Why it was deferred
The original framing was "expose every parameter so a wrong default is the user's responsibility". That does not hold up: a parameter left blank is still the maintainer's choice, merely relocated from a constant to a default. In a clinician-facing tool almost everyone leaves advanced fields blank, so the rendered figure would be identical to today's — produced by defaults we picked — while each new knob becomes a new place the implementation can be wrong.
What actually addresses the concern is that the defaults now track
scipy.signal.welch. After the scaling fix onnew-plot-type-spectrogram,window,noverlap,nfft,average,return_onesided,scalinganddetrendall match Welch's defaults, so there are zero unexplained divergences from the implementation any reviewer would compare against. A knob is only worth adding where someone wants to leave that reference point.Trigger to pick this up
A user asks for a specific parameter. Then add that one, not the set.
detrend='linear'is the likeliest first request (slow drift in long EEG). Note it would re-open a Welch divergence, so it needs to be an opt-in key rather than a new default.Constraint
spectral.pyis pure numpy on purpose — noscipy— because of the PyInstaller bundle inbuild_info/. Any parameter added here must stay implementable without it, or the bundle-size tradeoff has to be reopened first.