Coverage for C: \ Users \ peaco \ OneDrive \ Documents \ GitHub \ mth5 \ mth5 \ processing \ spectre \ stft.py: 100%
24 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-10 00:01 -0800
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-10 00:01 -0800
1"""
2This module has methods for applying the short-time-Fourier-transform.
5"""
7from typing import Union
9import numpy as np
10import scipy.signal as ssig
11import xarray as xr
12from mt_metadata.processing.aurora.decimation_level import (
13 DecimationLevel as AuroraDecimationLevel,
14)
15from mt_metadata.processing.fourier_coefficients import Decimation as FCDecimation
17from mth5.timeseries.spectre.spectrogram import Spectrogram
19from .prewhitening import apply_prewhitening, apply_recoloring
22def run_ts_to_stft_scipy(
23 decimation_obj: Union[AuroraDecimationLevel, FCDecimation],
24 run_xrds_orig: xr.Dataset,
25) -> Spectrogram:
26 """
27 Converts a runts object into a time series of Fourier coefficients.
28 This method uses scipy.signal.spectrogram.
30 TODO: consider making this a method of RunTS; runts.to_spectrogram(decimation_obj)
32 Parameters
33 ----------
34 decimation_obj : Union[AuroraDecimationLevel, FCDecimation]
35 Information about how the decimation level is to be processed
36 run_xrds_orig : : xarray.core.dataset.Dataset
37 Time series to be processed
39 Returns
40 -------
41 stft_obj : xarray.core.dataset.Dataset
42 Time series of Fourier coefficients
43 """
44 run_xrds = apply_prewhitening(decimation_obj.stft.prewhitening_type, run_xrds_orig)
46 stft_obj = xr.Dataset()
47 for channel_id in run_xrds.data_vars:
48 ff, tt, specgm = ssig.spectrogram(
49 run_xrds[channel_id].data,
50 fs=decimation_obj.decimation.sample_rate,
51 window=decimation_obj.stft.window.taper(),
52 nperseg=decimation_obj.stft.window.num_samples,
53 noverlap=decimation_obj.stft.window.overlap,
54 detrend="linear",
55 scaling="density",
56 mode="complex",
57 )
59 # drop Nyquist
60 ff = ff[:-1]
61 specgm = specgm[:-1, :]
62 specgm *= np.sqrt(
63 2
64 ) # compensate energy for keeping only positive harmonics (keep PSDs accurate)
66 # make time_axis
67 tt = tt - tt[0]
68 tt *= decimation_obj.decimation.sample_rate
69 time_axis = run_xrds.time.data[tt.astype(int)]
71 xrd = xr.DataArray(
72 specgm.T,
73 dims=["time", "frequency"],
74 coords={"frequency": ff, "time": time_axis},
75 )
76 stft_obj.update({channel_id: xrd})
78 if decimation_obj.stft.recoloring:
79 stft_obj = apply_recoloring(decimation_obj.stft.prewhitening_type, stft_obj)
81 return Spectrogram(dataset=stft_obj)