mth5.io.zen package

Submodules

mth5.io.zen.coil_response module

Read an amtant.cal file provided by Zonge.

Apparently, the file includes the 6th and 8th harmonic of the given frequency, which is a fancy way of saying f x 6 and f x 8.

class mth5.io.zen.coil_response.CoilResponse(calibration_file: str | Path | None = None, angular_frequency: bool = False)[source]

Bases: object

Read ANT4 coil calibration files from Zonge (amtant.cal).

This class parses a Zonge antenna calibration file and exposes a mt_metadata.timeseries.filters.FrequencyResponseTableFilter for a specified coil number.

Parameters:
  • calibration_file (str | Path | None, optional) – Path to the antenna calibration file. If provided the file will be read during initialization, by default None.

  • angular_frequency (bool, optional) – If True, reported frequencies will be converted to angular frequency (rad/s), by default False.

coil_calibrations[source]

Mapping of coil serial numbers to a structured numpy array containing frequency, amplitude, and phase columns.

Type:

dict[str, numpy.ndarray]

Examples

>>> from mth5.mth5.io.zen.coil_response import CoilResponse
>>> cr = CoilResponse('amtant.cal')
>>> fap = cr.get_coil_response_fap(1234)
>>> print(fap.name)
property calibration_file[source]
extrapolate(fap: FrequencyResponseTableFilter) FrequencyResponseTableFilter[source]

Extrapolate a frequency/amplitude/phase table using log-linear pads.

Parameters:

fap (FrequencyResponseTableFilter) – Frequency response object to extrapolate.

Returns:

A copy of fap with low- and high-frequency extrapolated values appended.

Return type:

FrequencyResponseTableFilter

file_exists()[source]

Check to make sure the file exists

Returns:

True if it does, False if it does not

Return type:

boolean

get_coil_response_fap(coil_number: int | str, extrapolate: bool = True) FrequencyResponseTableFilter[source]

Read an amtant.cal file provided by Zonge.

Apparently, the file includes the 6th and 8th harmonic of the given frequency, which is a fancy way of saying f * 6 and f * 8.

Parameters:

coil_number (int or string) – ANT4 4 digit serial number

Returns:

Frequency look up table

Return type:

mt_metadata.timeseries.filters.FrequencyResponseTableFilter

has_coil_number(coil_number: int | str | None) bool[source]

Test if coil number is in the antenna file

Parameters:

coil_number (int or string) – ANT4 serial number

Returns:

True if the coil is found, False if it is not

Return type:

boolean

read_antenna_file(antenna_calibration_file: str | Path | None = None) None[source]

Read a Zonge antenna calibration file and parse coil responses.

The expected file format contains blocks starting with an “antenna” header line that provides the base frequency followed by lines with coil serial number and amplitude/phase values for the 6th and 8th harmonics.

Parameters:

antenna_calibration_file (str | Path | None, optional) – Optional path to the antenna calibration file. If provided, it overrides the instance calibration_file.

Notes

Phase values in the file are expected in milliradians and are converted to radians.

mth5.io.zen.z3d_collection module

Z3DCollection

An object to hold Z3D file information to make processing easier.

Created on Sat Apr 4 12:40:40 2020

@author: peacock

class mth5.io.zen.z3d_collection.Z3DCollection(file_path: str | Path | None = None, **kwargs: Any)[source]

Bases: Collection

Collection manager for Z3D file operations and metadata processing.

This class provides functionality to handle collections of Z3D files, including metadata extraction, station information management, and dataframe creation for analysis workflows.

Parameters:
  • file_path (str or Path, optional) – Path to directory containing Z3D files, by default None

  • **kwargs (dict) – Additional keyword arguments passed to parent Collection class

station_metadata_dict[source]

Dictionary mapping station IDs to Station metadata objects

Type:

dict[str, Station]

file_ext[source]

File extension for Z3D files (“z3d”)

Type:

str

Examples

>>> zc = Z3DCollection("/path/to/z3d/files")
>>> df = zc.to_dataframe(sample_rates=[256, 4096])
>>> print(df.head())
assign_run_names(df: DataFrame, zeros: int = 3) DataFrame[source]

Assign standardized run names to dataframe based on start times.

Creates run names using the pattern ‘sr{sample_rate}_{block_number}’ where block_number is assigned sequentially based on unique start times within each station.

Parameters:
  • df (pd.DataFrame) – Input dataframe containing Z3D file information with at least ‘station’, ‘start’, and ‘sample_rate’ columns

  • zeros (int, default 3) – Number of zero-padding digits for block numbers in run names

Returns:

Modified dataframe with updated ‘run’ and ‘sequence_number’ columns assigned based on temporal ordering within each station

Return type:

pd.DataFrame

Examples

>>> zc = Z3DCollection()
>>> df = pd.DataFrame({
...     'station': ['001', '001', '002'],
...     'start': ['2022-01-01T10:00:00', '2022-01-01T12:00:00', '2022-01-01T10:00:00'],
...     'sample_rate': [256, 256, 4096]
... })
>>> df_with_runs = zc.assign_run_names(df, zeros=3)
>>> print(df_with_runs['run'].tolist())
['sr256_001', 'sr256_002', 'sr4096_001']

Notes

This method modifies the input dataframe in-place by updating the ‘run’ and ‘sequence_number’ columns. Start times are used to determine temporal ordering within each station.

get_calibrations(antenna_calibration_file: str | Path) CoilResponse[source]

Load coil calibration data from antenna calibration file.

Parameters:

antenna_calibration_file (str or Path) – Path to the antenna.cal file containing coil calibration data

Returns:

CoilResponse object containing calibration information for various coil serial numbers

Return type:

CoilResponse

Examples

>>> zc = Z3DCollection("/path/to/z3d/files")
>>> cal_obj = zc.get_calibrations("/path/to/antenna.cal")
>>> print(cal_obj.has_coil_number("2324"))
to_dataframe(sample_rates: list[int] = [256, 4096], run_name_zeros: int = 4, calibration_path: str | Path | None = None) DataFrame[source]

Extract Z3D file information and create analysis-ready dataframe.

Processes all Z3D files in the collection, extracting metadata and file information to create a comprehensive dataframe suitable for magnetotelluric data analysis workflows.

Parameters:
  • sample_rates (list of int, default [256, 4096]) – Allowed sampling rates in Hz. Files with sample rates not in this list will trigger a warning and early return

  • run_name_zeros (int, default 4) – Number of zero-padding digits for run names in dataframe sorting

  • calibration_path (str or Path, optional) – Path to antenna calibration file. If None, calibration information will not be included, by default None

Returns:

Dataframe containing Z3D file information with columns: - survey: Survey/job name from Z3D metadata - station: Station identifier - run: Automatically assigned run names based on start times - start/end: ISO format timestamps for data recording period - channel_id: Channel number from Z3D file - component: Measurement component (ex, ey, hx, hy, hz) - fn: Path to Z3D file - sample_rate: Sampling frequency in Hz - file_size: Size of Z3D file in bytes - n_samples: Number of data samples in file - sequence_number: Sequential numbering within station - dipole: Dipole length in meters (for electric channels) - coil_number: Coil serial number (for magnetic channels) - latitude/longitude/elevation: Station coordinates - instrument_id: ZEN box identifier - calibration_fn: Path to calibration file if available

Return type:

pd.DataFrame

Raises:
  • AttributeError – If Z3D files contain invalid or missing required metadata

  • FileNotFoundError – If calibration_path is specified but file doesn’t exist

Examples

>>> zc = Z3DCollection("/path/to/z3d/files")
>>> df = zc.to_dataframe(sample_rates=[256, 4096],
...                      calibration_path="/path/to/antenna.cal")
>>> print(df[['station', 'component', 'sample_rate']].head())
>>> df.to_csv("/path/output/z3d_inventory.csv")

Notes

This method also populates the station_metadata_dict attribute with consolidated station metadata derived from all processed files.

mth5.io.zen.z3d_header module

Zen Header

  • Tools for reading and writing files for Zen and processing software

  • Tools for copying data from SD cards

  • Tools for copying schedules to SD cards

Created on Tue Jun 11 10:53:23 2013 Updated August 2020 (JP)

copyright:

Jared Peacock (jpeacock@usgs.gov)

license:

MIT

class mth5.io.zen.z3d_header.Z3DHeader(fn: str | Path | None = None, fid: BinaryIO | None = None, **kwargs: Any)[source]

Bases: object

Read header information from a Z3D file and make each metadata entry an attribute.

Parameters:
  • fn (str or pathlib.Path, optional) – Full path to Z3D file.

  • fid (BinaryIO, optional) – File object (e.g., open(Z3Dfile, ‘rb’)).

  • **kwargs (dict) – Additional keyword arguments to set as attributes.

_header_len[source]

Length of header in bits (512).

Type:

int

ad_gain[source]

Gain of channel.

Type:

float or None

ad_rate[source]

Sampling rate in Hz.

Type:

float or None

alt[source]

Altitude of the station (not reliable).

Type:

float or None

attenchannelsmask[source]

Attenuation channels mask.

Type:

str or None

box_number[source]

ZEN box number.

Type:

float or None

box_serial[source]

ZEN box serial number.

Type:

str or None

channel[source]

Channel number of the file.

Type:

float or None

channelserial[source]

Serial number of the channel board.

Type:

str or None

ch_factor[source]

Channel factor (default 9.536743164062e-10).

Type:

float

channelgain[source]

Channel gain (default 1.0).

Type:

float

duty[source]

Duty cycle of the transmitter.

Type:

float or None

fid[source]

File object.

Type:

BinaryIO or None

fn[source]

Full path to Z3D file.

Type:

str or pathlib.Path or None

fpga_buildnum[source]

Build number of one of the boards.

Type:

float or None

gpsweek[source]

GPS week (default 1740).

Type:

int

header_str[source]

Full header string.

Type:

bytes or None

lat[source]

Latitude of station in degrees.

Type:

float or None

logterminal[source]

Log terminal setting.

Type:

str or None

long[source]

Longitude of the station in degrees.

Type:

float or None

main_hex_buildnum[source]

Build number of the ZEN box in hexadecimal.

Type:

float or None

numsats[source]

Number of GPS satellites.

Type:

float or None

old_version[source]

Whether this is an old version Z3D file (default False).

Type:

bool

period[source]

Period of the transmitter.

Type:

float or None

tx_duty[source]

Transmitter duty cycle.

Type:

float or None

tx_freq[source]

Transmitter frequency.

Type:

float or None

version[source]

Version of the firmware.

Type:

float or None

Examples

