mth5.io.phoenix package

Subpackages

Submodules

mth5.io.phoenix.phoenix_collection module

Phoenix file collection module for organizing and processing Phoenix MTU data files.

This module provides the PhoenixCollection class for discovering, organizing, and managing Phoenix magnetotelluric receiver files within a directory structure.

Created on Thu Aug 4 16:48:47 2022

@author: jpeacock

class mth5.io.phoenix.phoenix_collection.PhoenixCollection(file_path: str | Path | None = None, **kwargs)[source]

Bases: Collection

Collection manager for Phoenix MTU data files.

Organizes Phoenix magnetotelluric receiver files into runs based on timing and sample rates. Handles multiple sample rates (30, 150, 2400, 24000, 96000 Hz) and manages receiver metadata.

Parameters:
  • file_path (str | Path | None, optional) – Path to the directory containing Phoenix data files. Can be the station folder or a parent folder containing multiple stations.

  • **kwargs – Additional keyword arguments passed to parent Collection class.

metadata_dict[source]

Dictionary mapping station IDs to their receiver metadata.

Type:

dict[str, PhoenixReceiverMetadata]

Examples

Create a collection from a station directory:

>>> from mth5.io.phoenix import PhoenixCollection
>>> collection = PhoenixCollection(r"/path/to/station")
>>> runs = collection.get_runs(sample_rates=[150, 24000])
>>> print(runs.keys())
dict_keys(['MT001'])

Process multiple sample rates:

>>> df = collection.to_dataframe(sample_rates=[150, 2400, 24000])
>>> print(df.columns)
Index(['survey', 'station', 'run', 'start', 'end', ...])

Notes

The class automatically discovers station folders by locating ‘recmeta.json’ files and organizes time series files by sample rate.

File extensions are mapped as:

  • 30 Hz: td_30

  • 150 Hz: td_150

  • 2400 Hz: td_2400

  • 24000 Hz: td_24k

  • 96000 Hz: td_96k

See also

mth5.io.Collection

Base collection class

mth5.io.phoenix.PhoenixReceiverMetadata

Receiver metadata handler

assign_run_names(df: DataFrame, zeros: int = 4) DataFrame[source]

Assign run names based on temporal continuity.

Analyzes file timing to group files into runs. For continuous data (< 1000 Hz), maintains a single run as long as files are contiguous. For segmented data (≥ 1000 Hz), assigns a unique run to each segment.

Parameters:
  • df (pd.DataFrame) – DataFrame returned by to_dataframe method with file inventory.

  • zeros (int, optional) – Number of zeros for zero-padding run names (default is 4).

Returns:

DataFrame with ‘run’ column populated. Run names follow the format ‘sr{rate}_{number:0{zeros}}’, e.g., ‘sr150_0001’.

Return type:

pd.DataFrame

Examples

Assign run names to a DataFrame:

>>> df = collection.to_dataframe(sample_rates=[150, 24000])
>>> df_with_runs = collection.assign_run_names(df, zeros=4)
>>> print(df_with_runs.run.unique())
['sr150_0001', 'sr24k_0001', 'sr24k_0002', ...]

Check for data gaps in continuous data:

>>> df_150 = df_with_runs[df_with_runs.sample_rate == 150]
>>> print(df_150.run.unique())
['sr150_0001', 'sr150_0002']  # Gap detected between runs

Count segments in high-rate data:

>>> df_24k = df_with_runs[df_with_runs.sample_rate == 24000]
>>> n_segments = len(df_24k.run.unique())
>>> print(f"Found {n_segments} segments at 24 kHz")
Found 43 segments at 24 kHz

Notes

Continuous Data (< 1000 Hz):

  • Maintains single run ID while files are temporally contiguous

  • Detects gaps by comparing end time of file N with start time of file N+1

  • Increments run counter when gap > 0 seconds detected

Segmented Data (≥ 1000 Hz):

  • Each unique start time receives a new run ID

  • Typically results in one run per segment/file

The run naming scheme uses the sample rate in the identifier:

  • 30 Hz → ‘sr30_NNNN’

  • 150 Hz → ‘sr150_NNNN’

  • 2400 Hz → ‘sr2400_NNNN’

  • 24000 Hz → ‘sr24k_NNNN’

  • 96000 Hz → ‘sr96k_NNNN’

