mth5.io.phoenix package
Subpackages
- mth5.io.phoenix.readers package
- Subpackages
- Submodules
- mth5.io.phoenix.readers.base module
TSReaderBaseTSReaderBase.streamTSReaderBase.base_pathTSReaderBase.last_seqTSReaderBase.rx_metadataTSReaderBase.base_dirTSReaderBase.base_pathTSReaderBase.channel_metadataTSReaderBase.close()TSReaderBase.config_file_pathTSReaderBase.file_extensionTSReaderBase.file_nameTSReaderBase.file_sizeTSReaderBase.get_channel_response()TSReaderBase.get_config_object()TSReaderBase.get_dipole_filter()TSReaderBase.get_lowpass_filter_name()TSReaderBase.get_receiver_lowpass_filter()TSReaderBase.get_receiver_metadata_object()TSReaderBase.get_sensor_filter()TSReaderBase.get_v_to_mv_filter()TSReaderBase.instrument_idTSReaderBase.max_samplesTSReaderBase.open_file_seq()TSReaderBase.open_next()TSReaderBase.recmeta_file_pathTSReaderBase.run_metadataTSReaderBase.seqTSReaderBase.sequence_listTSReaderBase.station_metadataTSReaderBase.update_channel_map_from_recmeta()
- mth5.io.phoenix.readers.calibrations module
- mth5.io.phoenix.readers.config module
PhoenixConfigPhoenixConfig.fnPhoenixConfig.objPhoenixConfig.loggerPhoenixConfig.auto_power_enabledPhoenixConfig.configPhoenixConfig.empower_versionPhoenixConfig.fnPhoenixConfig.has_obj()PhoenixConfig.mtc150_resetPhoenixConfig.networkPhoenixConfig.read()PhoenixConfig.receiverPhoenixConfig.schedulePhoenixConfig.station_metadata()PhoenixConfig.surveyTechniquePhoenixConfig.timezonePhoenixConfig.timezone_offsetPhoenixConfig.version
- mth5.io.phoenix.readers.header module
HeaderHeader.loggerHeader.report_hw_satHeader.header_lengthHeader.ad_plus_minus_rangeHeader.channel_mapHeader.channel_azimuthsHeader.attenuator_gainHeader.battery_voltage_vHeader.board_model_mainHeader.board_model_revisionHeader.bytes_per_sampleHeader.ch_board_modelHeader.ch_board_serialHeader.ch_firmwareHeader.channel_idHeader.channel_main_gainHeader.channel_typeHeader.data_footerHeader.decimation_node_idHeader.detected_channel_typeHeader.file_sequenceHeader.file_typeHeader.file_versionHeader.frag_periodHeader.frame_rollover_countHeader.frame_sizeHeader.frame_size_bytesHeader.future1Header.future2Header.get_channel_metadata()Header.get_run_metadata()Header.get_station_metadata()Header.gps_elevationHeader.gps_horizontal_accuracyHeader.gps_latHeader.gps_longHeader.gps_vertical_accuracyHeader.hardware_configurationHeader.header_lengthHeader.instrument_serial_numberHeader.instrument_typeHeader.intrinsic_circuitry_gainHeader.lp_frequencyHeader.max_signalHeader.min_signalHeader.missing_framesHeader.preamp_gainHeader.recording_idHeader.recording_start_timeHeader.sample_rateHeader.sample_rate_baseHeader.sample_rate_expHeader.saturated_framesHeader.timing_flagsHeader.timing_sat_countHeader.timing_stabilityHeader.timing_statusHeader.total_circuitry_gainHeader.total_selectable_gainHeader.unpack_header()
- mth5.io.phoenix.readers.helpers module
- mth5.io.phoenix.readers.receiver_metadata module
PhoenixReceiverMetadataPhoenixReceiverMetadata.fnPhoenixReceiverMetadata.objPhoenixReceiverMetadata.loggerPhoenixReceiverMetadata.channel_mapPhoenixReceiverMetadata.e1_metadataPhoenixReceiverMetadata.e2_metadataPhoenixReceiverMetadata.fnPhoenixReceiverMetadata.get_ch_index()PhoenixReceiverMetadata.get_ch_metadata()PhoenixReceiverMetadata.get_ch_tag()PhoenixReceiverMetadata.h1_metadataPhoenixReceiverMetadata.h2_metadataPhoenixReceiverMetadata.h3_metadataPhoenixReceiverMetadata.h4_metadataPhoenixReceiverMetadata.h5_metadataPhoenixReceiverMetadata.h6_metadataPhoenixReceiverMetadata.has_obj()PhoenixReceiverMetadata.instrument_idPhoenixReceiverMetadata.lp_filter_base_namePhoenixReceiverMetadata.read()PhoenixReceiverMetadata.run_metadataPhoenixReceiverMetadata.station_metadataPhoenixReceiverMetadata.survey_metadata
- Module contents
DecimatedContinuousReaderDecimatedContinuousReader.subheaderDecimatedContinuousReader.data_sizeDecimatedContinuousReader.read()DecimatedContinuousReader.read_sequence()DecimatedContinuousReader.segment_end_timeDecimatedContinuousReader.segment_start_timeDecimatedContinuousReader.sequence_endDecimatedContinuousReader.sequence_startDecimatedContinuousReader.to_channel_ts()
DecimatedSegmentedReaderHeaderHeader.loggerHeader.report_hw_satHeader.header_lengthHeader.ad_plus_minus_rangeHeader.channel_mapHeader.channel_azimuthsHeader.attenuator_gainHeader.battery_voltage_vHeader.board_model_mainHeader.board_model_revisionHeader.bytes_per_sampleHeader.ch_board_modelHeader.ch_board_serialHeader.ch_firmwareHeader.channel_idHeader.channel_main_gainHeader.channel_typeHeader.data_footerHeader.decimation_node_idHeader.detected_channel_typeHeader.file_sequenceHeader.file_typeHeader.file_versionHeader.frag_periodHeader.frame_rollover_countHeader.frame_sizeHeader.frame_size_bytesHeader.future1Header.future2Header.get_channel_metadata()Header.get_run_metadata()Header.get_station_metadata()Header.gps_elevationHeader.gps_horizontal_accuracyHeader.gps_latHeader.gps_longHeader.gps_vertical_accuracyHeader.hardware_configurationHeader.header_lengthHeader.instrument_serial_numberHeader.instrument_typeHeader.intrinsic_circuitry_gainHeader.lp_frequencyHeader.max_signalHeader.min_signalHeader.missing_framesHeader.preamp_gainHeader.recording_idHeader.recording_start_timeHeader.sample_rateHeader.sample_rate_baseHeader.sample_rate_expHeader.saturated_framesHeader.timing_flagsHeader.timing_sat_countHeader.timing_stabilityHeader.timing_statusHeader.total_circuitry_gainHeader.total_selectable_gainHeader.unpack_header()
MTUTSNMTUTableMTUTable.channel_keysMTUTable.decode_tbl_value()MTUTable.ex_calibrationMTUTable.ex_metadataMTUTable.ey_calibrationMTUTable.ey_metadataMTUTable.hx_metadataMTUTable.hy_metadataMTUTable.hz_metadataMTUTable.magnetic_calibrationMTUTable.read_tbl()MTUTable.run_metadataMTUTable.station_metadataMTUTable.survey_metadata
NativeReaderNativeReader.last_frameNativeReader.data_scalingNativeReader.ad_plus_minus_rangeNativeReader.input_plusminus_rangeNativeReader.scale_factorNativeReader.footer_idx_samp_maskNativeReader.footer_sat_maskNativeReader.npts_per_frameNativeReader.read()NativeReader.read_frames()NativeReader.read_sequence()NativeReader.skip_frames()NativeReader.to_channel_ts()
PhoenixCalibrationPhoenixConfigPhoenixConfig.fnPhoenixConfig.objPhoenixConfig.loggerPhoenixConfig.auto_power_enabledPhoenixConfig.configPhoenixConfig.empower_versionPhoenixConfig.fnPhoenixConfig.has_obj()PhoenixConfig.mtc150_resetPhoenixConfig.networkPhoenixConfig.read()PhoenixConfig.receiverPhoenixConfig.schedulePhoenixConfig.station_metadata()PhoenixConfig.surveyTechniquePhoenixConfig.timezonePhoenixConfig.timezone_offsetPhoenixConfig.version
PhoenixReceiverMetadataPhoenixReceiverMetadata.fnPhoenixReceiverMetadata.objPhoenixReceiverMetadata.loggerPhoenixReceiverMetadata.channel_mapPhoenixReceiverMetadata.e1_metadataPhoenixReceiverMetadata.e2_metadataPhoenixReceiverMetadata.fnPhoenixReceiverMetadata.get_ch_index()PhoenixReceiverMetadata.get_ch_metadata()PhoenixReceiverMetadata.get_ch_tag()PhoenixReceiverMetadata.h1_metadataPhoenixReceiverMetadata.h2_metadataPhoenixReceiverMetadata.h3_metadataPhoenixReceiverMetadata.h4_metadataPhoenixReceiverMetadata.h5_metadataPhoenixReceiverMetadata.h6_metadataPhoenixReceiverMetadata.has_obj()PhoenixReceiverMetadata.instrument_idPhoenixReceiverMetadata.lp_filter_base_namePhoenixReceiverMetadata.read()PhoenixReceiverMetadata.run_metadataPhoenixReceiverMetadata.station_metadataPhoenixReceiverMetadata.survey_metadata
TSReaderBaseTSReaderBase.streamTSReaderBase.base_pathTSReaderBase.last_seqTSReaderBase.rx_metadataTSReaderBase.base_dirTSReaderBase.base_pathTSReaderBase.channel_metadataTSReaderBase.close()TSReaderBase.config_file_pathTSReaderBase.file_extensionTSReaderBase.file_nameTSReaderBase.file_sizeTSReaderBase.get_channel_response()TSReaderBase.get_config_object()TSReaderBase.get_dipole_filter()TSReaderBase.get_lowpass_filter_name()TSReaderBase.get_receiver_lowpass_filter()TSReaderBase.get_receiver_metadata_object()TSReaderBase.get_sensor_filter()TSReaderBase.get_v_to_mv_filter()TSReaderBase.instrument_idTSReaderBase.max_samplesTSReaderBase.open_file_seq()TSReaderBase.open_next()TSReaderBase.recmeta_file_pathTSReaderBase.run_metadataTSReaderBase.seqTSReaderBase.sequence_listTSReaderBase.station_metadataTSReaderBase.update_channel_map_from_recmeta()
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:
CollectionCollection 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.CollectionBase collection class
mth5.io.phoenix.PhoenixReceiverMetadataReceiver 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:
Calls to_dataframe() to inventory all files
Calls assign_run_names() to group files into runs
Selects first file(s) for each run and component
Returns organized structure for easy iteration
See also
to_dataframeCreate complete file inventory
assign_run_namesGroup files into runs
mth5.io.phoenix.read_phoenixRead 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_namesAssign run identifiers based on timing
get_runsGet 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:
CollectionCollection 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.CollectionBase collection class
mth5.io.phoenix.PhoenixReceiverMetadataReceiver 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:
Calls to_dataframe() to inventory all files
Calls assign_run_names() to group files into runs
Selects first file(s) for each run and component
Returns organized structure for easy iteration
See also
to_dataframeCreate complete file inventory
assign_run_namesGroup files into runs
mth5.io.phoenix.read_phoenixRead 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_namesAssign run identifiers based on timing
get_runsGet organized runs directly
- class mth5.io.phoenix.PhoenixConfig(fn: str | Path | None = None, **kwargs: Any)[source]
Bases:
objectPhoenix 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:
objectContainer 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.