>>> from mth5.io.zen import Z3DHeader
>>> Z3Dfn = r"/home/mt/mt01/mt01_20150522_080000_256_EX.Z3D"
>>> header_obj = Z3DHeader(fn=Z3Dfn)
>>> header_obj.read_header()
convert_value(key_string: str, value_string: str) float | str[source]

Convert the value to the appropriate units given the key.

Converts string values to appropriate types based on the key name. Special handling is provided for latitude and longitude values, which are converted from radians to degrees with validation.

Parameters:
  • key_string (str) – The metadata key name, used to determine conversion type.

  • value_string (str) – The string value to convert.

Returns:

Converted value. Returns float for numeric values, str for non-numeric values. Latitude and longitude values are converted from radians to degrees.

Return type:

float or str

Notes

  • Attempts to convert all values to float first

  • If conversion fails, returns original string

  • For keys containing ‘lat’, ‘lon’, or ‘long’: - Converts from radians to degrees using np.rad2deg - Validates latitude range (±90°), sets to 0.0 if invalid - Validates longitude range (±180°), sets to 0.0 if invalid

Examples

>>> header = Z3DHeader()
>>> header.convert_value("version", "4147")
4147.0
>>> header.convert_value("lat", "0.706816081")  # radians
40.49757833327694  # degrees
>>> header.convert_value("channelserial", "0xD474777C")
'0xD474777C'
property data_logger: str[source]

Data logger name as ZEN{box_number}.

Returns:

Data logger name formatted as ‘ZEN’ followed by zero-padded box number.

Return type:

str

Raises:

TypeError – If box_number is None or cannot be converted to int.

read_header(fn: str | Path | None = None, fid: BinaryIO | None = None) None[source]

Read the header information into appropriate attributes.

Parses the header information from a Z3D file and populates the object’s attributes with the extracted values. Supports both modern and legacy Z3D file formats.

Parameters:
  • fn (str or pathlib.Path, optional) – Full path to Z3D file. If None, uses the instance’s fn attribute.

  • fid (BinaryIO, optional) – File object (e.g., open(Z3Dfile, ‘rb’)). If None, uses the instance’s fid attribute or opens the file specified by fn.

Raises:

UnicodeDecodeError – If header bytes cannot be decoded as text.

Notes

This method reads the first 512 bytes of the Z3D file as the header. It supports two formats:

  1. Modern format: key=value pairs separated by newlines

  2. Legacy format: comma-separated key:value pairs

The method automatically detects legacy format and sets old_version=True.

Coordinate values (lat/long) are automatically converted from radians to degrees, with validation to ensure they fall within valid ranges.

Examples

>>> header_obj = Z3DHeader()
>>> header_obj.read_header("/path/to/file.Z3D")
>>> with open("/path/to/file.Z3D", "rb") as fid:
...     header_obj.read_header(fid=fid)

mth5.io.zen.z3d_metadata module

Created on Wed Aug 24 11:35:59 2022

@author: jpeacock

class mth5.io.zen.z3d_metadata.Z3DMetadata(fn: str | Path | None = None, fid: BinaryIO | None = None, **kwargs: Any)[source]

Bases: object

Read metadata information from a Z3D file and make each metadata entry an attribute.

The attributes are left in capitalization of the Z3D file format.

Parameters:
  • fn (str or pathlib.Path, optional) – Full path to Z3D file.

  • fid (BinaryIO, optional) – File object (e.g., open(Z3Dfile, ‘rb’)).

  • **kwargs (dict) – Additional keyword arguments to set as attributes.

_header_length[source]

Length of header in bits (512).

Type:

int

_metadata_length[source]

Length of metadata blocks (512).

Type:

int

_schedule_metadata_len[source]

Length of schedule meta data (512).

Type:

int

board_cal[source]

Board calibration array with frequency, rate, amplitude, phase.

Type:

np.ndarray or None

cal_ant[source]

Antenna calibration information.

Type:

str or None

cal_board[source]

Board calibration dictionary.

Type:

dict or None

cal_ver[source]

Calibration version.

Type:

str or None

ch_azimuth[source]

Channel azimuth.

Type:

str or None

ch_cmp[source]

Channel component.

Type:

str or None

ch_length[source]

Channel length (or number of coils).

Type:

str or None

ch_number[source]

Channel number on the ZEN board.

Type:

str or None

ch_xyz1[source]

Channel xyz location.

Type:

str or None

ch_xyz2[source]

Channel xyz location.

Type:

str or None

ch_cres[source]

Channel resistance.

Type:

str or None

coil_cal[source]

Coil calibration array (frequency, amplitude, phase).

Type:

np.ndarray or None

fid[source]

File object.

Type:

BinaryIO or None

find_metadata[source]

Boolean flag for finding metadata.

Type:

bool

fn[source]

Full path to Z3D file.

Type:

str or pathlib.Path or None

gdp_operator[source]

Operator of the survey.

Type:

str or None

gdp_progver[source]

Program version.

Type:

str or None

gdp_temp[source]

GDP temperature.

Type:

str or None

gdp_volt[source]

GDP voltage.

Type:

str or None

job_by[source]

Job performed by.

Type:

str or None

job_for[source]

Job for.

Type:

str or None

job_name[source]

Job name.

Type:

str or None

job_number[source]

Job number.

Type:

str or None

line_name[source]

Survey line name.

Type:

str or None

m_tell[source]

Location in the file where the last metadata block was found.

Type:

int

notes[source]

Additional notes from metadata.

Type:

str or None

rx_aspace[source]

Electrode spacing.

Type:

str or None

rx_sspace[source]

Receiver spacing.

Type:

str or None

rx_xazimuth[source]

X azimuth of electrode.

Type:

str or None

rx_xyz0[source]

Receiver xyz coordinates.

Type:

str or None

rx_yazimuth[source]

Y azimuth of electrode.

Type:

str or None

rx_zpositive[source]

Z positive direction (default ‘down’).

Type:

str

station[source]

Station name.

Type:

str or None

survey_type[source]

Type of survey.

Type:

str or None

unit_length[source]

Length units (m).

Type:

str or None

count[source]

Counter for metadata blocks read.

Type:

int

Examples

>>> from mth5.io.zen import Z3DMetadata
>>> Z3Dfn = r"/home/mt/mt01/mt01_20150522_080000_256_EX.Z3D"
>>> header_obj = Z3DMetadata(fn=Z3Dfn)
>>> header_obj.read_metadata()
read_metadata(fn: str | Path | None = None, fid: BinaryIO | None = None) None[source]

Read metadata from Z3D file.

Parses the metadata blocks in a Z3D file and populates the object’s attributes with the extracted values. Also reads calibration data for both board and coil calibrations.

Parameters:
  • fn (str or pathlib.Path, optional) – Full path to file. If None, uses the instance’s fn attribute.

  • fid (BinaryIO, optional) – Open file object. If None, uses the instance’s fid attribute or opens the file specified by fn.

Raises:

UnicodeDecodeError – If metadata blocks cannot be decoded as text.

Notes

This method reads metadata blocks sequentially from the Z3D file, starting after the header and schedule metadata sections. It processes:

  • Standard metadata records with key=value pairs

  • Board calibration data (cal.brd format)

  • Coil calibration data (cal.ant format)

  • Calibration data blocks (caldata format)

The method automatically determines the station name from available metadata fields in the following priority: 1. line_name + rx_xyz0 (first coordinate) 2. rx_stn 3. ch_stn

mth5.io.zen.z3d_schedule module

Z3D Schedule File Parser

This module provides functionality for parsing schedule information from Z3D files. The Z3DSchedule class extracts and processes schedule metadata stored at offset 512 in Z3D files, providing access to various recording parameters and timing information.

Created on Wed Aug 24 11:24:57 2022 @author: jpeacock

class mth5.io.zen.z3d_schedule.Z3DSchedule(fn: str | Path | None = None, fid: BinaryIO | None = None, **kwargs: Any)[source]

Bases: object

Parser for Z3D file schedule information and metadata.

Reads schedule information from Z3D files and creates object attributes for each metadata entry. Schedule data is stored at byte offset 512 in Z3D files and contains recording parameters, timing information, and instrument configuration settings.

The class preserves the original capitalization from the Z3D file format and provides automatic parsing of key-value pairs in the schedule section.

Parameters:
  • fn (Union[str, Path], optional) – Full path to Z3D file to read schedule information from. Can be string path or pathlib.Path object.

  • fid (BinaryIO, optional) – Open file object for reading Z3D file in binary mode. Example: open(‘file.z3d’, ‘rb’)

  • **kwargs (Any) – Additional keyword arguments to set as object attributes.

AutoGain[source]

Auto gain setting for the recording channel [‘Y’ or ‘N’].

Type:

str or None

Comment[source]

User comments or notes for the schedule configuration.

Type:

str or None

Date[source]

Date when the schedule action was started in YYYY-MM-DD format.

Type:

str or None

Duty[source]

Duty cycle percentage of the transmitter (0-100).

Type:

str or None

FFTStacks[source]

Number of FFT stacks used by the transmitter.

Type:

str or None

Filename[source]

Original filename that the ZEN instrument assigns to the recording.

Type:

str or None

Gain[source]

Gain setting for the recording channel (e.g., ‘1.0000’).

Type:

str or None

Log[source]

Data logging enabled flag [‘Y’ or ‘N’].

Type:

str or None

NewFile[source]

Create new file for recording flag [‘Y’ or ‘N’].

Type:

str or None

Period[source]

Base period setting for the transmitter in seconds.

Type:

str or None

RadioOn[source]

Radio communication enabled flag [‘Y’, ‘N’, or ‘X’].

Type:

str or None

SR[source]

Sampling rate in Hz (originally ‘S/R’ in file, converted to ‘SR’).

Type:

str or None

SamplesPerAcq[source]

Number of samples per acquisition for transmitter mode.

Type:

str or None

Sleep[source]

Sleep mode enabled flag [‘Y’ or ‘N’].

Type:

str or None

Sync[source]

GPS synchronization enabled flag [‘Y’ or ‘N’].

Type:

str or None

Time[source]

Time when the schedule action started in HH:MM:SS format (GPS time).

Type:

str or None

initial_start[source]

Parsed start time as MTime object with GPS time flag enabled. Combines Date and Time attributes for timestamp calculation.

Type:

MTime

fn[source]

Path to the Z3D file being processed.

Type:

Union[str, Path] or None

fid[source]

File object for reading the Z3D file.

Type:

BinaryIO or None

meta_string[source]

Raw schedule metadata string read from the file.

Type:

bytes or None

_header_len[source]

