mth5.timeseries.channel_ts

Channel time series module for MT data.

This module provides the ChannelTS class for handling magnetotelluric (MT) time series data with comprehensive metadata management, calibration, and signal processing capabilities.

Notes

  • Time series are stored in xarray.DataArray for efficient operations.

  • Metadata follows the mt_metadata standard with Survey/Station/Run/Channel hierarchy.

  • Supports instrument response removal, resampling, merging, and Obspy integration.

Attributes

meta_classes

Classes

ChannelTS

Time series container for a single MT channel with full metadata.

Module Contents

mth5.timeseries.channel_ts.meta_classes[source]
class mth5.timeseries.channel_ts.ChannelTS(channel_type: str = 'auxiliary', data: numpy.ndarray | pandas.DataFrame | pandas.Series | xarray.DataArray | list | tuple | None = None, channel_metadata: mt_metadata.timeseries.Electric | mt_metadata.timeseries.Magnetic | mt_metadata.timeseries.Auxiliary | dict | None = None, station_metadata: mt_metadata.timeseries.Station | dict | None = None, run_metadata: mt_metadata.timeseries.Run | dict | None = None, survey_metadata: mt_metadata.timeseries.Survey | dict | None = None, **kwargs: Any)[source]

Time series container for a single MT channel with full metadata.

Stores equally-spaced time series data in an xarray.DataArray with a time coordinate index. Integrates comprehensive metadata from Survey/Station/Run/Channel hierarchy and supports calibration, resampling, merging, and format conversions.

Parameters:
  • channel_type ({'electric', 'magnetic', 'auxiliary'}, default 'auxiliary') – Type of the channel.

  • data (array-like, optional) – Time series data (numpy array, pandas DataFrame/Series, xarray.DataArray).

  • channel_metadata (mt_metadata.timeseries.Electric | Magnetic | Auxiliary | dict, optional) – Channel-specific metadata.

  • station_metadata (mt_metadata.timeseries.Station | dict, optional) – Station metadata.

  • run_metadata (mt_metadata.timeseries.Run | dict, optional) – Run metadata.

  • survey_metadata (mt_metadata.timeseries.Survey | dict, optional) – Survey metadata.

  • **kwargs – Additional attributes to set on the object.

ts[source]

The time series data array.

Type:

numpy.ndarray

sample_rate[source]

Sample rate in samples per second.

Type:

float

start[source]

Start time (UTC).

Type:

MTime

end[source]

End time (UTC), derived from start + duration.

Type:

MTime

n_samples[source]

Number of samples.

Type:

int

component[source]

Component name (e.g., ‘ex’, ‘hy’, ‘temperature’).

Type:

str

channel_response[source]

Full instrument response filter chain.

Type:

ChannelResponse

Notes

  • End time is a derived property and cannot be set directly.

  • Leverages xarray for efficient interpolation, resampling, and groupby operations.

  • Metadata follows mt_metadata standards with automatic time period updates.

Examples

Create an auxiliary channel with synthetic data:

>>> from mth5.timeseries import ChannelTS
>>> import numpy as np
>>> ts_obj = ChannelTS('auxiliary')
>>> ts_obj.sample_rate = 8
>>> ts_obj.start = '2020-01-01T12:00:00+00:00'
>>> ts_obj.ts = np.random.randn(4096)
>>> ts_obj.station_metadata.id = 'MT001'
>>> ts_obj.run_metadata.id = 'MT001a'
>>> ts_obj.component = 'temperature'
>>> print(ts_obj)

Calibrate and remove instrument response:

>>> calibrated = ts_obj.remove_instrument_response()
>>> calibrated.channel_metadata.units
logger[source]
data_array[source]
property survey_metadata: mt_metadata.timeseries.Survey[source]

Survey metadata.

Returns:

Survey metadata with updated keys.

Return type:

mt_metadata.timeseries.Survey

property station_metadata: mt_metadata.timeseries.Station[source]

Station metadata.

Returns:

Station metadata from the first station in the survey.

Return type:

mt_metadata.timeseries.Station

