mth5.io.phoenix.readers
Submodules
- mth5.io.phoenix.readers.base
- mth5.io.phoenix.readers.calibrations
- mth5.io.phoenix.readers.config
- mth5.io.phoenix.readers.contiguous
- mth5.io.phoenix.readers.header
- mth5.io.phoenix.readers.helpers
- mth5.io.phoenix.readers.mtu
- mth5.io.phoenix.readers.native
- mth5.io.phoenix.readers.receiver_metadata
- mth5.io.phoenix.readers.segmented
Classes
Phoenix Geophysics MTU-5C binary header reader and parser. |
|
Phoenix Geophysics calibration data reader and filter manager. |
|
Generic reader that all other readers will inherit. |
|
Native sampling rate 'Raw' time series reader class. |
|
Class to create a streamer for segmented decimated time series. |
|
Class to create a streamer for continuous decimated time series. |
|
Phoenix Geophysics configuration file reader and metadata container. |
|
Container for Phoenix Geophysics recmeta.json metadata files. |
|
Reader for legacy Phoenix MTU-5A instrument time series binary files. |
Package Contents
- class mth5.io.phoenix.readers.Header(**kwargs: Any)[source]
Phoenix Geophysics MTU-5C binary header reader and parser.
This class reads and parses the 128-byte binary header from Phoenix Geophysics MTU-5C data files. The header contains instrument configuration, GPS location, timing information, and recording parameters essential for proper data interpretation.
The header format is fixed at 128 bytes and contains information about: - Instrument type and serial number - Recording parameters (sample rate, channel configuration) - GPS location and timing information - Hardware configuration and gain settings - Data quality metrics (saturated/missing frames)
- Parameters:
**kwargs (Any) – Additional keyword arguments to set as instance attributes.
- logger
Logger instance for debugging and error reporting.
- Type:
loguru.Logger
- report_hw_sat
Flag to control hardware saturation reporting.
- Type:
bool, default False
- header_length
Length of the binary header in bytes.
- Type:
int, default 128
- ad_plus_minus_range
Differential voltage range of the A/D converter (board dependent).
- Type:
float, default 5.0
- channel_map
Mapping from channel IDs to channel names.
- Type:
dict[int, str]
- channel_azimuths
Mapping from channel names to azimuth angles in degrees.
- Type:
dict[str, int]
Examples
>>> with open("phoenix_data.bin", "rb") as f: ... header = Header() ... header.unpack_header(f) ... print(f"Sample rate: {header.sample_rate}") ... print(f"GPS location: {header.gps_lat}, {header.gps_long}")
- logger: loguru.Logger
- report_hw_sat: bool = False
- property header_length: int
Length of the header in bytes.
- Returns:
Header length in bytes.
- Return type:
int
- ad_plus_minus_range: float = 5.0
- channel_map: dict[int, str]
- channel_azimuths: dict[str, int]
- property file_type: int | None
File type indicator from binary header.
- Returns:
File type identifier, or None if no header is loaded.
- Return type:
int or None
- property file_version: int | None
File version from binary header.
- Returns:
File version identifier, or None if no header is loaded.
- Return type:
int or None
- property instrument_type: str | None
Instrument type string from binary header.
- Returns:
Cleaned instrument type string, or None if no header is loaded.
- Return type:
str or None
- property instrument_serial_number: str | None
Instrument serial number from binary header.
- Returns:
Decoded instrument serial number, or None if no header is loaded.
- Return type:
str or None
- property recording_id: int | None
Recording identifier from binary header or cached value.
- Returns:
Recording ID as integer, or None if not available.
- Return type:
int or None
- property recording_start_time: mt_metadata.common.mttime.MTime | None
Recording start time from GPS timestamp.
The actual data recording starts 1 second after the set start time. This is caused by the data logger starting up and initializing filter. This is taken care of in the segment start time.
See https://github.com/kujaku11/PhoenixGeoPy/tree/main/Docs for more information.
The time recorded is GPS time.
- Returns:
GPS start time, or None if recording ID is not available.
- Return type:
MTime or None
- property channel_id: int | None
Channel identifier from binary header or cached value.
- Returns:
Channel ID, or None if not available.
- Return type:
int or None
- property file_sequence: int | None
File sequence number from binary header.
- Returns:
File sequence number, or None if no header is loaded.
- Return type:
int or None
- property frag_period: int | None
Fragment period from binary header.
- Returns:
Fragment period, or None if no header is loaded.
- Return type:
int or None
- property ch_board_model: str | None
Channel board model string from binary header.
- Returns:
Board model string, or None if no header is loaded.
- Return type:
str or None
- property board_model_main: str | None
Main board model identifier.
- Returns:
Main board model (first 5 characters), or None if not available.
- Return type:
str or None
- property board_model_revision: str | None
Board model revision identifier.
- Returns:
Board revision (character 6), or None if not available.
- Return type:
str or None
- property ch_board_serial: int
Channel board serial number from binary header.
- Returns:
Board serial number as integer, or 0 if not available or invalid.
- Return type:
int
- property ch_firmware: int | None
Channel firmware version from binary header.
- Returns:
Firmware version, or None if no header is loaded.
- Return type:
int or None
- property hardware_configuration: tuple[Any, Ellipsis] | None
Hardware configuration bytes from binary header.
- Returns:
Hardware configuration data, or None if no header is loaded.
- Return type:
tuple of Any or None
- property channel_type: str | None
Channel type determined from hardware configuration.
- Returns:
‘E’ for electric, ‘H’ for magnetic, or None if no header.
- Return type:
str or None
- property detected_channel_type: str | None
Channel type detected by electronics.
This normally matches channel_type, but used in electronics design and testing.
- Returns:
‘E’ for electric, ‘H’ for magnetic, or None if no header.
- Return type:
str or None
- property lp_frequency: int | None
Low-pass filter frequency based on hardware configuration.
- Returns:
Filter frequency in Hz, or None if no header.
- Return type:
int or None
- property preamp_gain: float
Pre-amplifier gain factor.
- Returns:
Gain factor, default 1.0.
- Return type:
float
- Raises:
Exception – If channel type is not determined before calculating gain.
- property channel_main_gain: float
Main gain of the board.
- Returns:
Main gain factor.
- Return type:
float
- property intrinsic_circuitry_gain: float
Intrinsic circuitry gain based on sensor range configuration.
This function adjusts the intrinsic circuitry gain based on the sensor range configuration in the configuration fingerprint.
For the Electric channel, calibration path, or H-legacy sensors all go through a 1/4 gain stage, and then they get a virtual x2 gain from Single-ended-diff before the A/D. In the case of newer sensors (differential) instead of a 1/4 gain stage, there is only a 1/2 gain stage.
Therefore, in the E, cal and legacy sensor case the circuitry gain is 1/2, while for newer sensors it is 1.
- Returns:
Intrinsic gain factor.
- Return type:
float
- Raises:
Exception – If channel type is not determined before calculating gain.
Notes
Circuitry Gain not directly configurable by the user.
- property attenuator_gain: float
Attenuator gain factor.
- Returns:
Attenuator gain factor, default 1.0.
- Return type:
float
- Raises:
Exception – If channel type is not determined before calculating gain.
- property total_selectable_gain: float
Total gain that is selectable by the user.
Combines attenuator, preamp, and main channel gains.
- Returns:
Total selectable gain factor.
- Return type:
float
- property total_circuitry_gain: float
Total board gain including both intrinsic and user-selectable gains.
- Returns:
Total circuitry gain factor.
- Return type:
float
- property sample_rate_base: int | None
Base sample rate from binary header.
- Returns:
Base sample rate, or None if no header.
- Return type:
int or None
- property sample_rate_exp: int | None
Sample rate exponent from binary header.
- Returns:
Sample rate exponent, or None if no header.
- Return type:
int or None
- property sample_rate: float | None
Calculated sample rate.
- Returns:
Sample rate in Hz, or None if no header.
- Return type:
float or None
- property bytes_per_sample: int | None
Number of bytes per sample.
- Returns:
Bytes per sample, or None if no header.
- Return type:
int or None
- property frame_size: int | None
Frame size from binary header.
- Returns:
Frame size value, or None if no header.
- Return type:
int or None
Data footer extracted from frame size.
- Returns:
Data footer value, or None if no frame size.
- Return type:
int or None
- property frame_size_bytes: int | None
Frame size in bytes.
- Returns:
Frame size in bytes, or None if no frame size.
- Return type:
int or None
- property decimation_node_id: int | None
Decimation node identifier.
- Returns:
Decimation node ID, or None if no header.
- Return type:
int or None
- property frame_rollover_count: int | None
Frame rollover count.
- Returns:
Rollover count, or None if no header.
- Return type:
int or None
- property gps_long: float | None
GPS longitude.
- Returns:
Longitude in degrees, or None if no header.
- Return type:
float or None
- property gps_lat: float | None
GPS latitude.
- Returns:
Latitude in degrees, or None if no header.
- Return type:
float or None
- property gps_elevation: float | None
GPS elevation.
- Returns:
Elevation in meters, or None if no header.
- Return type:
float or None
- property gps_horizontal_accuracy: float | None
GPS horizontal accuracy.
- Returns:
Horizontal accuracy in meters (converted from millimeters), or None if no header.
- Return type:
float or None
- property gps_vertical_accuracy: float | None
GPS vertical accuracy.
- Returns:
Vertical accuracy in meters (converted from millimeters), or None if no header.
- Return type:
float or None
- property timing_status: tuple[Any, Ellipsis] | None
Timing status information.
- Returns:
Timing status data, or None if no header.
- Return type:
tuple of Any or None
- property timing_flags: Any | None
Timing flags from timing status.
- Returns:
Timing flags, or None if no timing status.
- Return type:
Any or None
- property timing_sat_count: Any | None
Satellite count from timing status.
- Returns:
Satellite count, or None if no timing status.
- Return type:
Any or None
- property timing_stability: Any | None
Timing stability from timing status.
- Returns:
Timing stability value, or None if no timing status.
- Return type:
Any or None
- property future1: Any | None
Future field 1 (reserved).
- Returns:
Future field value, or None if no header.
- Return type:
Any or None
- property future2: Any | None
Future field 2 (reserved).
- Returns:
Future field value, or None if no header.
- Return type:
Any or None
- property saturated_frames: int | None
Number of saturated frames.
- Returns:
Saturated frame count, or None if no header.
- Return type:
int or None
- property missing_frames: int | None
Number of missing frames.
- Returns:
Missing frame count, or None if no header.
- Return type:
int or None
- property battery_voltage_v: float | None
Battery voltage in volts.
- Returns:
Battery voltage in volts (converted from millivolts), or None if no header.
- Return type:
float or None
- property min_signal: Any | None
Minimum signal value.
- Returns:
Minimum signal value, or None if no header.
- Return type:
Any or None
- property max_signal: Any | None
Maximum signal value.
- Returns:
Maximum signal value, or None if no header.
- Return type:
Any or None
- unpack_header(stream: BinaryIO) None[source]
Read and unpack binary header from stream.
- Parameters:
stream (BinaryIO) – Binary stream to read header from.
- get_channel_metadata() mt_metadata.timeseries.Magnetic | mt_metadata.timeseries.Electric[source]
Translate metadata to channel metadata.
- Returns:
Channel metadata object populated with header data.
- Return type:
Magnetic or Electric
- Raises:
KeyError – If channel ID is not found in channel map.
ValueError – If required fields are None or invalid.
- class mth5.io.phoenix.readers.PhoenixCalibration(cal_fn: str | pathlib.Path | None = None, **kwargs: Any)[source]
Phoenix Geophysics calibration data reader and filter manager.
This class reads Phoenix calibration files in JSON format and provides access to frequency response filters for different channels and lowpass filter settings. It supports both receiver and sensor calibration files.
- Parameters:
cal_fn (str or pathlib.Path, optional) – Path to the calibration file to read. If provided, the file will be loaded automatically during initialization.
**kwargs (Any) – Additional keyword arguments that will be set as instance attributes.
- obj
The parsed calibration object containing all calibration data.
- Type:
Any or None
- obj: Any = None
- property cal_fn: pathlib.Path
Path to the calibration file.
- Returns:
The path to the calibration file.
- Return type:
pathlib.Path
- property calibration_date: mt_metadata.common.mttime.MTime | None
Get the calibration date from the loaded calibration data.
- Returns:
The calibration date as an MTime object, or None if no data is loaded.
- Return type:
MTime or None
- get_max_freq(freq: numpy.typing.NDArray[numpy.floating] | list[float] | numpy.ndarray) int[source]
Calculate the maximum frequency for filter naming.
Determines the power-of-10 frequency limit based on the maximum frequency in the input array. Used to name filters as {channel}_{max_freq}hz_lowpass.
- Parameters:
freq (numpy.ndarray) – Array of frequency values in Hz.
- Returns:
The power-of-10 frequency limit (e.g., 1000 for frequencies up to 9999 Hz).
- Return type:
int
Examples
>>> cal = PhoenixCalibration() >>> freq = np.array([1.0, 10.0, 100.0, 1500.0]) >>> cal.get_max_freq(freq) 1000
- property base_filter_name: str | None
Generate the base filter name from instrument information.
Creates a standardized filter name prefix based on the instrument type, model, and serial number from the calibration data.
- Returns:
Base filter name in format “{instrument_type}_{instrument_model}_{serial}” converted to lowercase, or None if no data is loaded.
- Return type:
str or None
Examples
>>> cal = PhoenixCalibration("calibration.json") >>> cal.base_filter_name 'mtu-5c_rmt03-j_666'
- get_filter_lp_name(channel: str, max_freq: int) str[source]
Generate a lowpass filter name for a specific channel and frequency.
Creates a standardized filter name for receiver calibration filters in the format: {base_filter_name}_{channel}_{max_freq}hz_lowpass
- Parameters:
channel (str) – Channel identifier (e.g., ‘e1’, ‘h2’).
max_freq (int) – Maximum frequency in Hz for the lowpass filter.
- Returns:
Complete lowpass filter name in lowercase.
- Return type:
str
Examples
>>> cal = PhoenixCalibration("calibration.json") >>> cal.get_filter_lp_name("e1", 1000) 'mtu-5c_rmt03-j_666_e1_1000hz_lowpass'
- get_filter_sensor_name(sensor: str) str[source]
Generate a sensor filter name for a specific sensor.
Creates a standardized filter name for sensor calibration filters in the format: {base_filter_name}_{sensor}
- Parameters:
sensor (str) – Sensor identifier or serial number.
- Returns:
Complete sensor filter name in lowercase.
- Return type:
str
Examples
>>> cal = PhoenixCalibration("calibration.json") >>> cal.get_filter_sensor_name("sensor123") 'mtu-5c_rmt03-j_666_sensor123'
- read(cal_fn: str | pathlib.Path | None = None) None[source]
Read and parse a Phoenix calibration file.
Loads calibration data from a JSON file and creates frequency response filters for each channel and frequency band. The method creates channel attributes (e.g., self.e1, self.h2) containing either: - Dictionary of filters by frequency (receiver calibration) - Single filter object (sensor calibration)
- Parameters:
cal_fn (str, pathlib.Path, or None, optional) – Path to the calibration file to read. If None, uses the previously set calibration file path.
- Raises:
IOError – If the calibration file cannot be found or read.
Notes
The method automatically determines calibration type based on file_type: - “receiver calibration”: Creates multiple filters per channel by frequency - “sensor calibration”: Creates single filter per channel
- get_filter(channel: str, filter_name: str | int) mt_metadata.timeseries.filters.FrequencyResponseTableFilter[source]
Get the frequency response filter for a specific channel and filter.
Retrieves the lowpass filter for the given channel and filter specification. The method automatically handles both string and integer filter names.
- Parameters:
channel (str) – Channel identifier (e.g., ‘e1’, ‘h2’, ‘h3’).
filter_name (str or int) – Filter specification, typically the lowpass frequency in Hz (e.g., 1000, ‘100’, 10000).
- Returns:
The frequency response filter object containing the calibration data for the specified channel and filter.
- Return type:
FrequencyResponseTableFilter
- Raises:
AttributeError – If the specified channel is not found in the calibration data.
KeyError – If the specified filter is not found for the given channel.
Examples
>>> cal = PhoenixCalibration("calibration.json") >>> filt = cal.get_filter("e1", 1000) >>> print(f"Filter name: {filt.name}") >>> print(f"Frequency points: {len(filt.frequencies)}")
- class mth5.io.phoenix.readers.TSReaderBase(path: str | pathlib.Path, num_files: int = 1, header_length: int = 128, report_hw_sat: bool = False, **kwargs)[source]
Bases:
mth5.io.phoenix.readers.header.HeaderGeneric reader that all other readers will inherit.
This base class provides common functionality for reading Phoenix Geophysics time series data files, including header parsing, file sequence management, and metadata handling.
- Parameters:
path (str or Path) – Path to the time series file
num_files (int, optional) – Number of files in the sequence, by default 1
header_length (int, optional) – Length of file header in bytes, by default 128
report_hw_sat (bool, optional) – Whether to report hardware saturation, by default False
**kwargs – Additional keyword arguments passed to parent Header class
- stream
File stream for reading binary data
- Type:
BinaryIO or None
- base_path
Path to the current file
- Type:
Path
- last_seq
Last sequence number in the file sequence
- Type:
int
- rx_metadata
Receiver metadata object
- Type:
PhoenixReceiverMetadata or None
- logger
- property base_path: pathlib.Path
Full path of the file.
- Returns:
Full path to the file
- Return type:
Path
- last_seq
- stream = None
- rx_metadata = None
- property base_dir: pathlib.Path
Parent directory of the file.
- Returns:
Parent directory of the file
- Return type:
Path
- property file_name: str
Name of the file.
- Returns:
Name of the file
- Return type:
str
- property file_extension: str
File extension.
- Returns:
File extension including the dot
- Return type:
str
- property instrument_id: str
Instrument ID extracted from filename.
- Returns:
Instrument identifier
- Return type:
str
- property seq: int
Sequence number of the file.
- Returns:
Sequence number extracted from filename or set value
- Return type:
int
- property file_size: int
File size in bytes.
- Returns:
Size of the file in bytes
- Return type:
int
- property max_samples: int
Maximum number of samples in a file.
Calculated as: (total number of bytes - header length) / frame size * n samples per frame
- Returns:
Maximum number of samples in the file
- Return type:
int
- property sequence_list: list[pathlib.Path]
Get all the files in the sequence sorted by sequence number.
- Returns:
List of Path objects for all files in the sequence
- Return type:
list[Path]
- property config_file_path: pathlib.Path | None
Path to the config.json file.
- Returns:
Path to config file if it exists, None otherwise
- Return type:
Path or None
- property recmeta_file_path: pathlib.Path | None
Path to the recmeta.json file.
- Returns:
Path to recmeta file if it exists, None otherwise
- Return type:
Path or None
- open_next() bool[source]
Open the next file in the sequence.
- Returns:
True if next file is now open, False if it is not
- Return type:
bool
- open_file_seq(file_seq_num: int | None = None) bool[source]
Open a file in the sequence given the sequence number.
- Parameters:
file_seq_num (int, optional) – Sequence number to open, by default None
- Returns:
True if file is now open, False if it is not
- Return type:
bool
- get_config_object() mth5.io.phoenix.readers.config.PhoenixConfig | None[source]
Read a config file into an object.
- Returns:
Configuration object if config file exists, None otherwise
- Return type:
PhoenixConfig or None
- get_receiver_metadata_object() None[source]
Read recmeta.json into an object and store in rx_metadata attribute.
- get_lowpass_filter_name() str | None[source]
Get the lowpass filter used by the receiver pre-decimation.
- Returns:
Name of the lowpass filter if available, None otherwise
- Return type:
str or None
- property channel_metadata: Any
Channel metadata updated from recmeta.
- Returns:
Channel metadata object
- Return type:
Any
- property run_metadata: Any
Run metadata updated from recmeta.
- Returns:
Run metadata object
- Return type:
Any
- property station_metadata: Any
Station metadata updated from recmeta.
- Returns:
Station metadata object
- Return type:
Any
- get_receiver_lowpass_filter(rxcal_fn: str | pathlib.Path) Any[source]
Get receiver lowpass filter from the rxcal.json file.
- Parameters:
rxcal_fn (str or Path) – Path to the receiver calibration file
- Returns:
Filter object from calibration file
- Return type:
Any
- Raises:
ValueError – If the lowpass filter name cannot be found
- get_dipole_filter() mt_metadata.timeseries.filters.CoefficientFilter | None[source]
Get dipole filter for electric field channels.
- Returns:
Dipole filter if channel has dipole length, None otherwise
- Return type:
CoefficientFilter or None
- get_sensor_filter(scal_fn: str | pathlib.Path) Any[source]
Get sensor filter from calibration file.
- Parameters:
scal_fn (str or Path) – Path to sensor calibration file
- Returns:
Sensor filter object
- Return type:
Any
Notes
This method is not implemented yet.
- get_v_to_mv_filter() mt_metadata.timeseries.filters.CoefficientFilter[source]
Create a filter to convert units from volts to millivolts.
- Returns:
Filter that converts volts to millivolts with gain of 1000
- Return type:
CoefficientFilter
- get_channel_response(rxcal_fn: str | pathlib.Path | None = None, scal_fn: str | pathlib.Path | None = None) mt_metadata.timeseries.filters.ChannelResponse[source]
Get the channel response filter.
- Parameters:
rxcal_fn (str, Path or None, optional) – Path to receiver calibration file, by default None
scal_fn (str, Path or None, optional) – Path to sensor calibration file, by default None
- Returns:
Complete channel response filter chain
- Return type:
ChannelResponse
- class mth5.io.phoenix.readers.NativeReader(path: str | pathlib.Path, num_files: int = 1, scale_to: int = AD_INPUT_VOLTS, header_length: int = 128, last_frame: int = 0, ad_plus_minus_range: float = 5.0, channel_type: str = 'E', report_hw_sat: bool = False, **kwargs)[source]
Bases:
mth5.io.phoenix.readers.TSReaderBaseNative sampling rate ‘Raw’ time series reader class.
This class reads native binary (.bin) files from Phoenix Geophysics MTU-5C instruments. The files are formatted with a header of 128 bytes followed by frames of 64 bytes each. Each frame contains 20 x 3-byte (24-bit) data points plus a 4-byte footer.
- Parameters:
path (str or Path) – Path to the time series file
num_files (int, optional) – Number of files in the sequence, by default 1
scale_to (int, optional) – Data scaling mode (AD_IN_AD_UNITS, AD_INPUT_VOLTS, or INSTRUMENT_INPUT_VOLTS), by default AD_INPUT_VOLTS
header_length (int, optional) – Length of file header in bytes, by default 128
last_frame (int, optional) – Last frame number seen by the streamer, by default 0
ad_plus_minus_range (float, optional) – ADC plus/minus range in volts, by default 5.0
channel_type (str, optional) – Channel type identifier, by default “E”
report_hw_sat (bool, optional) – Whether to report hardware saturation, by default False
**kwargs – Additional keyword arguments passed to parent TSReaderBase class
- last_frame
Last frame number processed
- Type:
int
- data_scaling
Current data scaling mode
- Type:
int
- ad_plus_minus_range
ADC voltage range
- Type:
float
- input_plusminus_range
Input voltage range after gain correction
- Type:
float
- scale_factor
Calculated scaling factor for data conversion
- Type:
float
Bit mask for frame index in footer
- Type:
int
Bit mask for saturation count in footer
- Type:
int
- last_frame = 0
- header_length = 128
Length of the header in bytes.
- Returns:
Header length in bytes.
- Return type:
int
- data_scaling = 1
- ad_plus_minus_range = 5.0
- input_plusminus_range
- scale_factor = 256
- footer_idx_samp_mask = 0
- footer_sat_mask = 0
- read_frames(num_frames: int) numpy.ndarray[source]
Read the given number of frames from the data stream.
Note
The seek position is not reset, so iterating this method will read from the last position in the stream.
- Parameters:
num_frames (int) – Number of frames to read
- Returns:
Scaled data from the given number of frames with dtype float64
- Return type:
np.ndarray
- property npts_per_frame: int
Get the number of data points per frame.
- Returns:
Number of data points per frame (frame size - 4 footer bytes) / 3 bytes per sample
- Return type:
int
- read() tuple[numpy.ndarray, numpy.ndarray][source]
Read the full data file using memory mapping and stride tricks.
Note
This uses numpy.lib.stride_tricks.as_strided which can be unstable if the bytes are not the correct length. See notes by numpy.
The solution is adapted from: https://stackoverflow.com/questions/12080279/how-do-i-create-a-numpy-dtype-that-includes-24-bit-integers
- Returns:
Scaled time series data and footer data as (data, footer)
- Return type:
tuple[np.ndarray, np.ndarray]
- read_sequence(start: int = 0, end: int | None = None) tuple[numpy.ndarray, numpy.ndarray][source]
Read a sequence of files into a single array.
- Parameters:
start (int, optional) – Sequence start index, by default 0
end (int or None, optional) – Sequence end index, by default None
- Returns:
Scaled time series data and footer data as (data, footer) - data: np.ndarray with dtype float32 - footer: np.ndarray with dtype int32
- Return type:
tuple[np.ndarray, np.ndarray]
- skip_frames(num_frames: int) bool[source]
Skip frames in the data stream.
- Parameters:
num_frames (int) – Number of frames to skip
- Returns:
True if skip completed successfully, False if end of file reached
- Return type:
bool
- to_channel_ts(rxcal_fn: str | pathlib.Path | None = None, scal_fn: str | pathlib.Path | None = None) mth5.timeseries.ChannelTS[source]
Convert to a ChannelTS object.
- Parameters:
rxcal_fn (str, Path or None, optional) – Path to receiver calibration file, by default None
scal_fn (str, Path or None, optional) – Path to sensor calibration file, by default None
- Returns:
Channel time series object with data, metadata, and calibration
- Return type:
- class mth5.io.phoenix.readers.DecimatedSegmentedReader(path: str | pathlib.Path, num_files: int = 1, report_hw_sat: bool = False, **kwargs)[source]
Bases:
mth5.io.phoenix.readers.TSReaderBaseClass to create a streamer for segmented decimated time series.
This reader handles segmented decimated time series files such as ‘td_24k’. These files have sub headers containing metadata for each segment.
- Parameters:
path (str or Path) – Path to the time series file
num_files (int, optional) – Number of files in the sequence, by default 1
report_hw_sat (bool, optional) – Whether to report hardware saturation, by default False
**kwargs – Additional keyword arguments passed to parent TSReaderBase class
- subheader
Dictionary for additional subheader information
- Type:
dict
- sub_header
- subheader
- read_segment(metadata_only: bool = False) Segment[source]
Read a single segment from the file.
- Parameters:
metadata_only (bool, optional) – If True, only read metadata without loading data, by default False
- Returns:
Segment object containing data and metadata
- Return type:
- Raises:
ValueError – If stream is not available
- to_channel_ts(rxcal_fn: str | pathlib.Path | None = None, scal_fn: str | pathlib.Path | None = None) mth5.timeseries.ChannelTS[source]
Convert to a ChannelTS object.
- Parameters:
rxcal_fn (str, Path or None, optional) – Path to receiver calibration file, by default None
scal_fn (str, Path or None, optional) – Path to sensor calibration file, by default None
- Returns:
Channel time series object with data, metadata, and calibration
- Return type:
- class mth5.io.phoenix.readers.DecimatedContinuousReader(path: str | pathlib.Path, num_files: int = 1, report_hw_sat: bool = False, **kwargs)[source]
Bases:
mth5.io.phoenix.readers.TSReaderBaseClass to create a streamer for continuous decimated time series.
This reader handles continuous decimated time series files such as ‘td_150’, ‘td_30’. These files have no sub header information.
- Parameters:
path (str or Path) – Path to the time series file
num_files (int, optional) – Number of files in the sequence, by default 1
report_hw_sat (bool, optional) – Whether to report hardware saturation, by default False
**kwargs – Additional keyword arguments passed to parent TSReaderBase class
- subheader
Empty dictionary as these files have no sub header information
- Type:
dict
- data_size
Size of the data sequence when read
- Type:
int or None
- subheader
- data_size: int | None = None
- property segment_start_time: mt_metadata.common.mttime.MTime
Estimate the segment start time based on sequence number.
The first sequence starts 1 second later than the set start time due to initiation within the data logger.
- Returns:
Start time of the recording segment
- Return type:
MTime
- property segment_end_time: mt_metadata.common.mttime.MTime
Estimate end time of the segment.
The first sequence starts 1 second later than the set start time due to initiation within the data logger.
- Returns:
Estimated end time from number of samples
- Return type:
MTime
- property sequence_start: mt_metadata.common.mttime.MTime
Get the sequence start time.
- Returns:
Start time of the sequence
- Return type:
MTime
- property sequence_end: mt_metadata.common.mttime.MTime
Get the sequence end time.
- Returns:
End time of the sequence based on data size or max samples
- Return type:
MTime
- read() numpy.ndarray[source]
Read in the full data from the current file.
- Returns:
Single channel data array with dtype float32
- Return type:
np.ndarray
- read_sequence(start: int = 0, end: int | None = None) numpy.ndarray[source]
Read a sequence of files.
- Parameters:
start (int, optional) – Starting index in the sequence, by default 0
end (int or None, optional) – Ending index in the sequence to read, by default None
- Returns:
Data within the given sequence range as float32 array
- Return type:
np.ndarray
- to_channel_ts(rxcal_fn: str | pathlib.Path | None = None, scal_fn: str | pathlib.Path | None = None) mth5.timeseries.ChannelTS[source]
Convert to a ChannelTS object.
- Parameters:
rxcal_fn (str, Path or None, optional) – Path to receiver calibration file, by default None
scal_fn (str, Path or None, optional) – Path to sensor calibration file, by default None
- Returns:
Channel time series object with data, metadata, and calibration
- Return type:
- class mth5.io.phoenix.readers.PhoenixConfig(fn: str | pathlib.Path | None = None, **kwargs: Any)[source]
Phoenix Geophysics configuration file reader and metadata container.
This class reads and provides access to Phoenix MTU-5C instrument configuration data stored in JSON format. The configuration file contains recording parameters, instrument settings, and metadata used to control data acquisition.
- Parameters:
fn (str, pathlib.Path, or None, optional) – Path to the Phoenix configuration file (typically config.json). If provided, the file will be validated for existence.
**kwargs (Any) – Additional keyword arguments (currently unused).
- fn
Path to the configuration file.
- Type:
pathlib.Path or None
- obj
Parsed configuration object containing all settings.
- Type:
Any or None
- logger
Logger instance for debugging and error reporting.
- Type:
loguru.Logger
Examples
>>> config = PhoenixConfig("config.json") >>> config.read() >>> station = config.station_metadata() >>> print(f"Station ID: {station.id}")
- obj: Any = None
- logger: loguru.Logger
- property fn: pathlib.Path | None
Path to the Phoenix configuration file.
- Returns:
The path to the configuration file, or None if not set.
- Return type:
pathlib.Path or None
- read(fn: str | pathlib.Path | None = None) None[source]
Read and parse a Phoenix configuration file.
Loads and parses a Phoenix MTU-5C configuration file in JSON format. The parsed configuration is stored in the obj attribute and provides access to all recording parameters and instrument settings.
- Parameters:
fn (str, pathlib.Path, or None, optional) – Path to the configuration file to read. If None, uses the previously set file path from the fn property.
- Raises:
ValueError – If no file path is provided and none was previously set.
IOError – If the configuration file cannot be read or parsed.
Notes
The configuration file should be in Phoenix JSON format containing recording parameters, instrument settings, and metadata.
- has_obj() bool[source]
Check if configuration data has been loaded.
- Returns:
True if configuration data is loaded, False otherwise.
- Return type:
bool
- property auto_power_enabled: Any | None
Auto power enabled setting from configuration.
- Returns:
The auto power enabled setting, or None if no configuration is loaded.
- Return type:
Any or None
- property config: Any | None
Main configuration section from the configuration file.
- Returns:
The first configuration object containing recording parameters, or None if no configuration is loaded.
- Return type:
Any or None
- property empower_version: Any | None
EMPower software version from configuration.
- Returns:
The EMPower software version, or None if no configuration is loaded.
- Return type:
Any or None
- property mtc150_reset: Any | None
MTC150 reset setting from configuration.
- Returns:
The MTC150 reset setting, or None if no configuration is loaded.
- Return type:
Any or None
- property network: Any | None
Network configuration from configuration file.
- Returns:
The network configuration settings, or None if no configuration is loaded.
- Return type:
Any or None
- property receiver: Any | None
Receiver configuration from configuration file.
- Returns:
The receiver configuration settings, or None if no configuration is loaded.
- Return type:
Any or None
- property schedule: Any | None
Recording schedule from configuration file.
- Returns:
The recording schedule configuration, or None if no configuration is loaded.
- Return type:
Any or None
- property surveyTechnique: Any | None
Survey technique setting from configuration file.
- Returns:
The survey technique setting, or None if no configuration is loaded.
- Return type:
Any or None
- property timezone: Any | None
Timezone setting from configuration file.
- Returns:
The timezone setting, or None if no configuration is loaded.
- Return type:
Any or None
- property timezone_offset: Any | None
Timezone offset from configuration file.
- Returns:
The timezone offset in hours, or None if no configuration is loaded.
- Return type:
Any or None
- property version: Any | None
Configuration file version from configuration file.
- Returns:
The configuration file version, or None if no configuration is loaded.
- Return type:
Any or None
- station_metadata() mt_metadata.timeseries.Station[source]
Create a Station metadata object from configuration data.
Extracts station information from the loaded configuration and creates a standardized Station metadata object with basic station parameters.
- Returns:
A Station metadata object populated with configuration data including station ID, operator information, company name, and notes.
- Return type:
Station
- Raises:
AttributeError – If no configuration is loaded or required fields are missing.
Notes
The method extracts the following information from config.layout: - Station_Name -> station.id - Operator -> station.acquired_by.name - Company_Name -> station.acquired_by.organization - Notes -> station.comments
Examples
>>> config = PhoenixConfig("config.json") >>> config.read() >>> station = config.station_metadata() >>> print(f"Station: {station.id}")
- class mth5.io.phoenix.readers.PhoenixReceiverMetadata(fn: str | pathlib.Path | None = None, **kwargs: Any)[source]
Container for Phoenix Geophysics recmeta.json metadata files.
This class reads and parses receiver metadata from JSON configuration files used to control Phoenix Geophysics MTU-5C data recording systems. It provides methods to extract channel configurations, instrument settings, and convert them to standardized metadata objects.
- Parameters:
fn (str, Path, or None, optional) – Path to the recmeta.json file. If provided, the file will be read automatically during initialization.
**kwargs – Additional keyword arguments (currently unused).
- fn
Path to the metadata file.
- Type:
Path or None
- obj
Parsed JSON content as a SimpleNamespace object.
- Type:
SimpleNamespace or None
- logger
Logger instance for error reporting.
- Type:
loguru.Logger
- Raises:
IOError – If the specified file does not exist.
Examples
>>> metadata = PhoenixReceiverMetadata("recmeta.json") >>> channel_map = metadata.channel_map >>> e1_config = metadata.e1_metadata
Notes
The class supports both electric and magnetic channel configurations with automatic mapping from Phoenix-specific parameter names to standardized metadata attributes.
- property fn: pathlib.Path | None
Path to the metadata file.
- Returns:
Path to the recmeta.json file, or None if not set.
- Return type:
Path or None
- obj: types.SimpleNamespace | None = None
- logger
- property instrument_id: str | None
Instrument identifier from metadata.
- Returns:
Instrument ID if available, None otherwise.
- Return type:
str or None
- read(fn: str | pathlib.Path | None = None) None[source]
Read a recmeta.json file in Phoenix format.
- Parameters:
fn (str, Path, or None, optional) – Path to the JSON file. If None, uses the current fn property.
- Raises:
IOError – If no file path is specified or file doesn’t exist.
ValueError – If the file cannot be parsed as JSON.
- has_obj() bool[source]
Check if metadata object is loaded.
- Returns:
True if metadata object exists, False otherwise.
- Return type:
bool
- property channel_map: dict[int, str]
Channel mapping from index to component tag.
- Returns:
Dictionary mapping channel indices to component tags (lowercase).
- Return type:
dict[int, str]
- Raises:
AttributeError – If metadata object is not loaded or missing channel_map.
- property lp_filter_base_name: str | None
Base name for low-pass filter identifiers.
- Returns:
Filter base name combining receiver info, or None if not available.
- Return type:
str or None
- get_ch_index(tag: str) int[source]
Get channel index from component tag.
- Parameters:
tag (str) – Component tag (e.g., ‘e1’, ‘h1’, etc.).
- Returns:
Channel index corresponding to the tag.
- Return type:
int
- Raises:
ValueError – If the tag is not found in the channel map.
AttributeError – If metadata object is not loaded.
- get_ch_tag(index: int) str[source]
Get component tag from channel index.
- Parameters:
index (int) – Channel index.
- Returns:
Component tag corresponding to the index.
- Return type:
str
- Raises:
ValueError – If the index is not found in the channel map.
AttributeError – If metadata object is not loaded.
- property e1_metadata: mt_metadata.timeseries.Electric
Electric channel 1 metadata.
- property e2_metadata: mt_metadata.timeseries.Electric
Electric channel 2 metadata.
- property h1_metadata: mt_metadata.timeseries.Magnetic
Magnetic channel 1 metadata.
- property h2_metadata: mt_metadata.timeseries.Magnetic
Magnetic channel 2 metadata.
- property h3_metadata: mt_metadata.timeseries.Magnetic
Magnetic channel 3 metadata.
- property h4_metadata: mt_metadata.timeseries.Magnetic
Magnetic channel 4 metadata.
- property h5_metadata: mt_metadata.timeseries.Magnetic
Magnetic channel 5 metadata.
- property h6_metadata: mt_metadata.timeseries.Magnetic
Magnetic channel 6 metadata.
- get_ch_metadata(index: int) mt_metadata.timeseries.Electric | mt_metadata.timeseries.Magnetic[source]
Get channel metadata from index.
- Parameters:
index (int) – Channel index.
- Returns:
Channel metadata object corresponding to the index.
- Return type:
Electric or Magnetic
- Raises:
ValueError – If index is not found in channel map.
AttributeError – If the corresponding metadata property doesn’t exist.
- property run_metadata: mt_metadata.timeseries.Run
Run metadata from receiver configuration.
- Returns:
Run metadata object with data logger and timing information.
- Return type:
Run
- property station_metadata: mt_metadata.timeseries.Station
Station metadata from receiver configuration.
- Returns:
Station metadata object with location and acquisition information.
- Return type:
Station
- property survey_metadata: mt_metadata.timeseries.Survey
Survey metadata from receiver configuration.
- Returns:
Survey metadata object with survey information.
- Return type:
Survey
- class mth5.io.phoenix.readers.MTUTable(file_path: str | pathlib.Path | None = None, **kwargs)[source]
The Phoenix TBL file is a series of 25-byte blocks containing key-value pairs: - Bytes 0-11: Tag name (4-character string, null-padded) - Bytes 12-24: Value (13 bytes, mixed data types)
Values can be decoded as follows: 1. INT (4 bytes): struct.unpack(‘<i’, bytes[0:4]) - Little-endian signed int 2. DOUBLE (8 bytes): struct.unpack(‘<d’, bytes[0:8]) - Little-endian double 3. CHAR (variable): bytes.decode(‘latin-1’).strip() - Null-terminated string 4. BYTE (1 byte): struct.unpack(‘<B’, bytes[0:1]) - Unsigned byte 5. TIME (6 bytes): [sec, min, hour, day, month, year-2000] format
The TBL_TAG_TYPES dictionary maps each known tag to its data type, enabling automatic decoding via decode_tbl_value() function. Unknown tags return raw bytes.
- Example usage:
# Automatic decoding: tbl_dict = get_dictionary_from_tbl(‘file.TBL’, decode_values=True)
# Manual decoding with read_tbl (legacy): info = read_tbl(‘/path’, ‘file.TBL’)
read_tbl - reads a (binary) TBL table file of the legacy Phoenix format (MTU-5A) and output the “info” metadata dictionary.
- Parameters:
fpath – path to the tbl
fname – name of the tbl file (including extensions)
- Returns:
output dict of the TBL metadata
- Return type:
info
SITE: site name SNUM: serial number (of the box) FILE: file name recorded CMPY: company/institute of the survey SRVY: survey project name EXLN: Ex channel dipole length EYLN: Ey channel dipole length NREF: North reference (true, or magnetic north) LNGG: longitude in degree-minute format (DDD MM.MM) LATG: latitude in degree-minute format (DD MM.MM) ELEV: elevation (in metres) HXSN: Hx channel coil serial number HYSN: Hy channel coil serial number HZSN: Hz channel coil serial number STIM: starting time (UTC) ETIM: ending time (UTC) LFRQ: powerline frequency for filtering (can only be 50 or 60 Hz) HGN: final H-channel gain HGNC: H-channel gain control: HGN = PA * 2^HGNC (note: PA =
PreAmplifier gain)
EGN: final E-channel gain EGNC: E-channel gain control: HGN = PA * 2^HGNC (note: PA =
PreAmplifier gain)
- HSMP: L3 and L4 time slot in second (MTU-5A) or minute (MTU-5P),
this means the instrument will record L3NS seconds for L3 and L4NS seconds for L4, for every HSMP time slot.
L3NS: L3 sample time (in second) L4NS: L4 sample time (in second) SRL3: L3 sample rate SRL4: L4 sample rate SRL5: L5 sample rate HATT: H channel attenuation (1/4.3 for MTU-5A) HNOM: H channel normalization (mA/nT) TCMB: Type of comb filter (probably used to suppress the harmonics of the
powerline noise.
TALS: Type of anti-aliasing filter LPFR: Parameter of Low-pass/VLF filter. this is a quite complicated
part as the low-pass filter is simply an R-C circuit with a switch to connect to different capacitors. To ensure enough bandwidth (proportion to 1/RC), one should use smaller capacitors with larger ground resistance.
ACDC: AC/DC coupling (DC = 0, AC = 1; MT should always be DC) FSCV: full scaling A-D converter voltage (in unit of V) ======================================================================= note: Phoenix Legacy TBL is a straight-forward parameter-value metadata file, stored in a bizarre format. The parameter tag and value are stored in a series of 25-byte data blocks, in mixed data type: the first 12 bytes are reserved for the tag name (first 4 bytes as char). The values are stored in the 13 bytes afterwards, in various formats (char, int, float, etc.).
So a good practice is to read in those blocks one by one and extract all of them. However, not every thing is useful for the metadata, so I only extract a few of them, for now.
Original author: Hao 2012.07.04 Beijing
Translated to Python and enhanced by: J. Peacock (2025-12-31)
Main changes:
Encapsulated in MTUTable class
Automatic type detection and decoding based on TBL_TAG_TYPES
Added properties to extract metadata as mt_metadata objects
- file_path
- tbl_dict: dict[str, int | float | str | bytes]
- TBL_TAG_TYPES
- decode_tbl_value(value_bytes: bytes, data_type: str) int | float | str | bytes[source]
Decode TBL value bytes based on the specified data type.
- Parameters:
value_bytes (bytes) – 13 bytes from position 12-24 in the 25-byte block containing the value.
data_type (str) – Type of the data: ‘int’, ‘double’, ‘char’, ‘byte’, or ‘time’.
- Returns:
Decoded value in appropriate Python type. Returns raw bytes if decoding fails or data_type is unrecognized.
- Return type:
int or float or str or bytes
Examples
>>> tbl = MTUTable('/data', 'file.TBL') >>> value = tbl.decode_tbl_value(b'...', 'int') >>> print(value) 1690
- read_tbl() None[source]
Read and decode the TBL file, populating the tbl_dict attribute.
This method reads the TBL file specified during initialization and decodes all tag-value pairs according to their known types. The results are stored in self.tbl_dict.
- Returns:
Results are stored in the tbl_dict attribute.
- Return type:
None
Examples
>>> tbl = MTUTable('/data/phoenix', '1690C16C.TBL') >>> tbl.read_tbl() >>> print(tbl.tbl_dict['SITE']) '10441W10' >>> print(tbl.tbl_dict['SNUM']) 1690
- property channel_keys: dict[str, int]
Get list of channel keys present in the TBL metadata.
- Returns:
Dictionary of channel keys and their corresponding values found in tbl_dict (e.g., ‘CHEX’, ‘CHEY’, ‘CHHX’, etc.).
- Return type:
dict[str, int]
Examples
>>> tbl = MTUTable('/data', 'file.TBL') >>> tbl.read_tbl() >>> keys = tbl.channel_keys >>> print(keys) {'ex': 1, 'ey': 2, 'hx': 3, 'hy': 4, 'hz': 5}
- property survey_metadata: mt_metadata.timeseries.Survey
Extract survey metadata from TBL file.
- Returns:
mt_metadata Survey object populated with survey-level information from the TBL file (survey ID, company/author).
- Return type:
Survey
Notes
If TBL metadata has not been loaded (via read_tbl()), returns an empty Survey object with a warning.
Examples
>>> tbl = MTUTable('/data', 'file.TBL') >>> tbl.read_tbl() >>> survey = tbl.survey_metadata >>> print(survey.id) 'MT_Survey_2024'
- property station_metadata: mt_metadata.timeseries.Station
Extract station metadata from TBL file.
- Returns:
mt_metadata Station object populated with station-level information including location (latitude, longitude, elevation, declination) and time period.
- Return type:
Station
Notes
If TBL metadata has not been loaded (via read_tbl()), returns an empty Station object with a warning.
Examples
>>> tbl = MTUTable('/data', 'file.TBL') >>> tbl.read_tbl() >>> station = tbl.station_metadata >>> print(station.id) '10441W10' >>> print(f"{station.location.latitude:.6f}") 41.006467
- property run_metadata: mt_metadata.timeseries.Run
Extract run metadata from TBL file.
- Returns:
mt_metadata Run object populated with data logger information and channel metadata.
- Return type:
Run
Notes
If TBL metadata has not been loaded (via read_tbl()), returns an empty Run object with a warning.
The run includes all channel metadata (ex, ey, hx, hy, hz) obtained from their respective property methods.
Examples
>>> tbl = MTUTable('/data', 'file.TBL') >>> tbl.read_tbl() >>> run = tbl.run_metadata >>> print(run.id) 'run_1690' >>> print(run.data_logger.id) 'MTU_1690'
- property ex_metadata: mt_metadata.timeseries.Electric
Extract Ex electric channel metadata from TBL file.
- Returns:
mt_metadata Electric object for Ex component with dipole length, azimuth, AC/DC start values, and channel number.
- Return type:
Electric
Notes
If TBL metadata has not been loaded (via read_tbl()), returns an empty Electric object with a warning.
Examples
>>> tbl = MTUTable('/data', 'file.TBL') >>> tbl.read_tbl() >>> ex = tbl.ex_metadata >>> print(ex.dipole_length) 100.0
- property ey_metadata: mt_metadata.timeseries.Electric
Extract Ey electric channel metadata from TBL file.
- Returns:
mt_metadata Electric object for Ey component with dipole length, azimuth (Ex azimuth + 90°), AC/DC start values, and channel number.
- Return type:
Electric
Notes
If TBL metadata has not been loaded (via read_tbl()), returns an empty Electric object with a warning.
Examples
>>> tbl = MTUTable('/data', 'file.TBL') >>> tbl.read_tbl() >>> ey = tbl.ey_metadata >>> print(ey.dipole_length) 100.0
- property hx_metadata: mt_metadata.timeseries.Magnetic
Extract Hx magnetic channel metadata from TBL file.
- Returns:
mt_metadata Magnetic object for Hx component with maximum field, channel number, azimuth, and sensor serial number.
- Return type:
Magnetic
Notes
If TBL metadata has not been loaded (via read_tbl()), returns an empty Magnetic object with a warning.
Examples
>>> tbl = MTUTable('/data', 'file.TBL') >>> tbl.read_tbl() >>> hx = tbl.hx_metadata >>> print(hx.sensor.id) 'coil1693'
- property hy_metadata: mt_metadata.timeseries.Magnetic
Extract Hy magnetic channel metadata from TBL file.
- Returns:
mt_metadata Magnetic object for Hy component with maximum field, channel number, azimuth (Hx azimuth + 90°), and sensor serial number.
- Return type:
Magnetic
Notes
If TBL metadata has not been loaded (via read_tbl()), returns an empty Magnetic object with a warning.
Examples
>>> tbl = MTUTable('/data', 'file.TBL') >>> tbl.read_tbl() >>> hy = tbl.hy_metadata >>> print(hy.sensor.id) 'coil1694'
- property hz_metadata: mt_metadata.timeseries.Magnetic
Extract Hz magnetic channel metadata from TBL file.
- Returns:
mt_metadata Magnetic object for Hz component with maximum field, channel number, and sensor serial number.
- Return type:
Magnetic
Notes
If TBL metadata has not been loaded (via read_tbl()), returns an empty Magnetic object with a warning.
Examples
>>> tbl = MTUTable('/data', 'file.TBL') >>> tbl.read_tbl() >>> hz = tbl.hz_metadata >>> print(hz.sensor.id) 'coil1695'
- property ex_calibration: float | None
Calculate Ex channel calibration factor.
- Returns:
Calibration factor to convert raw ADC values to mV/km. Returns None if TBL metadata has not been loaded.
- Return type:
float or None
Notes
The calibration factor is calculated as:

where:
FSCV: Full-scale converter voltage
EGN: Electric channel gain
EXLN: Ex dipole length in meters
Examples
>>> tbl = MTUTable('/data', 'file.TBL') >>> tbl.read_tbl() >>> cal = tbl.ex_calibration >>> print(f"{cal:.6f}") 0.000762
- property ey_calibration: float | None
Calculate Ey channel calibration factor.
- Returns:
Calibration factor to convert raw ADC values to mV/km. Returns None if TBL metadata has not been loaded.
- Return type:
float or None
Notes
The calibration factor is calculated as:

where:
FSCV: Full-scale converter voltage
EGN: Electric channel gain
EYLN: Ey dipole length in meters
Examples
>>> tbl = MTUTable('/data', 'file.TBL') >>> tbl.read_tbl() >>> cal = tbl.ey_calibration >>> print(f"{cal:.6f}") 0.000762
- property magnetic_calibration: float | None
Calculate magnetic channel calibration factor.
- Returns:
Calibration factor to convert raw ADC values to nT. Returns None if TBL metadata has not been loaded.
- Return type:
float or None
Notes
The calibration factor is calculated as:

where:
FSCV: Full-scale converter voltage
HGN: Magnetic channel gain
HATT: Magnetic channel attenuation
HNOM: Magnetic channel normalization (mA/nT)
This calibration applies to all magnetic channels (Hx, Hy, Hz).
Examples
>>> tbl = MTUTable('/data', 'file.TBL') >>> tbl.read_tbl() >>> cal = tbl.magnetic_calibration >>> print(f"{cal:.9f}") 0.000000229
- class mth5.io.phoenix.readers.MTUTSN(file_path: str | pathlib.Path | None = None, **kwargs)[source]
Reader for legacy Phoenix MTU-5A instrument time series binary files.
Reads time series data from Phoenix MTU-5A (.TS2, .TS3, .TS4, .TS5) and V5-2000 system (.TSL, .TSH) binary files. The data consists of 24-bit signed integers organized in data blocks with headers.
- Parameters:
file_path (str or Path or None, optional) – Path to the TSN file to read. If None, the reader is created without loading data. Default is None.
- file_path
Path to the currently loaded TSN file.
- Type:
Path or None
- ts
Time series data array with shape (n_channels, n_samples).
- Type:
ndarray or None
- tag
Metadata dictionary containing file information.
- Type:
dict
Examples
Read a TS3 file:
>>> from pathlib import Path >>> reader = MTUTSN('data/1690C16C.TS3') >>> print(reader.ts.shape) (3, 86400) >>> print(reader.tag['sample_rate']) 24
Create reader without loading data:
>>> reader = MTUTSN() >>> reader.read('data/1690C16C.TS3')
Access metadata:
>>> reader = MTUTSN('data/1690C16C.TS4') >>> reader.read() >>> print(f"Channels: {reader.tag['n_ch']}") Channels: 4 >>> print(f"Blocks: {reader.tag['n_block']}") Blocks: 48
- property file_path: pathlib.Path | None
Get the TSN file path.
- ts = None
- ts_metadata = None
- get_sign24(x: numpy.ndarray | list | int) numpy.ndarray[source]
Convert unsigned 24-bit integers to signed integers.
Converts unsigned 24-bit values (0 to 16777215) to their signed equivalents (-8388608 to 8388607) by applying two’s complement.
- Parameters:
x (ndarray or list or int) – Unsigned 24-bit integer value(s) to convert.
- Returns:
Signed 24-bit integer value(s) as int32 array.
- Return type:
ndarray
Examples
Convert a single positive value:
>>> reader = MTUTSN() >>> reader.get_sign24(100) array([100], dtype=int32)
Convert a single negative value (unsigned representation):
>>> reader.get_sign24(16777215) # -1 in 24-bit signed array([-1], dtype=int32)
Convert an array:
>>> values = np.array([0, 8388607, 8388608, 16777215]) >>> reader.get_sign24(values) array([ 0, 8388607, -8388608, -1], dtype=int32)
- read(file_path: str | pathlib.Path | None = None) None[source]
Read and parse a Phoenix MTU time series binary file.
Reads complete time series data from legacy Phoenix MTU-5A instrument files (.TS2, .TS3, .TS4, .TS5) or V5-2000 system files (.TSL, .TSH). Each file contains multiple data blocks with 24-bit signed integer samples organized by channel.
- Parameters:
file_path (str or Path or None, optional) – Path to the TSN file to read. If None, uses the current file_path attribute. Default is None.
- Returns:
ts (ndarray) – Time series data array with shape (n_channels, total_samples). Data type is float64. Each row represents one channel, and each column is a time sample.
tag (dict) – Metadata dictionary containing file information with keys:
’box_number’ (int): Instrument serial number
’ts_type’ (str): Instrument type (‘MTU-5’ or ‘V5-2000’)
’sample_rate’ (int): Sampling frequency in Hz
’n_ch’ (int): Number of channels
’n_scan’ (int): Number of scans per data block
’start’ (MTime): UTC timestamp of first sample
’ts_length’ (float): Duration of each block in seconds
’n_block’ (int): Total number of data blocks in file
- Raises:
EOFError – If the file is empty or cannot be read.
ValueError – If the file has an unsupported extension or channel count.
FileNotFoundError – If the specified file does not exist.
Examples
Read a 3-channel TS3 file:
>>> reader = MTUTSN() >>> ts, tag = reader.read('data/1690C16C.TS3') >>> print(f"Shape: {ts.shape}") Shape: (3, 86400) >>> print(f"Sample rate: {tag['sample_rate']} Hz") Sample rate: 24 Hz >>> print(f"Duration: {ts.shape[1] / tag['sample_rate']:.1f} seconds") Duration: 3600.0 seconds
Read a 4-channel TS4 file:
>>> reader = MTUTSN('data/1690C16C.TS4') >>> print(f"Channels: {reader.tag['n_ch']}") Channels: 4 >>> print(f"Start time: {reader.tag['start'].isoformat()}") Start time: 2016-07-16T00:00:00+00:00
Read and process data:
>>> ts, tag = MTUTSN().read('data/station.TS5') >>> # Calculate statistics for each channel >>> for i in range(tag['n_ch']): ... print(f"Ch{i} mean: {ts[i].mean():.2f}, std: {ts[i].std():.2f}") Ch0 mean: 123.45, std: 456.78 Ch1 mean: -234.56, std: 567.89 ...
- to_runts(table_filepath: str | pathlib.Path | None = None, calibrate=True) mth5.timeseries.RunTS[source]
Create an MTUTable object from the TSN file and associated TBL file.
- Parameters:
table_filepath (str or Path) – Path to the corresponding TBL file.
- Returns:
An MTUTable object containing metadata from the TBL file.
- Return type:
Examples
>>> reader = MTUTSN('data/1690C16C.TS3') >>> mtu_table = reader.to_runts('data/1690C16C.TBL') >>> print(mtu_table.metadata) {...}