Length of Z3D file header in bytes (512).

Type:

int

_schedule_metadata_len[source]

Length of schedule metadata section in bytes (512).

Type:

int

logger[source]

Loguru logger instance for debugging and status messages.

Type:

Logger

Notes

The Z3D file format stores schedule information at a fixed offset of 512 bytes from the beginning of the file. The schedule section is also 512 bytes long and contains key-value pairs in the format “Schedule.key = value”.

All schedule values are stored as strings to preserve the original format from the Z3D file. Boolean-like values use ‘Y’/’N’ convention.

The initial_start attribute automatically converts Date and Time into a GPS-corrected MTime object for accurate timestamp handling.

Examples

Read schedule from file path:

>>> from mth5.io.zen import Z3DSchedule
>>> from pathlib import Path
>>>
>>> # Using filename
>>> schedule = Z3DSchedule(fn="recording.z3d")
>>> schedule.read_schedule()
>>> print(f"Sampling rate: {schedule.SR} Hz")
>>> print(f"Start time: {schedule.initial_start}")

Read schedule from file object:

>>> with open("recording.z3d", "rb") as fid:
...     schedule = Z3DSchedule(fid=fid)
...     schedule.read_schedule()
...     print(f"Date: {schedule.Date}, Time: {schedule.Time}")
...     print(f"GPS Sync: {schedule.Sync}")

Access schedule attributes:

>>> schedule = Z3DSchedule()
>>> schedule.read_schedule(fn="recording.z3d")
>>>
>>> # Check recording configuration
>>> if schedule.Sync == 'Y':
...     print("GPS synchronization enabled")
>>> if schedule.Log == 'Y':
...     print("Data logging enabled")
>>>
>>> # Get numeric values (stored as strings)
>>> sample_rate = float(schedule.SR) if schedule.SR else 0
>>> gain_value = float(schedule.Gain) if schedule.Gain else 1.0
read_schedule(fn: str | Path | None = None, fid: BinaryIO | None = None) None[source]

Read and parse schedule metadata from Z3D file.

Reads the schedule information section from a Z3D file starting at byte offset 512 (after the header) and parses key-value pairs to populate object attributes. Automatically creates an MTime object for the initial start time using GPS time correction.

Parameters:
  • fn (Union[str, Path], optional) – Path to Z3D file to read. Overrides instance fn if provided. Can be string path or pathlib.Path object.

  • fid (BinaryIO, optional) – Open file object for reading Z3D file. Overrides instance fid if provided. Must be opened in binary mode (‘rb’).

Raises:
  • UnicodeDecodeError – If schedule metadata cannot be decoded as UTF-8 text.

  • IndexError – If schedule lines don’t match expected “Schedule.key = value” format.

  • ValueError – If Date/Time values cannot be parsed into valid MTime object.

Notes

The method performs the following steps: 1. Determines file source (fn parameter, fid parameter, or instance attributes) 2. Seeks to byte offset 512 (after Z3D header) 3. Reads 512 bytes of schedule metadata 4. Splits metadata into lines and parses key-value pairs 5. Sets object attributes for each parsed schedule entry 6. Creates MTime object from Date and Time with GPS correction

Schedule entries must follow the format “Schedule.key = value”. The “Schedule.” prefix is removed and “/” characters in keys are stripped (e.g., “S/R” becomes “SR”).

If both Date and Time are present, they are combined into an MTime object with GPS time correction applied automatically.

Examples

Read from file path:

>>> schedule = Z3DSchedule()
>>> schedule.read_schedule(fn="recording.z3d")
>>> print(f"Sampling rate: {schedule.SR}")

Read from open file object:

>>> with open("recording.z3d", "rb") as fid:
...     schedule = Z3DSchedule()
...     schedule.read_schedule(fid=fid)
...     print(f"GPS sync: {schedule.Sync}")

Read using instance attributes:

>>> schedule = Z3DSchedule(fn="recording.z3d")
>>> schedule.read_schedule()  # Uses instance fn
>>> print(f"Start time: {schedule.initial_start}")

mth5.io.zen.zen module

Zen

  • Tools for reading and writing files for Zen and processing software

  • Tools for copying data from SD cards

  • Tools for copying schedules to SD cards

Created on Tue Jun 11 10:53:23 2013 Updated August 2020 (JP)

copyright:

Jared Peacock (jpeacock@usgs.gov)

license:

MIT

class mth5.io.zen.zen.Z3D(fn: str | Path | None = None, **kwargs: Any)[source]

Bases: object

A class for reading and processing Z3D files output by Zen data loggers.

This class handles the parsing of Z3D binary files which contain GPS-stamped time series data from magnetotelluric measurements. It provides methods for reading file headers, metadata, schedule information, and time series data, as well as converting between different units and formats.

Parameters:
  • fn (str or Path, optional) – Full path to the .Z3D file to be read. Default is None.

  • **kwargs (dict) –

    Additional keyword arguments including: - stamp_len : int, default 64

    GPS stamp length in bits

fn[source]

Path to the Z3D file

Type:

Path or None

calibration_fn[source]

Path to calibration file

Type:

str or None

header[source]

Header information object

Type:

Z3DHeader

schedule[source]

Schedule information object

Type:

Z3DSchedule

metadata[source]

Metadata information object

Type:

Z3DMetadata

gps_stamps[source]

Array of GPS time stamps

Type:

numpy.ndarray or None

time_series[source]

Time series data array

Type:

numpy.ndarray or None

sample_rate[source]

Data sampling rate in Hz

Type:

float or None

units[source]

Data units, default ‘counts’

Type:

str

Notes

GPS data type is formatted as:

numpy.dtype([('flag0', numpy.int32),
             ('flag1', numpy.int32),
             ('time', numpy.int32),
             ('lat', numpy.float64),
             ('lon', numpy.float64),
             ('num_sat', numpy.int32),
             ('gps_sens', numpy.int32),
             ('temperature', numpy.float32),
             ('voltage', numpy.float32),
             ('num_fpga', numpy.int32),
             ('num_adc', numpy.int32),
             ('pps_count', numpy.int32),
             ('dac_tune', numpy.int32),
             ('block_len', numpy.int32)])

Examples

>>> from mth5.io.zen import Z3D
>>> z3d = Z3D(r"/path/to/data/station_20150522_080000_256_EX.Z3D")
>>> z3d.read_z3d()
>>> print(f"Found {z3d.gps_stamps.shape[0]} GPS time stamps")
>>> print(f"Found {z3d.time_series.size} data points")
property azimuth: float | None[source]

Get the azimuth of instrument setup.

Returns:

Azimuth angle in degrees from north, or None if not available.

Return type:

float or None

property channel_metadata[source]

Generate Channel metadata object from Z3D file information.

Creates either an Electric or Magnetic metadata object based on the component type, populated with channel-specific parameters, sensor information, and data statistics.

Returns:

Channel metadata object appropriate for the measurement type: - Electric: includes dipole length, AC/DC statistics - Magnetic: includes sensor details, field min/max values

Return type:

Electric or Magnetic

Notes

Electric channels (ex, ey) get dipole length and voltage statistics. Magnetic channels (hx, hy, hz) get sensor information and field strength statistics computed from the first and last seconds of data.

Examples

>>> z3d = Z3D("/path/to/file.Z3D")
>>> z3d.read_z3d()
>>> ch_meta = z3d.channel_metadata
>>> print(f"Channel component: {ch_meta.component}")
property channel_number: int[source]

Get the channel number.

Returns:

Channel number identifier. Maps component names to standard channel numbers or uses metadata channel number.

Return type:

int

property channel_response[source]

Generate comprehensive channel response for the Z3D data.

Creates a ChannelResponse object containing all applicable filters including coil response, dipole conversion, and counts-to-milliVolt transformation.

Returns:

Channel response object with appropriate filter chain for converting raw Z3D data to physical units.

Return type:

ChannelResponse

Notes

The filter chain includes: - Coil response (for magnetic channels) or dipole filter (for electric) - Counts to milliVolt conversion filter

check_start_time() MTime[source]

Validate scheduled start time against first GPS stamp.

Compare the scheduled start time from the file header with the actual first GPS timestamp to identify timing discrepancies.

Returns:

UTC start time from the first valid GPS stamp.

Return type:

MTime

Notes

Logs warnings if the difference exceeds the maximum allowed time difference (default 20 seconds).

property coil_number: str | None[source]

Get the coil number identifier.

Returns:

Coil antenna number identifier, or None if not available.

Return type:

str or None

property coil_response[source]

Make the coile response into a FAP filter

Phase must be in radians

property component: str[source]

Get the channel component identifier.

Returns:

Channel component name in lowercase (e.g., ‘ex’, ‘hy’, ‘hz’).

Return type:

str

convert_counts_to_mv(data: ndarray) ndarray[source]

Convert time series data from counts to milliVolt.

Parameters:

data (numpy.ndarray) – Time series data in digital counts.

Returns:

Time series data converted to milliVolt.

Return type:

numpy.ndarray

convert_gps_time() None[source]

Convert GPS time integers to floating point seconds.

Transform GPS time from integer format to float and convert from GPS time units to seconds relative to the GPS week.

Notes

GPS time is initially stored as integers in units of 1/1024 seconds. This method converts to floating point seconds and applies the necessary scaling factors.

convert_mv_to_counts(data: ndarray) ndarray[source]

Convert time series data from milliVolt to counts.

Parameters:

data (numpy.ndarray) – Time series data in milliVolt.

Returns:

Time series data converted to digital counts.

Return type:

numpy.ndarray

Notes

Assumes no other scaling has been applied to the data.

property counts2mv_filter[source]

Create a counts to milliVolt coefficient filter.

Generate a coefficient filter for converting digital counts to milliVolt using the channel factor from the Z3D file header.

Returns:

Filter object configured for counts to milliVolt conversion with gain set to the inverse of the channel factor.

Return type:

CoefficientFilter

Notes

The gain is set to 1/channel_factor because this represents the inverse operation when the instrument response has been divided from the data during processing.

Examples

>>> z3d = Z3D("/path/to/file.Z3D")
>>> z3d.read_all_info()
>>> filter_obj = z3d.counts2mv_filter
>>> print(f"Conversion gain: {filter_obj.gain}")
property dipole_filter[source]

Create dipole conversion filter for electric field measurements.

Generate a coefficient filter for converting electric field measurements from milliVolt per kilometer to milliVolt using the dipole length.

Returns:

Filter object for dipole conversion if dipole_length is non-zero, None otherwise.

Return type:

CoefficientFilter or None

Notes

