mth5.groups.fourier_coefficients
Fourier Coefficient group management for MTH5 format.
This module provides classes for organizing and managing Fourier Coefficient data at multiple decimation levels, including utilities for data import/export with different formats (numpy, xarray, pandas).
- copyright:
Jared Peacock (jpeacock@usgs.gov)
Classes
Master container for all Fourier Coefficient estimations of time series data. |
|
Container for a single decimation level of Fourier Coefficient data. |
|
Manage a set of Fourier Coefficients from a single processing run. |
Module Contents
- class mth5.groups.fourier_coefficients.MasterFCGroup(group: h5py.Group, **kwargs)[source]
Bases:
mth5.groups.BaseGroupMaster container for all Fourier Coefficient estimations of time series data.
This class manages multiple Fourier Coefficient processing runs, each containing different decimation levels. No metadata is required at the master level.
Hierarchy
MasterFCGroup -> FCGroup (processing runs) -> FCDecimationGroup (decimation levels) -> FCChannelDataset (individual channels)
- param group:
HDF5 group object for the master FC container.
- type group:
h5py.Group
- param **kwargs:
Additional keyword arguments passed to BaseGroup.
Examples
>>> import h5py >>> from mth5.groups.fourier_coefficients import MasterFCGroup >>> with h5py.File('data.h5', 'r') as f: ... master = MasterFCGroup(f['FC']) ... fc_group = master.add_fc_group('processing_run_1')
- property fc_summary: pandas.DataFrame[source]
Get a summary of all Fourier Coefficient processing runs.
- Returns:
Summary information for all FC groups including names and metadata.
- Return type:
pd.DataFrame
Examples
>>> master = MasterFCGroup(h5_group) >>> summary = master.fc_summary
- add_fc_group(fc_name: str, fc_metadata: mt_metadata.processing.fourier_coefficients.Decimation | None = None) FCGroup[source]
Add a Fourier Coefficient processing run group.
- Parameters:
fc_name (str) – Name for the FC group (usually identifies the processing run).
fc_metadata (fc.Decimation, optional) – Metadata for the FC group. Default is None.
- Returns:
Newly created Fourier Coefficient group.
- Return type:
Examples
>>> master = MasterFCGroup(h5_group) >>> fc_group = master.add_fc_group('processing_run_1') >>> print(fc_group.name) 'processing_run_1'
- get_fc_group(fc_name: str) FCGroup[source]
Retrieve a Fourier Coefficient group by name.
- Parameters:
fc_name (str) – Name of the FC group to retrieve.
- Returns:
The requested Fourier Coefficient group.
- Return type:
- Raises:
MTH5Error – If the FC group does not exist.
Examples
>>> master = MasterFCGroup(h5_group) >>> fc_group = master.get_fc_group('processing_run_1')
- remove_fc_group(fc_name: str) None[source]
Remove a Fourier Coefficient group.
Deletes the specified FC group and all associated decimation levels and channels.
- Parameters:
fc_name (str) – Name of the FC group to remove.
- Raises:
MTH5Error – If the FC group does not exist.
Examples
>>> master = MasterFCGroup(h5_group) >>> master.remove_fc_group('processing_run_1')
- class mth5.groups.fourier_coefficients.FCDecimationGroup(group: h5py.Group, decimation_level_metadata: mt_metadata.processing.fourier_coefficients.Decimation | None = None, **kwargs)[source]
Bases:
mth5.groups.BaseGroupContainer for a single decimation level of Fourier Coefficient data.
This class manages all channels at a specific decimation level, assuming uniform sampling in both frequency and time domains.
Data Assumptions
Data uniformly sampled in frequency domain
Data uniformly sampled in time domain
FFT moving window has uniform step size
- start_time
Start time of the decimation level
- Type:
datetime
- end_time
End time of the decimation level
- Type:
datetime
- channels
List of channel names in this decimation level
- Type:
list
- decimation_factor
Factor by which data was decimated
- Type:
int
- decimation_level
Level index in decimation hierarchy
- Type:
int
- sample_rate
Sample rate after decimation (Hz)
- Type:
float
- method
Method used (FFT, wavelet, etc.)
- Type:
str
- window
Window parameters (length, overlap, type, sample rate)
- Type:
dict
- param group:
HDF5 group object for this decimation level.
- type group:
h5py.Group
- param decimation_level_metadata:
Metadata for the decimation level. Default is None.
- type decimation_level_metadata:
optional
- param **kwargs:
Additional keyword arguments passed to BaseGroup.
Examples
>>> decimation = FCDecimationGroup(h5_group, decimation_level_metadata=metadata) >>> channel = decimation.add_channel('Ex', fc_data=fc_array)
- property channel_summary: pandas.DataFrame[source]
Get a summary of all channels in this decimation level.
Returns a pandas DataFrame with detailed information about each Fourier Coefficient channel including time ranges, dimensions, and sampling rates.
- Returns:
DataFrame with columns:
- componentstr
Channel component name (e.g., ‘Ex’, ‘Hy’)
- startdatetime64[ns]
Start time of the channel data
- enddatetime64[ns]
End time of the channel data
- n_frequencyint64
Number of frequency bins
- n_windowsint64
Number of time windows
- sample_rate_decimation_levelfloat64
Decimation level sample rate (Hz)
- sample_rate_window_stepfloat64
Sample rate of window stepping (Hz)
- unitsstr
Physical units of the data
- hdf5_referenceh5py.ref_dtype
HDF5 reference to the channel dataset
- Return type:
pd.DataFrame
Examples
>>> decimation = FCDecimationGroup(h5_group) >>> summary = decimation.channel_summary >>> print(summary[['component', 'n_frequency', 'n_windows']])
- from_dataframe(df: pandas.DataFrame, channel_key: str, time_key: str = 'time', frequency_key: str = 'frequency') None[source]
Load Fourier Coefficient data from a pandas DataFrame.
Assumes the channel_key column contains complex coefficient values organized with time and frequency dimensions.
- Parameters:
df (pd.DataFrame) – Input DataFrame containing the coefficient data.
channel_key (str) – Name of the column containing coefficient values.
time_key (str, default='time') – Name of the time coordinate column.
frequency_key (str, default='frequency') – Name of the frequency coordinate column.
- Raises:
TypeError – If df is not a pandas DataFrame.
Examples
>>> decimation = FCDecimationGroup(h5_group) >>> decimation.from_dataframe(df, channel_key='Ex', time_key='time')
- from_xarray(data_array: xarray.Dataset | xarray.DataArray, sample_rate_decimation_level: float) None[source]
Load Fourier Coefficient data from an xarray DataArray or Dataset.
Automatically extracts metadata (time, frequency, units) from the xarray object and creates appropriate FCChannelDataset instances for each variable or the single DataArray.
- Parameters:
data_array (xr.DataArray or xr.Dataset) – Input xarray object with ‘time’ and ‘frequency’ coordinates and dimensions [‘time’, ‘frequency’] (or transposed variant).
sample_rate_decimation_level (float) – Sample rate of the decimation level (Hz).
- Raises:
TypeError – If data_array is not an xarray Dataset or DataArray.
Notes
Automatically handles both (time, frequency) and (frequency, time) dimension ordering. Units are extracted from xarray attributes if available.
Examples
>>> import xarray as xr >>> import numpy as np >>> decimation = FCDecimationGroup(h5_group)
Create sample xarray data:
>>> times = np.arange('2023-01-01', '2023-01-02', dtype='datetime64[s]') >>> freqs = np.linspace(0.01, 100, 256) >>> data_array = np.random.randn(len(times), len(freqs)) + \ ... 1j * np.random.randn(len(times), len(freqs)) >>> xr_data = xr.DataArray( ... data_array, ... dims=['time', 'frequency'], ... coords={'time': times, 'frequency': freqs}, ... name='Ex' ... )
Load into decimation group:
>>> decimation.from_xarray(xr_data, sample_rate_decimation_level=0.5)
- to_xarray(channels: list[str] | None = None) xarray.Dataset[source]
Create an xarray Dataset from Fourier Coefficient channels.
If no channels are specified, all channels in the decimation level are included. Each channel becomes a data variable in the resulting Dataset.
- Parameters:
channels (list[str], optional) – List of channel names to include. If None, all channels are used. Default is None.
- Returns:
xarray Dataset with channels as data variables and ‘time’ and ‘frequency’ as shared coordinates.
- Return type:
xr.Dataset
Examples
>>> decimation = FCDecimationGroup(h5_group) >>> xr_data = decimation.to_xarray() >>> print(xr_data.data_vars) Data variables: Ex (time, frequency) complex128 Ey (time, frequency) complex128
Get specific channels:
>>> subset = decimation.to_xarray(channels=['Ex', 'Ey'])
- from_numpy_array(nd_array: numpy.ndarray, ch_name: str | list[str]) None[source]
Load Fourier Coefficient data from a numpy array.
Assumes array shape is either (n_frequencies, n_windows) for a single channel or (n_channels, n_frequencies, n_windows) for multiple channels.
- Parameters:
nd_array (np.ndarray) – Input numpy array containing coefficient data.
ch_name (str or list[str]) – Channel name (for 2D array) or list of channel names (for 3D array).
- Raises:
TypeError – If nd_array is not a numpy ndarray.
ValueError – If array shape is not (n_frequencies, n_windows) or (n_channels, n_frequencies, n_windows).
Examples
>>> decimation = FCDecimationGroup(h5_group)
Load single channel:
>>> data_2d = np.random.randn(256, 100) + 1j * np.random.randn(256, 100) >>> decimation.from_numpy_array(data_2d, ch_name='Ex')
Load multiple channels:
>>> data_3d = np.random.randn(2, 256, 100) + 1j * np.random.randn(2, 256, 100) >>> decimation.from_numpy_array(data_3d, ch_name=['Ex', 'Ey'])
- add_channel(fc_name: str, fc_data: numpy.ndarray | None = None, fc_metadata: mt_metadata.processing.fourier_coefficients.FCChannel | None = None, max_shape: tuple = (None, None), chunks: bool = True, dtype: type = complex, **kwargs) mth5.groups.FCChannelDataset[source]
Add a Fourier Coefficient channel to the decimation level.
Creates a new FCChannelDataset for a single channel at a single decimation level. Input data can be provided as numpy array or created empty.
- Parameters:
fc_name (str) – Name for the Fourier Coefficient channel (usually component name like ‘Ex’).
fc_data (np.ndarray, optional) – Input data with shape (n_frequencies, n_windows). Default is None (creates empty).
fc_metadata (fc.FCChannel, optional) – Metadata for the channel. Default is None.
max_shape (tuple, default=(None, None)) – Maximum shape for HDF5 dataset dimensions (expandable if None).
chunks (bool, default=True) – Whether to use HDF5 chunking.
dtype (type, default=complex) – Data type for the dataset.
**kwargs – Additional keyword arguments for HDF5 dataset creation.
- Returns:
Newly created FCChannelDataset object.
- Return type:
- Raises:
TypeError – If fc_data type is not supported.
Notes
Data layout assumes (time, frequency) organization:
time index: window start times
frequency index: harmonic indices or float values
data: complex Fourier coefficients
If a channel with the same name already exists, the existing channel is returned instead of creating a duplicate.
Examples
>>> decimation = FCDecimationGroup(h5_group) >>> metadata = fc.FCChannel(component='Ex')
Create from numpy array:
>>> fc_data = np.random.randn(100, 256) + 1j * np.random.randn(100, 256) >>> channel = decimation.add_channel('Ex', fc_data=fc_data, fc_metadata=metadata)
Create empty channel (expandable):
>>> channel = decimation.add_channel('Ex', fc_metadata=metadata)
- get_channel(fc_name: str) mth5.groups.FCChannelDataset[source]
Retrieve a Fourier Coefficient channel by name.
- Parameters:
fc_name (str) – Name of the Fourier Coefficient channel to retrieve.
- Returns:
The requested Fourier Coefficient channel dataset.
- Return type:
- Raises:
KeyError – If the channel does not exist in this decimation level.
MTH5Error – If unable to retrieve the channel from HDF5.
Examples
>>> decimation = FCDecimationGroup(h5_group) >>> channel = decimation.get_channel('Ex') >>> print(channel.shape) (100, 256)
- remove_channel(fc_name: str) None[source]
Remove a Fourier Coefficient channel from the decimation level.
Deletes the HDF5 dataset associated with the channel. Note that this removes the reference but does not reduce the HDF5 file size.
- Parameters:
fc_name (str) – Name of the Fourier Coefficient channel to remove.
- Raises:
MTH5Error – If the channel does not exist.
Notes
Deleting a channel does not reduce the HDF5 file size; it simply removes the reference to the data. To truly reduce file size, copy the desired data to a new file.
Examples
>>> decimation = FCDecimationGroup(h5_group) >>> decimation.remove_channel('Ex')
- update_metadata() None[source]
Update decimation level metadata from all channels.
Aggregates metadata from all FC channels in the decimation level including time period, sample rates, and window step information. Updates the internal metadata object and writes to HDF5.
Notes
Collects the following information from channels:
Time period start/end from channel data
Sample rate decimation level
Sample rate window step
Should be called after adding or modifying channels to keep metadata synchronized.
Examples
>>> decimation = FCDecimationGroup(h5_group) >>> decimation.add_channel('Ex', fc_data=data_ex) >>> decimation.add_channel('Ey', fc_data=data_ey) >>> decimation.update_metadata()
- add_feature(feature_name: str, feature_data: numpy.ndarray | None = None, feature_metadata: dict | None = None, max_shape: tuple = (None, None, None), chunks: bool = True, **kwargs) None[source]
Add a feature dataset to the decimation level.
Creates a new dataset for auxiliary features or derived quantities related to Fourier Coefficients (e.g., SNR, coherency, power, etc.).
- Parameters:
feature_name (str) – Name for the feature dataset.
feature_data (np.ndarray, optional) – Input data for the feature. Default is None (creates empty).
feature_metadata (dict, optional) – Metadata dictionary for the feature. Default is None.
max_shape (tuple, default=(None, None, None)) – Maximum shape for HDF5 dataset dimensions (expandable if None).
chunks (bool, default=True) – Whether to use HDF5 chunking.
**kwargs – Additional keyword arguments for HDF5 dataset creation.
Notes
Feature types may include:
Power: Total power in Fourier coefficients
SNR: Signal-to-noise ratio
Coherency: Cross-component coherence
Weights: Channel-specific weights
Flags: Data quality or processing flags
Examples
>>> decimation = FCDecimationGroup(h5_group) >>> snr_data = np.random.randn(100, 256) >>> decimation.add_feature('snr', feature_data=snr_data)
Or create empty feature for later population:
>>> decimation.add_feature('power_Ex')
- class mth5.groups.fourier_coefficients.FCGroup(group: h5py.Group, decimation_level_metadata: mt_metadata.processing.fourier_coefficients.Decimation | None = None, **kwargs)[source]
Bases:
mth5.groups.BaseGroupManage a set of Fourier Coefficients from a single processing run.
Holds Fourier Coefficient estimations organized by decimation level. Each decimation level contains channels (Ex, Ey, Hz, etc.) with complex frequency or time-frequency representations of the input signal.
All channels must use the same calibration. Recalibration requires rerunning the Fourier Coefficient estimation.
- hdf5_group
The HDF5 group containing decimation levels
- Type:
h5py.Group
- metadata[source]
Decimation metadata including time period, sample rates, and channels
- Type:
fc.Decimation
Notes
Processing run structure:
Multiple decimation levels at different sample rates
Each decimation level contains multiple channels
Each channel contains complex Fourier coefficients
Time period and sample rates define the estimation window
Examples
>>> with h5py.File('data.h5', 'r') as f: ... fc_run = FCGroup(f['Fourier_Coefficients/run_1']) ... print(fc_run.decimation_level_summary)
- metadata() mt_metadata.processing.fourier_coefficients.Decimation[source]
Get processing run metadata including all decimation levels.
Collects metadata from all decimation level groups and aggregates into a single Decimation metadata object.
- Returns:
Metadata containing time period, sample rates, and all decimation level information.
- Return type:
fc.Decimation
Notes
This getter automatically populates:
Time period (start and end)
List of all decimation levels and their metadata
HDF5 reference to this group
Examples
>>> fc_run = FCGroup(h5_group) >>> metadata = fc_run.metadata >>> print(metadata.time_period.start) 2023-01-01T00:00:00
- property decimation_level_summary: pandas.DataFrame[source]
Get a summary of all decimation levels in this processing run.
Returns information about each decimation level including sample rate, decimation level value, and time span.
- Returns:
Summary with columns:
decimation_level: Integer decimation level identifier
start: ISO format start time of this decimation level
end: ISO format end time of this decimation level
hdf5_reference: Reference to the HDF5 group
- Return type:
pd.DataFrame
Notes
Each row represents a single decimation level containing multiple channels with Fourier coefficients at different sample rates.
Examples
>>> fc_run = FCGroup(h5_group) >>> summary = fc_run.decimation_level_summary >>> print(summary[['decimation_level', 'start', 'end']]) decimation_level start end 0 0 2023-01-01T00:00:00.000000 2023-01-01T01:00:00.000000 1 1 2023-01-01T00:00:00.000000 2023-01-01T02:00:00.000000
- add_decimation_level(decimation_level_name: str, decimation_level_metadata: dict | mt_metadata.processing.fourier_coefficients.Decimation | None = None) FCDecimationGroup[source]
Add a new decimation level to the processing run.
Creates a new FCDecimationGroup for a single decimation level containing Fourier Coefficient channels at a specific sample rate.
- Parameters:
decimation_level_name (str) – Identifier for the decimation level.
decimation_level_metadata (dict | fc.Decimation, optional) – Metadata for the decimation level. Can be a dictionary or fc.Decimation object. Default is None.
- Returns:
Newly created decimation level group.
- Return type:
Examples
>>> fc_run = FCGroup(h5_group) >>> metadata = fc.Decimation(decimation_level=0) >>> decimation = fc_run.add_decimation_level('0', metadata)
- get_decimation_level(decimation_level_name: str) FCDecimationGroup[source]
Retrieve a decimation level by name.
- Parameters:
decimation_level_name (str) – Name or identifier of the decimation level.
- Returns:
The requested decimation level group.
- Return type:
Examples
>>> fc_run = FCGroup(h5_group) >>> decimation = fc_run.get_decimation_level('0') >>> channels = decimation.groups_list
- remove_decimation_level(decimation_level_name: str) None[source]
Remove a decimation level from the processing run.
Deletes the HDF5 group and all its channels (FCChannelDataset objects).
- Parameters:
decimation_level_name (str) – Name or identifier of the decimation level to remove.
Notes
This removes the entire decimation level and all channels within it. To remove individual channels, use FCDecimationGroup.remove_channel() instead.
Examples
>>> fc_run = FCGroup(h5_group) >>> fc_run.remove_decimation_level('0')
- update_metadata() None[source]
Update processing run metadata from all decimation levels.
Aggregates time period information from all decimation levels and writes updated metadata to HDF5.
Notes
Collects:
Earliest start time across all decimation levels
Latest end time across all decimation levels
Should be called after adding or removing decimation levels.
Examples
>>> fc_run = FCGroup(h5_group) >>> fc_run.add_decimation_level('0', metadata0) >>> fc_run.add_decimation_level('1', metadata1) >>> fc_run.update_metadata()
- supports_aurora_processing_config(processing_config: aurora.config.metadata.processing.Processing, remote: bool) bool[source]
Check if all required decimation levels exist for Aurora processing.
Performs an all-or-nothing check: returns True only if every decimation level required by the processing config is available in this FCGroup.
Uses sequential logic to short-circuit: if any required decimation level is missing, immediately returns False without checking remaining levels.
- Parameters:
processing_config (aurora.config.metadata.processing.Processing) – Aurora processing configuration containing required decimation levels.
remote (bool) – Whether to check for remote processing compatibility.
- Returns:
True if all required decimation levels are available and consistent, False otherwise.
- Return type:
bool
Notes
Validation logic:
Extract list of decimation levels from processing config
Iterate through each required level in sequence
For each level, find a matching FCDecimation in this group
Check consistency using Aurora’s validation method
If any level is missing or inconsistent, return False immediately
Return True only if all levels pass validation
Examples
>>> fc_run = FCGroup(h5_group) >>> config = aurora.config.metadata.processing.Processing(...) >>> if fc_run.supports_aurora_processing_config(config, remote=False): ... # All decimation levels are available ... pass