get_runs(sample_rates: list[int] | int, run_name_zeros: int = 4, calibration_path: str | Path | None = None) OrderedDict[str, OrderedDict[str, DataFrame]][source]

Organize Phoenix files into runs ready for reading.

Creates a nested dictionary structure organizing files by station and run. For each run, returns only the first file(s) needed to initialize reading, as continuous readers will automatically load sequences.

Parameters:
  • sample_rates (list[int] | int) – Sample rate(s) to include in Hz. Valid values are 30, 150, 2400, 24000, 96000. Can be a single integer or list.

  • run_name_zeros (int, optional) – Number of zeros for zero-padding run names (default is 4).

  • calibration_path (str | Path | None, optional) – Path to calibration files. Currently unused but reserved for future functionality.

Returns:

Nested OrderedDict with structure:

  • Keys: station IDs

  • Values: OrderedDict of runs

    • Keys: run IDs (e.g., ‘sr150_0001’)

    • Values: DataFrame with first file(s) for each channel

Return type:

OrderedDict[str, OrderedDict[str, pd.DataFrame]]

Examples

Get runs for standard sample rates:

>>> from mth5.io.phoenix import PhoenixCollection
>>> collection = PhoenixCollection(r"/path/to/station")
>>> runs = collection.get_runs(sample_rates=[150, 24000])
>>> print(runs.keys())
odict_keys(['MT001'])

Access specific station’s runs:

>>> station_runs = runs['MT001']
>>> print(list(station_runs.keys()))
['sr150_0001', 'sr24k_0001', 'sr24k_0002', ...]

Get first file for a specific run:

>>> run_df = runs['MT001']['sr150_0001']
>>> print(run_df[['component', 'fn', 'start']])
  component                           fn                 start
0        Ex  /path/to/8441_2020...td_150  2020-06-02T19:00:00
1        Ey  /path/to/8441_2020...td_150  2020-06-02T19:00:00

Iterate over all runs:

>>> for station_id, station_runs in runs.items():
...     for run_id, run_df in station_runs.items():
...         print(f"{station_id}/{run_id}: {len(run_df)} channels")
MT001/sr150_0001: 5 channels
MT001/sr24k_0001: 5 channels

Get single sample rate:

>>> runs_150 = collection.get_runs(sample_rates=150)
>>> run_ids = list(runs_150['MT001'].keys())
>>> print([r for r in run_ids if 'sr150' in r])
['sr150_0001']

Notes

For Continuous Data (< 1000 Hz):

Returns only the first file in each sequence per channel. The Phoenix reader will automatically load the complete sequence when reading.

For Segmented Data (≥ 1000 Hz):

Returns the first file for each segment. Each segment must be read separately.

DataFrame Content:

Each DataFrame contains one row per channel component with the earliest file for that component in the run. This ensures all channels start from the same time.

The method internally:

  1. Calls to_dataframe() to inventory all files

  2. Calls assign_run_names() to group files into runs

  3. Selects first file(s) for each run and component

  4. Returns organized structure for easy iteration

See also

to_dataframe

Create complete file inventory

assign_run_names

Group files into runs

mth5.io.phoenix.read_phoenix

Read Phoenix files

to_dataframe(sample_rates: list[int] | int = [150, 24000], run_name_zeros: int = 4, calibration_path: str | Path | None = None) DataFrame[source]

Create a DataFrame cataloging all Phoenix files in the collection.

Scans all station folders for time series files at specified sample rates and creates a comprehensive inventory with metadata for each file.

Parameters:
  • sample_rates (list[int] | int, optional) – Sample rate(s) to include in Hz. Valid values are 30, 150, 2400, 24000, 96000. Can be a single integer or list (default is [150, 24000]).

  • run_name_zeros (int, optional) – Number of zeros for zero-padding run names (default is 4). For example, 4 produces ‘sr150_0001’.

  • calibration_path (str | Path | None, optional) – Path to calibration files. Currently unused but reserved for future functionality.

Returns:

DataFrame with one row per file containing columns:

  • survey: Survey ID from metadata

  • station: Station ID from metadata

  • run: Run ID (assigned by assign_run_names)

  • start: File start time (ISO format)

  • end: File end time (ISO format)

  • channel_id: Numeric channel identifier

  • component: Channel component name (e.g., ‘Ex’, ‘Hy’)

  • fn: Full file path

  • sample_rate: Sample rate in Hz

  • file_size: File size in bytes

  • n_samples: Number of samples in file

  • sequence_number: File sequence number for continuous data

  • instrument_id: Recording/receiver ID

  • calibration_fn: Path to calibration file (currently None)