The gain is set to dipole_length/1000 to convert from mV/km to mV. This represents the physical dipole length scaling for electric field measurements.

Examples

>>> z3d = Z3D("/path/to/electric.Z3D")
>>> z3d.read_all_info()
>>> if z3d.dipole_filter is not None:
...     print(f"Dipole length: {z3d.dipole_length} m")
property dipole_length: float[source]

Get the dipole length for electric field measurements.

Returns:

Dipole length in meters. Calculated from electrode positions if not directly specified in metadata. Returns 0 for magnetic channels or if positions are not available.

Return type:

float

Notes

Length is calculated from xyz coordinates using Euclidean distance formula when position data is available in metadata.

property elevation: float | None[source]

Get the elevation in meters.

Returns:

Elevation above sea level in meters, or None if not available.

Return type:

float or None

property end: MTime | float[source]

Get the end time of the data.

Returns:

End time from GPS stamps if available, otherwise calculated from start time and number of samples.

Return type:

MTime or float

property file_size: int[source]

Get the size of the Z3D file in bytes.

Returns:

File size in bytes, or 0 if no file is set.

Return type:

int

property fn: Path | None[source]

Get the Z3D file path.

Returns:

Path to the Z3D file, or None if not set.

Return type:

Path or None

get_UTC_date_time(gps_week: int, gps_time: float) MTime[source]

Convert GPS week and time to UTC datetime.

Calculate the actual UTC date and time of measurement from GPS week number and seconds within that week.

Parameters:
  • gps_week (int) – GPS week number when data was collected.

  • gps_time (float) – Number of seconds from beginning of GPS week.

Returns:

UTC datetime object for the measurement time.

Return type:

MTime

Notes

Automatically handles GPS time rollover when seconds exceed one week (604800 seconds).

get_gps_stamp_index(ts_data: ndarray, old_version: bool = False) list[int][source]

Locate GPS time stamp indices in time series data.

Searches for GPS flag patterns in the data array. For newer files, verifies that flag_1 follows flag_0.

Parameters:
  • ts_data (numpy.ndarray) – Time series data array containing GPS stamps.

  • old_version (bool, default False) – If True, only searches for single GPS flag (old format). If False, validates flag pairs (new format).

Returns:

List of indices where GPS stamps are located.

Return type:

list of int

get_gps_time(gps_int: int, gps_week: int = 0) tuple[float, int][source]

Convert GPS integer timestamp to seconds and GPS week.

Parameters:
  • gps_int (int) – Integer from the GPS time stamp line.

  • gps_week (int, default 0) – Relative GPS week. If seconds exceed one week, this is incremented.

Returns:

GPS time in seconds from beginning of GPS week, and updated GPS week.

Return type:

tuple[float, int]

Notes

GPS integers are in units of 1/1024 seconds. This method handles week rollovers when seconds exceed 604800.

property latitude: float | None[source]

Get the latitude in decimal degrees.

Returns:

Latitude coordinate in decimal degrees, or None if not available.

Return type:

float or None

property longitude: float | None[source]

Get the longitude in decimal degrees.

Returns:

Longitude coordinate in decimal degrees, or None if not available.

Return type:

float or None

property n_samples: int[source]

Get the number of data samples in the file.

Returns:

Number of data samples. Calculated from file size if time_series is not loaded, otherwise returns the actual array size.

Return type:

int

Notes

Calculation assumes 4 bytes per sample and accounts for metadata blocks. If sample_rate is available, adds buffer for GPS stamps.

read_all_info() None[source]

Read header, schedule, and metadata from Z3D file.

Convenience method to read all file information in one call. Opens the file once and reads all sections sequentially.

Raises:

FileNotFoundError – If the Z3D file does not exist.

read_z3d(z3d_fn: str | Path | None = None) None[source]

Read and parse Z3D file data.

Comprehensive method to read a Z3D file and populate all object attributes. Performs the following operations:

  1. Read file as chunks of 32-bit integers

  2. Extract and validate GPS stamps

  3. Check GPS time stamp consistency (1 second intervals)

  4. Verify data block lengths match sampling rate

  5. Convert GPS time to seconds relative to GPS week

  6. Skip initial buffered data (first 2 seconds)

  7. Populate time series array with non-zero data

Parameters:

z3d_fn (str, Path, or None, optional) – Path to Z3D file to read. If None, uses current fn attribute.

Raises:

ZenGPSError – If data is too short or GPS timing issues prevent parsing.

Examples

>>> z3d = Z3D(r"/path/to/data/station_20150522_080000_256_EX.Z3D")
>>> z3d.read_z3d()
>>> print(f"Read {z3d.time_series.size} data points")
property run_metadata[source]

Generate Run metadata object from Z3D file information.

Creates a Run metadata object populated with data logger information, timing details, and measurement parameters extracted from the Z3D file.

Returns:

Run metadata object with populated fields including data logger details, sample rate, time period, and data type information.

Return type:

Run

Examples

>>> z3d = Z3D("/path/to/file.Z3D")
>>> z3d.read_all_info()
>>> run_meta = z3d.run_metadata
>>> print(f"Sample rate: {run_meta.sample_rate}")
property sample_rate: float | None[source]

Get the sampling rate in Hz.

Returns:

Data sampling rate in samples per second, or None if not available.

Return type:

float or None

property start: MTime[source]

Get the start time of the data.

Returns:

Start time from GPS stamps if available, otherwise scheduled time.

Return type:

MTime

property station: str | None[source]

Get the station name.

Returns:

Station identifier name.

Return type:

str or None

property station_metadata[source]

Generate Station metadata object from Z3D file information.

Creates a Station metadata object populated with location and timing information extracted from the Z3D file header and metadata.

Returns:

Station metadata object with populated fields including station ID, coordinates, elevation, time period, and operator information.

Return type:

Station

Examples

>>> z3d = Z3D("/path/to/file.Z3D")
>>> z3d.read_all_info()
>>> station_meta = z3d.station_metadata
>>> print(station_meta.id)
to_channelts() ChannelTS[source]

Convert Z3D data to ChannelTS time series object.

Create a ChannelTS object populated with the time series data and all associated metadata from the Z3D file.

Returns:

Time series object with data, metadata, and instrument response.

Return type:

ChannelTS

trim_data() None[source]

Trim the first 2 seconds of data due to SD buffer issues.

Remove the first 2 GPS stamps and corresponding time series data to account for SD card buffering artifacts in early data.

Notes

This method may be deprecated after field testing confirms the buffer behavior is consistent across all instruments.

Deprecated since version This: method will be deprecated after field testing.

validate_gps_time() bool[source]

Validate that GPS time stamps are consistently 1 second apart.

Returns:

True if all GPS stamps are properly spaced, False otherwise.

Return type:

bool

Notes

Logs debug information for any stamps that are more than 1 second apart.

validate_time_blocks() bool[source]

Validate GPS time stamps and verify data block lengths.

Check that each GPS stamp block contains the expected number of data points (should equal sample rate for 1-second blocks).

Returns:

True if all blocks have correct length, False otherwise.

Return type:

bool

Notes

If bad blocks are detected near the beginning (index < 5), this method will automatically skip those blocks and trim the time series data accordingly.

property zen_response[source]

Zen response, not sure the full calibration comes directly from the Z3D file, so skipping for now. Will have to read a Zen##.cal file to get the full calibration. This shouldn’t be a big issue cause it should roughly be the same for all channels and since the TF is computing the ratio they will cancel out. Though we should look more into this if just looking at calibrate time series.

property zen_schedule: MTime[source]

Get the zen schedule date and time.

Returns:

Scheduled start time from header or schedule object.

Return type:

MTime

exception mth5.io.zen.zen.ZenGPSError[source]

Bases: Exception

Exception raised for GPS timing errors in Z3D files.

exception mth5.io.zen.zen.ZenInputFileError[source]

Bases: Exception

Exception raised for Z3D file input/reading errors.

exception mth5.io.zen.zen.ZenSamplingRateError[source]

Bases: Exception

Exception raised for sampling rate inconsistencies.

mth5.io.zen.zen.read_z3d(fn: str | Path, calibration_fn: str | Path | None = None, logger_file_handler: Any | None = None) ChannelTS | None[source]

Read a Z3D file and return a ChannelTS object.

Convenience function to read Z3D files with error handling.

Parameters:
  • fn (str or Path) – Path to the Z3D file to read.

  • calibration_fn (str, Path, or None, optional) – Path to calibration file. Default is None.

  • logger_file_handler (optional) – Logger file handler to add to Z3D logger. Default is None.

Returns:

Time series object if successful, None if GPS timing errors occur.

Return type:

ChannelTS or None

Examples

>>> ts = read_z3d("/path/to/data/station_EX.Z3D")
>>> if ts is not None:
...     print(f"Read {ts.n_samples} samples")

mth5.io.zen.zen_tools module

Created on Tue Apr 18 15:40:28 2023

@author: jpeacock

class mth5.io.zen.zen_tools.ZenSchedule[source]

Bases: object

deals with reading, writing and copying schedule Creates a repeating schedule based on the master_schedule. It will then change the first scheduling action to coincide with the master schedule, such that all deployed boxes will have the same schedule. :Example:

>>> import mtpy.usgs.zen as zen
>>> zs = zen.ZenSchedule()
>>> zs.write_schedule('MT01', dt_offset='2013-06-23,04:00:00')

Attributes

Description

ch_cmp_dict

dictionary for channel components with keys being the channel number and values being the channel label

ch_num_dict

dictionary for channel components whith keys being channel label and values being channel number

df_list

sequential list of sampling rates to repeat in

schedule

df_time_list

sequential list of time intervals to measure for

each corresponding sampling rate

dt_format

date and time format. default is YYY-MM-DD,hh:mm:ss

dt_offset

start date and time of schedule in dt_format

gain_dict

dictionary of gain values for channel number

initial_dt

initial date, or dummy zero date for scheduling

light_dict

dictionary of light color values for schedule

master_schedule

the schedule that all data loggers should schedule at. Will taylor the schedule to match the master schedule according to dt_offset

meta_dict

dictionary for meta data

meta_keys

keys for meta data dictionary

sa_keys

keys for schedule actions

sa_list

list of schedule actions including time and df

sr_dict

dictionary of sampling rate values

verbose

[ True | False ] True to print information to console

add_time(date_time, add_minutes=0, add_seconds=0, add_hours=0, add_days=0)[source]

add time to a time string assuming date_time is in the format YYYY-MM-DD,HH:MM:SS

get_schedule_offset(time_offset, schedule_time_list)[source]

