suboptimumg.loganalysis.filtering#
FFT plotting and digital lowpass filtering utilities.
- suboptimumg.loganalysis.filtering.lowpass_filter(dfs, columns, cutoff_hz, time_col='time_s', order=4)[source]#
Apply a Butterworth lowpass filter to one or more columns.
On first call for a given column the current data is saved to
<col>_pre_lp. Subsequent calls always filter from<col>_pre_lpso that re-filtering at a different cutoff does not stack, while still preserving any upstream filtering (e.g.zscore_filter) that was applied before this function.A
<col>_originalbackup is also created on the very first filter call (zscore or lowpass) to allow full reset viaundo_filters().- Parameters:
dfs (DataFrame or list[DataFrame]) – Accepts a single DataFrame or a list; applies to all.
columns (str or list[str]) – Column name(s) to filter.
cutoff_hz (float) – Cutoff frequency in Hz.
time_col (str) – Time column to derive sampling frequency from.
order (int) – Butterworth filter order (applied forward-backward, so effective order is 2x).
- Returns:
Same type as *dfs, with filtered columns overwritten and*
_pre_lpbackups created on first filter.
- Return type:
DataFrame | list[DataFrame]
- suboptimumg.loganalysis.filtering.lowpass_filter_by_distance(dfs, columns, cutoff_freq_per_meter, distance_col='distance', order=4)[source]#
Apply a Butterworth lowpass in the spatial domain (1/m).
Same semantics as
lowpass_filter()but the sample rate is derived from a distance column instead of time.- Parameters:
dfs (DataFrame or list[DataFrame])
columns (str or list[str])
cutoff_freq_per_meter (float) – Cutoff in cycles per meter (1/m).
distance_col (str)
order (int)
- Return type:
Same type as dfs.
- suboptimumg.loganalysis.filtering.plot_fft(df, columns, domain='time', time_col='time_s', distance_col='distance', stacked=True, cutoff=None, log_x=True, log_y=False, xlim=None)[source]#
Plot FFT magnitude spectrum of one or more columns.
- Parameters:
df (pd.DataFrame)
columns (str or list[str])
domain (str) –
"time"or"distance".time_col (str)
distance_col (str)
stacked (bool) –
True-> one subplot per column;False-> all on one plot.cutoff (float or None) – If given, draw a vertical dashed line at this frequency.
log_x (bool) – Logarithmic x-axis.
log_y (bool) – Logarithmic y-axis.
xlim ((start, end) or None) – Restrict the FFT to a subdomain of the x-axis (time in seconds or distance in meters, depending on domain).
Noneuses the full range.
- Return type:
go.Figure
Note
No
max_display_hzdownsampling is applied here — the FFT output is already in the frequency domain and thinning would corrupt the spectrum shape.
- suboptimumg.loganalysis.filtering.undo_filters(df, columns)[source]#
Restore columns to their original (pre-filter) state.
Copies data back from
<col>_originaland removes all backup columns (_original,_pre_lp,_raw).- Parameters:
df (pd.DataFrame)
columns (str or list[str]) – Column name(s) to restore.
- Returns:
The same DataFrame, modified in-place and returned.
- Return type:
pd.DataFrame
- suboptimumg.loganalysis.filtering.zscore_filter(dfs, columns, window_s=2.0, threshold=4.8, time_col='time_s')[source]#
Mask outliers using a rolling-window z-score.
For each sample, a z-score is computed relative to the local rolling mean and standard deviation. Samples exceeding threshold are replaced with
NaNand linearly interpolated.Always re-filters from
<col>_original(the true intake data) so that re-running with different parameters does not stack. If a<col>_pre_lpbackup exists (lowpass was already applied), it is updated to the new zscore output so subsequent lowpass calls chain correctly.- Parameters:
dfs (DataFrame or list[DataFrame])
columns (str or list[str]) – Column name(s) to filter.
window_s (float) – Rolling window size in seconds.
threshold (float) – Z-score threshold – samples with
|z| > thresholdare masked.time_col (str) – Time column used to convert window_s to a sample count.
- Returns:
Same type as *dfs, with outliers masked to NaN and*
_originalbackups created on first call.
- Return type:
DataFrame | list[DataFrame]