Return type:

pd.DataFrame

Examples

Get DataFrame for standard sample rates:

>>> df = collection.to_dataframe(sample_rates=[150, 24000])
>>> print(df.shape)
(245, 14)
>>> print(df.station.unique())
['MT001']

Process single sample rate:

>>> df_150 = collection.to_dataframe(sample_rates=150)
>>> print(df_150.sample_rate.unique())
[150.]

Check file coverage:

>>> for comp in df.component.unique():
...     comp_df = df[df.component == comp]
...     print(f"{comp}: {len(comp_df)} files")
Ex: 35 files
Ey: 35 files
Hx: 35 files

Notes

  • Calibration files (identified by ‘calibration’ in filename) are automatically skipped

  • Files that cannot be opened are logged and skipped

  • The DataFrame is sorted by station, sample_rate, and start time

  • Run names must be assigned separately using assign_run_names()

See also

assign_run_names

Assign run identifiers based on timing

get_runs

Get organized runs directly

mth5.io.phoenix.read module

Created on Fri May 6 12:39:34 2022

@author: jpeacock

mth5.io.phoenix.read.get_file_extenstion(file_name: str | Path) str[source]

Get the file extension from a file name.

Parameters:

file_name (str or pathlib.Path) – The file name to extract the extension from.

Returns:

The file extension without the leading dot.

Return type:

str

mth5.io.phoenix.read.open_phoenix(file_name: str | Path, **kwargs: Any) DecimatedContinuousReader | DecimatedSegmentedReader | NativeReader | MTUTSN | MTUTable[source]

Open a Phoenix Geophysics data file in the appropriate container.

Parameters:
  • file_name (str or pathlib.Path) – Full path to the Phoenix data file to open.

  • **kwargs (Any) – Additional keyword arguments to pass to the reader constructor.

Returns:

reader – The appropriate Phoenix reader container based on file extension: - .bin files: NativeReader - .td_24k files: DecimatedSegmentedReader - .td_150/.td_30 files: DecimatedContinuousReader

Return type:

DecimatedContinuousReader | DecimatedSegmentedReader | NativeReader

Raises:

KeyError – If the file extension is not supported by any Phoenix reader.

mth5.io.phoenix.read.read_phoenix(file_name: str | Path, **kwargs: Any) ChannelTS | RunTS | MTUTable[source]

Read a Phoenix Geophysics data file into a ChannelTS or RunTS object depending on the file type. Newer files that end in .td_XX or .bin will be read into ChannelTS objects. Older MTU files that end in .TS3, .TS4, .TS5, .TSL, or .TSH will be read into RunTS objects.

Parameters:
  • file_name (str or pathlib.Path) – Path to the Phoenix data file to read.

  • **kwargs (Any) –

    Additional keyword arguments. May include:

    • rxcal_fnstr or pathlib.Path, optional

      Path to receiver calibration file.

    • scal_fnstr or pathlib.Path, optional

      Path to sensor calibration file.

    • table_filepathstr or pathlib.Path, optional

      Path to the MTU TBL file for use with MTUTSN files.

    • Other arguments passed to the Phoenix reader constructor.

Returns:

  • channel_ts (ChannelTS) – Time series data object containing the Phoenix file data with calibration applied if calibration files were provided.

  • run_ts (RunTS) – Time series data object containing the MTU data from the Phoenix MTU files with calibration applied if specified.

  • mtu_table (MTUTable) – Metadata table object containing the MTU table data.

Raises:
  • KeyError – If the file extension is not supported by any Phoenix reader.

  • ValueError – If the file cannot be read or converted to ChannelTS or RunTS format.

Module contents

class mth5.io.phoenix.PhoenixCollection(file_path: str | Path | None = None, **kwargs)[source]

Bases: Collection

Collection manager for Phoenix MTU data files.

Organizes Phoenix magnetotelluric receiver files into runs based on timing and sample rates. Handles multiple sample rates (30, 150, 2400, 24000, 96000 Hz) and manages receiver metadata.