gets the offset in time from master schedule list and time_offset so that all schedules will record at the same time according to master schedule list schedule_time_list Attributes: ———–

time_offsethh:mm:ss

the time offset given to the zen reciever

schedule_time_listlist

list of actual schedule times returned from make_schedule

Returns:

s1dictionary
dictionary with keys:
  • ‘dt’ –> date and time of offset from next schedule

    event from schedule_time_list

  • ‘df’ –> sampling rate of that event

make_schedule(df_list, df_length_list, repeat=5, t1_dict=None)[source]

make a repeated schedule given list of sampling frequencies and duration for each. Arguments: ———–

df_listlist

list of sampling frequencies in Hz, note needs to be powers of 2 starting at 256

df_length_listlist

list of durations in hh:mm:ss format

repeatint

number of times to repeat the sequence

t1_dictdictionary

dictionary returned from get_schedule_offset

Returns:

time_list: list of dictionaries with keys:
  • ‘dt’ –> date and time of schedule event

  • ‘df’ –> sampling rate for that event

write_schedule_for_gui(zen_start=None, df_list=None, df_time_list=None, repeat=8, gain=0, save_path=None, schedule_fn='zen_schedule.MTsch', version=4)[source]

write a zen schedule file Note: for the older boxes use ‘Zeus3Ini.cfg’ for the savename Arguments: ———-

zen_starthh:mm:ss

start time you want the zen to start collecting data. if this is none then current time on computer is used. In UTC Time Note: this will shift the starting point to

match the master schedule, so that all stations have the same schedule.

df_listlist

list of sampling rates in Hz

df_time_listlist

list of time intervals corresponding to df_list in hh:mm:ss format

repeatint

number of time to repeat the cycle of df_list

gainint

gain on instrument, 2 raised to this number.

Returns:

  • writes a schedule file to input into the ZenAcq Gui

mth5.io.zen.zen_tools.copy_from_sd(station, save_path='d:\\Peacock\\MTData', channel_dict={'1': 'HX', '2': 'HY', '3': 'HZ', '4': 'EX', '5': 'EY', '6': 'HZ'}, copy_date=None, copy_type='all')[source]

copy files from sd cards into a common folder (save_path) do not put an underscore in station, causes problems at the moment Arguments: ———–

stationstring

full name of station from which data is being saved

save_pathstring

full path to save data to

channel_dictdictionary

keys are the channel numbers as strings and the values are the component that corresponds to that channel, values are placed in upper case in the code

copy_dateYYYY-MM-DD

date to copy from depending on copy_type

copy_type[ ‘all’ | ‘before’ | ‘after’ | ‘on’ ]
  • ‘all’ –> copy all files on the SD card

  • ‘before’ –> copy files before and on this date

  • ‘after’ –> copy files on and after this date

  • ‘on’ –> copy files on this date only

Outputs:

fn_listlist

list of filenames copied to save_path

Example:

:: >>> import mtpy.usgs.zen as zen >>> fn_list = zen.copy_from_sd(‘mt01’, save_path=r”/home/mt/survey_1”)

mth5.io.zen.zen_tools.delete_files_from_sd(delete_date=None, delete_type=None, delete_folder='d:\\Peacock\\MTData\\Deleted', verbose=True)[source]

delete files from sd card, if delete_date is not None, anything on this date and before will be deleted. Deletes just .Z3D files, leaves zenini.cfg Agruments: ———–

delete_dateYYYY-MM-DD

date to delete files from

delete_type[ ‘all’ | ‘before’ | ‘after’ | ‘on’ ]
  • ‘all’ –> delete all files on sd card

  • ‘before’ –> delete files on and before delete_date

  • ‘after’ –> delete files on and after delete_date

  • ‘on’ –> delete files on delete_date

delete_folderstring

full path to a folder where files will be moved to just in case. If None, files will be deleted for ever.

Returns:

delete_fn_listlist

list of deleted files.

Example:

:: >>> import mtpy.usgs.zen as zen >>> # Delete all files before given date, forever. >>> zen.delete_files_from_sd(delete_date=’2004/04/20’,

delete_type=’before’, delete_folder=None)

>>> # Delete all files into a folder just in case
>>> zen.delete_files_from_sd(delete_type='all',
                             delete_folder=r"/home/mt/deleted_files")
mth5.io.zen.zen_tools.get_drive_names()[source]

get a list of drive names detected assuming the cards are names by box and channel. Outputs: ———-

drive_dictdictionary

keys are the drive letters and values are the drive names

Example:

:: >>> import mtpy.usgs.zen as zen >>> zen.get_drives_names()

mth5.io.zen.zen_tools.get_drives()[source]

get a list of logical drives detected on the machine Note this only works for windows. Outputs: ———-

drives : list of drives as letters

Example:

:: >>> import mtpy.usgs.zen as zen >>> zen.get_drives()

mth5.io.zen.zen_tools.split_station(station)[source]

split station name into name and number

Module contents

class mth5.io.zen.CoilResponse(calibration_file: str | Path | None = None, angular_frequency: bool = False)[source]

Bases: object

Read ANT4 coil calibration files from Zonge (amtant.cal).

This class parses a Zonge antenna calibration file and exposes a mt_metadata.timeseries.filters.FrequencyResponseTableFilter for a specified coil number.

Parameters:
  • calibration_file (str | Path | None, optional) – Path to the antenna calibration file. If provided the file will be read during initialization, by default None.

  • angular_frequency (bool, optional) – If True, reported frequencies will be converted to angular frequency (rad/s), by default False.

coil_calibrations

Mapping of coil serial numbers to a structured numpy array containing frequency, amplitude, and phase columns.

Type:

dict[str, numpy.ndarray]

Examples

>>> from mth5.mth5.io.zen.coil_response import CoilResponse
>>> cr = CoilResponse('amtant.cal')
>>> fap = cr.get_coil_response_fap(1234)
>>> print(fap.name)
property calibration_file
extrapolate(fap: FrequencyResponseTableFilter) FrequencyResponseTableFilter[source]

Extrapolate a frequency/amplitude/phase table using log-linear pads.

Parameters:

fap (FrequencyResponseTableFilter) – Frequency response object to extrapolate.

Returns:

A copy of fap with low- and high-frequency extrapolated values appended.

Return type:

FrequencyResponseTableFilter

file_exists()[source]

Check to make sure the file exists

Returns:

True if it does, False if it does not

Return type:

boolean

get_coil_response_fap(coil_number: int | str, extrapolate: bool = True) FrequencyResponseTableFilter[source]

Read an amtant.cal file provided by Zonge.

Apparently, the file includes the 6th and 8th harmonic of the given frequency, which is a fancy way of saying f * 6 and f * 8.

Parameters:

coil_number (int or string) – ANT4 4 digit serial number

Returns:

Frequency look up table

Return type:

mt_metadata.timeseries.filters.FrequencyResponseTableFilter

has_coil_number(coil_number: int | str | None) bool[source]

Test if coil number is in the antenna file

Parameters:

coil_number (int or string) – ANT4 serial number

Returns:

True if the coil is found, False if it is not

Return type:

boolean

read_antenna_file(antenna_calibration_file: str | Path | None = None) None[source]

Read a Zonge antenna calibration file and parse coil responses.

The expected file format contains blocks starting with an “antenna” header line that provides the base frequency followed by lines with coil serial number and amplitude/phase values for the 6th and 8th harmonics.

Parameters:

antenna_calibration_file (str | Path | None, optional) – Optional path to the antenna calibration file. If provided, it overrides the instance calibration_file.

Notes

Phase values in the file are expected in milliradians and are converted to radians.

class mth5.io.zen.Z3D(fn: str | Path | None = None, **kwargs: Any)[source]

Bases: object

A class for reading and processing Z3D files output by Zen data loggers.

This class handles the parsing of Z3D binary files which contain GPS-stamped time series data from magnetotelluric measurements. It provides methods for reading file headers, metadata, schedule information, and time series data, as well as converting between different units and formats.

Parameters:
  • fn (str or Path, optional) – Full path to the .Z3D file to be read. Default is None.

  • **kwargs (dict) –

    Additional keyword arguments including: - stamp_len : int, default 64

    GPS stamp length in bits

fn

Path to the Z3D file

Type:

Path or None

calibration_fn

Path to calibration file

Type:

str or None

header

Header information object

Type:

Z3DHeader

schedule

Schedule information object

Type:

Z3DSchedule

metadata

Metadata information object

Type:

Z3DMetadata

gps_stamps

Array of GPS time stamps

Type:

numpy.ndarray or None

time_series

Time series data array

Type:

numpy.ndarray or None

sample_rate

Data sampling rate in Hz

Type:

float or None

units

Data units, default ‘counts’

Type:

str

Notes

GPS data type is formatted as:

numpy.dtype([('flag0', numpy.int32),
             ('flag1', numpy.int32),
             ('time', numpy.int32),
             ('lat', numpy.float64),
             ('lon', numpy.float64),
             ('num_sat', numpy.int32),
             ('gps_sens', numpy.int32),
             ('temperature', numpy.float32),
             ('voltage', numpy.float32),
             ('num_fpga', numpy.int32),
             ('num_adc', numpy.int32),
             ('pps_count', numpy.int32),
             ('dac_tune', numpy.int32),
             ('block_len', numpy.int32)])

Examples

>>> from mth5.io.zen import Z3D
>>> z3d = Z3D(r"/path/to/data/station_20150522_080000_256_EX.Z3D")
>>> z3d.read_z3d()
>>> print(f"Found {z3d.gps_stamps.shape[0]} GPS time stamps")
>>> print(f"Found {z3d.time_series.size} data points")
property azimuth: float | None

Get the azimuth of instrument setup.

Returns:

Azimuth angle in degrees from north, or None if not available.

Return type:

float or None

property channel_metadata

Generate Channel metadata object from Z3D file information.

Creates either an Electric or Magnetic metadata object based on the component type, populated with channel-specific parameters, sensor information, and data statistics.

Returns:

Channel metadata object appropriate for the measurement type: - Electric: includes dipole length, AC/DC statistics - Magnetic: includes sensor details, field min/max values

Return type:

Electric or Magnetic

Notes

Electric channels (ex, ey) get dipole length and voltage statistics. Magnetic channels (hx, hy, hz) get sensor information and field strength statistics computed from the first and last seconds of data.

Examples

>>> z3d = Z3D("/path/to/file.Z3D")
>>> z3d.read_z3d()
>>> ch_meta = z3d.channel_metadata
>>> print(f"Channel component: {ch_meta.component}")
property channel_number: int

Get the channel number.

Returns:

Channel number identifier. Maps component names to standard channel numbers or uses metadata channel number.

Return type:

int

property channel_response

Generate comprehensive channel response for the Z3D data.

Creates a ChannelResponse object containing all applicable filters including coil response, dipole conversion, and counts-to-milliVolt transformation.

Returns:

Channel response object with appropriate filter chain for converting raw Z3D data to physical units.

Return type:

ChannelResponse

Notes

The filter chain includes: - Coil response (for magnetic channels) or dipole filter (for electric) - Counts to milliVolt conversion filter

check_start_time() MTime[source]

Validate scheduled start time against first GPS stamp.

Compare the scheduled start time from the file header with the actual first GPS timestamp to identify timing discrepancies.

Returns:

UTC start time from the first valid GPS stamp.

Return type:

MTime

Notes

Logs warnings if the difference exceeds the maximum allowed time difference (default 20 seconds).

property coil_number: str | None

Get the coil number identifier.

Returns:

Coil antenna number identifier, or None if not available.

Return type:

str or None

property coil_response

Make the coile response into a FAP filter

Phase must be in radians

property component: str

Get the channel component identifier.

Returns:

Channel component name in lowercase (e.g., ‘ex’, ‘hy’, ‘hz’).

Return type:

str

convert_counts_to_mv(data: ndarray) ndarray[source]

Convert time series data from counts to milliVolt.

Parameters:

data (numpy.ndarray) – Time series data in digital counts.

Returns:

Time series data converted to milliVolt.

Return type:

numpy.ndarray

convert_gps_time() None[source]

Convert GPS time integers to floating point seconds.

Transform GPS time from integer format to float and convert from GPS time units to seconds relative to the GPS week.

Notes

GPS time is initially stored as integers in units of 1/1024 seconds. This method converts to floating point seconds and applies the necessary scaling factors.

convert_mv_to_counts(data: ndarray) ndarray[source]

Convert time series data from milliVolt to counts.

Parameters:

data (numpy.ndarray) – Time series data in milliVolt.

Returns:

Time series data converted to digital counts.

Return type:

numpy.ndarray

Notes

Assumes no other scaling has been applied to the data.

property counts2mv_filter

Create a counts to milliVolt coefficient filter.

Generate a coefficient filter for converting digital counts to milliVolt using the channel factor from the Z3D file header.

Returns:

Filter object configured for counts to milliVolt conversion with gain set to the inverse of the channel factor.

Return type:

CoefficientFilter

Notes

The gain is set to 1/channel_factor because this represents the inverse operation when the instrument response has been divided from the data during processing.

Examples

>>> z3d = Z3D("/path/to/file.Z3D")
>>> z3d.read_all_info()
>>> filter_obj = z3d.counts2mv_filter
>>> print(f"Conversion gain: {filter_obj.gain}")
property dipole_filter

Create dipole conversion filter for electric field measurements.

Generate a coefficient filter for converting electric field measurements from milliVolt per kilometer to milliVolt using the dipole length.

Returns:

Filter object for dipole conversion if dipole_length is non-zero, None otherwise.

Return type:

CoefficientFilter or None

Notes

The gain is set to dipole_length/1000 to convert from mV/km to mV. This represents the physical dipole length scaling for electric field measurements.

Examples

>>> z3d = Z3D("/path/to/electric.Z3D")
>>> z3d.read_all_info()
>>> if z3d.dipole_filter is not None:
...     print(f"Dipole length: {z3d.dipole_length} m")
property dipole_length: float

Get the dipole length for electric field measurements.

Returns:

Dipole length in meters. Calculated from electrode positions if not directly specified in metadata. Returns 0 for magnetic channels or if positions are not available.

Return type:

float

Notes

Length is calculated from xyz coordinates using Euclidean distance formula when position data is available in metadata.

property elevation: float | None

Get the elevation in meters.

Returns:

Elevation above sea level in meters, or None if not available.

Return type:

float or None

property end: MTime | float

Get the end time of the data.

Returns:

End time from GPS stamps if available, otherwise calculated from start time and number of samples.

Return type:

MTime or float

property file_size: int

Get the size of the Z3D file in bytes.

Returns:

File size in bytes, or 0 if no file is set.

Return type:

int

property fn: Path | None

Get the Z3D file path.

Returns:

Path to the Z3D file, or None if not set.

Return type:

Path or None

get_UTC_date_time(gps_week: int, gps_time: float) MTime[source]

Convert GPS week and time to UTC datetime.

Calculate the actual UTC date and time of measurement from GPS week number and seconds within that week.

Parameters:
  • gps_week (int) – GPS week number when data was collected.

  • gps_time (float) – Number of seconds from beginning of GPS week.

Returns:

UTC datetime object for the measurement time.

Return type:

MTime

Notes

Automatically handles GPS time rollover when seconds exceed one week (604800 seconds).

get_gps_stamp_index(ts_data: ndarray, old_version: bool = False) list[int][source]

Locate GPS time stamp indices in time series data.

Searches for GPS flag patterns in the data array. For newer files, verifies that flag_1 follows flag_0.

Parameters:
  • ts_data (numpy.ndarray) – Time series data array containing GPS stamps.

  • old_version (bool, default False) – If True, only searches for single GPS flag (old format). If False, validates flag pairs (new format).

Returns:

List of indices where GPS stamps are located.

Return type:

list of int

get_gps_time(gps_int: int, gps_week: int = 0) tuple[float, int][source]

Convert GPS integer timestamp to seconds and GPS week.

Parameters:
  • gps_int (int) – Integer from the GPS time stamp line.

  • gps_week (int, default 0) – Relative GPS week. If seconds exceed one week, this is incremented.

Returns:

GPS time in seconds from beginning of GPS week, and updated GPS week.

Return type:

tuple[float, int]

Notes

GPS integers are in units of 1/1024 seconds. This method handles week rollovers when seconds exceed 604800.

property latitude: float | None

Get the latitude in decimal degrees.

Returns:

Latitude coordinate in decimal degrees, or None if not available.

Return type:

float or None

property longitude: float | None

Get the longitude in decimal degrees.

Returns:

Longitude coordinate in decimal degrees, or None if not available.

Return type:

float or None

property n_samples: int

Get the number of data samples in the file.

Returns:

Number of data samples. Calculated from file size if time_series is not loaded, otherwise returns the actual array size.

Return type:

int

Notes

Calculation assumes 4 bytes per sample and accounts for metadata blocks. If sample_rate is available, adds buffer for GPS stamps.

read_all_info() None[source]

Read header, schedule, and metadata from Z3D file.

Convenience method to read all file information in one call. Opens the file once and reads all sections sequentially.

Raises:

FileNotFoundError – If the Z3D file does not exist.

read_z3d(z3d_fn: str | Path | None = None) None[source]

Read and parse Z3D file data.

Comprehensive method to read a Z3D file and populate all object attributes. Performs the following operations:

  1. Read file as chunks of 32-bit integers

  2. Extract and validate GPS stamps

  3. Check GPS time stamp consistency (1 second intervals)

  4. Verify data block lengths match sampling rate

  5. Convert GPS time to seconds relative to GPS week

  6. Skip initial buffered data (first 2 seconds)

  7. Populate time series array with non-zero data

Parameters:

z3d_fn (str, Path, or None, optional) – Path to Z3D file to read. If None, uses current fn attribute.

Raises:

ZenGPSError – If data is too short or GPS timing issues prevent parsing.

Examples

>>> z3d = Z3D(r"/path/to/data/station_20150522_080000_256_EX.Z3D")
>>> z3d.read_z3d()
>>> print(f"Read {z3d.time_series.size} data points")
property run_metadata

Generate Run metadata object from Z3D file information.

Creates a Run metadata object populated with data logger information, timing details, and measurement parameters extracted from the Z3D file.

Returns:

Run metadata object with populated fields including data logger details, sample rate, time period, and data type information.

Return type:

Run

Examples

>>> z3d = Z3D("/path/to/file.Z3D")
>>> z3d.read_all_info()
>>> run_meta = z3d.run_metadata
>>> print(f"Sample rate: {run_meta.sample_rate}")
property sample_rate: float | None

Get the sampling rate in Hz.

Returns:

Data sampling rate in samples per second, or None if not available.

Return type:

float or None

property start: MTime

Get the start time of the data.

Returns:

Start time from GPS stamps if available, otherwise scheduled time.

Return type:

MTime

property station: str | None

Get the station name.

Returns:

Station identifier name.

Return type:

str or None

property station_metadata

Generate Station metadata object from Z3D file information.

Creates a Station metadata object populated with location and timing information extracted from the Z3D file header and metadata.

Returns:

Station metadata object with populated fields including station ID, coordinates, elevation, time period, and operator information.

Return type:

Station

Examples

>>> z3d = Z3D("/path/to/file.Z3D")
>>> z3d.read_all_info()
>>> station_meta = z3d.station_metadata
>>> print(station_meta.id)
to_channelts() ChannelTS[source]

Convert Z3D data to ChannelTS time series object.

Create a ChannelTS object populated with the time series data and all associated metadata from the Z3D file.

Returns:

Time series object with data, metadata, and instrument response.

Return type:

ChannelTS

trim_data() None[source]

Trim the first 2 seconds of data due to SD buffer issues.

Remove the first 2 GPS stamps and corresponding time series data to account for SD card buffering artifacts in early data.

Notes

This method may be deprecated after field testing confirms the buffer behavior is consistent across all instruments.

Deprecated since version This: method will be deprecated after field testing.

validate_gps_time() bool[source]

Validate that GPS time stamps are consistently 1 second apart.

Returns:

True if all GPS stamps are properly spaced, False otherwise.

Return type:

bool

Notes

Logs debug information for any stamps that are more than 1 second apart.

validate_time_blocks() bool[source]

Validate GPS time stamps and verify data block lengths.

Check that each GPS stamp block contains the expected number of data points (should equal sample rate for 1-second blocks).

Returns:

True if all blocks have correct length, False otherwise.

Return type:

bool

Notes

If bad blocks are detected near the beginning (index < 5), this method will automatically skip those blocks and trim the time series data accordingly.

property zen_response

Zen response, not sure the full calibration comes directly from the Z3D file, so skipping for now. Will have to read a Zen##.cal file to get the full calibration. This shouldn’t be a big issue cause it should roughly be the same for all channels and since the TF is computing the ratio they will cancel out. Though we should look more into this if just looking at calibrate time series.

property zen_schedule: MTime

Get the zen schedule date and time.

Returns:

Scheduled start time from header or schedule object.

Return type:

MTime