property run_metadata: mt_metadata.timeseries.Run[source]

Run metadata.

Returns:

Run metadata from the first run in the station.

Return type:

mt_metadata.timeseries.Run

property channel_metadata: mt_metadata.timeseries.Electric | mt_metadata.timeseries.Magnetic | mt_metadata.timeseries.Auxiliary[source]

Channel metadata.

Returns:

Channel metadata from the first channel in the run.

Return type:

mt_metadata.timeseries.Electric | Magnetic | Auxiliary

get_sample_rate_supplied_at_init(channel_metadata: mt_metadata.timeseries.Electric | mt_metadata.timeseries.Magnetic | mt_metadata.timeseries.Auxiliary | dict | None) float | None[source]

Extract sample_rate from channel_metadata if available.

Parameters:

channel_metadata (mt_metadata.timeseries.Electric | Magnetic | Auxiliary | dict | None) – Metadata that may contain a sample_rate field.

Returns:

Sample rate if found, otherwise None.

Return type:

float | None

Notes

Supports nested dict structures like {"electric": {"sample_rate": 8.0}}.

copy(data: bool = True) ChannelTS[source]

Create a copy of the ChannelTS object.

Parameters:

data (bool, default True) – Include data in the copy (True) or only metadata (False).

Returns:

Copy of the channel.

Return type:

ChannelTS

Examples

Copy metadata structure without data:

>>> ch_copy = ts_obj.copy(data=False)
property ts: numpy.ndarray[source]

Time series data as a numpy array.

Returns:

The time series data.

Return type:

numpy.ndarray

property time_index: numpy.ndarray[source]

Time index as a numpy array.

Returns:

Array of datetime64[ns] timestamps.

Return type:

numpy.ndarray

property channel_type: str[source]

Channel type.

Returns:

Channel type: ‘Electric’, ‘Magnetic’, or ‘Auxiliary’.

Return type:

str

property component[source]

component

property n_samples[source]

number of samples

has_data()[source]

check to see if there is an index in the time series

is_high_frequency(threshold_dt=0.0001)[source]

Quasi hard-coded condition to check if data are logged at more than 10kHz can be parameterized in future

compute_sample_rate()[source]

Two cases, high_frequency (HF) data and not HF data.

# Original comment about the HF case: Taking the median(diff(timestamps)) is more accurate for high sample rates, the way pandas.date_range rounds nanoseconds is not consistent between samples, therefore taking the median provides better results if the time series is long this can be inefficient so test first

property sample_rate[source]

sample rate in samples/second

property sample_interval[source]

Sample interval = 1 / sample_rate

Returns:

sample interval as time distance between time samples

Return type:

float

property start[source]

MTime object

property end[source]

MTime object

property channel_response[source]

Full channel response filter

Returns:

full channel response filter

Return type:

mt_metadata.timeseries.filters.ChannelResponse

get_calibration_operation()[source]
get_calibrated_units()[source]

Follows the FDSN standard which has the filter stages starting with physical units to digital counts.

The channel_response is expected to have a list of filter “stages” of which the first stage has input units corresponding to the the physical quantity that the instrument measures, and the last is normally counts.

channel_response can be viewed as the chaining together of all of these filters.

Thus it is normal for channel_response.units_out will be in the same units as the archived raw time series, and for the units after the response is corrected for will be the units_in of

The units of the channel metadata are compared to the input and output units of the channel_response.

Returns:

tuple, calibration_operation, either “mulitply” or divide”, and a string for calibrated units

Return type:

tuple (of two strings_

remove_instrument_response(include_decimation=False, include_delay=False, **kwargs)[source]

Remove instrument response from the given channel response filter

The order of operations is important (if applied):

  1. detrend

  2. zero mean

  3. zero pad

  4. time window

  5. frequency window

  6. remove response

  7. undo time window

  8. bandpass

Parameters:
  • include_decimation (bool, optional) – Include decimation in response, defaults to True

  • include_delay (bool, optional) – include delay in complex response, defaults to False

kwargs

Parameters:
  • plot (boolean, default True) – to plot the calibration process [ False | True ]

  • detrend (boolean, default True) – Remove linar trend of the time series

  • zero_mean (boolean, default True) – Remove the mean of the time series

  • zero_pad (boolean, default True) – pad the time series to the next power of 2 for efficiency

  • t_window (string, default None) – Time domain windown name see scipy.signal.windows for options

  • t_window_params – Time domain window parameters, parameters can be

found in scipy.signal.windows :type t_window_params: dictionary :param f_window: Frequency domain windown name see scipy.signal.windows for options :type f_window: string, defualt None :param f_window_params: Frequency window parameters, parameters can be found in scipy.signal.windows :type f_window_params: dictionary :param bandpass: bandpass freequency and order {“low”:, “high”:, “order”:,} :type bandpass: dictionary

get_slice(start, end=None, n_samples=None)[source]

Get a slice from the time series given a start and end time.

Looks for >= start & <= end

Uses loc to be exact with milliseconds

Parameters:
  • start (string, MTime) – start time of the slice

  • end (string, MTime) – end time of the slice

  • n_samples (integer) – number of sample to get after start time

Returns:

slice of the channel requested

Return type:

ChannelTS

decimate(new_sample_rate, inplace=False, max_decimation=8)[source]

decimate the data by using scipy.signal.decimate

Parameters:

dec_factor (int) – decimation factor

  • refills ts.data with decimated data and replaces sample_rate

resample_poly(new_sample_rate, pad_type='mean', inplace=False)[source]

Use scipy.signal.resample_poly to resample data while using an FIR filter to remove aliasing.

Parameters:
  • new_sample_rate (TYPE) – DESCRIPTION

  • pad_type (TYPE, optional) – DESCRIPTION, defaults to “mean”

Returns:

DESCRIPTION

Return type:

TYPE

merge(other, gap_method='slinear', new_sample_rate=None, resample_method='poly')[source]

merg two channels or list of channels together in the following steps

  1. xr.combine_by_coords([original, other])

  2. compute monotonic time index

  3. reindex(new_time_index, method=gap_method)

If you want a different method or more control use merge

Parameters:

other (mth5.timeseries.ChannelTS) – Another channel

Raises:
  • TypeError – If input is not a ChannelTS

  • ValueError – if the components are different

Returns:

Combined channel with monotonic time index and same metadata

Return type:

mth5.timeseries.ChannelTS

to_xarray()[source]

Returns a xarray.DataArray object of the channel timeseries this way metadata from the metadata class is updated upon return.

Returns:

Returns a xarray.DataArray object of the channel timeseries

this way metadata from the metadata class is updated upon return. :rtype: xarray.DataArray

>>> import numpy as np
>>> from mth5.timeseries import ChannelTS
>>> ex = ChannelTS("electric")
>>> ex.start = "2020-01-01T12:00:00"
>>> ex.sample_rate = 16
>>> ex.ts = np.random.rand(4096)
to_obspy_trace(network_code=None, encoding=None)[source]

Convert the time series to an obspy.core.trace.Trace object. This will be helpful for converting between data pulled from IRIS and data going into IRIS.

Parameters:

network_code (string) – two letter code provided by FDSN DMC

Returns:

DESCRIPTION

Return type:

TYPE

from_obspy_trace(obspy_trace)[source]

Fill data from an obspy.core.Trace

Parameters:

obspy_trace (obspy.core.trace) – Obspy trace object

plot()[source]

Simple plot of the data

Returns:

figure object

Return type:

matplotlib.figure

welch_spectra(window_length=2**12, **kwargs)[source]

get welch spectra

Parameters:
  • window_length (TYPE) – DESCRIPTION

  • **kwargs

    DESCRIPTION

Returns:

DESCRIPTION

Return type:

TYPE

plot_spectra(spectra_type='welch', window_length=2**12, **kwargs)[source]
Parameters:
  • spectra_type (string, optional) – spectra type, defaults to “welch”

  • window_length (int, optional) – window length of the welch method should be a power of 2, defaults to 2 ** 12

  • **kwargs

    DESCRIPTION