Parameters:
  • file_path (str | Path | None, optional) – Path to the directory containing Phoenix data files. Can be the station folder or a parent folder containing multiple stations.

  • **kwargs – Additional keyword arguments passed to parent Collection class.

metadata_dict

Dictionary mapping station IDs to their receiver metadata.

Type:

dict[str, PhoenixReceiverMetadata]

Examples

Create a collection from a station directory:

>>> from mth5.io.phoenix import PhoenixCollection
>>> collection = PhoenixCollection(r"/path/to/station")
>>> runs = collection.get_runs(sample_rates=[150, 24000])
>>> print(runs.keys())
dict_keys(['MT001'])

Process multiple sample rates:

>>> df = collection.to_dataframe(sample_rates=[150, 2400, 24000])
>>> print(df.columns)
Index(['survey', 'station', 'run', 'start', 'end', ...])

Notes

The class automatically discovers station folders by locating ‘recmeta.json’ files and organizes time series files by sample rate.

File extensions are mapped as:

  • 30 Hz: td_30

  • 150 Hz: td_150

  • 2400 Hz: td_2400

  • 24000 Hz: td_24k

  • 96000 Hz: td_96k

See also

mth5.io.Collection

Base collection class

mth5.io.phoenix.PhoenixReceiverMetadata

Receiver metadata handler

assign_run_names(df: DataFrame, zeros: int = 4) DataFrame[source]

Assign run names based on temporal continuity.

Analyzes file timing to group files into runs. For continuous data (< 1000 Hz), maintains a single run as long as files are contiguous. For segmented data (≥ 1000 Hz), assigns a unique run to each segment.

Parameters:
  • df (pd.DataFrame) – DataFrame returned by to_dataframe method with file inventory.

  • zeros (int, optional) – Number of zeros for zero-padding run names (default is 4).

Returns:

DataFrame with ‘run’ column populated. Run names follow the format ‘sr{rate}_{number:0{zeros}}’, e.g., ‘sr150_0001’.

Return type:

pd.DataFrame

Examples

Assign run names to a DataFrame:

>>> df = collection.to_dataframe(sample_rates=[150, 24000])
>>> df_with_runs = collection.assign_run_names(df, zeros=4)
>>> print(df_with_runs.run.unique())
['sr150_0001', 'sr24k_0001', 'sr24k_0002', ...]

Check for data gaps in continuous data:

>>> df_150 = df_with_runs[df_with_runs.sample_rate == 150]
>>> print(df_150.run.unique())
['sr150_0001', 'sr150_0002']  # Gap detected between runs

Count segments in high-rate data:

>>> df_24k = df_with_runs[df_with_runs.sample_rate == 24000]
>>> n_segments = len(df_24k.run.unique())
>>> print(f"Found {n_segments} segments at 24 kHz")
Found 43 segments at 24 kHz

Notes

Continuous Data (< 1000 Hz):

  • Maintains single run ID while files are temporally contiguous

  • Detects gaps by comparing end time of file N with start time of file N+1

  • Increments run counter when gap > 0 seconds detected

Segmented Data (≥ 1000 Hz):

  • Each unique start time receives a new run ID

  • Typically results in one run per segment/file

The run naming scheme uses the sample rate in the identifier:

  • 30 Hz → ‘sr30_NNNN’

  • 150 Hz → ‘sr150_NNNN’

  • 2400 Hz → ‘sr2400_NNNN’

  • 24000 Hz → ‘sr24k_NNNN’

  • 96000 Hz → ‘sr96k_NNNN’

get_runs(sample_rates: list[int] | int, run_name_zeros: int = 4, calibration_path: str | Path | None = None) OrderedDict[str, OrderedDict[str, DataFrame]][source]

Organize Phoenix files into runs ready for reading.

Creates a nested dictionary structure organizing files by station and run. For each run, returns only the first file(s) needed to initialize reading, as continuous readers will automatically load sequences.

Parameters:
  • sample_rates (list[int] | int) – Sample rate(s) to include in Hz. Valid values are 30, 150, 2400, 24000, 96000. Can be a single integer or list.

  • run_name_zeros (int, optional) – Number of zeros for zero-padding run names (default is 4).

  • calibration_path (str | Path | None, optional) – Path to calibration files. Currently unused but reserved for future functionality.

Returns:

Nested OrderedDict with structure:

  • Keys: station IDs

  • Values: OrderedDict of runs

    • Keys: run IDs (e.g., ‘sr150_0001’)

    • Values: DataFrame with first file(s) for each channel