class mth5.io.zen.Z3DCollection(file_path: str | Path | None = None, **kwargs: Any)[source]

Bases: Collection

Collection manager for Z3D file operations and metadata processing.

This class provides functionality to handle collections of Z3D files, including metadata extraction, station information management, and dataframe creation for analysis workflows.

Parameters:
  • file_path (str or Path, optional) – Path to directory containing Z3D files, by default None

  • **kwargs (dict) – Additional keyword arguments passed to parent Collection class

station_metadata_dict

Dictionary mapping station IDs to Station metadata objects

Type:

dict[str, Station]

file_ext

File extension for Z3D files (“z3d”)

Type:

str

Examples

>>> zc = Z3DCollection("/path/to/z3d/files")
>>> df = zc.to_dataframe(sample_rates=[256, 4096])
>>> print(df.head())
assign_run_names(df: DataFrame, zeros: int = 3) DataFrame[source]

Assign standardized run names to dataframe based on start times.

Creates run names using the pattern ‘sr{sample_rate}_{block_number}’ where block_number is assigned sequentially based on unique start times within each station.

Parameters:
  • df (pd.DataFrame) – Input dataframe containing Z3D file information with at least ‘station’, ‘start’, and ‘sample_rate’ columns

  • zeros (int, default 3) – Number of zero-padding digits for block numbers in run names

Returns:

Modified dataframe with updated ‘run’ and ‘sequence_number’ columns assigned based on temporal ordering within each station

Return type:

pd.DataFrame

Examples

>>> zc = Z3DCollection()
>>> df = pd.DataFrame({
...     'station': ['001', '001', '002'],
...     'start': ['2022-01-01T10:00:00', '2022-01-01T12:00:00', '2022-01-01T10:00:00'],
...     'sample_rate': [256, 256, 4096]
... })
>>> df_with_runs = zc.assign_run_names(df, zeros=3)
>>> print(df_with_runs['run'].tolist())
['sr256_001', 'sr256_002', 'sr4096_001']

Notes

This method modifies the input dataframe in-place by updating the ‘run’ and ‘sequence_number’ columns. Start times are used to determine temporal ordering within each station.

get_calibrations(antenna_calibration_file: str | Path) CoilResponse[source]

Load coil calibration data from antenna calibration file.

Parameters:

antenna_calibration_file (str or Path) – Path to the antenna.cal file containing coil calibration data

Returns:

CoilResponse object containing calibration information for various coil serial numbers

Return type:

CoilResponse

Examples

>>> zc = Z3DCollection("/path/to/z3d/files")
>>> cal_obj = zc.get_calibrations("/path/to/antenna.cal")
>>> print(cal_obj.has_coil_number("2324"))
to_dataframe(sample_rates: list[int] = [256, 4096], run_name_zeros: int = 4, calibration_path: str | Path | None = None) DataFrame[source]

Extract Z3D file information and create analysis-ready dataframe.

Processes all Z3D files in the collection, extracting metadata and file information to create a comprehensive dataframe suitable for magnetotelluric data analysis workflows.

Parameters:
  • sample_rates (list of int, default [256, 4096]) – Allowed sampling rates in Hz. Files with sample rates not in this list will trigger a warning and early return

  • run_name_zeros (int, default 4) – Number of zero-padding digits for run names in dataframe sorting

  • calibration_path (str or Path, optional) – Path to antenna calibration file. If None, calibration information will not be included, by default None

Returns:

Dataframe containing Z3D file information with columns: - survey: Survey/job name from Z3D metadata - station: Station identifier - run: Automatically assigned run names based on start times - start/end: ISO format timestamps for data recording period - channel_id: Channel number from Z3D file - component: Measurement component (ex, ey, hx, hy, hz) - fn: Path to Z3D file - sample_rate: Sampling frequency in Hz - file_size: Size of Z3D file in bytes - n_samples: Number of data samples in file - sequence_number: Sequential numbering within station - dipole: Dipole length in meters (for electric channels) - coil_number: Coil serial number (for magnetic channels) - latitude/longitude/elevation: Station coordinates - instrument_id: ZEN box identifier - calibration_fn: Path to calibration file if available

Return type:

pd.DataFrame

Raises:
  • AttributeError – If Z3D files contain invalid or missing required metadata

  • FileNotFoundError – If calibration_path is specified but file doesn’t exist

Examples

>>> zc = Z3DCollection("/path/to/z3d/files")
>>> df = zc.to_dataframe(sample_rates=[256, 4096],
...                      calibration_path="/path/to/antenna.cal")
>>> print(df[['station', 'component', 'sample_rate']].head())
>>> df.to_csv("/path/output/z3d_inventory.csv")

Notes

This method also populates the station_metadata_dict attribute with consolidated station metadata derived from all processed files.

class mth5.io.zen.Z3DHeader(fn: str | Path | None = None, fid: BinaryIO | None = None, **kwargs: Any)[source]

Bases: object

Read header information from a Z3D file and make each metadata entry an attribute.

Parameters:
  • fn (str or pathlib.Path, optional) – Full path to Z3D file.

  • fid (BinaryIO, optional) – File object (e.g., open(Z3Dfile, ‘rb’)).

  • **kwargs (dict) – Additional keyword arguments to set as attributes.

_header_len

Length of header in bits (512).

Type:

int

ad_gain

Gain of channel.

Type:

float or None

ad_rate

Sampling rate in Hz.

Type:

float or None

alt

Altitude of the station (not reliable).

Type:

float or None

attenchannelsmask

Attenuation channels mask.

Type:

str or None

box_number

ZEN box number.

Type:

float or None

box_serial

ZEN box serial number.

Type:

str or None

channel

Channel number of the file.

Type:

float or None

channelserial

Serial number of the channel board.

Type:

str or None

ch_factor

Channel factor (default 9.536743164062e-10).

Type:

float

channelgain

Channel gain (default 1.0).

Type:

float

duty

Duty cycle of the transmitter.

Type:

float or None

fid

File object.

Type:

BinaryIO or None

fn

Full path to Z3D file.

Type:

str or pathlib.Path or None

fpga_buildnum

Build number of one of the boards.

Type:

float or None

gpsweek

GPS week (default 1740).

Type:

int

header_str

Full header string.

Type:

bytes or None

lat

Latitude of station in degrees.

Type:

float or None

logterminal

Log terminal setting.

Type:

str or None

long

Longitude of the station in degrees.

Type:

float or None

main_hex_buildnum

Build number of the ZEN box in hexadecimal.

Type:

float or None

numsats

Number of GPS satellites.

Type:

float or None

old_version

Whether this is an old version Z3D file (default False).

Type:

bool

period

Period of the transmitter.

Type:

float or None

tx_duty

Transmitter duty cycle.

Type:

float or None

tx_freq

Transmitter frequency.

Type:

float or None

version

Version of the firmware.

Type:

float or None

Examples

>>> from mth5.io.zen import Z3DHeader
>>> Z3Dfn = r"/home/mt/mt01/mt01_20150522_080000_256_EX.Z3D"
>>> header_obj = Z3DHeader(fn=Z3Dfn)
>>> header_obj.read_header()
convert_value(key_string: str, value_string: str) float | str[source]

Convert the value to the appropriate units given the key.

Converts string values to appropriate types based on the key name. Special handling is provided for latitude and longitude values, which are converted from radians to degrees with validation.

Parameters:
  • key_string (str) – The metadata key name, used to determine conversion type.

  • value_string (str) – The string value to convert.

Returns:

Converted value. Returns float for numeric values, str for non-numeric values. Latitude and longitude values are converted from radians to degrees.

Return type:

float or str

Notes

  • Attempts to convert all values to float first

  • If conversion fails, returns original string

  • For keys containing ‘lat’, ‘lon’, or ‘long’: - Converts from radians to degrees using np.rad2deg - Validates latitude range (±90°), sets to 0.0 if invalid - Validates longitude range (±180°), sets to 0.0 if invalid

Examples

>>> header = Z3DHeader()
>>> header.convert_value("version", "4147")
4147.0
>>> header.convert_value("lat", "0.706816081")  # radians
40.49757833327694  # degrees
>>> header.convert_value("channelserial", "0xD474777C")
'0xD474777C'
property data_logger: str

Data logger name as ZEN{box_number}.

Returns:

Data logger name formatted as ‘ZEN’ followed by zero-padded box number.

Return type:

str

Raises:

TypeError – If box_number is None or cannot be converted to int.

read_header(fn: str | Path | None = None, fid: BinaryIO | None = None) None[source]

Read the header information into appropriate attributes.

Parses the header information from a Z3D file and populates the object’s attributes with the extracted values. Supports both modern and legacy Z3D file formats.

Parameters:
  • fn (str or pathlib.Path, optional) – Full path to Z3D file. If None, uses the instance’s fn attribute.

  • fid (BinaryIO, optional) – File object (e.g., open(Z3Dfile, ‘rb’)). If None, uses the instance’s fid attribute or opens the file specified by fn.

Raises:

UnicodeDecodeError – If header bytes cannot be decoded as text.

Notes

This method reads the first 512 bytes of the Z3D file as the header. It supports two formats:

  1. Modern format: key=value pairs separated by newlines

  2. Legacy format: comma-separated key:value pairs

The method automatically detects legacy format and sets old_version=True.

Coordinate values (lat/long) are automatically converted from radians to degrees, with validation to ensure they fall within valid ranges.

Examples

>>> header_obj = Z3DHeader()
>>> header_obj.read_header("/path/to/file.Z3D")
>>> with open("/path/to/file.Z3D", "rb") as fid:
...     header_obj.read_header(fid=fid)
class mth5.io.zen.Z3DMetadata(fn: str | Path | None = None, fid: BinaryIO | None = None, **kwargs: Any)[source]

Bases: object

Read metadata information from a Z3D file and make each metadata entry an attribute.

The attributes are left in capitalization of the Z3D file format.

Parameters:
  • fn (str or pathlib.Path, optional) – Full path to Z3D file.

  • fid (BinaryIO, optional) – File object (e.g., open(Z3Dfile, ‘rb’)).

  • **kwargs (dict) – Additional keyword arguments to set as attributes.

_header_length

Length of header in bits (512).

Type:

int

_metadata_length

Length of metadata blocks (512).

Type:

int

_schedule_metadata_len

Length of schedule meta data (512).

Type:

int

board_cal

Board calibration array with frequency, rate, amplitude, phase.

Type:

np.ndarray or None

cal_ant

Antenna calibration information.

Type:

str or None

cal_board

Board calibration dictionary.

Type:

dict or None

cal_ver

Calibration version.

Type:

str or None

ch_azimuth

Channel azimuth.

Type:

str or None

ch_cmp

Channel component.

Type:

str or None

ch_length

Channel length (or number of coils).

Type:

str or None

ch_number

Channel number on the ZEN board.

Type:

str or None

ch_xyz1

Channel xyz location.

Type:

str or None

ch_xyz2

Channel xyz location.

Type:

str or None

ch_cres

Channel resistance.

Type:

str or None

coil_cal

Coil calibration array (frequency, amplitude, phase).

Type:

np.ndarray or None

fid

File object.

Type:

BinaryIO or None

find_metadata

Boolean flag for finding metadata.

Type:

bool

fn

Full path to Z3D file.

Type:

str or pathlib.Path or None

gdp_operator

Operator of the survey.

Type:

str or None

gdp_progver

Program version.

Type:

str or None

gdp_temp

GDP temperature.

Type:

str or None

gdp_volt

GDP voltage.

Type:

str or None

job_by

Job performed by.

Type:

str or None

job_for

Job for.

Type:

str or None

job_name

Job name.

Type:

str or None

job_number

Job number.

Type:

str or None

line_name

Survey line name.

Type:

str or None

m_tell

Location in the file where the last metadata block was found.

Type:

int

notes

Additional notes from metadata.

Type:

str or None

rx_aspace

Electrode spacing.

Type:

str or None

rx_sspace

Receiver spacing.

Type:

str or None

rx_xazimuth

X azimuth of electrode.

Type:

str or None

rx_xyz0

Receiver xyz coordinates.

Type:

str or None

rx_yazimuth

Y azimuth of electrode.

Type:

str or None

rx_zpositive

Z positive direction (default ‘down’).

Type:

str

station

Station name.

Type:

str or None

survey_type

Type of survey.

Type:

str or None

unit_length

Length units (m).

Type:

str or None

count

Counter for metadata blocks read.

Type:

int

Examples

>>> from mth5.io.zen import Z3DMetadata
>>> Z3Dfn = r"/home/mt/mt01/mt01_20150522_080000_256_EX.Z3D"
>>> header_obj = Z3DMetadata(fn=Z3Dfn)
>>> header_obj.read_metadata()
read_metadata(fn: str | Path | None = None, fid: BinaryIO | None = None) None[source]

Read metadata from Z3D file.

Parses the metadata blocks in a Z3D file and populates the object’s attributes with the extracted values. Also reads calibration data for both board and coil calibrations.

Parameters:
  • fn (str or pathlib.Path, optional) – Full path to file. If None, uses the instance’s fn attribute.

  • fid (BinaryIO, optional) – Open file object. If None, uses the instance’s fid attribute or opens the file specified by fn.

Raises:

UnicodeDecodeError – If metadata blocks cannot be decoded as text.

Notes

This method reads metadata blocks sequentially from the Z3D file, starting after the header and schedule metadata sections. It processes:

  • Standard metadata records with key=value pairs

  • Board calibration data (cal.brd format)

  • Coil calibration data (cal.ant format)

  • Calibration data blocks (caldata format)

The method automatically determines the station name from available metadata fields in the following priority: 1. line_name + rx_xyz0 (first coordinate) 2. rx_stn 3. ch_stn

class mth5.io.zen.Z3DSchedule(fn: str | Path | None = None, fid: BinaryIO | None = None, **kwargs: Any)[source]

Bases: object

Parser for Z3D file schedule information and metadata.

Reads schedule information from Z3D files and creates object attributes for each metadata entry. Schedule data is stored at byte offset 512 in Z3D files and contains recording parameters, timing information, and instrument configuration settings.

The class preserves the original capitalization from the Z3D file format and provides automatic parsing of key-value pairs in the schedule section.

Parameters:
  • fn (Union[str, Path], optional) – Full path to Z3D file to read schedule information from. Can be string path or pathlib.Path object.

  • fid (BinaryIO, optional) – Open file object for reading Z3D file in binary mode. Example: open(‘file.z3d’, ‘rb’)

  • **kwargs (Any) – Additional keyword arguments to set as object attributes.

AutoGain

Auto gain setting for the recording channel [‘Y’ or ‘N’].

Type:

str or None

Comment

User comments or notes for the schedule configuration.

Type:

str or None

Date

Date when the schedule action was started in YYYY-MM-DD format.

Type:

str or None

Duty

Duty cycle percentage of the transmitter (0-100).

Type:

str or None

FFTStacks

Number of FFT stacks used by the transmitter.

Type:

str or None

Filename

Original filename that the ZEN instrument assigns to the recording.

Type:

str or None

Gain

Gain setting for the recording channel (e.g., ‘1.0000’).

Type:

str or None

Log

Data logging enabled flag [‘Y’ or ‘N’].

Type:

str or None

NewFile

Create new file for recording flag [‘Y’ or ‘N’].

Type:

str or None

Period

Base period setting for the transmitter in seconds.

Type:

str or None

RadioOn

Radio communication enabled flag [‘Y’, ‘N’, or ‘X’].

Type:

str or None

SR

Sampling rate in Hz (originally ‘S/R’ in file, converted to ‘SR’).

Type:

str or None

SamplesPerAcq

Number of samples per acquisition for transmitter mode.

Type:

str or None

Sleep

Sleep mode enabled flag [‘Y’ or ‘N’].

Type:

str or None

Sync

GPS synchronization enabled flag [‘Y’ or ‘N’].

Type:

str or None

Time

Time when the schedule action started in HH:MM:SS format (GPS time).

Type:

str or None

initial_start

Parsed start time as MTime object with GPS time flag enabled. Combines Date and Time attributes for timestamp calculation.

Type:

MTime

fn

Path to the Z3D file being processed.

Type:

Union[str, Path] or None

fid

File object for reading the Z3D file.

Type:

BinaryIO or None

meta_string

Raw schedule metadata string read from the file.

Type:

bytes or None

_header_len

Length of Z3D file header in bytes (512).

Type:

int

_schedule_metadata_len

Length of schedule metadata section in bytes (512).

Type:

int

logger

Loguru logger instance for debugging and status messages.

Type:

Logger

Notes

The Z3D file format stores schedule information at a fixed offset of 512 bytes from the beginning of the file. The schedule section is also 512 bytes long and contains key-value pairs in the format “Schedule.key = value”.

All schedule values are stored as strings to preserve the original format from the Z3D file. Boolean-like values use ‘Y’/’N’ convention.

The initial_start attribute automatically converts Date and Time into a GPS-corrected MTime object for accurate timestamp handling.

Examples

Read schedule from file path:

>>> from mth5.io.zen import Z3DSchedule
>>> from pathlib import Path
>>>
>>> # Using filename
>>> schedule = Z3DSchedule(fn="recording.z3d")
>>> schedule.read_schedule()
>>> print(f"Sampling rate: {schedule.SR} Hz")
>>> print(f"Start time: {schedule.initial_start}")

Read schedule from file object:

>>> with open("recording.z3d", "rb") as fid:
...     schedule = Z3DSchedule(fid=fid)
...     schedule.read_schedule()
...     print(f"Date: {schedule.Date}, Time: {schedule.Time}")
...     print(f"GPS Sync: {schedule.Sync}")

Access schedule attributes:

>>> schedule = Z3DSchedule()
>>> schedule.read_schedule(fn="recording.z3d")
>>>
>>> # Check recording configuration
>>> if schedule.Sync == 'Y':
...     print("GPS synchronization enabled")
>>> if schedule.Log == 'Y':
...     print("Data logging enabled")
>>>
>>> # Get numeric values (stored as strings)
>>> sample_rate = float(schedule.SR) if schedule.SR else 0
>>> gain_value = float(schedule.Gain) if schedule.Gain else 1.0
read_schedule(fn: str | Path | None = None, fid: BinaryIO | None = None) None[source]

Read and parse schedule metadata from Z3D file.

Reads the schedule information section from a Z3D file starting at byte offset 512 (after the header) and parses key-value pairs to populate object attributes. Automatically creates an MTime object for the initial start time using GPS time correction.

Parameters:
  • fn (Union[str, Path], optional) – Path to Z3D file to read. Overrides instance fn if provided. Can be string path or pathlib.Path object.

  • fid (BinaryIO, optional) – Open file object for reading Z3D file. Overrides instance fid if provided. Must be opened in binary mode (‘rb’).

Raises:
  • UnicodeDecodeError – If schedule metadata cannot be decoded as UTF-8 text.

  • IndexError – If schedule lines don’t match expected “Schedule.key = value” format.

  • ValueError – If Date/Time values cannot be parsed into valid MTime object.

Notes

The method performs the following steps: 1. Determines file source (fn parameter, fid parameter, or instance attributes) 2. Seeks to byte offset 512 (after Z3D header) 3. Reads 512 bytes of schedule metadata 4. Splits metadata into lines and parses key-value pairs 5. Sets object attributes for each parsed schedule entry 6. Creates MTime object from Date and Time with GPS correction

Schedule entries must follow the format “Schedule.key = value”. The “Schedule.” prefix is removed and “/” characters in keys are stripped (e.g., “S/R” becomes “SR”).

If both Date and Time are present, they are combined into an MTime object with GPS time correction applied automatically.

Examples

Read from file path:

>>> schedule = Z3DSchedule()
>>> schedule.read_schedule(fn="recording.z3d")
>>> print(f"Sampling rate: {schedule.SR}")

Read from open file object:

>>> with open("recording.z3d", "rb") as fid:
...     schedule = Z3DSchedule()
...     schedule.read_schedule(fid=fid)
...     print(f"GPS sync: {schedule.Sync}")

Read using instance attributes:

>>> schedule = Z3DSchedule(fn="recording.z3d")
>>> schedule.read_schedule()  # Uses instance fn
>>> print(f"Start time: {schedule.initial_start}")
mth5.io.zen.read_z3d(fn: str | Path, calibration_fn: str | Path | None = None, logger_file_handler: Any | None = None) ChannelTS | None[source]

Read a Z3D file and return a ChannelTS object.

Convenience function to read Z3D files with error handling.

Parameters:
  • fn (str or Path) – Path to the Z3D file to read.

  • calibration_fn (str, Path, or None, optional) – Path to calibration file. Default is None.

  • logger_file_handler (optional) – Logger file handler to add to Z3D logger. Default is None.

Returns:

Time series object if successful, None if GPS timing errors occur.

Return type:

ChannelTS or None

Examples

>>> ts = read_z3d("/path/to/data/station_EX.Z3D")
>>> if ts is not None:
...     print(f"Read {ts.n_samples} samples")