Return type:

OrderedDict[str, OrderedDict[str, pd.DataFrame]]

Examples

Get runs for standard sample rates:

>>> from mth5.io.phoenix import PhoenixCollection
>>> collection = PhoenixCollection(r"/path/to/station")
>>> runs = collection.get_runs(sample_rates=[150, 24000])
>>> print(runs.keys())
odict_keys(['MT001'])

Access specific station’s runs:

>>> station_runs = runs['MT001']
>>> print(list(station_runs.keys()))
['sr150_0001', 'sr24k_0001', 'sr24k_0002', ...]

Get first file for a specific run:

>>> run_df = runs['MT001']['sr150_0001']
>>> print(run_df[['component', 'fn', 'start']])
  component                           fn                 start
0        Ex  /path/to/8441_2020...td_150  2020-06-02T19:00:00
1        Ey  /path/to/8441_2020...td_150  2020-06-02T19:00:00

Iterate over all runs:

>>> for station_id, station_runs in runs.items():
...     for run_id, run_df in station_runs.items():
...         print(f"{station_id}/{run_id}: {len(run_df)} channels")
MT001/sr150_0001: 5 channels
MT001/sr24k_0001: 5 channels

Get single sample rate:

>>> runs_150 = collection.get_runs(sample_rates=150)
>>> run_ids = list(runs_150['MT001'].keys())
>>> print([r for r in run_ids if 'sr150' in r])
['sr150_0001']

Notes

For Continuous Data (< 1000 Hz):

Returns only the first file in each sequence per channel. The Phoenix reader will automatically load the complete sequence when reading.

For Segmented Data (≥ 1000 Hz):

Returns the first file for each segment. Each segment must be read separately.

DataFrame Content:

Each DataFrame contains one row per channel component with the earliest file for that component in the run. This ensures all channels start from the same time.

The method internally:

  1. Calls to_dataframe() to inventory all files

  2. Calls assign_run_names() to group files into runs

  3. Selects first file(s) for each run and component

  4. Returns organized structure for easy iteration

See also

to_dataframe

Create complete file inventory

assign_run_names

Group files into runs

mth5.io.phoenix.read_phoenix

Read Phoenix files

to_dataframe(sample_rates: list[int] | int = [150, 24000], run_name_zeros: int = 4, calibration_path: str | Path | None = None) DataFrame[source]

Create a DataFrame cataloging all Phoenix files in the collection.

Scans all station folders for time series files at specified sample rates and creates a comprehensive inventory with metadata for each file.

Parameters:
  • sample_rates (list[int] | int, optional) – Sample rate(s) to include in Hz. Valid values are 30, 150, 2400, 24000, 96000. Can be a single integer or list (default is [150, 24000]).

  • run_name_zeros (int, optional) – Number of zeros for zero-padding run names (default is 4). For example, 4 produces ‘sr150_0001’.

  • calibration_path (str | Path | None, optional) – Path to calibration files. Currently unused but reserved for future functionality.

Returns:

DataFrame with one row per file containing columns:

  • survey: Survey ID from metadata

  • station: Station ID from metadata

  • run: Run ID (assigned by assign_run_names)

  • start: File start time (ISO format)

  • end: File end time (ISO format)

  • channel_id: Numeric channel identifier

  • component: Channel component name (e.g., ‘Ex’, ‘Hy’)

  • fn: Full file path

  • sample_rate: Sample rate in Hz

  • file_size: File size in bytes

  • n_samples: Number of samples in file

  • sequence_number: File sequence number for continuous data

  • instrument_id: Recording/receiver ID

  • calibration_fn: Path to calibration file (currently None)

Return type:

pd.DataFrame

Examples

Get DataFrame for standard sample rates:

>>> df = collection.to_dataframe(sample_rates=[150, 24000])
>>> print(df.shape)
(245, 14)
>>> print(df.station.unique())
['MT001']

Process single sample rate:

>>> df_150 = collection.to_dataframe(sample_rates=150)
>>> print(df_150.sample_rate.unique())
[150.]

Check file coverage:

>>> for comp in df.component.unique():
...     comp_df = df[df.component == comp]
...     print(f"{comp}: {len(comp_df)} files")
Ex: 35 files
Ey: 35 files
Hx: 35 files

Notes

  • Calibration files (identified by ‘calibration’ in filename) are automatically skipped

  • Files that cannot be opened are logged and skipped

  • The DataFrame is sorted by station, sample_rate, and start time

  • Run names must be assigned separately using assign_run_names()

See also

assign_run_names

Assign run identifiers based on timing

get_runs

Get organized runs directly

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

Bases: object

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}")
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 fn: 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

has_obj() bool[source]

Check if configuration data has been loaded.

Returns:

True if configuration data is loaded, False otherwise.

Return type:

bool

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

read(fn: str | 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.

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

station_metadata() 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}")
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

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

Bases: object

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 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 e1_metadata: Electric

Electric channel 1 metadata.

property e2_metadata: Electric

Electric channel 2 metadata.

property fn: Path | None

Path to the metadata file.

Returns:

Path to the recmeta.json file, or None if not set.

Return type:

Path 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_metadata(index: int) Electric | 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.

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 h1_metadata: Magnetic

Magnetic channel 1 metadata.

property h2_metadata: Magnetic

Magnetic channel 2 metadata.

property h3_metadata: Magnetic

Magnetic channel 3 metadata.

property h4_metadata: Magnetic

Magnetic channel 4 metadata.

property h5_metadata: Magnetic

Magnetic channel 5 metadata.

property h6_metadata: Magnetic

Magnetic channel 6 metadata.

has_obj() bool[source]

Check if metadata object is loaded.

Returns:

True if metadata object exists, False otherwise.

Return type:

bool

property instrument_id: str | None

Instrument identifier from metadata.

Returns:

Instrument ID if available, None otherwise.

Return type:

str or None

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

read(fn: str | 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.

property run_metadata: Run

Run metadata from receiver configuration.

Returns:

Run metadata object with data logger and timing information.

Return type:

Run

property station_metadata: Station

Station metadata from receiver configuration.

Returns:

Station metadata object with location and acquisition information.

Return type:

Station

property survey_metadata: Survey

Survey metadata from receiver configuration.

Returns:

Survey metadata object with survey information.

Return type:

Survey

mth5.io.phoenix.open_phoenix(file_name: str | Path, **kwargs: Any) DecimatedContinuousReader | DecimatedSegmentedReader | NativeReader | MTUTSN | MTUTable[source]

Open a Phoenix Geophysics data file in the appropriate container.

Parameters:
  • file_name (str or pathlib.Path) – Full path to the Phoenix data file to open.

  • **kwargs (Any) – Additional keyword arguments to pass to the reader constructor.

Returns:

reader – The appropriate Phoenix reader container based on file extension: - .bin files: NativeReader - .td_24k files: DecimatedSegmentedReader - .td_150/.td_30 files: DecimatedContinuousReader

Return type:

DecimatedContinuousReader | DecimatedSegmentedReader | NativeReader

Raises:

KeyError – If the file extension is not supported by any Phoenix reader.

mth5.io.phoenix.read_phoenix(file_name: str | Path, **kwargs: Any) ChannelTS | RunTS | MTUTable[source]

Read a Phoenix Geophysics data file into a ChannelTS or RunTS object depending on the file type. Newer files that end in .td_XX or .bin will be read into ChannelTS objects. Older MTU files that end in .TS3, .TS4, .TS5, .TSL, or .TSH will be read into RunTS objects.

Parameters:
  • file_name (str or pathlib.Path) – Path to the Phoenix data file to read.

  • **kwargs (Any) –

    Additional keyword arguments. May include:

    • rxcal_fnstr or pathlib.Path, optional

      Path to receiver calibration file.

    • scal_fnstr or pathlib.Path, optional

      Path to sensor calibration file.

    • table_filepathstr or pathlib.Path, optional

      Path to the MTU TBL file for use with MTUTSN files.

    • Other arguments passed to the Phoenix reader constructor.

Returns:

  • channel_ts (ChannelTS) – Time series data object containing the Phoenix file data with calibration applied if calibration files were provided.

  • run_ts (RunTS) – Time series data object containing the MTU data from the Phoenix MTU files with calibration applied if specified.

  • mtu_table (MTUTable) – Metadata table object containing the MTU table data.

Raises:
  • KeyError – If the file extension is not supported by any Phoenix reader.

  • ValueError – If the file cannot be read or converted to ChannelTS or RunTS format.